@johnmorrisdotca/kyogijo-stadiums 0.49.1 → 0.51.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.
@@ -0,0 +1,74 @@
1
+ // The catalogue: every venue the package draws today (supported), the ones being built (working on) and the ones wanted, with their facts, in one list. The same data is published as a static
2
+ // file, `catalogue.json`, in the npm package and on the demo's site (`CATALOGUE_ADDRESS`). There is no server: a reader fetches the file or imports this entry.
3
+ import { CATALOGUE_DATA } from "./catalogue.data.js";
4
+ /** Every venue: the supported ones first, then those being built, then the wanted ones, each group in its order. */
5
+ export const CATALOGUE = CATALOGUE_DATA.venues;
6
+ /** The leagues (every venue of the season, NBA, MLB, NFL, CFL and NHL) and the collections of the Working on and Wanted sections, each with its venues in order and its name in both languages. */
7
+ export const CATALOGUE_GROUPS = CATALOGUE_DATA.groups;
8
+ /** The sports, with their names in both languages and the `sport` of `drawKyogijo` that draws each (`null`: not drawn yet). */
9
+ export const CATALOGUE_SPORTS = CATALOGUE_DATA.sports;
10
+ /** The countries of the catalogue by ISO code, with their names in English and Japanese (Wikidata's labels). */
11
+ export const CATALOGUE_COUNTRIES = CATALOGUE_DATA.countries;
12
+ /** Where `catalogue.json` is published: the same data as this entry, for a page or a program that does not install the package. */
13
+ export const CATALOGUE_ADDRESS = CATALOGUE_DATA.address;
14
+ /** The demo's address: a supported venue's `demo` is relative to it. */
15
+ export const CATALOGUE_SITE = CATALOGUE_DATA.site;
16
+ /** The counts, the day the sources were read and where they are kept, and the licence of the facts. */
17
+ export const CATALOGUE_ABOUT = {
18
+ schemaVersion: CATALOGUE_DATA.schemaVersion,
19
+ generatedAt: CATALOGUE_DATA.generatedAt,
20
+ package: CATALOGUE_DATA.package,
21
+ licence: CATALOGUE_DATA.licence,
22
+ source: CATALOGUE_DATA.source,
23
+ counts: CATALOGUE_DATA.counts,
24
+ };
25
+ const BY_ID = new Map(CATALOGUE.map((entry) => [entry.id, entry]));
26
+ /**
27
+ * A venue by its id, or `undefined`.
28
+ * @example
29
+ * ```ts
30
+ * import { catalogueById } from "@johnmorrisdotca/kyogijo-stadiums/catalogue";
31
+ * const ashe = catalogueById("arthur-ashe-stadium")!;
32
+ * console.log(ashe.status, ashe.ticket, ashe.wikidata);
33
+ * // working-on KYOGIJO-STADIUMS-22 Q609551
34
+ * ```
35
+ */
36
+ export function catalogueById(id) {
37
+ return BY_ID.get(id);
38
+ }
39
+ /** The venues of a status, in the catalogue's order. */
40
+ export function catalogueByStatus(status) {
41
+ return CATALOGUE.filter((entry) => entry.status === status);
42
+ }
43
+ /** The venues of a sport (any of a venue's sports), in the catalogue's order. */
44
+ export function catalogueBySport(sport) {
45
+ return CATALOGUE.filter((entry) => entry.sports.includes(sport));
46
+ }
47
+ /** The venues of a group (a league or a collection), in the group's order; empty for a group that does not exist. */
48
+ export function catalogueByGroup(group) {
49
+ return (CATALOGUE_GROUPS.find((one) => one.id === group)?.ids ?? []).map((id) => BY_ID.get(id)).filter((entry) => entry !== undefined);
50
+ }
51
+ /** Every venue whose building or whole venue is wanted: the venues of the Wanted section and the supported venues of a league or a collection that are drawn as a surface only. */
52
+ export function catalogueWanted() {
53
+ return CATALOGUE.filter((entry) => entry.want !== undefined && entry.status !== "working-on");
54
+ }
55
+ /**
56
+ * How much of a league the package draws: its venues this season, how many in their buildings, how many as a field only, how many not yet.
57
+ * @example
58
+ * ```ts
59
+ * import { catalogueCoverage } from "@johnmorrisdotca/kyogijo-stadiums/catalogue";
60
+ * const nhl = catalogueCoverage("nhl");
61
+ * console.log(nhl.venues, nhl.outline, nhl.notYet);
62
+ * // 32 32 0
63
+ * ```
64
+ */
65
+ export function catalogueCoverage(league) {
66
+ const venues = catalogueByGroup(league);
67
+ return {
68
+ league,
69
+ venues: venues.length,
70
+ outline: venues.filter((entry) => entry.drawn === "outline").length,
71
+ surface: venues.filter((entry) => entry.drawn === "surface").length,
72
+ notYet: venues.filter((entry) => entry.status !== "supported").length,
73
+ };
74
+ }
@@ -0,0 +1,143 @@
1
+ import type { PlaceSurface } from "./atlas.ts";
2
+ /** Where a venue stands with the package: drawn today, being built (an open ticket), or wanted. */
3
+ export type CatalogueStatus = "supported" | "working-on" | "wanted";
4
+ /**
5
+ * How a supported venue is drawn: `outline`, inside the outline of its real building with a bowl of its seats (`STADIUMS` and the NHL's `VENUES`), or `surface`, its field, court, rink, park or
6
+ * floor only, at the venue's own size where the data gives one (a key of `PARKS`, `GROUNDS`, `ARENAS` or `HALLS`), or `circuit`, the lap as OpenStreetMap maps it with its pit lane and no stands
7
+ * (a key of `CIRCUITS`, drawn by `drawCircuit` of the `circuits` entry).
8
+ */
9
+ export type CatalogueDrawn = "outline" | "surface" | "circuit";
10
+ /** What is wanted of a venue: its building's `outline` (a venue drawn today as a surface only), or the `venue` itself (one the package does not draw at all). */
11
+ export type CatalogueWant = "outline" | "venue";
12
+ /** What has to exist before a wanted venue can be drawn: a `circuit-surface` for motor racing, which the package does not draw yet. */
13
+ export type CatalogueNeed = "circuit-surface";
14
+ /** The sports of the catalogue, in kebab case. Every one but `motor-racing` names a surface the package draws (`CATALOGUE_SPORTS[sport].surface`). */
15
+ export type CatalogueSport = "baseball" | "basketball" | "hockey" | "american-football" | "canadian-football" | "soccer" | "cricket" | "rugby" | "australian-football" | "gaelic-games" | "tennis" | "budo" | "athletics" | "swimming" | "skating" | "curling" | "volleyball" | "badminton" | "handball" | "boxing" | "motor-racing";
16
+ /** The leagues whose every venue of the season is in the catalogue. */
17
+ export type CatalogueLeague = "nba" | "mlb" | "nfl" | "cfl" | "nhl";
18
+ /** A club that plays its home games at a venue this season. */
19
+ export interface CatalogueTeam {
20
+ name: string;
21
+ nameJa?: string;
22
+ league: CatalogueLeague;
23
+ }
24
+ /** The options that draw a supported venue with `drawKyogijo`: its surface (a park, a ground, an arena or a hall), or its real building (`stadium` or `arena` with `crowd: { real: true }`). */
25
+ export type CatalogueDraw = PlaceSurface | {
26
+ sport: "nfl" | "cfl" | "soccer" | "mlb" | "boxing" | "nba" | "nhl";
27
+ stadium?: string;
28
+ park?: string;
29
+ arena?: string;
30
+ crowd: {
31
+ real: true;
32
+ };
33
+ };
34
+ /** One venue of the catalogue. */
35
+ export interface CatalogueEntry {
36
+ /** Kebab case, unique: the package's own key for a venue it draws (`fenway-park`, `bc-place`), else one made from the venue's English name. */
37
+ id: string;
38
+ status: CatalogueStatus;
39
+ /** How a supported venue is drawn. */
40
+ drawn?: CatalogueDrawn;
41
+ /** What is wanted: the building's outline of a venue drawn as a surface that a league or a group lists, or the venue itself. */
42
+ want?: CatalogueWant;
43
+ /** What must be built first. */
44
+ needs?: CatalogueNeed;
45
+ /** Which of the package's lists a supported venue comes from: a real stadium or NHL venue (`stadium`, `venue`), or a `park`, `ground`, `arena` or `hall`. */
46
+ kind?: "stadium" | "venue" | "park" | "ground" | "arena" | "hall" | "circuit";
47
+ /** The everyday name in English. */
48
+ name: string;
49
+ /** The name in Japanese; absent where no source gives one (`missing.nameJa` says so). */
50
+ nameJa?: string;
51
+ /** Where the Japanese name was read: the package's own data, Wikidata's label, the title of the Japanese Wikipedia's article, or a name a reviewer checked. */
52
+ nameJaFrom?: "package" | "wikidata" | "jawiki" | "reviewed";
53
+ city?: string;
54
+ cityJa?: string;
55
+ /** ISO 3166-1 alpha-2. */
56
+ country?: string;
57
+ /** Wikidata's coordinates (P625), in degrees. */
58
+ lat?: number;
59
+ lon?: number;
60
+ sports: CatalogueSport[];
61
+ /** The Wikidata item. */
62
+ wikidata: string;
63
+ /** The seats, where Wikidata gives one figure (P1083), for a venue that is not drawn yet. */
64
+ capacity?: number;
65
+ /** `current` or `past`, for a supported venue. */
66
+ era?: "current" | "past";
67
+ /** The leagues that play there this season, and their clubs. */
68
+ leagues?: CatalogueLeague[];
69
+ teams?: CatalogueTeam[];
70
+ /** The groups the venue is listed in (a league, a collection of the Wanted section). */
71
+ groups: string[];
72
+ /** The ticket of a venue being built. */
73
+ ticket?: string;
74
+ /** The options that draw a supported venue with `drawKyogijo` (a circuit has none: `drawCircuit({ circuit: id })` of the `circuits` entry draws it). */
75
+ draw?: CatalogueDraw;
76
+ /** The demo page that shows a supported venue, relative to the demo's address (`CATALOGUE_SITE`). */
77
+ demo?: string;
78
+ /** The facts left out, each with why. */
79
+ missing?: Partial<Record<"nameJa" | "city" | "country" | "coordinates", string>>;
80
+ }
81
+ /** A group: a league (every venue of its season) or a collection of the Wanted or Working on section, in its order. */
82
+ export interface CatalogueGroup {
83
+ id: string;
84
+ kind: "league" | "collection";
85
+ en: string;
86
+ ja: string;
87
+ /** For a league: its sport and its season. */
88
+ sport?: CatalogueSport;
89
+ season?: string;
90
+ /** For a collection that is being built. */
91
+ status?: "working-on";
92
+ needs?: CatalogueNeed;
93
+ ids: string[];
94
+ }
95
+ /** The whole catalogue, as `catalogue.json` holds it. */
96
+ export interface CatalogueData {
97
+ /** The shape's version: a change that breaks a reader raises it. */
98
+ schemaVersion: 1;
99
+ /** The day the sources were read (not the day the file was written). */
100
+ generatedAt: string;
101
+ package: {
102
+ name: string;
103
+ version: string;
104
+ };
105
+ /** Where the JSON is published. */
106
+ address: string;
107
+ /** The demo's address, which `demo` is relative to. */
108
+ site: string;
109
+ licence: string;
110
+ source: {
111
+ read: string;
112
+ rawAnswers: string;
113
+ articles: Record<string, number>;
114
+ };
115
+ counts: {
116
+ supported: number;
117
+ outline: number;
118
+ surface: number;
119
+ circuit: number;
120
+ workingOn: number;
121
+ wanted: number;
122
+ outlineWanted: number;
123
+ };
124
+ sports: Record<CatalogueSport, {
125
+ en: string;
126
+ ja: string;
127
+ surface: string | null;
128
+ }>;
129
+ groups: CatalogueGroup[];
130
+ countries: Record<string, {
131
+ en: string;
132
+ ja?: string;
133
+ }>;
134
+ venues: CatalogueEntry[];
135
+ }
136
+ /** How many venues of a league the package draws in their buildings, as a surface only, or not at all. */
137
+ export interface CatalogueCoverage {
138
+ league: CatalogueLeague;
139
+ venues: number;
140
+ outline: number;
141
+ surface: number;
142
+ notYet: number;
143
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import "./strings.ts";
2
+ export { CIRCUITS, CIRCUIT_ATTRIBUTION, CIRCUIT_IDS, circuitById, circuitPlan } from "./circuits.ts";
3
+ export type { CircuitPlan, PlanTurn } from "./circuits.ts";
4
+ export { circuitDrawing, circuitTable, circuitText, drawCircuit } from "./circuits.draw.ts";
5
+ export type { CircuitDrawing } from "./circuits.draw.ts";
6
+ export { CIRCUIT_MARKER, CIRCUIT_PLANES_MAX, CIRCUIT_PRESETS, buildCircuitTurn, circuitTurnMarkup, mountCircuitTurn } from "./circuits.turn.ts";
7
+ export { KYOGIJO_CIRCUIT_STYLE } from "./circuits.style.ts";
8
+ export { CIRCUIT_WORDS } from "./circuits.words.ts";
9
+ export type { CircuitWords } from "./circuits.words.ts";
10
+ export { lineLength } from "./circuits.geo.ts";
11
+ export type { Circuit, CircuitBasis, CircuitData, CircuitFact, CircuitOptions, CircuitOsm, CircuitOsmPoint } from "./circuits.types.ts";
@@ -0,0 +1,9 @@
1
+ // The circuits entry (`@johnmorrisdotca/kyogijo-stadiums/circuits`): famous race tracks as OpenStreetMap maps them, with a few facts each, drawn flat and in 3D.
2
+ // The words of the 3D view's controls in both languages (the circuits' own are in circuits.words.ts).
3
+ import "./strings.js";
4
+ export { CIRCUITS, CIRCUIT_ATTRIBUTION, CIRCUIT_IDS, circuitById, circuitPlan } from "./circuits.js";
5
+ export { circuitDrawing, circuitTable, circuitText, drawCircuit } from "./circuits.draw.js";
6
+ export { CIRCUIT_MARKER, CIRCUIT_PLANES_MAX, CIRCUIT_PRESETS, buildCircuitTurn, circuitTurnMarkup, mountCircuitTurn } from "./circuits.turn.js";
7
+ export { KYOGIJO_CIRCUIT_STYLE } from "./circuits.style.js";
8
+ export { CIRCUIT_WORDS } from "./circuits.words.js";
9
+ export { lineLength } from "./circuits.geo.js";
@@ -0,0 +1,62 @@
1
+ import type { Pt } from "./crowd.ts";
2
+ import type { Circuit } from "./circuits.types.ts";
3
+ import { type LonLat } from "./venues.geo.ts";
4
+ /** The credit a drawing made from OpenStreetMap's data carries (the same words as the venues'). */
5
+ export declare const CIRCUIT_ATTRIBUTION = "(c) OpenStreetMap contributors, ODbL 1.0, openstreetmap.org/copyright";
6
+ /** Every circuit, in the order of the data. */
7
+ export declare const CIRCUITS: readonly Circuit[];
8
+ /** The keys of the circuits. */
9
+ export declare const CIRCUIT_IDS: readonly string[];
10
+ /** A circuit by its key, or `undefined`. */
11
+ export declare const circuitById: (id: string) => Circuit | undefined;
12
+ /** A turn as the plan places it: its number, its point on the lap, how far round the lap it is, which way the lap runs there and the side the bend turns to (1 left, -1 right, 0 straight). */
13
+ export interface PlanTurn {
14
+ n: number;
15
+ at: Pt;
16
+ along: number;
17
+ dir: Pt;
18
+ side: -1 | 0 | 1;
19
+ }
20
+ /** A circuit's plan in the drawing's frame: feet, the long side of the lap along x, y down the page. */
21
+ export interface CircuitPlan {
22
+ circuit: Circuit;
23
+ /** The point of the map the frame is measured from (the middle of the lap's box), `[longitude, latitude]`. */
24
+ origin: LonLat;
25
+ /** The heading of the lap's long side, degrees clockwise from north, and the way north points on the page, degrees clockwise from its top. */
26
+ heading: number;
27
+ north: number;
28
+ lap: Pt[];
29
+ /** The length of the lap measured along the drawn line, in metres. */
30
+ measured: number;
31
+ pitLane: Pt[];
32
+ area: Pt[];
33
+ building?: {
34
+ ring: Pt[];
35
+ height: number;
36
+ };
37
+ turns: PlanTurn[];
38
+ start: {
39
+ at: Pt;
40
+ dir: Pt;
41
+ along: number;
42
+ };
43
+ finish: {
44
+ at: Pt;
45
+ dir: Pt;
46
+ along: number;
47
+ };
48
+ /** The track's width and the pit lane's, in feet. */
49
+ width: number;
50
+ pitWidth: number;
51
+ /** The box of everything drawn on the ground, in feet. */
52
+ box: {
53
+ x0: number;
54
+ y0: number;
55
+ x1: number;
56
+ y1: number;
57
+ };
58
+ }
59
+ /** A circuit's plan: its lap, pit lane, ground, pit building, turns, start and finish in the drawing's frame. */
60
+ export declare function circuitPlan(circuit: Circuit): CircuitPlan;
61
+ /** The circuit a set of options names, or an error that lists the keys. */
62
+ export declare function circuitOf(id: string): Circuit;
@@ -0,0 +1,2 @@
1
+ import type { CircuitData } from "./circuits.types.ts";
2
+ export declare const CIRCUIT_DATA: CircuitData[];
@@ -0,0 +1,18 @@
1
+ export const CIRCUIT_DATA = [
2
+ {
3
+ "id": "las-vegas",
4
+ "wikidata": "Q113112116",
5
+ "en": { "title": "Las Vegas Strip Circuit", "revision": 1376988769 },
6
+ "ja": { "title": "ラスベガス・ストリップ・サーキット", "revision": 108197128 },
7
+ "names": { "en": "Las Vegas Strip Circuit", "ja": "ラスベガス・ストリップ・サーキット" },
8
+ "country": "US",
9
+ "opened": { "value": "2023-11-16", "basis": "documented", "source": "wikidata", "read": "P1619, date of official opening, 16 November 2023; the English article says it opened on November 16, 2023, and the Japanese infobox gives the same day" },
10
+ "length": { "value": 6201, "basis": "documented", "source": "wikipedia", "read": "the English infobox's length, 6.201 km (3.853 mi), which the Japanese infobox also gives; the Japanese article's prose says 6.120 km, which neither infobox nor the English article does, and is not used" },
11
+ "corners": { "value": 17, "basis": "documented", "source": "wikipedia", "read": "the English infobox's turns, 17, and its prose: 14 corners when announced, 17 after a chicane was added; the Japanese infobox gives 17 too" },
12
+ "direction": { "value": "counterclockwise", "basis": "documented", "source": "wikipedia", "read": "the English article: the street circuit runs counterclockwise; the Japanese article says the same (反時計回り)" },
13
+ "width": { "value": 12, "basis": "plausible", "read": "ours: no source we read gives the track's width (OpenStreetMap maps no width on the lap's ways, and neither article gives one), so the ribbon is drawn 12 metres wide" },
14
+ "pitLaneWidth": { "value": 8, "basis": "plausible", "read": "ours: no source gives the pit lane's width" },
15
+ "turnNumbers": { "basis": "documented", "source": "openstreetmap", "read": "the relation's member nodes tagged junction=yes with ref 1 to 17, one at each turn as OpenStreetMap maps them; the English article's account of the lap (Turn 1 a hairpin after the pits, Turns 10 and 11 on Sands Avenue, Turn 12 onto Las Vegas Boulevard, Turn 13 on the Strip, Turns 14 to 16 onto Harmon Avenue, Turn 17 before the pits) agrees with where they lie" },
16
+ "pitBuilding": { "basis": "documented", "source": "openstreetmap", "read": "the building OpenStreetMap maps inside the circuit's area beside the pit lane, 19.5 metres high in 4 levels (its height and building:levels tags)" },
17
+ },
18
+ ];
@@ -0,0 +1,56 @@
1
+ import type { Pt } from "./crowd.ts";
2
+ import { type CircuitPlan } from "./circuits.ts";
3
+ import type { CircuitOptions } from "./circuits.types.ts";
4
+ import type { Language } from "./types.ts";
5
+ /** A drawing of a circuit and what was worked out to make it. */
6
+ export interface CircuitDrawing {
7
+ svg: string;
8
+ plan: CircuitPlan;
9
+ /** The viewBox, in feet. */
10
+ viewBox: {
11
+ x: number;
12
+ y: number;
13
+ w: number;
14
+ h: number;
15
+ };
16
+ /** The size of the drawing's type and marks: a thousandth of its longer side, in feet. */
17
+ k: number;
18
+ /** Where each turn's number is drawn (its badge's middle), in feet, or would be when `turns` is `false`. */
19
+ badges: {
20
+ n: number;
21
+ at: Pt;
22
+ r: number;
23
+ }[];
24
+ title: string;
25
+ description: string;
26
+ }
27
+ /** The words of a circuit's drawing: its title and its description, sentence by sentence. */
28
+ export declare function circuitText(plan: CircuitPlan, language: Language, standing?: string): {
29
+ title: string;
30
+ description: string;
31
+ };
32
+ /** A circuit's drawing and what was worked out to make it. */
33
+ export declare function circuitDrawing(options: CircuitOptions): CircuitDrawing;
34
+ /**
35
+ * A circuit as one SVG string: the lap as a ribbon of the track's width on the ways OpenStreetMap maps for it, the pit lane and the circuit's ground with its pit building, the start and the chequered finish across the
36
+ * track, arrows the way the lap runs, each turn's number beside its bend where OpenStreetMap numbers it, a north arrow, a scale bar and the credit of the map's data. Light and dark follow the page.
37
+ * @example
38
+ * ```ts
39
+ * import { drawCircuit } from "@johnmorrisdotca/kyogijo-stadiums/circuits";
40
+ * const svg = drawCircuit({ circuit: "las-vegas" });
41
+ * console.log(svg.startsWith("<svg"), svg.includes('data-turn="17"'), svg.includes("OpenStreetMap"));
42
+ * // true true true
43
+ * ```
44
+ */
45
+ export declare function drawCircuit(options: CircuitOptions): string;
46
+ /**
47
+ * A circuit's facts as a table, each with its basis (a source's, or ours) and the length the drawn line measures: for a reader who cannot see the drawing, and for a page that wants the data.
48
+ * @example
49
+ * ```ts
50
+ * import { circuitTable } from "@johnmorrisdotca/kyogijo-stadiums/circuits";
51
+ * const table = circuitTable({ circuit: "las-vegas" });
52
+ * console.log(table.startsWith("<table"), table.includes("6.201 km"));
53
+ * // true true
54
+ * ```
55
+ */
56
+ export declare function circuitTable(options: CircuitOptions): string;