@johnmorrisdotca/kyogijo-stadiums 0.19.0 → 0.21.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/NOTICE.md +1 -0
  3. package/README.md +43 -15
  4. package/dist/budo/cage.d.ts +46 -0
  5. package/dist/budo/cage.js +91 -0
  6. package/dist/budo/describe.js +22 -0
  7. package/dist/budo/looks.d.ts +2 -0
  8. package/dist/budo/looks.js +14 -0
  9. package/dist/budo/plan.d.ts +12 -2
  10. package/dist/budo/plan.js +23 -1
  11. package/dist/budo/ring.d.ts +47 -0
  12. package/dist/budo/ring.js +80 -0
  13. package/dist/budo/types.d.ts +13 -3
  14. package/dist/budo-entry.d.ts +1 -1
  15. package/dist/budo-entry.js +1 -1
  16. package/dist/budo.style.js +15 -3
  17. package/dist/crowd.js +4 -0
  18. package/dist/draw.js +9 -7
  19. package/dist/features.js +18 -0
  20. package/dist/fields.types.d.ts +2 -2
  21. package/dist/heat.zones.js +1 -1
  22. package/dist/homeside.js +4 -0
  23. package/dist/leagues/budo.d.ts +3 -2
  24. package/dist/leagues/budo.js +2 -1
  25. package/dist/leagues/combat.d.ts +102 -0
  26. package/dist/leagues/combat.js +64 -0
  27. package/dist/leagues/sources.js +10 -0
  28. package/dist/leagues/types.d.ts +1 -1
  29. package/dist/leagues.d.ts +1 -0
  30. package/dist/leagues.js +40 -1
  31. package/dist/outline.js +2 -0
  32. package/dist/ranges.names.js +2 -0
  33. package/dist/score.js +6 -0
  34. package/dist/strings.d.ts +13 -1
  35. package/dist/strings.js +34 -10
  36. package/dist/surfaces/budo.js +3 -2
  37. package/dist/turn.kit.d.ts +1 -1
  38. package/dist/turn.style.js +13 -3
  39. package/dist/types.d.ts +4 -2
  40. package/dist/units.js +4 -0
  41. package/dist/uprights.budo.js +7 -2
  42. package/dist/uprights.cage.d.ts +4 -0
  43. package/dist/uprights.cage.js +91 -0
  44. package/dist/uprights.js +3 -3
  45. package/dist/uprights.ring.d.ts +12 -0
  46. package/dist/uprights.ring.js +76 -0
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +5 -3
@@ -0,0 +1,91 @@
1
+ import { box, flat, mesh, n, pole, shy, threads, wall } from "./turn.kit.js";
2
+ const K = 1 / 0.3048;
3
+ /** The mesh of the fence: a cell of 5 cm (a diamond of chain link, drawn as a square grid, ours). */
4
+ const CELL = 0.05 * K;
5
+ /** The planes of the platform: its four sides from the floor of the building up to the canvas, and a top that is the floor's own drawing in the platform's rectangle. */
6
+ function deckPlanes(plan, at, h) {
7
+ const b = plan.mma.platform;
8
+ const corners = [at(b.x0, b.y0), at(b.x1, b.y0), at(b.x1, b.y1), at(b.x0, b.y1)];
9
+ const planes = [];
10
+ corners.forEach((a, i) => {
11
+ const c = corners[(i + 1) % 4];
12
+ planes.push(wall(`deck-${i + 1}`, "wall", a[0], a[1], c[0], c[1], 0, h, `<rect width="${n(Math.hypot(c[0] - a[0], c[1] - a[1]))}" height="${n(h)}" class="u-deck-side"/>`));
13
+ });
14
+ planes.push({ ...flat("deck-top", "platform", corners[0][0], corners[0][1], corners[2][0], corners[2][1], h, ""), crop: true });
15
+ return planes;
16
+ }
17
+ /** The mesh of a fence panel w by h feet. */
18
+ const meshOf = (w, h) => `<rect width="${n(w)}" height="${n(h)}" class="u-netfill"/>${threads(mesh(w, h, CELL), CELL)}`;
19
+ /** What stands on a cage: the platform, the posts, the fence with its gates, and the steps. */
20
+ export function cageUprights(plan, at, thin) {
21
+ const L = plan.mma;
22
+ if (L === undefined)
23
+ return [];
24
+ const fig = plan.figures;
25
+ const h0 = L.height * K;
26
+ const top = h0 + L.fence * K;
27
+ const centre = at(L.centre[0], L.centre[1]);
28
+ const items = [];
29
+ items.push({ id: "deck", kind: "deck", at: centre, height: h0, planes: deckPlanes(plan, at, h0) });
30
+ // The steps: each tread a block as high as the treads below it and itself, the lowest the farthest from the platform.
31
+ if (L.steps.length > 0) {
32
+ const s = fig.platform.steps;
33
+ const planes = [];
34
+ for (const b of L.steps) {
35
+ const north = b.y1 <= 0.0001;
36
+ for (let t = 0; t < s.treads; t += 1) {
37
+ // The tread t from the ground: its depth lies further in as t grows.
38
+ const y0 = north ? b.y0 + t * s.tread : b.y0;
39
+ const y1 = north ? b.y1 : b.y1 - t * s.tread;
40
+ const [x0, ya] = at(b.x0, y0);
41
+ const [x1, yb] = at(b.x1, y1);
42
+ planes.push(...box(`step-${north ? "north" : "south"}-${t + 1}`, "platform", { x0, y0: ya, x1, y1: yb }, (h0 * (t + 1)) / s.treads, "u-step"));
43
+ }
44
+ }
45
+ items.push({ id: "steps", kind: "deck", at: centre, height: h0, planes });
46
+ }
47
+ // The posts: padded, from the platform up a hand's breadth over the fence; solid, so two crossed strips as wide as the pad.
48
+ const padW = fig.post.pad * K;
49
+ const postTop = top + 0.15 * K;
50
+ const posts = L.posts.flatMap(([x, y], i) => {
51
+ const [px, py] = at(x, y);
52
+ return pole(`post-${i + 1}`, "post", px, py, h0, postTop, padW, "u-cagepad");
53
+ });
54
+ // The fence: one panel on each flat, in mesh, with a pad along the top and one along the foot. The panels give way to an eye that has them between it and the cage.
55
+ const rail = fig.post.rail * K;
56
+ const planes = [];
57
+ const doorH = fig.gates.height * K;
58
+ L.posts.forEach((p, i) => {
59
+ const q = L.posts[(i + 1) % L.posts.length];
60
+ const [ax, ay] = at(p[0], p[1]);
61
+ const [bx, by] = at(q[0], q[1]);
62
+ const len = Math.hypot(bx - ax, by - ay);
63
+ const gate = L.gates.find((g) => g.flat === i);
64
+ const wallOf = (id, x0, y0, x1, y1, z0, z1, svg, kind = "wall") => ({ ...shy(wall(id, kind, x0, y0, x1, y1, z0, z1, svg), centre), fadeTo: 0.3, fadeAt: 0.2 });
65
+ if (gate === undefined) {
66
+ planes.push(wallOf(`fence-${i + 1}`, ax, ay, bx, by, h0 + rail, top - rail, meshOf(len, top - rail - (h0 + rail)), "net"));
67
+ }
68
+ else {
69
+ const [fx, fy] = at(gate.from[0], gate.from[1]);
70
+ const [tx, ty] = at(gate.to[0], gate.to[1]);
71
+ const left = Math.hypot(fx - ax, fy - ay);
72
+ const open = Math.hypot(tx - fx, ty - fy);
73
+ const right = Math.hypot(bx - tx, by - ty);
74
+ planes.push(wallOf(`fence-${i + 1}a`, ax, ay, fx, fy, h0 + rail, top - rail, meshOf(left, top - rail - (h0 + rail)), "net"));
75
+ planes.push(wallOf(`fence-${i + 1}b`, tx, ty, bx, by, h0 + rail, top - rail, meshOf(right, top - rail - (h0 + rail)), "net"));
76
+ // Over the door: mesh from the door's head to the top pad. The door itself is a frame of padded rails round mesh, closed.
77
+ planes.push(wallOf(`fence-${i + 1}-over`, fx, fy, tx, ty, h0 + doorH, top - rail, meshOf(open, top - rail - (h0 + doorH)), "net"));
78
+ const leafH = doorH - rail;
79
+ const frame = `<rect x="${n(rail / 2)}" y="${n(rail / 2)}" width="${n(open - rail)}" height="${n(leafH - rail)}" class="u-gateframe" fill="none" stroke-width="${n(rail)}"/>`;
80
+ planes.push(wallOf(`gate-${gate.side}`, fx, fy, tx, ty, h0 + rail, h0 + doorH, `<rect width="${n(open)}" height="${n(doorH - rail)}" class="u-netfill"/>${threads(mesh(open, doorH - rail, CELL), CELL)}${frame}`, "wall"));
81
+ }
82
+ // The pads: along the top (the whole flat), and along the foot (except across a gate).
83
+ planes.push(wallOf(`fence-top-${i + 1}`, ax, ay, bx, by, top - rail, top, `<rect width="${n(len)}" height="${n(rail)}" class="u-cagepad"/>`, "rail"));
84
+ if (gate === undefined)
85
+ planes.push(wallOf(`fence-foot-${i + 1}`, ax, ay, bx, by, h0, h0 + rail, `<rect width="${n(len)}" height="${n(rail)}" class="u-cagepad"/>`, "rail"));
86
+ });
87
+ items.push({ id: "fence", kind: "cage-fence", at: centre, height: top - h0, planes });
88
+ items.push({ id: "posts", kind: "cage-posts", at: centre, height: postTop - h0, planes: posts });
89
+ void thin;
90
+ return items;
91
+ }
package/dist/uprights.js CHANGED
@@ -23,7 +23,7 @@ import { isPoolSport, poolPlan, feet as poolFeet } from "./pool.js";
23
23
  import { poolUprights } from "./uprights.pools.js";
