Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
223ebff543
|
|||
15f8c57cea
|
|||
3136d217d8
|
|||
229c69e203
|
|||
641bd83207
|
|||
e9fbd20f46
|
|||
a85d5767b0 | |||
162a2cc733
|
|||
fdae6d29e9
|
|||
90a8526394
|
|||
34f6beeec7
|
|||
a24b03d299
|
|||
c5f71f6976
|
|||
2a84b7f4fd
|
|||
cca1e1bee9
|
|||
b69e557e33
|
21
.eslintrc
Normal file
21
.eslintrc
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"rules": {
|
||||
"comma-dangle": 0,
|
||||
"indent": [2, 4],
|
||||
"max-len": "off",
|
||||
"radix": [2, "as-needed"],
|
||||
"no-console": 0,
|
||||
"linebreak-style": "off",
|
||||
"prettier/prettier": 0,
|
||||
"quotes": ["error", "single"],
|
||||
"jsdoc/require-jsdoc": 0
|
||||
},
|
||||
"settings": {
|
||||
"import/core-modules": [ "node_helper" ]
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"es6": true
|
||||
}
|
||||
}
|
29
.github/workflows/nodejs.yml
vendored
Normal file
29
.github/workflows/nodejs.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: Node.js CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x, 14.x, 16.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run build --if-present
|
||||
- run: npm run lint
|
8
.markdownlint.json
Normal file
8
.markdownlint.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"default": true,
|
||||
"no-duplicate-header": {
|
||||
"siblings_only": true
|
||||
},
|
||||
"line-length": false,
|
||||
"no-inline-html": false
|
||||
}
|
32
CHANGELOG.md
32
CHANGELOG.md
@ -1,28 +1,56 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.1.1] - 2020-03-07
|
||||
## [1.2.0] - 2021-10-13
|
||||
|
||||
### Added
|
||||
|
||||
- Can optionally display pH tank level alongside raw pH value now (on by default).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Better font size scaling with newer MagicMirror versions.
|
||||
|
||||
## [1.1.2] - 2020-04-08
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed which property was being read to determine whether heat mode was enabled or not. Previously the state of the heater itself was being used to display on/off status, now the requested mode is used instead (the heater toggles on/off as part of normal operation even while heating is enabled).
|
||||
|
||||
## [1.1.1] - 2020-04-07
|
||||
|
||||
### Added
|
||||
|
||||
- Ability to specify which heat mode to use when enabling heating for a specific body. Previously mode 1 was always sent which means "solar" while most people probably want mode 3 which is "heat pump".
|
||||
|
||||
## [1.1.0] - 2020-03-01
|
||||
## [1.1.0] - 2020-04-01
|
||||
|
||||
### Added
|
||||
|
||||
- Ability to show buttons for controlling pool equipment (with a touch screen, for example). NOTE: running `npm install` again is necessary after upgrading to this version if the heat controls are used.
|
||||
|
||||
## [1.0.3] - 2018-04-27
|
||||
|
||||
### Changed
|
||||
|
||||
- Packaged a newer `node-screenlogic` dependency to fix server broadcast in certain environments.
|
||||
|
||||
## [1.0.2] - 2018-04-26
|
||||
|
||||
### Added
|
||||
|
||||
- New option `updateInterval` to control how often the pool data is updated (default 30 minutes).
|
||||
|
||||
## [1.0.1] - 2018-04-25
|
||||
|
||||
### Added
|
||||
|
||||
- New option `showFreezeMode` shows a banner acrosss the top if the pool is currently in freeze-protection mode.
|
||||
|
||||
## [1.0.0] - 2018-04-24
|
||||
|
||||
- Initial release.
|
||||
|
@ -1,288 +1,311 @@
|
||||
poolData = {};
|
||||
var moduleObj;
|
||||
let poolData = {};
|
||||
let moduleObj;
|
||||
|
||||
Module.register("MMM-ScreenLogic",{
|
||||
defaults: {
|
||||
showPoolTemp: true,
|
||||
showSpaTemp: true,
|
||||
showPH: true,
|
||||
showOrp: true,
|
||||
showSaltLevel: true,
|
||||
showSaturation: true,
|
||||
showFreezeMode: true,
|
||||
showControls: false,
|
||||
controls: [],
|
||||
colored: true,
|
||||
coldTemp: 84,
|
||||
hotTemp: 90,
|
||||
columns: 3,
|
||||
contentClass: "light",
|
||||
updateInterval: 30 * 60 * 1000
|
||||
},
|
||||
Module.register('MMM-ScreenLogic',{
|
||||
defaults: {
|
||||
showPoolTemp: true,
|
||||
showSpaTemp: true,
|
||||
showPH: true,
|
||||
showOrp: true,
|
||||
showSaltLevel: true,
|
||||
showSaturation: true,
|
||||
showFreezeMode: true,
|
||||
showControls: false,
|
||||
controls: [],
|
||||
colored: true,
|
||||
coldTemp: 84,
|
||||
hotTemp: 90,
|
||||
columns: 3,
|
||||
contentClass: 'light',
|
||||
updateInterval: 30 * 60 * 1000,
|
||||
showPHTankLevel: true,
|
||||
pHTankLevelMax: 6
|
||||
},
|
||||
|
||||
start: function() {
|
||||
// this isn't a great solution...is there a better one? needed to do stuff with buttons
|
||||
moduleObj = this;
|
||||
if (this.config.showControls && (!this.config.controls || this.config.controls.length == 0)) {
|
||||
Log.warn('Controls are enabled, but no controls are configured. See README for info on setting up controls.');
|
||||
this.config.showControls = false;
|
||||
}
|
||||
start: function() {
|
||||
// this isn't a great solution...is there a better one? needed to do stuff with buttons
|
||||
moduleObj = this;
|
||||
if (this.config.showControls && (!this.config.controls || this.config.controls.length === 0)) {
|
||||
Log.warn('Controls are enabled, but no controls are configured. See README for info on setting up controls.');
|
||||
this.config.showControls = false;
|
||||
}
|
||||
|
||||
this.sendSocketNotification('SCREENLOGIC_CONFIG', this.config);
|
||||
this.sendSocketNotification('SCREENLOGIC_UPDATE');
|
||||
},
|
||||
this.sendSocketNotification('SCREENLOGIC_CONFIG', this.config);
|
||||
this.sendSocketNotification('SCREENLOGIC_UPDATE');
|
||||
},
|
||||
|
||||
getStyles: function() {
|
||||
return ["screenlogic.css"];
|
||||
},
|
||||
getStyles: function() {
|
||||
return ['screenlogic.css'];
|
||||
},
|
||||
|
||||
getDom: function() {
|
||||
if (!poolData.status) {
|
||||
var wrapper = document.createElement("div");
|
||||
wrapper.innerHTML = 'Loading...';
|
||||
wrapper.className += "dimmed light small";
|
||||
getDom: function() {
|
||||
if (!poolData.status) {
|
||||
let wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = 'Loading...';
|
||||
wrapper.className += 'dimmed light small';
|
||||
|
||||
return wrapper;
|
||||
} else {
|
||||
var table = document.createElement('table');
|
||||
table.className = "small";
|
||||
if (this.config.colored) {
|
||||
table.className += " colored";
|
||||
}
|
||||
return wrapper;
|
||||
} else {
|
||||
let table = document.createElement('table');
|
||||
table.className = 'small';
|
||||
if (this.config.colored) {
|
||||
table.className += ' colored';
|
||||
}
|
||||
|
||||
var contents = [];
|
||||
let contents = [];
|
||||
|
||||
if (this.config.showPoolTemp) {
|
||||
var className = "";
|
||||
if (poolData.status.currentTemp[0] <= this.config.coldTemp) {
|
||||
className += " cold-temp";
|
||||
} else if (poolData.status.currentTemp[0] >= this.config.hotTemp) {
|
||||
className += " hot-temp";
|
||||
}
|
||||
if (this.config.showPoolTemp) {
|
||||
let className = '';
|
||||
if (poolData.status.currentTemp[0] <= this.config.coldTemp) {
|
||||
className += ' cold-temp';
|
||||
} else if (poolData.status.currentTemp[0] >= this.config.hotTemp) {
|
||||
className += ' hot-temp';
|
||||
}
|
||||
|
||||
contents.push({
|
||||
header: "Pool temp",
|
||||
data: poolData.status.currentTemp[0] + "°" + (!isPoolActive(poolData.status) ? " (last)" : ""),
|
||||
class: this.config.contentClass + className
|
||||
});
|
||||
}
|
||||
if (this.config.showSpaTemp) {
|
||||
var className = "";
|
||||
if (poolData.status.currentTemp[1] <= this.config.coldTemp) {
|
||||
className = " cold-temp";
|
||||
} else if (poolData.status.currentTemp[1] >= this.config.hotTemp) {
|
||||
className = " hot-temp";
|
||||
}
|
||||
contents.push({
|
||||
header: 'Pool temp',
|
||||
data: poolData.status.currentTemp[0] + '°' + (!isPoolActive(poolData.status) ? ' (last)' : ''),
|
||||
class: this.config.contentClass + className
|
||||
});
|
||||
}
|
||||
if (this.config.showSpaTemp) {
|
||||
let className = '';
|
||||
if (poolData.status.currentTemp[1] <= this.config.coldTemp) {
|
||||
className = ' cold-temp';
|
||||
} else if (poolData.status.currentTemp[1] >= this.config.hotTemp) {
|
||||
className = ' hot-temp';
|
||||
}
|
||||
|
||||
contents.push({
|
||||
header: "Spa temp",
|
||||
data: poolData.status.currentTemp[1] + "°" + (!isSpaActive(poolData.status) ? " (last)" : ""),
|
||||
class: this.config.contentClass + className
|
||||
});
|
||||
}
|
||||
if (this.config.showPH) {
|
||||
contents.push({
|
||||
header: "pH",
|
||||
data: poolData.status.pH,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
}
|
||||
if (this.config.showOrp) {
|
||||
contents.push({
|
||||
header: "ORP",
|
||||
data: poolData.status.orp,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
}
|
||||
if (this.config.showSaltLevel) {
|
||||
contents.push({
|
||||
header: "Salt PPM",
|
||||
data: poolData.status.saltPPM,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
}
|
||||
if (this.config.showSaturation) {
|
||||
contents.push({
|
||||
header: "Saturation",
|
||||
data: poolData.status.saturation,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
}
|
||||
if (this.config.showControls) {
|
||||
for (var control in this.config.controls) {
|
||||
var controlObj = this.config.controls[control];
|
||||
contents.push({
|
||||
header: 'Spa temp',
|
||||
data: poolData.status.currentTemp[1] + '°' + (!isSpaActive(poolData.status) ? ' (last)' : ''),
|
||||
class: this.config.contentClass + className
|
||||
});
|
||||
}
|
||||
if (this.config.showPH) {
|
||||
let dataStr = poolData.status.pH
|
||||
if (this.config.showPHTankLevel) {
|
||||
let percent = Math.round(((poolData.status.pHTank - 1) / this.config.pHTankLevelMax) * 100)
|
||||
let cls = ''
|
||||
if (this.config.colored) {
|
||||
if (percent <= 50 && percent > 33) {
|
||||
cls = 'progress-bar-warning'
|
||||
} else if (percent <= 33) {
|
||||
cls = 'progress-bar-danger'
|
||||
} else {
|
||||
cls = 'progress-bar-success'
|
||||
}
|
||||
}
|
||||
let progBarDiv = `<div class="progress vertical">
|
||||
<div class="progress-bar ${cls}" role="progressbar" aria-valuenow="${percent}" aria-valuemin="0" aria-valuemax="100" style="width: ${percent}%;">
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
if (controlObj.type === 'circuit') {
|
||||
var name = controlObj.name;
|
||||
for (var circuit in poolData.controllerConfig.bodyArray) {
|
||||
if (poolData.controllerConfig.bodyArray[circuit].circuitId == controlObj.id) {
|
||||
if (!name) {
|
||||
name = poolData.controllerConfig.bodyArray[circuit].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
dataStr = `${dataStr} ${progBarDiv}`
|
||||
}
|
||||
|
||||
var on = false;
|
||||
for (var circuit in poolData.status.circuitArray) {
|
||||
if (poolData.status.circuitArray[circuit].id == controlObj.id) {
|
||||
on = poolData.status.circuitArray[circuit].state !== 0;
|
||||
}
|
||||
}
|
||||
contents.push({
|
||||
header: 'pH',
|
||||
data: dataStr,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
}
|
||||
if (this.config.showOrp) {
|
||||
contents.push({
|
||||
header: 'ORP',
|
||||
data: poolData.status.orp,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
}
|
||||
if (this.config.showSaltLevel) {
|
||||
contents.push({
|
||||
header: 'Salt PPM',
|
||||
data: poolData.status.saltPPM,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
}
|
||||
if (this.config.showSaturation) {
|
||||
contents.push({
|
||||
header: 'Saturation',
|
||||
data: poolData.status.saturation,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
}
|
||||
if (this.config.showControls) {
|
||||
for (let control in this.config.controls) {
|
||||
let controlObj = this.config.controls[control];
|
||||
|
||||
var cls = '';
|
||||
if (this.config.colored) {
|
||||
cls = on ? 'control-on' : 'control-off';
|
||||
}
|
||||
if (controlObj.type === 'circuit') {
|
||||
let name = controlObj.name;
|
||||
for (let circuit in poolData.controllerConfig.bodyArray) {
|
||||
if (poolData.controllerConfig.bodyArray[circuit].circuitId === controlObj.id) {
|
||||
if (!name) {
|
||||
name = poolData.controllerConfig.bodyArray[circuit].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contents.push({
|
||||
data: '<button id="sl-control-' + controlObj.id + '" class="control ' + cls + '" onclick="setCircuit(this)" data-circuit="' +
|
||||
let on = false;
|
||||
for (let circuit in poolData.status.circuitArray) {
|
||||
if (poolData.status.circuitArray[circuit].id === controlObj.id) {
|
||||
on = poolData.status.circuitArray[circuit].state !== 0;
|
||||
}
|
||||
}
|
||||
|
||||
let cls = '';
|
||||
if (this.config.colored) {
|
||||
cls = on ? 'control-on' : 'control-off';
|
||||
}
|
||||
|
||||
contents.push({
|
||||
data: '<button id="sl-control-' + controlObj.id + '" class="control ' + cls + '" onclick="setCircuit(this)" data-circuit="' +
|
||||
controlObj.id + '" data-state="' + (on ? '1' : '0') + '"><div class="content">' +
|
||||
name + '</div></button>',
|
||||
class: this.config.contentClass
|
||||
});
|
||||
} else if (controlObj.type === 'heatpoint') {
|
||||
if (controlObj.body < 0 || controlObj.body > poolData.status.setPoint.length) {
|
||||
Log.warn('Invalid body specified for heatpoint');
|
||||
continue;
|
||||
}
|
||||
class: this.config.contentClass
|
||||
});
|
||||
} else if (controlObj.type === 'heatpoint') {
|
||||
if (controlObj.body < 0 || controlObj.body > poolData.status.setPoint.length) {
|
||||
Log.warn('Invalid body specified for heatpoint');
|
||||
continue;
|
||||
}
|
||||
|
||||
var temperature = poolData.status.setPoint[controlObj.body];
|
||||
let temperature = poolData.status.setPoint[controlObj.body];
|
||||
|
||||
var dataHtml = '<div class="temperature-container">';
|
||||
dataHtml += '<button id="sl-temp-up-'+controlObj.body+'" class="temperature control-off" onclick="setHeatpoint(this, 1)" data-body="'+controlObj.body+'" data-temperature="'+temperature+'"><div class="content">+</div></button>';
|
||||
dataHtml += '<div class="temperature-label">'+controlObj.name+': '+temperature+'°</div>';
|
||||
dataHtml += '<button id="sl-temp-down-'+controlObj.body+'" class="temperature control-off" onclick="setHeatpoint(this, -1)" data-body="'+controlObj.body+'" data-temperature="'+temperature+'"><div class="content">-</div></button>';
|
||||
let dataHtml = '<div class="temperature-container">';
|
||||
dataHtml += '<button id="sl-temp-up-'+controlObj.body+'" class="temperature control-off" onclick="setHeatpoint(this, 1)" data-body="'+controlObj.body+'" data-temperature="'+temperature+'"><div class="content">+</div></button>';
|
||||
dataHtml += '<div class="temperature-label">'+controlObj.name+': '+temperature+'°</div>';
|
||||
dataHtml += '<button id="sl-temp-down-'+controlObj.body+'" class="temperature control-off" onclick="setHeatpoint(this, -1)" data-body="'+controlObj.body+'" data-temperature="'+temperature+'"><div class="content">-</div></button>';
|
||||
|
||||
contents.push({
|
||||
data: dataHtml,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
} else if (controlObj.type === 'heatmode') {
|
||||
if (controlObj.body < 0 || controlObj.body > poolData.status.heatStatus.length) {
|
||||
Log.warn('Invalid body specified for heatmode');
|
||||
continue;
|
||||
}
|
||||
contents.push({
|
||||
data: dataHtml,
|
||||
class: this.config.contentClass
|
||||
});
|
||||
} else if (controlObj.type === 'heatmode') {
|
||||
if (controlObj.body < 0 || controlObj.body > poolData.status.heatMode.length) {
|
||||
Log.warn('Invalid body specified for heatmode');
|
||||
continue;
|
||||
}
|
||||
|
||||
var on = poolData.status.heatStatus[controlObj.body] !== 0;
|
||||
var mode = typeof controlObj.heatMode === 'number' ? controlObj.heatMode : 3;
|
||||
let on = poolData.status.heatMode[controlObj.body] !== 0;
|
||||
let mode = typeof controlObj.heatMode === 'number' ? controlObj.heatMode : 3;
|
||||
|
||||
var cls = '';
|
||||
if (this.config.colored) {
|
||||
cls = on ? 'control-on' : 'control-off';
|
||||
}
|
||||
let cls = '';
|
||||
if (this.config.colored) {
|
||||
cls = on ? 'control-on' : 'control-off';
|
||||
}
|
||||
|
||||
contents.push({
|
||||
data: '<button id="sl-heat-' + controlObj.body + '" class="control ' + cls + '" onclick="setHeatmode(this)" data-body="' +
|
||||
contents.push({
|
||||
data: '<button id="sl-heat-' + controlObj.body + '" class="control ' + cls + '" onclick="setHeatmode(this)" data-body="' +
|
||||
controlObj.body + '" data-state="' + (on ? '1' : '0') + '" data-mode="' + mode.toString() + '"><div class="content">' +
|
||||
controlObj.name + '</div></button>',
|
||||
class: this.config.contentClass
|
||||
});
|
||||
} else {
|
||||
Log.warn('circuit with unknown type, unable to display:');
|
||||
Log.warn(controlObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
class: this.config.contentClass
|
||||
});
|
||||
} else {
|
||||
Log.warn('circuit with unknown type, unable to display:');
|
||||
Log.warn(controlObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var headerRow = null;
|
||||
var contentRow = null;
|
||||
let headerRow = null;
|
||||
let contentRow = null;
|
||||
|
||||
if (this.config.showFreezeMode && poolData.status.freezeMode !== 0) {
|
||||
var row = document.createElement('tr');
|
||||
table.appendChild(row);
|
||||
row.className = 'cold-temp';
|
||||
var cell = document.createElement('th');
|
||||
row.appendChild(cell);
|
||||
cell.colSpan = this.config.columns;
|
||||
cell.innerHTML = '<center>FREEZE MODE</center>';
|
||||
}
|
||||
if (this.config.showFreezeMode && poolData.status.freezeMode !== 0) {
|
||||
let row = document.createElement('tr');
|
||||
table.appendChild(row);
|
||||
row.className = 'cold-temp';
|
||||
let cell = document.createElement('th');
|
||||
row.appendChild(cell);
|
||||
cell.colSpan = this.config.columns;
|
||||
cell.innerHTML = '<center>FREEZE MODE</center>';
|
||||
}
|
||||
|
||||
var cols = -1;
|
||||
for (var item in contents) {
|
||||
cols++;
|
||||
if (cols % this.config.columns === 0) {
|
||||
headerRow = document.createElement('tr');
|
||||
contentRow = document.createElement('tr');
|
||||
table.appendChild(headerRow);
|
||||
table.appendChild(contentRow);
|
||||
}
|
||||
let cols = -1;
|
||||
for (let item in contents) {
|
||||
cols++;
|
||||
if (cols % this.config.columns === 0) {
|
||||
headerRow = document.createElement('tr');
|
||||
contentRow = document.createElement('tr');
|
||||
table.appendChild(headerRow);
|
||||
table.appendChild(contentRow);
|
||||
}
|
||||
|
||||
if (contents[item].header) {
|
||||
var headerCell = document.createElement('th');
|
||||
headerCell.innerHTML = contents[item].header;
|
||||
headerRow.appendChild(headerCell);
|
||||
}
|
||||
if (contents[item].header) {
|
||||
let headerCell = document.createElement('th');
|
||||
headerCell.innerHTML = contents[item].header;
|
||||
headerRow.appendChild(headerCell);
|
||||
}
|
||||
|
||||
var contentCell = document.createElement('td');
|
||||
contentCell.innerHTML = contents[item].data;
|
||||
contentCell.className = contents[item].class;
|
||||
contentRow.appendChild(contentCell);
|
||||
}
|
||||
let contentCell = document.createElement('td');
|
||||
contentCell.innerHTML = contents[item].data;
|
||||
contentCell.className = contents[item].class;
|
||||
contentRow.appendChild(contentCell);
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
},
|
||||
return table;
|
||||
}
|
||||
},
|
||||
|
||||
socketNotificationReceived: function(notification, payload) {
|
||||
if (notification === 'SCREENLOGIC_RESULT') {
|
||||
poolData = payload;
|
||||
this.updateDom();
|
||||
} else if (notification === 'SCREENLOGIC_CIRCUIT_DONE'
|
||||
socketNotificationReceived: function(notification, payload) {
|
||||
if (notification === 'SCREENLOGIC_RESULT') {
|
||||
poolData = payload;
|
||||
this.updateDom();
|
||||
} else if (notification === 'SCREENLOGIC_CIRCUIT_DONE'
|
||||
|| notification === 'SCREENLOGIC_HEATSTATE_DONE'
|
||||
|| notification === 'SCREENLOGIC_HEATPOINT_DONE') {
|
||||
poolData.status = payload.status;
|
||||
this.updateDom();
|
||||
}
|
||||
},
|
||||
poolData.status = payload.status;
|
||||
this.updateDom();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const SPA_CIRCUIT_ID = 500;
|
||||
const POOL_CIRCUIT_ID = 505;
|
||||
|
||||
function isPoolActive(status) {
|
||||
for (var i = 0; i < status.circuitArray.length; i++) {
|
||||
if (status.circuitArray[i].id === POOL_CIRCUIT_ID) {
|
||||
return status.circuitArray[i].state === 1;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < status.circuitArray.length; i++) {
|
||||
if (status.circuitArray[i].id === POOL_CIRCUIT_ID) {
|
||||
return status.circuitArray[i].state === 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hasSpa(status) {
|
||||
for (var i = 0; i < status.circuitArray.length; i++) {
|
||||
if (status.circuitArray[i].id === SPA_CIRCUIT_ID) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < status.circuitArray.length; i++) {
|
||||
if (status.circuitArray[i].id === SPA_CIRCUIT_ID) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
function isSpaActive(status) {
|
||||
for (var i = 0; i < status.circuitArray.length; i++) {
|
||||
if (status.circuitArray[i].id === SPA_CIRCUIT_ID) {
|
||||
return status.circuitArray[i].state === 1;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < status.circuitArray.length; i++) {
|
||||
if (status.circuitArray[i].id === SPA_CIRCUIT_ID) {
|
||||
return status.circuitArray[i].state === 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setCircuit(e) {
|
||||
var circuitId = parseInt(e.dataset.circuit);
|
||||
var on = e.dataset.state !== '0';
|
||||
moduleObj.sendSocketNotification('SCREENLOGIC_CIRCUIT', {id: circuitId, state: on ? 0 : 1});
|
||||
e.classList.remove('control-on', 'control-off');
|
||||
let circuitId = parseInt(e.dataset.circuit);
|
||||
let on = e.dataset.state !== '0';
|
||||
moduleObj.sendSocketNotification('SCREENLOGIC_CIRCUIT', {id: circuitId, state: on ? 0 : 1});
|
||||
e.classList.remove('control-on', 'control-off');
|
||||
}
|
||||
|
||||
function setHeatmode(e) {
|
||||
var bodyId = parseInt(e.dataset.body);
|
||||
var on = e.dataset.state !== '0';
|
||||
var mode = e.dataset.mode;
|
||||
moduleObj.sendSocketNotification('SCREENLOGIC_HEATSTATE', {body: bodyId, state: on ? 0 : parseInt(mode)});
|
||||
e.classList.remove('control-on', 'control-off');
|
||||
let bodyId = parseInt(e.dataset.body);
|
||||
let on = e.dataset.state !== '0';
|
||||
let mode = e.dataset.mode;
|
||||
moduleObj.sendSocketNotification('SCREENLOGIC_HEATSTATE', {body: bodyId, state: on ? 0 : parseInt(mode)});
|
||||
e.classList.remove('control-on', 'control-off');
|
||||
}
|
||||
|
||||
function setHeatpoint(e, tempChange) {
|
||||
var bodyId = parseInt(e.dataset.body);
|
||||
var temp = parseInt(e.dataset.temperature) + tempChange;
|
||||
moduleObj.sendSocketNotification('SCREENLOGIC_HEATPOINT', {body: bodyId, temperature: temp});
|
||||
e.classList.remove('control-on', 'control-off');
|
||||
let bodyId = parseInt(e.dataset.body);
|
||||
let temp = parseInt(e.dataset.temperature) + tempChange;
|
||||
moduleObj.sendSocketNotification('SCREENLOGIC_HEATPOINT', {body: bodyId, temperature: temp});
|
||||
e.classList.remove('control-on', 'control-off');
|
||||
}
|
||||
|
50
README.md
50
README.md
@ -1,13 +1,16 @@
|
||||
# MMM-ScreenLogic
|
||||
A <a href="https://github.com/MichMich/MagicMirror">MagicMirror²</a> module used to connect to a local Pentair ScreenLogic pool controller system.
|
||||
|
||||
[MagicMirror²](https://github.com/MichMich/MagicMirror) module used to connect to a local Pentair ScreenLogic pool controller system.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Navigate into your MagicMirror's `modules` folder and execute `git clone https://github.com/parnic/MMM-ScreenLogic.git`.
|
||||
2. `cd MMM-ScreenLogic`
|
||||
3. Execute `npm install` to install the node dependencies.
|
||||
3. Execute `npm install --production` to install the node dependencies.
|
||||
4. Add the module inside `config.js` placing it where you prefer.
|
||||
|
||||
## Config
|
||||
|
||||
|Option|Type|Description|Default|
|
||||
|---|---|---|---|
|
||||
|`coldTemp`|Integer|Show the temperature colored blue if it's at or below this level for pool/spa (requires option `colored`). This is in whatever scale your system is set to (Fahrenheit/Celsius).|`84`|
|
||||
@ -22,6 +25,8 @@ A <a href="https://github.com/MichMich/MagicMirror">MagicMirror²</a> module use
|
||||
|`showFreezeMode`|Boolean|Whether you'd like to show a banner when the pool is in freeze mode or not. [added in v1.0.1]|`true`|
|
||||
|`showOrp`|Boolean|Whether you'd like to show ORP level or not.|`true`|
|
||||
|`showPH`|Boolean|Whether you'd like to show pH level or not.|`true`|
|
||||
|`showPHTankLevel`|Boolean|Whether you'd like to show how much pH balancer is in the tank or not. Only functions if `showPH` is also on.|`true`|
|
||||
|`pHTankLevelMax`|Boolean|If `showPHTankLevel` is enabled, this is the maximum value that the system returns for a full tank. My systems has this always set to 6, but maybe it differs based on what type of pH balancer you're using.|`6`|
|
||||
|`showPoolTemp`|Boolean|Whether you'd like to show pool temperature or not.|`true`|
|
||||
|`showSaltLevel`|Boolean|Whether you'd like to show salt level (in PPM) or not.|`true`|
|
||||
|`showSaturation`|Boolean|Whether you'd like to show saturation/balance or not.|`true`|
|
||||
@ -29,32 +34,36 @@ A <a href="https://github.com/MichMich/MagicMirror">MagicMirror²</a> module use
|
||||
|`updateInterval`|Integer|How frequently, in milliseconds, to update pool data.|`30 * 60 * 1000` (every 30 minutes)|
|
||||
|
||||
Here is an example of an entry in config.js
|
||||
```
|
||||
|
||||
```js
|
||||
{
|
||||
module: 'MMM-ScreenLogic',
|
||||
header: 'Pool info',
|
||||
position: 'top_left',
|
||||
config: {
|
||||
showSpaTemp: false,
|
||||
columns: 2,
|
||||
contentClass: 'thin',
|
||||
showControls: true,
|
||||
controls: [
|
||||
{type: 'circuit', id: 500},
|
||||
{type: 'circuit', id: 505, name: 'Pool'},
|
||||
{type: 'heatmode', body: 0, name: 'Pool heater'},
|
||||
{type: 'heatpoint', body: 0, name: 'Pool'},
|
||||
{type: 'heatmode', body: 1, heatMode: 2, name: 'Spa heater'},
|
||||
]
|
||||
}
|
||||
module: 'MMM-ScreenLogic',
|
||||
header: 'Pool info',
|
||||
position: 'top_left',
|
||||
config: {
|
||||
showSpaTemp: false,
|
||||
columns: 2,
|
||||
contentClass: 'thin',
|
||||
showControls: true,
|
||||
controls: [
|
||||
{type: 'circuit', id: 500},
|
||||
{type: 'circuit', id: 505, name: 'Pool'},
|
||||
{type: 'heatmode', body: 0, name: 'Pool heater'},
|
||||
{type: 'heatpoint', body: 0, name: 'Pool'},
|
||||
{type: 'heatmode', body: 1, heatMode: 2, name: 'Spa heater'},
|
||||
]
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
## Screenshot
|
||||
#### With color
|
||||
|
||||
### With color
|
||||
|
||||

|
||||
|
||||
## Notes
|
||||
|
||||
Pull requests are very welcome! If you'd like to see any additional functionality, don't hesitate to let me know.
|
||||
|
||||
This module only works with ScreenLogic controllers on the local network via either a UDP broadcast on 255.255.255.255 or a direct connection if you've specified an address and port in the configuration.
|
||||
@ -64,4 +73,5 @@ The data is updated every 30 minutes by default (configurable with `updateInterv
|
||||
When toggling a circuit or changing heat mode, sometimes other circuits are affected. For example, some pools share the same pump for the pool and spa, so when the pool is toggled on the spa must be toggled off. Unfortunately the ScreenLogic system doesn't update its internal status at any predictable rate, so the data on the screen can be wrong immediately after toggling a circuit until the next periodic update runs. If you know of a reliable way around this, please open a pull request!
|
||||
|
||||
## Libraries
|
||||
|
||||
This uses a Node.JS library I created for interfacing with ScreenLogic controllers over the network: [node-screenlogic](https://github.com/parnic/node-screenlogic), so feel free to check that out for more information.
|
||||
|
314
node_helper.js
314
node_helper.js
@ -1,210 +1,210 @@
|
||||
var NodeHelper = require('node_helper');
|
||||
|
||||
module.exports = NodeHelper.create({
|
||||
start: function() {
|
||||
this.setTimer(30 * 60 * 1000);
|
||||
},
|
||||
start: function() {
|
||||
this.setTimer(30 * 60 * 1000);
|
||||
},
|
||||
|
||||
doUpdate: function() {
|
||||
var self = this;
|
||||
getPoolData(this.config, function(poolData) {
|
||||
self.sendSocketNotification('SCREENLOGIC_RESULT', poolData);
|
||||
});
|
||||
},
|
||||
doUpdate: function() {
|
||||
var self = this;
|
||||
getPoolData(this.config, function(poolData) {
|
||||
self.sendSocketNotification('SCREENLOGIC_RESULT', poolData);
|
||||
});
|
||||
},
|
||||
|
||||
setCircuit: function(circuitState) {
|
||||
var self = this;
|
||||
setCircuitState(circuitState, function(poolStatus) {
|
||||
self.sendSocketNotification('SCREENLOGIC_CIRCUIT_DONE', {circuitState: circuitState, status: poolStatus});
|
||||
});
|
||||
},
|
||||
setCircuit: function(circuitState) {
|
||||
var self = this;
|
||||
setCircuitState(circuitState, function(poolStatus) {
|
||||
self.sendSocketNotification('SCREENLOGIC_CIRCUIT_DONE', {circuitState: circuitState, status: poolStatus});
|
||||
});
|
||||
},
|
||||
|
||||
setHeatpoint: function(heatpoint) {
|
||||
var self = this;
|
||||
setHeatpointState(heatpoint, function(poolStatus) {
|
||||
self.sendSocketNotification('SCREENLOGIC_HEATPOINT_DONE', {heatpoint: heatpoint, status: poolStatus});
|
||||
});
|
||||
},
|
||||
setHeatpoint: function(heatpoint) {
|
||||
var self = this;
|
||||
setHeatpointState(heatpoint, function(poolStatus) {
|
||||
self.sendSocketNotification('SCREENLOGIC_HEATPOINT_DONE', {heatpoint: heatpoint, status: poolStatus});
|
||||
});
|
||||
},
|
||||
|
||||
setHeatstate: function(heatstate) {
|
||||
var self = this;
|
||||
setHeatstateState(heatstate, function(poolStatus) {
|
||||
self.sendSocketNotification('SCREENLOGIC_HEATSTATE_DONE', {heatstate: heatstate, status: poolStatus});
|
||||
});
|
||||
},
|
||||
setHeatstate: function(heatstate) {
|
||||
var self = this;
|
||||
setHeatstateState(heatstate, function(poolStatus) {
|
||||
self.sendSocketNotification('SCREENLOGIC_HEATSTATE_DONE', {heatstate: heatstate, status: poolStatus});
|
||||
});
|
||||
},
|
||||
|
||||
setLightcmd: function(lightCmd) {
|
||||
var self = this;
|
||||
setLights(lightCmd, function(poolStatus) {
|
||||
self.sendSocketNotification('SCREENLOGIC_LIGHTCMD_DONE', {lightCmd: lightCmd, status: poolStatus});
|
||||
});
|
||||
},
|
||||
setLightcmd: function(lightCmd) {
|
||||
var self = this;
|
||||
setLights(lightCmd, function(poolStatus) {
|
||||
self.sendSocketNotification('SCREENLOGIC_LIGHTCMD_DONE', {lightCmd: lightCmd, status: poolStatus});
|
||||
});
|
||||
},
|
||||
|
||||
restartTimer: function() {
|
||||
var interval = this.updateInterval;
|
||||
this.updateInterval = undefined;
|
||||
this.setTimer(interval);
|
||||
},
|
||||
restartTimer: function() {
|
||||
var interval = this.updateInterval;
|
||||
this.updateInterval = undefined;
|
||||
this.setTimer(interval);
|
||||
},
|
||||
|
||||
setTimer: function(updateInterval) {
|
||||
var update = true;
|
||||
update = typeof this.updateInterval === 'undefined' || this.updateInterval != updateInterval;
|
||||
this.updateInterval = updateInterval;
|
||||
setTimer: function(updateInterval) {
|
||||
var update = true;
|
||||
update = typeof this.updateInterval === 'undefined' || this.updateInterval !== updateInterval;
|
||||
this.updateInterval = updateInterval;
|
||||
|
||||
if (update) {
|
||||
if (typeof this.timer !== 'undefined') {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
if (update) {
|
||||
if (typeof this.timer !== 'undefined') {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
self.timer = setInterval(function() {
|
||||
self.doUpdate()
|
||||
}, self.updateInterval);
|
||||
}
|
||||
},
|
||||
var self = this;
|
||||
self.timer = setInterval(function() {
|
||||
self.doUpdate();
|
||||
}, self.updateInterval);
|
||||
}
|
||||
},
|
||||
|
||||
socketNotificationReceived: function(notification, payload) {
|
||||
if (notification === 'SCREENLOGIC_CONFIG') {
|
||||
this.config = payload;
|
||||
this.setTimer(this.config.updateInterval);
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_UPDATE') {
|
||||
this.doUpdate();
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_CIRCUIT') {
|
||||
this.setCircuit(payload);
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_HEATPOINT') {
|
||||
this.setHeatpoint(payload);
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_HEATSTATE') {
|
||||
this.setHeatstate(payload);
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_LIGHTCMD') {
|
||||
this.setLightcmd(payload);
|
||||
}
|
||||
}
|
||||
socketNotificationReceived: function(notification, payload) {
|
||||
if (notification === 'SCREENLOGIC_CONFIG') {
|
||||
this.config = payload;
|
||||
this.setTimer(this.config.updateInterval);
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_UPDATE') {
|
||||
this.doUpdate();
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_CIRCUIT') {
|
||||
this.setCircuit(payload);
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_HEATPOINT') {
|
||||
this.setHeatpoint(payload);
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_HEATSTATE') {
|
||||
this.setHeatstate(payload);
|
||||
}
|
||||
if (notification === 'SCREENLOGIC_LIGHTCMD') {
|
||||
this.setLightcmd(payload);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const ScreenLogic = require('node-screenlogic');
|
||||
var foundUnit;
|
||||
|
||||
function getPoolData(config, cb) {
|
||||
if (!foundUnit && typeof config !== 'undefined' && config.serverAddress && config.serverPort) {
|
||||
foundUnit = new ScreenLogic.UnitConnection(config.serverPort, config.serverAddress);
|
||||
}
|
||||
if (!foundUnit && typeof config !== 'undefined' && config.serverAddress && config.serverPort) {
|
||||
foundUnit = new ScreenLogic.UnitConnection(config.serverPort, config.serverAddress);
|
||||
}
|
||||
|
||||
if (foundUnit) {
|
||||
populateSystemData(cb);
|
||||
} else {
|
||||
findServer(cb);
|
||||
}
|
||||
if (foundUnit) {
|
||||
populateSystemData(cb);
|
||||
} else {
|
||||
findServer(cb);
|
||||
}
|
||||
}
|
||||
|
||||
function findServer(cb) {
|
||||
var finder = new ScreenLogic.FindUnits();
|
||||
finder.on('serverFound', function(server) {
|
||||
finder.close();
|
||||
var finder = new ScreenLogic.FindUnits();
|
||||
finder.on('serverFound', function(server) {
|
||||
finder.close();
|
||||
|
||||
foundUnit = new ScreenLogic.UnitConnection(server);
|
||||
populateSystemData(cb);
|
||||
});
|
||||
foundUnit = new ScreenLogic.UnitConnection(server);
|
||||
populateSystemData(cb);
|
||||
});
|
||||
|
||||
finder.search();
|
||||
finder.search();
|
||||
}
|
||||
|
||||
function populateSystemData(cb) {
|
||||
var poolData = {};
|
||||
var poolData = {};
|
||||
|
||||
if (!foundUnit) {
|
||||
cb(poolData);
|
||||
return;
|
||||
}
|
||||
if (!foundUnit) {
|
||||
cb(poolData);
|
||||
return;
|
||||
}
|
||||
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.getControllerConfig();
|
||||
}).once('controllerConfig', function(config) {
|
||||
poolData.controllerConfig = config;
|
||||
poolData.degStr = config.degC ? 'C' : 'F';
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
poolData.status = status;
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.getControllerConfig();
|
||||
}).once('controllerConfig', function(config) {
|
||||
poolData.controllerConfig = config;
|
||||
poolData.degStr = config.degC ? 'C' : 'F';
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
poolData.status = status;
|
||||
|
||||
foundUnit.close();
|
||||
cb(poolData);
|
||||
});
|
||||
foundUnit.close();
|
||||
cb(poolData);
|
||||
});
|
||||
|
||||
foundUnit.connect();
|
||||
foundUnit.connect();
|
||||
}
|
||||
|
||||
function setCircuitState(circuitState, cb) {
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.setCircuitState(0, circuitState.id, circuitState.state);
|
||||
}).once('circuitStateChanged', function() {
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
foundUnit.close();
|
||||
cb(status);
|
||||
});
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.setCircuitState(0, circuitState.id, circuitState.state);
|
||||
}).once('circuitStateChanged', function() {
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
foundUnit.close();
|
||||
cb(status);
|
||||
});
|
||||
|
||||
foundUnit.connect();
|
||||
foundUnit.connect();
|
||||
}
|
||||
|
||||
function setHeatpointState(heatpoint, cb) {
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.setSetPoint(0, heatpoint.body, heatpoint.temperature);
|
||||
}).once('setPointChanged', function() {
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
foundUnit.close();
|
||||
cb(status);
|
||||
});
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.setSetPoint(0, heatpoint.body, heatpoint.temperature);
|
||||
}).once('setPointChanged', function() {
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
foundUnit.close();
|
||||
cb(status);
|
||||
});
|
||||
|
||||
foundUnit.connect();
|
||||
foundUnit.connect();
|
||||
}
|
||||
|
||||
function setHeatstateState(heatstate, cb) {
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.setHeatMode(0, heatstate.body, heatstate.state);
|
||||
}).once('heatModeChanged', function() {
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
foundUnit.close();
|
||||
cb(status);
|
||||
});
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.setHeatMode(0, heatstate.body, heatstate.state);
|
||||
}).once('heatModeChanged', function() {
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
foundUnit.close();
|
||||
cb(status);
|
||||
});
|
||||
|
||||
foundUnit.connect();
|
||||
foundUnit.connect();
|
||||
}
|
||||
|
||||
function setLights(lightCmd, cb) {
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
if (!foundUnit) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.sendLightCommand(0, lightCmd);
|
||||
}).once('sentLightCommand', function() {
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
foundUnit.close();
|
||||
cb(status);
|
||||
});
|
||||
foundUnit.once('loggedIn', function() {
|
||||
foundUnit.sendLightCommand(0, lightCmd);
|
||||
}).once('sentLightCommand', function() {
|
||||
foundUnit.getPoolStatus();
|
||||
}).once('poolStatus', function(status) {
|
||||
foundUnit.close();
|
||||
cb(status);
|
||||
});
|
||||
|
||||
foundUnit.connect();
|
||||
foundUnit.connect();
|
||||
}
|
||||
|
795
package-lock.json
generated
795
package-lock.json
generated
@ -1,21 +1,796 @@
|
||||
{
|
||||
"name": "magic-mirror-module-screenlogic",
|
||||
"version": "1.0.3",
|
||||
"name": "mmm-screenlogic",
|
||||
"version": "1.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"node-screenlogic": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/node-screenlogic/-/node-screenlogic-1.3.1.tgz",
|
||||
"integrity": "sha512-KbqK2lH2PcyGcmQCDqEvL55OWtSG4TvupglBpNrBuuxEbd5id8C3iKT0+9af69BJHDiTT6oAbog9NsJcUI2Zrw==",
|
||||
"@eslint/eslintrc": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.2.tgz",
|
||||
"integrity": "sha512-x1ZXdEFsvTcnbTZgqcWUL9w2ybgZCw/qbKTPQnab+XnYA2bMQpJCh+/bBzCRfDJaJdlrrQlOk49jNtru9gL/6Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"smart-buffer": "~4.0.1"
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.0.0",
|
||||
"globals": "^13.9.0",
|
||||
"ignore": "^4.0.6",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
"minimatch": "^3.0.4",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@humanwhocodes/config-array": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz",
|
||||
"integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@humanwhocodes/object-schema": "^1.2.0",
|
||||
"debug": "^4.1.1",
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"@humanwhocodes/object-schema": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
|
||||
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz",
|
||||
"integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"ansi-colors": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
|
||||
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"deep-is": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
||||
"dev": true
|
||||
},
|
||||
"doctrine": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
||||
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esutils": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"enquirer": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
|
||||
"integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-colors": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"dev": true
|
||||
},
|
||||
"eslint": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.0.0.tgz",
|
||||
"integrity": "sha512-03spzPzMAO4pElm44m60Nj08nYonPGQXmw6Ceai/S4QK82IgwWO1EXx1s9namKzVlbVu3Jf81hb+N+8+v21/HQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint/eslintrc": "^1.0.2",
|
||||
"@humanwhocodes/config-array": "^0.6.0",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.2",
|
||||
"debug": "^4.3.2",
|
||||
"doctrine": "^3.0.0",
|
||||
"enquirer": "^2.3.5",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"eslint-scope": "^6.0.0",
|
||||
"eslint-utils": "^3.0.0",
|
||||
"eslint-visitor-keys": "^3.0.0",
|
||||
"espree": "^9.0.0",
|
||||
"esquery": "^1.4.0",
|
||||
"esutils": "^2.0.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"file-entry-cache": "^6.0.1",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"glob-parent": "^6.0.1",
|
||||
"globals": "^13.6.0",
|
||||
"ignore": "^4.0.6",
|
||||
"import-fresh": "^3.0.0",
|
||||
"imurmurhash": "^0.1.4",
|
||||
"is-glob": "^4.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||
"levn": "^0.4.1",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"minimatch": "^3.0.4",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.9.1",
|
||||
"progress": "^2.0.0",
|
||||
"regexpp": "^3.2.0",
|
||||
"semver": "^7.2.1",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"strip-json-comments": "^3.1.0",
|
||||
"text-table": "^0.2.0",
|
||||
"v8-compile-cache": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz",
|
||||
"integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^5.2.0"
|
||||
}
|
||||
},
|
||||
"eslint-utils": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
||||
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
|
||||
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-visitor-keys": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz",
|
||||
"integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==",
|
||||
"dev": true
|
||||
},
|
||||
"espree": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz",
|
||||
"integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^8.5.0",
|
||||
"acorn-jsx": "^5.3.1",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||
"dev": true
|
||||
},
|
||||
"esquery": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
|
||||
"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estraverse": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"esrecurse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estraverse": "^5.2.0"
|
||||
}
|
||||
},
|
||||
"estraverse": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-levenshtein": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"file-entry-cache": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
||||
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"flat-cache": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"flat-cache": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
||||
"integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"flatted": "^3.1.0",
|
||||
"rimraf": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"flatted": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz",
|
||||
"integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
|
||||
"dev": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"functional-red-black-tree": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
|
||||
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "13.11.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz",
|
||||
"integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.20.2"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||
"dev": true
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"parent-module": "^1.0.0",
|
||||
"resolve-from": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"imurmurhash": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
|
||||
"dev": true
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
|
||||
"dev": true
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
},
|
||||
"js-yaml": {
|
||||
"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"
|
||||
},
|
||||
"dependencies": {
|
||||
"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
|
||||
}
|
||||
}
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
|
||||
"dev": true
|
||||
},
|
||||
"levn": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"prelude-ls": "^1.2.1",
|
||||
"type-check": "~0.4.0"
|
||||
}
|
||||
},
|
||||
"lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||
"dev": true
|
||||
},
|
||||
"node-screenlogic": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-screenlogic/-/node-screenlogic-1.6.1.tgz",
|
||||
"integrity": "sha512-HcjhFvv2OORlXgv9kfnMZA+mCZdCGeTe/3vx5kcKckH130zenVaM2jKcGuzNBdDQpGPz/sogcaZpfCp0xwA+Ag==",
|
||||
"requires": {
|
||||
"debug": "^4.3.1",
|
||||
"smart-buffer": "~4.1.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"optionator": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
||||
"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"deep-is": "^0.1.3",
|
||||
"fast-levenshtein": "^2.0.6",
|
||||
"levn": "^0.4.1",
|
||||
"prelude-ls": "^1.2.1",
|
||||
"type-check": "^0.4.0",
|
||||
"word-wrap": "^1.2.3"
|
||||
}
|
||||
},
|
||||
"parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"callsites": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
|
||||
"dev": true
|
||||
},
|
||||
"progress": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"dev": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
},
|
||||
"regexpp": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||
"dev": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true
|
||||
},
|
||||
"smart-buffer": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz",
|
||||
"integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw=="
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz",
|
||||
"integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw=="
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
||||
"dev": true
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"prelude-ls": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||
"dev": true
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
|
||||
"dev": true
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"dev": true
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
30
package.json
30
package.json
@ -1,12 +1,18 @@
|
||||
{
|
||||
"name": "magic-mirror-module-screenlogic",
|
||||
"version": "1.1.0",
|
||||
"description": "Show data from Pentair ScreenLogic systems",
|
||||
"main": "MMM-ScreenLogic.js",
|
||||
"author": "Chris Pickett",
|
||||
"repository": "https://github.com/parnic/MMM-ScreenLogic.git",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-screenlogic": "1.x"
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "mmm-screenlogic",
|
||||
"version": "1.1.0",
|
||||
"description": "Show data from Pentair ScreenLogic systems",
|
||||
"main": "MMM-ScreenLogic.js",
|
||||
"author": "parnic",
|
||||
"repository": "https://github.com/parnic/MMM-ScreenLogic.git",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-screenlogic": "^1.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "./node_modules/.bin/eslint ."
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,29 @@
|
||||
.MMM-ScreenLogic table.colored .cold-temp {
|
||||
color: #BCDDFF;
|
||||
color: #BCDDFF;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic table.colored .hot-temp {
|
||||
color: #FF8E99;
|
||||
color: #FF8E99;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic td {
|
||||
width: 33%;
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .control {
|
||||
background: #000;
|
||||
border: 1px solid #6c757d;
|
||||
font-size: .9rem;
|
||||
font-size: .8rem;
|
||||
color: #fff;
|
||||
display: block;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 80%;
|
||||
height: 5rem;
|
||||
margin: auto;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 80%;
|
||||
height: 5rem;
|
||||
margin: auto;
|
||||
font-weight: bold;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
@ -34,13 +34,13 @@
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .control:after {
|
||||
padding-bottom: 100%;
|
||||
content: "";
|
||||
display: block;
|
||||
padding-bottom: 100%;
|
||||
content: "";
|
||||
display: block;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .content {
|
||||
position: absolute;
|
||||
position: absolute;
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
left: 0px;
|
||||
@ -52,13 +52,13 @@
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .control-on {
|
||||
background: #28a745 !important;
|
||||
border-color: #28a745 !important;
|
||||
background: #28a745 !important;
|
||||
border-color: #28a745 !important;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .control-off {
|
||||
background: transparent !important;
|
||||
border-color: #6c757d !important;
|
||||
background: transparent !important;
|
||||
border-color: #6c757d !important;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .temperature-container {
|
||||
@ -81,10 +81,10 @@
|
||||
background: #000;
|
||||
border: 0px solid #6c757d;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
width: 80%;
|
||||
height: 2.45rem;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
width: 80%;
|
||||
height: 2.45rem;
|
||||
margin: auto;
|
||||
font-weight: bold;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
@ -93,3 +93,47 @@
|
||||
cursor: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .vertical {
|
||||
display: inline-block;
|
||||
width: 20%;
|
||||
height: 0.7em;
|
||||
-webkit-transform: rotate(-90deg); /* Chrome, Safari, Opera */
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .vertical {
|
||||
box-shadow: inset 0px 0px 3px #ccc;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .progress-bar {
|
||||
box-shadow: inset 0px 0px 3px rgba(100, 100, 100, 0.6);
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .progress-bar {
|
||||
float: left;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
|
||||
box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
|
||||
-webkit-transition: width .6s ease;
|
||||
-o-transition: width .6s ease;
|
||||
transition: width .6s ease;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .progress-bar-success {
|
||||
background-color: #5cb85c;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .progress-bar-warning {
|
||||
background-color: #ffc107;
|
||||
}
|
||||
|
||||
.MMM-ScreenLogic .progress-bar-danger {
|
||||
background-color: #dc3545;
|
||||
}
|
BIN
screenshot.png
BIN
screenshot.png
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 38 KiB |
Reference in New Issue
Block a user