mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Matrix Layout enhancements (#1701)
* Support gaps on Matrix Layout * Ensure BlackBorder objects are initialised * Update Changelog * Fix automated semicolon insertion * Fix automated semicolon insertion * Remove SPI activation from post install script (#1708)
This commit is contained in:
parent
fd5a94a32a
commit
fedb409157
@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- Support gaps on Matrix Layout (#1696)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
@ -327,7 +327,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="ltd">
|
<td class="ltd">
|
||||||
<label class="ltdlabel" for="ip_ma_direction" data-i18n="conf_leds_layout_ma_direction">Cabling</label>
|
<label class="ltdlabel" for="ip_ma_direction" data-i18n="conf_leds_layout_ma_direction">Direction</label>
|
||||||
</td>
|
</td>
|
||||||
<td class="itd">
|
<td class="itd">
|
||||||
<select class="form-control ledMAconstr" id="ip_ma_direction">
|
<select class="form-control ledMAconstr" id="ip_ma_direction">
|
||||||
@ -352,6 +352,61 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading headcollapse" data-toggle="collapse" data-target="#collapse-maadv" id="ma_advanced_settings">
|
||||||
|
<h4 class="panel-title">
|
||||||
|
<a>
|
||||||
|
<i class="fa fa-fw fa-cogs"></i>
|
||||||
|
<span data-i18n="conf_leds_layout_advanced">Advanced settings</span>
|
||||||
|
<i class="fa fa-angle-down pull-right" id="ma_advanced_settings_right_icon"></i>
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div id="collapse-maadv" class="panel-collapse collapse">
|
||||||
|
<div class="panel-body ">
|
||||||
|
<table class="tableform borderless">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="ltd">
|
||||||
|
<label class="ltdlabel" for="ip_ma_gapleft" data-i18n="conf_leds_layout_gapleft">Gap Left</label>
|
||||||
|
</td>
|
||||||
|
<td class="itd input-group">
|
||||||
|
<input class="form-control ledMAconstr" id="ip_ma_gapleft" type="number" value="0" min="0" max="100" step="1"></input>
|
||||||
|
<div class="input-group-addon" data-i18n="edt_append_percent">%h</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="ltd">
|
||||||
|
<label class="ltdlabel" for="ip_ma_gapright" data-i18n="conf_leds_layout_gapright">Gap Right</label>
|
||||||
|
</td>
|
||||||
|
<td class="itd input-group">
|
||||||
|
<input class="form-control ledMAconstr" id="ip_ma_gapright" type="number" value="0" min="0" max="100" step="1"></input>
|
||||||
|
<div class="input-group-addon" data-i18n="edt_append_percent">%v</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="ltd">
|
||||||
|
<label class="ltdlabel" for="ip_ma_gaptop" data-i18n="conf_leds_layout_gaptop">Gap Left</label>
|
||||||
|
</td>
|
||||||
|
<td class="itd input-group">
|
||||||
|
<input class="form-control ledMAconstr" id="ip_ma_gaptop" type="number" value="0" min="0" max="100" step="1"></input>
|
||||||
|
<div class="input-group-addon" data-i18n="edt_append_percent">%h</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="ltd">
|
||||||
|
<label class="ltdlabel" for="ip_ma_gapbottom" data-i18n="conf_leds_layout_gapbottom">Gap Right</label>
|
||||||
|
</td>
|
||||||
|
<td class="itd input-group">
|
||||||
|
<input class="form-control ledMAconstr" id="ip_ma_gapbottom" type="number" value="0" min="0" max="100" step="1"></input>
|
||||||
|
<div class="input-group-addon" data-i18n="edt_append_percent">%v</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel-footer" style="text-align:right;">
|
<div class="panel-footer" style="text-align:right;">
|
||||||
<button id="btn_ma_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
|
<button id="btn_ma_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -117,6 +117,10 @@
|
|||||||
"conf_leds_layout_cl_topright": "Top Right (Corner)",
|
"conf_leds_layout_cl_topright": "Top Right (Corner)",
|
||||||
"conf_leds_layout_cl_vleddepth": "Vertical LED depth",
|
"conf_leds_layout_cl_vleddepth": "Vertical LED depth",
|
||||||
"conf_leds_layout_frame": "Classic Layout (LED Frame)",
|
"conf_leds_layout_frame": "Classic Layout (LED Frame)",
|
||||||
|
"conf_leds_layout_gapleft": "Left gap",
|
||||||
|
"conf_leds_layout_gapright": "Right gap",
|
||||||
|
"conf_leds_layout_gaptop": "Top gap",
|
||||||
|
"conf_leds_layout_gapbottom": "Bottom gap",
|
||||||
"conf_leds_layout_generatedconf": "Generated/Current LED Configuration",
|
"conf_leds_layout_generatedconf": "Generated/Current LED Configuration",
|
||||||
"conf_leds_layout_generation_success": "LED Layout generated sucessfully",
|
"conf_leds_layout_generation_success": "LED Layout generated sucessfully",
|
||||||
"conf_leds_layout_generation_error": "LED Layout was not generated",
|
"conf_leds_layout_generation_error": "LED Layout was not generated",
|
||||||
|
@ -468,17 +468,18 @@ function createClassicLeds() {
|
|||||||
aceEdt.set(finalLedArray);
|
aceEdt.set(finalLedArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction) {
|
function createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction, gap) {
|
||||||
// Big thank you to RanzQ (Juha Rantanen) from Github for this script
|
// Big thank you to RanzQ (Juha Rantanen) from Github for this script
|
||||||
// https://raw.githubusercontent.com/RanzQ/hyperion-audio-effects/master/matrix-config.js
|
// https://raw.githubusercontent.com/RanzQ/hyperion-audio-effects/master/matrix-config.js
|
||||||
|
|
||||||
var parallel = false
|
let parallel = false;
|
||||||
var leds = []
|
const leds = [];
|
||||||
var hblock = 1.0 / ledshoriz
|
|
||||||
var vblock = 1.0 / ledsvert
|
const hblock = (1.0 - gap.left - gap.right) / ledshoriz;
|
||||||
|
const vblock = (1.0 - gap.top - gap.bottom) / ledsvert;
|
||||||
|
|
||||||
if (cabling == "parallel") {
|
if (cabling == "parallel") {
|
||||||
parallel = true
|
parallel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -487,10 +488,10 @@ function createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction) {
|
|||||||
* @param {Number} y Vertical position in matrix
|
* @param {Number} y Vertical position in matrix
|
||||||
*/
|
*/
|
||||||
function addLed(x, y) {
|
function addLed(x, y) {
|
||||||
var hscanMin = x * hblock
|
let hscanMin = gap.left + (x * hblock);
|
||||||
var hscanMax = (x + 1) * hblock
|
let hscanMax = gap.left + (x + 1) * hblock;
|
||||||
var vscanMin = y * vblock
|
let vscanMin = gap.top + y * vblock;
|
||||||
var vscanMax = (y + 1) * vblock
|
let vscanMax = gap.top + (y + 1) * vblock;
|
||||||
|
|
||||||
hscanMin = round(hscanMin);
|
hscanMin = round(hscanMin);
|
||||||
hscanMax = round(hscanMax);
|
hscanMax = round(hscanMax);
|
||||||
@ -502,43 +503,41 @@ function createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction) {
|
|||||||
hmax: hscanMax,
|
hmax: hscanMax,
|
||||||
vmin: vscanMin,
|
vmin: vscanMin,
|
||||||
vmax: vscanMax
|
vmax: vscanMax
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var startYX = start.split('-')
|
const startYX = start.split('-');
|
||||||
var startX = startYX[1] === 'right' ? ledshoriz - 1 : 0
|
let startX = startYX[1] === 'right' ? ledshoriz - 1 : 0;
|
||||||
var startY = startYX[0] === 'bottom' ? ledsvert - 1 : 0
|
let startY = startYX[0] === 'bottom' ? ledsvert - 1 : 0;
|
||||||
var endX = startX === 0 ? ledshoriz - 1 : 0
|
let endX = startX === 0 ? ledshoriz - 1 : 0;
|
||||||
var endY = startY === 0 ? ledsvert - 1 : 0
|
let endY = startY === 0 ? ledsvert - 1 : 0;
|
||||||
var forward = startX < endX
|
let forward = startX < endX;
|
||||||
|
let downward = startY < endY;
|
||||||
|
|
||||||
var downward = startY < endY
|
let x, y;
|
||||||
|
|
||||||
var x, y
|
|
||||||
|
|
||||||
if (direction === 'vertical') {
|
if (direction === 'vertical') {
|
||||||
for (x = startX; forward && x <= endX || !forward && x >= endX; x += forward ? 1 : -1) {
|
for (x = startX; forward && x <= endX || !forward && x >= endX; x += forward ? 1 : -1) {
|
||||||
for (y = startY; downward && y <= endY || !downward && y >= endY; y += downward ? 1 : -1) {
|
for (y = startY; downward && y <= endY || !downward && y >= endY; y += downward ? 1 : -1) {
|
||||||
|
addLed(x, y);
|
||||||
addLed(x, y)
|
|
||||||
}
|
}
|
||||||
if (!parallel) {
|
if (!parallel) {
|
||||||
downward = !downward
|
downward = !downward;
|
||||||
var tmp = startY
|
const tmp = startY;
|
||||||
startY = endY
|
startY = endY;
|
||||||
endY = tmp
|
endY = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (y = startY; downward && y <= endY || !downward && y >= endY; y += downward ? 1 : -1) {
|
for (y = startY; downward && y <= endY || !downward && y >= endY; y += downward ? 1 : -1) {
|
||||||
for (x = startX; forward && x <= endX || !forward && x >= endX; x += forward ? 1 : -1) {
|
for (x = startX; forward && x <= endX || !forward && x >= endX; x += forward ? 1 : -1) {
|
||||||
addLed(x, y)
|
addLed(x, y);
|
||||||
}
|
}
|
||||||
if (!parallel) {
|
if (!parallel) {
|
||||||
forward = !forward
|
forward = !forward;
|
||||||
var tmp = startX
|
const tmp = startX;
|
||||||
startX = endX
|
startX = endX;
|
||||||
endX = tmp
|
endX = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,13 +550,20 @@ function createMatrixLeds() {
|
|||||||
// https://raw.githubusercontent.com/RanzQ/hyperion-audio-effects/master/matrix-config.js
|
// https://raw.githubusercontent.com/RanzQ/hyperion-audio-effects/master/matrix-config.js
|
||||||
|
|
||||||
//get values
|
//get values
|
||||||
var ledshoriz = parseInt($("#ip_ma_ledshoriz").val());
|
const ledshoriz = parseInt($("#ip_ma_ledshoriz").val());
|
||||||
var ledsvert = parseInt($("#ip_ma_ledsvert").val());
|
const ledsvert = parseInt($("#ip_ma_ledsvert").val());
|
||||||
var cabling = $("#ip_ma_cabling").val();
|
const cabling = $("#ip_ma_cabling").val();
|
||||||
var direction = $("#ip_ma_direction").val();
|
const direction = $("#ip_ma_direction").val();
|
||||||
var start = $("#ip_ma_start").val();
|
const start = $("#ip_ma_start").val();
|
||||||
|
const gap = {
|
||||||
|
//gap values % -> float
|
||||||
|
left: parseInt($("#ip_ma_gapleft").val()) / 100,
|
||||||
|
right: parseInt($("#ip_ma_gapright").val()) / 100,
|
||||||
|
top: parseInt($("#ip_ma_gaptop").val()) / 100,
|
||||||
|
bottom: parseInt($("#ip_ma_gapbottom").val()) / 100,
|
||||||
|
};
|
||||||
|
|
||||||
nonBlacklistLedArray = createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction);
|
nonBlacklistLedArray = createMatrixLayout(ledshoriz, ledsvert, cabling, start, direction, gap);
|
||||||
finalLedArray = blackListLeds(nonBlacklistLedArray, ledBlacklist);
|
finalLedArray = blackListLeds(nonBlacklistLedArray, ledBlacklist);
|
||||||
|
|
||||||
createLedPreview(finalLedArray);
|
createLedPreview(finalLedArray);
|
||||||
@ -797,6 +803,35 @@ $(document).ready(function () {
|
|||||||
|
|
||||||
$('.ledMAconstr').on("change", function () {
|
$('.ledMAconstr').on("change", function () {
|
||||||
valValue(this.id, this.value, this.min, this.max);
|
valValue(this.id, this.value, this.min, this.max);
|
||||||
|
|
||||||
|
// top/bottom and left/right must not overlap
|
||||||
|
switch (this.id) {
|
||||||
|
case "ip_ma_gapleft":
|
||||||
|
let left = 100 - parseInt($("#ip_ma_gapright").val());
|
||||||
|
if (this.value > left) {
|
||||||
|
$(this).val(left);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "ip_ma_gapright":
|
||||||
|
let right = 100 - parseInt($("#ip_ma_gapleft").val());
|
||||||
|
if (this.value > right) {
|
||||||
|
$(this).val(right);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "ip_ma_gaptop":
|
||||||
|
let top = 100 - parseInt($("#ip_ma_gapbottom").val());
|
||||||
|
if (this.value > top) {
|
||||||
|
$(this).val(top);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "ip_ma_gapbottom":
|
||||||
|
let bottom = 100 - parseInt($("#ip_ma_gaptop").val());
|
||||||
|
if (this.value > bottom) {
|
||||||
|
$(this).val(bottom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
createMatrixLeds();
|
createMatrixLeds();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -26,13 +26,6 @@ install_file()
|
|||||||
|
|
||||||
echo "--- Hyperion ambient light postinstall ---"
|
echo "--- Hyperion ambient light postinstall ---"
|
||||||
|
|
||||||
#check system
|
|
||||||
CPU_RPI=`grep -m1 -c 'BCM2708\|BCM2709\|BCM2710\|BCM2835\|BCM2836\|BCM2837\|BCM2711' /proc/cpuinfo`
|
|
||||||
CPU_X32X64=`uname -m | grep 'x86_32\|i686\|x86_64' | wc -l`
|
|
||||||
|
|
||||||
#Check for a bootloader as Berryboot
|
|
||||||
BOOT_BERRYBOOT=$(grep -m1 -c '\(/var/media\|/media/pi\)/berryboot' /etc/mtab)
|
|
||||||
|
|
||||||
#get current system ip
|
#get current system ip
|
||||||
NET_IP=`hostname -I | cut -d " " -f1`
|
NET_IP=`hostname -I | cut -d " " -f1`
|
||||||
|
|
||||||
@ -128,25 +121,6 @@ fi
|
|||||||
rm -r /usr/share/hyperion/desktop 2>/dev/null
|
rm -r /usr/share/hyperion/desktop 2>/dev/null
|
||||||
rm -r /usr/share/hyperion/icons 2>/dev/null
|
rm -r /usr/share/hyperion/icons 2>/dev/null
|
||||||
|
|
||||||
#Check, if dtparam=spi=on is in place
|
|
||||||
if [ $CPU_RPI -eq 1 ]; then
|
|
||||||
BOOT_DIR="/boot"
|
|
||||||
if [ $BOOT_BERRYBOOT -eq 1 ]; then
|
|
||||||
BOOT_DIR=$(sed -ne "s#/dev/mmcblk0p1 \([^ ]*\) vfat rw,.*#\1#p" /etc/mtab)
|
|
||||||
fi
|
|
||||||
if [ -z "$BOOT_DIR" -o ! -f "$BOOT_DIR/config.txt" ]; then
|
|
||||||
echo '---> Warning: RPi using BERRYBOOT found but can not locate where config.txt is to enable SPI. (BOOT_DIR='"$BOOT_DIR)"
|
|
||||||
SPIOK=1 # Not sure if OK, but don't ask to reboot
|
|
||||||
else
|
|
||||||
SPIOK=`grep '^\dtparam=spi=on' "$BOOT_DIR/config.txt" | wc -l`
|
|
||||||
if [ $SPIOK -ne 1 ]; then
|
|
||||||
echo '---> Raspberry Pi found, but SPI is not set, we write "dtparam=spi=on" to '"$BOOT_DIR/config.txt"
|
|
||||||
sed -i '$a dtparam=spi=on' "$BOOT_DIR/config.txt"
|
|
||||||
REBOOTMESSAGE="echo Please reboot your Raspberry Pi, we inserted dtparam=spi=on to $BOOT_DIR/config.txt"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ${START_MSG}
|
echo ${START_MSG}
|
||||||
|
|
||||||
echo "-----------------------------------------------------------------------------"
|
echo "-----------------------------------------------------------------------------"
|
||||||
@ -171,7 +145,7 @@ if [ -e /opt/hyperion/ ]
|
|||||||
then
|
then
|
||||||
echo
|
echo
|
||||||
echo "---------------------------------------------------------------------------------"
|
echo "---------------------------------------------------------------------------------"
|
||||||
echo "- It seemd that you have an older version of hyperion installed in /opt/hyperion -"
|
echo "- It seems that you have an older version of hyperion installed in /opt/hyperion -"
|
||||||
echo "- please remove it to avoid problems -"
|
echo "- please remove it to avoid problems -"
|
||||||
echo "---------------------------------------------------------------------------------"
|
echo "---------------------------------------------------------------------------------"
|
||||||
fi
|
fi
|
||||||
|
@ -110,7 +110,7 @@ namespace hyperion
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct result
|
// Construct result
|
||||||
BlackBorder detectedBorder;
|
BlackBorder detectedBorder{};
|
||||||
detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
|
detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
|
||||||
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
|
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
|
||||||
detectedBorder.verticalSize = firstNonBlackXPixelIndex;
|
detectedBorder.verticalSize = firstNonBlackXPixelIndex;
|
||||||
@ -167,7 +167,7 @@ namespace hyperion
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct result
|
// Construct result
|
||||||
BlackBorder detectedBorder;
|
BlackBorder detectedBorder{};
|
||||||
detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
|
detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
|
||||||
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
|
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
|
||||||
detectedBorder.verticalSize = firstNonBlackXPixelIndex;
|
detectedBorder.verticalSize = firstNonBlackXPixelIndex;
|
||||||
@ -224,7 +224,7 @@ namespace hyperion
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct result
|
// Construct result
|
||||||
BlackBorder detectedBorder;
|
BlackBorder detectedBorder{};
|
||||||
detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
|
detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
|
||||||
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
|
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
|
||||||
detectedBorder.verticalSize = firstNonBlackXPixelIndex;
|
detectedBorder.verticalSize = firstNonBlackXPixelIndex;
|
||||||
@ -267,7 +267,7 @@ namespace hyperion
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct result
|
// Construct result
|
||||||
BlackBorder detectedBorder;
|
BlackBorder detectedBorder{};
|
||||||
detectedBorder.unknown = firstNonBlackYPixelIndex == -1;
|
detectedBorder.unknown = firstNonBlackYPixelIndex == -1;
|
||||||
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
|
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
|
||||||
detectedBorder.verticalSize = 0;
|
detectedBorder.verticalSize = 0;
|
||||||
|
@ -144,6 +144,30 @@
|
|||||||
"start": {
|
"start": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [ "top-left", "top-right", "bottom-left", "bottom-right" ]
|
"enum": [ "top-left", "top-right", "bottom-left", "bottom-right" ]
|
||||||
|
},
|
||||||
|
"gapleft": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 100,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"gapright": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 100,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"gaptop": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 100,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"gapbottom": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 100,
|
||||||
|
"default": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user