2d Mapping with Matrix Gaps (#2892)

* New 2d mapping
* panel matrix generator
* add todos, fix vert/horz swap
* Fix 2d mapping to matrix in settings 2D
* add correct index mapping to pixels per panel
* fix panel bug in led layout
* formatting and change max panels
* add per panel width and height
* fix using length instead of custom mapping size
* fix: panel dimensions location

* panel[] implemented as a vector.
Removed matrixWidth & matrixHeight.
Panel structure update.
* Fixes.

Co-authored-by: Blaz Kristan <blaz@kristan-sp.si>
This commit is contained in:
Caleb Marting 2023-01-02 13:56:00 -06:00 committed by GitHub
parent 8e208bc76d
commit 187ecf511f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1445 additions and 1349 deletions

View File

@ -655,12 +655,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)),
@ -697,6 +693,7 @@ class WS2812FX { // 96 bytes
_mode.clear();
_modeData.clear();
_segments.clear();
panel.clear();
customPalettes.clear();
if (useLedsArray && Segment::_globalLeds) free(Segment::_globalLeds);
}
@ -809,22 +806,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 {
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

@ -41,57 +41,57 @@ void WS2812FX::setUpMatrix() {
customMappingTable = nullptr;
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;
}
customMappingTable = new uint16_t[maxWidth * maxHeight];
customMappingTable = new uint16_t[Segment::maxWidth * Segment::maxHeight];
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;
// 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[startL + offset] = startP + q;
}
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[(p.yOffset + (p.vertical?x:y)) * Segment::maxWidth + p.xOffset + (p.vertical?y:x)] = pix;
}
}
}
#ifdef WLED_DEBUG
DEBUG_PRINT(F("Matrix ledmap:"));
for (uint16_t i=0; i<customMappingSize; i++) {
@ -101,7 +101,13 @@ void WS2812FX::setUpMatrix() {
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
@ -115,7 +121,7 @@ void IRAM_ATTR WS2812FX::setPixelColorXY(int x, int y, uint32_t col)
#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

@ -97,32 +97,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();
@ -700,22 +706,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://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

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

File diff suppressed because it is too large Load Diff

View File

@ -643,22 +643,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.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"));
for (uint8_t i=0; i<WLED_MAX_PANELS; i++) {
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'; 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);
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

@ -726,18 +726,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));
@ -748,6 +750,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