24
24
  import { athleticsUprights, skatingUprights } from "./uprights.track.js";
25
25
  import { budoUprights } from "./uprights.budo.js";
26
- import { isBudoSport } from "./budo/plan.js";
26
+ import { isBudoSport, isMatSport } from "./budo/plan.js";
27
27
  import { courtUprights, rinkUprights } from "./uprights.rinks.js";
28
28
  import { convertLength } from "./units.js";
29
29
  import { sheetFor } from "./sheet.js";
@@ -32,7 +32,7 @@ import { NO_VENUE, standsVenue } from "./venue.js";
32
32
  /** All the planes of all the things. */
33
33
  export const planesOf = (u) => u.items.flatMap((item) => item.planes);
34
34
  /** The unit each sport's rulebook gives its heights in, when the options name none. */
35
- const RULEBOOK_UNIT = { volleyball: "m", badminton: "m", tabletennis: "m", padel: "m", squash: "m", athletics: "m", skating: "m", judo: "m", karate: "m", kendo: "m", sumo: "m", kyudo: "m", dojo: "m", swimming: "m", waterpolo: "m", diving: "m", artisticswimming: "m", sepaktakraw: "m", teqball: "m", roundnet: "m", netball: "m", soccer: "m", handball: "m", fieldhockey: "m", rugby: "m", afl: "m", gaelic: "m" };
35
+ const RULEBOOK_UNIT = { volleyball: "m", badminton: "m", tabletennis: "m", padel: "m", squash: "m", athletics: "m", skating: "m", judo: "m", karate: "m", kendo: "m", sumo: "m", kyudo: "m", dojo: "m", mma: "ft", swimming: "m", waterpolo: "m", diving: "m", artisticswimming: "m", sepaktakraw: "m", teqball: "m", roundnet: "m", netball: "m", soccer: "m", handball: "m", fieldhockey: "m", rugby: "m", afl: "m", gaelic: "m" };
36
36
  /** What stands on the surface the options draw: nothing on a curling sheet, which is flat. */
