[update] GPIOライブラリをrgpioに変更。PWM関連ブロックからJSコードを削除。動作環境にOrangePi5を追加

This commit is contained in:
ocogeclub 2023-05-09 09:05:48 +09:00
parent 7a2997c35a
commit d0adc9edf7
20 changed files with 647 additions and 345 deletions

View File

@ -31,7 +31,7 @@ class appTool {
this.saveFilepath = null;
this.wsChanged = false;
this.children = [];
this.gpio_lib = ugj_const.pig;
this.gpio_lib = ugj_const.rg;
this.i2c_bus = ugj_const.i2c_defbus;
this.lang = ugj_const.lang;
this.doc_root = this.path.join(process.env["HOME"], ugj_const.document_root);
@ -222,7 +222,6 @@ class appTool {
'doc_current': this.doc_current,
'i2c_bus': this.i2c_bus,
'lang': this.lang,
'gpio_lib': this.gpio_lib
};
let s = JSON.stringify(o);
localStorage.setItem(ugj_const.localStorage_fname, s);
@ -243,15 +242,15 @@ class appTool {
this.ipcRenderer.send('i2c_check_menu', 'i2c-' + this.i2c_bus);
}
if (o.lang) {
let l;
if (o.lang == 'js' || o.gpio_lib) {
l = o.lang + '-' + o.gpio_lib;
} else {
l = o.lang;
}
this.setLang(l);
console.log(`l= ${l}`);
this.ipcRenderer.send('lang_check_menu', l);
// let l;
// if (o.lang == 'js' || o.gpio_lib) {
// l = o.lang + '-' + o.gpio_lib;
// } else {
// l = o.lang;
// }
this.setLang(o.lang);
console.log(`lang= ${this.lang}`);
this.ipcRenderer.send('lang_check_menu', this.lang);
}
}
}
@ -271,13 +270,14 @@ class appTool {
// 言語/GPIOライブラリ変更
setLang(l) {
if (l == 'js-pigpio') {
this.lang = 'js';
this.gpio_lib = ugj_const.pig;
} else if (l == 'js-rgpio') {
this.lang = 'js';
this.gpio_lib = ugj_const.rg;
} else this.lang = 'py';
this.lang = l;
// if (l == 'js-pigpio') {
// this.lang = 'js';
// this.gpio_lib = ugj_const.pig;
// } else if (l == 'js-rgpio') {
// this.lang = 'js';
// this.gpio_lib = ugj_const.rg;
// } else this.lang = 'py';
const exp = document.getElementById('dlgExport');
if (this.lang == 'js') {

View File

@ -465,11 +465,6 @@ var ugjPwmDefinition = {
"type": "input_value",
"name": "pwm_frequency",
"check": "Number"
},
{
"type": "input_value",
"name": "pwm_duty_cycle",
"check": "Number"
}
],
"inputsInline": true,
@ -484,20 +479,50 @@ Blockly.Blocks['ugj_pwm'] = {
this.jsonInit(ugjPwmDefinition);
}
};
Blockly.JavaScript['ugj_pwm'] = function (block) {
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
var value_pwm_frequency = Blockly.JavaScript.valueToCode(block, 'pwm_frequency', Blockly.JavaScript.ORDER_ATOMIC);
var value_pwm_duty_cycle = Blockly.JavaScript.valueToCode(block, 'pwm_duty_cycle', Blockly.JavaScript.ORDER_ATOMIC);
var code = `await _pi.pwm(${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`;
return code;
};
// Blockly.Python['ugj_pwm'] = function (block) {
// var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
// var value_pwm_frequency = Blockly.Python.valueToCode(block, 'pwm_frequency', Blockly.Python.ORDER_ATOMIC);
// var value_pwm_duty_cycle = Blockly.Python.valueToCode(block, 'pwm_duty_cycle', Blockly.Python.ORDER_ATOMIC);
// var code = `await pi.pwm(gpioHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`;
// Blockly.JavaScript['ugj_pwm'] = function (block) {
// var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
// var value_pwm_frequency = Blockly.JavaScript.valueToCode(block, 'pwm_frequency', Blockly.JavaScript.ORDER_ATOMIC);
// var value_pwm_duty_cycle = Blockly.JavaScript.valueToCode(block, 'pwm_duty_cycle', Blockly.JavaScript.ORDER_ATOMIC);
// var code = `await _pi.pwm(${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`;
// return code;
// };
Blockly.Python['ugj_pwm'] = function (block) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var value_pwm_frequency = Blockly.Python.valueToCode(block, 'pwm_frequency', Blockly.Python.ORDER_ATOMIC);
var value_pwm_duty_cycle = Blockly.Python.valueToCode(block, 'pwm_duty_cycle', Blockly.Python.ORDER_ATOMIC);
Blockly.Python.provideFunction_(
'import_pwm', ['from machine import PWM']
);
var code = `_pin[${value_gpio}] = PWM(Pin(${value_gpio}))
_pin[${value_gpio}].freq(${value_pwm_frequency})
`;
// var code = `await pi.pwm(gpioHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`;
return code;
};
Blockly.Blocks['oc_pwm_duty'] = {
init: function () {
this.appendValueInput("gpio")
.setCheck("Number")
.appendField("GPIO");
this.appendValueInput("duty")
.setCheck("Number")
.appendField("へデューティ値");
this.appendDummyInput()
.appendField("でパルスを出力");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("PWM出力に設定したGPIOへパルスを出力します。デューティ値は 0(0%) 65535(100%) の範囲で指定します。");
this.setHelpUrl("");
this.setStyle('gpio_blocks');
}
};
Blockly.Python['oc_pwm_duty'] = function (block) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var value_duty = Blockly.Python.valueToCode(block, 'duty', Blockly.Python.ORDER_ATOMIC);
var code = `_pin[${value_gpio}].duty_u16(${value_duty})\n`;
return code;
};
/********************** */
/** Open Serial Port ** */
/********************** */
@ -542,7 +567,8 @@ Blockly.JavaScript['ugj_serial_open'] = function (block) {
Blockly.JavaScript.provideFunction_(
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
);
var code = `await _pi.serial_open('/dev/serial0', ${dropdown_baud});\n`;
var code = `await _pi.serial_open('/dev/ttyS0', ${dropdown_baud});\n`;
// var code = `await _pi.serial_open('/dev/serial0', ${dropdown_baud});\n`;
return code;
};
// Blockly.Python['ugj_serial_open'] = function (block) {
@ -721,6 +747,30 @@ Blockly.Python['ugj_i2c_close'] = function (block) {
return code;
};
/*************************************** */
/** Sends a single byte to the device ** */
/*************************************** */
Blockly.Blocks['oc_i2c_write_byte'] = {
init: function () {
this.appendValueInput("byte_val")
.setCheck("Number")
.appendField("デバイスに1バイトデータ");
this.appendDummyInput()
.appendField("を送信");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setTooltip("i2cデバイスにバイトデータを送信します。0-0xFF(255)の範囲の数字で入力してください。");
this.setHelpUrl("");
this.setStyle('gpio_blocks');
}
};
Blockly.JavaScript['oc_i2c_write_byte'] = function (block) {
var value_byte_val = Blockly.JavaScript.valueToCode(block, 'byte_val', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var code = `await _pi.i2c_write_byte(${value_byte_val});\n`;
return code;
};
/****************************************************************** */
/** Writes a single byte to the specified register of the device ** */
/****************************************************************** */

View File

@ -30,5 +30,6 @@ registerCategory('sensors', [ // カテゴリディレクトリ名
"paj7620",
"bme280",
"dht11",
"pico_slave",
"z-line" // フライアウト下端の不可視ライン。スクリプトにカテゴリ名を含むので注意
]);

View File

@ -1,7 +1,7 @@
'use strict';
const err_msg = 'AMG8833 is already opened. Please close old connection to use new one.';
const pig = require('@ocoge.club/pigpio');
const pig = require(`@ocoge.club/${apptool.gpio_lib}`);
let pi = -1;
let i2c_hand = -1;
@ -12,7 +12,7 @@ exports.init = async (i2c_bus, i2c_addr, wael = null) => {
});
}
if (pi >= 0) { throw new Error(err_msg); return; }
pi = await pig._pigpio_start('', '');
pi = await pig._gpiod_start('', '');
console.log('pi=' + pi);
if (i2c_hand >= 0) { throw new Error(err_msg); return; }
i2c_hand = await pig._i2c_open(pi, i2c_bus, i2c_addr);
@ -45,7 +45,7 @@ exports.stop = async () => {
i2c_hand = -1;
}
if (pi >= 0) {
await pig._pigpio_stop(pi);
await pig._gpiod_stop(pi);
pi = -1;
}
}

