diff --git a/biome.json b/biome.json
index b6c4919..4c8efc5 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/2.4.2/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.4.4/schema.json",
"assist": {
"actions": {
"source": {
@@ -10,13 +10,125 @@
"linter": {
"enabled": true,
"rules": {
- "recommended": true
+ "recommended": true,
+ "nursery": {
+ "recommended": true,
+ "noShadow": "error",
+ "useExplicitType": "warn",
+ "noEqualsToNull": "error",
+ "noReturnAssign": "error",
+ "useArraySortCompare": "error",
+ "useFind": "warn",
+ "useSpread": "warn"
+ },
+ "correctness": {
+ "recommended": true,
+ "noUnusedImports": "error",
+ "noUnusedVariables": "error",
+ "noUnusedPrivateClassMembers": "error",
+ "noUndeclaredVariables": "error",
+ "noUnreachable": "error",
+ "noInvalidUseBeforeDeclaration": "error"
+ },
+ "style": {
+ "recommended": true,
+ "noDefaultExport": "off",
+ "noParameterAssign": "error",
+ "useBlockStatements": "error",
+ "useCollapsedElseIf": "warn",
+ "useConsistentBuiltinInstantiation": "error",
+ "useDefaultParameterLast": "error",
+ "useExplicitLengthCheck": "warn",
+ "useForOf": "warn",
+ "useFragmentSyntax": "warn",
+ "useImportType": "error",
+ "useShorthandAssign": "warn",
+ "useShorthandFunctionType": "warn",
+ "useThrowNewError": "error",
+ "useThrowOnlyError": "error",
+ "noCommonJs": "error",
+ "noExportedImports": "off",
+ "useNamingConvention": {
+ "level": "warn",
+ "options": {
+ "conventions": [
+ {
+ "selector": { "kind": "variable" },
+ "formats": ["camelCase", "CONSTANT_CASE", "PascalCase"]
+ },
+ {
+ "selector": { "kind": "function" },
+ "formats": ["camelCase", "PascalCase"]
+ },
+ {
+ "selector": { "kind": "typeLike" },
+ "formats": ["PascalCase"]
+ },
+ {
+ "selector": { "kind": "enumMember" },
+ "formats": ["CONSTANT_CASE", "PascalCase"]
+ }
+ ]
+ }
+ },
+ "useFilenamingConvention": {
+ "level": "warn",
+ "options": {
+ "requireAscii": true,
+ "filenameCases": ["PascalCase", "camelCase"]
+ }
+ }
+ },
+ "suspicious": {
+ "recommended": true,
+ "noConsole": "warn",
+ "noEmptyBlockStatements": "error",
+ "noExplicitAny": "warn",
+ "useAwait": "error",
+ "useErrorMessage": "error",
+ "useGuardForIn": "error",
+ "useIsArray": "error",
+ "noIrregularWhitespace": "off"
+ },
+ "complexity": {
+ "recommended": true,
+ "noExcessiveCognitiveComplexity": {
+ "level": "warn",
+ "options": {
+ "maxAllowedComplexity": 25
+ }
+ },
+ "noForEach": "warn",
+ "noStaticOnlyClass": "error",
+ "noUselessStringConcat": "error",
+ "noUselessUndefinedInitialization": "error",
+ "noVoid": "error",
+ "useArrowFunction": "warn",
+ "useDateNow": "error",
+ "useFlatMap": "warn",
+ "useSimplifiedLogicExpression": "warn"
+ },
+ "performance": {
+ "recommended": true,
+ "noAccumulatingSpread": "warn",
+ "noBarrelFile": "warn",
+ "noDelete": "warn",
+ "noReExportAll": "warn"
+ },
+ "a11y": {
+ "recommended": true
+ },
+ "security": {
+ "recommended": true,
+ "noGlobalEval": "error"
+ }
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
- "indentWidth": 2
+ "indentWidth": 2,
+ "lineWidth": 120
},
"files": {
"includes": ["**/*.ts", "**/*.js", "**/*.json", "**/*.html", "!dist"]
@@ -24,7 +136,10 @@
"javascript": {
"formatter": {
"quoteStyle": "double",
- "semicolons": "always"
+ "semicolons": "always",
+ "trailingCommas": "all",
+ "arrowParentheses": "always",
+ "bracketSameLine": false
}
}
}
diff --git a/scripts/bouncingBallToSVG.ts b/scripts/bouncingBallToSVG.ts
index e5b0932..e21a2c7 100644
--- a/scripts/bouncingBallToSVG.ts
+++ b/scripts/bouncingBallToSVG.ts
@@ -29,10 +29,7 @@ const FLOOR_WIDTH = 0.8; // stroke-width
* T_n ∝ sqrt(h_n). We normalise so the total "time" = 1.
*/
function buildBounces(): Array<{ tStart: number; tEnd: number; h: number }> {
- const heights = Array.from(
- { length: NUM_BOUNCES },
- (_, n) => INITIAL_HEIGHT * RESTITUTION ** n,
- );
+ const heights = Array.from({ length: NUM_BOUNCES }, (_, n) => INITIAL_HEIGHT * RESTITUTION ** n);
// flight time ∝ sqrt(h)
const durations = heights.map((h) => Math.sqrt(h));
@@ -59,9 +56,7 @@ function computeSnapshots(): Point[] {
// x positions of bounce endpoints (floor contacts) spaced proportionally
// to flight time (= proportional to normalised duration)
- const xContacts: number[] = bounces.map(
- (b) => X_START + b.tStart * (X_END - X_START),
- );
+ const xContacts: number[] = bounces.map((b) => X_START + b.tStart * (X_END - X_START));
xContacts.push(X_END); // final landing
for (let i = 0; i < TOTAL_SNAPSHOTS; i++) {
@@ -70,7 +65,9 @@ function computeSnapshots(): Point[] {
// find which bounce this snapshot falls in
const bounce = bounces.find((b) => tGlobal >= b.tStart && tGlobal < b.tEnd);
- if (!bounce) continue; // shouldn't happen
+ if (!bounce) {
+ continue; // shouldn't happen
+ }
const bounceIdx = bounces.indexOf(bounce);
// local time within this bounce, in [0, 1]
@@ -93,13 +90,9 @@ function computeSnapshots(): Point[] {
return points;
}
-function buildSVG(points: Point[]): string {
- const circles = points
- .map(
- (p) =>
- ` `,
- )
+function buildSvg(snapshots: Point[]): string {
+ const circles = snapshots
+ .map((p) => ` `)
.join("\n");
return `