Merge remote-tracking branch 'upstream/main' into mdev

This commit is contained in:
Ewoud
2023-01-02 21:23:23 +01:00
7 changed files with 326 additions and 230 deletions

View File

@@ -665,12 +665,8 @@ class WS2812FX { // 96 bytes
timebase(0),
isMatrix(false),
#ifndef WLED_DISABLE_2D
hPanels(1),
vPanels(1),
panelH(8),
panelW(8),
panels(1),
matrix{0,0,0,0},
panel{{0,0,0,0}},
#endif
// semi-private (just obscured) used in effect functions through macros
_currentPalette(CRGBPalette16(CRGB::Black)),
@@ -707,6 +703,7 @@ class WS2812FX { // 96 bytes
_mode.clear();
_modeData.clear();
_segments.clear();
panel.clear();
customPalettes.clear();
if (useLedsArray && Segment::_globalLeds) free(Segment::_globalLeds);
}
@@ -819,22 +816,31 @@ class WS2812FX { // 96 bytes
#ifndef WLED_DISABLE_2D
#define WLED_MAX_PANELS 64
uint8_t
hPanels,
vPanels;
panels;
uint16_t
panelH,
panelW;
struct {
bool bottomStart : 1;
bool rightStart : 1;
bool vertical : 1;
bool serpentine : 1;
} matrix;
typedef struct panel_bitfield_t {
bool bottomStart : 1; // starts at bottom?
bool rightStart : 1; // starts on right?
bool vertical : 1; // is vertical?
bool serpentine : 1; // is serpentine?
typedef struct panel_t {
uint16_t xOffset; // x offset relative to the top left of matrix in LEDs
uint16_t yOffset; // y offset relative to the top left of matrix in LEDs
uint8_t width; // width of the panel
uint8_t height; // height of the panel
union {
uint8_t options;
struct {
bool bottomStart : 1; // starts at bottom?
bool rightStart : 1; // starts on right?
bool vertical : 1; // is vertical?
bool serpentine : 1; // is serpentine?
};
};
} Panel;
Panel
matrix,
panel[WLED_MAX_PANELS];
std::vector<Panel> panel;
#endif
void

View File

@@ -43,63 +43,64 @@ void WS2812FX::setUpMatrix(bool reset) {
customMappingSize = 0;
}
// important if called from set.cpp, irrelevant if called from cfg.cpp
// fix limits if not a matrix set-up (no finalizeInit() called from set.cpp)
Segment::maxWidth = _length;
Segment::maxHeight = 1;
// isMatrix is set in cfg.cpp or set.cpp
if (isMatrix) {
uint16_t maxWidth = hPanels * panelW;
uint16_t maxHeight = vPanels * panelH;
// calculate width dynamically because it will have gaps
Segment::maxWidth = 1;
Segment::maxHeight = 1;
for (size_t i = 0; i < panel.size(); i++) {
Panel &p = panel[i];
if (p.xOffset + p.width > Segment::maxWidth) {
Segment::maxWidth = p.xOffset + p.width;
}
if (p.yOffset + p.height > Segment::maxHeight) {
Segment::maxHeight = p.yOffset + p.height;
}
}
// safety check
if (maxWidth * maxHeight > MAX_LEDS || maxWidth == 1 || maxHeight == 1) {
if (Segment::maxWidth * Segment::maxHeight > MAX_LEDS || Segment::maxWidth <= 1 || Segment::maxHeight <= 1) {
DEBUG_PRINTLN(F("2D Bounds error."));
isMatrix = false;
Segment::maxWidth = _length;
Segment::maxHeight = 1;
panels = 0;
panel.clear(); // release memory allocated by panels
return;
}
if (reset) { //WLEDMM: add reset option to switch on/off reset of customMappingTable
customMappingTable = new uint16_t[maxWidth * maxHeight];
customMappingTable = new uint16_t[Segment::maxWidth * Segment::maxHeight];
//WLEDMM: init customMappingTable with a 1:1 mapping (for customMappingTable[customMappingTable[x]])
for (uint16_t i=0; i<maxWidth * maxHeight; i++) {
for (uint16_t i=0; i<Segment::maxWidth * Segment::maxHeight; i++) {
customMappingTable[i] = i;
}
}
if (customMappingTable != nullptr) {
Segment::maxWidth = maxWidth;
Segment::maxHeight = maxHeight;
customMappingSize = maxWidth * maxHeight;
customMappingSize = Segment::maxWidth * Segment::maxHeight;
uint16_t startL; // index in custom mapping array (logical strip)
uint16_t startP; // position of 1st pixel of panel on (virtual) strip
uint16_t x, y, offset;
uint8_t h = matrix.vertical ? vPanels : hPanels;
uint8_t v = matrix.vertical ? hPanels : vPanels;
//WLEDMM: Comment this as we initialize with cmt[i]=i
// fill with empty in case we don't fill the entire matrix
// for (size_t i = 0; i< customMappingSize; i++) {
// customMappingTable[i] = (uint16_t)-1;
// }
for (uint8_t j=0, p=0; j<v; j++) {
for (uint8_t i=0; i<h; i++, p++) {
y = (matrix.vertical ? matrix.rightStart : matrix.bottomStart) ? v - j - 1 : j;
x = (matrix.vertical ? matrix.bottomStart : matrix.rightStart) ? h - i - 1 : i;
x = matrix.serpentine && j%2 ? h - x - 1 : x;
startL = (matrix.vertical ? y : x) * panelW + (matrix.vertical ? x : y) * Segment::maxWidth * panelH; // logical index (top-left corner)
startP = p * panelW * panelH; // physical index (top-left corner)
uint8_t H = panel[h*j + i].vertical ? panelW : panelH;
uint8_t W = panel[h*j + i].vertical ? panelH : panelW;
for (uint16_t l=0, q=0; l<H; l++) {
for (uint16_t k=0; k<W; k++, q++) {
y = (panel[h*j + i].vertical ? panel[h*j + i].rightStart : panel[h*j + i].bottomStart) ? H - l - 1 : l;
x = (panel[h*j + i].vertical ? panel[h*j + i].bottomStart : panel[h*j + i].rightStart) ? W - k - 1 : k;
x = (panel[h*j + i].serpentine && l%2) ? (W - x - 1) : x;
offset = (panel[h*j + i].vertical ? y : x) + (panel[h*j + i].vertical ? x : y) * Segment::maxWidth;
customMappingTable[customMappingTable[startL + offset]] = startP + q; //WLEDMM: allow for 2 transitions if reset = false (ledmap and logical to physical)
}
uint16_t x, y, pix=0; //pixel
for (size_t pan = 0; pan < panel.size(); pan++) {
Panel &p = panel[pan];
uint16_t h = p.vertical ? p.height : p.width;
uint16_t v = p.vertical ? p.width : p.height;
for (size_t j = 0; j < v; j++){
for(size_t i = 0; i < h; i++, pix++) {
y = (p.vertical?p.rightStart:p.bottomStart) ? v-j-1 : j;
x = (p.vertical?p.bottomStart:p.rightStart) ? h-i-1 : i;
x = p.serpentine && j%2 ? h-x-1 : x;
customMappingTable[customMappingTable[(p.yOffset + (p.vertical?x:y)) * Segment::maxWidth + p.xOffset + (p.vertical?y:x)]] = pix; //WLEDMM: allow for 2 transitions if reset = false (ledmap and logical to physical)
}
}
}
#ifdef WLED_DEBUG
DEBUG_PRINT(F("Matrix ledmap:"));
for (uint16_t i=0; i<customMappingSize; i++) {
@@ -109,7 +110,13 @@ void WS2812FX::setUpMatrix(bool reset) {
DEBUG_PRINTLN();
#endif
} else { // memory allocation error
DEBUG_PRINTLN(F("Ledmap alloc error."));
isMatrix = false;
panels = 0;
panel.clear();
Segment::maxWidth = _length;
Segment::maxHeight = 1;
return;
}
}
#else
@@ -123,7 +130,7 @@ void IRAM_ATTR_YN WS2812FX::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM
#ifndef WLED_DISABLE_2D
if (!isMatrix) return; // not a matrix set-up
uint16_t index = y * Segment::maxWidth + x;
if (index >= customMappingSize) return; // customMappingSize is always W * H of matrix in 2D setup
if (index >= customMappingSize) return;
#else
uint16_t index = x;
if (index >= _length) return;

View File

@@ -100,32 +100,38 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
JsonObject matrix = hw_led[F("matrix")];
if (!matrix.isNull()) {
strip.isMatrix = true;
CJSON(strip.panelH, matrix[F("ph")]);
CJSON(strip.panelW, matrix[F("pw")]);
CJSON(strip.hPanels, matrix[F("mph")]);
CJSON(strip.vPanels, matrix[F("mpv")]);
CJSON(strip.panels, matrix[F("mpc")]);
CJSON(strip.matrix.bottomStart, matrix[F("pb")]);
CJSON(strip.matrix.rightStart, matrix[F("pr")]);
CJSON(strip.matrix.vertical, matrix[F("pv")]);
CJSON(strip.matrix.serpentine, matrix["ps"]);
strip.panel.clear();
JsonArray panels = matrix[F("panels")];
uint8_t s = 0;
if (!panels.isNull()) {
strip.panel.reserve(max(1U,min((size_t)strip.panels,(size_t)WLED_MAX_PANELS))); // pre-allocate memory for panels
for (JsonObject pnl : panels) {
CJSON(strip.panel[s].bottomStart, pnl["b"]);
CJSON(strip.panel[s].rightStart, pnl["r"]);
CJSON(strip.panel[s].vertical, pnl["v"]);
CJSON(strip.panel[s].serpentine, pnl["s"]);
if (++s >= WLED_MAX_PANELS) break; // max panels reached
WS2812FX::Panel p;
CJSON(p.bottomStart, pnl["b"]);
CJSON(p.rightStart, pnl["r"]);
CJSON(p.vertical, pnl["v"]);
CJSON(p.serpentine, pnl["s"]);
CJSON(p.xOffset, pnl["x"]);
CJSON(p.yOffset, pnl["y"]);
CJSON(p.height, pnl["h"]);
CJSON(p.width, pnl["w"]);
strip.panel.push_back(p);
if (++s >= WLED_MAX_PANELS || s >= strip.panels) break; // max panels reached
}
}
// clear remaining panels
for (; s<WLED_MAX_PANELS; s++) {
strip.panel[s].bottomStart = 0;
strip.panel[s].rightStart = 0;
strip.panel[s].vertical = 0;
strip.panel[s].serpentine = 0;
} else {
// fallback
WS2812FX::Panel p;
strip.panels = 1;
p.height = p.width = 8;
p.xOffset = p.yOffset = 0;
p.options = 0;
strip.panel.push_back(p);
}
strip.setUpMatrix();
@@ -703,22 +709,23 @@ void serializeConfig() {
// 2D Matrix Settings
if (strip.isMatrix) {
JsonObject matrix = hw_led.createNestedObject(F("matrix"));
matrix[F("ph")] = strip.panelH;
matrix[F("pw")] = strip.panelW;
matrix[F("mph")] = strip.hPanels;
matrix[F("mpv")] = strip.vPanels;
matrix[F("mpc")] = strip.panels;
matrix[F("pb")] = strip.matrix.bottomStart;
matrix[F("pr")] = strip.matrix.rightStart;
matrix[F("pv")] = strip.matrix.vertical;
matrix["ps"] = strip.matrix.serpentine;
JsonArray panels = matrix.createNestedArray(F("panels"));
for (uint8_t i=0; i<strip.hPanels*strip.vPanels; i++) {
for (uint8_t i=0; i<strip.panel.size(); i++) {
JsonObject pnl = panels.createNestedObject();
pnl["b"] = strip.panel[i].bottomStart;
pnl["r"] = strip.panel[i].rightStart;
pnl["v"] = strip.panel[i].vertical;
pnl["s"] = strip.panel[i].serpentine;
pnl["x"] = strip.panel[i].xOffset;
pnl["y"] = strip.panel[i].yOffset;
pnl["h"] = strip.panel[i].height;
pnl["w"] = strip.panel[i].width;
}
}
#endif

View File

@@ -8,6 +8,7 @@
<script>
var d=document;
var loc = false, locip;
var maxPanels=64;
function H(){window.open("https://mm.kno.wled.ge/features/2D");}
function B(){window.open("/settings","_self");}
function gId(n){return d.getElementById(n);}
@@ -43,34 +44,31 @@
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
}
var maxPanels=64;
function UI(change=false)
function UI(panels=1)
{
gId("mpdiv").style.display = "block";
if (gId("somp").value === "0") {
gId("mpdiv").style.display = "none";
resetPanels();
return;
}
gId("mpdiv").style.display = "block";
maxPanels = parseInt(d.Sf.MPH.value) * parseInt(d.Sf.MPV.value);
let i = gId("panels").children.length;
if (i<maxPanels) for (let j=i; j<maxPanels; j++) addPanel(j);
if (i>maxPanels) for (let j=i; j>maxPanels; j--) remPanel();
//btnPanel(gId("panels").children.length);
if (i<panels) for (let j=i; j<panels; j++) addPanel(j);
if (i>panels) for (let j=i; j>panels; j--) remPanel();
}
function addPanels() {
let h = parseInt(d.Sf.MPH.value);
let v = parseInt(d.Sf.MPV.value);
for (let i=0; i<h*v; i++) addPanel(i);
let c = parseInt(d.Sf.MPC.value);
for (let i=0; i<c; i++) addPanel(i);
}
function addPanel(i=0) {
let p = gId("panels");
if (p.children.length >= maxPanels) return;
let b = `<div id="pnl${i}">${i===0?"":'<hr class="sml">'}Panel ${i}<br>1<sup>st</sup> LED: <select name="P${i}B">
let b = `<div id="pnl${i}"><hr class="sml">Panel ${i}<br>
1<sup>st</sup> LED: <select name="P${i}B">
<option value="0">Top</option>
<option value="1">Bottom</option>
</select><select name="P${i}R">
@@ -81,7 +79,11 @@ Orientation: <select name="P${i}V">
<option value="0">Horizontal</option>
<option value="1">Vertical</option>
</select><br>
Serpentine: <input type="checkbox" name="P${i}S"></div>`;
Serpentine: <input type="checkbox" name="P${i}S"><br>
Dimensions (WxH): <input id="P${i}W" name="P${i}W" type="number" min="1" max="128" value="8"> x <input id="P${i}H" name="P${i}H" type="number" min="1" max="128" value="8"><br>
Offset X:<input id="P${i}X" name="P${i}X" type="number" min="0" max="256" value="0">
Y:<input id="P${i}Y" name="P${i}Y" type="number" min="0" max="256" value="0"><br><i>(offset from top-left corner in # LEDs)</i>
</div>`;
p.insertAdjacentHTML("beforeend", b);
}
@@ -93,15 +95,48 @@ Serpentine: <input type="checkbox" name="P${i}S"></div>`;
}
function resetPanels() {
d.Sf.MPH.value = 1;
d.Sf.MPV.value = 1;
d.Sf.MPC.value = 1;
for (let e of gId("panels").children) e.remove();
for (let e of gId("panels").children) e.remove(); // to remove any leftovers
}
function btnPanel(i) {
gId("pnl_add").style.display = (i<maxPanels) ? "inline":"none";
gId("pnl_rem").style.display = (i>1) ? "inline":"none";
}
function gen() {
resetPanels();
var pansH = parseInt(d.Sf.MPH.value);
var pansV = parseInt(d.Sf.MPV.value);
var c = pansH*pansV;
//maxPanels = c;
d.Sf.MPC.value = c; // number of panels
var ps = d.Sf.PS.checked;
var pv = d.Sf.PV.value==="1";
var pb = d.Sf.PB.value==="1";
var pr = d.Sf.PR.value==="1";
var pw = parseInt(d.Sf.PW.value);
var ph = parseInt(d.Sf.PH.value);
var h = pv ? pansV : pansH;
var v = pv ? pansH : pansV;
for (let j = 0, p = 0; j < v; j++) {
for (let i = 0; i < h; i++, p++) {
if (j*i < maxPanels) addPanel(p);
var y = (pv?pr:pb) ? v-j-1: j;
var x = (pv?pb:pr) ? h-i-1 : i;
x = ps && j%2 ? h-x-1 : x;
gId("P"+p+"X").value = (pv?y:x) * pw;
gId("P"+p+"Y").value = (pv?x:y) * ph
gId("P"+p+"W").value = pw;
gId("P"+p+"H").value = ph;
}
}
}
</script>
<style>@import url("style.css");</style>
</head>
@@ -118,7 +153,8 @@ Serpentine: <input type="checkbox" name="P${i}S"></div>`;
<option value="1">2D Matrix</option>
</select><br>
<div id="mpdiv" style="display:none;">
<h3>Panel set-up</h3>
<hr class="sml">
<h3>Matrix Generator</h3>
Panel dimensions (WxH): <input name="PW" type="number" min="1" max="128" value="8"> x <input name="PH" type="number" min="1" max="128" value="8"><br>
Horizontal panels: <input name="MPH" type="number" min="1" max="8" value="1" oninput="UI()">
Vertical panels: <input name="MPV" type="number" min="1" max="8" value="1" oninput="UI()"><br>
@@ -133,12 +169,15 @@ Serpentine: <input type="checkbox" name="P${i}S"></div>`;
<option value="0">Horizontal</option>
<option value="1">Vertical</option>
</select><br>
Serpentine: <input type="checkbox" name="PS">
<hr class="sml">
<i>A matrix is made of 1 or more physical LED panels of the same dimensions.<br>
Panels should be arranged from top-left to bottom-right order, starting with lower panel number on the left (or top if transposed).<br>
Each panel can have different LED orientation and/or starting point and/or layout.</i><br>
Serpentine: <input type="checkbox" name="PS"><br>
<i style="color:#fa0;">Can populate LED panel layout with pre-arranged matrix.<br>These values do not affect final layout.</i><br>
<button type="button" onclick="gen()">Populate</button>
<hr class="sml">
<h3>Panel set-up</h3>
Number of panels: <input name="MPC" type="number" min="1" max="64" value="1" oninput="UI(parseInt(this.value))"><br>
<i>A matrix is made of 1 or more physical LED panels.<br>
<!--Panels should be arranged from top-left to bottom-right order, starting with lower panel number on the left (or top if transposed).<br>-->
Each panel can be of different size and/or have different LED orientation and/or starting point and/or layout.</i><br>
<h3>LED panel layout</h3>
<div id="panels">
</div>

View File

@@ -1872,118 +1872,137 @@ const uint8_t PAGE_settings_um[] PROGMEM = {
// Autogenerated from wled00/data/settings_2D.htm, do not edit!!
const uint16_t PAGE_settings_2D_length = 1747;
const uint16_t PAGE_settings_2D_length = 2056;
const uint8_t PAGE_settings_2D[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x95, 0x58, 0x5b, 0x6f, 0xdb, 0x36,
0x14, 0x7e, 0xd7, 0xaf, 0x60, 0x88, 0xa2, 0x93, 0x5a, 0x59, 0x8e, 0xbb, 0x0b, 0x8a, 0x58, 0x52,
0xd6, 0x34, 0xd9, 0x92, 0x21, 0x41, 0x83, 0xba, 0x4b, 0x31, 0xac, 0x43, 0x4b, 0x4b, 0xc7, 0x16,
0x1b, 0x89, 0x14, 0x48, 0xca, 0x49, 0xe6, 0xe6, 0xbf, 0xef, 0x90, 0x92, 0xaf, 0x71, 0xda, 0xee,
0x25, 0x36, 0xc9, 0x73, 0x3f, 0xdf, 0xb9, 0x38, 0xf1, 0xde, 0xf1, 0x9b, 0xd7, 0xef, 0xfe, 0xba,
0x3c, 0x21, 0x85, 0xa9, 0xca, 0x34, 0xb6, 0x7f, 0x49, 0xc9, 0xc4, 0x34, 0xa1, 0x20, 0x28, 0x9e,
0x81, 0xe5, 0x69, 0x5c, 0x81, 0x61, 0x24, 0x2b, 0x98, 0xd2, 0x60, 0x12, 0xda, 0x98, 0x49, 0xef,
0x25, 0xed, 0x6e, 0x3d, 0xc1, 0x2a, 0x48, 0xe8, 0x8c, 0xc3, 0x4d, 0x2d, 0x95, 0xa1, 0x24, 0x93,
0xc2, 0x80, 0x40, 0xb2, 0x1b, 0x9e, 0x9b, 0x22, 0xf9, 0x79, 0x7f, 0x7f, 0x49, 0xba, 0xf5, 0x94,
0xc3, 0x8c, 0x67, 0xd0, 0x73, 0x87, 0x90, 0x0b, 0x6e, 0x38, 0x2b, 0x7b, 0x3a, 0x63, 0x25, 0x24,
0x83, 0xb0, 0x62, 0xb7, 0xbc, 0x6a, 0xaa, 0xe5, 0xb9, 0xd1, 0xa0, 0xdc, 0x81, 0x8d, 0xf1, 0x2c,
0x24, 0x7d, 0xa0, 0x39, 0x8d, 0x0d, 0x37, 0x25, 0xa4, 0x2f, 0x8e, 0xc9, 0x08, 0x4c, 0xaf, 0xa9,
0xe3, 0x7e, 0x7b, 0x11, 0xeb, 0x4c, 0xf1, 0xda, 0xa4, 0xde, 0x8c, 0x29, 0x52, 0xca, 0x8c, 0xd7,
0x61, 0x9e, 0xe4, 0x32, 0x6b, 0x2a, 0x34, 0x26, 0xc4, 0x8b, 0x64, 0x6f, 0x30, 0x9c, 0x34, 0x22,
0x33, 0x5c, 0x0a, 0x72, 0xea, 0x07, 0xf3, 0x1b, 0x2e, 0x72, 0x79, 0x13, 0xc9, 0x1a, 0x84, 0x4f,
0x0b, 0x63, 0x6a, 0x7d, 0xd0, 0xef, 0x57, 0x55, 0x74, 0x2d, 0x64, 0x74, 0x53, 0x42, 0x1e, 0x4d,
0xa1, 0x3f, 0x01, 0x66, 0x1a, 0x05, 0xba, 0xff, 0xe2, 0x98, 0x06, 0xf7, 0x4b, 0xf6, 0xa3, 0x6d,
0xf6, 0x3e, 0xc6, 0xcc, 0x70, 0x31, 0xd5, 0x34, 0xa4, 0x1f, 0x35, 0x94, 0x93, 0x75, 0xea, 0xe9,
0x59, 0xee, 0x43, 0x30, 0x57, 0x80, 0xa2, 0x04, 0xb1, 0x72, 0xcd, 0x49, 0x09, 0xd6, 0xae, 0xa3,
0x3b, 0xf7, 0xb4, 0x22, 0x2d, 0x25, 0xcb, 0xff, 0x18, 0xf9, 0x10, 0x8a, 0x64, 0x6f, 0x3f, 0x98,
0x97, 0x60, 0x88, 0x49, 0xf2, 0x28, 0x53, 0x68, 0x07, 0x74, 0x4c, 0x3e, 0x6d, 0x5d, 0xa5, 0xc1,
0xd0, 0x44, 0xa8, 0xf7, 0x95, 0x31, 0x8a, 0x8f, 0x1b, 0x03, 0xf8, 0xa0, 0x32, 0x1a, 0x42, 0x10,
0x6e, 0xdf, 0x9b, 0xbb, 0x1a, 0xd0, 0x32, 0x03, 0xb7, 0xa6, 0xff, 0x99, 0xcd, 0xd8, 0x42, 0xc0,
0x03, 0x42, 0xa6, 0xef, 0x04, 0x8a, 0x10, 0x41, 0x98, 0x47, 0x63, 0x99, 0xdf, 0x45, 0xac, 0x46,
0xff, 0xf2, 0xd7, 0x05, 0x2f, 0x73, 0xdf, 0x58, 0x7a, 0x96, 0xe7, 0x27, 0x33, 0xb4, 0xe2, 0x9c,
0x6b, 0x4c, 0x33, 0x28, 0x9f, 0x5a, 0x9b, 0x69, 0xe8, 0x07, 0x49, 0x3a, 0xff, 0x1d, 0xcc, 0x95,
0x1f, 0x84, 0x7f, 0x9e, 0xf9, 0xc1, 0xfd, 0x6e, 0x62, 0x50, 0x4a, 0x2a, 0xb4, 0x11, 0x89, 0x11,
0x28, 0x5a, 0x96, 0x10, 0x95, 0x72, 0xea, 0xd3, 0x13, 0x7b, 0x4f, 0xba, 0x08, 0x60, 0x20, 0xc9,
0x84, 0x97, 0xe0, 0x7c, 0x41, 0x64, 0x28, 0xf4, 0xf9, 0xbc, 0xbb, 0x97, 0x13, 0x0b, 0xbe, 0x09,
0x9f, 0x36, 0x8a, 0xb9, 0x90, 0xb5, 0xbe, 0x90, 0x09, 0xe3, 0x36, 0x67, 0x1f, 0xc4, 0x99, 0xc8,
0x64, 0x55, 0x63, 0xe4, 0x80, 0xd4, 0x6c, 0x0a, 0x24, 0x67, 0x86, 0xed, 0x61, 0x3a, 0xd6, 0xa2,
0x3c, 0xc2, 0xf4, 0x51, 0xab, 0xe0, 0x80, 0x26, 0x49, 0x97, 0x47, 0x44, 0x88, 0x93, 0x17, 0xd5,
0x4a, 0x1a, 0x99, 0xc9, 0xf2, 0xe9, 0x53, 0xdf, 0xa1, 0x66, 0x3f, 0xf4, 0x1d, 0x9c, 0x12, 0x4b,
0x51, 0x8e, 0x8c, 0x54, 0x28, 0xd5, 0xe6, 0xf0, 0xcc, 0x40, 0x65, 0xbd, 0xcf, 0xce, 0x6a, 0x1a,
0x04, 0x5f, 0xbe, 0x74, 0x64, 0xc8, 0x5f, 0xd5, 0x68, 0xf0, 0x6f, 0x28, 0x9f, 0x5c, 0xc8, 0x1c,
0x22, 0x72, 0x59, 0x02, 0xd3, 0x40, 0x30, 0x10, 0xa0, 0xc8, 0xfb, 0xf3, 0x93, 0x63, 0x72, 0x76,
0x89, 0x26, 0x85, 0x1b, 0x12, 0xf5, 0xa6, 0xc4, 0xd0, 0x49, 0x0b, 0x02, 0x4b, 0xe5, 0x30, 0x61,
0xc5, 0x1f, 0x3a, 0x9c, 0x22, 0x4c, 0xe9, 0x73, 0xf7, 0x7c, 0x40, 0x69, 0xf0, 0x7c, 0x05, 0xbe,
0xbe, 0x8e, 0x3e, 0xeb, 0xc3, 0x3a, 0x19, 0xec, 0xd3, 0x70, 0x6f, 0x10, 0xdc, 0xdb, 0x52, 0xc0,
0x12, 0xbb, 0x64, 0x02, 0x4a, 0x9d, 0xfc, 0xf2, 0xd3, 0x0a, 0xff, 0x98, 0x21, 0xc0, 0x82, 0x08,
0xe6, 0x7c, 0xe2, 0xd3, 0x7d, 0x8c, 0x42, 0x62, 0x41, 0x4a, 0x35, 0x9a, 0x4e, 0x83, 0x68, 0xc6,
0xca, 0x06, 0x82, 0x0e, 0xaf, 0xee, 0xa1, 0xaa, 0x73, 0x3e, 0xc3, 0x17, 0x6d, 0xee, 0x30, 0x63,
0x39, 0xd7, 0x75, 0xc9, 0xee, 0x12, 0x2a, 0xa4, 0xc0, 0x24, 0xcd, 0x24, 0xcf, 0x09, 0x16, 0x09,
0x98, 0x56, 0x93, 0x1f, 0x0c, 0xbf, 0xc6, 0x34, 0x46, 0xd3, 0xaf, 0x69, 0xb8, 0x32, 0xac, 0xb6,
0x2d, 0xe7, 0x0c, 0x81, 0x9d, 0x47, 0xa3, 0x49, 0x74, 0x71, 0x79, 0xda, 0x19, 0xf0, 0x6c, 0xfb,
0xe1, 0xaa, 0x7b, 0x18, 0xda, 0xba, 0x10, 0xad, 0xc9, 0xb5, 0x93, 0x81, 0x5a, 0x32, 0x8b, 0x51,
0x05, 0x22, 0x2a, 0x41, 0x4c, 0x4d, 0x31, 0x44, 0xcf, 0x44, 0xbc, 0x54, 0x12, 0x4c, 0xa4, 0xf2,
0x2d, 0x1b, 0xb6, 0x95, 0x21, 0xac, 0xee, 0x87, 0xf0, 0xfc, 0x79, 0x80, 0x30, 0x75, 0x27, 0x2c,
0x45, 0xc7, 0x96, 0x3e, 0xc2, 0x96, 0xae, 0xb1, 0xf5, 0x7a, 0x18, 0xa0, 0xaa, 0x65, 0x5b, 0x83,
0xd6, 0x42, 0x14, 0x06, 0x61, 0xde, 0xf2, 0x3d, 0xe6, 0x1d, 0x96, 0xf8, 0xa3, 0xfe, 0x2d, 0xb4,
0x9a, 0x64, 0x7f, 0x68, 0x62, 0x78, 0x26, 0x86, 0x66, 0xdd, 0x4c, 0xb3, 0x43, 0x21, 0xe6, 0xb3,
0x6b, 0x18, 0x5b, 0x81, 0x71, 0x1e, 0x6d, 0x47, 0x27, 0x4d, 0x56, 0x2e, 0xb6, 0x79, 0x1e, 0xb6,
0xfa, 0x3e, 0xc5, 0x98, 0x33, 0xc2, 0xf3, 0x84, 0xd6, 0xa2, 0x7c, 0x32, 0x87, 0x7b, 0x9a, 0x3e,
0x99, 0xef, 0x23, 0x3e, 0xe0, 0x90, 0xd2, 0x83, 0x1f, 0xe2, 0x42, 0x91, 0xac, 0x64, 0x5a, 0x27,
0x54, 0x57, 0x25, 0x4d, 0x7f, 0xb8, 0x77, 0x42, 0x88, 0xa5, 0x8c, 0xc7, 0x2a, 0x1d, 0xc4, 0xba,
0xa9, 0x53, 0x6d, 0xe2, 0xbe, 0xfd, 0x24, 0x08, 0xf5, 0x03, 0x12, 0x63, 0x3f, 0x84, 0x0c, 0xed,
0x72, 0x9d, 0xfc, 0xd2, 0x92, 0x1e, 0xd1, 0xf4, 0x83, 0xf8, 0x60, 0x62, 0x59, 0x3b, 0x1f, 0x9c,
0xd7, 0x09, 0xe2, 0x30, 0x7d, 0x27, 0xb1, 0xa1, 0xb7, 0xb7, 0xbb, 0x28, 0x06, 0x34, 0x3d, 0x92,
0xc6, 0xc8, 0x6a, 0x8d, 0x08, 0x55, 0x39, 0xf9, 0xe9, 0x0e, 0x3d, 0x6f, 0x1f, 0xd3, 0x73, 0x0e,
0x13, 0xf3, 0x0d, 0x45, 0x6f, 0xf9, 0xb4, 0x30, 0x3b, 0xf5, 0xa0, 0x9f, 0x1f, 0xc4, 0x1b, 0xc5,
0xb1, 0x9e, 0x5d, 0xcb, 0xd8, 0xe9, 0xe2, 0xd5, 0x63, 0xaa, 0x4f, 0xa5, 0xe2, 0xff, 0xe2, 0x8c,
0x64, 0xe5, 0x37, 0x0c, 0xb8, 0xc2, 0xbe, 0xc7, 0xb3, 0x0d, 0xb2, 0x2d, 0x1b, 0x46, 0xa0, 0xb0,
0x3b, 0x63, 0xe9, 0x03, 0x9a, 0xc0, 0x45, 0xdd, 0x60, 0x06, 0xb1, 0xd3, 0x27, 0x34, 0x2b, 0x20,
0xbb, 0x1e, 0xcb, 0x5b, 0xba, 0x6e, 0xd1, 0x08, 0x87, 0x67, 0x1f, 0xb3, 0x9b, 0x7e, 0x1a, 0x8a,
0x88, 0x0b, 0x1c, 0xb5, 0xe6, 0x55, 0xfe, 0x99, 0x65, 0x28, 0xe1, 0xf4, 0xdd, 0xc5, 0xb9, 0x4f,
0xc7, 0x80, 0xb8, 0x03, 0x6c, 0xf7, 0x34, 0x5c, 0x47, 0xd8, 0x0a, 0xe6, 0x1d, 0xa2, 0x77, 0xd7,
0xdd, 0xd0, 0x76, 0x1b, 0x91, 0xc0, 0xa2, 0xfe, 0x44, 0x9c, 0x0c, 0xbe, 0x7c, 0x81, 0xbf, 0x45,
0x6f, 0xf0, 0x4f, 0x84, 0x32, 0xe4, 0x0c, 0xfc, 0x0d, 0xa9, 0x6b, 0xfd, 0x62, 0xbe, 0x59, 0x1b,
0xb8, 0x09, 0x6c, 0x56, 0x44, 0x32, 0x58, 0x96, 0x04, 0xd8, 0x09, 0xb0, 0xdb, 0x82, 0x00, 0x76,
0xe8, 0x19, 0x1b, 0xb1, 0xa8, 0xed, 0x79, 0xcb, 0x26, 0xca, 0x8f, 0x58, 0x34, 0x0f, 0xfa, 0xd2,
0x5a, 0x53, 0x38, 0xa4, 0x5c, 0x94, 0x18, 0x55, 0x7a, 0xd0, 0x75, 0xb8, 0x25, 0x23, 0xca, 0x7f,
0xc8, 0x98, 0x0e, 0xb6, 0x19, 0xee, 0x3d, 0xcc, 0x54, 0xbb, 0x8f, 0xc4, 0x8e, 0x38, 0xfd, 0x95,
0x57, 0x76, 0x7f, 0x21, 0x8d, 0x2a, 0xb1, 0xcd, 0x3a, 0xfe, 0x4c, 0xdb, 0xea, 0x44, 0x42, 0x47,
0x10, 0xf7, 0xdb, 0x2d, 0xcc, 0x4e, 0x5d, 0x9c, 0x83, 0xb6, 0xe9, 0x27, 0x14, 0x07, 0x15, 0x26,
0x0d, 0x5d, 0xaf, 0x3c, 0x57, 0x93, 0xf6, 0xdb, 0x47, 0xbd, 0xc8, 0xea, 0x68, 0x42, 0x09, 0xee,
0x5c, 0x85, 0xb4, 0xd5, 0x2a, 0xb5, 0x5d, 0x8e, 0x6c, 0xf1, 0x76, 0xf5, 0x69, 0x24, 0x4e, 0xa2,
0x9b, 0xcd, 0xbb, 0x02, 0xca, 0x1a, 0x6b, 0xcf, 0x8b, 0x71, 0xda, 0x1b, 0x0c, 0x4e, 0x8b, 0x96,
0xf6, 0x40, 0x51, 0x6b, 0x56, 0xf2, 0xec, 0x3a, 0xa1, 0xa7, 0x56, 0xed, 0x61, 0xdc, 0x6f, 0x1f,
0x3a, 0xd4, 0xec, 0xe6, 0xf1, 0x96, 0x4c, 0x47, 0x96, 0xe9, 0x88, 0x65, 0xd7, 0x2b, 0xbe, 0x0d,
0x0e, 0xdd, 0x8c, 0x2b, 0x8e, 0x36, 0x8e, 0xd8, 0x0c, 0x56, 0x24, 0x85, 0x5a, 0x88, 0x2f, 0x5e,
0xa4, 0x1e, 0x6e, 0x75, 0x88, 0x0a, 0xbb, 0xd4, 0xe1, 0x69, 0x84, 0x5b, 0x49, 0x4d, 0x70, 0x2b,
0x70, 0x89, 0x5e, 0x15, 0x99, 0x0d, 0x84, 0x1b, 0x54, 0x8b, 0x30, 0xbc, 0xb9, 0xb8, 0x6c, 0x0d,
0x29, 0x70, 0xa5, 0xc5, 0x8b, 0x0d, 0x68, 0x85, 0x6b, 0x1d, 0xd9, 0x2d, 0x26, 0x18, 0x91, 0x07,
0x35, 0x39, 0xc0, 0x6d, 0xd2, 0x6a, 0x5b, 0x96, 0x9a, 0xf7, 0xb0, 0x1c, 0xd1, 0xb6, 0x0b, 0x86,
0x44, 0xb7, 0x4b, 0xa2, 0x8d, 0x6a, 0x5c, 0xf6, 0xcd, 0x76, 0xea, 0x11, 0xcf, 0xa5, 0x35, 0xa1,
0x1d, 0x4a, 0x0e, 0x1c, 0x2e, 0xd0, 0xcb, 0x1f, 0xd3, 0xb6, 0x63, 0xea, 0x6e, 0x7b, 0x5d, 0x5e,
0xe4, 0x1c, 0x97, 0x3b, 0x8d, 0x72, 0x35, 0xf1, 0xdf, 0xdf, 0x9e, 0x06, 0xcb, 0x92, 0xee, 0x56,
0xe0, 0xcb, 0xf7, 0xb4, 0x8b, 0xa4, 0x68, 0xaa, 0x31, 0x28, 0xcc, 0x3d, 0x17, 0xd6, 0x32, 0x3b,
0xe2, 0xf1, 0xf3, 0xc5, 0x4b, 0xba, 0xb0, 0x16, 0xf7, 0x76, 0x72, 0xbb, 0x60, 0xef, 0xb8, 0x4f,
0xd1, 0xa4, 0xef, 0x67, 0xb7, 0x1e, 0xad, 0x1a, 0x55, 0x9b, 0x01, 0xbd, 0x6d, 0xd1, 0x85, 0x15,
0xfa, 0x15, 0x99, 0x2b, 0x89, 0x03, 0x0b, 0x2e, 0xc7, 0x9b, 0xd0, 0x36, 0x07, 0x1e, 0x59, 0xb4,
0xb7, 0x6d, 0xe1, 0x0b, 0xd9, 0x57, 0xdf, 0x2f, 0xdb, 0xdb, 0x12, 0xbe, 0x63, 0x12, 0x6d, 0x61,
0xa8, 0x0b, 0xca, 0xd1, 0x2e, 0x30, 0xe0, 0x0c, 0xf2, 0x56, 0x39, 0xfe, 0xd6, 0x00, 0x7a, 0x6c,
0xfc, 0xbc, 0x5d, 0x89, 0xf6, 0x1e, 0x99, 0x3b, 0xdf, 0x9a, 0x39, 0x1b, 0xf8, 0xf2, 0xbe, 0x36,
0x70, 0xae, 0x76, 0xf9, 0xb1, 0x63, 0xd0, 0x6c, 0x5b, 0xb4, 0x6b, 0xca, 0x6c, 0x68, 0xfd, 0x8e,
0x09, 0xb3, 0x80, 0xa7, 0x1d, 0x2f, 0x5b, 0xdb, 0x41, 0xcc, 0x53, 0xef, 0x15, 0xe6, 0xcb, 0x56,
0x0d, 0xe1, 0x1a, 0xbf, 0xe5, 0xae, 0x7d, 0x0f, 0x6c, 0x55, 0x57, 0x38, 0x6b, 0x48, 0x5d, 0xdc,
0x69, 0x07, 0x02, 0xbb, 0x14, 0xb7, 0x40, 0xb0, 0x04, 0xa6, 0x00, 0xa2, 0x51, 0xec, 0x5a, 0x51,
0x44, 0x2e, 0x08, 0x6d, 0x25, 0x13, 0x5d, 0xc8, 0xa6, 0xcc, 0xc9, 0x18, 0x08, 0x53, 0xca, 0x16,
0x7d, 0x4e, 0x26, 0xb8, 0x76, 0x13, 0xec, 0x79, 0xbd, 0x12, 0x43, 0x8c, 0x5f, 0xc8, 0xd8, 0xe5,
0xa9, 0xa7, 0x6c, 0x48, 0x51, 0x5f, 0x0e, 0x2a, 0x24, 0xda, 0x30, 0x65, 0x37, 0x65, 0x72, 0xc3,
0x4d, 0x81, 0x3f, 0x35, 0x6e, 0xa0, 0xeb, 0x2e, 0xa4, 0x05, 0x99, 0xfd, 0x01, 0x62, 0x75, 0x3b,
0x19, 0x3e, 0x1a, 0x89, 0x02, 0x09, 0x47, 0x7b, 0x50, 0x89, 0xc6, 0x16, 0x0b, 0x79, 0x10, 0x79,
0xce, 0x90, 0x13, 0x96, 0x15, 0x1d, 0x6b, 0xc6, 0x04, 0x29, 0xb0, 0xa9, 0xa1, 0xb1, 0x93, 0x09,
0xe0, 0x1c, 0x32, 0xce, 0x1b, 0xb9, 0xca, 0x17, 0x61, 0x22, 0xef, 0xa3, 0xb4, 0xa5, 0xfa, 0x5a,
0x72, 0xa4, 0xea, 0x6e, 0xb1, 0x3b, 0xc8, 0xc6, 0xa0, 0xdc, 0x3e, 0x6f, 0x3b, 0xc9, 0x76, 0x14,
0xb1, 0x45, 0x2c, 0xc3, 0xd3, 0x51, 0xbb, 0xbe, 0xb1, 0x5a, 0xd5, 0xda, 0x49, 0xb8, 0xe8, 0xa4,
0xee, 0xaf, 0xe7, 0x5a, 0xeb, 0xd7, 0xfb, 0xfc, 0xff, 0x69, 0xd9, 0xde, 0xda, 0x38, 0xb0, 0x63,
0x08, 0x3f, 0xec, 0xa8, 0xb2, 0x73, 0xcb, 0xfe, 0x4f, 0xe1, 0x3f, 0xea, 0x4c, 0xe6, 0x1a, 0x63,
0x10, 0x00, 0x00
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x9d, 0x58, 0x6b, 0x73, 0xdb, 0xb8,
0x15, 0xfd, 0xae, 0x5f, 0x01, 0x63, 0xdb, 0x0c, 0x19, 0x53, 0x94, 0xe4, 0xdd, 0xcd, 0xec, 0x48,
0x24, 0xdd, 0xf8, 0xd1, 0xb5, 0x3b, 0x76, 0xa3, 0x89, 0x52, 0x3b, 0x9e, 0xa6, 0x93, 0x85, 0xc8,
0x4b, 0x13, 0x31, 0x09, 0x70, 0x08, 0xc8, 0x8f, 0x75, 0xfc, 0xdf, 0x7b, 0x01, 0x52, 0xd4, 0xd3,
0x76, 0xd3, 0x2f, 0xb6, 0x09, 0xdc, 0x7b, 0x70, 0x71, 0x9f, 0x07, 0x0e, 0x76, 0x8e, 0x3e, 0x1c,
0x7e, 0xba, 0x1a, 0x1f, 0x93, 0x4c, 0x17, 0x79, 0x14, 0x98, 0x9f, 0x24, 0x67, 0xe2, 0x3a, 0xa4,
0x20, 0x28, 0x7e, 0x03, 0x4b, 0xa2, 0xa0, 0x00, 0xcd, 0x48, 0x9c, 0xb1, 0x4a, 0x81, 0x0e, 0xe9,
0x4c, 0xa7, 0xdd, 0xdf, 0x68, 0xb3, 0xda, 0x11, 0xac, 0x80, 0x90, 0xde, 0x72, 0xb8, 0x2b, 0x65,
0xa5, 0x29, 0x89, 0xa5, 0xd0, 0x20, 0x50, 0xec, 0x8e, 0x27, 0x3a, 0x0b, 0x7f, 0xed, 0xf7, 0x5b,
0xd1, 0xb5, 0xad, 0x04, 0x6e, 0x79, 0x0c, 0x5d, 0xfb, 0xe1, 0x71, 0xc1, 0x35, 0x67, 0x79, 0x57,
0xc5, 0x2c, 0x87, 0x70, 0xe0, 0x15, 0xec, 0x9e, 0x17, 0xb3, 0xa2, 0xfd, 0x9e, 0x29, 0xa8, 0xec,
0x07, 0x9b, 0xe2, 0xb7, 0x90, 0x74, 0xe3, 0xe4, 0x28, 0xd0, 0x5c, 0xe7, 0x10, 0xed, 0x1d, 0x91,
0x09, 0xe8, 0xee, 0xac, 0x0c, 0x7a, 0xf5, 0x42, 0xa0, 0xe2, 0x8a, 0x97, 0x3a, 0xea, 0xdc, 0xb2,
0x8a, 0xe4, 0x32, 0xe6, 0xa5, 0x97, 0x84, 0x89, 0x8c, 0x67, 0x05, 0x1a, 0xe3, 0xe1, 0x42, 0xb8,
0x63, 0xcf, 0x1b, 0x33, 0x01, 0xb9, 0x0a, 0xdf, 0xfd, 0x32, 0x4a, 0x67, 0x22, 0xd6, 0x5c, 0x0a,
0x72, 0xe2, 0xb8, 0x8f, 0x77, 0x5c, 0x24, 0xf2, 0xce, 0x97, 0x25, 0x08, 0x87, 0x66, 0x5a, 0x97,
0x6a, 0xd8, 0xeb, 0x15, 0x85, 0x7f, 0x23, 0xa4, 0x7f, 0x97, 0x43, 0xe2, 0x5f, 0x43, 0x2f, 0x05,
0xa6, 0x67, 0x15, 0xa8, 0xde, 0xde, 0x11, 0x75, 0x9f, 0x5a, 0xf5, 0x83, 0x75, 0xf5, 0x1e, 0x3a,
0x50, 0x73, 0x71, 0xad, 0xa8, 0x47, 0xbf, 0x2a, 0xc8, 0xd3, 0x65, 0xe9, 0xeb, 0xd3, 0xc4, 0x01,
0xf7, 0xb1, 0x02, 0x84, 0x12, 0xc4, 0xe0, 0xea, 0xe3, 0x1c, 0x8c, 0x91, 0x07, 0x0f, 0x76, 0x6b,
0x21, 0x9a, 0x4b, 0x96, 0xfc, 0x63, 0xe2, 0x80, 0x27, 0xc2, 0x9d, 0xbe, 0xfb, 0x98, 0x83, 0x26,
0x3a, 0x4c, 0xfc, 0xb8, 0x42, 0x3b, 0xa0, 0x51, 0x72, 0x68, 0x7d, 0x6f, 0xea, 0x8e, 0xb4, 0x8f,
0xe7, 0xbe, 0xd7, 0xba, 0xe2, 0xd3, 0x99, 0x06, 0xdc, 0xa8, 0x62, 0xea, 0x81, 0xeb, 0xad, 0xaf,
0xeb, 0x87, 0x12, 0xd0, 0x32, 0x0d, 0xf7, 0xba, 0xf7, 0x8d, 0xdd, 0xb2, 0x39, 0xc0, 0x86, 0x20,
0x53, 0x0f, 0x02, 0x21, 0x84, 0xeb, 0x25, 0xfe, 0x54, 0x26, 0x0f, 0x3e, 0x2b, 0xf1, 0x7e, 0xc9,
0x61, 0xc6, 0xf3, 0xc4, 0xd1, 0x46, 0x9e, 0x25, 0xc9, 0xf1, 0x2d, 0x5a, 0x71, 0xc6, 0x15, 0xc6,
0x1c, 0x2a, 0x87, 0x1a, 0x9b, 0xa9, 0xe7, 0xb8, 0x61, 0xf4, 0xf8, 0x3b, 0xe8, 0x0b, 0xc7, 0xf5,
0xfe, 0x75, 0xea, 0xb8, 0x4f, 0xdb, 0x85, 0xa1, 0xaa, 0x64, 0x85, 0x36, 0xa2, 0x30, 0x66, 0x8d,
0x92, 0x39, 0xf8, 0xb9, 0xbc, 0x76, 0xe8, 0xb1, 0x59, 0x27, 0x8d, 0x07, 0xd0, 0x91, 0x24, 0xe5,
0x39, 0xd8, 0xbb, 0x60, 0x9a, 0x54, 0x78, 0xe7, 0xb3, 0x66, 0x5d, 0xa6, 0x26, 0x13, 0x53, 0x7e,
0x3d, 0xab, 0x98, 0x75, 0x59, 0x7d, 0x17, 0x92, 0x32, 0x6e, 0x62, 0xf6, 0x45, 0x9c, 0x8a, 0x58,
0x16, 0x25, 0x7a, 0x0e, 0x48, 0xc9, 0xae, 0x81, 0x24, 0x4c, 0xb3, 0x1d, 0x0c, 0xc7, 0x92, 0x97,
0x27, 0x18, 0x3e, 0x6a, 0x0e, 0x18, 0xd2, 0x30, 0x6c, 0xe2, 0x88, 0xe9, 0x62, 0xf1, 0xfc, 0xb2,
0x92, 0x5a, 0xc6, 0x32, 0x7f, 0xf3, 0xc6, 0xb1, 0x29, 0xd4, 0xf7, 0x1c, 0x9b, 0x5b, 0xa1, 0x91,
0xc8, 0x27, 0x5a, 0x56, 0x88, 0x6a, 0x62, 0x78, 0xaa, 0xa1, 0x30, 0xb7, 0x8f, 0x4f, 0x4b, 0xea,
0xba, 0xdf, 0xbf, 0x37, 0x62, 0xa8, 0x5f, 0x94, 0x68, 0xf0, 0xdf, 0x11, 0x9f, 0x9c, 0xcb, 0x04,
0x7c, 0x32, 0xce, 0x81, 0x29, 0x20, 0xe8, 0x08, 0xa8, 0xc8, 0xe5, 0xd9, 0xf1, 0x11, 0x39, 0x1d,
0xa3, 0x49, 0xde, 0x0a, 0xa2, 0x5a, 0x45, 0xf4, 0x2c, 0x9a, 0xeb, 0x1a, 0x29, 0x9b, 0x13, 0x06,
0x7e, 0xdf, 0xe6, 0x29, 0xa6, 0x29, 0xdd, 0xb5, 0xdb, 0x43, 0x4a, 0xdd, 0xdd, 0x45, 0xf2, 0xf5,
0x94, 0xff, 0x4d, 0xed, 0x97, 0xe1, 0xa0, 0x4f, 0xbd, 0x9d, 0xc1, 0xd2, 0x85, 0x31, 0x20, 0x58,
0x6b, 0xee, 0x23, 0x4f, 0x1d, 0x93, 0x8c, 0xb4, 0x28, 0x13, 0x7e, 0x4b, 0x5d, 0x5f, 0xe9, 0x07,
0x0c, 0x40, 0xc2, 0x55, 0x99, 0xb3, 0x87, 0x90, 0x4e, 0x11, 0xf4, 0x06, 0xf3, 0xa4, 0x8f, 0x6e,
0x09, 0xad, 0xa0, 0xc2, 0xbb, 0xa0, 0xdc, 0x2d, 0xcb, 0x67, 0xe0, 0x36, 0x09, 0xfc, 0x12, 0x82,
0x90, 0x02, 0xa3, 0x76, 0x2b, 0x79, 0x42, 0xb0, 0x6a, 0x40, 0xd7, 0xa5, 0xe7, 0xb8, 0x23, 0x93,
0xc9, 0xa2, 0xc6, 0x2c, 0xed, 0x1a, 0xea, 0xc6, 0x26, 0xab, 0x2a, 0x10, 0x7e, 0x0e, 0xe2, 0x5a,
0x67, 0x23, 0xb4, 0x4e, 0x04, 0xe0, 0xa6, 0xb2, 0x72, 0xea, 0xc4, 0x17, 0x23, 0x1d, 0xc0, 0x48,
0xef, 0xee, 0xba, 0x98, 0x48, 0x16, 0x0a, 0x73, 0xd0, 0x8a, 0x45, 0x6b, 0x62, 0x11, 0x8a, 0x75,
0xbb, 0x68, 0x61, 0x51, 0x8b, 0x2d, 0xdd, 0x7d, 0xae, 0x8a, 0x56, 0xd8, 0x7a, 0x82, 0xb0, 0x34,
0xfd, 0xee, 0x14, 0x0b, 0x29, 0xf1, 0x27, 0xa9, 0x7f, 0x3e, 0x3e, 0x6c, 0xee, 0x37, 0x9a, 0x43,
0x8a, 0xb0, 0x3f, 0x42, 0x4b, 0x46, 0x62, 0xf9, 0x64, 0xb1, 0x05, 0x13, 0xbd, 0xda, 0x54, 0xe9,
0xda, 0xdd, 0xac, 0x91, 0xeb, 0x17, 0x8c, 0xc2, 0xb6, 0x19, 0x35, 0xbe, 0x1c, 0xd5, 0x17, 0xf8,
0x23, 0x40, 0x67, 0x12, 0x9e, 0x84, 0xb4, 0x14, 0xf9, 0x5f, 0x1e, 0xe1, 0xc9, 0x34, 0xe8, 0x8a,
0xc4, 0x39, 0x53, 0x2a, 0xa4, 0xaa, 0xc8, 0x69, 0x64, 0xd5, 0x88, 0xd9, 0x0b, 0xa6, 0x55, 0xf4,
0x45, 0x0c, 0x02, 0x35, 0x2b, 0x23, 0xa5, 0x83, 0x9e, 0xf9, 0x4d, 0x30, 0xa7, 0x86, 0x24, 0xc0,
0xc6, 0x03, 0x31, 0xda, 0x62, 0xfb, 0xe7, 0xd8, 0x08, 0x1f, 0x50, 0x94, 0xfd, 0xa2, 0x03, 0x59,
0x5a, 0xbb, 0xed, 0x3d, 0x43, 0x8c, 0x6f, 0xf4, 0x49, 0x62, 0x1b, 0xad, 0x57, 0xb7, 0x49, 0x0c,
0x68, 0x74, 0x20, 0xb5, 0x96, 0xc5, 0x92, 0x10, 0x1e, 0x65, 0xf1, 0xa3, 0x2d, 0xe7, 0x7c, 0x7c,
0xee, 0x9c, 0x33, 0x48, 0xf5, 0x2b, 0x07, 0x7d, 0xe4, 0xd7, 0x99, 0xde, 0x7a, 0x8e, 0xbd, 0xe9,
0x87, 0x8a, 0x63, 0xe1, 0xd8, 0xda, 0xdc, 0x7a, 0xc5, 0x8b, 0xe7, 0x8e, 0x3e, 0x91, 0x15, 0xff,
0x13, 0x27, 0x13, 0xcb, 0x5f, 0x31, 0xe0, 0x02, 0x1b, 0x0c, 0x8f, 0x57, 0xc4, 0xd6, 0x6c, 0x98,
0x40, 0x85, 0x6d, 0x10, 0x6b, 0x0c, 0xd0, 0x04, 0x2e, 0xca, 0x19, 0x46, 0x0d, 0x5b, 0x6a, 0x48,
0xe3, 0x0c, 0xe2, 0x9b, 0xa9, 0xbc, 0xa7, 0xcb, 0x16, 0x4d, 0x68, 0xa3, 0x76, 0xc4, 0xb1, 0x5f,
0x2b, 0x44, 0x54, 0xc4, 0xb9, 0xbc, 0x3f, 0x71, 0x5b, 0x65, 0x13, 0x6a, 0x2b, 0x7a, 0xb9, 0xa2,
0x88, 0x5f, 0x35, 0xac, 0x98, 0x15, 0x53, 0xa8, 0x28, 0x29, 0xb8, 0x30, 0x16, 0x12, 0xcc, 0x1b,
0xfc, 0xbd, 0xf7, 0x1b, 0x9d, 0x5b, 0x8d, 0x63, 0x9a, 0xdc, 0x6f, 0xa0, 0x9d, 0xac, 0xa0, 0x9d,
0xfc, 0x08, 0x5a, 0xe3, 0xeb, 0x34, 0xc5, 0xa2, 0x25, 0x9f, 0x87, 0xeb, 0xc8, 0x9f, 0x57, 0x90,
0x3f, 0x6f, 0x45, 0xee, 0x37, 0xc8, 0x7b, 0xbf, 0xbe, 0xa3, 0x4b, 0x61, 0xf8, 0x22, 0xae, 0x36,
0xe0, 0xae, 0x56, 0xe0, 0xae, 0x7e, 0x04, 0xce, 0x18, 0x1a, 0xf0, 0xc8, 0x91, 0xb5, 0xa9, 0x29,
0x76, 0x5b, 0xa2, 0x65, 0xd9, 0xcd, 0x31, 0xd1, 0x70, 0x32, 0x54, 0x38, 0x65, 0x08, 0x17, 0xe4,
0x27, 0x53, 0x12, 0xca, 0x0d, 0x7a, 0xdc, 0x46, 0x13, 0xeb, 0x2b, 0xfa, 0x63, 0x24, 0x7c, 0x2e,
0x90, 0x6e, 0xe8, 0xf7, 0xc9, 0x37, 0x16, 0x63, 0x3c, 0x4f, 0x3e, 0x9d, 0x9f, 0x39, 0x74, 0x0a,
0x58, 0xf7, 0x80, 0x53, 0x8e, 0x7a, 0x7a, 0xa9, 0xc6, 0x17, 0xbd, 0xa4, 0x69, 0x1b, 0xdb, 0x9b,
0xd7, 0xc8, 0x90, 0x0f, 0x11, 0xc2, 0xbc, 0x89, 0x89, 0x20, 0x1c, 0x7c, 0xff, 0x0e, 0xff, 0x16,
0xdd, 0xc1, 0x7f, 0x7c, 0xc4, 0x90, 0xb7, 0xe0, 0xac, 0xa0, 0x2e, 0x75, 0xc5, 0xc7, 0xd5, 0x06,
0x14, 0x0e, 0xda, 0x0e, 0x04, 0x66, 0xce, 0x6d, 0x3f, 0xd0, 0x85, 0x16, 0xf6, 0x07, 0xc5, 0x17,
0x56, 0x4c, 0xb5, 0x68, 0xfa, 0x97, 0xfb, 0x58, 0xab, 0x89, 0xfc, 0x2b, 0x36, 0xb5, 0x8d, 0x86,
0x0e, 0x41, 0xdb, 0xb2, 0xf6, 0x29, 0x17, 0x39, 0x56, 0x00, 0x1d, 0x36, 0x5d, 0xbe, 0x55, 0x44,
0xfc, 0x4d, 0xc5, 0x68, 0xb0, 0xae, 0xb0, 0x44, 0x88, 0x90, 0x32, 0x19, 0x3e, 0xb4, 0x3c, 0x20,
0x8c, 0x1b, 0x37, 0x5b, 0xf3, 0x49, 0xd3, 0x9a, 0x91, 0x0f, 0xad, 0x6f, 0x5d, 0xcc, 0xb7, 0x74,
0x08, 0x6f, 0xc5, 0x68, 0xcd, 0x95, 0xda, 0x02, 0xe6, 0xa1, 0x5d, 0x1e, 0x4f, 0x7c, 0x5b, 0xa8,
0x90, 0x78, 0xcc, 0x54, 0x00, 0x4e, 0xb7, 0x7a, 0xbd, 0xc1, 0xf0, 0xe4, 0xca, 0xea, 0x41, 0xb3,
0xca, 0x57, 0x56, 0x3f, 0x36, 0xab, 0xd5, 0x9a, 0x25, 0xe3, 0xcb, 0xb9, 0x21, 0xe5, 0xfa, 0x4e,
0x6b, 0xbd, 0x0a, 0xd9, 0xbe, 0x18, 0x82, 0x37, 0xc3, 0xdf, 0x30, 0x14, 0x8b, 0xb8, 0x85, 0x7d,
0xcf, 0x0c, 0x1b, 0x08, 0x66, 0x23, 0xc0, 0x61, 0xb3, 0x98, 0x69, 0x7d, 0x1c, 0x7d, 0xca, 0x8c,
0x3e, 0xcf, 0x0c, 0xa1, 0x47, 0x78, 0xab, 0x17, 0x91, 0x78, 0xf3, 0x66, 0x69, 0x28, 0xd9, 0x7b,
0xc6, 0xa1, 0xc3, 0xf6, 0xf9, 0x50, 0xba, 0xfb, 0xb3, 0x2e, 0x74, 0x07, 0x78, 0x52, 0x6a, 0x56,
0xe4, 0x90, 0xbb, 0xfb, 0xaa, 0xab, 0x71, 0x45, 0x8f, 0xd2, 0x10, 0x29, 0x0d, 0xfc, 0x75, 0x0f,
0x17, 0x52, 0x5c, 0x48, 0xeb, 0xf8, 0x8d, 0xe9, 0xae, 0xd8, 0xa5, 0x9f, 0xe7, 0x33, 0xde, 0x68,
0xc5, 0xc3, 0xd4, 0x7d, 0x5b, 0x2d, 0x6f, 0x5f, 0x2d, 0x6f, 0xa7, 0xc3, 0xd8, 0x7d, 0x5b, 0x2e,
0x6f, 0x5f, 0xb6, 0xdb, 0x2b, 0x5a, 0x27, 0xed, 0x72, 0xf9, 0xf4, 0xd4, 0xc1, 0x8e, 0x5a, 0xb3,
0xf5, 0xc0, 0x26, 0x4a, 0xf4, 0x37, 0x5e, 0x18, 0x76, 0x4f, 0x66, 0x55, 0x8e, 0x34, 0xc3, 0xe6,
0x4e, 0xac, 0xcc, 0xe4, 0x44, 0x41, 0x2b, 0x10, 0xf4, 0xea, 0x37, 0x8a, 0xa1, 0xa1, 0x48, 0x0c,
0x0d, 0x0b, 0x0a, 0x29, 0x32, 0x37, 0x6c, 0x01, 0xe8, 0xa6, 0xa2, 0x63, 0xbb, 0x89, 0xf9, 0xeb,
0xab, 0x9a, 0x77, 0x93, 0x49, 0x8a, 0x3d, 0x03, 0x74, 0x26, 0xcd, 0x24, 0x95, 0xca, 0x3c, 0x1d,
0xcc, 0x60, 0x6d, 0xe6, 0x28, 0x76, 0x89, 0x4a, 0xde, 0xad, 0xae, 0x65, 0x90, 0x97, 0x38, 0x23,
0x3b, 0x01, 0xd2, 0x5f, 0x8d, 0x99, 0x59, 0xf7, 0xa1, 0xfa, 0x83, 0xe2, 0xa9, 0x71, 0xce, 0xe3,
0x9b, 0x90, 0x9e, 0x98, 0x63, 0xf7, 0x83, 0x5e, 0xbd, 0x11, 0xd5, 0xfd, 0x64, 0xbb, 0x4e, 0xa7,
0x55, 0x3a, 0x30, 0x4a, 0x07, 0x2c, 0xbe, 0x59, 0xe8, 0xad, 0x68, 0xa8, 0xd9, 0xb4, 0xe0, 0x68,
0xe3, 0x84, 0xdd, 0xc2, 0x42, 0x24, 0xab, 0xe6, 0xf0, 0xd9, 0x5e, 0xd4, 0xc1, 0x37, 0x0f, 0x16,
0x89, 0x79, 0xf2, 0xe0, 0xd7, 0x04, 0x69, 0x7a, 0x49, 0x90, 0x26, 0xdb, 0x22, 0x5f, 0x0c, 0x43,
0xe3, 0x08, 0x4b, 0xd4, 0xe6, 0x6e, 0xf8, 0x70, 0x3e, 0xae, 0x0d, 0xc9, 0xf0, 0xc1, 0x87, 0x0b,
0x2b, 0x95, 0xe6, 0x2d, 0x11, 0x22, 0xcb, 0xd4, 0xd1, 0x23, 0x1b, 0xb3, 0x73, 0x80, 0x6f, 0x2d,
0x73, 0x5a, 0x3b, 0x12, 0x3b, 0x9b, 0x63, 0x13, 0x6d, 0x3b, 0x67, 0x28, 0x74, 0xdf, 0x0a, 0xad,
0x4c, 0xcd, 0x96, 0xd3, 0xd4, 0x54, 0x91, 0x74, 0x6c, 0x58, 0x43, 0xda, 0x74, 0x88, 0xa1, 0xed,
0x09, 0x1b, 0x3c, 0x27, 0xc8, 0x7e, 0x8e, 0x6a, 0x54, 0xf2, 0xbb, 0x79, 0x31, 0x30, 0x64, 0xc7,
0x78, 0xf9, 0x9f, 0xa3, 0x4e, 0xcd, 0x80, 0x92, 0xe7, 0x46, 0x6a, 0x33, 0x4f, 0xfe, 0x87, 0x11,
0xda, 0xd9, 0x36, 0x43, 0x1b, 0xf5, 0x1f, 0x9e, 0x99, 0x9d, 0x05, 0xcb, 0xa8, 0xc3, 0xa2, 0xd6,
0x2c, 0x3a, 0x7f, 0x05, 0x73, 0x81, 0x38, 0xb0, 0x31, 0xb3, 0xba, 0x21, 0xad, 0x03, 0x43, 0xe6,
0xd4, 0xe4, 0x39, 0xec, 0x8b, 0xe7, 0xb0, 0x3b, 0x9b, 0xe0, 0x6b, 0xd8, 0xc6, 0xfa, 0x35, 0x16,
0xb9, 0x96, 0x57, 0x8d, 0x4f, 0x6c, 0x7d, 0xbc, 0x48, 0x20, 0x5f, 0x25, 0x8f, 0x1b, 0xd4, 0xb1,
0x79, 0xe3, 0x8f, 0x3f, 0x6e, 0x4b, 0xbe, 0x15, 0xce, 0xf8, 0x1a, 0x5f, 0xec, 0xac, 0x24, 0xdd,
0x4b, 0x64, 0xf1, 0x62, 0xdb, 0x59, 0x8b, 0xf0, 0x75, 0x5e, 0x38, 0x72, 0x83, 0x21, 0xae, 0x1c,
0xba, 0x85, 0x1d, 0x76, 0x9e, 0xa1, 0x87, 0x93, 0x39, 0x81, 0x21, 0x4d, 0x35, 0xe0, 0x43, 0x53,
0x56, 0xc3, 0x9f, 0x52, 0x86, 0xb6, 0x74, 0x0e, 0x99, 0x20, 0xa5, 0x2c, 0x67, 0x39, 0x3e, 0xf6,
0x0d, 0x7f, 0xa9, 0x03, 0x42, 0xb0, 0x5a, 0x24, 0x62, 0xde, 0x71, 0x9d, 0x91, 0xb2, 0x82, 0x2e,
0xab, 0x2a, 0x53, 0xd7, 0x09, 0x26, 0x90, 0x29, 0x14, 0xdf, 0xe6, 0xe1, 0xa7, 0x0c, 0x8b, 0xbc,
0x36, 0x59, 0x91, 0x44, 0x12, 0x21, 0x35, 0x61, 0x69, 0x6a, 0xee, 0x9f, 0x72, 0xc1, 0xe6, 0x28,
0xbe, 0x61, 0x44, 0xd6, 0x84, 0x57, 0xba, 0x97, 0x9d, 0xd1, 0xf8, 0xee, 0x68, 0xcc, 0x59, 0x6e,
0x50, 0x1b, 0x05, 0x5b, 0x97, 0xa6, 0x6a, 0xfe, 0x39, 0x63, 0x8a, 0xf5, 0x9f, 0x36, 0x1d, 0x0d,
0x2b, 0x79, 0x26, 0x71, 0x0f, 0x5f, 0x2c, 0x8a, 0x77, 0xbf, 0x3c, 0x5b, 0x15, 0xed, 0x88, 0xd5,
0x19, 0x57, 0xcd, 0x7c, 0x75, 0x5b, 0x5a, 0xd8, 0x79, 0xdf, 0x38, 0x85, 0x70, 0x85, 0x7f, 0x25,
0x96, 0x18, 0x0d, 0x4c, 0xcf, 0x2c, 0x90, 0xe3, 0x91, 0x32, 0x7b, 0x50, 0xb6, 0x9c, 0x5a, 0xe7,
0xaa, 0xda, 0x7b, 0xc7, 0x2c, 0xce, 0x1a, 0x6f, 0xc7, 0x18, 0x84, 0xa9, 0xd5, 0x4b, 0x38, 0xfa,
0x0f, 0x29, 0x94, 0x26, 0x8a, 0xff, 0x09, 0x84, 0x89, 0xa4, 0x87, 0x40, 0x19, 0xb6, 0xeb, 0xa5,
0x2d, 0x83, 0x24, 0x17, 0x59, 0x37, 0x97, 0x52, 0x9a, 0x55, 0xe6, 0x4d, 0x8e, 0xf1, 0xe4, 0x28,
0xd5, 0xac, 0x36, 0x31, 0xe8, 0xb4, 0x41, 0x40, 0x5f, 0xad, 0xc7, 0xd9, 0x3a, 0x70, 0xf1, 0x20,
0xac, 0xf9, 0xdc, 0x7c, 0x26, 0x34, 0x93, 0x61, 0x11, 0xbe, 0xce, 0x33, 0x13, 0xeb, 0xff, 0x1a,
0x3e, 0x68, 0x97, 0x19, 0xa8, 0x78, 0x8c, 0x19, 0xba, 0x66, 0x02, 0x9b, 0xff, 0x1d, 0xfe, 0x17,
0x93, 0xa0, 0x63, 0xf3, 0x4b, 0x14, 0x00, 0x00
};

View File

@@ -646,22 +646,34 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
if (subPage == 10)
{
strip.isMatrix = request->arg(F("SOMP")).toInt();
strip.panelH = MAX(1,MIN(128,request->arg(F("PH")).toInt()));
strip.panelW = MAX(1,MIN(128,request->arg(F("PW")).toInt()));
strip.hPanels = MAX(1,MIN(8,request->arg(F("MPH")).toInt()));
strip.vPanels = MAX(1,MIN(8,request->arg(F("MPV")).toInt()));
strip.matrix.bottomStart = request->arg(F("PB")).toInt();
strip.matrix.rightStart = request->arg(F("PR")).toInt();
strip.matrix.vertical = request->arg(F("PV")).toInt();
strip.matrix.serpentine = request->hasArg(F("PS"));
for (uint8_t i=0; i<WLED_MAX_PANELS; i++) {
char pO[8]; sprintf_P(pO, PSTR("P%d"), i);
uint8_t l = strlen(pO); pO[l+1] = 0;
pO[l] = 'B'; if (!request->hasArg(pO)) break;
pO[l] = 'B'; strip.panel[i].bottomStart = request->arg(pO).toInt();
pO[l] = 'R'; strip.panel[i].rightStart = request->arg(pO).toInt();
pO[l] = 'V'; strip.panel[i].vertical = request->arg(pO).toInt();
pO[l] = 'S'; strip.panel[i].serpentine = request->hasArg(pO);
// strip.panelH = MAX(1,MIN(128,request->arg(F("PH")).toInt()));
// strip.panelW = MAX(1,MIN(128,request->arg(F("PW")).toInt()));
strip.panel.clear(); // release memory if allocated
if (strip.isMatrix) {
strip.panels = MAX(1,MIN(WLED_MAX_PANELS,request->arg(F("MPC")).toInt()));
strip.matrix.bottomStart = request->arg(F("PB")).toInt();
strip.matrix.rightStart = request->arg(F("PR")).toInt();
strip.matrix.vertical = request->arg(F("PV")).toInt();
strip.matrix.serpentine = request->hasArg(F("PS"));
strip.panel.reserve(strip.panels); // pre-allocate memory
for (uint8_t i=0; i<strip.panels; i++) {
WS2812FX::Panel p;
char pO[8]; sprintf_P(pO, PSTR("P%d"), i);
uint8_t l = strlen(pO); pO[l+1] = 0;
pO[l] = 'B'; if (!request->hasArg(pO)) break;
pO[l] = 'B'; p.bottomStart = request->arg(pO).toInt();
pO[l] = 'R'; p.rightStart = request->arg(pO).toInt();
pO[l] = 'V'; p.vertical = request->arg(pO).toInt();
pO[l] = 'S'; p.serpentine = request->hasArg(pO);
pO[l] = 'X'; p.xOffset = request->arg(pO).toInt();
pO[l] = 'Y'; p.yOffset = request->arg(pO).toInt();
pO[l] = 'W'; p.width = request->arg(pO).toInt();
pO[l] = 'H'; p.height = request->arg(pO).toInt();
strip.panel.push_back(p);
}
} else {
Segment::maxWidth = strip.getLengthTotal();
Segment::maxHeight = 1;
}
strip.setUpMatrix(); // will check limits
}

View File

@@ -763,18 +763,20 @@ void getSettingsJS(byte subPage, char* dest)
{
sappend('v',SET_F("SOMP"),strip.isMatrix);
#ifndef WLED_DISABLE_2D
oappend(SET_F("maxPanels=")); oappendi(WLED_MAX_PANELS); oappend(SET_F(";"));
oappend(SET_F("resetPanels();"));
if (strip.isMatrix) {
sappend('v',SET_F("PH"),strip.panelH);
sappend('v',SET_F("PW"),strip.panelW);
sappend('v',SET_F("MPH"),strip.hPanels);
sappend('v',SET_F("MPV"),strip.vPanels);
if(strip.panels>0){
sappend('v',SET_F("PW"),strip.panel[0].width); //Set generator Width and Height to first panel size for convenience
sappend('v',SET_F("PH"),strip.panel[0].height);
}
sappend('v',SET_F("MPC"),strip.panels);
sappend('v',SET_F("PB"),strip.matrix.bottomStart);
sappend('v',SET_F("PR"),strip.matrix.rightStart);
sappend('v',SET_F("PV"),strip.matrix.vertical);
sappend('c',SET_F("PS"),strip.matrix.serpentine);
// panels
for (uint8_t i=0; i<strip.hPanels*strip.vPanels; i++) {
for (uint8_t i=0; i<strip.panels; i++) {
char n[5];
oappend(SET_F("addPanel("));
oappend(itoa(i,n,10));
@@ -785,6 +787,10 @@ void getSettingsJS(byte subPage, char* dest)
pO[l] = 'R'; sappend('v',pO,strip.panel[i].rightStart);
pO[l] = 'V'; sappend('v',pO,strip.panel[i].vertical);
pO[l] = 'S'; sappend('c',pO,strip.panel[i].serpentine);
pO[l] = 'X'; sappend('v',pO,strip.panel[i].xOffset);
pO[l] = 'Y'; sappend('v',pO,strip.panel[i].yOffset);
pO[l] = 'W'; sappend('v',pO,strip.panel[i].width);
pO[l] = 'H'; sappend('v',pO,strip.panel[i].height);
}
}
#else