View File

@ -1,55 +0,0 @@
'use strict';
const err_msg = 'AMG8833 is already opened. Please close old connection to use new one.';
const pig = require('@ocoge.club/rgpio');
let pi = -1;
let i2c_hand = -1;
exports.init = async (i2c_bus, i2c_addr, wael = null) => {
if (wael !== null) {
wael('beforeunload', async () => {
await exports.stop();
});
}
if (pi >= 0) { throw new Error(err_msg); return; }
pi = await pig._rgpiod_start('', '');
console.log('pi=' + pi);
if (i2c_hand >= 0) { throw new Error(err_msg); return; }
i2c_hand = await pig._i2c_open(pi, i2c_bus, i2c_addr, 0);
console.log('i2c_hand=' + i2c_hand);
await pig._i2c_write_byte_data(pi, i2c_hand, 0x00, 0x00); //Normal mode
await pig._i2c_write_byte_data(pi, i2c_hand, 0x02, 0x00); //10FPS
}
exports.read_thermistor = async () => {
let temp = await pig._i2c_read_word_data(pi, i2c_hand, 0x0e);
return temp * 0.0625;
}
exports.read_temp_array = async () => {
let linedata = [];
for (let i = 0; i < 8; i++) {
let data = await pig._i2c_read_i2c_block_data(pi, i2c_hand, 0x80 + 0x10 * i, 16);
let oneline = [];
for (let j = 0; j < 8; j++) {
oneline.push(((data[2 * j + 1] & 0x07) * 256 + data[2 * j]) * 0.25);
}
linedata.push(oneline);
}
return linedata;
}
exports.stop = async () => {
if (i2c_hand >= 0) {
await pig._i2c_close(pi, i2c_hand);
i2c_hand = -1;
}
if (pi >= 0) {
await pig._rgpiod_stop(pi);
pi = -1;
}
}
/*
* This code was ported from https://www.denshi.club/pc/raspi/5raspberry-pi-zeroiot381i2c-amg8833.html
*/

View File

@ -56,7 +56,7 @@ Blockly.JavaScript['ugj_grideye_init'] = function (block) {
// Blockly.JavaScript.provideFunction_(
// 'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
// );
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'amg8833', `AMG8833x_${apptool.gpio_lib}.js`);
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'amg8833', `AMG8833x.js`);
Blockly.JavaScript.provideFunction_(
'require_amg8833', [`const _amg8833 = require('${modpath}');`]
);

View File

@ -42,8 +42,8 @@ this.REGISTER_TEMP_DATA = 0xFA;
this.REGISTER_HUMIDITY_DATA = 0xFD;
exports.init = async (options) => {
this.pig = require('@ocoge.club/pigpio');
this.pi = await this.pig._pigpio_start('', '');
this.pig = require(`@ocoge.club/${apptool.gpio_lib}`);
this.pi = await this.pig._gpiod_start('', '');
this.i2cBusNo = (options && options.hasOwnProperty('i2cBusNo')) ? options.i2cBusNo : 1;
this.i2cAddress = (options && options.hasOwnProperty('i2cAddress')) ? options.i2cAddress : this.BME280_DEFAULT_I2C_ADDRESS();
@ -96,7 +96,7 @@ exports.cancel = async () => {
if (this.i2cHand >= 0) {
await this.pig._i2c_close(this.pi, this.i2cHand);
this.i2cHand = null;
await this.pig._pigpio_stop(this.pi);
await this.pig._gpiod_stop(this.pi);
this.pi = null;
}
}

View File

@ -17,10 +17,11 @@ Blockly.Blocks['ugj_bme280'] = {
};
Blockly.JavaScript['ugj_bme280'] = function (block) {
var dropdown_addr = block.getFieldValue('addr');
Blockly.JavaScript.provideFunction_(
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
);
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'bme280', 'BME280x.js');
// Blockly.JavaScript.provideFunction_(
// 'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
// );
// let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'bme280', 'BME280x.js');
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'bme280', `BME280x.js`);
Blockly.JavaScript.provideFunction_(
'require_bme280', [`const _bme280 = require('${modpath}');`]
);

View File

@ -311,7 +311,7 @@ const initRegisterArray = [
//Enable debug message
const debug = 1;
const err_msg = 'AMG8833 is already opened. Please close old connection to use new one.';
const err_msg = 'PAJ7620 is already opened. Please close old connection to use new one.';
let pig = -1;
let pi = -1;
let i2c_hand = -1;
@ -322,9 +322,9 @@ exports.init = async (i2c_bus, i2c_addr, wael = null) => {
await exports.stop();
});
}
pig = require('@ocoge.club/pigpio');
pig = require(`@ocoge.club/${apptool.gpio_lib}`);
if (pi >= 0) { throw new Error(err_msg); return; }
pi = await pig._pigpio_start('', '');
pi = await pig._gpiod_start('', '');
if (i2c_hand >= 0) { throw new Error(err_msg); return; }
i2c_hand = await pig._i2c_open(pi, i2c_bus, i2c_addr);
if (debug)
@ -461,7 +461,7 @@ exports.stop = async () => {
i2c_hand = -1;
}
if (pi >= 0) {
await pig._pigpio_stop(pi);
await pig._gpiod_stop(pi);
pi = -1;
}
}

View File