37
37
  export function uprightsFor(o, settings = {}) {
38
38
  const { sport, league } = chooseLeague(o);
@@ -107,7 +107,7 @@ export function uprightsFor(o, settings = {}) {
107
107
  thin = thinnest(area.x1, area.y1);
108
108
  items = skatingUprights({ ...o, sport }, thin).items;
109
109
  }
110
- else if (isBudoSport(sport)) {
110
+ else if (isMatSport(sport)) {
111
111
  const built = budoUprights({ ...o, sport }, 0.3);
112
112
  area = built.area;
113
113
  thin = thinnest(area.x1, area.y1);
@@ -0,0 +1,12 @@
1
+ import type { BudoPlan } from "./budo/plan.ts";
2
+ import type { RingLayout } from "./budo/ring.ts";
3
+ import { type Plane, type Upright } from "./turn.kit.ts";
4
+ /** The platform of a ring as a solid block: its four sides and its top, which is the drawing's own canvas in the platform's rectangle. */
5
+ export declare function platformPlanes(b: {
6
+ x0: number;
7
+ y0: number;
8
+ x1: number;
9
+ y1: number;
10
+ }, at: (x: number, y: number) => readonly [number, number], h: number): Plane[];
11
+ /** What stands on a ring: the platform, its steps, the posts, the ropes and their ties. */
12
+ export declare function ringUprights(plan: BudoPlan, L: RingLayout, at: (x: number, y: number) => readonly [number, number]): Upright[];
@@ -0,0 +1,76 @@
1
+ import { box, flat, n, pole, bar, wall } from "./turn.kit.js";
2
+ const K = 1 / 0.3048;
3
+ /** The platform of a ring as a solid block: its four sides and its top, which is the drawing's own canvas in the platform's rectangle. */
4
+ export function platformPlanes(b, at, h) {
5
+ const corners = [at(b.x0, b.y0), at(b.x1, b.y0), at(b.x1, b.y1), at(b.x0, b.y1)];
6
+ const planes = [];
7
+ corners.forEach((a, i) => {
8
+ const c = corners[(i + 1) % 4];
9
+ planes.push(wall(`deck-${i + 1}`, "wall", a[0], a[1], c[0], c[1], 0, h, `<rect width="${n(Math.hypot(c[0] - a[0], c[1] - a[1]))}" height="${n(h)}" class="u-deck-side"/>`));
10
+ });
11
+ planes.push({ ...flat("deck-top", "platform", corners[0][0], corners[0][1], corners[2][0], corners[2][1], h, ""), crop: true });
12
+ return planes;
13
+ }
14
+ /** What stands on a ring: the platform, its steps, the posts, the ropes and their ties. */
15
+ export function ringUprights(plan, L, at) {
16
+ const fig = plan.figures;
17
+ const h0 = L.height * K;
18
+ const centre = at(L.centre[0], L.centre[1]);
19
+ const items = [{ id: "deck", kind: "deck", at: centre, height: h0, planes: platformPlanes(L.platform, at, h0) }];
20
+ if (L.steps.length > 0) {
21
+ const s = fig.platform.steps;
22
+ const planes = [];
23
+ for (const st of L.steps) {
24
+ const north = st.edge === "north";
25
+ for (let t = 0; t < s.treads; t += 1) {
26
+ const y0 = north ? st.box.y0 + t * s.tread : st.box.y0;
27
+ const y1 = north ? st.box.y1 : st.box.y1 - t * s.tread;
28
+ const [x0, ya] = at(st.box.x0, y0);
29
+ const [x1, yb] = at(st.box.x1, y1);
30
+ planes.push(...box(`step-${st.corner}-${t + 1}`, "platform", { x0, y0: ya, x1, y1: yb }, (h0 * (t + 1)) / s.treads, "u-step"));
31
+ }
32
+ }
33
+ items.push({ id: "steps", kind: "deck", at: centre, height: h0, planes });
34
+ }
35
+ // The posts: solid, two crossed strips as wide as the pad, in the corner's colour, from the platform to the height the rules give over the ring floor.
36
+ const top = h0 + fig.post.height * K;
37
+ const padW = fig.post.pad * K;
38
+ const posts = L.corners.flatMap((c) => {
39
+ const [px, py] = at(c.post[0], c.post[1]);
40
+ return pole(`post-${c.index + 1}`, "post", px, py, h0, top, padW, `u-corner-${c.colour}`);
41
+ });
42
+ // The ropes: along each side between the corners of the rope square, and at each corner out to the post by the extension.
43
+ const ropeW = Math.max(fig.ropes.diameter.drawn, 0.03) * K;
44
+ const ropes = [];
45
+ fig.ropes.heights.forEach((rh, level) => {
46
+ const z = h0 + rh * K;
47
+ const sq = L.corners.map((c) => at(c.rope[0], c.rope[1]));
48
+ for (let i = 0; i < 4; i += 1) {
49
+ const a = sq[i];
50
+ const b = sq[(i + 1) % 4];
51
+ ropes.push(...bar(`rope-${level + 1}-${i + 1}`, "rail", [a[0], a[1], z], [b[0], b[1], z], ropeW, "u-rope"));
52
+ }
53
+ L.corners.forEach((c, i) => {
54
+ const a = at(c.rope[0], c.rope[1]);
55
+ const p = at(c.post[0], c.post[1]);
56
+ ropes.push(...bar(`rope-${level + 1}-ext-${i + 1}`, "rail", [a[0], a[1], z], [p[0], p[1], z], ropeW, "u-rope"));
57
+ });
58
+ });
59
+ // Two ties on each side, a strip joining the ropes where they are a third and two thirds along, as the rules ask (spacers).
60
+ const lo = h0 + fig.ropes.heights[0] * K;
61
+ const hi = h0 + fig.ropes.heights[fig.ropes.heights.length - 1] * K;
62
+ const ties = [];
63
+ const sq = L.corners.map((c) => at(c.rope[0], c.rope[1]));
64
+ for (let i = 0; i < 4; i += 1) {
65
+ const a = sq[i];
66
+ const b = sq[(i + 1) % 4];
67
+ for (const t of [1 / 3, 2 / 3]) {
68
+ const x = a[0] + (b[0] - a[0]) * t;
69
+ const y = a[1] + (b[1] - a[1]) * t;
70
+ ties.push(...pole(`tie-${i + 1}-${t < 0.5 ? 1 : 2}`, "rail", x, y, lo, hi, 0.1 * K, "u-rope-tie"));
71
+ }
72
+ }
73
+ items.push({ id: "posts", kind: "ring-posts", at: centre, height: top - h0, planes: posts });
74
+ items.push({ id: "ropes", kind: "ring-ropes", at: centre, height: hi - h0, planes: [...ropes, ...ties] });
75
+ return items;
76
+ }
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** The package's version: the same as package.json's, and a test holds them to each other. */
2
- export declare const VERSION = "0.19.0";
2
+ export declare const VERSION = "0.21.0";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** The package's version: the same as package.json's, and a test holds them to each other. */
2
- export const VERSION = "0.19.0";
2
+ export const VERSION = "0.21.0";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@johnmorrisdotca/kyogijo-stadiums",
3
- "version": "0.19.0",
4
- "description": "Kyogijo Stadiums 競技場, 39 sports' surfaces as SVG, drawn to scale from the rulebooks: NFL, CFL and IFAF football fields, an NHL rink, an NBA court, MLB ballparks, soccer pitches, curling sheets, athletics stadiums, speed skating, short track and figure skating rinks, swimming pools, water polo fields, diving wells, artistic swimming areas, and the courts and fields of tennis, volleyball (indoor, beach and sitting), badminton, pickleball, table tennis, padel, squash, racquetball, sepak takraw, teqball, roundnet, netball, lacrosse, rugby, Australian football, Gaelic games, cricket, field hockey and handball, and the budo of judo, karate, kendo, sumo and kyudo with a dojo of tatami laid as real units, with each team's name and logo on its side and the score in the middle, stands and a crowd, a pageant of flags, and a 3D view. Light and dark, accessible, a compact badge for lists, a helper for React and a custom element. Zero dependencies.",
3
+ "version": "0.21.0",
4
+ "description": "Kyogijo Stadiums 競技場, 40 sports' surfaces as SVG, drawn to scale from the rulebooks: NFL, CFL and IFAF football fields, an NHL rink, an NBA court, MLB ballparks, soccer pitches, curling sheets, athletics stadiums, speed skating, short track and figure skating rinks, swimming pools, water polo fields, diving wells, artistic swimming areas, and the courts and fields of tennis, volleyball (indoor, beach and sitting), badminton, pickleball, table tennis, padel, squash, racquetball, sepak takraw, teqball, roundnet, netball, lacrosse, rugby, Australian football, Gaelic games, cricket, field hockey and handball, and the budo of judo, karate, kendo, sumo and kyudo with a dojo of tatami laid as real units, the MMA cage, with each team's name and logo on its side and the score in the middle, stands and a crowd, a pageant of flags, and a 3D view. Light and dark, accessible, a compact badge for lists, a helper for React and a custom element. Zero dependencies.",
5
5
  "keywords": [
6
6
  "sports",
7
7
  "scoreboard",
@@ -50,7 +50,9 @@
50
50
  "sumo",
51
51
  "kyudo",
52
52
  "dojo",
53
- "tatami"
53
+ "tatami",
54
+ "mma",
55
+ "cage"
54
56
  ],
55
57
  "homepage": "https://johnmorrisdotca.github.io/kyogijo-stadiums/",
56
58
  "repository": {