/** * Issue #233: resize labels measure between wall faces, not between centrelines. * * Before the fix one bubble carried two conventions at once — lengths along the * centreline next to an area computed from the floor — so «3.00 × 4.00 · 11.0 m²» * described a room that no tape measure would confirm. * * The room below is 300×400 cm centre-to-centre with 15 cm walls on all four * sides, so every clear span is exactly 15 cm shorter than the axis it sits on: * 285 and 385 cm. Thickness is set through the card's own dialog path * (`_wallThickClick` → `_wallThickApply(true)`), and both label producers are * then called as the drag handlers call them. The legacy room-scale frame was * deliberately removed by #277, so only fixed-topology edge labels remain. */ import { launch, checkAll, finish } from './serve.mjs'; const { page, browser } = await launch(); const res = await page.evaluate(async () => { const out = {}; const c = window.__card; const sr = c.shadowRoot || c.renderRoot; const upd = async () => { c._cfgEpoch++; c.requestUpdate(); await c.updateComplete; }; // First number of a label: both formatters emit a dot, so this is locale-safe. const num = (text) => Number((String(text).match(/-?\d+(?:\.\d+)?/) || [])[0]); c._setMode('plan'); await upd(); const space = c._curSpaceCfg; const savedConfig = JSON.parse(JSON.stringify(c._serverCfg)); // 5 cm to a grid cell, so 300×400 cm is 60×80 cells of the plan. space.cell_cm = 5; c._serverCfg.model_version = 7; space.partitions = []; delete space.walls; delete space.wall_segments; delete space.open_spans; const g = c._gridPitch; const x0 = 20 * g, y0 = 20 * g; const render = [ [x0, y0], [x0 + 60 * g, y0], [x0 + 60 * g, y0 + 80 * g], [x0, y0 + 80 * g], ]; space.rooms = [{ id: 'r233', name: 'r233', poly: render.map((p) => [p[0] / 1000, p[1] / 1000]) }]; await upd(); out.roomBuilt = !!c._spaceModel()?.rooms?.some((r) => r.id === 'r233'); // 15 cm on every side, applied the way the Thickness tool applies it. c._tool = 'wallthick'; await upd(); const mid = (a, b) => [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2]; c._wallThickClick(mid(render[0], render[1])); await upd(); out.thicknessDialogOpened = !!c._wallDialog && c._wallDialog.roomId === 'r233'; if (c._wallDialog) c._wallDialog = { ...c._wallDialog, value: '15' }; c._wallThickApply(true); await upd(); const committed = c._curSpaceCfg; const committedRoom = committed.rooms.find((room) => room.id === 'r233'); const byId = new Map((committed.wall_segments || []).map((segment) => [segment.id, segment])); out.fourWallsRecorded = committedRoom?.wall_ids?.length === 4; out.everyWallFifteen = committedRoom?.wall_ids?.every((id) => Math.abs((byId.get(id)?.cm ?? -1) - 15) < 0.01) === true; // Wall labels: the clear span across is 285 cm, along it 385 cm. const spans = c._rszInnerSpanCms('r233', render, {}); out.spansComputed = Array.isArray(spans) && spans.length === 4; out.spanAcrossIsInner = !!spans && Math.abs(spans[0] - 285) < 1; out.spanAlongIsInner = !!spans && Math.abs(spans[1] - 385) < 1; out.spansSymmetric = !!spans && Math.abs(spans[0] - spans[2]) < 1 && Math.abs(spans[1] - spans[3]) < 1; // The whole point of #233: no label may still read the centreline. out.noCentrelineSpan = !!spans && !spans.some((s) => Math.abs(s - 300) < 0.5 || Math.abs(s - 400) < 0.5); // The two useful side-wall bubbles, called with the controller's room snapshot. const resizeRooms = c._spaceModel().rooms.map((r) => ({ id: r.id, poly: r.poly })); await upd(); const drag = c._rszEdgeLabels( { polys: { r233: render } }, { roomId: 'r233', edge: 0, roomIds: ['r233'], edgeByRoom: { r233: 0 } }, resizeRooms, ); const dragLens = drag.filter((l) => l.kind === 'length').map((l) => num(l.text)); out.dragLabelsTwoSideEdges = dragLens.length === 2; out.dragLabelsInner = dragLens.every((v) => Math.abs(v - 2.85) < 0.02 || Math.abs(v - 3.85) < 0.02); out.dragLabelsNotCentreline = !dragLens.some((v) => Math.abs(v - 3) < 0.005 || Math.abs(v - 4) < 0.005); const dragArea = drag.find((l) => l.kind === 'area'); out.dragAreaStillInner = !!dragArea && Math.abs(num(dragArea.text) - 11) < 0.06; out.legacyScaleLabelsAbsent = typeof c._rszScaleLabels === 'undefined'; out.legacyCornerHandlesAbsent = !sr.querySelector('.rszcorner'); c._resize.reset(); c._tool = null; c._serverCfg = savedConfig; c._modelCache = null; c._frame = null; await upd(); return out; }); checkAll(res); await finish(browser);