@ -32,9 +32,9 @@ Blockly.Blocks['ugj_gesture_init'] = {
};
Blockly.JavaScript['ugj_gesture_init'] = function (block) {
var value_i2c_addr = Blockly.JavaScript.valueToCode(block, 'i2c_addr', Blockly.JavaScript.ORDER_ATOMIC);
Blockly.JavaScript.provideFunction_(
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
);
// Blockly.JavaScript.provideFunction_(
// 'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
// );
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'paj7620', 'PAJ7620x.js');
Blockly.JavaScript.provideFunction_(
'require_paj7620', [`const _paj7620 = require('${modpath}');`]

View File

@ -0,0 +1,66 @@
Blockly.Blocks['oc_i2cslave'] = {
init: function () {
this.appendValueInput("i2c_addr")
.setCheck("Number")
.appendField("PICOスレーブI2Cアドレス");
this.appendDummyInput()
.appendField(new Blockly.FieldVariable("データ"), "data")
.appendField("を受け取ったら");
this.appendStatementInput("do")
.setCheck(null);
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setTooltip("Raspberry Pi Pico及びその互換機を I2Cスレーブ化します。受信データは1バイトデータです。i2c_slave.py が必要です。");
this.setHelpUrl("");
this.setStyle('gpio_blocks');
}
};
Blockly.Python['oc_i2cslave'] = function (block) {
var value_i2c_addr = Blockly.Python.valueToCode(block, 'i2c_addr', Blockly.Python.ORDER_ATOMIC);
var variable_data = Blockly.Python.nameDB_.getName(block.getFieldValue('data'), Blockly.Names.NameType.VARIABLE);
var statements_do = Blockly.Python.statementToCode(block, 'do');
Blockly.Python.provideFunction_(
'import_i2cslave', ['from i2cSlave import i2c_slave']
);
var code = `_i2cs = i2c_slave(0,sda=0,scl=1,slaveAddress=${value_i2c_addr})
while True:
${variable_data} = int(_i2cs.get())
${statements_do}
`;
return code;
};
flyout_contents = flyout_contents.concat([
{
"kind": "label",
"text": "RPi Pico I2Cスレーブ化",
"web-line": "4.0",
"web-line-width": "200"
}, {
"kind": "block",
"type": "oc_i2cslave",
"fields": {
"data": {
"name": "データ"
}
},
"inputs": {
"i2c_addr": {
"shadow": {
"type": "ugj_hextodec",
"inputs": {
"hex": {
"shadow": {
"type": "text",
"fields": {
"TEXT": "41"
}
}
}
}
}
}
}
}
])

View File

@ -368,7 +368,7 @@
<block type="ugj_pwm">
<value name="gpio">
<shadow type="math_number">
<field name="NUM">5</field>
<field name="NUM">29</field>
</shadow>
</value>
<value name="pwm_frequency">
@ -376,21 +376,16 @@
<field name="NUM">50</field>
</shadow>
</value>
<value name="pwm_duty_cycle">
<shadow type="math_number">
<field name="NUM">30</field>
</shadow>
</value>
</block>
<block type="ugj_servo">
<block type="oc_pwm_duty">
<value name="gpio">
<shadow type="math_number">
<field name="NUM">12</field>
<field name="NUM">29</field>
</shadow>
</value>
<value name="pulsewidth">
<value name="duty">
<shadow type="math_number">
<field name="NUM">1500</field>
<field name="NUM">0</field>
</shadow>
</value>
</block>
@ -403,6 +398,13 @@
</value>
</block>
<block type="ugj_i2c_close"></block>
<block type="oc_i2c_write_byte">
<value name="byte_val">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
</block>
<block type="ugj_i2c_write_byte_data">
<value name="reg">
<shadow type="math_number">
@ -493,7 +495,7 @@
<label text="Extra" web-line="4.0" web-line-width="200"></label>
<label text="_" web-line="4.0" web-line-width="200"></label>
</category>
<category toolboxitemid="category_sensors" name="センサー" css-icon="customIcon fas fa-microchip"
<category toolboxitemid="category_sensors" name="モジュール" css-icon="customIcon fas fa-microchip"
categorystyle="sensor_category">
</category>
<category name="マルチメディア" css-icon="customIcon fas fa-gamepad" categorystyle="multimedia_category">

View File

@ -113,8 +113,8 @@ Blockly.Msg["GPIO_WRITE_TITLE"] = "GPIO %1 の値を %2 にする";
Blockly.Msg["GPIO_WRITE_TOOLTIP"] = "GPIO端子の値をデジタル値0または1で出力します。";
Blockly.Msg["SERVO_TITLE"] = "GPIO %1 のサーボモータの回転を %2 にする";
Blockly.Msg["SERVO_TOOLTIP"] = "サーボモータの回転をパルス幅(10002000μsec)までの数値で指定します。";
Blockly.Msg["PWM_TITLE"] = "PWM : GPIO %1 に、パルス周波数 %2 Hz, デューティー比 %3 %%で出力";
Blockly.Msg["PWM_TOOLTIP"] = "パルス周波数をセットして、GPIO端子がPWM出力できるようにします。レンジは100固定です。";
Blockly.Msg["PWM_TITLE"] = "GPIO %1 をパルス周波数 %2 Hzの PWM 出力に設定";
Blockly.Msg["PWM_TOOLTIP"] = "パルス周波数をセットして、GPIO端子がPWM出力できるようにします。(MicorPython 専用)";
Blockly.Msg["I2C_OPEN_TITLE"] = "アドレス %1 の I2C デバイスを開く";
Blockly.Msg["I2C_OPEN_TOOLTIP"] = "I2C接続されたデバイスとの通信を開始します。一度にオープンできるI2Cデバイスはひとつだけです。";
Blockly.Msg["SERIAL_OPEN_TITLE"] = "シリアルポートを速度 %1 bpsで開く";
@ -293,7 +293,7 @@ const ugj_newWorkspace = () => {
// ワークスペースをファイルに保存・読込
const ugj_saveWorkspaceToFile = async () => {
let xml = Blockly.Xml.workspaceToDom(workspace);
let xml_text = Blockly.Xml.domToText(xml);
let xml_text = Blockly.utils.xml.domToText(xml);
if (await apptool.saveWsFile(xml_text) === false) {
window.alert('保存できませんでした。');
}
@ -301,7 +301,7 @@ const ugj_saveWorkspaceToFile = async () => {
const ugj_loadWorkspaceFromFile = async () => {
let xml_text = await apptool.loadWsFile();
if (xml_text.length > 0) {
let xml = Blockly.Xml.textToDom(xml_text);
let xml = Blockly.utils.xml.textToDom(xml_text);
Blockly.Xml.domToWorkspace(xml, workspace);
}
}
@ -316,7 +316,7 @@ const ugj_saveWorkspaceAs = () => {
const ugj_saveWorkspace = () => {
// Workspace
let xml = Blockly.Xml.workspaceToDom(workspace);
let xml_text = Blockly.Xml.domToText(xml);
let xml_text = Blockly.utils.xml.domToText(xml);
localStorage.setItem("ocoge.xml", xml_text);
}
const ugj_loadWorkspace = () => {
@ -324,7 +324,7 @@ const ugj_loadWorkspace = () => {
let xml_text = localStorage.getItem("ocoge.xml");
if (xml_text !== null) {
if (xml_text.length != 0) {
let xml = Blockly.Xml.textToDom(xml_text);
let xml = Blockly.utils.xml.textToDom(xml_text);
Blockly.Xml.domToWorkspace(xml, workspace);
}
}
@ -341,8 +341,13 @@ const ugj_generateCode = () => {
code = '';
}
} else { // Javascript コード出力
try {
code = Blockly.JavaScript.workspaceToCode(workspace).replace(/(?<=^|\n)function \w+\(.*\)/g, 'async $&');
// .replace 以降は、関数の常時非同期化のため
} catch (e) { // JSコードを持たないブロックがある場合
window.alert('Python 専用ブロックが使用されています。\n' + e.message);
code = '';
}
// .replace 以降は、関数の常時非同期化のため...要するに async 付加
}
return code;
}

View File

@ -14,11 +14,11 @@ let pi = -1;
let i2c_hand = -1;
let ser_hand = -1;
module.exports.gpio_open = async () => {
if (pi < 0) pi = await module.exports._pigpio_start('', '');
if (pi < 0) pi = await module.exports._gpiod_start('', '');
return pi;
}
module.exports.gpio_close = async () => {
if (pi >= 0) await module.exports._pigpio_stop(pi);
if (pi >= 0) await module.exports._gpiod_stop(pi);
pi = -1;
}
module.exports.gpio_set_output = async gpio => {

View File

@ -651,8 +651,8 @@ Promise _i2cWriteDevice(const CallbackInfo &info)
Object
Init(Env env, Object exports)
{
exports.Set(String::New(env, "_pigpio_start"), Function::New(env, _pigpioStart));
exports.Set(String::New(env, "_pigpio_stop"), Function::New(env, _pigpioStop));
exports.Set(String::New(env, "_gpiod_start"), Function::New(env, _pigpioStart));
exports.Set(String::New(env, "_gpiod_stop"), Function::New(env, _pigpioStop));
exports.Set(String::New(env, "_set_mode"), Function::New(env, _setMode));
exports.Set(String::New(env, "_set_pull_up_down"), Function::New(env, _setPullUpDown));
exports.Set(String::New(env, "_gpio_read"), Function::New(env, _gpioRead));

View File

@ -18,7 +18,7 @@ let gpiochip_hand = [];
let ser_hand = -1;
let i2c_hand = -1;
module.exports.gpio_open = async () => {
sbc = await module.exports._rgpiod_start('', port);
sbc = await module.exports._gpiod_start('', '');
if (sbc < 0) return sbc;
for (let i = 0; i < CHIP_COUNT; i++) {
gpiochip_hand.push(await module.exports._gpiochip_open(sbc, i));
@ -26,13 +26,16 @@ module.exports.gpio_open = async () => {
return gpiochip_hand;
}
module.exports.gpio_close = async () => {
if (sbc >= 0) {
for (let i = 0; i < CHIP_COUNT; i++) {
if (gpiochip_hand[i] >= 0)
await module.exports._gpiochip_close(sbc, gpiochip_hand[i]);
}
gpiochip_hand = [];
await module.exports._rgpiod_stop(sbc);
await module.exports._gpiod_stop(sbc);
sbc = -1;
}
}
module.exports.gpio_set_output = async gpio => {
let chip = Math.floor(gpio / 32);
let pin = Math.floor(gpio % 32);
@ -43,28 +46,62 @@ module.exports.gpio_write = async (gpio, value) => {
let pin = Math.floor(gpio % 32);
if (gpiochip_hand[chip] >= 0) return await module.exports._gpio_write(sbc, gpiochip_hand[chip], pin, value);
}
module.exports.serial_open = async (tty, baud) => {
if (ser_hand >= 0) await module.exports._serial_close(sbc, ser_hand); // 勝手に閉じる
ser_hand = await module.exports._serial_open(sbc, tty, baud);
return ser_hand;
}
module.exports.serial_close = async () => {
if (ser_hand >= 0) await module.exports._serial_close(sbc, ser_hand);
ser_hand = -1;
}
module.exports.serial_write = async data => {
if (ser_hand >= 0) return await module.exports._serial_write(sbc, ser_hand, Buffer.from(data));
}
module.exports.serial_read = async count => {
if (ser_hand >= 0) return new TextDecoder().decode(await module.exports._serial_read(sbc, ser_hand, count));
// if (ser_hand >= 0) return await module.exports._serial_read(pi, ser_hand, count);//.toString('utf8');
}
module.exports.i2c_open = async (i2c_bus, i2c_address) => {
if (i2c_hand >= 0) await module.exports._i2c_close(i2c_hand); // 勝手に閉じる
i2c_hand = await module.exports._i2c_open(sbc, i2c_bus, i2c_address, 0);
i2c_hand = await module.exports._i2c_open(sbc, i2c_bus, i2c_address);
return i2c_hand;
}
module.exports.i2c_close = async () => {
if (i2c_hand >= 0) await module.exports._i2c_close(sbc, i2c_hand);
i2c_hand = -1;
}
module.exports.i2c_write_byte = async (byte_val) => {
if (i2c_hand >= 0) return await module.exports._i2c_write_byte(sbc, i2c_hand, byte_val);
}
module.exports.i2c_read_byte = async () => {
if (i2c_hand >= 0) return await module.exports._i2c_read_byte(sbc, i2c_hand);
}
module.exports.i2c_write_byte_data = async (reg, byte_val) => {
if (i2c_hand >= 0) return await module.exports._i2c_write_byte_data(sbc, i2c_hand, reg, byte_val);
}
module.exports.i2c_read_byte_data = async reg => {
if (i2c_hand >= 0) return await module.exports._i2c_read_byte_data(sbc, i2c_hand, reg);
}
module.exports.i2c_write_i2c_block_data = async (reg, data) => {
if (i2c_hand >= 0) return await module.exports._i2c_write_i2c_block_data(sbc, i2c_hand, reg, Buffer.from(data));
}
module.exports.i2c_read_word_data = async reg => {
if (i2c_hand >= 0) return await module.exports._i2c_read_word_data(sbc, i2c_hand, reg);
}
module.exports.i2c_read_device = async count => {
if (i2c_hand >= 0) return new TextDecoder().decode(await module.exports._i2c_read_device(sbc, i2c_hand, count));
}
module.exports.i2c_write_device = async data => {
if (i2c_hand >= 0) return await module.exports._i2c_write_device(sbc, i2c_hand, Buffer.from(data));
}
// 終了処理
module.exports.close_all_handle = async () => {
await module.exports.gpio_close();
// await module.exports.serial_close();
await module.exports.serial_close();
await module.exports.i2c_close();
}

View File

@ -159,17 +159,122 @@ Promise _gpioWrite(const CallbackInfo &info)
return deferred.Promise();
}
// シリアルポートを開く
Promise _serialOpen(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count: _serialOpen").Value());
}
else if (!info[0].IsNumber() || !info[1].IsString() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types: _serialOpen").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
std::string ser_tty = info[1].As<String>().Utf8Value();
int baud = info[2].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, serial_open(sbc, (char *)ser_tty.c_str(), baud, 0)));
}
return deferred.Promise();
}
// シリアルポートを閉じる
Promise _serialClose(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 2)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
int handle = info[1].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, serial_close(sbc, handle)));
}
return deferred.Promise();
}
// シリアルデバイスからデータを読む
Promise _serialRead(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
int handle = info[1].As<Number>().Uint32Value();
int count = info[2].As<Number>().Uint32Value();
char buf[count];
int rxCount = serial_read(sbc, handle, buf, count);
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
deferred.Resolve(outBuf);
}
return deferred.Promise();
}
// シリアルデバイスにバイト列を書き込む(data: string)
Promise _serialWrite(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
int handle = info[1].As<Number>().Uint32Value();
auto buf = info[2].As<Buffer<char>>();
int count = buf.Length();
deferred.Resolve(Number::New(env, serial_write(sbc, handle, buf.Data(), count)));
}
return deferred.Promise();
}
// I2Cバスアドレスのデバイスのハンドルを返す
Promise _i2cOpen(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 4)
if (info.Length() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
@ -179,8 +284,7 @@ Promise _i2cOpen(const CallbackInfo &info)
int sbc = info[0].As<Number>().Int32Value();
unsigned int i2c_bus = info[1].As<Number>().Uint32Value();
unsigned int i2c_addr = info[2].As<Number>().Uint32Value();
int flags = 0;
deferred.Resolve(Number::New(env, i2c_open(sbc, i2c_bus, i2c_addr, flags)));
deferred.Resolve(Number::New(env, i2c_open(sbc, i2c_bus, i2c_addr, 0)));
}
return deferred.Promise();
}
@ -208,6 +312,54 @@ Promise _i2cClose(const CallbackInfo &info)
return deferred.Promise();
}
// デバイスに1バイトを送る
Promise _i2cWriteByte(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int bVal = info[2].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, i2c_write_byte(sbc, handle, bVal)));
}
return deferred.Promise();
}
// デバイスから1バイトを受け取る
Promise _i2cReadByte(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 2)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[0].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, i2c_read_byte(sbc, handle)));
}
return deferred.Promise();
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに1バイトを書き込む
Promise _i2cWriteByteData(const CallbackInfo &info)
{
@ -233,6 +385,30 @@ Promise _i2cWriteByteData(const CallbackInfo &info)
}
return deferred.Promise();
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから1バイトを読み込む
Promise _i2cReadByteData(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, i2c_read_byte_data(sbc, handle, i2c_reg)));
}
return deferred.Promise();
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタからcountバイトを読み込む。countは132。
Promise _i2cReadI2cBlockData(const CallbackInfo &info)
@ -315,22 +491,114 @@ Promise _i2cReadWordData(const CallbackInfo &info)
}
return deferred.Promise();
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに単一の16ビットワードを書き込む
Promise _i2cWriteWordData(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 4)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
unsigned int wVal = info[3].As<Number>().Uint32Value();
deferred.Resolve(Number::New(env, i2c_write_word_data(sbc, handle, i2c_reg, wVal)));
}
return deferred.Promise();
}
// i2c デバイスからデータを受け取る
Promise _i2cReadDevice(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int count = info[2].As<Number>().Uint32Value();
char buf[count];
int rxCount = i2c_read_device(sbc, handle, buf, count);
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
deferred.Resolve(outBuf);
}
return deferred.Promise();
}
// i2c デバイスにバイト列を送る(data: buffer)
Promise _i2cWriteDevice(const CallbackInfo &info)
{
Env env = info.Env();
auto deferred = Napi::Promise::Deferred::New(env);
if (info.Length() != 3)
{
deferred.Reject(
TypeError::New(env, "Invalid argument count").Value());
}
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
{
deferred.Reject(
Napi::TypeError::New(env, "Invalid argument types").Value());
}
else
{
int sbc = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
auto buf = info[2].As<Buffer<char>>();
unsigned int count = buf.Length();
deferred.Resolve(Number::New(env, i2c_write_device(sbc, handle, buf.Data(), count)));
}
return deferred.Promise();
}
Object
Init(Env env, Object exports)
{
exports.Set(String::New(env, "_rgpiod_start"), Function::New(env, _rgpiodStart));
exports.Set(String::New(env, "_rgpiod_stop"), Function::New(env, _rgpiodStop));
exports.Set(String::New(env, "_gpiod_start"), Function::New(env, _rgpiodStart));
exports.Set(String::New(env, "_gpiod_stop"), Function::New(env, _rgpiodStop));
exports.Set(String::New(env, "_gpiochip_open"), Function::New(env, _gpiochipOpen));
exports.Set(String::New(env, "_gpiochip_close"), Function::New(env, _gpiochipClose));
exports.Set(String::New(env, "_gpio_claim_output"), Function::New(env, _gpioClaimOutput));
exports.Set(String::New(env, "_gpio_write"), Function::New(env, _gpioWrite));
exports.Set(String::New(env, "_serial_open"), Function::New(env, _serialOpen));
exports.Set(String::New(env, "_serial_close"), Function::New(env, _serialClose));
exports.Set(String::New(env, "_serial_read"), Function::New(env, _serialRead));
exports.Set(String::New(env, "_serial_write"), Function::New(env, _serialWrite));
exports.Set(String::New(env, "_i2c_open"), Function::New(env, _i2cOpen));
exports.Set(String::New(env, "_i2c_close"), Function::New(env, _i2cClose));
exports.Set(String::New(env, "_i2c_write_byte"), Function::New(env, _i2cWriteByte));
exports.Set(String::New(env, "_i2c_read_byte"), Function::New(env, _i2cReadByte));
exports.Set(String::New(env, "_i2c_write_byte_data"), Function::New(env, _i2cWriteByteData));
exports.Set(String::New(env, "_i2c_read_byte_data"), Function::New(env, _i2cReadByteData));
exports.Set(String::New(env, "_i2c_read_i2c_block_data"), Function::New(env, _i2cReadI2cBlockData));
exports.Set(String::New(env, "_i2c_write_i2c_block_data"), Function::New(env, _i2cWriteI2cBlockData));
exports.Set(String::New(env, "_i2c_read_word_data"), Function::New(env, _i2cReadWordData));
exports.Set(String::New(env, "_i2c_write_word_data"), Function::New(env, _i2cWriteWordData));
exports.Set(String::New(env, "_i2c_write_device"), Function::New(env, _i2cWriteDevice));
exports.Set(String::New(env, "_i2c_read_device"), Function::New(env, _i2cReadDevice));
return exports;
}

