-
-
-
-
+
+
+
+
-
+
+
+
+ {!sync &&
+
+ {melodyElements}
+ }
+
+ {sync &&
+
+
+ }
+
-
- {!sync && melodyElements}
-
- {sync &&
- }
-
-
-
- { !sync &&
- }
-
- { !dummy &&
- }
-
-
-
+
+
+ { !sync &&
+ }
+
+ { !dummy &&
+ }
+
+
+
+
+
);
}
@@ -456,6 +512,7 @@ MelodyEditor.propTypes = {
onDelete: PropTypes.func.isRequired,
onSave: PropTypes.func.isRequired,
onWrite: PropTypes.func.isRequired,
+ open: PropTypes.bool.isRequired,
writing: PropTypes.bool.isRequired,
};
diff --git a/src/Components/MelodyEditor/style.scss b/src/Components/MelodyEditor/style.scss
deleted file mode 100644
index e54963afd..000000000
--- a/src/Components/MelodyEditor/style.scss
+++ /dev/null
@@ -1,142 +0,0 @@
-#melody-editor {
- .overlay {
- .overlay__wrapper {
- max-width: 960px;
- width: 80%;
-
- @media screen and (max-width: 600px) {
- width: 90%;
- }
- }
- }
-
- .line-wrapper {
- margin-top: 20px;
- display: flex;
- flex-direction: row;
-
- .info-wrapper-wrapper {
- white-space: nowrap;
- }
-
- select {
- margin-left: 10px;
- height: 20px;
- border: 1px solid silver;
- border-radius: 3px;
- }
-
- .melody-selection-wrapper {
- display: flex;
- flex-direction: row;
- margin-bottom: 6px;
-
- .info-wrapper-wrapper {
- display: none;
- }
-
- .default-btn {
- margin-top: -2px;
- margin-left: 10px;
-
- button {
- width: 100px;
- }
- }
- }
-
- @media screen and (max-width: 768px) {
- flex-direction: column;
-
- select {
- margin-left: 0px;
- }
-
- .melody-selection-wrapper {
- .default-btn button {
- width: inherit;
- }
- }
- }
- }
-
- .save-melody-wrapper {
- display: flex;
- flex-direction: row;
-
- input {
- border: 1px solid silver;
- padding-left: 5px;
- padding-right: 5px;
- line-height: 23px;
- }
-
- .default-btn {
- margin-left: 10px;
-
- button {
- width: 100px;
-
- @media screen and (max-width: 768px) {
- width: inherit;
- }
- }
- }
- }
-
- .sync-wrapper {
- .checkbox {
- display: flex;
- }
- }
-
- .melody-editor-escs {
- display: flex;
- flex-wrap: wrap;
- margin-left: -10px;
- margin-right: -10px;
-
- &.all {
- .esc-melody-wrapper {
- width: 100%;
- }
- }
- }
-
- .button-wrapper {
- display: flex;
- justify-content: flex-end;
-
- button {
- width: 100px;
- margin-left: 15px;
- }
- }
-
- @media screen and (max-width: 600px) {
- .melody-editor-escs.single {
- .esc-melody {
- margin-top: 5px;
- margin-bottom: 5px;
-
- header {
- flex-direction: column;
- border: 0px;
- padding-bottom: 0px;
- margin-bottom: 4px;
-
- .default-btn {
- margin-top: 2px;
- margin-left: -2px;
- margin-right: -2px;
-
- button {
- margin-left: 2px;
- margin-right: 2px;
- }
- }
- }
- }
- }
- }
-}
diff --git a/src/Components/MotorControl/index.jsx b/src/Components/MotorControl/index.jsx
index 651cd5f02..357004f88 100644
--- a/src/Components/MotorControl/index.jsx
+++ b/src/Components/MotorControl/index.jsx
@@ -1,19 +1,20 @@
-import Slider, { createSliderWithTooltip } from 'rc-slider';
import { useTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
import React, {
useCallback,
+ useEffect,
useState,
useMemo,
} from 'react';
-import 'rc-slider/assets/index.css';
-import Checkbox from '../Input/Checkbox';
-import { useInterval } from '../../utils/helpers/React';
-
-import './style.scss';
+import Grid from '@mui/material/Grid';
+import MuiSlider from '@mui/material/Slider';
+import Typography from '@mui/material/Typography';
-const SliderWithTooltip = createSliderWithTooltip(Slider);
+import { useInterval } from '../../utils/helpers/React';
+import Checkbox from '../Input/Checkbox';
+import MainCard from '../MainCard';
+import Warning from '../Warning';
function BatteryState({ getBatteryState }) {
const { t } = useTranslation('common');
@@ -46,9 +47,9 @@ function BatteryState({ getBatteryState }) {
if(batteryState.text) {
return (
-
+
{`${t('battery')} ${batteryState.text}`}
-
+
);
}
@@ -65,24 +66,28 @@ function MotorSlider({
}) {
const [value, setValue] = useState(startValue);
+ useEffect(() => {
+ setValue(startValue);
+ }, [startValue]);
+
/* istanbul ignore next */
- const update = useCallback((value) => {
+ const update = useCallback((e) => {
+ const value = e.target.value;
+
setValue(value);
onChange(value);
}, [onChange]);
return(
-
);
}
@@ -110,10 +115,10 @@ function IndividualMotorSlider({
}, [index, onChange]);
return(
-
-
+ <>
+
{t("motorNr", { index: index + 1 })}
-
+
-
+ >
);
}
IndividualMotorSlider.propTypes = {
@@ -142,12 +147,12 @@ function MotorControl({
startValue,
}) {
const { t } = useTranslation('common');
-
const minValue = 1000;
const maxValue = 2000;
const [unlock, setUnlock] = useState(false);
const [unlockIndividual, setUnlockIndividual] = useState(true);
+ const [masterValue, setMasterValue] = useState(startValue);
const toggleUnlock = useCallback(() => {
setUnlock(!unlock);
@@ -166,6 +171,7 @@ function MotorControl({
setUnlockIndividual(true);
}
+ setMasterValue(value);
onAllUpdate(value);
}, [startValue, unlockIndividual, onAllUpdate]);
@@ -184,7 +190,7 @@ function MotorControl({
max={maxValue}
min={minValue}
onChange={updateSingleValue}
- startValue={startValue}
+ startValue={masterValue}
/>
);
}
@@ -200,58 +206,86 @@ function MotorControl({
), [startValue, unlock, updateValue]);
return (
-
-
-
-
- {t('motorControl')}
-
-
-
-
-
-
- { t('motorControlTextLine1') }
-
-
-
- { t('motorControlTextLine2') }
-
-
-
- { t('motorControlTextLine3') }
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ {t('motorControlTextLine1')}
+
+
+
+ {t('motorControlTextLine2')}
+
+
+
+ {t('motorControlTextLine3')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{singleSliderElements}
-
+
-
-
+
+
{t('masterSpeed')}
-
+
{memoizedMasterSlider}
-
-
-
-
-
+
+
+
+
+
);
}
MotorControl.defaultProps = {
diff --git a/src/Components/MotorControl/style.scss b/src/Components/MotorControl/style.scss
deleted file mode 100644
index 00140ca35..000000000
--- a/src/Components/MotorControl/style.scss
+++ /dev/null
@@ -1,126 +0,0 @@
-#motor-control-wrapper {
- max-width: 600px;
- width: 100%;
- // margin-bottom: 65px;
-
- .gui-box {
- .spacer-box {
- p {
- font-weight: normal;
- padding-bottom: 10px;
- }
- }
-
- .line-wrapper {
- display: flex;
- align-items: center;
- margin-bottom: 3px;
-
- &>* {
- flex: 1;
- padding: 0px;
- margin-bottom: 7px;
- }
-
- .battery-state {
- font-weight: bold;
-
- &.danger {
- font-weight: bold;
- color: red;
- }
- }
- }
- }
-
- .rc-slider {
- margin-left: 8px;
- height: 30px;
- }
-
- .rc-slider-tooltip {
- .rc-slider-tooltip-content {
- margin-bottom: -15px;
- }
-
- .rc-slider-tooltip-arrow {
- display: none;
- }
- .rc-slider-tooltip-inner {
- background-color: transparent;
- color: black;
- font-weight: normal;
- box-shadow: none;
- }
- }
-
- .rc-slider-track {
- background: var(--color-primary);
- }
-
- .rc-slider-handle {
- margin-top: -7px;
- width: 19px;
- height: 19px;
- border: 0px;
- background: var(--color-primary);
- }
-
- .rc-slider-disabled {
- background: transparent;
-
- .rc-slider-handle {
- background: #cccccc;
- }
- }
-
- .checkbox label {
- flex: 0 0 10px !important;
- }
-
- .checkbox {
- span {
- margin-left: 5px;
- }
- }
-
- #slider-wrapper {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
-
- #single-slider,
- #master-slider {
- flex: 1;
- margin-right: 30px;
- }
-
- .slider,
- #master-slider {
- h3 {
- padding-bottom: 20px;
- }
-
- .input-range {
- float: none;
- margin-left: 8px;
- }
- }
-
- @media only screen and (max-width: 600px) {
- flex-direction: column-reverse;
- align-items: flex-start;
-
- #single-slider,
- #master-slider {
- width: 90%;
- }
-
- .slider {
- h3 {
- padding-top: 10px;
- }
- }
- }
- }
-}
diff --git a/src/Components/Overlay/index.jsx b/src/Components/Overlay/index.jsx
index 824df6496..521df8fe6 100644
--- a/src/Components/Overlay/index.jsx
+++ b/src/Components/Overlay/index.jsx
@@ -1,46 +1,63 @@
-import { useTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
import React from 'react';
-import './style.scss';
+import Dialog from '@mui/material/Dialog';
+import DialogContent from '@mui/material/DialogContent';
+import DialogTitle from '@mui/material/DialogTitle';
+import IconButton from '@mui/material/IconButton';
+
+import CloseIcon from '@mui/icons-material/Close';
function Overlay({
children,
headline,
+ maxWidth,
onClose,
+ open,
}) {
- const { t } = useTranslation('settings');
-
- return (
-
-
+ return(
+
+
+
);
}
-Overlay.defaultProps = { children: null };
+
+Overlay.defaultProps = {
+ children: null,
+ maxWidth: 'sm',
+ open: false,
+};
Overlay.propTypes = {
children: PropTypes.element,
headline: PropTypes.string.isRequired,
+ maxWidth: PropTypes.string,
onClose: PropTypes.func.isRequired,
+ open: PropTypes.bool,
};
export default Overlay;
diff --git a/src/Components/Overlay/style.scss b/src/Components/Overlay/style.scss
deleted file mode 100644
index 62efa8a56..000000000
--- a/src/Components/Overlay/style.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-.overlay {
- position: fixed;
- width: 100%;
- height: 100%;
- left: 0px;
- top: 0px;
- z-index: 2;
- display: flex;
- justify-content: center;
- align-items: center;
-
- .overlay__wrapper {
- padding: 10px;
- background: white;
- max-width: 500px;
- width: 80%;
- position: relative;
-
- .overlay__close {
- cursor: pointer;
- position: absolute;
- top: 10px;
- right: 10px;
- font-weight: bold;
- }
-
- h3 {
- padding-bottom: 5px;
- margin-bottom: 10px;
- border-bottom: 1px solid silver;
- }
- }
-}
diff --git a/src/Components/PortPicker/style.scss b/src/Components/PortPicker/style.scss
index e13b3d313..4601cc868 100644
--- a/src/Components/PortPicker/style.scss
+++ b/src/Components/PortPicker/style.scss
@@ -19,8 +19,10 @@
border: 1px solid var(--color-primary);
color: #fff;
float: right;
+ /*
font-family: 'open_sansbold', Arial;
font-size: 12px;
+ */
text-shadow: 0px 1px rgba(0, 0, 0, 0.25);
display: block;
cursor: pointer;
@@ -67,8 +69,10 @@
width: 100%;
text-align: center;
color: #fff;
+ /*
font-size: 12px;
font-family: 'open_sansregular', Arial;
+ */
text-shadow: 0px 1px rgba(0, 0, 0, 0.25);
margin-top: -1px;
}
diff --git a/src/Components/Statusbar/__tests__/index.test.jsx b/src/Components/Statusbar/__tests__/index.test.jsx
index 95b00c29b..52f692d51 100644
--- a/src/Components/Statusbar/__tests__/index.test.jsx
+++ b/src/Components/Statusbar/__tests__/index.test.jsx
@@ -27,7 +27,7 @@ describe('Statusbar', () => {
setTimeout(r, 1200);
});
});
- expect(screen.getByText('statusbarPortUtilization D: 0% U: 0%')).toBeInTheDocument();
+ expect(screen.getByText(/statusbarPortUtilization D: 0% U: 0%/i)).toBeInTheDocument();
});
it('should render with utilization callback', async () => {
@@ -55,6 +55,6 @@ describe('Statusbar', () => {
});
expect(getUtilization).toHaveBeenCalled();
- expect(screen.getByText('statusbarPortUtilization D: 20% U: 10%')).toBeInTheDocument();
+ expect(screen.getByText(/statusbarPortUtilization D: 20% U: 10%/i)).toBeInTheDocument();
});
});
diff --git a/src/Components/Statusbar/index.jsx b/src/Components/Statusbar/index.jsx
index 31a544964..89b5d54ca 100644
--- a/src/Components/Statusbar/index.jsx
+++ b/src/Components/Statusbar/index.jsx
@@ -2,9 +2,11 @@ import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
-import { useInterval } from '../../utils/helpers/React';
+import Box from '@mui/material/Box';
+import Grid from '@mui/material/Grid';
+import Typography from '@mui/material/Typography';
-import './style.scss';
+import { useInterval } from '../../utils/helpers/React';
function Statusbar({
getUtilization,
@@ -26,19 +28,48 @@ function Statusbar({
}, 1000);
return (
-
-
- {`${t('statusbarPortUtilization')} D: ${utilization.down}% U: ${utilization.up}%`}
-
-
-
- {`${t('statusbarPacketError')} ${packetErrors}`}
-
-
-
- {version}
-
-
+
+
+
+
+
+ {`${t('statusbarPortUtilization')} D: ${utilization.down}% U: ${utilization.up}%`}
+
+ |
+
+ {`${t('statusbarPacketError')} ${packetErrors}`}
+
+
+
+
+
+ {version}
+
+
+
+
+
);
}
Statusbar.defaultProps = { getUtilization: null };
diff --git a/src/Components/Statusbar/style.scss b/src/Components/Statusbar/style.scss
deleted file mode 100644
index 96a8c1f3c..000000000
--- a/src/Components/Statusbar/style.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-.status-bar {
- position: fixed;
- bottom: 0px;
- width: calc(100% - 20px);
- height: 20px;
- line-height: 20px;
- padding: 0 10px 0 10px;
- border-top: 1px solid #7d7d79;
- background-color: #bfbeb5;
-
- span {
- display: block;
- float: left;
- padding-right: 10px;
- margin-right: 10px;
- border-right: 1px solid #7d7d79;
- }
-
- .status-bar__version {
- float: right;
- margin: 0;
- padding: 0;
- border: 0;
- }
-
- @media only screen and (max-width: 600px) {
- & {
- display: flex;
- justify-content: center;
-
- span {
- float: none;
- }
- }
- }
-}
diff --git a/src/Components/Warning/index.jsx b/src/Components/Warning/index.jsx
new file mode 100644
index 000000000..4b51fb1dd
--- /dev/null
+++ b/src/Components/Warning/index.jsx
@@ -0,0 +1,31 @@
+import { useTranslation } from 'react-i18next';
+import React from 'react';
+import ReactMarkdown from 'react-markdown';
+
+import Alert from '@mui/material/Alert';
+import AlertTitle from '@mui/material/AlertTitle';
+import Card from '@mui/material/Card';
+
+function Warning() {
+ const { t } = useTranslation('common');
+
+ return (
+
+
+
+ {t('note')}
+
+
+
+ {t('notePropsOff')}
+
+
+
+ {t('noteConnectPower')}
+
+
+
+ );
+}
+
+export default Warning;
diff --git a/src/Containers/App/__tests__/index.test.jsx b/src/Containers/App/__tests__/index.test.jsx
index d05243eea..ff05165b4 100644
--- a/src/Containers/App/__tests__/index.test.jsx
+++ b/src/Containers/App/__tests__/index.test.jsx
@@ -21,24 +21,37 @@ describe('App', () => {
App = require('../').default;
});
- test('should render container', () => {
+ test('should render', () => {
render(
);
+
expect(screen.getByRole('button', { name: /settings/i })).toBeInTheDocument();
expect(screen.getByAltText(/Discord/i)).toBeInTheDocument();
- // Ensure that a warning is displayed when no web Serial is detected
expect(screen.getByText(/is not supported on your browser/i)).toBeInTheDocument();
- // Ensure that the footer is there
expect(screen.getByText(/statusbarPortUtilization/i)).toBeInTheDocument();
expect(screen.getByText(/statusbarPacketError/i)).toBeInTheDocument();
- // Click the Settings
+ expect(screen.getByText(/cookieText/i)).toBeInTheDocument();
+ });
+
+ test('should allow to open the settings', () => {
+ render(
);
+
userEvent.click(screen.getByRole('button', { name: /settings/i }));
expect(screen.getByText(/settingsHeader/i)).toBeInTheDocument();
+ });
+
+ test('should allow to open the melody editor', () => {
+ render(
);
- // Open Melody editor
userEvent.click(screen.getByRole('button', { name: /openMelodyEditor/i }));
expect(screen.getByText(/melodyEditorHeader/i)).toBeInTheDocument();
});
+
+ test('should be possible to allow cookies', () => {
+ render(
);
+
+ userEvent.click(screen.getByRole('button', { name: /allow/i }));
+ });
});
diff --git a/src/Containers/App/index.jsx b/src/Containers/App/index.jsx
index 4a51fcd5b..8b4fa0fb5 100644
--- a/src/Containers/App/index.jsx
+++ b/src/Containers/App/index.jsx
@@ -5,6 +5,11 @@ import Rtttl from 'bluejay-rtttl-parse';
import dateFormat from 'dateformat';
import i18next from 'i18next';
+import '@fontsource/roboto/300.css';
+import '@fontsource/roboto/400.css';
+import '@fontsource/roboto/500.css';
+import '@fontsource/roboto/700.css';
+
import { fetchHexCached } from '../../utils/Fetch';
import { getMasterSettings } from '../../utils/helpers/Settings';
import { delay } from '../../utils/helpers/General';
@@ -15,6 +20,7 @@ import Serial from '../../utils/Serial';
import sources from '../../sources';
import {
clearLog,
+ loadCookie,
loadLanguage,
loadLog,
loadMelodies,
@@ -35,6 +41,7 @@ class App extends Component {
this.serialApi = loadSerialApi();
this.gtmActive = false;
+
this.serial = undefined;
this.lastConnected = 0;
@@ -44,6 +51,7 @@ class App extends Component {
show: false,
settings: loadSettings(),
},
+ cookieDone: loadCookie(),
escs: {
connected: 0,
master: {},
@@ -205,7 +213,10 @@ class App extends Component {
}
const log = [ ...serial.log ];
- log.push(this.formatLogMessage(translation));
+ log.push({
+ html: translation,
+ date: new Date(),
+ });
this.setSerial({ log });
};
@@ -231,26 +242,6 @@ class App extends Component {
return configs;
};
- formatLogMessage = (html) => {
- const now = new Date();
- const formattedDate = dateFormat(now, 'yyyy-mm-dd @ ');
- const formattedTime = dateFormat(now, 'HH:MM:ss -- ');
-
- return (
-
-
- {formattedDate}
-
-
-
- {formattedTime}
-
-
- {html}
-
- );
- };
-
flash = async(text, force, migrate) => {
const { escs } = this.state;
const individual = [ ...escs.individual ];
@@ -863,13 +854,16 @@ class App extends Component {
await this.serial.spinMotor(index, speed);
};
- handleCookieAccept = () => {
+ handleCookieAccept = (value) => {
if(!this.gtmActive) {
const tagManagerArgs = { gtmId: process.env.REACT_APP_GTM_ID };
TagManager.initialize(tagManagerArgs);
- this.gtmActive = true;
+ this.gtmActive = value;
}
+
+ localStorage.setItem('cookie', true);
+ this.setState({ cookieDone: true });
};
handleLanguageSelection = (e) => {
@@ -999,6 +993,7 @@ class App extends Component {
escs,
actions,
configs,
+ cookieDone,
language,
melodies,
msp,
@@ -1024,6 +1019,7 @@ class App extends Component {
show: appSettings.show,
}}
configs={configs}
+ cookieDone={cookieDone}
escs={{
actions: {
handleMasterUpdate: this.handleSettingsUpdate,
diff --git a/src/changelog.json b/src/changelog.json
index 961ae2637..82180c220 100644
--- a/src/changelog.json
+++ b/src/changelog.json
@@ -1,4 +1,10 @@
[
+ {
+ "title": "Unreleased - MUI",
+ "items": [
+ "Enhancement: Refactoring to use MUI components"
+ ]
+ },
{
"title": "0.24.0",
"items": [
diff --git a/src/sources/BlheliS/__tests__/index.test.js b/src/sources/BlheliS/__tests__/index.test.js
index 2e6726bd3..49644819f 100644
--- a/src/sources/BlheliS/__tests__/index.test.js
+++ b/src/sources/BlheliS/__tests__/index.test.js
@@ -2,10 +2,9 @@ import config from '../';
const SETTINGS_DESCRIPTIONS = config.getSettingsDescriptions();
-describe('BLHeli', () => {
+describe('BLHeli_S', () => {
it('should handle conditional visibility with general settings', () => {
const keys = Object.keys(SETTINGS_DESCRIPTIONS.COMMON);
- const settings = { MOTOR_DIRECTION: 3 };
const visibleIf = [];
for(let i = 0; i < keys.length; i += 1) {
@@ -50,6 +49,30 @@ describe('BLHeli', () => {
expect(ledFunction(settings)).not.toBeTruthy();
});
+ it('should show LED settings with supported layout', () => {
+ const keys = Object.keys(SETTINGS_DESCRIPTIONS.INDIVIDUAL);
+ const settings = {
+ GOVERNOR_MODE: 3,
+ MOTOR_DIRECTION: 3,
+ LAYOUT: '#E-H-90#',
+ };
+
+ let ledFunction = null;
+ for(let i = 0; i < keys.length; i += 1) {
+ const base = SETTINGS_DESCRIPTIONS.INDIVIDUAL[keys[i]].base;
+ for(let j = 0; j < base.length; j += 1) {
+ const current = base[j];
+ if(current.visibleIf) {
+ if(current.name === 'LED_CONTROL') {
+ ledFunction = current.visibleIf;
+ }
+ }
+ }
+ }
+
+ expect(ledFunction(settings)).toBeTruthy();
+ });
+
it('should return display name', () => {
const flash = {
settings: {
diff --git a/src/sources/BlheliS/escs.json b/src/sources/BlheliS/escs.json
index 5d0e6eb21..7f8f2e440 100644
--- a/src/sources/BlheliS/escs.json
+++ b/src/sources/BlheliS/escs.json
@@ -1,137 +1,1757 @@
{
- "mcus": [
- { "name": "EFM8BB10x", "signature": "0xE8B1", "page_size": 512, "flash_size": 8192 },
- { "name": "EFM8BB21x", "signature": "0xE8B2", "page_size": 512, "flash_size": 8192 }
- ],
- "layouts": {
- "#A_L_00#": { "name": "A-L-0" }, "#A_L_05#": { "name": "A-L-5" }, "#A_L_10#": { "name": "A-L-10" }, "#A_L_15#": { "name": "A-L-15" }, "#A_L_20#": { "name": "A-L-20" }, "#A_L_25#": { "name": "A-L-25" },
- "#A_L_30#": { "name": "A-L-30" }, "#A_L_40#": { "name": "A-L-40" }, "#A_L_50#": { "name": "A-L-50" }, "#A_L_70#": { "name": "A-L-70" }, "#A_L_90#": { "name": "A-L-90" },
- "#A_H_00#": { "name": "A-H-0" }, "#A_H_05#": { "name": "A-H-5" }, "#A_H_10#": { "name": "A-H-10" }, "#A_H_15#": { "name": "A-H-15" }, "#A_H_20#": { "name": "A-H-20" }, "#A_H_25#": { "name": "A-H-25" },
- "#A_H_30#": { "name": "A-H-30" }, "#A_H_40#": { "name": "A-H-40" }, "#A_H_50#": { "name": "A-H-50" }, "#A_H_70#": { "name": "A-H-70" }, "#A_H_90#": { "name": "A-H-90" },
-
- "#B_L_00#": { "name": "B-L-0" }, "#B_L_05#": { "name": "B-L-5" }, "#B_L_10#": { "name": "B-L-10" }, "#B_L_15#": { "name": "B-L-15" }, "#B_L_20#": { "name": "B-L-20" }, "#B_L_25#": { "name": "B-L-25" },
- "#B_L_30#": { "name": "B-L-30" }, "#B_L_40#": { "name": "B-L-40" }, "#B_L_50#": { "name": "B-L-50" }, "#B_L_70#": { "name": "B-L-70" }, "#B_L_90#": { "name": "B-L-90" },
- "#B_H_00#": { "name": "B-H-0" }, "#B_H_05#": { "name": "B-H-5" }, "#B_H_10#": { "name": "B-H-10" }, "#B_H_15#": { "name": "B-H-15" }, "#B_H_20#": { "name": "B-H-20" }, "#B_H_25#": { "name": "B-H-25" },
- "#B_H_30#": { "name": "B-H-30" }, "#B_H_40#": { "name": "B-H-40" }, "#B_H_50#": { "name": "B-H-50" }, "#B_H_70#": { "name": "B-H-70" }, "#B_H_90#": { "name": "B-H-90" },
-
- "#C_L_00#": { "name": "C-L-0" }, "#C_L_05#": { "name": "C-L-5" }, "#C_L_10#": { "name": "C-L-10" }, "#C_L_15#": { "name": "C-L-15" }, "#C_L_20#": { "name": "C-L-20" }, "#C_L_25#": { "name": "C-L-25" },
- "#C_L_30#": { "name": "C-L-30" }, "#C_L_40#": { "name": "C-L-40" }, "#C_L_50#": { "name": "C-L-50" }, "#C_L_70#": { "name": "C-L-70" }, "#C_L_90#": { "name": "C-L-90" },
- "#C_H_00#": { "name": "C-H-0" }, "#C_H_05#": { "name": "C-H-5" }, "#C_H_10#": { "name": "C-H-10" }, "#C_H_15#": { "name": "C-H-15" }, "#C_H_20#": { "name": "C-H-20" }, "#C_H_25#": { "name": "C-H-25" },
- "#C_H_30#": { "name": "C-H-30" }, "#C_H_40#": { "name": "C-H-40" }, "#C_H_50#": { "name": "C-H-50" }, "#C_H_70#": { "name": "C-H-70" }, "#C_H_90#": { "name": "C-H-90" },
-
- "#D_L_00#": { "name": "D-L-0" }, "#D_L_05#": { "name": "D-L-5" }, "#D_L_10#": { "name": "D-L-10" }, "#D_L_15#": { "name": "D-L-15" }, "#D_L_20#": { "name": "D-L-20" }, "#D_L_25#": { "name": "D-L-25" },
- "#D_L_30#": { "name": "D-L-30" }, "#D_L_40#": { "name": "D-L-40" }, "#D_L_50#": { "name": "D-L-50" }, "#D_L_70#": { "name": "D-L-70" }, "#D_L_90#": { "name": "D-L-90" },
- "#D_H_00#": { "name": "D-H-0" }, "#D_H_05#": { "name": "D-H-5" }, "#D_H_10#": { "name": "D-H-10" }, "#D_H_15#": { "name": "D-H-15" }, "#D_H_20#": { "name": "D-H-20" }, "#D_H_25#": { "name": "D-H-25" },
- "#D_H_30#": { "name": "D-H-30" }, "#D_H_40#": { "name": "D-H-40" }, "#D_H_50#": { "name": "D-H-50" }, "#D_H_70#": { "name": "D-H-70" }, "#D_H_90#": { "name": "D-H-90" },
-
- "#E_L_00#": { "name": "E-L-0" }, "#E_L_05#": { "name": "E-L-5" }, "#E_L_10#": { "name": "E-L-10" }, "#E_L_15#": { "name": "E-L-15" }, "#E_L_20#": { "name": "E-L-20" }, "#E_L_25#": { "name": "E-L-25" },
- "#E_L_30#": { "name": "E-L-30" }, "#E_L_40#": { "name": "E-L-40" }, "#E_L_50#": { "name": "E-L-50" }, "#E_L_70#": { "name": "E-L-70" }, "#E_L_90#": { "name": "E-L-90" },
- "#E_H_00#": { "name": "E-H-0" }, "#E_H_05#": { "name": "E-H-5" }, "#E_H_10#": { "name": "E-H-10" }, "#E_H_15#": { "name": "E-H-15" }, "#E_H_20#": { "name": "E-H-20" }, "#E_H_25#": { "name": "E-H-25" },
- "#E_H_30#": { "name": "E-H-30" }, "#E_H_40#": { "name": "E-H-40" }, "#E_H_50#": { "name": "E-H-50" }, "#E_H_70#": { "name": "E-H-70" }, "#E_H_90#": { "name": "E-H-90" },
-
- "#F_L_00#": { "name": "F-L-0" }, "#F_L_05#": { "name": "F-L-5" }, "#F_L_10#": { "name": "F-L-10" }, "#F_L_15#": { "name": "F-L-15" }, "#F_L_20#": { "name": "F-L-20" }, "#F_L_25#": { "name": "F-L-25" },
- "#F_L_30#": { "name": "F-L-30" }, "#F_L_40#": { "name": "F-L-40" }, "#F_L_50#": { "name": "F-L-50" }, "#F_L_70#": { "name": "F-L-70" }, "#F_L_90#": { "name": "F-L-90" },
- "#F_H_00#": { "name": "F-H-0" }, "#F_H_05#": { "name": "F-H-5" }, "#F_H_10#": { "name": "F-H-10" }, "#F_H_15#": { "name": "F-H-15" }, "#F_H_20#": { "name": "F-H-20" }, "#F_H_25#": { "name": "F-H-25" },
- "#F_H_30#": { "name": "F-H-30" }, "#F_H_40#": { "name": "F-H-40" }, "#F_H_50#": { "name": "F-H-50" }, "#F_H_70#": { "name": "F-H-70" }, "#F_H_90#": { "name": "F-H-90" },
-
- "#G_L_00#": { "name": "G-L-0" }, "#G_L_05#": { "name": "G-L-5" }, "#G_L_10#": { "name": "G-L-10" }, "#G_L_15#": { "name": "G-L-15" }, "#G_L_20#": { "name": "G-L-20" }, "#G_L_25#": { "name": "G-L-25" },
- "#G_L_30#": { "name": "G-L-30" }, "#G_L_40#": { "name": "G-L-40" }, "#G_L_50#": { "name": "G-L-50" }, "#G_L_70#": { "name": "G-L-70" }, "#G_L_90#": { "name": "G-L-90" },
- "#G_H_00#": { "name": "G-H-0" }, "#G_H_05#": { "name": "G-H-5" }, "#G_H_10#": { "name": "G-H-10" }, "#G_H_15#": { "name": "G-H-15" }, "#G_H_20#": { "name": "G-H-20" }, "#G_H_25#": { "name": "G-H-25" },
- "#G_H_30#": { "name": "G-H-30" }, "#G_H_40#": { "name": "G-H-40" }, "#G_H_50#": { "name": "G-H-50" }, "#G_H_70#": { "name": "G-H-70" }, "#G_H_90#": { "name": "G-H-90" },
-
- "#H_L_00#": { "name": "H-L-0" }, "#H_L_05#": { "name": "H-L-5" }, "#H_L_10#": { "name": "H-L-10" }, "#H_L_15#": { "name": "H-L-15" }, "#H_L_20#": { "name": "H-L-20" }, "#H_L_25#": { "name": "H-L-25" },
- "#H_L_30#": { "name": "H-L-30" }, "#H_L_40#": { "name": "H-L-40" }, "#H_L_50#": { "name": "H-L-50" }, "#H_L_70#": { "name": "H-L-70" }, "#H_L_90#": { "name": "H-L-90" },
- "#H_H_00#": { "name": "H-H-0" }, "#H_H_05#": { "name": "H-H-5" }, "#H_H_10#": { "name": "H-H-10" }, "#H_H_15#": { "name": "H-H-15" }, "#H_H_20#": { "name": "H-H-20" }, "#H_H_25#": { "name": "H-H-25" },
- "#H_H_30#": { "name": "H-H-30" }, "#H_H_40#": { "name": "H-H-40" }, "#H_H_50#": { "name": "H-H-50" }, "#H_H_70#": { "name": "H-H-70" }, "#H_H_90#": { "name": "H-H-90" },
-
- "#I_L_00#": { "name": "I-L-0" }, "#I_L_05#": { "name": "I-L-5" }, "#I_L_10#": { "name": "I-L-10" }, "#I_L_15#": { "name": "I-L-15" }, "#I_L_20#": { "name": "I-L-20" }, "#I_L_25#": { "name": "I-L-25" },
- "#I_L_30#": { "name": "I-L-30" }, "#I_L_40#": { "name": "I-L-40" }, "#I_L_50#": { "name": "I-L-50" }, "#I_L_70#": { "name": "I-L-70" }, "#I_L_90#": { "name": "I-L-90" },
- "#I_H_00#": { "name": "I-H-0" }, "#I_H_05#": { "name": "I-H-5" }, "#I_H_10#": { "name": "I-H-10" }, "#I_H_15#": { "name": "I-H-15" }, "#I_H_20#": { "name": "I-H-20" }, "#I_H_25#": { "name": "I-H-25" },
- "#I_H_30#": { "name": "I-H-30" }, "#I_H_40#": { "name": "I-H-40" }, "#I_H_50#": { "name": "I-H-50" }, "#I_H_70#": { "name": "I-H-70" }, "#I_H_90#": { "name": "I-H-90" },
-
- "#J_L_00#": { "name": "J-L-0" }, "#J_L_05#": { "name": "J-L-5" }, "#J_L_10#": { "name": "J-L-10" }, "#J_L_15#": { "name": "J-L-15" }, "#J_L_20#": { "name": "J-L-20" }, "#J_L_25#": { "name": "J-L-25" },
- "#J_L_30#": { "name": "J-L-30" }, "#J_L_40#": { "name": "J-L-40" }, "#J_L_50#": { "name": "J-L-50" }, "#J_L_70#": { "name": "J-L-70" }, "#J_L_90#": { "name": "J-L-90" },
- "#J_H_00#": { "name": "J-H-0" }, "#J_H_05#": { "name": "J-H-5" }, "#J_H_10#": { "name": "J-H-10" }, "#J_H_15#": { "name": "J-H-15" }, "#J_H_20#": { "name": "J-H-20" }, "#J_H_25#": { "name": "J-H-25" },
- "#J_H_30#": { "name": "J-H-30" }, "#J_H_40#": { "name": "J-H-40" }, "#J_H_50#": { "name": "J-H-50" }, "#J_H_70#": { "name": "J-H-70" }, "#J_H_90#": { "name": "J-H-90" },
-
- "#K_L_00#": { "name": "K-L-0" }, "#K_L_05#": { "name": "K-L-5" }, "#K_L_10#": { "name": "K-L-10" }, "#K_L_15#": { "name": "K-L-15" }, "#K_L_20#": { "name": "K-L-20" }, "#K_L_25#": { "name": "K-L-25" },
- "#K_L_30#": { "name": "K-L-30" }, "#K_L_40#": { "name": "K-L-40" }, "#K_L_50#": { "name": "K-L-50" }, "#K_L_70#": { "name": "K-L-70" }, "#K_L_90#": { "name": "K-L-90" },
- "#K_H_00#": { "name": "K-H-0" }, "#K_H_05#": { "name": "K-H-5" }, "#K_H_10#": { "name": "K-H-10" }, "#K_H_15#": { "name": "K-H-15" }, "#K_H_20#": { "name": "K-H-20" }, "#K_H_25#": { "name": "K-H-25" },
- "#K_H_30#": { "name": "K-H-30" }, "#K_H_40#": { "name": "K-H-40" }, "#K_H_50#": { "name": "K-H-50" }, "#K_H_70#": { "name": "K-H-70" }, "#K_H_90#": { "name": "K-H-90" },
-
- "#L_L_00#": { "name": "L-L-0" }, "#L_L_05#": { "name": "L-L-5" }, "#L_L_10#": { "name": "L-L-10" }, "#L_L_15#": { "name": "L-L-15" }, "#L_L_20#": { "name": "L-L-20" }, "#L_L_25#": { "name": "L-L-25" },
- "#L_L_30#": { "name": "L-L-30" }, "#L_L_40#": { "name": "L-L-40" }, "#L_L_50#": { "name": "L-L-50" }, "#L_L_70#": { "name": "L-L-70" }, "#L_L_90#": { "name": "L-L-90" },
- "#L_H_00#": { "name": "L-H-0" }, "#L_H_05#": { "name": "L-H-5" }, "#L_H_10#": { "name": "L-H-10" }, "#L_H_15#": { "name": "L-H-15" }, "#L_H_20#": { "name": "L-H-20" }, "#L_H_25#": { "name": "L-H-25" },
- "#L_H_30#": { "name": "L-H-30" }, "#L_H_40#": { "name": "L-H-40" }, "#L_H_50#": { "name": "L-H-50" }, "#L_H_70#": { "name": "L-H-70" }, "#L_H_90#": { "name": "L-H-90" },
-
- "#M_L_00#": { "name": "M-L-0" }, "#M_L_05#": { "name": "M-L-5" }, "#M_L_10#": { "name": "M-L-10" }, "#M_L_15#": { "name": "M-L-15" }, "#M_L_20#": { "name": "M-L-20" }, "#M_L_25#": { "name": "M-L-25" },
- "#M_L_30#": { "name": "M-L-30" }, "#M_L_40#": { "name": "M-L-40" }, "#M_L_50#": { "name": "M-L-50" }, "#M_L_70#": { "name": "M-L-70" }, "#M_L_90#": { "name": "M-L-90" },
- "#M_H_00#": { "name": "M-H-0" }, "#M_H_05#": { "name": "M-H-5" }, "#M_H_10#": { "name": "M-H-10" }, "#M_H_15#": { "name": "M-H-15" }, "#M_H_20#": { "name": "M-H-20" }, "#M_H_25#": { "name": "M-H-25" },
- "#M_H_30#": { "name": "M-H-30" }, "#M_H_40#": { "name": "M-H-40" }, "#M_H_50#": { "name": "M-H-50" }, "#M_H_70#": { "name": "M-H-70" }, "#M_H_90#": { "name": "M-H-90" },
-
- "#N_L_00#": { "name": "N-L-0" }, "#N_L_05#": { "name": "N-L-5" }, "#N_L_10#": { "name": "N-L-10" }, "#N_L_15#": { "name": "N-L-15" }, "#N_L_20#": { "name": "N-L-20" }, "#N_L_25#": { "name": "N-L-25" },
- "#N_L_30#": { "name": "N-L-30" }, "#N_L_40#": { "name": "N-L-40" }, "#N_L_50#": { "name": "N-L-50" }, "#N_L_70#": { "name": "N-L-70" }, "#N_L_90#": { "name": "N-L-90" },
- "#N_H_00#": { "name": "N-H-0" }, "#N_H_05#": { "name": "N-H-5" }, "#N_H_10#": { "name": "N-H-10" }, "#N_H_15#": { "name": "N-H-15" }, "#N_H_20#": { "name": "N-H-20" }, "#N_H_25#": { "name": "N-H-25" },
- "#N_H_30#": { "name": "N-H-30" }, "#N_H_40#": { "name": "N-H-40" }, "#N_H_50#": { "name": "N-H-50" }, "#N_H_70#": { "name": "N-H-70" }, "#N_H_90#": { "name": "N-H-90" },
-
- "#O_L_00#": { "name": "O-L-0" }, "#O_L_05#": { "name": "O-L-5" }, "#O_L_10#": { "name": "O-L-10" }, "#O_L_15#": { "name": "O-L-15" }, "#O_L_20#": { "name": "O-L-20" }, "#O_L_25#": { "name": "O-L-25" },
- "#O_L_30#": { "name": "O-L-30" }, "#O_L_40#": { "name": "O-L-40" }, "#O_L_50#": { "name": "O-L-50" }, "#O_L_70#": { "name": "O-L-70" }, "#O_L_90#": { "name": "O-L-90" },
- "#O_H_00#": { "name": "O-H-0" }, "#O_H_05#": { "name": "O-H-5" }, "#O_H_10#": { "name": "O-H-10" }, "#O_H_15#": { "name": "O-H-15" }, "#O_H_20#": { "name": "O-H-20" }, "#O_H_25#": { "name": "O-H-25" },
- "#O_H_30#": { "name": "O-H-30" }, "#O_H_40#": { "name": "O-H-40" }, "#O_H_50#": { "name": "O-H-50" }, "#O_H_70#": { "name": "O-H-70" }, "#O_H_90#": { "name": "O-H-90" },
-
- "#P_L_00#": { "name": "P-L-0" }, "#P_L_05#": { "name": "P-L-5" }, "#P_L_10#": { "name": "P-L-10" }, "#P_L_15#": { "name": "P-L-15" }, "#P_L_20#": { "name": "P-L-20" }, "#P_L_25#": { "name": "P-L-25" },
- "#P_L_30#": { "name": "P-L-30" }, "#P_L_40#": { "name": "P-L-40" }, "#P_L_50#": { "name": "P-L-50" }, "#P_L_70#": { "name": "P-L-70" }, "#P_L_90#": { "name": "P-L-90" },
- "#P_H_00#": { "name": "P-H-0" }, "#P_H_05#": { "name": "P-H-5" }, "#P_H_10#": { "name": "P-H-10" }, "#P_H_15#": { "name": "P-H-15" }, "#P_H_20#": { "name": "P-H-20" }, "#P_H_25#": { "name": "P-H-25" },
- "#P_H_30#": { "name": "P-H-30" }, "#P_H_40#": { "name": "P-H-40" }, "#P_H_50#": { "name": "P-H-50" }, "#P_H_70#": { "name": "P-H-70" }, "#P_H_90#": { "name": "P-H-90" },
-
- "#Q_L_00#": { "name": "Q-L-0" }, "#Q_L_05#": { "name": "Q-L-5" }, "#Q_L_10#": { "name": "Q-L-10" }, "#Q_L_15#": { "name": "Q-L-15" }, "#Q_L_20#": { "name": "Q-L-20" }, "#Q_L_25#": { "name": "Q-L-25" },
- "#Q_L_30#": { "name": "Q-L-30" }, "#Q_L_40#": { "name": "Q-L-40" }, "#Q_L_50#": { "name": "Q-L-50" }, "#Q_L_70#": { "name": "Q-L-70" }, "#Q_L_90#": { "name": "Q-L-90" },
- "#Q_H_00#": { "name": "Q-H-0" }, "#Q_H_05#": { "name": "Q-H-5" }, "#Q_H_10#": { "name": "Q-H-10" }, "#Q_H_15#": { "name": "Q-H-15" }, "#Q_H_20#": { "name": "Q-H-20" }, "#Q_H_25#": { "name": "Q-H-25" },
- "#Q_H_30#": { "name": "Q-H-30" }, "#Q_H_40#": { "name": "Q-H-40" }, "#Q_H_50#": { "name": "Q-H-50" }, "#Q_H_70#": { "name": "Q-H-70" }, "#Q_H_90#": { "name": "Q-H-90" },
-
- "#R_L_00#": { "name": "R-L-0" }, "#R_L_05#": { "name": "R-L-5" }, "#R_L_10#": { "name": "R-L-10" }, "#R_L_15#": { "name": "R-L-15" }, "#R_L_20#": { "name": "R-L-20" }, "#R_L_25#": { "name": "R-L-25" },
- "#R_L_30#": { "name": "R-L-30" }, "#R_L_40#": { "name": "R-L-40" }, "#R_L_50#": { "name": "R-L-50" }, "#R_L_70#": { "name": "R-L-70" }, "#R_L_90#": { "name": "R-L-90" },
- "#R_H_00#": { "name": "R-H-0" }, "#R_H_05#": { "name": "R-H-5" }, "#R_H_10#": { "name": "R-H-10" }, "#R_H_15#": { "name": "R-H-15" }, "#R_H_20#": { "name": "R-H-20" }, "#R_H_25#": { "name": "R-H-25" },
- "#R_H_30#": { "name": "R-H-30" }, "#R_H_40#": { "name": "R-H-40" }, "#R_H_50#": { "name": "R-H-50" }, "#R_H_70#": { "name": "R-H-70" }, "#R_H_90#": { "name": "R-H-90" },
-
- "#S_L_00#": { "name": "S-L-0" }, "#S_L_05#": { "name": "S-L-5" }, "#S_L_10#": { "name": "S-L-10" }, "#S_L_15#": { "name": "S-L-15" }, "#S_L_20#": { "name": "S-L-20" }, "#S_L_25#": { "name": "S-L-25" },
- "#S_L_30#": { "name": "S-L-30" }, "#S_L_40#": { "name": "S-L-40" }, "#S_L_50#": { "name": "S-L-50" }, "#S_L_70#": { "name": "S-L-70" }, "#S_L_90#": { "name": "S-L-90" },
- "#S_H_00#": { "name": "S-H-0" }, "#S_H_05#": { "name": "S-H-5" }, "#S_H_10#": { "name": "S-H-10" }, "#S_H_15#": { "name": "S-H-15" }, "#S_H_20#": { "name": "S-H-20" }, "#S_H_25#": { "name": "S-H-25" },
- "#S_H_30#": { "name": "S-H-30" }, "#S_H_40#": { "name": "S-H-40" }, "#S_H_50#": { "name": "S-H-50" }, "#S_H_70#": { "name": "S-H-70" }, "#S_H_90#": { "name": "S-H-90" },
-
- "#T_L_00#": { "name": "T-L-0" }, "#T_L_05#": { "name": "T-L-5" }, "#T_L_10#": { "name": "T-L-10" }, "#T_L_15#": { "name": "T-L-15" }, "#T_L_20#": { "name": "T-L-20" }, "#T_L_25#": { "name": "T-L-25" },
- "#T_L_30#": { "name": "T-L-30" }, "#T_L_40#": { "name": "T-L-40" }, "#T_L_50#": { "name": "T-L-50" }, "#T_L_70#": { "name": "T-L-70" }, "#T_L_90#": { "name": "T-L-90" },
- "#T_H_00#": { "name": "T-H-0" }, "#T_H_05#": { "name": "T-H-5" }, "#T_H_10#": { "name": "T-H-10" }, "#T_H_15#": { "name": "T-H-15" }, "#T_H_20#": { "name": "T-H-20" }, "#T_H_25#": { "name": "T-H-25" },
- "#T_H_30#": { "name": "T-H-30" }, "#T_H_40#": { "name": "T-H-40" }, "#T_H_50#": { "name": "T-H-50" }, "#T_H_70#": { "name": "T-H-70" }, "#T_H_90#": { "name": "T-H-90" },
-
- "#U_L_00#": { "name": "U-L-0" }, "#U_L_05#": { "name": "U-L-5" }, "#U_L_10#": { "name": "U-L-10" }, "#U_L_15#": { "name": "U-L-15" }, "#U_L_20#": { "name": "U-L-20" }, "#U_L_25#": { "name": "U-L-25" },
- "#U_L_30#": { "name": "U-L-30" }, "#U_L_40#": { "name": "U-L-40" }, "#U_L_50#": { "name": "U-L-50" }, "#U_L_70#": { "name": "U-L-70" }, "#U_L_90#": { "name": "U-L-90" },
- "#U_H_00#": { "name": "U-H-0" }, "#U_H_05#": { "name": "U-H-5" }, "#U_H_10#": { "name": "U-H-10" }, "#U_H_15#": { "name": "U-H-15" }, "#U_H_20#": { "name": "U-H-20" }, "#U_H_25#": { "name": "U-H-25" },
- "#U_H_30#": { "name": "U-H-30" }, "#U_H_40#": { "name": "U-H-40" }, "#U_H_50#": { "name": "U-H-50" }, "#U_H_70#": { "name": "U-H-70" }, "#U_H_90#": { "name": "U-H-90" },
-
- "#V_L_00#": { "name": "V-L-0" }, "#V_L_05#": { "name": "V-L-5" }, "#V_L_10#": { "name": "V-L-10" }, "#V_L_15#": { "name": "V-L-15" }, "#V_L_20#": { "name": "V-L-20" }, "#V_L_25#": { "name": "V-L-25" },
- "#V_L_30#": { "name": "V-L-30" }, "#V_L_40#": { "name": "V-L-40" }, "#V_L_50#": { "name": "V-L-50" }, "#V_L_70#": { "name": "V-L-70" }, "#V_L_90#": { "name": "V-L-90" },
- "#V_H_00#": { "name": "V-H-0" }, "#V_H_05#": { "name": "V-H-5" }, "#V_H_10#": { "name": "V-H-10" }, "#V_H_15#": { "name": "V-H-15" }, "#V_H_20#": { "name": "V-H-20" }, "#V_H_25#": { "name": "V-H-25" },
- "#V_H_30#": { "name": "V-H-30" }, "#V_H_40#": { "name": "V-H-40" }, "#V_H_50#": { "name": "V-H-50" }, "#V_H_70#": { "name": "V-H-70" }, "#V_H_90#": { "name": "V-H-90" },
-
- "#W_L_00#": { "name": "W-L-0" }, "#W_L_05#": { "name": "W-L-5" }, "#W_L_10#": { "name": "W-L-10" }, "#W_L_15#": { "name": "W-L-15" }, "#W_L_20#": { "name": "W-L-20" }, "#W_L_25#": { "name": "W-L-25" },
- "#W_L_30#": { "name": "W-L-30" }, "#W_L_40#": { "name": "W-L-40" }, "#W_L_50#": { "name": "W-L-50" }, "#W_L_70#": { "name": "W-L-70" }, "#W_L_90#": { "name": "W-L-90" },
- "#W_H_00#": { "name": "W-H-0" }, "#W_H_05#": { "name": "W-H-5" }, "#W_H_10#": { "name": "W-H-10" }, "#W_H_15#": { "name": "W-H-15" }, "#W_H_20#": { "name": "W-H-20" }, "#W_H_25#": { "name": "W-H-25" },
- "#W_H_30#": { "name": "W-H-30" }, "#W_H_40#": { "name": "W-H-40" }, "#W_H_50#": { "name": "W-H-50" }, "#W_H_70#": { "name": "W-H-70" }, "#W_H_90#": { "name": "W-H-90" },
-
- "#X_L_00#": { "name": "X-L-0" }, "#X_L_05#": { "name": "X-L-5" }, "#X_L_10#": { "name": "X-L-10" }, "#X_L_15#": { "name": "X-L-15" }, "#X_L_20#": { "name": "X-L-20" }, "#X_L_25#": { "name": "X-L-25" },
- "#X_L_30#": { "name": "X-L-30" }, "#X_L_40#": { "name": "X-L-40" }, "#X_L_50#": { "name": "X-L-50" }, "#X_L_70#": { "name": "X-L-70" }, "#X_L_90#": { "name": "X-L-90" },
- "#X_H_00#": { "name": "X-H-0" }, "#X_H_05#": { "name": "X-H-5" }, "#X_H_10#": { "name": "X-H-10" }, "#X_H_15#": { "name": "X-H-15" }, "#X_H_20#": { "name": "X-H-20" }, "#X_H_25#": { "name": "X-H-25" },
- "#X_H_30#": { "name": "X-H-30" }, "#X_H_40#": { "name": "X-H-40" }, "#X_H_50#": { "name": "X-H-50" }, "#X_H_70#": { "name": "X-H-70" }, "#X_H_90#": { "name": "X-H-90" },
-
- "#Y_L_00#": { "name": "Y-L-0" }, "#Y_L_05#": { "name": "Y-L-5" }, "#Y_L_10#": { "name": "Y-L-10" }, "#Y_L_15#": { "name": "Y-L-15" }, "#Y_L_20#": { "name": "Y-L-20" }, "#Y_L_25#": { "name": "Y-L-25" },
- "#Y_L_30#": { "name": "Y-L-30" }, "#Y_L_40#": { "name": "Y-L-40" }, "#Y_L_50#": { "name": "Y-L-50" }, "#Y_L_70#": { "name": "Y-L-70" }, "#Y_L_90#": { "name": "Y-L-90" },
- "#Y_H_00#": { "name": "Y-H-0" }, "#Y_H_05#": { "name": "Y-H-5" }, "#Y_H_10#": { "name": "Y-H-10" }, "#Y_H_15#": { "name": "Y-H-15" }, "#Y_H_20#": { "name": "Y-H-20" }, "#Y_H_25#": { "name": "Y-H-25" },
- "#Y_H_30#": { "name": "Y-H-30" }, "#Y_H_40#": { "name": "Y-H-40" }, "#Y_H_50#": { "name": "Y-H-50" }, "#Y_H_70#": { "name": "Y-H-70" }, "#Y_H_90#": { "name": "Y-H-90" },
-
- "#Z_L_00#": { "name": "Z-L-0" }, "#Z_L_05#": { "name": "Z-L-5" }, "#Z_L_10#": { "name": "Z-L-10" }, "#Z_L_15#": { "name": "Z-L-15" }, "#Z_L_20#": { "name": "Z-L-20" }, "#Z_L_25#": { "name": "Z-L-25" },
- "#Z_L_30#": { "name": "Z-L-30" }, "#Z_L_40#": { "name": "Z-L-40" }, "#Z_L_50#": { "name": "Z-L-50" }, "#Z_L_70#": { "name": "Z-L-70" }, "#Z_L_90#": { "name": "Z-L-90" },
- "#Z_H_00#": { "name": "Z-H-0" }, "#Z_H_05#": { "name": "Z-H-5" }, "#Z_H_10#": { "name": "Z-H-10" }, "#Z_H_15#": { "name": "Z-H-15" }, "#Z_H_20#": { "name": "Z-H-20" }, "#Z_H_25#": { "name": "Z-H-25" },
- "#Z_H_30#": { "name": "Z-H-30" }, "#Z_H_40#": { "name": "Z-H-40" }, "#Z_H_50#": { "name": "Z-H-50" }, "#Z_H_70#": { "name": "Z-H-70" }, "#Z_H_90#": { "name": "Z-H-90" }
+ "mcus":[
+ {
+ "name":"EFM8BB10x",
+ "signature":"0xE8B1",
+ "page_size":512,
+ "flash_size":8192
+ },
+ {
+ "name":"EFM8BB21x",
+ "signature":"0xE8B2",
+ "page_size":512,
+ "flash_size":8192
+ }
+ ],
+ "layouts":{
+ "#A_L_00#":{
+ "name":"A-L-0"
+ },
+ "#A_L_05#":{
+ "name":"A-L-5"
+ },
+ "#A_L_10#":{
+ "name":"A-L-10"
+ },
+ "#A_L_15#":{
+ "name":"A-L-15"
+ },
+ "#A_L_20#":{
+ "name":"A-L-20"
+ },
+ "#A_L_25#":{
+ "name":"A-L-25"
+ },
+ "#A_L_30#":{
+ "name":"A-L-30"
+ },
+ "#A_L_40#":{
+ "name":"A-L-40"
+ },
+ "#A_L_50#":{
+ "name":"A-L-50"
+ },
+ "#A_L_70#":{
+ "name":"A-L-70"
+ },
+ "#A_L_90#":{
+ "name":"A-L-90"
+ },
+ "#A_H_00#":{
+ "name":"A-H-0"
+ },
+ "#A_H_05#":{
+ "name":"A-H-5"
+ },
+ "#A_H_10#":{
+ "name":"A-H-10"
+ },
+ "#A_H_15#":{
+ "name":"A-H-15"
+ },
+ "#A_H_20#":{
+ "name":"A-H-20"
+ },
+ "#A_H_25#":{
+ "name":"A-H-25"
+ },
+ "#A_H_30#":{
+ "name":"A-H-30"
+ },
+ "#A_H_40#":{
+ "name":"A-H-40"
+ },
+ "#A_H_50#":{
+ "name":"A-H-50"
+ },
+ "#A_H_70#":{
+ "name":"A-H-70"
+ },
+ "#A_H_90#":{
+ "name":"A-H-90"
+ },
+ "#B_L_00#":{
+ "name":"B-L-0"
+ },
+ "#B_L_05#":{
+ "name":"B-L-5"
+ },
+ "#B_L_10#":{
+ "name":"B-L-10"
+ },
+ "#B_L_15#":{
+ "name":"B-L-15"
+ },
+ "#B_L_20#":{
+ "name":"B-L-20"
+ },
+ "#B_L_25#":{
+ "name":"B-L-25"
+ },
+ "#B_L_30#":{
+ "name":"B-L-30"
+ },
+ "#B_L_40#":{
+ "name":"B-L-40"
+ },
+ "#B_L_50#":{
+ "name":"B-L-50"
+ },
+ "#B_L_70#":{
+ "name":"B-L-70"
+ },
+ "#B_L_90#":{
+ "name":"B-L-90"
+ },
+ "#B_H_00#":{
+ "name":"B-H-0"
+ },
+ "#B_H_05#":{
+ "name":"B-H-5"
+ },
+ "#B_H_10#":{
+ "name":"B-H-10"
+ },
+ "#B_H_15#":{
+ "name":"B-H-15"
+ },
+ "#B_H_20#":{
+ "name":"B-H-20"
+ },
+ "#B_H_25#":{
+ "name":"B-H-25"
+ },
+ "#B_H_30#":{
+ "name":"B-H-30"
+ },
+ "#B_H_40#":{
+ "name":"B-H-40"
+ },
+ "#B_H_50#":{
+ "name":"B-H-50"
+ },
+ "#B_H_70#":{
+ "name":"B-H-70"
+ },
+ "#B_H_90#":{
+ "name":"B-H-90"
+ },
+ "#C_L_00#":{
+ "name":"C-L-0"
+ },
+ "#C_L_05#":{
+ "name":"C-L-5"
+ },
+ "#C_L_10#":{
+ "name":"C-L-10"
+ },
+ "#C_L_15#":{
+ "name":"C-L-15"
+ },
+ "#C_L_20#":{
+ "name":"C-L-20"
+ },
+ "#C_L_25#":{
+ "name":"C-L-25"
+ },
+ "#C_L_30#":{
+ "name":"C-L-30"
+ },
+ "#C_L_40#":{
+ "name":"C-L-40"
+ },
+ "#C_L_50#":{
+ "name":"C-L-50"
+ },
+ "#C_L_70#":{
+ "name":"C-L-70"
+ },
+ "#C_L_90#":{
+ "name":"C-L-90"
+ },
+ "#C_H_00#":{
+ "name":"C-H-0"
+ },
+ "#C_H_05#":{
+ "name":"C-H-5"
+ },
+ "#C_H_10#":{
+ "name":"C-H-10"
+ },
+ "#C_H_15#":{
+ "name":"C-H-15"
+ },
+ "#C_H_20#":{
+ "name":"C-H-20"
+ },
+ "#C_H_25#":{
+ "name":"C-H-25"
+ },
+ "#C_H_30#":{
+ "name":"C-H-30"
+ },
+ "#C_H_40#":{
+ "name":"C-H-40"
+ },
+ "#C_H_50#":{
+ "name":"C-H-50"
+ },
+ "#C_H_70#":{
+ "name":"C-H-70"
+ },
+ "#C_H_90#":{
+ "name":"C-H-90"
+ },
+ "#D_L_00#":{
+ "name":"D-L-0"
+ },
+ "#D_L_05#":{
+ "name":"D-L-5"
+ },
+ "#D_L_10#":{
+ "name":"D-L-10"
+ },
+ "#D_L_15#":{
+ "name":"D-L-15"
+ },
+ "#D_L_20#":{
+ "name":"D-L-20"
+ },
+ "#D_L_25#":{
+ "name":"D-L-25"
+ },
+ "#D_L_30#":{
+ "name":"D-L-30"
+ },
+ "#D_L_40#":{
+ "name":"D-L-40"
+ },
+ "#D_L_50#":{
+ "name":"D-L-50"
+ },
+ "#D_L_70#":{
+ "name":"D-L-70"
+ },
+ "#D_L_90#":{
+ "name":"D-L-90"
+ },
+ "#D_H_00#":{
+ "name":"D-H-0"
+ },
+ "#D_H_05#":{
+ "name":"D-H-5"
+ },
+ "#D_H_10#":{
+ "name":"D-H-10"
+ },
+ "#D_H_15#":{
+ "name":"D-H-15"
+ },
+ "#D_H_20#":{
+ "name":"D-H-20"
+ },
+ "#D_H_25#":{
+ "name":"D-H-25"
+ },
+ "#D_H_30#":{
+ "name":"D-H-30"
+ },
+ "#D_H_40#":{
+ "name":"D-H-40"
+ },
+ "#D_H_50#":{
+ "name":"D-H-50"
+ },
+ "#D_H_70#":{
+ "name":"D-H-70"
+ },
+ "#D_H_90#":{
+ "name":"D-H-90"
+ },
+ "#E_L_00#":{
+ "name":"E-L-0",
+ "led": true
+ },
+ "#E_L_05#":{
+ "name":"E-L-5",
+ "led": true
+ },
+ "#E_L_10#":{
+ "name":"E-L-10",
+ "led": true
+ },
+ "#E_L_15#":{
+ "name":"E-L-15",
+ "led": true
+ },
+ "#E_L_20#":{
+ "name":"E-L-20",
+ "led": true
+ },
+ "#E_L_25#":{
+ "name":"E-L-25",
+ "led": true
+ },
+ "#E_L_30#":{
+ "name":"E-L-30",
+ "led": true
+ },
+ "#E_L_40#":{
+ "name":"E-L-40",
+ "led": true
+ },
+ "#E_L_50#":{
+ "name":"E-L-50",
+ "led": true
+ },
+ "#E_L_70#":{
+ "name":"E-L-70",
+ "led": true
+ },
+ "#E_L_90#":{
+ "name":"E-L-90",
+ "led": true
+ },
+ "#E_H_00#":{
+ "name":"E-H-0",
+ "led": true
+ },
+ "#E_H_05#":{
+ "name":"E-H-5",
+ "led": true
+ },
+ "#E_H_10#":{
+ "name":"E-H-10",
+ "led": true
+ },
+ "#E_H_15#":{
+ "name":"E-H-15",
+ "led": true
+ },
+ "#E_H_20#":{
+ "name":"E-H-20",
+ "led": true
+ },
+ "#E_H_25#":{
+ "name":"E-H-25",
+ "led": true
+ },
+ "#E_H_30#":{
+ "name":"E-H-30",
+ "led": true
+ },
+ "#E_H_40#":{
+ "name":"E-H-40",
+ "led": true
+ },
+ "#E_H_50#":{
+ "name":"E-H-50",
+ "led": true
+ },
+ "#E_H_70#":{
+ "name":"E-H-70",
+ "led": true
+ },
+ "#E_H_90#":{
+ "name":"E-H-90",
+ "led": true
+ },
+ "#F_L_00#":{
+ "name":"F-L-0"
+ },
+ "#F_L_05#":{
+ "name":"F-L-5"
+ },
+ "#F_L_10#":{
+ "name":"F-L-10"
+ },
+ "#F_L_15#":{
+ "name":"F-L-15"
+ },
+ "#F_L_20#":{
+ "name":"F-L-20"
+ },
+ "#F_L_25#":{
+ "name":"F-L-25"
+ },
+ "#F_L_30#":{
+ "name":"F-L-30"
+ },
+ "#F_L_40#":{
+ "name":"F-L-40"
+ },
+ "#F_L_50#":{
+ "name":"F-L-50"
+ },
+ "#F_L_70#":{
+ "name":"F-L-70"
+ },
+ "#F_L_90#":{
+ "name":"F-L-90"
+ },
+ "#F_H_00#":{
+ "name":"F-H-0"
+ },
+ "#F_H_05#":{
+ "name":"F-H-5"
+ },
+ "#F_H_10#":{
+ "name":"F-H-10"
+ },
+ "#F_H_15#":{
+ "name":"F-H-15"
+ },
+ "#F_H_20#":{
+ "name":"F-H-20"
+ },
+ "#F_H_25#":{
+ "name":"F-H-25"
+ },
+ "#F_H_30#":{
+ "name":"F-H-30"
+ },
+ "#F_H_40#":{
+ "name":"F-H-40"
+ },
+ "#F_H_50#":{
+ "name":"F-H-50"
+ },
+ "#F_H_70#":{
+ "name":"F-H-70"
+ },
+ "#F_H_90#":{
+ "name":"F-H-90"
+ },
+ "#G_L_00#":{
+ "name":"G-L-0"
+ },
+ "#G_L_05#":{
+ "name":"G-L-5"
+ },
+ "#G_L_10#":{
+ "name":"G-L-10"
+ },
+ "#G_L_15#":{
+ "name":"G-L-15"
+ },
+ "#G_L_20#":{
+ "name":"G-L-20"
+ },
+ "#G_L_25#":{
+ "name":"G-L-25"
+ },
+ "#G_L_30#":{
+ "name":"G-L-30"
+ },
+ "#G_L_40#":{
+ "name":"G-L-40"
+ },
+ "#G_L_50#":{
+ "name":"G-L-50"
+ },
+ "#G_L_70#":{
+ "name":"G-L-70"
+ },
+ "#G_L_90#":{
+ "name":"G-L-90"
+ },
+ "#G_H_00#":{
+ "name":"G-H-0"
+ },
+ "#G_H_05#":{
+ "name":"G-H-5"
+ },
+ "#G_H_10#":{
+ "name":"G-H-10"
+ },
+ "#G_H_15#":{
+ "name":"G-H-15"
+ },
+ "#G_H_20#":{
+ "name":"G-H-20"
+ },
+ "#G_H_25#":{
+ "name":"G-H-25"
+ },
+ "#G_H_30#":{
+ "name":"G-H-30"
+ },
+ "#G_H_40#":{
+ "name":"G-H-40"
+ },
+ "#G_H_50#":{
+ "name":"G-H-50"
+ },
+ "#G_H_70#":{
+ "name":"G-H-70"
+ },
+ "#G_H_90#":{
+ "name":"G-H-90"
+ },
+ "#H_L_00#":{
+ "name":"H-L-0"
+ },
+ "#H_L_05#":{
+ "name":"H-L-5"
+ },
+ "#H_L_10#":{
+ "name":"H-L-10"
+ },
+ "#H_L_15#":{
+ "name":"H-L-15"
+ },
+ "#H_L_20#":{
+ "name":"H-L-20"
+ },
+ "#H_L_25#":{
+ "name":"H-L-25"
+ },
+ "#H_L_30#":{
+ "name":"H-L-30"
+ },
+ "#H_L_40#":{
+ "name":"H-L-40"
+ },
+ "#H_L_50#":{
+ "name":"H-L-50"
+ },
+ "#H_L_70#":{
+ "name":"H-L-70"
+ },
+ "#H_L_90#":{
+ "name":"H-L-90"
+ },
+ "#H_H_00#":{
+ "name":"H-H-0"
+ },
+ "#H_H_05#":{
+ "name":"H-H-5"
+ },
+ "#H_H_10#":{
+ "name":"H-H-10"
+ },
+ "#H_H_15#":{
+ "name":"H-H-15"
+ },
+ "#H_H_20#":{
+ "name":"H-H-20"
+ },
+ "#H_H_25#":{
+ "name":"H-H-25"
+ },
+ "#H_H_30#":{
+ "name":"H-H-30"
+ },
+ "#H_H_40#":{
+ "name":"H-H-40"
+ },
+ "#H_H_50#":{
+ "name":"H-H-50"
+ },
+ "#H_H_70#":{
+ "name":"H-H-70"
+ },
+ "#H_H_90#":{
+ "name":"H-H-90"
+ },
+ "#I_L_00#":{
+ "name":"I-L-0"
+ },
+ "#I_L_05#":{
+ "name":"I-L-5"
+ },
+ "#I_L_10#":{
+ "name":"I-L-10"
+ },
+ "#I_L_15#":{
+ "name":"I-L-15"
+ },
+ "#I_L_20#":{
+ "name":"I-L-20"
+ },
+ "#I_L_25#":{
+ "name":"I-L-25"
+ },
+ "#I_L_30#":{
+ "name":"I-L-30"
+ },
+ "#I_L_40#":{
+ "name":"I-L-40"
+ },
+ "#I_L_50#":{
+ "name":"I-L-50"
+ },
+ "#I_L_70#":{
+ "name":"I-L-70"
+ },
+ "#I_L_90#":{
+ "name":"I-L-90"
+ },
+ "#I_H_00#":{
+ "name":"I-H-0"
+ },
+ "#I_H_05#":{
+ "name":"I-H-5"
+ },
+ "#I_H_10#":{
+ "name":"I-H-10"
+ },
+ "#I_H_15#":{
+ "name":"I-H-15"
+ },
+ "#I_H_20#":{
+ "name":"I-H-20"
+ },
+ "#I_H_25#":{
+ "name":"I-H-25"
+ },
+ "#I_H_30#":{
+ "name":"I-H-30"
+ },
+ "#I_H_40#":{
+ "name":"I-H-40"
+ },
+ "#I_H_50#":{
+ "name":"I-H-50"
+ },
+ "#I_H_70#":{
+ "name":"I-H-70"
+ },
+ "#I_H_90#":{
+ "name":"I-H-90"
+ },
+ "#J_L_00#":{
+ "name":"J-L-0"
+ },
+ "#J_L_05#":{
+ "name":"J-L-5"
+ },
+ "#J_L_10#":{
+ "name":"J-L-10"
+ },
+ "#J_L_15#":{
+ "name":"J-L-15"
+ },
+ "#J_L_20#":{
+ "name":"J-L-20"
+ },
+ "#J_L_25#":{
+ "name":"J-L-25"
+ },
+ "#J_L_30#":{
+ "name":"J-L-30"
+ },
+ "#J_L_40#":{
+ "name":"J-L-40"
+ },
+ "#J_L_50#":{
+ "name":"J-L-50"
+ },
+ "#J_L_70#":{
+ "name":"J-L-70"
+ },
+ "#J_L_90#":{
+ "name":"J-L-90"
+ },
+ "#J_H_00#":{
+ "name":"J-H-0"
+ },
+ "#J_H_05#":{
+ "name":"J-H-5"
+ },
+ "#J_H_10#":{
+ "name":"J-H-10"
+ },
+ "#J_H_15#":{
+ "name":"J-H-15"
+ },
+ "#J_H_20#":{
+ "name":"J-H-20"
+ },
+ "#J_H_25#":{
+ "name":"J-H-25"
+ },
+ "#J_H_30#":{
+ "name":"J-H-30"
+ },
+ "#J_H_40#":{
+ "name":"J-H-40"
+ },
+ "#J_H_50#":{
+ "name":"J-H-50"
+ },
+ "#J_H_70#":{
+ "name":"J-H-70"
+ },
+ "#J_H_90#":{
+ "name":"J-H-90"
+ },
+ "#K_L_00#":{
+ "name":"K-L-0"
+ },
+ "#K_L_05#":{
+ "name":"K-L-5"
+ },
+ "#K_L_10#":{
+ "name":"K-L-10"
+ },
+ "#K_L_15#":{
+ "name":"K-L-15"
+ },
+ "#K_L_20#":{
+ "name":"K-L-20"
+ },
+ "#K_L_25#":{
+ "name":"K-L-25"
+ },
+ "#K_L_30#":{
+ "name":"K-L-30"
+ },
+ "#K_L_40#":{
+ "name":"K-L-40"
+ },
+ "#K_L_50#":{
+ "name":"K-L-50"
+ },
+ "#K_L_70#":{
+ "name":"K-L-70"
+ },
+ "#K_L_90#":{
+ "name":"K-L-90"
+ },
+ "#K_H_00#":{
+ "name":"K-H-0"
+ },
+ "#K_H_05#":{
+ "name":"K-H-5"
+ },
+ "#K_H_10#":{
+ "name":"K-H-10"
+ },
+ "#K_H_15#":{
+ "name":"K-H-15"
+ },
+ "#K_H_20#":{
+ "name":"K-H-20"
+ },
+ "#K_H_25#":{
+ "name":"K-H-25"
+ },
+ "#K_H_30#":{
+ "name":"K-H-30"
+ },
+ "#K_H_40#":{
+ "name":"K-H-40"
+ },
+ "#K_H_50#":{
+ "name":"K-H-50"
+ },
+ "#K_H_70#":{
+ "name":"K-H-70"
+ },
+ "#K_H_90#":{
+ "name":"K-H-90"
+ },
+ "#L_L_00#":{
+ "name":"L-L-0"
+ },
+ "#L_L_05#":{
+ "name":"L-L-5"
+ },
+ "#L_L_10#":{
+ "name":"L-L-10"
+ },
+ "#L_L_15#":{
+ "name":"L-L-15"
+ },
+ "#L_L_20#":{
+ "name":"L-L-20"
+ },
+ "#L_L_25#":{
+ "name":"L-L-25"
+ },
+ "#L_L_30#":{
+ "name":"L-L-30"
+ },
+ "#L_L_40#":{
+ "name":"L-L-40"
+ },
+ "#L_L_50#":{
+ "name":"L-L-50"
+ },
+ "#L_L_70#":{
+ "name":"L-L-70"
+ },
+ "#L_L_90#":{
+ "name":"L-L-90"
+ },
+ "#L_H_00#":{
+ "name":"L-H-0"
+ },
+ "#L_H_05#":{
+ "name":"L-H-5"
+ },
+ "#L_H_10#":{
+ "name":"L-H-10"
+ },
+ "#L_H_15#":{
+ "name":"L-H-15"
+ },
+ "#L_H_20#":{
+ "name":"L-H-20"
+ },
+ "#L_H_25#":{
+ "name":"L-H-25"
+ },
+ "#L_H_30#":{
+ "name":"L-H-30"
+ },
+ "#L_H_40#":{
+ "name":"L-H-40"
+ },
+ "#L_H_50#":{
+ "name":"L-H-50"
+ },
+ "#L_H_70#":{
+ "name":"L-H-70"
+ },
+ "#L_H_90#":{
+ "name":"L-H-90"
+ },
+ "#M_L_00#":{
+ "name":"M-L-0"
+ },
+ "#M_L_05#":{
+ "name":"M-L-5"
+ },
+ "#M_L_10#":{
+ "name":"M-L-10"
+ },
+ "#M_L_15#":{
+ "name":"M-L-15"
+ },
+ "#M_L_20#":{
+ "name":"M-L-20"
+ },
+ "#M_L_25#":{
+ "name":"M-L-25"
+ },
+ "#M_L_30#":{
+ "name":"M-L-30"
+ },
+ "#M_L_40#":{
+ "name":"M-L-40"
+ },
+ "#M_L_50#":{
+ "name":"M-L-50"
+ },
+ "#M_L_70#":{
+ "name":"M-L-70"
+ },
+ "#M_L_90#":{
+ "name":"M-L-90"
+ },
+ "#M_H_00#":{
+ "name":"M-H-0"
+ },
+ "#M_H_05#":{
+ "name":"M-H-5"
+ },
+ "#M_H_10#":{
+ "name":"M-H-10"
+ },
+ "#M_H_15#":{
+ "name":"M-H-15"
+ },
+ "#M_H_20#":{
+ "name":"M-H-20"
+ },
+ "#M_H_25#":{
+ "name":"M-H-25"
+ },
+ "#M_H_30#":{
+ "name":"M-H-30"
+ },
+ "#M_H_40#":{
+ "name":"M-H-40"
+ },
+ "#M_H_50#":{
+ "name":"M-H-50"
+ },
+ "#M_H_70#":{
+ "name":"M-H-70"
+ },
+ "#M_H_90#":{
+ "name":"M-H-90"
+ },
+ "#N_L_00#":{
+ "name":"N-L-0"
+ },
+ "#N_L_05#":{
+ "name":"N-L-5"
+ },
+ "#N_L_10#":{
+ "name":"N-L-10"
+ },
+ "#N_L_15#":{
+ "name":"N-L-15"
+ },
+ "#N_L_20#":{
+ "name":"N-L-20"
+ },
+ "#N_L_25#":{
+ "name":"N-L-25"
+ },
+ "#N_L_30#":{
+ "name":"N-L-30"
+ },
+ "#N_L_40#":{
+ "name":"N-L-40"
+ },
+ "#N_L_50#":{
+ "name":"N-L-50"
+ },
+ "#N_L_70#":{
+ "name":"N-L-70"
+ },
+ "#N_L_90#":{
+ "name":"N-L-90"
+ },
+ "#N_H_00#":{
+ "name":"N-H-0"
+ },
+ "#N_H_05#":{
+ "name":"N-H-5"
+ },
+ "#N_H_10#":{
+ "name":"N-H-10"
+ },
+ "#N_H_15#":{
+ "name":"N-H-15"
+ },
+ "#N_H_20#":{
+ "name":"N-H-20"
+ },
+ "#N_H_25#":{
+ "name":"N-H-25"
+ },
+ "#N_H_30#":{
+ "name":"N-H-30"
+ },
+ "#N_H_40#":{
+ "name":"N-H-40"
+ },
+ "#N_H_50#":{
+ "name":"N-H-50"
+ },
+ "#N_H_70#":{
+ "name":"N-H-70"
+ },
+ "#N_H_90#":{
+ "name":"N-H-90"
+ },
+ "#O_L_00#":{
+ "name":"O-L-0"
+ },
+ "#O_L_05#":{
+ "name":"O-L-5"
+ },
+ "#O_L_10#":{
+ "name":"O-L-10"
+ },
+ "#O_L_15#":{
+ "name":"O-L-15"
+ },
+ "#O_L_20#":{
+ "name":"O-L-20"
+ },
+ "#O_L_25#":{
+ "name":"O-L-25"
+ },
+ "#O_L_30#":{
+ "name":"O-L-30"
+ },
+ "#O_L_40#":{
+ "name":"O-L-40"
+ },
+ "#O_L_50#":{
+ "name":"O-L-50"
+ },
+ "#O_L_70#":{
+ "name":"O-L-70"
+ },
+ "#O_L_90#":{
+ "name":"O-L-90"
+ },
+ "#O_H_00#":{
+ "name":"O-H-0"
+ },
+ "#O_H_05#":{
+ "name":"O-H-5"
+ },
+ "#O_H_10#":{
+ "name":"O-H-10"
+ },
+ "#O_H_15#":{
+ "name":"O-H-15"
+ },
+ "#O_H_20#":{
+ "name":"O-H-20"
+ },
+ "#O_H_25#":{
+ "name":"O-H-25"
+ },
+ "#O_H_30#":{
+ "name":"O-H-30"
+ },
+ "#O_H_40#":{
+ "name":"O-H-40"
+ },
+ "#O_H_50#":{
+ "name":"O-H-50"
+ },
+ "#O_H_70#":{
+ "name":"O-H-70"
+ },
+ "#O_H_90#":{
+ "name":"O-H-90"
+ },
+ "#P_L_00#":{
+ "name":"P-L-0"
+ },
+ "#P_L_05#":{
+ "name":"P-L-5"
+ },
+ "#P_L_10#":{
+ "name":"P-L-10"
+ },
+ "#P_L_15#":{
+ "name":"P-L-15"
+ },
+ "#P_L_20#":{
+ "name":"P-L-20"
+ },
+ "#P_L_25#":{
+ "name":"P-L-25"
+ },
+ "#P_L_30#":{
+ "name":"P-L-30"
+ },
+ "#P_L_40#":{
+ "name":"P-L-40"
+ },
+ "#P_L_50#":{
+ "name":"P-L-50"
+ },
+ "#P_L_70#":{
+ "name":"P-L-70"
+ },
+ "#P_L_90#":{
+ "name":"P-L-90"
+ },
+ "#P_H_00#":{
+ "name":"P-H-0"
+ },
+ "#P_H_05#":{
+ "name":"P-H-5"
+ },
+ "#P_H_10#":{
+ "name":"P-H-10"
+ },
+ "#P_H_15#":{
+ "name":"P-H-15"
+ },
+ "#P_H_20#":{
+ "name":"P-H-20"
+ },
+ "#P_H_25#":{
+ "name":"P-H-25"
+ },
+ "#P_H_30#":{
+ "name":"P-H-30"
+ },
+ "#P_H_40#":{
+ "name":"P-H-40"
+ },
+ "#P_H_50#":{
+ "name":"P-H-50"
+ },
+ "#P_H_70#":{
+ "name":"P-H-70"
+ },
+ "#P_H_90#":{
+ "name":"P-H-90"
+ },
+ "#Q_L_00#":{
+ "name":"Q-L-0"
+ },
+ "#Q_L_05#":{
+ "name":"Q-L-5"
+ },
+ "#Q_L_10#":{
+ "name":"Q-L-10"
+ },
+ "#Q_L_15#":{
+ "name":"Q-L-15"
+ },
+ "#Q_L_20#":{
+ "name":"Q-L-20"
+ },
+ "#Q_L_25#":{
+ "name":"Q-L-25"
+ },
+ "#Q_L_30#":{
+ "name":"Q-L-30"
+ },
+ "#Q_L_40#":{
+ "name":"Q-L-40"
+ },
+ "#Q_L_50#":{
+ "name":"Q-L-50"
+ },
+ "#Q_L_70#":{
+ "name":"Q-L-70"
+ },
+ "#Q_L_90#":{
+ "name":"Q-L-90"
+ },
+ "#Q_H_00#":{
+ "name":"Q-H-0"
+ },
+ "#Q_H_05#":{
+ "name":"Q-H-5"
+ },
+ "#Q_H_10#":{
+ "name":"Q-H-10"
+ },
+ "#Q_H_15#":{
+ "name":"Q-H-15"
+ },
+ "#Q_H_20#":{
+ "name":"Q-H-20"
+ },
+ "#Q_H_25#":{
+ "name":"Q-H-25"
+ },
+ "#Q_H_30#":{
+ "name":"Q-H-30"
+ },
+ "#Q_H_40#":{
+ "name":"Q-H-40"
+ },
+ "#Q_H_50#":{
+ "name":"Q-H-50"
+ },
+ "#Q_H_70#":{
+ "name":"Q-H-70"
+ },
+ "#Q_H_90#":{
+ "name":"Q-H-90"
+ },
+ "#R_L_00#":{
+ "name":"R-L-0"
+ },
+ "#R_L_05#":{
+ "name":"R-L-5"
+ },
+ "#R_L_10#":{
+ "name":"R-L-10"
+ },
+ "#R_L_15#":{
+ "name":"R-L-15"
+ },
+ "#R_L_20#":{
+ "name":"R-L-20"
+ },
+ "#R_L_25#":{
+ "name":"R-L-25"
+ },
+ "#R_L_30#":{
+ "name":"R-L-30"
+ },
+ "#R_L_40#":{
+ "name":"R-L-40"
+ },
+ "#R_L_50#":{
+ "name":"R-L-50"
+ },
+ "#R_L_70#":{
+ "name":"R-L-70"
+ },
+ "#R_L_90#":{
+ "name":"R-L-90"
+ },
+ "#R_H_00#":{
+ "name":"R-H-0"
+ },
+ "#R_H_05#":{
+ "name":"R-H-5"
+ },
+ "#R_H_10#":{
+ "name":"R-H-10"
+ },
+ "#R_H_15#":{
+ "name":"R-H-15"
+ },
+ "#R_H_20#":{
+ "name":"R-H-20"
+ },
+ "#R_H_25#":{
+ "name":"R-H-25"
+ },
+ "#R_H_30#":{
+ "name":"R-H-30"
+ },
+ "#R_H_40#":{
+ "name":"R-H-40"
+ },
+ "#R_H_50#":{
+ "name":"R-H-50"
+ },
+ "#R_H_70#":{
+ "name":"R-H-70"
+ },
+ "#R_H_90#":{
+ "name":"R-H-90"
+ },
+ "#S_L_00#":{
+ "name":"S-L-0"
+ },
+ "#S_L_05#":{
+ "name":"S-L-5"
+ },
+ "#S_L_10#":{
+ "name":"S-L-10"
+ },
+ "#S_L_15#":{
+ "name":"S-L-15"
+ },
+ "#S_L_20#":{
+ "name":"S-L-20"
+ },
+ "#S_L_25#":{
+ "name":"S-L-25"
+ },
+ "#S_L_30#":{
+ "name":"S-L-30"
+ },
+ "#S_L_40#":{
+ "name":"S-L-40"
+ },
+ "#S_L_50#":{
+ "name":"S-L-50"
+ },
+ "#S_L_70#":{
+ "name":"S-L-70"
+ },
+ "#S_L_90#":{
+ "name":"S-L-90"
+ },
+ "#S_H_00#":{
+ "name":"S-H-0"
+ },
+ "#S_H_05#":{
+ "name":"S-H-5"
+ },
+ "#S_H_10#":{
+ "name":"S-H-10"
+ },
+ "#S_H_15#":{
+ "name":"S-H-15"
+ },
+ "#S_H_20#":{
+ "name":"S-H-20"
+ },
+ "#S_H_25#":{
+ "name":"S-H-25"
+ },
+ "#S_H_30#":{
+ "name":"S-H-30"
+ },
+ "#S_H_40#":{
+ "name":"S-H-40"
+ },
+ "#S_H_50#":{
+ "name":"S-H-50",
+ "led":true
+ },
+ "#S_H_70#":{
+ "name":"S-H-70"
+ },
+ "#S_H_90#":{
+ "name":"S-H-90"
+ },
+ "#T_L_00#":{
+ "name":"T-L-0"
+ },
+ "#T_L_05#":{
+ "name":"T-L-5"
+ },
+ "#T_L_10#":{
+ "name":"T-L-10"
+ },
+ "#T_L_15#":{
+ "name":"T-L-15"
+ },
+ "#T_L_20#":{
+ "name":"T-L-20"
+ },
+ "#T_L_25#":{
+ "name":"T-L-25"
+ },
+ "#T_L_30#":{
+ "name":"T-L-30"
+ },
+ "#T_L_40#":{
+ "name":"T-L-40"
+ },
+ "#T_L_50#":{
+ "name":"T-L-50"
+ },
+ "#T_L_70#":{
+ "name":"T-L-70"
+ },
+ "#T_L_90#":{
+ "name":"T-L-90"
+ },
+ "#T_H_00#":{
+ "name":"T-H-0"
+ },
+ "#T_H_05#":{
+ "name":"T-H-5"
+ },
+ "#T_H_10#":{
+ "name":"T-H-10"
+ },
+ "#T_H_15#":{
+ "name":"T-H-15"
+ },
+ "#T_H_20#":{
+ "name":"T-H-20"
+ },
+ "#T_H_25#":{
+ "name":"T-H-25"
+ },
+ "#T_H_30#":{
+ "name":"T-H-30"
+ },
+ "#T_H_40#":{
+ "name":"T-H-40"
+ },
+ "#T_H_50#":{
+ "name":"T-H-50"
+ },
+ "#T_H_70#":{
+ "name":"T-H-70"
+ },
+ "#T_H_90#":{
+ "name":"T-H-90"
+ },
+ "#U_L_00#":{
+ "name":"U-L-0"
+ },
+ "#U_L_05#":{
+ "name":"U-L-5"
+ },
+ "#U_L_10#":{
+ "name":"U-L-10"
+ },
+ "#U_L_15#":{
+ "name":"U-L-15"
+ },
+ "#U_L_20#":{
+ "name":"U-L-20"
+ },
+ "#U_L_25#":{
+ "name":"U-L-25"
+ },
+ "#U_L_30#":{
+ "name":"U-L-30"
+ },
+ "#U_L_40#":{
+ "name":"U-L-40"
+ },
+ "#U_L_50#":{
+ "name":"U-L-50"
+ },
+ "#U_L_70#":{
+ "name":"U-L-70"
+ },
+ "#U_L_90#":{
+ "name":"U-L-90"
+ },
+ "#U_H_00#":{
+ "name":"U-H-0"
+ },
+ "#U_H_05#":{
+ "name":"U-H-5"
+ },
+ "#U_H_10#":{
+ "name":"U-H-10"
+ },
+ "#U_H_15#":{
+ "name":"U-H-15"
+ },
+ "#U_H_20#":{
+ "name":"U-H-20"
+ },
+ "#U_H_25#":{
+ "name":"U-H-25"
+ },
+ "#U_H_30#":{
+ "name":"U-H-30"
+ },
+ "#U_H_40#":{
+ "name":"U-H-40"
+ },
+ "#U_H_50#":{
+ "name":"U-H-50"
+ },
+ "#U_H_70#":{
+ "name":"U-H-70"
+ },
+ "#U_H_90#":{
+ "name":"U-H-90"
+ },
+ "#V_L_00#":{
+ "name":"V-L-0"
+ },
+ "#V_L_05#":{
+ "name":"V-L-5"
+ },
+ "#V_L_10#":{
+ "name":"V-L-10"
+ },
+ "#V_L_15#":{
+ "name":"V-L-15"
+ },
+ "#V_L_20#":{
+ "name":"V-L-20"
+ },
+ "#V_L_25#":{
+ "name":"V-L-25"
+ },
+ "#V_L_30#":{
+ "name":"V-L-30"
+ },
+ "#V_L_40#":{
+ "name":"V-L-40"
+ },
+ "#V_L_50#":{
+ "name":"V-L-50"
+ },
+ "#V_L_70#":{
+ "name":"V-L-70"
+ },
+ "#V_L_90#":{
+ "name":"V-L-90"
+ },
+ "#V_H_00#":{
+ "name":"V-H-0"
+ },
+ "#V_H_05#":{
+ "name":"V-H-5"
+ },
+ "#V_H_10#":{
+ "name":"V-H-10"
+ },
+ "#V_H_15#":{
+ "name":"V-H-15"
+ },
+ "#V_H_20#":{
+ "name":"V-H-20"
+ },
+ "#V_H_25#":{
+ "name":"V-H-25"
+ },
+ "#V_H_30#":{
+ "name":"V-H-30"
+ },
+ "#V_H_40#":{
+ "name":"V-H-40"
+ },
+ "#V_H_50#":{
+ "name":"V-H-50"
+ },
+ "#V_H_70#":{
+ "name":"V-H-70"
+ },
+ "#V_H_90#":{
+ "name":"V-H-90"
+ },
+ "#W_L_00#":{
+ "name":"W-L-0"
+ },
+ "#W_L_05#":{
+ "name":"W-L-5"
+ },
+ "#W_L_10#":{
+ "name":"W-L-10"
+ },
+ "#W_L_15#":{
+ "name":"W-L-15"
+ },
+ "#W_L_20#":{
+ "name":"W-L-20"
+ },
+ "#W_L_25#":{
+ "name":"W-L-25"
+ },
+ "#W_L_30#":{
+ "name":"W-L-30"
+ },
+ "#W_L_40#":{
+ "name":"W-L-40"
+ },
+ "#W_L_50#":{
+ "name":"W-L-50"
+ },
+ "#W_L_70#":{
+ "name":"W-L-70"
+ },
+ "#W_L_90#":{
+ "name":"W-L-90"
+ },
+ "#W_H_00#":{
+ "name":"W-H-0"
+ },
+ "#W_H_05#":{
+ "name":"W-H-5"
+ },
+ "#W_H_10#":{
+ "name":"W-H-10"
+ },
+ "#W_H_15#":{
+ "name":"W-H-15"
+ },
+ "#W_H_20#":{
+ "name":"W-H-20"
+ },
+ "#W_H_25#":{
+ "name":"W-H-25"
+ },
+ "#W_H_30#":{
+ "name":"W-H-30"
+ },
+ "#W_H_40#":{
+ "name":"W-H-40"
+ },
+ "#W_H_50#":{
+ "name":"W-H-50"
+ },
+ "#W_H_70#":{
+ "name":"W-H-70"
+ },
+ "#W_H_90#":{
+ "name":"W-H-90"
+ },
+ "#X_L_00#":{
+ "name":"X-L-0"
+ },
+ "#X_L_05#":{
+ "name":"X-L-5"
+ },
+ "#X_L_10#":{
+ "name":"X-L-10"
+ },
+ "#X_L_15#":{
+ "name":"X-L-15"
+ },
+ "#X_L_20#":{
+ "name":"X-L-20"
+ },
+ "#X_L_25#":{
+ "name":"X-L-25"
+ },
+ "#X_L_30#":{
+ "name":"X-L-30"
+ },
+ "#X_L_40#":{
+ "name":"X-L-40"
+ },
+ "#X_L_50#":{
+ "name":"X-L-50"
+ },
+ "#X_L_70#":{
+ "name":"X-L-70"
+ },
+ "#X_L_90#":{
+ "name":"X-L-90"
+ },
+ "#X_H_00#":{
+ "name":"X-H-0"
+ },
+ "#X_H_05#":{
+ "name":"X-H-5"
+ },
+ "#X_H_10#":{
+ "name":"X-H-10"
+ },
+ "#X_H_15#":{
+ "name":"X-H-15"
+ },
+ "#X_H_20#":{
+ "name":"X-H-20"
+ },
+ "#X_H_25#":{
+ "name":"X-H-25"
+ },
+ "#X_H_30#":{
+ "name":"X-H-30"
+ },
+ "#X_H_40#":{
+ "name":"X-H-40"
+ },
+ "#X_H_50#":{
+ "name":"X-H-50"
+ },
+ "#X_H_70#":{
+ "name":"X-H-70"
+ },
+ "#X_H_90#":{
+ "name":"X-H-90"
+ },
+ "#Y_L_00#":{
+ "name":"Y-L-0"
+ },
+ "#Y_L_05#":{
+ "name":"Y-L-5"
+ },
+ "#Y_L_10#":{
+ "name":"Y-L-10"
+ },
+ "#Y_L_15#":{
+ "name":"Y-L-15"
+ },
+ "#Y_L_20#":{
+ "name":"Y-L-20"
+ },
+ "#Y_L_25#":{
+ "name":"Y-L-25"
+ },
+ "#Y_L_30#":{
+ "name":"Y-L-30"
+ },
+ "#Y_L_40#":{
+ "name":"Y-L-40"
+ },
+ "#Y_L_50#":{
+ "name":"Y-L-50"
+ },
+ "#Y_L_70#":{
+ "name":"Y-L-70"
+ },
+ "#Y_L_90#":{
+ "name":"Y-L-90"
+ },
+ "#Y_H_00#":{
+ "name":"Y-H-0"
+ },
+ "#Y_H_05#":{
+ "name":"Y-H-5"
+ },
+ "#Y_H_10#":{
+ "name":"Y-H-10"
+ },
+ "#Y_H_15#":{
+ "name":"Y-H-15"
+ },
+ "#Y_H_20#":{
+ "name":"Y-H-20"
+ },
+ "#Y_H_25#":{
+ "name":"Y-H-25"
+ },
+ "#Y_H_30#":{
+ "name":"Y-H-30"
+ },
+ "#Y_H_40#":{
+ "name":"Y-H-40"
+ },
+ "#Y_H_50#":{
+ "name":"Y-H-50"
+ },
+ "#Y_H_70#":{
+ "name":"Y-H-70"
+ },
+ "#Y_H_90#":{
+ "name":"Y-H-90"
+ },
+ "#Z_L_00#":{
+ "name":"Z-L-0"
+ },
+ "#Z_L_05#":{
+ "name":"Z-L-5"
+ },
+ "#Z_L_10#":{
+ "name":"Z-L-10"
+ },
+ "#Z_L_15#":{
+ "name":"Z-L-15"
+ },
+ "#Z_L_20#":{
+ "name":"Z-L-20"
+ },
+ "#Z_L_25#":{
+ "name":"Z-L-25"
+ },
+ "#Z_L_30#":{
+ "name":"Z-L-30"
+ },
+ "#Z_L_40#":{
+ "name":"Z-L-40"
+ },
+ "#Z_L_50#":{
+ "name":"Z-L-50"
+ },
+ "#Z_L_70#":{
+ "name":"Z-L-70"
+ },
+ "#Z_L_90#":{
+ "name":"Z-L-90"
+ },
+ "#Z_H_00#":{
+ "name":"Z-H-0"
+ },
+ "#Z_H_05#":{
+ "name":"Z-H-5"
+ },
+ "#Z_H_10#":{
+ "name":"Z-H-10"
+ },
+ "#Z_H_15#":{
+ "name":"Z-H-15"
+ },
+ "#Z_H_20#":{
+ "name":"Z-H-20"
+ },
+ "#Z_H_25#":{
+ "name":"Z-H-25"
+ },
+ "#Z_H_30#":{
+ "name":"Z-H-30"
+ },
+ "#Z_H_40#":{
+ "name":"Z-H-40"
+ },
+ "#Z_H_50#":{
+ "name":"Z-H-50"
+ },
+ "#Z_H_70#":{
+ "name":"Z-H-70"
+ },
+ "#Z_H_90#":{
+ "name":"Z-H-90"
+ }
}
}
diff --git a/src/sources/Bluejay/__tests__/index.test.js b/src/sources/Bluejay/__tests__/index.test.js
index 5eee96485..4911d9650 100644
--- a/src/sources/Bluejay/__tests__/index.test.js
+++ b/src/sources/Bluejay/__tests__/index.test.js
@@ -5,7 +5,6 @@ const SETTINGS_DESCRIPTIONS = source.getSettingsDescriptions();
describe('Bluejay', () => {
it('should handle conditional visibility with general settings', () => {
const keys = Object.keys(SETTINGS_DESCRIPTIONS.COMMON);
- const settings = { MOTOR_DIRECTION: 3 };
const visibleIf = [];
for(let i = 0; i < keys.length; i += 1) {
@@ -41,6 +40,30 @@ describe('Bluejay', () => {
expect(ledFunction(settings)).not.toBeTruthy();
});
+ it('should show LED settings with supported layout', () => {
+ const keys = Object.keys(SETTINGS_DESCRIPTIONS.INDIVIDUAL);
+ const settings = {
+ GOVERNOR_MODE: 3,
+ MOTOR_DIRECTION: 3,
+ LAYOUT: '#E-H-90#',
+ };
+
+ let ledFunction = null;
+ for(let i = 0; i < keys.length; i += 1) {
+ const base = SETTINGS_DESCRIPTIONS.INDIVIDUAL[keys[i]].base;
+ for(let j = 0; j < base.length; j += 1) {
+ const current = base[j];
+ if(current.visibleIf) {
+ if(current.name === 'LED_CONTROL') {
+ ledFunction = current.visibleIf;
+ }
+ }
+ }
+ }
+
+ expect(ledFunction(settings)).toBeTruthy();
+ });
+
it('should return display name', () => {
const flash = {
settings: {
diff --git a/src/sources/Bluejay/escs.json b/src/sources/Bluejay/escs.json
index d55a55591..703a6dfcc 100644
--- a/src/sources/Bluejay/escs.json
+++ b/src/sources/Bluejay/escs.json
@@ -1,30 +1,162 @@
{
- "layouts": {
- "#A_L_120#":{ "name":"A-L-120" }, "#A_H_120#":{ "name":"A-H-120" },
- "#B_L_120#":{ "name":"B-L-120" }, "#B_H_120#":{ "name":"B-H-120" },
- "#C_L_120#":{ "name":"C-L-120" }, "#C_H_120#":{ "name":"C-H-120" },
- "#D_L_120#":{ "name":"D-L-120" }, "#D_H_120#":{ "name":"D-H-120" },
- "#E_L_120#":{ "name":"E-L-120" }, "#E_H_120#":{ "name":"E-H-120" },
- "#F_L_120#":{ "name":"F-L-120" }, "#F_H_120#":{ "name":"F-H-120" },
- "#G_L_120#":{ "name":"G-L-120" }, "#G_H_120#":{ "name":"G-H-120" },
- "#H_L_120#":{ "name":"H-L-120" }, "#H_H_120#":{ "name":"H-H-120" },
- "#I_L_120#":{ "name":"I-L-120" }, "#I_H_120#":{ "name":"I-H-120" },
- "#J_L_120#":{ "name":"J-L-120" }, "#J_H_120#":{ "name":"J-H-120" },
- "#K_L_120#":{ "name":"K-L-120" }, "#K_H_120#":{ "name":"K-H-120" },
- "#L_L_120#":{ "name":"L-L-120" }, "#L_H_120#":{ "name":"L-H-120" },
- "#M_L_120#":{ "name":"M-L-120" }, "#M_H_120#":{ "name":"M-H-120" },
- "#N_L_120#":{ "name":"N-L-120" }, "#N_H_120#":{ "name":"N-H-120" },
- "#O_L_120#":{ "name":"O-L-120" }, "#O_H_120#":{ "name":"O-H-120" },
- "#P_L_120#":{ "name":"P-L-120" }, "#P_H_120#":{ "name":"P-H-120" },
- "#Q_L_120#":{ "name":"Q-L-120" }, "#Q_H_120#":{ "name":"Q-H-120" },
- "#R_L_120#":{ "name":"R-L-120" }, "#R_H_120#":{ "name":"R-H-120" },
- "#S_L_120#":{ "name":"S-L-120" }, "#S_H_120#":{ "name":"S-H-120" },
- "#T_L_120#":{ "name":"T-L-120" }, "#T_H_120#":{ "name":"T-H-120" },
- "#U_L_120#":{ "name":"U-L-120" }, "#U_H_120#":{ "name":"U-H-120" },
- "#V_L_120#":{ "name":"V-L-120" }, "#V_H_120#":{ "name":"V-H-120" },
- "#W_L_120#":{ "name":"W-L-120" }, "#W_H_120#":{ "name":"W-H-120" },
- "#X_L_120#":{ "name":"X-L-120" }, "#X_H_120#":{ "name":"X-H-120" },
- "#Y_L_120#":{ "name":"Y-L-120" }, "#Y_H_120#":{ "name":"Y-H-120" },
- "#Z_L_120#":{ "name":"Z-L-120" }, "#Z_H_120#":{ "name":"Z-H-120" }
+ "layouts":{
+ "#A_L_120#":{
+ "name":"A-L-120"
+ },
+ "#A_H_120#":{
+ "name":"A-H-120"
+ },
+ "#B_L_120#":{
+ "name":"B-L-120"
+ },
+ "#B_H_120#":{
+ "name":"B-H-120"
+ },
+ "#C_L_120#":{
+ "name":"C-L-120"
+ },
+ "#C_H_120#":{
+ "name":"C-H-120"
+ },
+ "#D_L_120#":{
+ "name":"D-L-120"
+ },
+ "#D_H_120#":{
+ "name":"D-H-120"
+ },
+ "#E_L_120#":{
+ "name":"E-L-120",
+ "led": true
+ },
+ "#E_H_120#":{
+ "name":"E-H-120",
+ "led": true
+ },
+ "#F_L_120#":{
+ "name":"F-L-120"
+ },
+ "#F_H_120#":{
+ "name":"F-H-120"
+ },
+ "#G_L_120#":{
+ "name":"G-L-120"
+ },
+ "#G_H_120#":{
+ "name":"G-H-120"
+ },
+ "#H_L_120#":{
+ "name":"H-L-120"
+ },
+ "#H_H_120#":{
+ "name":"H-H-120"
+ },
+ "#I_L_120#":{
+ "name":"I-L-120"
+ },
+ "#I_H_120#":{
+ "name":"I-H-120"
+ },
+ "#J_L_120#":{
+ "name":"J-L-120"
+ },
+ "#J_H_120#":{
+ "name":"J-H-120"
+ },
+ "#K_L_120#":{
+ "name":"K-L-120"
+ },
+ "#K_H_120#":{
+ "name":"K-H-120"
+ },
+ "#L_L_120#":{
+ "name":"L-L-120"
+ },
+ "#L_H_120#":{
+ "name":"L-H-120"
+ },
+ "#M_L_120#":{
+ "name":"M-L-120"
+ },
+ "#M_H_120#":{
+ "name":"M-H-120"
+ },
+ "#N_L_120#":{
+ "name":"N-L-120"
+ },
+ "#N_H_120#":{
+ "name":"N-H-120"
+ },
+ "#O_L_120#":{
+ "name":"O-L-120"
+ },
+ "#O_H_120#":{
+ "name":"O-H-120"
+ },
+ "#P_L_120#":{
+ "name":"P-L-120"
+ },
+ "#P_H_120#":{
+ "name":"P-H-120"
+ },
+ "#Q_L_120#":{
+ "name":"Q-L-120"
+ },
+ "#Q_H_120#":{
+ "name":"Q-H-120"
+ },
+ "#R_L_120#":{
+ "name":"R-L-120"
+ },
+ "#R_H_120#":{
+ "name":"R-H-120"
+ },
+ "#S_L_120#":{
+ "name":"S-L-120"
+ },
+ "#S_H_120#":{
+ "name":"S-H-120"
+ },
+ "#T_L_120#":{
+ "name":"T-L-120"
+ },
+ "#T_H_120#":{
+ "name":"T-H-120"
+ },
+ "#U_L_120#":{
+ "name":"U-L-120"
+ },
+ "#U_H_120#":{
+ "name":"U-H-120"
+ },
+ "#V_L_120#":{
+ "name":"V-L-120"
+ },
+ "#V_H_120#":{
+ "name":"V-H-120"
+ },
+ "#W_L_120#":{
+ "name":"W-L-120"
+ },
+ "#W_H_120#":{
+ "name":"W-H-120"
+ },
+ "#X_L_120#":{
+ "name":"X-L-120"
+ },
+ "#X_H_120#":{
+ "name":"X-H-120"
+ },
+ "#Y_L_120#":{
+ "name":"Y-L-120"
+ },
+ "#Y_H_120#":{
+ "name":"Y-H-120"
+ },
+ "#Z_L_120#":{
+ "name":"Z-L-120"
+ },
+ "#Z_H_120#":{
+ "name":"Z-H-120"
+ }
}
}
diff --git a/src/translations/de/common.json b/src/translations/de/common.json
index 71a62b605..747e56037 100644
--- a/src/translations/de/common.json
+++ b/src/translations/de/common.json
@@ -65,14 +65,14 @@
"homeDisclaimerTextLine5": "Der aktuellste [CP210x Treiber](http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx) kann von [hier heruntergeladen werden](http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx).",
"homeDisclaimerTextLine6": "Der aktuellste [STM USB VCP Treiber](http://www.st.com/web/en/catalog/tools/PF257938) kann von [hier heruntergeladen werden](http://www.st.com/web/en/catalog/tools/PF257938).",
"homeWelcome": "Willkommen im **ESC - Konfigurator**, eine Anwendung um Updates und Konfiguration deiner ESC's zu erleichtern.",
- "betaWarningLine1": "**Dieses App befindet sich im BETA Stadium.**",
+ "betaWarningLine1": "Dieses App befindet sich im BETA Stadium.",
"betaWarningLine2": "Möglicherweise funktioniert noch nicht alles wie erwartet - falls du irgendwelche Fehler findest, [melde sie](https://github.com/stylesuxx/esc-configurator/issues/new) bitte.",
"findHelp": "Bekannte Browserprobleme findest du im [wiki](https://github.com/stylesuxx/esc-configurator/wiki/Known-Browser-issues).",
"escButtonSelectLocally": "Lokale Datei flashen",
"cookieText": "Diese Website oder Tools von Drittanbietern, die von dieser Website verwendet werden, verwenden Cookies für den Betrieb. Durch deine Zustimmung erklärst du dich mit der Verwendung von Cookies einverstanden.",
"resetDefaults": "Standardeinstellungen wiederherstellen",
"forceFlashText": "Falsches MCU Layout ignorieren?",
- "forceFlashHint": "(Ungeeignete Firmware könnte deinen ESC beschädigen. Auf eigene Verantwortung fortfahren.)",
+ "forceFlashHint": "Ungeeignete Firmware könnte deinen ESC beschädigen. Auf eigene Verantwortung fortfahren.",
"migrateFlashText": "Einstellungen zwischen unterschiedlichen Firmwares migrieren?",
"migrateFlashHint": "(Hiermit wird versucht, Einstellungen zwischen unterschiedlichen Firmwares zu migrieren, wie zum Beispiel von BLHeli_S auf Bluejay)",
"migrationNote": "Beachte, dass Einstellungen nicht zwischen unterschiedlichen Firmwares migriert werden. Stelle sicher, dass du diverse Einstellungen wie zum Beispiel die Drehrichtung der Motoren notiert hast. Bei verschiedenen Versionen derselben Firmware werden die Einstellungen übernommen.",
diff --git a/src/translations/de/settings.json b/src/translations/de/settings.json
index 1ef506480..8684190f1 100644
--- a/src/translations/de/settings.json
+++ b/src/translations/de/settings.json
@@ -1,8 +1,7 @@
{
"settingsHeader": "Einstellungen",
- "closeText": "Schließen",
- "directInput": "Numerische Eingabe",
- "directInputHint": "Direkte Eingabe für Zahlen anstelle der Schieberegler.",
+ "directInput": "Direkteingabe",
+ "directInputHint": "Direkte Eingabe für Zahlen statt Schieberegler.",
"printLogs": "Logs anzeigen",
"printLogsHint": "Zeigt Logs in der Browser Konsole an, wenn aktiviert.",
"extendedDebug": "Erweiterte Debug-Infos",
diff --git a/src/translations/en/common.json b/src/translations/en/common.json
index 0eb9effdf..e031bc8f8 100644
--- a/src/translations/en/common.json
+++ b/src/translations/en/common.json
@@ -6,7 +6,7 @@
"serialPermission": "Select Serial Port",
"showLog": "Show Log",
"hideLog": "Hide Log",
- "note": "Note: ",
+ "note": "Note",
"notePropsOff": "Make sure you've taken the propellers **OFF** before doing anything on this tab.",
"noteConnectPower": "Connect power to the ESCs.",
"commonParameters": "Common Parameters",
@@ -48,7 +48,7 @@
"changelogClose": "Close",
"escDampingMode": "Damping mode (Complementary PWM)",
"escBrakingStrength": "Maximum Braking Strength",
- "homeExperimental": "This is an experimental web app to configure ESC firmware online.",
+ "homeExperimental": "A web app to configure ESC firmware online",
"homeVersionInfo": "You will always find the latest stable version here. Currently the following firmware are supported:",
"homeContributionHeader": "Contributing",
"homeContributionText": "If you would like to help make ESC Configurator even better you can help in many ways, including:",
@@ -65,14 +65,14 @@
"homeDisclaimerTextLine5": "Latest [CP210x Drivers](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers) can be downloaded from [here](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers).",
"homeDisclaimerTextLine6": "Latest [STM USB VCP Drivers](https://www.st.com/en/development-tools/stsw-stm32102.html) can be downloaded from [here](https://www.st.com/en/development-tools/stsw-stm32102.html).",
"homeWelcome": "Welcome to **ESC - Configurator**, a utility designed to simplify updating and configuring of your ESCs.",
- "betaWarningLine1": "**This tool is considered BETA.**",
+ "betaWarningLine1": "This tool is considered BETA.",
"betaWarningLine2": "Things might not work as expected yet - if you find any bugs please [report them](https://github.com/stylesuxx/esc-configurator/issues/new).",
"findHelp": "For known browser issues please check [the wiki](https://github.com/stylesuxx/esc-configurator/wiki/Known-Browser-issues).",
"escButtonSelectLocally": "Flash Local Firmware",
- "cookieText": "This site or third-party tools used by this site make use of cookies necessary for the operation and useful for the purposes outlined in the cookie policy. By accepting, you consent to the use of cookies.",
+ "cookieText": "This site uses Google Analytics to track usage statistics in order to improve quality of service. This data is not (and will never be) shared with any other third party. The data collected is mostly ESC related like used layout and firmware.",
"resetDefaults": "Restore Default Settings",
"forceFlashText": "Ignore inappropriate MCU and Layout?",
- "forceFlashHint": "(Flashing inappropriate firmware may damage your ESC, do so at your own risk)",
+ "forceFlashHint": "Flashing inappropriate firmware may damage your ESC, do so at your own risk",
"migrateFlashText": "Migrate settings between different firmwares?",
"migrateFlashHint": "(This will attempt to migrate settings between different firmwares like for example from BLHeli_S to Bluejay)",
"migrationNote": "Be aware that settings are not migrated between different firmwares, make sure to take note of your motor directions and other settings you might want to move over. Settings will be migrated between different versions of the same firmware.",
@@ -99,13 +99,13 @@
"escHallSensors": "Hall Sensors",
"escSineModeRange": "Sine Mode Range",
"escBrakeStrength": "Braking Strength",
- "bluejayTextLine1": "Bluejay is BLHeli_S based firmware capable of bi-directional DShot - so a great choice if you want to run RPM filtering on your rig. This project also aims to clean up and simplify the original BLHeli_S source code.",
+ "bluejayTextLine1": "[Bluejay](https://github.com/mathiasvr/bluejay) is BLHeli_S based firmware capable of bi-directional DShot - so a great choice if you want to run RPM filtering on your rig. This project also aims to clean up and simplify the original BLHeli_S source code.",
"bluejayTextLine2": "A startup sound editor is also part of the deal.",
"bluejaySupportedHardwareLine1": "Please take the time to help us document hardware on which you have successfully flashed and tested Bluejay by [adding it to the Wiki](https://github.com/mathiasvr/bluejay/wiki/Tested-Hardware).",
"bluejaySupportedHardwareLine2": "Although it should be working on all BLHeli compatible hardware, we would like to maintain a list, so people can be confident that their chosen hardware will indeed work properly with Bluejay.",
- "blheli32ToAM32Line1": "The up and coming firmware for ARM based ESCs. Although being relatively new on the scene it has a lot of interest, both from users and manufacturers. AM32 ESCs will soon be available from different manufacturers.",
+ "blheli32ToAM32Line1": "[AM32](https://github.com/AlkaMotors/AM32-MultiRotor-ESC-firmware) - the up and coming firmware for ARM based ESCs. Although being relatively new on the scene it has a lot of interest, both from users and manufacturers. AM32 ESCs will soon be available from different manufacturers.",
"blheli32ToAM32Line2": "**AM32 can be flashed on BLHeli_32 ESCs**. But, you will have to first flash the AM32 bootloader via [STM32 Cube Programmer](https://www.st.com/en/development-tools/stm32cubeprog.html#get-software) and ST Link V2 programming adapter. The required bootloader can be found in the [AM32 bootloader repository](https://github.com/AlkaMotors/AM32_Bootloader_F051/releases).",
- "blhelisTextLine1": "BLHeli_S probably does not need an introduction - the wildly popular ESC firmware used on almost every EFM8 based ESC in the quadcopter hobby.",
+ "blhelisTextLine1": "[BLHeli_S probably](https://github.com/bitdump/BLHeli) does not need an introduction - the wildly popular ESC firmware used on almost every EFM8 based ESC in the quadcopter hobby.",
"blhelisTextLine2": "Tried and tested, supports every analog and digital protocol out there.",
"whatsNextHeader": "What's next?",
"whatsNextText": "If you want to see which features are upcoming, drop by in the [github repository](https://github.com/stylesuxx/esc-configurator). Also feel free to add a feature request if you have an idea that you want to see implemented.",
@@ -169,5 +169,7 @@
"mistaggedLine4": "**If you do not understand the risks involved in proceeding, do not hesitate to [join us on discord](https://discord.gg/QvSS5dk23C).**",
"mistaggedTagged": "Tagged",
"mistaggedDetected": "Detected",
- "update": "Update available! To update the app, refresh or restart it."
+ "update": "Update available! To update the app, refresh or restart it.",
+ "allow": "Allow",
+ "deny": "Deny"
}
diff --git a/src/translations/en/settings.json b/src/translations/en/settings.json
index dab1e47ff..3b250dde8 100644
--- a/src/translations/en/settings.json
+++ b/src/translations/en/settings.json
@@ -1,8 +1,7 @@
{
"settingsHeader": "Settings",
- "closeText": "Close",
- "directInput": "Numeric Input",
- "directInputHint": "Use numeric input for numbers instead of sliders.",
+ "directInput": "Direct Input",
+ "directInputHint": "Use direct input for numbers instead of sliders.",
"printLogs": "Print logs",
"printLogsHint": "Will print logs to the console if enabled.",
"extendedDebug": "Extended debugging",
diff --git a/src/translations/es/common.json b/src/translations/es/common.json
index 2652b5d1a..bfefc3747 100644
--- a/src/translations/es/common.json
+++ b/src/translations/es/common.json
@@ -65,14 +65,14 @@
"homeDisclaimerTextLine5": "Últimos [controladores CP210x](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers) se pueden descargar desde [aquí](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers).",
"homeDisclaimerTextLine6": "Últimos [controladores VCP STM USB](https://www.st.com/en/development-tools/stsw-stm32102.html) se puede descargar desde [aquí](https://www.st.com/en/development-tools/stsw-stm32102.html).",
"homeWelcome": "Bienvenido a **ESC - Configurator**, una utilidad diseñada para simplificar el actualizar, configurar y ajustar tus ESC.",
- "betaWarningLine1": "**Esta herramienta se considera BETA.**",
+ "betaWarningLine1": "Esta herramienta se considera BETA.",
"betaWarningLine2": "Es posible que las cosas no funcionen como se esperaba - si encuentras algún error por favor [infórmanos](https://github.com/stylesuxx/esc-configurator/issues/new).",
"findHelp": "Para problemas conocidos con el navegador, por favor revisa [la wiki](https://github.com/stylesuxx/esc-configurator/wiki/known-Browser-issues).",
"escButtonSelectLocally": "Instalar Firmware Local",
"cookieText": "Este sitio o herramientas de terceros utilizadas por este sitio hacen necesarias el uso de cookies para el funcionamiento y útiles para los propósitos descritos en la política de cookies. Al aceptar, usted consiente el uso de cookies.",
"resetDefaults": "Restaurar Configuración Predeterminada",
"forceFlashText": "¿Ignorar MCU y Layout inapropiado?",
- "forceFlashHint": "(Flashear un firmware inapropiado puede dañar tu ESC, hazlo bajo tu propio riesgo)",
+ "forceFlashHint": "Flashear un firmware inapropiado puede dañar tu ESC, hazlo bajo tu propio riesgo",
"migrateFlashText": "¿Migrar ajustes entre diferentes firmwares?",
"migrateFlashHint": "(Esto intentará migrar la configuración entre diferentes firmwares como por ejemplo de BLHeli_S a Bluejay)",
"migrationNote": "Tenga en cuenta que los ajustes no se migran entre diferentes firmwares, asegúrese de tener en cuenta las direcciones de su motor y otras configuraciones que podría querer mover. Los ajustes se migrarán entre diferentes versiones del mismo firmware.",
diff --git a/src/translations/es/settings.json b/src/translations/es/settings.json
index 7418f779e..7672b8412 100644
--- a/src/translations/es/settings.json
+++ b/src/translations/es/settings.json
@@ -1,6 +1,5 @@
{
"settingsHeader": "Ajustes",
- "closeText": "Cerrar",
"directInput": "Entrada numérica",
"directInputHint": "Utilice la entrada numérica para números en lugar de deslizadores.",
"printLogs": "Imprimir registros",
diff --git a/src/translations/tr/common.json b/src/translations/tr/common.json
index b517819bd..dbaf54a72 100644
--- a/src/translations/tr/common.json
+++ b/src/translations/tr/common.json
@@ -65,7 +65,7 @@
"homeDisclaimerTextLine5": "Güncel [CP210x Sürücüsünü](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers) [buradan](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers) indirebilirsiniz.",
"homeDisclaimerTextLine6": "Güncel [STM USB VCP Sürücüsünü](https://www.st.com/en/development-tools/stsw-stm32102.html) [buradan](https://www.st.com/en/development-tools/stsw-stm32102.html) indirebilirsiniz.",
"homeWelcome": "**ESC - Yapılandırma Aracına** Hoşgeldiniz, ESC lerinizi yapılandırma ve güncelleme işlerinizi kolaylaştırmak için tasarlanan araç.",
- "betaWarningLine1": "**Bu araç BETA dır.**",
+ "betaWarningLine1": "Bu araç BETA dır.",
"betaWarningLine2": "Beklenildiği üzere bazı şeyler çalışmayabilir - herhangi bir hata bulursanız lütfen [raporlayınız](https://github.com/stylesuxx/esc-configurator/issues/new).",
"findHelp": "For known browser issues please check [the wiki](https://github.com/stylesuxx/esc-configurator/wiki/Known-Browser-issues).",
"escButtonSelectLocally": "Donanım Yazılımı Yükle",
diff --git a/src/translations/zh-CN/common.json b/src/translations/zh-CN/common.json
index b37091316..0c915abc2 100644
--- a/src/translations/zh-CN/common.json
+++ b/src/translations/zh-CN/common.json
@@ -65,14 +65,14 @@
"homeDisclaimerTextLine5": "最新的 [CP210x 驱动程序](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers) 可从 [这里](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers)下载。",
"homeDisclaimerTextLine6": "最新的 [STM USB VCP 驱动程序](https://www.st.com/en/development-tools/stsw-stm32102.html) 可从 [这里](https://www.st.com/en/development-tools/stsw-stm32102.html)下载。",
"homeWelcome": "欢迎使用 **ESC - 配置程序**,为简化固件升级、配置电调而生的工具。",
- "betaWarningLine1": "**此工具目前还在BETA测试阶段。**",
+ "betaWarningLine1": "此工具目前还在BETA测试阶段。",
"betaWarningLine2": "部分功能可能无法正常工作 - 如果您发现任何bug,请 [反馈](https://github.com/stylesuxx/esc-configurator/issues/new)。",
"findHelp": "对于已知的浏览器问题,请检查 [wiki](https://github.com/stylesuxx/esc-configurator/wiki/Nown-Browser-issues).",
"escButtonSelectLocally": "烧录本地固件",
"cookieText": "此站点或此站点使用的第三方工具使用操作所需的 cookie 和 cookie 策略中所概述的有用性。 接受即表示同意使用 cookie。",
"resetDefaults": "恢复默认设置",
"forceFlashText": "忽略不匹配的 MCU 和布局?",
- "forceFlashHint": "(烧录不匹配的固件可能会损坏您的 ESC,请自行承担风险)",
+ "forceFlashHint": "烧录不匹配的固件可能会损坏您的 ESC,请自行承担风险",
"migrateFlashText": "在不同的固件之间迁移设置?",
"migrateFlashHint": "(这将尝试在不同固件之间迁移设置,例如从 BLHeli_S 迁移到 Bluejay)",
"migrationNote": "设置不能在不同的固件之间进行迁移, 请务必注意您的电机转向和其他您可能想要改动的设置。 设置可以在同一固件的不同版本之间迁移。",
diff --git a/src/translations/zh-CN/settings.json b/src/translations/zh-CN/settings.json
index 01b18aaee..6c2c963d4 100644
--- a/src/translations/zh-CN/settings.json
+++ b/src/translations/zh-CN/settings.json
@@ -1,8 +1,7 @@
{
"settingsHeader": "设置",
- "closeText": "关闭",
- "directInput": "数值化输入",
- "directInputHint": "直接输入数值以代替滑块。",
+ "directInput": "直接输入",
+ "directInputHint": "使用直接输入数值以代替滑块。",
"printLogs": "打印日志",
"printLogsHint": "如果启用,则会将日志打印到控制台。",
"extendedDebug": "扩展调试中",
diff --git a/src/translations/zh-TW/common.json b/src/translations/zh-TW/common.json
index 1d6ab3fd5..b8560229d 100644
--- a/src/translations/zh-TW/common.json
+++ b/src/translations/zh-TW/common.json
@@ -65,14 +65,14 @@
"homeDisclaimerTextLine5": "最新的 [CP210x 驅動程式](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers) 可從 [這裏](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers) 下載。",
"homeDisclaimerTextLine6": "最新的 [STM USB VCP 驅動程式](https://www.st.com/en/development-tools/stsw-stm32102.html) 可從 [這裏](https://www.st.com/en/development-tools/stsw-stm32102.html) 下載。",
"homeWelcome": "歡迎使用** ESC - 配置程式**,為簡化固件升級,配置電調而生的工具。",
- "betaWarningLine1": "**此工具目前還在BETA測試階段。**",
+ "betaWarningLine1": "此工具目前還在BETA測試階段。",
"betaWarningLine2": "部分功能可能無法正常工作 - 如果您發現任何bug,請 [反饋](https://github.com/stylesuxx/esc-configurator/issues/new)。",
"findHelp": "對於已知的瀏覽器問題,請檢查 [wiki](https://github.com/stylesuxx/esc-configurator/wiki/Nown-Browser-issues).",
"escButtonSelectLocally": "燒錄本地固件",
"cookieText": "此站點或此站點是以哦那個的第三方工具使用操作所需的 cookie 和cookie 策略中所概述的有用性。接受即表示同意使用 cookie。",
"resetDefaults": "恢復默認設定",
"forceFlashText": "忽略不匹配的 MCU 和佈局?",
- "forceFlashHint": "(燒錄不匹配的固件可能會損壞您的 ESC,請自行承擔風險)",
+ "forceFlashHint": "燒錄不匹配的固件可能會損壞您的 ESC,請自行承擔風險",
"migrateFlashText": "在不同的固件之間遷移設定?",
"migrateFlashHint": "(這將嘗試在不同固件之間遷移設定,例如從 BLHeli_S 遷移到 Bluejay)",
"migrationNote": "設定不能再不同的固件進行遷移,請務必注意您的電機轉向和其他您可能想要改動的設定。設定可以在同意固件的不同版本之間遷移。",
diff --git a/src/translations/zh-TW/settings.json b/src/translations/zh-TW/settings.json
index 0ea75a4d4..fa9d56c48 100644
--- a/src/translations/zh-TW/settings.json
+++ b/src/translations/zh-TW/settings.json
@@ -1,8 +1,7 @@
{
"settingsHeader": "設定",
- "closeText": "關閉",
- "directInput": "數值化輸入",
- "directInputHint": "直接輸入數值以代替滑塊。",
+ "directInput": "直接輸入",
+ "directInputHint": "使用直接輸入數值以代替滑塊。",
"printLogs": "打印日志",
"printLogsHint": "如果啓用,則會將日志打印到控制臺。",
"extendedDebug": "擴展調試中",
diff --git a/src/utils/LocalStorage.js b/src/utils/LocalStorage.js
index 1bf344f15..3224c5583 100644
--- a/src/utils/LocalStorage.js
+++ b/src/utils/LocalStorage.js
@@ -9,6 +9,18 @@ const {
defaultLanguage,
} = settings;
+function clearLog() {
+ localStorage.setItem('log', JSON.stringify([]));
+
+ return [];
+}
+
+function loadCookie() {
+ const cookie = localStorage.getItem('cookie');
+
+ return cookie === 'true';
+}
+
function loadLanguage() {
let storedLanguage = localStorage.getItem('language');
if(!storedLanguage) {
@@ -50,12 +62,6 @@ function loadLog() {
return [];
}
-function clearLog() {
- localStorage.setItem('log', JSON.stringify([]));
-
- return [];
-}
-
function loadMelodies() {
const storedMelodies = JSON.parse(localStorage.getItem('melodies'));
if(storedMelodies) {
@@ -65,14 +71,6 @@ function loadMelodies() {
return [];
}
-function loadSettings() {
- const settings = JSON.parse(localStorage.getItem('settings')) || {};
- return {
- ...defaultAppSettings,
- ...settings,
- };
-}
-
function loadSerialApi() {
if('serial' in navigator) {
return navigator.serial;
@@ -89,8 +87,17 @@ function loadSerialApi() {
return null;
}
+function loadSettings() {
+ const settings = JSON.parse(localStorage.getItem('settings')) || {};
+ return {
+ ...defaultAppSettings,
+ ...settings,
+ };
+}
+
export {
clearLog,
+ loadCookie,
loadLanguage,
loadLog,
loadMelodies,
diff --git a/src/utils/Serial.js b/src/utils/Serial.js
index 8c9797d9a..cd2ac0403 100644
--- a/src/utils/Serial.js
+++ b/src/utils/Serial.js
@@ -17,8 +17,10 @@ import { QueueProcessor } from './helpers/QueueProcessor';
* No command will be written until the previous one is finished processing.
*/
class Serial {
- constructor(port) {
+ constructor(port, timeout = 1000) {
this.port = port;
+ this.timeout = timeout;
+
this.baudRate = 115200;
this.msp = null;
this.fourWay = null;
@@ -90,7 +92,7 @@ class Serial {
await this.writeBuffer(buffer);
}.bind(this);
- return this.qp.addCommand(sendHandler, responseHandler);
+ return this.qp.addCommand(sendHandler, responseHandler, this.timeout);
}
async writeBuffer(buffer) {
diff --git a/src/utils/__tests__/LocalStorage.test.js b/src/utils/__tests__/LocalStorage.test.js
new file mode 100644
index 000000000..d3d711b2f
--- /dev/null
+++ b/src/utils/__tests__/LocalStorage.test.js
@@ -0,0 +1,134 @@
+import {
+ clearLog,
+ loadCookie,
+ loadLanguage,
+ loadLog,
+ loadMelodies,
+ loadSerialApi,
+} from '../LocalStorage';
+
+jest.mock('i18next', () => ({ changeLanguage: jest.fn() }));
+
+describe('LocalStorage', () => {
+ it('should allow to clear log', () => {
+ localStorage.setItem('log', 'foobar');
+ expect(localStorage.getItem('log')).toEqual('foobar');
+
+ clearLog();
+ expect(localStorage.getItem('log')).toEqual('[]');
+ });
+
+ it('should return empty log if it has not been set', () => {
+ expect(loadLog().length).toEqual(0);
+ });
+
+ it('should return saved log', () => {
+ const log = [
+ 'item1',
+ 'item2',
+ 'item3',
+ ];
+ localStorage.setItem('log', JSON.stringify(log));
+ expect(loadLog().length).toEqual(3);
+ });
+
+ it('should handle cookie flag', () => {
+ expect(loadCookie()).toBeFalsy();
+ });
+
+ it('should handle loading melodies', () => {
+ expect(loadMelodies().length).toEqual(0);
+
+ const melodies = [
+ 'item1',
+ 'item2',
+ 'item3',
+ ];
+
+ localStorage.setItem('melodies', JSON.stringify(melodies));
+ expect(loadMelodies().length).toEqual(3);
+ });
+
+ it('should handle default language', () => {
+ expect(loadLanguage()).toEqual('en');
+ });
+
+ it('should handle stored language', () => {
+ localStorage.setItem('language', 'de');
+ expect(loadLanguage()).toEqual('de');
+
+ localStorage.removeItem('language');
+ });
+
+ it('should handle loading language', () => {
+ expect(loadLanguage()).toEqual('en');
+
+ Object.defineProperty(navigator, 'languages', {
+ configurable: true,
+ get: () => ['en'],
+ });
+
+ expect(loadLanguage()).toEqual('en');
+ });
+
+ it('should handle no language', () => {
+ Object.defineProperty(navigator, 'languages', {
+ configurable: true,
+ get: () => [],
+ });
+
+ delete navigator.language;
+ Object.defineProperty(navigator, 'language', {
+ configurable: true,
+ get: () => null,
+ });
+
+ Object.defineProperty(navigator, 'userLanguage', {
+ configurable: true,
+ get: () => null,
+ });
+
+ delete navigator.userLanguage;
+
+ expect(loadLanguage()).toEqual('en');
+ });
+
+ it('should return null if no serial API is found', () => {
+ expect(loadSerialApi()).toEqual(null);
+ });
+
+ it('should return serial API if available in navigator object', () => {
+ Object.defineProperty(navigator, 'serial', {
+ configurable: true,
+ get: () => 'serial',
+ });
+ expect(loadSerialApi()).toEqual('serial');
+
+ delete navigator.serial;
+ });
+
+ it('should return serial API polyfill', () => {
+ Object.defineProperty(navigator, 'usb', {
+ configurable: true,
+ get: () => 'usb',
+ });
+ expect(loadSerialApi()).toEqual({});
+
+ delete navigator.usb;
+ });
+
+ it('should return handle Brave Browser', () => {
+ Object.defineProperty(navigator, 'usb', {
+ configurable: true,
+ get: () => 'usb',
+ });
+ Object.defineProperty(navigator, 'brave', {
+ configurable: true,
+ get: () => true,
+ });
+ expect(loadSerialApi()).toEqual(null);
+
+ delete navigator.usb;
+ delete navigator.brave;
+ });
+});
diff --git a/src/utils/__tests__/Serial.test.js b/src/utils/__tests__/Serial.test.js
index 298cb6160..6177e3403 100644
--- a/src/utils/__tests__/Serial.test.js
+++ b/src/utils/__tests__/Serial.test.js
@@ -11,6 +11,8 @@ let serial;
let Serial;
describe('Serial', () => {
+ const timeout = 50;
+
beforeAll(async() => {
/**
* require component instead of import so that we can properly
@@ -40,7 +42,7 @@ describe('Serial', () => {
},
};
- serial = new Serial(port);
+ serial = new Serial(port, timeout);
});
it('should throw without port', async() => {
@@ -87,7 +89,7 @@ describe('Serial', () => {
},
};
- serial = new Serial(port);
+ serial = new Serial(port, timeout);
expect(() => serial.open()).not.toThrow();
});
@@ -107,7 +109,7 @@ describe('Serial', () => {
},
};
- serial = new Serial(port);
+ serial = new Serial(port, timeout);
expect(() => serial.open()).not.toThrow();
});
@@ -133,7 +135,7 @@ describe('Serial', () => {
},
};
- serial = new Serial(port);
+ serial = new Serial(port, timeout);
await serial.open();
// commands will all time out
@@ -173,7 +175,7 @@ describe('Serial', () => {
},
};
- serial = new Serial(port);
+ serial = new Serial(port, timeout);
await serial.open();
expect(port.open).toHaveBeenCalled();
@@ -203,7 +205,7 @@ describe('Serial', () => {
},
};
- serial = new Serial(port);
+ serial = new Serial(port, timeout);
await serial.open();
expect(serial.startFourWayInterface()).toBe(undefined);
diff --git a/src/utils/helpers/__tests__/Flash.test.js b/src/utils/helpers/__tests__/Flash.test.js
index 9ee851a83..f3182eb93 100644
--- a/src/utils/helpers/__tests__/Flash.test.js
+++ b/src/utils/helpers/__tests__/Flash.test.js
@@ -2,48 +2,86 @@ import fs from 'fs';
import Flash from '../Flash';
-test('should parse a valid hex file', () => {
- const hexContent = fs.readFileSync(`${__dirname}/valid.hex`);
- const hexString = hexContent.toString();
- const result = Flash.parseHex(hexString);
+describe('Flash', () => {
+ test('should parse a valid hex file', () => {
+ const hexContent = fs.readFileSync(`${__dirname}/valid.hex`);
+ const hexString = hexContent.toString();
+ const result = Flash.parseHex(hexString);
- expect(result).not.toBeNull();
-});
+ expect(result).not.toBeNull();
+ });
-test('should not parse an invalid hex file', () => {
- const hexContent = fs.readFileSync(`${__dirname}/invalid.hex`);
- const hexString = hexContent.toString();
- const result = Flash.parseHex(hexString);
+ test('should not parse an invalid hex file', () => {
+ const hexContent = fs.readFileSync(`${__dirname}/invalid.hex`);
+ const hexString = hexContent.toString();
+ const result = Flash.parseHex(hexString);
- expect(result).toBeNull();
-});
+ expect(result).toBeNull();
+ });
-test('should not parse a hex file with broken checksum', () => {
- const hexContent = fs.readFileSync(`${__dirname}/broken_checksum.hex`);
- const hexString = hexContent.toString();
- const result = Flash.parseHex(hexString);
+ test('should not parse a hex file with broken checksum', () => {
+ const hexContent = fs.readFileSync(`${__dirname}/broken_checksum.hex`);
+ const hexString = hexContent.toString();
+ const result = Flash.parseHex(hexString);
- expect(result).toBeNull();
-});
+ expect(result).toBeNull();
+ });
-test('should fill an Image to a given size', () => {
- const hexContent = fs.readFileSync(`${__dirname}/valid.hex`);
- const hexString = hexContent.toString();
- const parsed = Flash.parseHex(hexString);
- const endAddress = parsed.data[parsed.data.length - 1].address + parsed.data[parsed.data.length - 1].bytes;
- const flashOffset = 0;
- const result = Flash.fillImage(parsed, endAddress - flashOffset, flashOffset);
+ test('should fill an Image to a given size', () => {
+ const hexContent = fs.readFileSync(`${__dirname}/valid.hex`);
+ const hexString = hexContent.toString();
+ const parsed = Flash.parseHex(hexString);
+ const endAddress = parsed.data[parsed.data.length - 1].address + parsed.data[parsed.data.length - 1].bytes;
+ const flashOffset = 0;
+ const result = Flash.fillImage(parsed, endAddress - flashOffset, flashOffset);
- expect(result.length).toEqual(endAddress);
-});
+ expect(result.length).toEqual(endAddress);
+ });
+
+ test('should fail filling an Image with address higher than length', () => {
+ const hexContent = fs.readFileSync(`${__dirname}/valid.hex`);
+ const hexString = hexContent.toString();
+ const parsed = Flash.parseHex(hexString);
+ const endAddress = parsed.data[parsed.data.length - 1].address + parsed.data[parsed.data.length - 1].bytes;
+ const flashOffset = 0;
+ const result = Flash.fillImage(parsed, endAddress - flashOffset - 1000, flashOffset);
+
+ expect(result).toBeNull();
+ });
+
+ test('should handle extended segment address record', () => {
+ let hexContent = ':0100000200000000000000';
+ let hexString = hexContent.toString();
+ let result = Flash.parseHex(hexString);
+
+ expect(result).toBeNull();
+
+ hexContent = ':01000002FF000000000000';
+ hexString = hexContent.toString();
+ result = Flash.parseHex(hexString);
+
+ expect(result).toBeNull();
+ });
+
+ test('should handle start of segment address record', () => {
+ let hexContent = ':0100000300000000000000';
+ let hexString = hexContent.toString();
+ let result = Flash.parseHex(hexString);
+
+ expect(result).toBeNull();
+
+ hexContent = ':01000003FF000000000000';
+ hexString = hexContent.toString();
+ result = Flash.parseHex(hexString);
+
+ expect(result).toBeNull();
+ });
-test('should fail filling an Image with address higher than length', () => {
- const hexContent = fs.readFileSync(`${__dirname}/valid.hex`);
- const hexString = hexContent.toString();
- const parsed = Flash.parseHex(hexString);
- const endAddress = parsed.data[parsed.data.length - 1].address + parsed.data[parsed.data.length - 1].bytes;
- const flashOffset = 0;
- const result = Flash.fillImage(parsed, endAddress - flashOffset - 1000, flashOffset);
+ test('should handle start of linear address record', () => {
+ const hexContent = ':01000005FF000000000000';
+ const hexString = hexContent.toString();
+ const result = Flash.parseHex(hexString);
- expect(result).toBeNull();
+ expect(result).toBeNull();
+ });
});
diff --git a/src/utils/helpers/__tests__/React.test.jsx b/src/utils/helpers/__tests__/React.test.jsx
index a940177f6..5da96a756 100644
--- a/src/utils/helpers/__tests__/React.test.jsx
+++ b/src/utils/helpers/__tests__/React.test.jsx
@@ -17,9 +17,10 @@ function TestComponent({
);
}
+TestComponent.defaultProps = { timeout: null };
TestComponent.propTypes = {
callback: PropTypes.func.isRequired,
- timeout: PropTypes.number.isRequired,
+ timeout: PropTypes.number,
};
test('useInterval with proper delay', async () => {
@@ -28,12 +29,12 @@ test('useInterval with proper delay', async () => {
render(