@johnmorrisdotca/kyogijo-stadiums 0.4.0 → 0.6.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/CHANGELOG.md +133 -0
- package/NOTICE.md +182 -2
- package/README.md +106 -19
- package/dist/annotate.js +1 -1
- package/dist/arenas-entry.d.ts +4 -0
- package/dist/arenas-entry.js +3 -0
- package/dist/arenas.d.ts +125 -0
- package/dist/arenas.data.d.ts +2 -0
- package/dist/arenas.data.js +3763 -0
- package/dist/arenas.js +72 -0
- package/dist/athletics/describe.d.ts +8 -0
- package/dist/athletics/describe.js +41 -0
- package/dist/athletics/events.d.ts +17 -0
- package/dist/athletics/events.js +48 -0
- package/dist/athletics/facilities.d.ts +80 -0
- package/dist/athletics/facilities.js +176 -0
- package/dist/athletics/infield.d.ts +79 -0
- package/dist/athletics/infield.js +166 -0
- package/dist/athletics/layout.d.ts +13 -0
- package/dist/athletics/layout.js +98 -0
- package/dist/athletics/oval.d.ts +57 -0
- package/dist/athletics/oval.js +116 -0
- package/dist/athletics/plan.d.ts +97 -0
- package/dist/athletics/plan.js +355 -0
- package/dist/athletics/races.d.ts +102 -0
- package/dist/athletics/races.js +355 -0
- package/dist/athletics/steeplechase.d.ts +72 -0
- package/dist/athletics/steeplechase.js +196 -0
- package/dist/athletics/stencil.d.ts +13 -0
- package/dist/athletics/stencil.js +85 -0
- package/dist/athletics/track.d.ts +54 -0
- package/dist/athletics/track.js +105 -0
- package/dist/athletics/types.d.ts +77 -0
- package/dist/athletics/types.js +1 -0
- package/dist/athletics-entry.d.ts +17 -0
- package/dist/athletics-entry.js +11 -0
- package/dist/athletics.style.d.ts +16 -0
- package/dist/athletics.style.js +51 -0
- package/dist/atlas-entry.d.ts +6 -2
- package/dist/atlas-entry.js +4 -2
- package/dist/atlas.d.ts +117 -23
- package/dist/atlas.js +197 -12
- package/dist/background.js +2 -1
- package/dist/budo/describe.d.ts +13 -0
- package/dist/budo/describe.js +120 -0
- package/dist/budo/dojo.api.d.ts +64 -0
- package/dist/budo/dojo.api.js +46 -0
- package/dist/budo/dojo.d.ts +72 -0
- package/dist/budo/dojo.js +300 -0
- package/dist/budo/judo.d.ts +61 -0
- package/dist/budo/judo.js +109 -0
- package/dist/budo/karate.d.ts +29 -0
- package/dist/budo/karate.js +80 -0
- package/dist/budo/kendo.d.ts +18 -0
- package/dist/budo/kendo.js +44 -0
- package/dist/budo/kimarite.d.ts +19 -0
- package/dist/budo/kimarite.js +33 -0
- package/dist/budo/kit.d.ts +16 -0
- package/dist/budo/kit.js +24 -0
- package/dist/budo/kyudo.d.ts +28 -0
- package/dist/budo/kyudo.js +66 -0
- package/dist/budo/looks.d.ts +28 -0
- package/dist/budo/looks.js +58 -0
- package/dist/budo/parts.d.ts +32 -0
- package/dist/budo/parts.js +10 -0
- package/dist/budo/plan.d.ts +64 -0
- package/dist/budo/plan.js +139 -0
- package/dist/budo/room.d.ts +133 -0
- package/dist/budo/room.js +111 -0
- package/dist/budo/sumo.d.ts +31 -0
- package/dist/budo/sumo.js +71 -0
- package/dist/budo/tatami.d.ts +55 -0
- package/dist/budo/tatami.js +156 -0
- package/dist/budo/types.d.ts +192 -0
- package/dist/budo/types.js +2 -0
- package/dist/budo-entry.d.ts +22 -0
- package/dist/budo-entry.js +13 -0
- package/dist/budo.board.d.ts +28 -0
- package/dist/budo.board.js +81 -0
- package/dist/budo.score.d.ts +18 -0
- package/dist/budo.score.js +52 -0
- package/dist/budo.style.d.ts +6 -0
- package/dist/budo.style.js +67 -0
- package/dist/charts-entry.d.ts +6 -1
- package/dist/charts-entry.js +3 -0
- package/dist/charts.athletics.d.ts +183 -0
- package/dist/charts.athletics.js +455 -0
- package/dist/charts.baseball.js +1 -1
- package/dist/charts.curling.heat.d.ts +24 -0
- package/dist/charts.curling.heat.js +116 -0
- package/dist/charts.curling.js +14 -3
- package/dist/charts.js +4 -4
- package/dist/charts.pool.d.ts +67 -0
- package/dist/charts.pool.js +76 -0
- package/dist/charts.skating.d.ts +204 -0
- package/dist/charts.skating.js +426 -0
- package/dist/charts.soccer.js +3 -3
- package/dist/charts.types.d.ts +63 -1
- package/dist/colour.d.ts +4 -4
- package/dist/colour.js +4 -4
- package/dist/court.d.ts +85 -2
- package/dist/court.js +102 -7
- package/dist/court.more.d.ts +46 -0
- package/dist/court.more.js +219 -0
- package/dist/courts.style.d.ts +14 -2
- package/dist/courts.style.js +51 -4
- package/dist/crowd.d.ts +164 -0
- package/dist/crowd.draw.d.ts +17 -0
- package/dist/crowd.draw.js +204 -0
- package/dist/crowd.js +480 -0
- package/dist/crowd.park.d.ts +19 -0
- package/dist/crowd.park.js +153 -0
- package/dist/curling.stats.d.ts +271 -0
- package/dist/curling.stats.js +301 -0
- package/dist/draw.d.ts +16 -0
- package/dist/draw.js +462 -54
- package/dist/element-entry.d.ts +3 -1
- package/dist/element-entry.js +2 -1
- package/dist/element.d.ts +13 -2
- package/dist/element.js +79 -4
- package/dist/emblems-source.d.ts +50 -0
- package/dist/emblems-source.js +56 -0
- package/dist/eras.d.ts +3 -1
- package/dist/eras.js +8 -3
- package/dist/features.js +204 -0
- package/dist/field.data.d.ts +16 -0
- package/dist/field.data.js +50 -0
- package/dist/fields.kit.d.ts +2 -2
- package/dist/fields.types.d.ts +24 -4
- package/dist/formations.js +18 -7
- package/dist/formations.sports.d.ts +8 -0
- package/dist/formations.sports.js +251 -0
- package/dist/frames.providers.js +71 -8
- package/dist/geojson.js +3 -0
- package/dist/geometry-entry.d.ts +2 -1
- package/dist/geometry-entry.js +2 -1
- package/dist/geometry.d.ts +20 -0
- package/dist/geometry.js +78 -1
- package/dist/grounds.d.ts +4 -0
- package/dist/grounds.data.js +12 -0
- package/dist/halls.d.ts +65 -0
- package/dist/halls.js +122 -0
- package/dist/hardwood.d.ts +31 -0
- package/dist/hardwood.js +157 -0
- package/dist/heat.js +21 -13
- package/dist/heat.types.d.ts +5 -0
- package/dist/heat.zones.d.ts +4 -2
- package/dist/heat.zones.js +207 -7
- package/dist/homeside.js +24 -0
- package/dist/index.d.ts +30 -4
- package/dist/index.js +18 -2
- package/dist/layers-entry.d.ts +2 -1
- package/dist/layers-entry.js +1 -0
- package/dist/layers.d.ts +2 -1
- package/dist/layers.env.d.ts +12 -1
- package/dist/layers.env.js +36 -4
- package/dist/layers.js +32 -13
- package/dist/layers.types.d.ts +9 -2
- package/dist/leagues/athletics.d.ts +63 -0
- package/dist/leagues/athletics.js +87 -0
- package/dist/leagues/budo.d.ts +196 -0
- package/dist/leagues/budo.js +105 -0
- package/dist/leagues/courts.d.ts +269 -4
- package/dist/leagues/courts.js +155 -1
- package/dist/leagues/hockey.js +41 -19
- package/dist/leagues/skating.d.ts +145 -0
- package/dist/leagues/skating.js +73 -0
- package/dist/leagues/sources.js +41 -0
- package/dist/leagues/types.d.ts +1 -1
- package/dist/leagues-entry.d.ts +4 -2
- package/dist/leagues-entry.js +2 -1
- package/dist/leagues.d.ts +17 -4
- package/dist/leagues.js +246 -5
- package/dist/lineup.codes.d.ts +23 -0
- package/dist/lineup.codes.js +122 -0
- package/dist/logo.d.ts +25 -0
- package/dist/logo.js +47 -0
- package/dist/look.d.ts +3 -3
- package/dist/look.js +39 -6
- package/dist/outline.d.ts +1 -1
- package/dist/outline.js +46 -4
- package/dist/pageant.d.ts +120 -0
- package/dist/pageant.draw.d.ts +21 -0
- package/dist/pageant.draw.js +171 -0
- package/dist/pageant.js +211 -0
- package/dist/pageant.style.d.ts +8 -0
- package/dist/pageant.style.js +42 -0
- package/dist/png.d.ts +8 -1
- package/dist/png.js +21 -1
- package/dist/pointer-entry.d.ts +2 -0
- package/dist/pointer-entry.js +2 -0
- package/dist/pointer.d.ts +113 -0
- package/dist/pointer.js +151 -0
- package/dist/pool.d.ts +176 -0
- package/dist/pool.figures.d.ts +306 -0
- package/dist/pool.figures.js +148 -0
- package/dist/pool.js +304 -0
- package/dist/pool.kit.d.ts +48 -0
- package/dist/pool.kit.js +141 -0
- package/dist/pool.labels.d.ts +20 -0
- package/dist/pool.labels.js +258 -0
- package/dist/pool.race.d.ts +65 -0
- package/dist/pool.race.js +140 -0
- package/dist/pool.replay.d.ts +46 -0
- package/dist/pool.replay.js +127 -0
- package/dist/pool.section.d.ts +13 -0
- package/dist/pool.section.js +83 -0
- package/dist/pool.style.d.ts +20 -0
- package/dist/pool.style.js +169 -0
- package/dist/pool.types.d.ts +145 -0
- package/dist/pool.types.js +3 -0
- package/dist/pool.words.d.ts +13 -0
- package/dist/pool.words.js +101 -0
- package/dist/ranges.names.js +53 -3
- package/dist/replay-entry.d.ts +3 -0
- package/dist/replay-entry.js +2 -0
- package/dist/restyle.js +1 -1
- package/dist/road.draw.js +3 -2
- package/dist/road.js +2 -1
- package/dist/road.types.d.ts +3 -0
- package/dist/rules.d.ts +138 -0
- package/dist/rules.js +511 -0
- package/dist/rules.types.d.ts +4 -0
- package/dist/rules.types.js +64 -0
- package/dist/score.d.ts +3 -0
- package/dist/score.js +93 -6
- package/dist/sheet.d.ts +3 -0
- package/dist/sheet.js +7 -3
- package/dist/situation.d.ts +135 -0
- package/dist/situation.draw.d.ts +34 -0
- package/dist/situation.draw.js +202 -0
- package/dist/situation.js +337 -0
- package/dist/situation.style.d.ts +2 -0
- package/dist/situation.style.js +45 -0
- package/dist/situation.types.d.ts +77 -0
- package/dist/situation.types.js +3 -0
- package/dist/situation.widgets.d.ts +39 -0
- package/dist/situation.widgets.js +129 -0
- package/dist/skating/describe.d.ts +7 -0
- package/dist/skating/describe.js +44 -0
- package/dist/skating/events.d.ts +24 -0
- package/dist/skating/events.js +47 -0
- package/dist/skating/figure.d.ts +24 -0
- package/dist/skating/figure.js +37 -0
- package/dist/skating/long.d.ts +54 -0
- package/dist/skating/long.js +111 -0
- package/dist/skating/parts.d.ts +43 -0
- package/dist/skating/parts.js +40 -0
- package/dist/skating/plan.d.ts +55 -0
- package/dist/skating/plan.js +197 -0
- package/dist/skating/short.d.ts +47 -0
- package/dist/skating/short.js +89 -0
- package/dist/skating/track.d.ts +66 -0
- package/dist/skating/track.js +94 -0
- package/dist/skating/types.d.ts +57 -0
- package/dist/skating/types.js +3 -0
- package/dist/skating-entry.d.ts +17 -0
- package/dist/skating-entry.js +11 -0
- package/dist/skating.style.d.ts +4 -0
- package/dist/skating.style.js +24 -0
- package/dist/strings.d.ts +470 -0
- package/dist/strings.js +674 -13
- package/dist/style.d.ts +2 -0
- package/dist/style.js +19 -2
- package/dist/surfaces/artistic.d.ts +9 -0
- package/dist/surfaces/artistic.js +94 -0
- package/dist/surfaces/athletics.d.ts +16 -0
- package/dist/surfaces/athletics.js +132 -0
- package/dist/surfaces/baseball.js +17 -0
- package/dist/surfaces/basketball.floor.d.ts +27 -0
- package/dist/surfaces/basketball.floor.js +83 -0
- package/dist/surfaces/basketball.gear.d.ts +27 -0
- package/dist/surfaces/basketball.gear.js +90 -0
- package/dist/surfaces/basketball.js +44 -22
- package/dist/surfaces/budo.d.ts +6 -0
- package/dist/surfaces/budo.js +104 -0
- package/dist/surfaces/curling.d.ts +16 -0
- package/dist/surfaces/curling.fold.d.ts +67 -0
- package/dist/surfaces/curling.fold.js +107 -0
- package/dist/surfaces/curling.js +37 -3
- package/dist/surfaces/dive.d.ts +9 -0
- package/dist/surfaces/dive.js +128 -0
- package/dist/surfaces/field.d.ts +7 -2
- package/dist/surfaces/field.js +15 -9
- package/dist/surfaces/football.js +7 -0
- package/dist/surfaces/hockey.js +4 -2
- package/dist/surfaces/net.d.ts +2 -1
- package/dist/surfaces/net.js +160 -15
- package/dist/surfaces/polo.d.ts +12 -0
- package/dist/surfaces/polo.js +159 -0
- package/dist/surfaces/pool.d.ts +27 -0
- package/dist/surfaces/pool.js +198 -0
- package/dist/surfaces/skating.d.ts +6 -0
- package/dist/surfaces/skating.js +62 -0
- package/dist/surfaces/soccer.js +2 -1
- package/dist/surfaces/surface.d.ts +76 -0
- package/dist/surfaces/venue.d.ts +15 -0
- package/dist/surfaces/venue.js +95 -0
- package/dist/target-entry.d.ts +2 -0
- package/dist/target-entry.js +2 -0
- package/dist/target.d.ts +200 -0
- package/dist/target.js +525 -0
- package/dist/team.common.d.ts +1 -1
- package/dist/team.common.js +3 -3
- package/dist/team.formation.d.ts +3 -1
- package/dist/team.formation.js +3 -3
- package/dist/team.layers.d.ts +2 -2
- package/dist/team.layers.js +4 -1
- package/dist/team.lineup.d.ts +27 -0
- package/dist/team.lineup.js +207 -0
- package/dist/team.network.js +6 -5
- package/dist/team.shape.js +5 -5
- package/dist/team.types.d.ts +40 -1
- package/dist/tenants.d.ts +77 -0
- package/dist/tenants.data.d.ts +8 -0
- package/dist/tenants.data.js +1793 -0
- package/dist/tenants.js +46 -0
- package/dist/turn-entry.d.ts +12 -0
- package/dist/turn-entry.js +7 -0
- package/dist/turn.camera.d.ts +116 -0
- package/dist/turn.camera.js +184 -0
- package/dist/turn.dom.d.ts +40 -0
- package/dist/turn.dom.js +353 -0
- package/dist/turn.kit.d.ts +86 -0
- package/dist/turn.kit.js +110 -0
- package/dist/turn.markup.d.ts +48 -0
- package/dist/turn.markup.js +108 -0
- package/dist/turn.model.d.ts +78 -0
- package/dist/turn.model.js +91 -0
- package/dist/turn.style.d.ts +5 -0
- package/dist/turn.style.js +56 -0
- package/dist/types.d.ts +221 -20
- package/dist/units.d.ts +1 -1
- package/dist/units.js +22 -1
- package/dist/uprights.board.d.ts +17 -0
- package/dist/uprights.board.js +59 -0
- package/dist/uprights.budo.d.ts +17 -0
- package/dist/uprights.budo.js +87 -0
- package/dist/uprights.d.ts +37 -0
- package/dist/uprights.fields.d.ts +32 -0
- package/dist/uprights.fields.js +172 -0
- package/dist/uprights.goal.d.ts +49 -0
- package/dist/uprights.goal.js +69 -0
- package/dist/uprights.js +169 -0
- package/dist/uprights.more.d.ts +7 -0
- package/dist/uprights.more.js +183 -0
- package/dist/uprights.net.d.ts +12 -0
- package/dist/uprights.net.js +109 -0
- package/dist/uprights.netkit.d.ts +28 -0
- package/dist/uprights.netkit.js +67 -0
- package/dist/uprights.pools.d.ts +8 -0
- package/dist/uprights.pools.js +190 -0
- package/dist/uprights.rinks.d.ts +27 -0
- package/dist/uprights.rinks.js +106 -0
- package/dist/uprights.track.d.ts +50 -0
- package/dist/uprights.track.js +246 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/zones-entry.d.ts +2 -0
- package/dist/zones-entry.js +2 -0
- package/package.json +56 -3
package/dist/charts.js
CHANGED
|
@@ -218,7 +218,7 @@ export function nbaShotChart(shots, options = {}) {
|
|
|
218
218
|
const end = options.end === "left" ? "left" : "right";
|
|
219
219
|
// A shot chart puts every shot at the basket it was taken at; a frame fixed to the court says where each one is.
|
|
220
220
|
const shooter = frame.ends === "shooter";
|
|
221
|
-
const data = shots.map((s) => clean({ x: s.x, y: s.y, outcome: s.made === undefined ? s.outcome : s.made ? "made" : "missed", value: s.value, team: s.team, title: s.title }));
|
|
221
|
+
const data = shots.map((s) => clean({ id: s.id, x: s.x, y: s.y, outcome: s.made === undefined ? s.outcome : s.made ? "made" : "missed", value: s.value, team: s.team, title: s.title }));
|
|
222
222
|
const { counts, placed: count, skipped } = countOutcomes(data);
|
|
223
223
|
const entries = [{ label: w.made, outcome: "made" }, { label: w.missed, outcome: "missed" }];
|
|
224
224
|
const o = drawingOptions("nba", options, w.titleNba);
|
|
@@ -330,7 +330,7 @@ export function nhlShotMap(shots, options = {}) {
|
|
|
330
330
|
const frame = frameOf(options.from, "nhl-api");
|
|
331
331
|
const o = drawingOptions("nhl", options, w.titleNhl);
|
|
332
332
|
const folded = options.fold === true;
|
|
333
|
-
const given = shots.map((s) => clean({ x: s.x, y: s.y, outcome: hockeyOutcome(s), value: s.xg, team: s.team, title: s.title }));
|
|
333
|
+
const given = shots.map((s) => clean({ id: s.id, x: s.x, y: s.y, outcome: hockeyOutcome(s), value: s.xg, team: s.team, title: s.title }));
|
|
334
334
|
const data = folded ? foldToRight(given, frame, o) : given;
|
|
335
335
|
const { counts, placed: count, skipped } = countOutcomes(data);
|
|
336
336
|
const hasXg = data.some((d) => isNum(d.value));
|
|
@@ -441,7 +441,7 @@ export function nflPassChart(passes, options = {}) {
|
|
|
441
441
|
const data = rows.map(({ p, outcome }, i) => {
|
|
442
442
|
const place_ = at[i];
|
|
443
443
|
const air = isNum(p.airYards) ? p.airYards : place_ === undefined ? undefined : round(inYards(place_[0] - losFeet), 1);
|
|
444
|
-
return clean({ x: p.x, y: p.y, outcome, value: air, team: p.team, title: p.title });
|
|
444
|
+
return clean({ id: p.id, x: p.x, y: p.y, outcome, value: air, team: p.team, title: p.title });
|
|
445
445
|
});
|
|
446
446
|
const { counts, placed: count, skipped } = countOutcomes(data);
|
|
447
447
|
const entries = [["complete", w.complete], ["incomplete", w.incomplete], ["touchdown", w.touchdown], ["interception", w.interception]].filter(([k]) => counts.has(k) || counts.size === 0 || ["complete", "incomplete"].includes(k)).map(([outcome, label]) => ({ label, outcome }));
|
|
@@ -480,7 +480,7 @@ export function nflPassChart(passes, options = {}) {
|
|
|
480
480
|
layers.push(line);
|
|
481
481
|
}
|
|
482
482
|
if (options.arrows === true) {
|
|
483
|
-
const arrows = rows.filter(({ p }) => isNum(p.fromX) && isNum(p.fromY) && isNum(p.x) && isNum(p.y)).map(({ p, outcome }) => clean({ x: p.fromX, y: p.fromY, x2: p.x, y2: p.y, outcome, team: p.team, title: p.title }));
|
|
483
|
+
const arrows = rows.filter(({ p }) => isNum(p.fromX) && isNum(p.fromY) && isNum(p.x) && isNum(p.y)).map(({ p, outcome }) => clean({ id: p.id, x: p.fromX, y: p.fromY, x2: p.x, y2: p.y, outcome, team: p.team, title: p.title }));
|
|
484
484
|
layers.push(clean({ kind: "arrows", id: "arrows", name: w.passes, ...where, data: arrows, style: { width: 0.7, opacity: 0.7, curve: 0.08, outcomes: { touchdown: {}, interception: {}, complete: {}, incomplete: { hollow: true } } } }));
|
|
485
485
|
}
|
|
486
486
|
const values = data.map((d) => d.value).filter(isNum);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { PoolRace, PoolStyle } from "./pool.types.ts";
|
|
2
|
+
import type { Chart, ChartOptions } from "./charts.types.ts";
|
|
3
|
+
/** One split of a swimmer: the metres it covers, the seconds it took, and its pace. */
|
|
4
|
+
export interface SplitRow {
|
|
5
|
+
/** The distance at which the split ends, in metres of the race. */
|
|
6
|
+
distance: number;
|
|
7
|
+
/** The seconds of the split itself, and the cumulative time at its end. */
|
|
8
|
+
seconds: number;
|
|
9
|
+
cumulative: number;
|
|
10
|
+
/** Seconds per 100 m. */
|
|
11
|
+
pace: number;
|
|
12
|
+
}
|
|
13
|
+
/** What a swimmer's splits come to. */
|
|
14
|
+
export interface SwimmerSplits {
|
|
15
|
+
lane: number;
|
|
16
|
+
name: string;
|
|
17
|
+
splits: SplitRow[];
|
|
18
|
+
}
|
|
19
|
+
/** The numbers behind a splits chart. */
|
|
20
|
+
export interface SplitsTotals {
|
|
21
|
+
swimmers: number;
|
|
22
|
+
/** The metres of the race and the metres between splits. */
|
|
23
|
+
distance: number;
|
|
24
|
+
splitEvery: number;
|
|
25
|
+
/** The swimmers' splits, in the order down the pool. */
|
|
26
|
+
rows: SwimmerSplits[];
|
|
27
|
+
/** The fastest split of the field: whose it is, which one (from 1) and its pace; undefined with no splits. */
|
|
28
|
+
fastest: {
|
|
29
|
+
lane: number;
|
|
30
|
+
name: string;
|
|
31
|
+
split: number;
|
|
32
|
+
seconds: number;
|
|
33
|
+
pace: number;
|
|
34
|
+
} | undefined;
|
|
35
|
+
slowest: {
|
|
36
|
+
lane: number;
|
|
37
|
+
name: string;
|
|
38
|
+
split: number;
|
|
39
|
+
seconds: number;
|
|
40
|
+
pace: number;
|
|
41
|
+
} | undefined;
|
|
42
|
+
}
|
|
43
|
+
/** What a splits chart takes beyond a chart's own options. */
|
|
44
|
+
export interface SplitsOptions extends ChartOptions {
|
|
45
|
+
/** The pool: the course (`short` for 25 m), the lanes, the look of the water and the deck. */
|
|
46
|
+
pool?: Omit<PoolStyle, "race">;
|
|
47
|
+
/** Write each bar's time on it. On by default. */
|
|
48
|
+
labels?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The splits of a race as a chart: pace bars in the lanes of a pool (`pool.race.pace`), a title, a sentence that sums it up, the numbers (`totals`) and an HTML table of every split for a reader who cannot see the
|
|
52
|
+
* drawing. The splits are cumulative times, one every 50 m (every 25 m in a short course pool) unless the race says another distance.
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { splitsChart } from "@johnmorrisdotca/kyogijo-stadiums/charts";
|
|
56
|
+
* const chart = splitsChart({
|
|
57
|
+
* distance: 100,
|
|
58
|
+
* swimmers: [
|
|
59
|
+
* { lane: 4, name: "A. Swimmer", splits: [25.1, 52.4] },
|
|
60
|
+
* { lane: 5, name: "B. Swimmer", splits: [25.6, 52.9] },
|
|
61
|
+
* ],
|
|
62
|
+
* });
|
|
63
|
+
* console.log(chart.totals.fastest?.name, chart.totals.fastest?.pace, chart.draw().startsWith("<svg"));
|
|
64
|
+
* // A. Swimmer 50.2 true
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function splitsChart(race: PoolRace, options?: SplitsOptions): Chart<SplitsTotals>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// The swimming chart: the splits of a race as pace bars in the lanes of the pool, with the table that stands for it. A race of 200 m in a 50 m pool is swum along its lane and back; the chart lays it out
|
|
2
|
+
// flat, so that each lane is the whole race from the start (left) to the finish (right), each split a bar whose length is its share of the race and whose colour is its pace against the field's, written
|
|
3
|
+
// in seconds per 100 m. Written for this package; nothing of any other package is used.
|
|
4
|
+
import { drawKyogijo } from "./draw.js";
|
|
5
|
+
import { esc } from "./format.js";
|
|
6
|
+
import { swimPlan } from "./pool.js";
|
|
7
|
+
import { formatTime, pacePer100, splitMetres } from "./pool.race.js";
|
|
8
|
+
import { KYOGIJO_STRINGS, fill } from "./strings.js";
|
|
9
|
+
/**
|
|
10
|
+
* The splits of a race as a chart: pace bars in the lanes of a pool (`pool.race.pace`), a title, a sentence that sums it up, the numbers (`totals`) and an HTML table of every split for a reader who cannot see the
|
|
11
|
+
* drawing. The splits are cumulative times, one every 50 m (every 25 m in a short course pool) unless the race says another distance.
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { splitsChart } from "@johnmorrisdotca/kyogijo-stadiums/charts";
|
|
15
|
+
* const chart = splitsChart({
|
|
16
|
+
* distance: 100,
|
|
17
|
+
* swimmers: [
|
|
18
|
+
* { lane: 4, name: "A. Swimmer", splits: [25.1, 52.4] },
|
|
19
|
+
* { lane: 5, name: "B. Swimmer", splits: [25.6, 52.9] },
|
|
20
|
+
* ],
|
|
21
|
+
* });
|
|
22
|
+
* console.log(chart.totals.fastest?.name, chart.totals.fastest?.pace, chart.draw().startsWith("<svg"));
|
|
23
|
+
* // A. Swimmer 50.2 true
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function splitsChart(race, options = {}) {
|
|
27
|
+
const language = options.language === "ja" ? "ja" : "en";
|
|
28
|
+
const w = KYOGIJO_STRINGS[language].pool.chart;
|
|
29
|
+
const pool = { ...(options.pool ?? {}), race: { ...race, pace: { labels: options.labels !== false } } };
|
|
30
|
+
const plan = swimPlan({ sport: "swimming", pool });
|
|
31
|
+
const planRace = plan.race;
|
|
32
|
+
if (planRace === undefined)
|
|
33
|
+
throw new TypeError("a splits chart needs a race: { swimmers: [...] }");
|
|
34
|
+
const rows = planRace.rows.map((row) => ({
|
|
35
|
+
lane: row.lane,
|
|
36
|
+
name: row.name,
|
|
37
|
+
splits: row.splits
|
|
38
|
+
.map((cum, i) => {
|
|
39
|
+
const from = i === 0 ? 0 : row.splits[i - 1];
|
|
40
|
+
if (!Number.isFinite(cum) || !Number.isFinite(from))
|
|
41
|
+
return undefined;
|
|
42
|
+
const metres = splitMetres(i, planRace.splitEvery, planRace.distance);
|
|
43
|
+
return { distance: Math.min(planRace.distance, (i + 1) * planRace.splitEvery), seconds: Math.round((cum - from) * 100) / 100, cumulative: cum, pace: Math.round(pacePer100(from, cum, metres) * 100) / 100 };
|
|
44
|
+
})
|
|
45
|
+
.filter((split) => split !== undefined),
|
|
46
|
+
}));
|
|
47
|
+
const all = rows.flatMap((row) => row.splits.map((split, i) => ({ lane: row.lane, name: row.name, split: i + 1, seconds: split.seconds, pace: split.pace })));
|
|
48
|
+
const fastest = all.length === 0 ? undefined : all.reduce((a, b) => (b.pace < a.pace ? b : a));
|
|
49
|
+
const slowest = all.length === 0 ? undefined : all.reduce((a, b) => (b.pace > a.pace ? b : a));
|
|
50
|
+
const title = planRace.event === undefined ? w.title : `${w.title}${KYOGIJO_STRINGS[language].said.sep}${planRace.event}`;
|
|
51
|
+
const totals = { swimmers: rows.length, distance: planRace.distance, splitEvery: planRace.splitEvery, rows, fastest, slowest };
|
|
52
|
+
const summary = fastest === undefined ? "" : fill(w.summary, { n: rows.length, name: fastest.name, time: formatTime(fastest.seconds) });
|
|
53
|
+
const merged = { sport: "swimming", language, ...(options.id === undefined ? {} : { id: options.id }), title, pool, ...(options.surface ?? {}) };
|
|
54
|
+
const columns = Math.max(0, ...rows.map((row) => row.splits.length));
|
|
55
|
+
return {
|
|
56
|
+
options: merged,
|
|
57
|
+
layers: [],
|
|
58
|
+
title,
|
|
59
|
+
summary,
|
|
60
|
+
totals,
|
|
61
|
+
draw(extra = {}) {
|
|
62
|
+
return drawKyogijo({ ...merged, ...extra });
|
|
63
|
+
},
|
|
64
|
+
table() {
|
|
65
|
+
const head = [w.headLane, w.headName, ...Array.from({ length: columns }, (_, i) => `${w.headSplit} ${i + 1}`), w.headPace].map((text) => `<th scope="col">${esc(text)}</th>`).join("");
|
|
66
|
+
const body = rows
|
|
67
|
+
.map((row) => {
|
|
68
|
+
const cells = Array.from({ length: columns }, (_, i) => `<td>${row.splits[i] === undefined ? "" : `${formatTime(row.splits[i].seconds)} (${row.splits[i].pace.toFixed(2)})`}</td>`).join("");
|
|
69
|
+
const mean = row.splits.length === 0 ? "" : (row.splits.reduce((sum, s) => sum + s.pace, 0) / row.splits.length).toFixed(2);
|
|
70
|
+
return `<tr><th scope="row">${row.lane}</th><td>${esc(row.name)}</td>${cells}<td>${mean}</td></tr>`;
|
|
71
|
+
})
|
|
72
|
+
.join("");
|
|
73
|
+
return `<table class="ky-table" data-kind="splits"><caption>${esc(fill(w.caption, { event: planRace.event ?? w.title }))}</caption><thead><tr>${head}</tr></thead><tbody>${body}</tbody></table>`;
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import type { Chart, ChartOptions, KeyItem } from "./charts.types.ts";
|
|
2
|
+
import type { ReplayLook, ReplayTimeline } from "./replay.types.ts";
|
|
3
|
+
import type { SurfaceOptions } from "./types.ts";
|
|
4
|
+
import { type ElementKind } from "./skating/events.ts";
|
|
5
|
+
import type { SkatingRace } from "./skating/types.ts";
|
|
6
|
+
/** A skater in a race or on the ice. */
|
|
7
|
+
export interface SkatingEntry {
|
|
8
|
+
name: string;
|
|
9
|
+
/** The country's code or name, for the table. */
|
|
10
|
+
country?: string;
|
|
11
|
+
/** The flag: an SVG document as text, or an `https:` or relative address, as a team's `logo`. */
|
|
12
|
+
flag?: string;
|
|
13
|
+
bib?: string | number;
|
|
14
|
+
}
|
|
15
|
+
/** A pair of a long track race: two skaters, one in each lane (Rule 254.2). */
|
|
16
|
+
export interface SkatingPair {
|
|
17
|
+
/** The pair's number in the race, from 1. */
|
|
18
|
+
pair: number;
|
|
19
|
+
inner?: SkatingEntry;
|
|
20
|
+
outer?: SkatingEntry;
|
|
21
|
+
}
|
|
22
|
+
/** A starter of a short track race and the starting position he has on the line (Rule 280.2c: five positions of the 500 m and the 1000 m, from 1 on the inner side). */
|
|
23
|
+
export interface SkatingStarter extends SkatingEntry {
|
|
24
|
+
position: number;
|
|
25
|
+
}
|
|
26
|
+
/** One skater's result in a race. Times are in seconds from the gun. */
|
|
27
|
+
export interface SkatingResult extends SkatingEntry {
|
|
28
|
+
/** The place, from 1. A skater who did not finish has none. */
|
|
29
|
+
place?: number;
|
|
30
|
+
/** The pair, on the long track. */
|
|
31
|
+
pair?: number;
|
|
32
|
+
/** The lane the skater started in, on the long track: `inner` or `outer`. */
|
|
33
|
+
lane?: "inner" | "outer";
|
|
34
|
+
/** The time in seconds from the gun, or `null` for one who did not finish. */
|
|
35
|
+
time?: number | null;
|
|
36
|
+
/** The times, from the gun, at distances along the way: `{ distance: 200, time: 17.9 }`. */
|
|
37
|
+
splits?: readonly {
|
|
38
|
+
distance: number;
|
|
39
|
+
time: number;
|
|
40
|
+
}[];
|
|
41
|
+
/** The lap times in seconds, one for each lap (Rule 252), for the table. */
|
|
42
|
+
laps?: readonly number[];
|
|
43
|
+
/** `DQ`, `DNF`, `DNS` or a note of your own, for the table. */
|
|
44
|
+
note?: string;
|
|
45
|
+
}
|
|
46
|
+
/** What the race charts take beyond a chart's options. */
|
|
47
|
+
export interface SkatingRaceOptions extends ChartOptions {
|
|
48
|
+
/** The race: the 500 m by default. */
|
|
49
|
+
race?: SkatingRace;
|
|
50
|
+
}
|
|
51
|
+
/** The numbers behind a draw. */
|
|
52
|
+
export interface DrawTotals {
|
|
53
|
+
skaters: number;
|
|
54
|
+
/** Long track: the pairs; short track: 1. */
|
|
55
|
+
pairs: number;
|
|
56
|
+
}
|
|
57
|
+
/** The numbers behind results. */
|
|
58
|
+
export interface SkatingResultsTotals {
|
|
59
|
+
skaters: number;
|
|
60
|
+
finished: number;
|
|
61
|
+
winner: {
|
|
62
|
+
name: string;
|
|
63
|
+
time: number;
|
|
64
|
+
} | null;
|
|
65
|
+
}
|
|
66
|
+
/** A time in seconds as it is written: `34.32`, `1:40.91`, `6:01.03`. */
|
|
67
|
+
export declare function formatTime(seconds: number, places?: number): string;
|
|
68
|
+
/**
|
|
69
|
+
* The pairs of a long track race on the start's close-up: the pair `pair` (the first by default) with each skater's name and flag behind the starting line of his lane, and an armband's colour (white
|
|
70
|
+
* for the inner lane, red for the outer: Rule 253.3.1); a table lists every pair. The starting lines are the ISU's: the 500 m on the finishing straight, the 1000 m, 1500 m, 3000 m and 5000 m on the
|
|
71
|
+
* crossing straight, where each lane's line stands a different distance from the finish.
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* import { skatingPairs } from "@johnmorrisdotca/kyogijo-stadiums/skating";
|
|
75
|
+
* const chart = skatingPairs([{ pair: 1, inner: { name: "A. Skater" }, outer: { name: "B. Skater" } }], { race: "1000m" });
|
|
76
|
+
* console.log(chart.totals, chart.title);
|
|
77
|
+
* // { skaters: 2, pairs: 1 } Pairs, 1000 m
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function skatingPairs(pairs: readonly SkatingPair[], options?: SkatingRaceOptions & {
|
|
81
|
+
pair?: number;
|
|
82
|
+
}): Chart<DrawTotals> & {
|
|
83
|
+
key: KeyItem[];
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* The starting positions of a short track race on the start's close-up: the five dots of the 500 m and the 1000 m (every 1.3 m from 50 cm out from the inner side, Rule 280.2c), each with its starter's
|
|
87
|
+
* name and flag. The 500 m and the 1500 m start on the straight opposite the finishing line; the others at the finishing line.
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* import { skatingGrid } from "@johnmorrisdotca/kyogijo-stadiums/skating";
|
|
91
|
+
* const chart = skatingGrid([{ position: 1, name: "A. Skater" }, { position: 2, name: "B. Skater" }], { race: "500m", surface: { league: "isu-short-track" } });
|
|
92
|
+
* console.log(chart.totals.skaters);
|
|
93
|
+
* // 2
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function skatingGrid(starters: readonly SkatingStarter[], options?: SkatingRaceOptions): Chart<DrawTotals> & {
|
|
97
|
+
key: KeyItem[];
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* The results of a race as a leaderboard on the ice inside the track: for each skater with a place, a disc with the place (gold, silver and bronze for the first three), the name and the time; the splits
|
|
101
|
+
* as small marks along the skater's lane on the long track; and a table with the pair, the lane, the time, the splits and the lap times. Times are in seconds from the gun.
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* import { skatingResults } from "@johnmorrisdotca/kyogijo-stadiums/skating";
|
|
105
|
+
* const chart = skatingResults([{ name: "A", place: 1, time: 34.3 }, { name: "B", place: 2, time: 34.5 }], { race: "500m" });
|
|
106
|
+
* console.log(chart.totals.winner?.name, chart.summary);
|
|
107
|
+
* // A A won the 500 m in 34.30.
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function skatingResults(results: readonly SkatingResult[], options?: SkatingRaceOptions & {
|
|
111
|
+
splits?: boolean;
|
|
112
|
+
rows?: number;
|
|
113
|
+
}): Chart<SkatingResultsTotals> & {
|
|
114
|
+
key: KeyItem[];
|
|
115
|
+
};
|
|
116
|
+
/** One skater of a replay. */
|
|
117
|
+
export interface SkatingRunner extends SkatingEntry {
|
|
118
|
+
/** The time, in seconds from the gun, at which the skater finishes. */
|
|
119
|
+
time: number;
|
|
120
|
+
/** Long track: the lane the skater starts in. `inner` by default. */
|
|
121
|
+
lane?: "inner" | "outer";
|
|
122
|
+
/** Short track: the starting position, from 1 on the inner side. 1 by default. */
|
|
123
|
+
position?: number;
|
|
124
|
+
/** Times, from the gun, at distances along the way, which the skater's pace follows; without them the pace is even. */
|
|
125
|
+
splits?: readonly {
|
|
126
|
+
distance: number;
|
|
127
|
+
time: number;
|
|
128
|
+
}[];
|
|
129
|
+
}
|
|
130
|
+
/** What `skatingReplay` takes. */
|
|
131
|
+
export interface SkatingReplayOptions extends SkatingRaceOptions {
|
|
132
|
+
/** Seconds between two frames. 0.25 by default. */
|
|
133
|
+
step?: number;
|
|
134
|
+
}
|
|
135
|
+
/** What `skatingReplay` gives back. */
|
|
136
|
+
export interface SkatingReplay {
|
|
137
|
+
timeline: ReplayTimeline;
|
|
138
|
+
/** The drawing's options: the track with the race marked. */
|
|
139
|
+
options: SurfaceOptions;
|
|
140
|
+
/** A look for the frames: markers sized for the track, no trails, the lane or the position on them. */
|
|
141
|
+
look: ReplayLook;
|
|
142
|
+
title: string;
|
|
143
|
+
summary: string;
|
|
144
|
+
duration: number;
|
|
145
|
+
}
|
|
146
|
+
/** The distance a skater has skated at a time, by the splits and the finish: straight lines between them, coasting for three seconds after the finish. */
|
|
147
|
+
export declare function distanceSkated(runner: SkatingRunner, total: number, t: number): number;
|
|
148
|
+
/**
|
|
149
|
+
* A replay of a race: every skater, from the gun, on his own way round the track (the long track's lane changed once a lap, on the crossing straight, and the first straight of the 1000 m and the 1500 m
|
|
150
|
+
* kept in the lane; the short track's oval of 111.12 m, the starters coming in from their positions), at the pace of the splits and the finish time. The positions are in the skating frame (metres
|
|
151
|
+
* from the middle of the rink). The team races, the mass start and the relays are not replayed.
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* import { skatingReplay } from "@johnmorrisdotca/kyogijo-stadiums/skating";
|
|
155
|
+
* const replay = skatingReplay([{ name: "A", lane: "inner", time: 34.4 }, { name: "B", lane: "outer", time: 34.6 }], { race: "500m" });
|
|
156
|
+
* console.log(replay.timeline.frames.length > 40, replay.duration);
|
|
157
|
+
* // true 34.6
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export declare function skatingReplay(runners: readonly SkatingRunner[], options?: SkatingReplayOptions): SkatingReplay;
|
|
161
|
+
/** An element of a figure skating programme as it lies on the ice. */
|
|
162
|
+
export interface SkatingElement {
|
|
163
|
+
/** The kind: a jump, a spin, a step sequence, a choreographic sequence, a lift, a spiral, a twizzle, a death spiral or a throw. */
|
|
164
|
+
kind: ElementKind;
|
|
165
|
+
/** The name for the table and the label: `3Lz`, `CCoSp4`, `StSq3`. */
|
|
166
|
+
name?: string;
|
|
167
|
+
/** Where it starts, in metres from the middle of the rink: x along it (positive to the right as the rink lies wide), y across (positive towards the judges). */
|
|
168
|
+
x: number;
|
|
169
|
+
y: number;
|
|
170
|
+
/** Where it ends, for an element that travels (a step sequence, a spiral). */
|
|
171
|
+
x2?: number;
|
|
172
|
+
y2?: number;
|
|
173
|
+
/** The place in the programme, from 1. */
|
|
174
|
+
order?: number;
|
|
175
|
+
/** `home` or `away`: the two layer colours, for a pair's two skaters or two programmes. */
|
|
176
|
+
team?: string;
|
|
177
|
+
/** The tooltip, and what a screen reader reads. */
|
|
178
|
+
title?: string;
|
|
179
|
+
}
|
|
180
|
+
/** What `figureElements` takes. */
|
|
181
|
+
export interface FigureElementsOptions extends ChartOptions {
|
|
182
|
+
/** Write the name beside each mark. On by default. */
|
|
183
|
+
labels?: boolean;
|
|
184
|
+
}
|
|
185
|
+
/** The numbers behind the elements. */
|
|
186
|
+
export interface ElementTotals {
|
|
187
|
+
elements: number;
|
|
188
|
+
/** The count of each kind. */
|
|
189
|
+
kinds: Readonly<Record<string, number>>;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The elements of a programme as marks on the rink: a mark for each element where it starts, its shape for its kind, the track of a step sequence or a spiral as a line to where it ends, and the order
|
|
193
|
+
* and the name beside it. Put them on the rink (`league: "isu-figure"`, the default for this chart).
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* import { figureElements } from "@johnmorrisdotca/kyogijo-stadiums/skating";
|
|
197
|
+
* const chart = figureElements([{ kind: "jump", name: "3Lz", x: -12, y: 4, order: 1 }, { kind: "spin", name: "CCoSp4", x: 6, y: -3, order: 2 }]);
|
|
198
|
+
* console.log(chart.totals.elements, chart.totals.kinds.jump);
|
|
199
|
+
* // 2 1
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
export declare function figureElements(elements: readonly SkatingElement[], options?: FigureElementsOptions): Chart<ElementTotals> & {
|
|
203
|
+
key: KeyItem[];
|
|
204
|
+
};
|