23
main.js
View File

@ -60,7 +60,7 @@ const toggleCheck_i2c = checked_id => {
}
const toggleCheck_lang = checked_id => {
const menus = ['js-pigpio', 'js-rgpio', 'py'];
const menus = ['js', 'py'];
menus.forEach(id => {
menu.getMenuItemById(id).checked = (id == checked_id);
})
@ -159,28 +159,15 @@ let template = [
label: "Language",
submenu: [
{
label: "JavaScript (pigpio)",
id: "js-pigpio",
label: "JavaScript",
id: "js",
type: 'checkbox',
checked: true,
click: (item, focusedWindow) => {
if (focusedWindow) {
// menu.getMenuItemById('py').checked = false;
toggleCheck_lang("js-pigpio");
focusedWindow.webContents.executeJavaScript('apptool.setLang("js-pigpio")');
}
}
},
{
label: "JavaScript (rgpio)",
id: "js-rgpio",
type: 'checkbox',
checked: true,
click: (item, focusedWindow) => {
if (focusedWindow) {
// menu.getMenuItemById('py').checked = false;
toggleCheck_lang("js-rgpio");
focusedWindow.webContents.executeJavaScript('apptool.setLang("js-rgpio")');
toggleCheck_lang("js");
focusedWindow.webContents.executeJavaScript('apptool.setLang("js")');
}
}
},

288
package-lock.json generated
View File

@ -9,25 +9,25 @@
"version": "0.1.11",
"license": "ISC",
"dependencies": {
"@blockly/field-slider": "^4.0.12",
"@blockly/field-slider": "^4.0.15",
"@tensorflow-models/blazeface": "^0.0.7",
"@tensorflow-models/knn-classifier": "^1.2.4",
"@tensorflow-models/mobilenet": "^2.1.0",
"@tensorflow-models/speech-commands": "^0.5.4",
"@tensorflow/tfjs-node": "^4.4.0",
"axios": "^1.3.5",
"blockly": "^9.3.2",
"@tensorflow/tfjs-node": "^4.5.0",
"axios": "^1.4.0",
"blockly": "^9.3.3",
"dracula-prism": "^2.1.13",
"js-beautify": "^1.14.7",
"node-abi": "^3.35.0",
"node-abi": "^3.40.0",
"nodemailer": "^6.9.1",
"prismjs": "^1.29.0"
},
"devDependencies": {
"@electron-forge/cli": "^6.1.1",
"@electron-forge/maker-deb": "^6.1.1",
"@electron/rebuild": "^3.2.10",
"electron": "^24.0.0"
"@electron/rebuild": "^3.2.13",
"electron": "^24.2.0"
},
"optionalDependencies": {
"@ocoge.club/pigpio": "file:local_modules/pigpio",
@ -35,14 +35,14 @@
}
},
"node_modules/@blockly/field-slider": {
"version": "4.0.12",
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.12.tgz",
"integrity": "sha512-Mw6O8eQ225WURiz5Y3kldOMlbkoPSliTyJM7E20zEAFS6Ww6DFmfBI32UBUx8HeqdAAvIEottXERvGd3ONdE8g==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.15.tgz",
"integrity": "sha512-8U1nzWXKMSs0g3r5GD5i1DEWutIJOdTMhQn5kjD0a0447ZlA81d9gePdQuV+puTaesFDGWPcVBvuo4FQhJ2Y5w==",
"engines": {
"node": ">=8.0.0"
},
"peerDependencies": {
"blockly": "^9.2.0"
"blockly": "^9.3.1"
}
},
"node_modules/@electron-forge/cli": {
@ -423,9 +423,9 @@
}
},
"node_modules/@electron/rebuild": {
"version": "3.2.10",
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz",
"integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==",
"version": "3.2.13",
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.13.tgz",
"integrity": "sha512-DH9Ol4JCnHDYVOD0fKWq+Qqbn/0WU1O6QR0mIpMXEVU4YFM4PlaqNC9K36mGShNBxxGFotZCMDrB1wl/iHM12g==",
"dev": true,
"dependencies": {
"@malept/cross-spawn-promise": "^2.0.0",
@ -434,7 +434,6 @@
"detect-libc": "^2.0.1",
"fs-extra": "^10.0.0",
"got": "^11.7.0",
"lzma-native": "^8.0.5",
"node-abi": "^3.0.0",
"node-api-version": "^0.1.4",
"node-gyp": "^9.0.0",
@ -444,7 +443,7 @@
"yargs": "^17.0.1"
},
"bin": {
"electron-rebuild": "lib/src/cli.js"
"electron-rebuild": "lib/cli.js"
},
"engines": {
"node": ">=12.13.0"
@ -762,16 +761,16 @@
}
},
"node_modules/@tensorflow/tfjs": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.4.0.tgz",
"integrity": "sha512-EmCsnzdvawyk4b+4JKaLLuicHcJQRZtL1zSy9AWJLiiHTbDDseYgLxfaCEfLk8v2bUe7SBXwl3n3B7OjgvH11Q==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.5.0.tgz",
"integrity": "sha512-GMpFI9GgotUSQKpce500yyBujYY8sWagG0gCpnjTSVzWrYRS8bsL+6Fq/GCamiCX5jtOrlpZ/kRkz/HIqaYXWg==",
"dependencies": {
"@tensorflow/tfjs-backend-cpu": "4.4.0",
"@tensorflow/tfjs-backend-webgl": "4.4.0",
"@tensorflow/tfjs-converter": "4.4.0",
"@tensorflow/tfjs-core": "4.4.0",
"@tensorflow/tfjs-data": "4.4.0",
"@tensorflow/tfjs-layers": "4.4.0",
"@tensorflow/tfjs-backend-cpu": "4.5.0",
"@tensorflow/tfjs-backend-webgl": "4.5.0",
"@tensorflow/tfjs-converter": "4.5.0",
"@tensorflow/tfjs-core": "4.5.0",
"@tensorflow/tfjs-data": "4.5.0",
"@tensorflow/tfjs-layers": "4.5.0",
"argparse": "^1.0.10",
"chalk": "^4.1.0",
"core-js": "3.29.1",
@ -783,9 +782,9 @@
}
},
"node_modules/@tensorflow/tfjs-backend-cpu": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.4.0.tgz",
"integrity": "sha512-d4eln500/qNym78z9IrUUzF0ITBoJGLrxV8xd92kLVoXhg35Mm+zqUXShjFcrH8joOHOFuST0qZ0TbDDqcPzPA==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.5.0.tgz",
"integrity": "sha512-TO6tkGeqR0UhifEx2SBa15kv8UlpubCHPGFHAnAfiPqBe3Z+3D7zqMlw2RvOelrzxzCWpTQByppFkB5u1pfiiA==",
"dependencies": {
"@types/seedrandom": "^2.4.28",
"seedrandom": "^3.0.5"
@ -794,15 +793,15 @@
"yarn": ">= 1.3.2"
},
"peerDependencies": {
"@tensorflow/tfjs-core": "4.4.0"
"@tensorflow/tfjs-core": "4.5.0"
}
},
"node_modules/@tensorflow/tfjs-backend-webgl": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.4.0.tgz",
"integrity": "sha512-TzQKvfAPgGt9cMG+5bVoTckoG1xr/PVJM/uODkPvzcMqi3j97kuWDXwkYJIgXldStmfiKkU7f5CmyD3Cq3E6BA==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.5.0.tgz",
"integrity": "sha512-xBgb3GW9wPbKRKeL8k0hxhyZv21uPnZ1eEXgwnpfgu86rXajToA7ATklh7bCpOlrQDY/n7ixBA8PwvsQEt2Jcw==",
"dependencies": {
"@tensorflow/tfjs-backend-cpu": "4.4.0",
"@tensorflow/tfjs-backend-cpu": "4.5.0",
"@types/offscreencanvas": "~2019.3.0",
"@types/seedrandom": "^2.4.28",
"@types/webgl-ext": "0.0.30",
@ -812,21 +811,21 @@
"yarn": ">= 1.3.2"
},
"peerDependencies": {
"@tensorflow/tfjs-core": "4.4.0"
"@tensorflow/tfjs-core": "4.5.0"
}
},
"node_modules/@tensorflow/tfjs-converter": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.4.0.tgz",
"integrity": "sha512-JUjpRStrAuw37tgPd5UENu0UjQVuJT09yF7KpOur4BriJ0uQqrbEZHMPHmvUtr5nYzkqlXJTuXIyxvEY/olNpg==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.5.0.tgz",
"integrity": "sha512-gd2DiLPX1YStXk4mkgqzbQuOoiwcuSv4s7tTyYvFEX5Ty9SKmttYmannCCppzmliL6aTzyxTpIZyWnqTPuTxeg==",
"peerDependencies": {
"@tensorflow/tfjs-core": "4.4.0"
"@tensorflow/tfjs-core": "4.5.0"
}
},
"node_modules/@tensorflow/tfjs-core": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.4.0.tgz",
"integrity": "sha512-Anxpc7cAOA0Q7EUXdTbQKMg3reFvrdkgDlaYzH9ZfkMq2CgLV4Au6E/s6HmbYn/VrAtWy9mLY5c/lLJqh4764g==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.5.0.tgz",
"integrity": "sha512-FrHUnab/5msyzIg7zcjBmMV8W9vf2lj+f4em0zL+ntAczkEBeMAEIykk9BmV7sqMplRiCu2Cfrks8EqHFutSqw==",
"dependencies": {
"@types/long": "^4.0.1",
"@types/offscreencanvas": "~2019.7.0",
@ -847,35 +846,35 @@
"integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg=="
},
"node_modules/@tensorflow/tfjs-data": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.4.0.tgz",
"integrity": "sha512-aY4eq4cgrsrXeBU6ABZAAN3tV0fG4YcHd0z+cYuNXnCo+VEQLJnPmhn+xymZ4VQZQH4GXbVS4dV9pXMclFNRFw==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.5.0.tgz",
"integrity": "sha512-fqTS5K+TrdisyDOOjcKwYQtoGyk9GzYhxwof1X9kpdm2zxpwl0kzeSqqCuVMPGD5DAOKp+EccTWYfAC4MIafcw==",
"dependencies": {
"@types/node-fetch": "^2.1.2",
"node-fetch": "~2.6.1",
"string_decoder": "^1.3.0"
},
"peerDependencies": {
"@tensorflow/tfjs-core": "4.4.0",
"@tensorflow/tfjs-core": "4.5.0",
"seedrandom": "^3.0.5"
}
},
"node_modules/@tensorflow/tfjs-layers": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.4.0.tgz",
"integrity": "sha512-OGC7shfiD9Gc698hINHK4y9slOJvu5m54tVNm4xf+WSNrw/avvgpar6yyoL5bakYIZNQvFNK75Yr8VRPR7oPeQ==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.5.0.tgz",
"integrity": "sha512-/Ohzc39SiIszQqOjEb+4DzGyJkdCweGP4uoblUzQQZdolJB/NxsAHJ06YUj0mD5dflTwNVCwYAe3rkdYqNlgvg==",
"peerDependencies": {
"@tensorflow/tfjs-core": "4.4.0"
"@tensorflow/tfjs-core": "4.5.0"
}
},
"node_modules/@tensorflow/tfjs-node": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-4.4.0.tgz",
"integrity": "sha512-+JSAddsupjSQUDZeb7QGOFkL3Tty3kjPHx8ethiYFzwTZJHCMvM7wZJd0Fqnjxym6A0KpsmB7SPZgwRRXVIlPA==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-4.5.0.tgz",
"integrity": "sha512-KX1Vl9G6kqOvt9WIQhb54S3H9qx8K+rMaOoyy2LMytcUU5hbcOi8ElGju4BGM4xSCrYFtJI3hBsl+Xfgd2hAKg==",
"hasInstallScript": true,
"dependencies": {
"@mapbox/node-pre-gyp": "1.0.9",
"@tensorflow/tfjs": "4.4.0",
"@tensorflow/tfjs": "4.5.0",
"adm-zip": "^0.5.2",
"google-protobuf": "^3.9.2",
"https-proxy-agent": "^2.2.1",
@ -1318,9 +1317,9 @@
}
},
"node_modules/axios": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz",
"integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==",
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
@ -1386,9 +1385,9 @@
}
},
"node_modules/blockly": {
"version": "9.3.2",
"resolved": "https://registry.npmjs.org/blockly/-/blockly-9.3.2.tgz",
"integrity": "sha512-VbdvG7AWOJvbUaUAvia/hXhoIE1vznRAWrh4Tz3xDYJICP7KzKHJcS/Q7OF0JuX60rpo8SJ59XPZ6WnqENqLqA==",
"version": "9.3.3",
"resolved": "https://registry.npmjs.org/blockly/-/blockly-9.3.3.tgz",
"integrity": "sha512-L7LlrGXICEN+UaZsYq3Iz2/SF8uF2ks90ozwVXTkpueCpuo/Xt9eu4Skci6b1JUL7alMPPgt+AxIuq+2/p99Cg==",
"dependencies": {
"jsdom": "21.1.1"
}
@ -2132,9 +2131,9 @@
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
},
"node_modules/electron": {
"version": "24.0.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-24.0.0.tgz",
"integrity": "sha512-QmL8L53fQ+xOAp8m2mSGNewhDvJqQttCxrcesf0cqndKQDsIq4QvR35wGJqHg7MyPQKcBErLhZj9QvRheO5qnA==",
"version": "24.2.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-24.2.0.tgz",
"integrity": "sha512-fEYAftYqFhveniWJbEHXjNMWjooFFIuqNj/eEFJkGzycInfBJq/c4E/dew++s6s0YLubxFnjoF2qZiqapLj0gA==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@ -3997,24 +3996,6 @@
"node": ">=12"
}
},
"node_modules/lzma-native": {
"version": "8.0.6",
"resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz",
"integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"node-addon-api": "^3.1.0",
"node-gyp-build": "^4.2.1",
"readable-stream": "^3.6.0"
},
"bin": {
"lzmajs": "bin/lzmajs"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@ -4326,9 +4307,9 @@
"dev": true
},
"node_modules/node-abi": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.35.0.tgz",
"integrity": "sha512-jAlSOFR1Bls963NmFwxeQkNTzqjUF0NThm8Le7eRIRGzFUVJuMOFZDLv5Y30W/Oaw+KEebEJLAigwO9gQHoEmw==",
"version": "3.40.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.40.0.tgz",
"integrity": "sha512-zNy02qivjjRosswoYmPi8hIKJRr8MpQyeKT6qlcq/OnOgA3Rhoae+IYOqsM9V5+JnHWmxKnWOT2GxvtqdtOCXA==",
"dependencies": {
"semver": "^7.3.5"
},
@ -4336,12 +4317,6 @@
"node": ">=10"
}
},
"node_modules/node-addon-api": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
"dev": true
},
"node_modules/node-api-version": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz",
@ -4413,17 +4388,6 @@
"node": "^12.13 || ^14.13 || >=16"
}
},
"node_modules/node-gyp-build": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz",
"integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==",
"dev": true,
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/node-gyp/node_modules/are-we-there-yet": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
@ -6340,9 +6304,9 @@
},
"dependencies": {
"@blockly/field-slider": {
"version": "4.0.12",
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.12.tgz",
"integrity": "sha512-Mw6O8eQ225WURiz5Y3kldOMlbkoPSliTyJM7E20zEAFS6Ww6DFmfBI32UBUx8HeqdAAvIEottXERvGd3ONdE8g=="
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@blockly/field-slider/-/field-slider-4.0.15.tgz",
"integrity": "sha512-8U1nzWXKMSs0g3r5GD5i1DEWutIJOdTMhQn5kjD0a0447ZlA81d9gePdQuV+puTaesFDGWPcVBvuo4FQhJ2Y5w=="
},
"@electron-forge/cli": {
"version": "6.1.1",
@ -6627,9 +6591,9 @@
}
},
"@electron/rebuild": {
"version": "3.2.10",
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz",
"integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==",
"version": "3.2.13",
"resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.13.tgz",
"integrity": "sha512-DH9Ol4JCnHDYVOD0fKWq+Qqbn/0WU1O6QR0mIpMXEVU4YFM4PlaqNC9K36mGShNBxxGFotZCMDrB1wl/iHM12g==",
"dev": true,
"requires": {
"@malept/cross-spawn-promise": "^2.0.0",
@ -6638,7 +6602,6 @@
"detect-libc": "^2.0.1",
"fs-extra": "^10.0.0",
"got": "^11.7.0",
"lzma-native": "^8.0.5",
"node-abi": "^3.0.0",
"node-api-version": "^0.1.4",
"node-gyp": "^9.0.0",
@ -6869,16 +6832,16 @@
"integrity": "sha512-r0c/MvC15/09xWujx1pKe6mA0nta+4jQWDXGkqfSVkXLo8ARrwcZ4mTGLlfvT43ySfidiveUo0m+P51+UK821Q=="
},
"@tensorflow/tfjs": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.4.0.tgz",
"integrity": "sha512-EmCsnzdvawyk4b+4JKaLLuicHcJQRZtL1zSy9AWJLiiHTbDDseYgLxfaCEfLk8v2bUe7SBXwl3n3B7OjgvH11Q==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.5.0.tgz",
"integrity": "sha512-GMpFI9GgotUSQKpce500yyBujYY8sWagG0gCpnjTSVzWrYRS8bsL+6Fq/GCamiCX5jtOrlpZ/kRkz/HIqaYXWg==",
"requires": {
"@tensorflow/tfjs-backend-cpu": "4.4.0",
"@tensorflow/tfjs-backend-webgl": "4.4.0",
"@tensorflow/tfjs-converter": "4.4.0",
"@tensorflow/tfjs-core": "4.4.0",
"@tensorflow/tfjs-data": "4.4.0",
"@tensorflow/tfjs-layers": "4.4.0",
"@tensorflow/tfjs-backend-cpu": "4.5.0",
"@tensorflow/tfjs-backend-webgl": "4.5.0",
"@tensorflow/tfjs-converter": "4.5.0",
"@tensorflow/tfjs-core": "4.5.0",
"@tensorflow/tfjs-data": "4.5.0",
"@tensorflow/tfjs-layers": "4.5.0",
"argparse": "^1.0.10",
"chalk": "^4.1.0",
"core-js": "3.29.1",
@ -6918,20 +6881,20 @@
}
},
"@tensorflow/tfjs-backend-cpu": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.4.0.tgz",
"integrity": "sha512-d4eln500/qNym78z9IrUUzF0ITBoJGLrxV8xd92kLVoXhg35Mm+zqUXShjFcrH8joOHOFuST0qZ0TbDDqcPzPA==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.5.0.tgz",
"integrity": "sha512-TO6tkGeqR0UhifEx2SBa15kv8UlpubCHPGFHAnAfiPqBe3Z+3D7zqMlw2RvOelrzxzCWpTQByppFkB5u1pfiiA==",
"requires": {
"@types/seedrandom": "^2.4.28",
"seedrandom": "^3.0.5"
}
},
"@tensorflow/tfjs-backend-webgl": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.4.0.tgz",
"integrity": "sha512-TzQKvfAPgGt9cMG+5bVoTckoG1xr/PVJM/uODkPvzcMqi3j97kuWDXwkYJIgXldStmfiKkU7f5CmyD3Cq3E6BA==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.5.0.tgz",
"integrity": "sha512-xBgb3GW9wPbKRKeL8k0hxhyZv21uPnZ1eEXgwnpfgu86rXajToA7ATklh7bCpOlrQDY/n7ixBA8PwvsQEt2Jcw==",
"requires": {
"@tensorflow/tfjs-backend-cpu": "4.4.0",
"@tensorflow/tfjs-backend-cpu": "4.5.0",
"@types/offscreencanvas": "~2019.3.0",
"@types/seedrandom": "^2.4.28",
"@types/webgl-ext": "0.0.30",
@ -6939,14 +6902,14 @@
}
},
"@tensorflow/tfjs-converter": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.4.0.tgz",
"integrity": "sha512-JUjpRStrAuw37tgPd5UENu0UjQVuJT09yF7KpOur4BriJ0uQqrbEZHMPHmvUtr5nYzkqlXJTuXIyxvEY/olNpg=="
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.5.0.tgz",
"integrity": "sha512-gd2DiLPX1YStXk4mkgqzbQuOoiwcuSv4s7tTyYvFEX5Ty9SKmttYmannCCppzmliL6aTzyxTpIZyWnqTPuTxeg=="
},
"@tensorflow/tfjs-core": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.4.0.tgz",
"integrity": "sha512-Anxpc7cAOA0Q7EUXdTbQKMg3reFvrdkgDlaYzH9ZfkMq2CgLV4Au6E/s6HmbYn/VrAtWy9mLY5c/lLJqh4764g==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.5.0.tgz",
"integrity": "sha512-FrHUnab/5msyzIg7zcjBmMV8W9vf2lj+f4em0zL+ntAczkEBeMAEIykk9BmV7sqMplRiCu2Cfrks8EqHFutSqw==",
"requires": {
"@types/long": "^4.0.1",
"@types/offscreencanvas": "~2019.7.0",
@ -6966,9 +6929,9 @@
}
},
"@tensorflow/tfjs-data": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.4.0.tgz",
"integrity": "sha512-aY4eq4cgrsrXeBU6ABZAAN3tV0fG4YcHd0z+cYuNXnCo+VEQLJnPmhn+xymZ4VQZQH4GXbVS4dV9pXMclFNRFw==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.5.0.tgz",
"integrity": "sha512-fqTS5K+TrdisyDOOjcKwYQtoGyk9GzYhxwof1X9kpdm2zxpwl0kzeSqqCuVMPGD5DAOKp+EccTWYfAC4MIafcw==",
"requires": {
"@types/node-fetch": "^2.1.2",
"node-fetch": "~2.6.1",
@ -6976,17 +6939,17 @@
}
},
"@tensorflow/tfjs-layers": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.4.0.tgz",
"integrity": "sha512-OGC7shfiD9Gc698hINHK4y9slOJvu5m54tVNm4xf+WSNrw/avvgpar6yyoL5bakYIZNQvFNK75Yr8VRPR7oPeQ=="
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.5.0.tgz",
"integrity": "sha512-/Ohzc39SiIszQqOjEb+4DzGyJkdCweGP4uoblUzQQZdolJB/NxsAHJ06YUj0mD5dflTwNVCwYAe3rkdYqNlgvg=="
},
"@tensorflow/tfjs-node": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-4.4.0.tgz",
"integrity": "sha512-+JSAddsupjSQUDZeb7QGOFkL3Tty3kjPHx8ethiYFzwTZJHCMvM7wZJd0Fqnjxym6A0KpsmB7SPZgwRRXVIlPA==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-4.5.0.tgz",
"integrity": "sha512-KX1Vl9G6kqOvt9WIQhb54S3H9qx8K+rMaOoyy2LMytcUU5hbcOi8ElGju4BGM4xSCrYFtJI3hBsl+Xfgd2hAKg==",
"requires": {
"@mapbox/node-pre-gyp": "1.0.9",
"@tensorflow/tfjs": "4.4.0",
"@tensorflow/tfjs": "4.5.0",
"adm-zip": "^0.5.2",
"google-protobuf": "^3.9.2",
"https-proxy-agent": "^2.2.1",
@ -7326,9 +7289,9 @@
"dev": true
},
"axios": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz",
"integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==",
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
@ -7379,9 +7342,9 @@
}
},
"blockly": {
"version": "9.3.2",
"resolved": "https://registry.npmjs.org/blockly/-/blockly-9.3.2.tgz",
"integrity": "sha512-VbdvG7AWOJvbUaUAvia/hXhoIE1vznRAWrh4Tz3xDYJICP7KzKHJcS/Q7OF0JuX60rpo8SJ59XPZ6WnqENqLqA==",
"version": "9.3.3",
"resolved": "https://registry.npmjs.org/blockly/-/blockly-9.3.3.tgz",
"integrity": "sha512-L7LlrGXICEN+UaZsYq3Iz2/SF8uF2ks90ozwVXTkpueCpuo/Xt9eu4Skci6b1JUL7alMPPgt+AxIuq+2/p99Cg==",
"requires": {
"jsdom": "21.1.1"
}
@ -7929,9 +7892,9 @@
}
},
"electron": {
"version": "24.0.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-24.0.0.tgz",
"integrity": "sha512-QmL8L53fQ+xOAp8m2mSGNewhDvJqQttCxrcesf0cqndKQDsIq4QvR35wGJqHg7MyPQKcBErLhZj9QvRheO5qnA==",
"version": "24.2.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-24.2.0.tgz",
"integrity": "sha512-fEYAftYqFhveniWJbEHXjNMWjooFFIuqNj/eEFJkGzycInfBJq/c4E/dew++s6s0YLubxFnjoF2qZiqapLj0gA==",
"dev": true,
"requires": {
"@electron/get": "^2.0.0",
@ -9338,17 +9301,6 @@
"integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==",
"dev": true
},
"lzma-native": {
"version": "8.0.6",
"resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz",
"integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==",
"dev": true,
"requires": {
"node-addon-api": "^3.1.0",
"node-gyp-build": "^4.2.1",
"readable-stream": "^3.6.0"
}
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@ -9581,19 +9533,13 @@
"dev": true
},
"node-abi": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.35.0.tgz",
"integrity": "sha512-jAlSOFR1Bls963NmFwxeQkNTzqjUF0NThm8Le7eRIRGzFUVJuMOFZDLv5Y30W/Oaw+KEebEJLAigwO9gQHoEmw==",
"version": "3.40.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.40.0.tgz",
"integrity": "sha512-zNy02qivjjRosswoYmPi8hIKJRr8MpQyeKT6qlcq/OnOgA3Rhoae+IYOqsM9V5+JnHWmxKnWOT2GxvtqdtOCXA==",
"requires": {
"semver": "^7.3.5"
}
},
"node-addon-api": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz",
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
"dev": true
},
"node-api-version": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz",
@ -9708,12 +9654,6 @@
}
}
},
"node-gyp-build": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz",
"integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==",
"dev": true
},
"nodemailer": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.1.tgz",

View File

@ -24,21 +24,21 @@
"devDependencies": {
"@electron-forge/cli": "^6.1.1",
"@electron-forge/maker-deb": "^6.1.1",
"@electron/rebuild": "^3.2.10",
"electron": "^24.0.0"
"@electron/rebuild": "^3.2.13",
"electron": "^24.2.0"
},
"dependencies": {
"@blockly/field-slider": "^4.0.12",
"@blockly/field-slider": "^4.0.15",
"@tensorflow-models/blazeface": "^0.0.7",
"@tensorflow-models/knn-classifier": "^1.2.4",
"@tensorflow-models/mobilenet": "^2.1.0",
"@tensorflow-models/speech-commands": "^0.5.4",
"@tensorflow/tfjs-node": "^4.4.0",
"axios": "^1.3.5",
"blockly": "^9.3.2",
"@tensorflow/tfjs-node": "^4.5.0",
"axios": "^1.4.0",
"blockly": "^9.3.3",
"dracula-prism": "^2.1.13",
"js-beautify": "^1.14.7",
"node-abi": "^3.35.0",
"node-abi": "^3.40.0",
"nodemailer": "^6.9.1",
"prismjs": "^1.29.0"
},