Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.4/schema.json",
"$schema": "https://biomejs.dev/schemas/2.4.2/schema.json",
"assist": {
"actions": {
"source": {
Expand Down Expand Up @@ -51,6 +51,7 @@
"useNamingConvention": {
"level": "warn",
"options": {
"strictCase": false,
"conventions": [
{
"selector": { "kind": "variable" },
Expand All @@ -75,7 +76,8 @@
"level": "warn",
"options": {
"requireAscii": true,
"filenameCases": ["PascalCase", "camelCase"]
"strictCase": false,
"filenameCases": ["PascalCase", "camelCase", "kebab-case"]
}
}
},
Expand Down
6 changes: 3 additions & 3 deletions src/i18n/StringManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import stringsFr from "./strings_fr.json";
// These type aliases exist solely so TypeScript verifies that both language files
// share identical key structures. If a key is added to one file but not the
// other, a type error will appear here before the app is ever run.
type _EnMatchesFr = typeof stringsEn extends typeof stringsFr ? true : never;
type _FrMatchesEn = typeof stringsFr extends typeof stringsEn ? true : never;
type EnMatchesFr = typeof stringsEn extends typeof stringsFr ? true : never;
type FrMatchesEn = typeof stringsFr extends typeof stringsEn ? true : never;
// Force evaluation (unused types are not checked without a reference).
declare const _parity: _EnMatchesFr & _FrMatchesEn;
declare const _parity: EnMatchesFr & FrMatchesEn;

/**
* Manages all localized strings for the simulation
Expand Down
4 changes: 2 additions & 2 deletions src/screen-name/graph/ConfigurableGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,9 @@ export default class ConfigurableGraph extends Node {
this.graphContentNode.visible = visible;
this.headerBar.visible = visible;
this.titlePanel.visible = visible;
resizeHandles.forEach((handle) => {
for (const handle of resizeHandles) {
handle.visible = visible;
});
}
};
this.graphVisibleProperty.link(graphVisibleListener);

Expand Down
50 changes: 38 additions & 12 deletions src/screen-name/graph/GraphDataManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export default class GraphDataManager {
const result: Vector2[] = new Array(this.dataSize);
for (let i = 0; i < this.dataSize; i++) {
const idx = (this.dataHead - this.dataSize + i + this.maxDataPoints) % this.maxDataPoints;
// biome-ignore lint/style/noNonNullAssertion: index is within dataSize, slot is always written
result[i] = this.dataBuf[idx]!;
}
return result;
Expand Down Expand Up @@ -109,11 +110,20 @@ export default class GraphDataManager {
this.yMax = -Infinity;
for (let i = 0; i < this.dataSize; i++) {
const idx = (this.dataHead - this.dataSize + i + this.maxDataPoints) % this.maxDataPoints;
// biome-ignore lint/style/noNonNullAssertion: index is within dataSize, slot is always written
const p = this.dataBuf[idx]!;
if (p.x < this.xMin) this.xMin = p.x;
if (p.x > this.xMax) this.xMax = p.x;
if (p.y < this.yMin) this.yMin = p.y;
if (p.y > this.yMax) this.yMax = p.y;
if (p.x < this.xMin) {
this.xMin = p.x;
}
if (p.x > this.xMax) {
this.xMax = p.x;
}
if (p.y < this.yMin) {
this.yMin = p.y;
}
if (p.y > this.yMax) {
this.yMax = p.y;
}
}
}

Expand All @@ -123,10 +133,18 @@ export default class GraphDataManager {
* axis extreme (the common case — a buffer that has never filled — never rescans).
*/
private updateMinMaxIncremental(x: number, y: number, evicted: Vector2 | undefined): void {
if (x < this.xMin) this.xMin = x;
if (x > this.xMax) this.xMax = x;
if (y < this.yMin) this.yMin = y;
if (y > this.yMax) this.yMax = y;
if (x < this.xMin) {
this.xMin = x;
}
if (x > this.xMax) {
this.xMax = x;
}
if (y < this.yMin) {
this.yMin = y;
}
if (y > this.yMax) {
this.yMax = y;
}
if (
evicted !== undefined &&
(evicted.x <= this.xMin || evicted.x >= this.xMax || evicted.y <= this.yMin || evicted.y >= this.yMax)
Expand Down Expand Up @@ -190,10 +208,18 @@ export default class GraphDataManager {
if (Number.isFinite(x) && Number.isFinite(y)) {
const evicted = this.writePoint(x, y);
// Inline incremental update (avoids function-call overhead in tight loop).
if (x < this.xMin) this.xMin = x;
if (x > this.xMax) this.xMax = x;
if (y < this.yMin) this.yMin = y;
if (y > this.yMax) this.yMax = y;
if (x < this.xMin) {
this.xMin = x;
}
if (x > this.xMax) {
this.xMax = x;
}
if (y < this.yMin) {
this.yMin = y;
}
if (y > this.yMax) {
this.yMax = y;
}
if (
evicted !== undefined &&
(evicted.x <= this.xMin || evicted.x >= this.xMax || evicted.y <= this.yMin || evicted.y >= this.yMax)
Expand Down
4 changes: 2 additions & 2 deletions src/screen-name/view/AutoTrackerNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,10 @@ export class AutoTrackerNode extends Node {
}
})
.catch((err: unknown) => {
// biome-ignore lint/suspicious/noConsole: error logging for tracker init failure
console.error("AutoTracker: failed to initialise OpenCV tracker:", err);
if (this.initVersion === capturedVersion) {
const message =
err instanceof Error ? err.message : "Tracking initialisation failed. Try again.";
const message = err instanceof Error ? err.message : "Tracking initialisation failed. Try again.";
this.errorText.string = message;
this.errorText.visible = true;
this.hintText.visible = true;
Expand Down
1 change: 1 addition & 0 deletions src/screen-name/view/DataTableNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ export class DataTableNode extends Panel {
// or colour change) and an incremental row-append on data-only changes
// (new points added to existing tracks). During auto-tracking this fires
// ~30 times/s, so avoiding unnecessary full DOM rebuilds is critical.
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: intentionally complex — must handle structural and incremental updates efficiently
const rebuildTable = () => {
const tracks = model.tracksProperty.value;
const unit = unitProperty.value;
Expand Down
1 change: 1 addition & 0 deletions src/screen-name/view/VideoPlayerNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class VideoPlayerNode extends Node {
const isPlayingListener = (isPlaying: boolean) => {
if (isPlaying) {
this.videoElement.play().catch((err: unknown) => {
// biome-ignore lint/suspicious/noConsole: error logging for video playback failure
console.error("Video playback failed:", err);
model.isPlayingProperty.value = false;
});
Expand Down
9 changes: 8 additions & 1 deletion src/tracking/OpenCVTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,15 @@ interface MinMaxLocResult {
/** Typed surface of the OpenCV.js module used by this tracker. */
interface Cv {
// Constructors
// biome-ignore lint/style/useNamingConvention: OpenCV API uses PascalCase for constructor properties
readonly Mat: new () => CvMat;
readonly Rect: new (x: number, y: number, width: number, height: number) => CvRect;
// biome-ignore lint/style/useNamingConvention: OpenCV API uses PascalCase for constructor properties
readonly Rect: new (
x: number,
y: number,
width: number,
height: number,
) => CvRect;

// Factory from browser ImageData
matFromImageData(imageData: ImageData): CvMat;
Expand Down
3 changes: 3 additions & 0 deletions vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,12 @@ export default defineConfig({
registerType: "autoUpdate",
manifest: {
name: "trackLab",
// biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys
short_name: "trackLab",
description: "trackLab simulation",
// biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys
theme_color: "#1a1a2e",
// biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys
background_color: "#000000",
display: "standalone",
orientation: "landscape",
Expand Down