xonecode 0.31.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/web/dist/assets/{EditorDeFichero-ChyJtiiz.js → EditorDeFichero-H_kGeZt2.js} +1 -1
- package/apps/web/dist/assets/{index-IptObD2z.css → index-CWBaotdZ.css} +1 -1
- package/apps/web/dist/assets/index-DnGuOvbb.js +499 -0
- package/apps/web/dist/assets/{php-B91ZcS-9.js → php-CMFQiZgk.js} +1 -1
- package/apps/web/dist/assets/{ruby-DrxrTSz0.js → ruby-Dj3BOBHc.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/dist/agent/config/modelosDeMotor.js +4 -2
- package/dist/agent/config/modelosDeMotor.js.map +1 -1
- package/dist/agent/config/settingsEnDisco.js +26 -0
- package/dist/agent/config/settingsEnDisco.js.map +1 -1
- package/dist/agent/dispositivos/cajasDeMaqueta.js +130 -0
- package/dist/agent/dispositivos/cajasDeMaqueta.js.map +1 -0
- package/dist/agent/dispositivos/geometriaEnDisco.js +25 -0
- package/dist/agent/dispositivos/geometriaEnDisco.js.map +1 -0
- package/dist/agent/dispositivos/juezVisual.js +84 -3
- package/dist/agent/dispositivos/juezVisual.js.map +1 -1
- package/dist/agent/grafo/criticaVisual.js +240 -11
- package/dist/agent/grafo/criticaVisual.js.map +1 -1
- package/dist/agent/grafo/lectorDeReferencias.js +21 -0
- package/dist/agent/grafo/lectorDeReferencias.js.map +1 -1
- package/dist/agent/motores/motoresLocales.js +429 -0
- package/dist/agent/motores/motoresLocales.js.map +1 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js +30 -3
- package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
- package/dist/agent/motores/trueforge/toolsDeFichero.js +24 -6
- package/dist/agent/motores/trueforge/toolsDeFichero.js.map +1 -1
- package/dist/agent/sesiones/adjuntosDeSesion.js +125 -5
- package/dist/agent/sesiones/adjuntosDeSesion.js.map +1 -1
- package/dist/agent/subagentes/ejecutableEnWindows.js +139 -0
- package/dist/agent/subagentes/ejecutableEnWindows.js.map +1 -0
- package/dist/agent/subagentes/subagenteCodex.js +7 -2
- package/dist/agent/subagentes/subagenteCodex.js.map +1 -1
- package/dist/agent/subagentes/subagenteOpencode.js +12 -5
- package/dist/agent/subagentes/subagenteOpencode.js.map +1 -1
- package/dist/core/adjuntos.js +10 -2
- package/dist/core/adjuntos.js.map +1 -1
- package/dist/core/descripcionDePantalla.js +354 -0
- package/dist/core/descripcionDePantalla.js.map +1 -0
- package/dist/core/estiloMedido.js +332 -0
- package/dist/core/estiloMedido.js.map +1 -0
- package/dist/core/geometriaDePantalla.js +437 -0
- package/dist/core/geometriaDePantalla.js.map +1 -0
- package/dist/core/motoresLocales.js +128 -0
- package/dist/core/motoresLocales.js.map +1 -0
- package/dist/core/nucleoXone.js +6 -6
- package/dist/core/nucleoXone.js.map +1 -1
- package/dist/core/settings.js +5 -0
- package/dist/core/settings.js.map +1 -1
- package/dist/core/shellDeAgente.js +13 -0
- package/dist/core/shellDeAgente.js.map +1 -1
- package/dist/core/zipDeAdjunto.js +79 -0
- package/dist/core/zipDeAdjunto.js.map +1 -0
- package/dist/web/servidor/arranque.js +84 -0
- package/dist/web/servidor/arranque.js.map +1 -1
- package/dist/web/servidor/transporte.js.map +1 -1
- package/package.json +1 -1
- package/skills/xone-development/SKILL.md +2 -1
- package/skills/xone-development/references/css/buenas-practicas-y-parser.md +2 -1
- package/skills/xone-development/references/css/de-una-maqueta-a-xone.md +81 -0
- package/skills/xone-development/references/css/patrones-material-y-temas.md +15 -13
- package/skills/xone-development/references/css/propiedades-y-herencia.md +2 -2
- package/skills/xone-development/references/css/selectores-unidades-colores.md +8 -3
- package/skills/xone-development/references/indice-completo.md +1 -0
- package/skills/xone-hotswap/lib/geometria.mjs +147 -0
- package/skills/xone-hotswap/scripts/xone-captura-android +6 -0
- package/skills/xone-hotswap/scripts/xone-hotswap +8 -0
- package/skills/xone-hotswap/scripts/xone-recargar-android +15 -0
- package/apps/web/dist/assets/index-CFIrUOmW.js +0 -499
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/** Dos colores «iguales» a efectos de qué es fondo: compresión JPEG y antialias incluidos. */
|
|
2
|
+
const MISMO_COLOR = 28;
|
|
3
|
+
/**
|
|
4
|
+
* Un fondo PROPIO se distingue de lo de fuera con poco: una tecla #26292E sobre un panel #1C1E22 (medido en la
|
|
5
|
+
* calculadora) se separa unos 17 puntos, y con el umbral de «mismo color» la tecla pasaba por etiqueta sin fondo.
|
|
6
|
+
*/
|
|
7
|
+
const FONDO_PROPIO = 10;
|
|
8
|
+
/** Lo que se aparta del fondo lo bastante para ser tinta (texto, icono). */
|
|
9
|
+
const TINTA = 70;
|
|
10
|
+
const distancia = (a, b) => Math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2);
|
|
11
|
+
const hex = (c) => `#${c.map((v) => Math.round(v).toString(16).padStart(2, "0")).join("").toUpperCase()}`;
|
|
12
|
+
function pixel(img, x, y) {
|
|
13
|
+
const i = (Math.min(img.alto - 1, Math.max(0, y)) * img.ancho + Math.min(img.ancho - 1, Math.max(0, x))) * 4;
|
|
14
|
+
return [img.datos[i], img.datos[i + 1], img.datos[i + 2]];
|
|
15
|
+
}
|
|
16
|
+
/** El color más repetido de una lista, contando en cubos de 16 niveles y devolviendo la media del cubo ganador. */
|
|
17
|
+
function moda(colores) {
|
|
18
|
+
if (colores.length === 0)
|
|
19
|
+
return undefined;
|
|
20
|
+
const cubos = new Map();
|
|
21
|
+
for (const c of colores) {
|
|
22
|
+
const k = ((c[0] >> 4) << 8) | ((c[1] >> 4) << 4) | (c[2] >> 4);
|
|
23
|
+
const cubo = cubos.get(k) ?? { n: 0, suma: [0, 0, 0] };
|
|
24
|
+
cubo.n += 1;
|
|
25
|
+
cubo.suma = [cubo.suma[0] + c[0], cubo.suma[1] + c[1], cubo.suma[2] + c[2]];
|
|
26
|
+
cubos.set(k, cubo);
|
|
27
|
+
}
|
|
28
|
+
const mejor = [...cubos.values()].sort((a, b) => b.n - a.n)[0];
|
|
29
|
+
return [mejor.suma[0] / mejor.n, mejor.suma[1] / mejor.n, mejor.suma[2] / mejor.n];
|
|
30
|
+
}
|
|
31
|
+
/** Las categorías de forma a partir de las cifras. Pura y exportada para el test. */
|
|
32
|
+
export function formaDe(radio, proporcion) {
|
|
33
|
+
if (radio < 0.12)
|
|
34
|
+
return "recta";
|
|
35
|
+
if (radio < 0.38)
|
|
36
|
+
return "redondeada";
|
|
37
|
+
// Extremos redondos: círculo si es tan ancho como alto, píldora si es claramente más ancho (o alto). En medio
|
|
38
|
+
// —las teclas de la maqueta: 1,2:1 con radio 0,48— es un cuadrado muy redondeado, no una píldora.
|
|
39
|
+
if (Math.abs(proporcion - 1) <= 0.08)
|
|
40
|
+
return "circulo";
|
|
41
|
+
return proporcion >= 1.3 || proporcion <= 0.77 ? "pildora" : "redondeada";
|
|
42
|
+
}
|
|
43
|
+
/** El tamaño de letra a partir de su altura (fracción del ancho de pantalla). */
|
|
44
|
+
export function letraDe(altura) {
|
|
45
|
+
if (altura < 0.03)
|
|
46
|
+
return "pequena";
|
|
47
|
+
if (altura < 0.045)
|
|
48
|
+
return "normal";
|
|
49
|
+
if (altura < 0.08)
|
|
50
|
+
return "grande";
|
|
51
|
+
return "enorme";
|
|
52
|
+
}
|
|
53
|
+
/** Mide un control. `img` es la imagen entera; `caja`, en sus píxeles. Lo que no se puede medir no se pone. */
|
|
54
|
+
export function medirControl(img, caja) {
|
|
55
|
+
const x0 = Math.max(0, Math.round(caja.x));
|
|
56
|
+
const y0 = Math.max(0, Math.round(caja.y));
|
|
57
|
+
const x1 = Math.min(img.ancho - 1, Math.round(caja.x + caja.ancho) - 1);
|
|
58
|
+
const y1 = Math.min(img.alto - 1, Math.round(caja.y + caja.alto) - 1);
|
|
59
|
+
if (x1 - x0 < 4 || y1 - y0 < 4)
|
|
60
|
+
return {};
|
|
61
|
+
// Lo de FUERA: un anillo a 3 px de la caja.
|
|
62
|
+
const anillo = [];
|
|
63
|
+
for (let x = x0; x <= x1; x += 2)
|
|
64
|
+
anillo.push(pixel(img, x, y0 - 3), pixel(img, x, y1 + 3));
|
|
65
|
+
for (let y = y0; y <= y1; y += 2)
|
|
66
|
+
anillo.push(pixel(img, x0 - 3, y), pixel(img, x1 + 3, y));
|
|
67
|
+
const fuera = moda(anillo);
|
|
68
|
+
const dentro = [];
|
|
69
|
+
for (let y = y0; y <= y1; y += 1)
|
|
70
|
+
for (let x = x0; x <= x1; x += 1)
|
|
71
|
+
dentro.push(pixel(img, x, y));
|
|
72
|
+
const medido = {};
|
|
73
|
+
// El FONDO propio: el color más repetido, si no es lo de fuera.
|
|
74
|
+
const masRepetido = moda(dentro);
|
|
75
|
+
const conFondo = distancia(masRepetido, fuera) > FONDO_PROPIO;
|
|
76
|
+
const fondo = conFondo ? masRepetido : fuera;
|
|
77
|
+
if (conFondo)
|
|
78
|
+
medido.fondo = hex(fondo);
|
|
79
|
+
// El rectángulo del FONDO y su forma.
|
|
80
|
+
let fx0 = x0;
|
|
81
|
+
let fy0 = y0;
|
|
82
|
+
let fx1 = x1;
|
|
83
|
+
let fy1 = y1;
|
|
84
|
+
/**
|
|
85
|
+
* Qué es «del fondo» al buscar su forma: la mitad del contraste entre el fondo y lo de fuera. Con un umbral fijo,
|
|
86
|
+
* una tecla #282A2E sobre un panel #1F2125 (medido en la maqueta de la calculadora) se confundía con él y su esquina
|
|
87
|
+
* redondeada salía recta.
|
|
88
|
+
*/
|
|
89
|
+
const delFondo = Math.max(6, Math.min(MISMO_COLOR, distancia(fondo, fuera) / 2));
|
|
90
|
+
if (conFondo) {
|
|
91
|
+
[fx0, fy0, fx1, fy1] = [x1, y1, x0, y0];
|
|
92
|
+
for (let y = y0; y <= y1; y += 1)
|
|
93
|
+
for (let x = x0; x <= x1; x += 1)
|
|
94
|
+
if (distancia(pixel(img, x, y), fondo) <= delFondo) {
|
|
95
|
+
fx0 = Math.min(fx0, x);
|
|
96
|
+
fx1 = Math.max(fx1, x);
|
|
97
|
+
fy0 = Math.min(fy0, y);
|
|
98
|
+
fy1 = Math.max(fy1, y);
|
|
99
|
+
}
|
|
100
|
+
const ancho = fx1 - fx0 + 1;
|
|
101
|
+
const alto = fy1 - fy0 + 1;
|
|
102
|
+
// Cuánto se come la esquina: por la diagonal desde cada esquina, hasta el primer píxel de fondo. En un arco de
|
|
103
|
+
// radio r, la diagonal llega a d = r·(1 − 1/√2).
|
|
104
|
+
const esquinas = [
|
|
105
|
+
[fx0, fy0, 1, 1],
|
|
106
|
+
[fx1, fy0, -1, 1],
|
|
107
|
+
[fx0, fy1, 1, -1],
|
|
108
|
+
[fx1, fy1, -1, -1],
|
|
109
|
+
];
|
|
110
|
+
const radios = esquinas.map(([ex, ey, dx, dy]) => {
|
|
111
|
+
let d = 0;
|
|
112
|
+
while (d < Math.min(ancho, alto) / 2 && distancia(pixel(img, ex + dx * d, ey + dy * d), fondo) > delFondo)
|
|
113
|
+
d += 1;
|
|
114
|
+
return d / (1 - Math.SQRT1_2);
|
|
115
|
+
});
|
|
116
|
+
const radio = radios.sort((a, b) => a - b)[1] / Math.min(ancho, alto);
|
|
117
|
+
medido.radio = Math.round(Math.min(radio, 0.5) * 100) / 100;
|
|
118
|
+
medido.proporcion = Math.round((ancho / alto) * 100) / 100;
|
|
119
|
+
medido.forma = formaDe(medido.radio, medido.proporcion);
|
|
120
|
+
}
|
|
121
|
+
// El BORDE: los lados de la caja son una línea de otro color que lo de dentro, en tres de los cuatro lados.
|
|
122
|
+
/** Un lado es una LÍNEA si, en alguna de las tres primeras filas hacia dentro, casi todo es de un color distinto. */
|
|
123
|
+
/**
|
|
124
|
+
* Un lado es una LÍNEA FINA: casi todo de un color distinto del fondo y de lo de fuera, y tres píxeles más afuera
|
|
125
|
+
* (`afuera`: hacia dónde es fuera, en x e y) vuelve a verse lo de fuera. Sin esto último, el halo de un botón con
|
|
126
|
+
* resplandor contaba como borde (medido: la «=» de la maqueta).
|
|
127
|
+
*/
|
|
128
|
+
const lado = (puntos, afuera) => {
|
|
129
|
+
const colores = puntos.map(([x, y]) => pixel(img, x, y));
|
|
130
|
+
const linea = moda(colores);
|
|
131
|
+
const iguales = colores.filter((c) => distancia(c, linea) <= MISMO_COLOR).length / colores.length;
|
|
132
|
+
if (iguales <= 0.7 || distancia(linea, fondo) <= MISMO_COLOR || distancia(linea, fuera) <= MISMO_COLOR)
|
|
133
|
+
return false;
|
|
134
|
+
const masAfuera = puntos.filter(([x, y]) => distancia(pixel(img, x + 3 * afuera[0], y + 3 * afuera[1]), fuera) <= MISMO_COLOR).length;
|
|
135
|
+
return masAfuera / puntos.length > 0.7;
|
|
136
|
+
};
|
|
137
|
+
const tramo = (a, b) => Array.from({ length: Math.max(1, Math.floor((b - a) * 0.6)) }, (_, i) => Math.round(a + (b - a) * 0.2 + i));
|
|
138
|
+
const [bx0, by0, bx1, by1] = conFondo ? [fx0, fy0, fx1, fy1] : [x0, y0, x1, y1];
|
|
139
|
+
const lados = [0, 1, 2, 3].filter((cual) =>
|
|
140
|
+
// La línea puede caer justo FUERA del rectángulo del relleno (este se mide por el color del fondo, y el contorno es
|
|
141
|
+
// de otro color) o justo dentro: se busca a los dos lados.
|
|
142
|
+
[-3, -2, -1, 0, 1, 2].some((hacia) => {
|
|
143
|
+
if (cual === 0)
|
|
144
|
+
return lado(tramo(bx0, bx1).map((x) => [x, by0 + hacia]), [0, -1]);
|
|
145
|
+
if (cual === 1)
|
|
146
|
+
return lado(tramo(bx0, bx1).map((x) => [x, by1 - hacia]), [0, 1]);
|
|
147
|
+
if (cual === 2)
|
|
148
|
+
return lado(tramo(by0, by1).map((y) => [bx0 + hacia, y]), [-1, 0]);
|
|
149
|
+
return lado(tramo(by0, by1).map((y) => [bx1 - hacia, y]), [1, 0]);
|
|
150
|
+
})).length;
|
|
151
|
+
// En una píldora los lados cortos son arcos enteros: basta con los dos largos.
|
|
152
|
+
medido.borde = lados >= ((medido.radio ?? 0) >= 0.38 ? 2 : 3);
|
|
153
|
+
// La TINTA: lejos del fondo y de lo de fuera. Con borde, su franja no es tinta.
|
|
154
|
+
/**
|
|
155
|
+
* Con borde, su franja no es tinta; y si las esquinas son redondeadas, tampoco su ARCO: los píxeles suavizados de
|
|
156
|
+
* una línea curva no se parecen al color de la línea y entraban como texto que medía todo el alto (medido en las
|
|
157
|
+
* teclas de la calculadora). Todo punto del arco cae a menos de r·(1 − 1/√2) ≈ 0,3·r de algún lado.
|
|
158
|
+
*/
|
|
159
|
+
const arco = medido.radio === undefined ? 0 : Math.ceil(0.3 * medido.radio * Math.min(x1 - x0, y1 - y0));
|
|
160
|
+
// En un control con fondo, 6 px más el arco: la compresión JPEG deja un halo junto a una línea fina y brillante. En
|
|
161
|
+
// una etiqueta sin fondo —donde se mide el recorte— basta la línea: un texto cortado justo encima de su borde
|
|
162
|
+
// inferior tiene que seguir llegando al límite (medido: el «12 + 3» del visor).
|
|
163
|
+
const margen = !medido.borde ? 0 : conFondo ? 6 + arco : 1;
|
|
164
|
+
// Desde el rectángulo del FONDO si lo hay: la caja del árbol puede ser mayor que lo dibujado.
|
|
165
|
+
const [ix0, iy0, ix1, iy1] = [bx0 + margen, by0 + margen, bx1 - margen, by1 - margen];
|
|
166
|
+
// La tinta, como máscara.
|
|
167
|
+
const anchoI = Math.max(0, ix1 - ix0 + 1);
|
|
168
|
+
const altoI = Math.max(0, iy1 - iy0 + 1);
|
|
169
|
+
const esTinta = new Uint8Array(anchoI * altoI);
|
|
170
|
+
const porColumna = new Uint32Array(anchoI);
|
|
171
|
+
const porFilaN = new Uint32Array(altoI);
|
|
172
|
+
for (let y = iy0; y <= iy1; y += 1)
|
|
173
|
+
for (let x = ix0; x <= ix1; x += 1) {
|
|
174
|
+
const p = pixel(img, x, y);
|
|
175
|
+
if (distancia(p, fondo) <= TINTA || distancia(p, fuera) <= TINTA)
|
|
176
|
+
continue;
|
|
177
|
+
esTinta[(y - iy0) * anchoI + (x - ix0)] = 1;
|
|
178
|
+
porColumna[x - ix0] += 1;
|
|
179
|
+
porFilaN[y - iy0] += 1;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Una LÍNEA no es texto: una columna con tinta en casi todo el alto (el lado de un contorno) o una fila con tinta en
|
|
183
|
+
* casi todo el ancho (su tapa) se quita. Hace falta aunque no se haya detectado el borde: medido, un contorno tenue
|
|
184
|
+
* sobre una tecla poco contrastada no se detectaba y sus lados hacían medir a la letra todo el alto de la tecla.
|
|
185
|
+
*/
|
|
186
|
+
const lineaVertical = (cx) => porColumna[cx] > altoI * 0.8;
|
|
187
|
+
const lineaHorizontal = (cy) => porFilaN[cy] > anchoI * 0.8;
|
|
188
|
+
const porFila = new Map();
|
|
189
|
+
for (let cy = 0; cy < altoI; cy += 1) {
|
|
190
|
+
if (lineaHorizontal(cy))
|
|
191
|
+
continue;
|
|
192
|
+
for (let cx = 0; cx < anchoI; cx += 1) {
|
|
193
|
+
if (esTinta[cy * anchoI + cx] !== 1 || lineaVertical(cx))
|
|
194
|
+
continue;
|
|
195
|
+
const [x, y] = [ix0 + cx, iy0 + cy];
|
|
196
|
+
const fila = porFila.get(y) ?? { colores: [], x0: x, x1: x };
|
|
197
|
+
fila.colores.push(pixel(img, x, y));
|
|
198
|
+
fila.x1 = x;
|
|
199
|
+
porFila.set(y, fila);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* El TEXTO es el bloque continuo de filas con más tinta (huecos de hasta 3 filas: la «i», el «=»). Lo que sobra de un
|
|
204
|
+
* contorno, unos pocos píxeles sueltos lejos del texto, forma bloques aparte y no estira la altura de la letra
|
|
205
|
+
* (medido: una tecla «8» con borde redondeado medía cuatro veces su letra).
|
|
206
|
+
*/
|
|
207
|
+
const bloques = [];
|
|
208
|
+
// Una fila con solo un par de píxeles de tinta (lo que deja un contorno tenue en cada lado) no es texto, y no puede
|
|
209
|
+
// unir el texto con la tapa y el pie de la caja.
|
|
210
|
+
const minimo = Math.max(4, Math.round(anchoI * 0.02));
|
|
211
|
+
for (const y of [...porFila.keys()].sort((a, b) => a - b)) {
|
|
212
|
+
const ultimo = bloques[bloques.length - 1];
|
|
213
|
+
const n = porFila.get(y).colores.length;
|
|
214
|
+
if (n <= minimo)
|
|
215
|
+
continue;
|
|
216
|
+
if (ultimo !== undefined && y - ultimo.y1 <= 4) {
|
|
217
|
+
ultimo.y1 = y;
|
|
218
|
+
ultimo.n += n;
|
|
219
|
+
}
|
|
220
|
+
else
|
|
221
|
+
bloques.push({ y0: y, y1: y, n });
|
|
222
|
+
}
|
|
223
|
+
const texto = bloques.sort((a, b) => b.n - a.n)[0];
|
|
224
|
+
const tinta = [];
|
|
225
|
+
let [tx0, ty0, tx1, ty1] = [ix1, iy1, ix0, iy0];
|
|
226
|
+
if (texto !== undefined)
|
|
227
|
+
for (let y = texto.y0; y <= texto.y1; y += 1) {
|
|
228
|
+
const fila = porFila.get(y);
|
|
229
|
+
if (fila === undefined)
|
|
230
|
+
continue;
|
|
231
|
+
tinta.push(...fila.colores);
|
|
232
|
+
[tx0, tx1, ty0, ty1] = [Math.min(tx0, fila.x0), Math.max(tx1, fila.x1), Math.min(ty0, y), Math.max(ty1, y)];
|
|
233
|
+
}
|
|
234
|
+
const tocaArriba = texto !== undefined && texto.y0 <= iy0 + 1;
|
|
235
|
+
const tocaAbajo = texto !== undefined && texto.y1 >= iy1 - 1;
|
|
236
|
+
if (tinta.length >= 6) {
|
|
237
|
+
/**
|
|
238
|
+
* El color del texto es el de la tinta MÁS lejana del fondo: en un botón con degradado, el propio degradado se
|
|
239
|
+
* aparta del color más repetido y entra como «tinta» (medido: la «=» de la maqueta daba el coral del degradado y
|
|
240
|
+
* no el granate de su signo).
|
|
241
|
+
*/
|
|
242
|
+
const lejos = Math.max(...tinta.map((p) => distancia(p, fondo)));
|
|
243
|
+
medido.colorTexto = hex(moda(tinta.filter((p) => distancia(p, fondo) >= Math.max(TINTA, lejos * 0.6))));
|
|
244
|
+
medido.alturaDeLetra = Math.round(((ty1 - ty0 + 1) / img.ancho) * 1000) / 1000;
|
|
245
|
+
medido.letra = letraDe(medido.alturaDeLetra);
|
|
246
|
+
const centro = (tx0 + tx1) / 2;
|
|
247
|
+
const tercio = (ix1 - ix0) / 3;
|
|
248
|
+
medido.alineacion = (centro < ix0 + tercio ? "izquierda" : centro > ix1 - tercio ? "derecha" : "centro");
|
|
249
|
+
/**
|
|
250
|
+
* Recortado solo en lo que NO pinta fondo propio (una etiqueta de texto): en un botón, un degradado del fondo es
|
|
251
|
+
* «tinta» que llega al borde (medido: la «=» de la calculadora) y el texto de un botón no es lo que se corta.
|
|
252
|
+
*/
|
|
253
|
+
if (!conFondo)
|
|
254
|
+
medido.recortado = tocaArriba || tocaAbajo;
|
|
255
|
+
}
|
|
256
|
+
return medido;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Una pantalla entera MEDIDA, en el mismo esquema que `compararDescripciones` entiende: las filas que se le dan, y
|
|
260
|
+
* cada control con su estilo medido y su centro en fracción de la pantalla (con eso se empareja).
|
|
261
|
+
*/
|
|
262
|
+
export function pantallaMedida(img, filas) {
|
|
263
|
+
return {
|
|
264
|
+
filas: filas.map((fila) => ({
|
|
265
|
+
controles: fila.map((c) => ({
|
|
266
|
+
texto: c.texto,
|
|
267
|
+
centro: { x: (c.caja.x + c.caja.ancho / 2) / img.ancho, y: (c.caja.y + c.caja.alto / 2) / img.alto },
|
|
268
|
+
...medirControl(img, c.caja),
|
|
269
|
+
})),
|
|
270
|
+
})),
|
|
271
|
+
extras: [],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
// ---------------------------------------------------------------- los bloques anchos (cabecera, visor, panel)
|
|
275
|
+
/** Los bloques que no están dentro de otro: la cabecera y no su título, el visor y no sus filas. Pura. */
|
|
276
|
+
export function bloquesDeFuera(cajas) {
|
|
277
|
+
const dentro = (a, b) => a !== b && a.x >= b.x - 2 && a.y >= b.y - 2 && a.x + a.ancho <= b.x + b.ancho + 2 && a.y + a.alto <= b.y + b.alto + 2;
|
|
278
|
+
return cajas.filter((a) => !cajas.some((b) => dentro(a, b) && !(dentro(b, a) && cajas.indexOf(b) > cajas.indexOf(a))));
|
|
279
|
+
}
|
|
280
|
+
const porciento = (x) => `${Math.round(x * 100)} %`;
|
|
281
|
+
/** El color más repetido dentro de una caja: el del fondo del bloque, sea propio o el de lo que tiene detrás. */
|
|
282
|
+
function colorDominante(img, caja) {
|
|
283
|
+
const colores = [];
|
|
284
|
+
const paso = Math.max(1, Math.floor(Math.sqrt((caja.ancho * caja.alto) / 4000)));
|
|
285
|
+
for (let y = Math.round(caja.y); y < caja.y + caja.alto; y += paso)
|
|
286
|
+
for (let x = Math.round(caja.x); x < caja.x + caja.ancho; x += paso)
|
|
287
|
+
colores.push(pixel(img, x, y));
|
|
288
|
+
return moda(colores);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Compara el COLOR y la FORMA de los bloques anchos, emparejados por su altura relativa dentro de la franja útil de
|
|
292
|
+
* cada pantalla (la maqueta y el aparato no tienen la misma proporción). Pura. Existe por la calculadora: una cabecera
|
|
293
|
+
* amarilla donde la maqueta tiene la del fondo oscuro no la veía nadie, porque solo se comparaban los botones.
|
|
294
|
+
*
|
|
295
|
+
* Solo dice DIFERENCIAS de lo emparejado: un bloque sin pareja no es noticia, porque los dos lados no parten igual
|
|
296
|
+
* (el aparato puede tener un bloque por fila de teclas donde la maqueta tiene un solo panel).
|
|
297
|
+
*/
|
|
298
|
+
export function compararBloques(maqueta, aparato) {
|
|
299
|
+
const situar = (b) => bloquesDeFuera(b.bloques)
|
|
300
|
+
.slice()
|
|
301
|
+
.sort((x, y) => x.y - y.y)
|
|
302
|
+
.map((caja) => {
|
|
303
|
+
const alto = Math.max(1, b.util.abajo - b.util.arriba);
|
|
304
|
+
return { caja, y0: (caja.y - b.util.arriba) / alto, y1: (caja.y + caja.alto - b.util.arriba) / alto, color: colorDominante(b.img, caja), forma: medirControl(b.img, caja).forma };
|
|
305
|
+
});
|
|
306
|
+
const ms = situar(maqueta);
|
|
307
|
+
const as = situar(aparato);
|
|
308
|
+
const usados = new Set();
|
|
309
|
+
const salida = [];
|
|
310
|
+
for (const a of as) {
|
|
311
|
+
let mejor;
|
|
312
|
+
ms.forEach((m, i) => {
|
|
313
|
+
const solape = Math.min(a.y1, m.y1) - Math.max(a.y0, m.y0);
|
|
314
|
+
if (!usados.has(i) && solape > 0 && (mejor === undefined || solape > mejor.solape))
|
|
315
|
+
mejor = { i, solape };
|
|
316
|
+
});
|
|
317
|
+
if (mejor === undefined || mejor.solape < (a.y1 - a.y0) * 0.4)
|
|
318
|
+
continue;
|
|
319
|
+
usados.add(mejor.i);
|
|
320
|
+
const m = ms[mejor.i];
|
|
321
|
+
const donde = a.y0 < 0.12 ? "de arriba del todo" : `que va del ${porciento(Math.max(0, a.y0))} al ${porciento(Math.min(1, a.y1))} del alto`;
|
|
322
|
+
if (a.color !== undefined && m.color !== undefined && Math.hypot(a.color[0] - m.color[0], a.color[1] - m.color[1], a.color[2] - m.color[2]) > 90) {
|
|
323
|
+
salida.push(`El bloque ${donde} es de color ${hex(a.color)}; en la maqueta, ${hex(m.color)}.`);
|
|
324
|
+
}
|
|
325
|
+
const proporcion = (a.y1 - a.y0) / Math.max(0.001, m.y1 - m.y0);
|
|
326
|
+
if (a.forma !== undefined && m.forma !== undefined && a.forma !== m.forma && proporcion > 0.6 && proporcion < 1.6) {
|
|
327
|
+
salida.push(`El bloque ${donde} tiene forma ${a.forma}; en la maqueta, ${m.forma}.`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return salida;
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=estiloMedido.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estiloMedido.js","sourceRoot":"","sources":["../../src/core/estiloMedido.ts"],"names":[],"mappings":"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"}
|