@lotics/cli 0.244.0 → 0.246.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/dist/probe_page.js +87 -31
- package/dist/src/cli.js +30 -9
- package/docs/cli_reference.md +2 -2
- package/package.json +1 -1
package/dist/probe_page.js
CHANGED
|
@@ -732,6 +732,15 @@ var __loticsProbe = (() => {
|
|
|
732
732
|
});
|
|
733
733
|
return { total: briefs.length, fold, below: briefs.filter((one) => one.bottom > fold) };
|
|
734
734
|
}
|
|
735
|
+
function openPanel(body) {
|
|
736
|
+
return within(body, '[role="tabpanel"]').find(onScreen);
|
|
737
|
+
}
|
|
738
|
+
function headings(el) {
|
|
739
|
+
return within(el, ".lotics-section-heading").filter(onScreen).flatMap((heading) => {
|
|
740
|
+
const title = within(heading, "h1, h2, h3, h4, h5, h6")[0];
|
|
741
|
+
return title === void 0 ? [] : [words2(title)];
|
|
742
|
+
});
|
|
743
|
+
}
|
|
735
744
|
function briefRepeats(root = document.body) {
|
|
736
745
|
let total = 0;
|
|
737
746
|
const repeated = surfaces(root).flatMap((surface) => {
|
|
@@ -741,10 +750,34 @@ var __loticsProbe = (() => {
|
|
|
741
750
|
within(surface.root, "*").filter((el) => el.childElementCount === 0 && !surface.body.contains(el) && el.closest('button, [role="button"], [role="tab"]') === null && onScreen(el)).map((el) => said(words2(el))).filter((text) => text.length > 1)
|
|
742
751
|
);
|
|
743
752
|
const values = within(brief, ".lotics-record-facts__value").filter(onScreen);
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
753
|
+
const parts = headings(brief);
|
|
754
|
+
total += values.length + parts.length;
|
|
755
|
+
const panel = openPanel(surface.body);
|
|
756
|
+
const open = new Set(panel === void 0 ? [] : headings(panel).map(said));
|
|
757
|
+
return [
|
|
758
|
+
...values.flatMap((value) => {
|
|
759
|
+
const text = said(words2(value));
|
|
760
|
+
return text !== "" && head.has(text) ? [{ record: surface.name, value: words2(value), where: "head" }] : [];
|
|
761
|
+
}),
|
|
762
|
+
...parts.flatMap((part) => open.has(said(part)) ? [{ record: surface.name, value: part, where: "tab" }] : [])
|
|
763
|
+
];
|
|
764
|
+
});
|
|
765
|
+
return { total, repeated };
|
|
766
|
+
}
|
|
767
|
+
function actRepeats(root = document.body) {
|
|
768
|
+
let total = 0;
|
|
769
|
+
const repeated = surfaces(root).flatMap((surface) => {
|
|
770
|
+
const panel = openPanel(surface.body);
|
|
771
|
+
if (panel === void 0) return [];
|
|
772
|
+
const verbs = new Set(
|
|
773
|
+
within(surface.root, PRIMARY).filter((act) => !surface.body.contains(act) && onScreen(act)).map((act) => said(words2(act))).filter((text) => text !== "")
|
|
774
|
+
);
|
|
775
|
+
const waiting = within(panel, ".lotics-act-card").filter((card) => card.querySelector(".lotics-act-card__fold") === null && onScreen(card));
|
|
776
|
+
const firsts = waiting.filter((card, at) => waiting.findIndex((other) => other.parentElement === card.parentElement) === at);
|
|
777
|
+
total += firsts.length;
|
|
778
|
+
return firsts.flatMap((card) => {
|
|
779
|
+
const title = words2(card.querySelector(".lotics-act-card__title"));
|
|
780
|
+
return title !== "" && verbs.has(said(title)) ? [{ record: surface.name, act: title }] : [];
|
|
748
781
|
});
|
|
749
782
|
});
|
|
750
783
|
return { total, repeated };
|
|
@@ -755,7 +788,7 @@ var __loticsProbe = (() => {
|
|
|
755
788
|
const tabs = within(surface.body, '[role="tab"]').filter(onScreen);
|
|
756
789
|
total += tabs.length;
|
|
757
790
|
const open = tabs.find((tab) => tab.getAttribute("aria-selected") === "true");
|
|
758
|
-
const panel =
|
|
791
|
+
const panel = openPanel(surface.body);
|
|
759
792
|
const bare = open !== void 0 && panel !== void 0 && within(panel, ".lotics-section").filter(onScreen).length === 0;
|
|
760
793
|
return bare ? [{ record: surface.name, tab: words2(open).replace(/\d+$/, "").trim() }] : [];
|
|
761
794
|
});
|
|
@@ -769,7 +802,7 @@ var __loticsProbe = (() => {
|
|
|
769
802
|
const skipTag = /^(SCRIPT|STYLE|TITLE|META|LINK|NOSCRIPT|TEMPLATE)$/;
|
|
770
803
|
const chrome = 'nav, [role="banner"]';
|
|
771
804
|
const recordSurface = '.lotics-record-page, [role="dialog"]';
|
|
772
|
-
const
|
|
805
|
+
const headings2 = 'h1, h2, h3, h4, h5, h6, [role="heading"]';
|
|
773
806
|
const noteFloor = 3;
|
|
774
807
|
const formFloor = 3;
|
|
775
808
|
const hueStep = 30;
|
|
@@ -778,7 +811,7 @@ var __loticsProbe = (() => {
|
|
|
778
811
|
const sameEdge = 8;
|
|
779
812
|
const words5 = (el) => el === null ? "" : (el.textContent || "").trim().slice(0, 40);
|
|
780
813
|
const surfaces2 = within(root, recordSurface).filter(onScreen);
|
|
781
|
-
const called2 = (el) => el.matches(
|
|
814
|
+
const called2 = (el) => el.matches(headings2) ? words5(el) || "the section" : el.matches(recordSurface) ? words5(el.querySelector(".lotics-record-page__heading, h1, h2")) || "the record" : "the screen";
|
|
782
815
|
const rules = [];
|
|
783
816
|
const primary = '[data-variant="primary"]';
|
|
784
817
|
const acts = within(root, primary).filter(
|
|
@@ -791,7 +824,7 @@ var __loticsProbe = (() => {
|
|
|
791
824
|
const surface = act.closest(recordSurface) ?? page;
|
|
792
825
|
let titles = titled.get(surface);
|
|
793
826
|
if (titles === void 0) {
|
|
794
|
-
titles = within(surface,
|
|
827
|
+
titles = within(surface, headings2).filter(onScreen);
|
|
795
828
|
titled.set(surface, titles);
|
|
796
829
|
}
|
|
797
830
|
let owner = surface;
|
|
@@ -1144,11 +1177,11 @@ var __loticsProbe = (() => {
|
|
|
1144
1177
|
const tag = /^H([1-6])$/.exec(el.tagName);
|
|
1145
1178
|
return tag === null ? 2 : Number(tag[1]);
|
|
1146
1179
|
};
|
|
1147
|
-
const
|
|
1180
|
+
const headings2 = within(root, HEADING2).filter(
|
|
1148
1181
|
(el) => onScreen(el) && el.closest(NAVIGATION) === null && words3(el) !== ""
|
|
1149
1182
|
);
|
|
1150
|
-
const shallowest =
|
|
1151
|
-
const pageTitle =
|
|
1183
|
+
const shallowest = headings2.reduce((top, el) => Math.min(top, rank(el)), Infinity);
|
|
1184
|
+
const pageTitle = headings2.find((el) => rank(el) === shallowest);
|
|
1152
1185
|
const headerRow = (heading) => {
|
|
1153
1186
|
const own = words3(heading);
|
|
1154
1187
|
let row = heading;
|
|
@@ -1162,7 +1195,7 @@ var __loticsProbe = (() => {
|
|
|
1162
1195
|
let sections = 0;
|
|
1163
1196
|
let badged = 0;
|
|
1164
1197
|
const badges = [];
|
|
1165
|
-
for (const heading of
|
|
1198
|
+
for (const heading of headings2) {
|
|
1166
1199
|
if (heading === pageTitle) continue;
|
|
1167
1200
|
sections += 1;
|
|
1168
1201
|
const mark = graphicIn(headerRow(heading));
|
|
@@ -1366,18 +1399,18 @@ var __loticsProbe = (() => {
|
|
|
1366
1399
|
const row = ".lotics-table__row";
|
|
1367
1400
|
return within(root, table).filter((register) => onScreen(register) && !register.hasAttribute("data-stacked")).map((register) => {
|
|
1368
1401
|
const rows = Array.from(register.querySelectorAll(row)).filter((one) => inside(one, register, table) && onScreen(one) && stored(one));
|
|
1369
|
-
const
|
|
1402
|
+
const headings2 = Array.from(register.querySelectorAll(".lotics-table__column")).filter((heading) => inside(heading, register, table));
|
|
1370
1403
|
const cellsOf = (one) => {
|
|
1371
1404
|
const box = Array.from(one.querySelectorAll(".lotics-table__cells")).find((cells) => inside(cells, one, row));
|
|
1372
1405
|
return box === void 0 ? [] : Array.from(box.children).filter((cell) => cell.classList.contains("lotics-table__cell"));
|
|
1373
1406
|
};
|
|
1374
1407
|
const gutterOf = (one) => Array.from(one.querySelectorAll(".lotics-table__trailing")).find((gutter) => inside(gutter, one, row));
|
|
1375
1408
|
const grid = rows.map(cellsOf);
|
|
1376
|
-
const columns = Math.max(
|
|
1409
|
+
const columns = Math.max(headings2.length, ...grid.map((cells) => cells.length), 0);
|
|
1377
1410
|
const slots = Array.from({ length: columns }, (_, index) => ({
|
|
1378
|
-
name: words4(
|
|
1411
|
+
name: words4(headings2[index]) || `column ${index + 1}`,
|
|
1379
1412
|
kind: "column",
|
|
1380
|
-
heading:
|
|
1413
|
+
heading: headings2[index],
|
|
1381
1414
|
cells: grid.map((cells) => cells[index])
|
|
1382
1415
|
}));
|
|
1383
1416
|
const gutters = rows.map(gutterOf);
|
|
@@ -1388,19 +1421,19 @@ var __loticsProbe = (() => {
|
|
|
1388
1421
|
function ariaRegisters(root) {
|
|
1389
1422
|
const table = '[role="table"], [role="grid"]';
|
|
1390
1423
|
return within(root, table).filter(onScreen).map((register) => {
|
|
1391
|
-
const
|
|
1424
|
+
const headings2 = Array.from(register.querySelectorAll('[role="columnheader"]')).filter((heading) => inside(heading, register, table)).map(words4);
|
|
1392
1425
|
const grid = Array.from(register.querySelectorAll('[role="row"]')).filter((one) => inside(one, register, table) && onScreen(one) && stored(one)).map((one) => ({
|
|
1393
1426
|
row: one,
|
|
1394
1427
|
cells: Array.from(one.querySelectorAll('[role="cell"], [role="gridcell"]')).filter(
|
|
1395
1428
|
(cell) => inside(cell, one, '[role="row"]')
|
|
1396
1429
|
)
|
|
1397
1430
|
})).filter((one) => one.cells.length > 0);
|
|
1398
|
-
const columns = Math.max(
|
|
1431
|
+
const columns = Math.max(headings2.length, ...grid.map((one) => one.cells.length), 0);
|
|
1399
1432
|
return {
|
|
1400
1433
|
root: register,
|
|
1401
1434
|
rows: grid.map((one) => one.row),
|
|
1402
1435
|
slots: Array.from({ length: columns }, (_, index) => ({
|
|
1403
|
-
name:
|
|
1436
|
+
name: headings2[index] || `column ${index + 1}`,
|
|
1404
1437
|
kind: "column",
|
|
1405
1438
|
cells: grid.map((one) => one.cells[index])
|
|
1406
1439
|
}))
|
|
@@ -1497,9 +1530,15 @@ var __loticsProbe = (() => {
|
|
|
1497
1530
|
);
|
|
1498
1531
|
return Math.max(0, width - drawn);
|
|
1499
1532
|
}
|
|
1500
|
-
function
|
|
1501
|
-
const
|
|
1502
|
-
|
|
1533
|
+
function slotGaps(register) {
|
|
1534
|
+
const first = register.slots.map((slot) => slot.cells[0]).filter((cell) => cell !== void 0);
|
|
1535
|
+
const boxes = first.map((cell) => cell.getBoundingClientRect()).sort((a, b) => a.left - b.left);
|
|
1536
|
+
if (boxes.length < 2) return { gap: 0, beyond: 0 };
|
|
1537
|
+
const drawn = boxes.slice(1).map((box, index) => Math.max(0, box.left - boxes[index].right));
|
|
1538
|
+
const parent = first[0].parentElement;
|
|
1539
|
+
const declared = parent === null ? Number.NaN : Number.parseFloat(getComputedStyle(parent).columnGap);
|
|
1540
|
+
const gap = Number.isFinite(declared) ? declared : Math.min(...drawn);
|
|
1541
|
+
return { gap: Math.round(gap), beyond: drawn.reduce((sum, one) => sum + Math.max(0, one - gap), 0) };
|
|
1503
1542
|
}
|
|
1504
1543
|
function shedWithRoom(root = document.body) {
|
|
1505
1544
|
let total = 0;
|
|
@@ -1508,8 +1547,8 @@ var __loticsProbe = (() => {
|
|
|
1508
1547
|
const shed = shedOf(register.root);
|
|
1509
1548
|
if (shed.length === 0 || register.rows.length === 0) continue;
|
|
1510
1549
|
total += shed.length;
|
|
1511
|
-
const
|
|
1512
|
-
const
|
|
1550
|
+
const { gap, beyond } = slotGaps(register);
|
|
1551
|
+
const unused = Math.round(register.slots.reduce((sum, slot) => sum + spare(slot), 0) + beyond);
|
|
1513
1552
|
for (const column of shed) if (column.width + gap <= unused) found.push({ ...column, gap, unused });
|
|
1514
1553
|
}
|
|
1515
1554
|
return { total, shed: found };
|
|
@@ -1668,7 +1707,7 @@ var __loticsProbe = (() => {
|
|
|
1668
1707
|
walk(root);
|
|
1669
1708
|
}
|
|
1670
1709
|
const dates = leaves.filter((leaf) => leaf.date);
|
|
1671
|
-
const
|
|
1710
|
+
const headings2 = leaves.filter((leaf) => !leaf.date);
|
|
1672
1711
|
const leads = (leaf) => !leaves.some(
|
|
1673
1712
|
(other) => other.left < leaf.left && other.top < leaf.bottom && other.bottom > leaf.top
|
|
1674
1713
|
);
|
|
@@ -1694,7 +1733,7 @@ var __loticsProbe = (() => {
|
|
|
1694
1733
|
grouped += 1;
|
|
1695
1734
|
if (runs.length < 3) {
|
|
1696
1735
|
const top = Math.min(...column.items.map((leaf) => leaf.top));
|
|
1697
|
-
const over =
|
|
1736
|
+
const over = headings2.filter((label) => label.top < top && top - label.top <= 360 && label.left < column.right && label.right > column.left).sort((a, b) => b.top - a.top)[0];
|
|
1698
1737
|
runs.push(
|
|
1699
1738
|
`${over === void 0 ? "(unnamed)" : over.text}: ${column.items.length} rows over ${days.size} days, the date repeated per row`
|
|
1700
1739
|
);
|
|
@@ -1811,12 +1850,12 @@ var __loticsProbe = (() => {
|
|
|
1811
1850
|
const navFirst = nav === null ? void 0 : Array.from(nav.querySelectorAll('a[href], [role="link"]')).filter(
|
|
1812
1851
|
(item) => onScreen(item) && (item.textContent || "").trim() !== ""
|
|
1813
1852
|
)[0];
|
|
1814
|
-
const
|
|
1853
|
+
const headings2 = within(root, "h1, h2, h3, h4, h5, h6").filter(
|
|
1815
1854
|
(el) => onScreen(el) && el.closest('nav, [role="banner"]') === null && (el.textContent || "").trim() !== ""
|
|
1816
1855
|
);
|
|
1817
|
-
const title =
|
|
1856
|
+
const title = headings2[0];
|
|
1818
1857
|
const rank = (el) => Number(el.tagName.slice(1));
|
|
1819
|
-
const heading = title === void 0 ? void 0 :
|
|
1858
|
+
const heading = title === void 0 ? void 0 : headings2.slice(1).find((el) => rank(el) > rank(title));
|
|
1820
1859
|
const primaries = within(root, '[data-variant="primary"]').filter(
|
|
1821
1860
|
(el) => onScreen(el) && el.closest('nav, [role="banner"]') === null
|
|
1822
1861
|
);
|
|
@@ -1987,7 +2026,12 @@ var __loticsProbe = (() => {
|
|
|
1987
2026
|
brief_repeats: {
|
|
1988
2027
|
law: "hierarchy.md",
|
|
1989
2028
|
section: "One fact, one place",
|
|
1990
|
-
fix: "Take
|
|
2029
|
+
fix: "Take it out of the brief: the head already states the value, or the tab open at rest already draws the part, so the brief says it a second time."
|
|
2030
|
+
},
|
|
2031
|
+
act_repeats: {
|
|
2032
|
+
law: "hierarchy.md",
|
|
2033
|
+
section: "One fact, one place",
|
|
2034
|
+
fix: "Draw the head's act in its queue's card by its words and outcomes alone (`ActCard` `carried`): its verb, due day and refusal are the head's."
|
|
1991
2035
|
},
|
|
1992
2036
|
empty_tab: {
|
|
1993
2037
|
law: "hierarchy.md",
|
|
@@ -2244,7 +2288,19 @@ var __loticsProbe = (() => {
|
|
|
2244
2288
|
...signature("brief_repeats"),
|
|
2245
2289
|
total: repeats.total,
|
|
2246
2290
|
count: repeats.repeated.length,
|
|
2247
|
-
detail: repeats.repeated.slice(0, 5).map(
|
|
2291
|
+
detail: repeats.repeated.slice(0, 5).map(
|
|
2292
|
+
(one) => one.where === "head" ? `"${one.record}": the brief states "${one.value}", which the head already says` : `"${one.record}": the brief stands "${one.value}", which the tab open at rest draws too`
|
|
2293
|
+
)
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2296
|
+
const acts = actRepeats(surface);
|
|
2297
|
+
if (acts.repeated.length > 0) {
|
|
2298
|
+
findings.push({
|
|
2299
|
+
probe: "act_repeats",
|
|
2300
|
+
...signature("act_repeats"),
|
|
2301
|
+
total: acts.total,
|
|
2302
|
+
count: acts.repeated.length,
|
|
2303
|
+
detail: acts.repeated.slice(0, 5).map((one) => `"${one.record}": the head's act "${one.act}" heads a card in the tab open at rest too`)
|
|
2248
2304
|
});
|
|
2249
2305
|
}
|
|
2250
2306
|
const tabs = emptyTabs(surface);
|