@johnmorrisdotca/kyogijo-stadiums 0.5.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.
Files changed (193) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/NOTICE.md +179 -3
  3. package/README.md +43 -11
  4. package/dist/arenas-entry.d.ts +4 -0
  5. package/dist/arenas-entry.js +3 -0
  6. package/dist/arenas.d.ts +125 -0
  7. package/dist/arenas.data.d.ts +2 -0
  8. package/dist/arenas.data.js +3763 -0
  9. package/dist/arenas.js +72 -0
  10. package/dist/atlas-entry.d.ts +3 -1
  11. package/dist/atlas-entry.js +3 -2
  12. package/dist/atlas.d.ts +37 -19
  13. package/dist/atlas.js +92 -7
  14. package/dist/background.js +2 -1
  15. package/dist/budo/describe.d.ts +13 -0
  16. package/dist/budo/describe.js +120 -0
  17. package/dist/budo/dojo.api.d.ts +64 -0
  18. package/dist/budo/dojo.api.js +46 -0
  19. package/dist/budo/dojo.d.ts +72 -0
  20. package/dist/budo/dojo.js +300 -0
  21. package/dist/budo/judo.d.ts +61 -0
  22. package/dist/budo/judo.js +109 -0
  23. package/dist/budo/karate.d.ts +29 -0
  24. package/dist/budo/karate.js +80 -0
  25. package/dist/budo/kendo.d.ts +18 -0
  26. package/dist/budo/kendo.js +44 -0
  27. package/dist/budo/kimarite.d.ts +19 -0
  28. package/dist/budo/kimarite.js +33 -0
  29. package/dist/budo/kit.d.ts +16 -0
  30. package/dist/budo/kit.js +24 -0
  31. package/dist/budo/kyudo.d.ts +28 -0
  32. package/dist/budo/kyudo.js +66 -0
  33. package/dist/budo/looks.d.ts +28 -0
  34. package/dist/budo/looks.js +58 -0
  35. package/dist/budo/parts.d.ts +32 -0
  36. package/dist/budo/parts.js +10 -0
  37. package/dist/budo/plan.d.ts +64 -0
  38. package/dist/budo/plan.js +139 -0
  39. package/dist/budo/room.d.ts +133 -0
  40. package/dist/budo/room.js +111 -0
  41. package/dist/budo/sumo.d.ts +31 -0
  42. package/dist/budo/sumo.js +71 -0
  43. package/dist/budo/tatami.d.ts +55 -0
  44. package/dist/budo/tatami.js +156 -0
  45. package/dist/budo/types.d.ts +192 -0
  46. package/dist/budo/types.js +2 -0
  47. package/dist/budo-entry.d.ts +22 -0
  48. package/dist/budo-entry.js +13 -0
  49. package/dist/budo.board.d.ts +28 -0
  50. package/dist/budo.board.js +81 -0
  51. package/dist/budo.score.d.ts +18 -0
  52. package/dist/budo.score.js +52 -0
  53. package/dist/budo.style.d.ts +6 -0
  54. package/dist/budo.style.js +67 -0
  55. package/dist/charts.baseball.js +1 -1
  56. package/dist/charts.js +4 -4
  57. package/dist/charts.soccer.js +3 -3
  58. package/dist/charts.types.d.ts +10 -0
  59. package/dist/colour.d.ts +4 -4
  60. package/dist/colour.js +4 -4
  61. package/dist/crowd.d.ts +11 -1
  62. package/dist/crowd.draw.js +15 -9
  63. package/dist/crowd.js +17 -2
  64. package/dist/draw.js +156 -31
  65. package/dist/element-entry.d.ts +2 -0
  66. package/dist/element-entry.js +1 -0
  67. package/dist/element.d.ts +2 -2
  68. package/dist/element.js +2 -1
  69. package/dist/emblems-source.d.ts +50 -0
  70. package/dist/emblems-source.js +56 -0
  71. package/dist/eras.d.ts +3 -1
  72. package/dist/eras.js +8 -3
  73. package/dist/features.js +73 -0
  74. package/dist/field.data.d.ts +16 -0
  75. package/dist/field.data.js +50 -0
  76. package/dist/fields.kit.d.ts +2 -2
  77. package/dist/fields.types.d.ts +9 -3
  78. package/dist/formations.js +18 -7
  79. package/dist/formations.sports.d.ts +8 -0
  80. package/dist/formations.sports.js +251 -0
  81. package/dist/frames.providers.js +9 -1
  82. package/dist/halls.d.ts +65 -0
  83. package/dist/halls.js +122 -0
  84. package/dist/heat.js +17 -10
  85. package/dist/heat.zones.d.ts +4 -2
  86. package/dist/heat.zones.js +55 -3
  87. package/dist/homeside.js +7 -0
  88. package/dist/index.d.ts +15 -3
  89. package/dist/index.js +8 -1
  90. package/dist/layers-entry.d.ts +2 -1
  91. package/dist/layers-entry.js +1 -0
  92. package/dist/layers.d.ts +2 -1
  93. package/dist/layers.env.d.ts +10 -1
  94. package/dist/layers.env.js +33 -3
  95. package/dist/layers.js +30 -11
  96. package/dist/layers.types.d.ts +9 -2
  97. package/dist/leagues/budo.d.ts +196 -0
  98. package/dist/leagues/budo.js +105 -0
  99. package/dist/leagues/hockey.js +41 -19
  100. package/dist/leagues/sources.js +21 -0
  101. package/dist/leagues/types.d.ts +1 -1
  102. package/dist/leagues.d.ts +4 -1
  103. package/dist/leagues.js +102 -2
  104. package/dist/lineup.codes.d.ts +23 -0
  105. package/dist/lineup.codes.js +122 -0
  106. package/dist/logo.d.ts +25 -0
  107. package/dist/logo.js +47 -0
  108. package/dist/outline.d.ts +1 -1
  109. package/dist/outline.js +17 -3
  110. package/dist/pageant.js +7 -3
  111. package/dist/pointer-entry.d.ts +2 -0
  112. package/dist/pointer-entry.js +2 -0
  113. package/dist/pointer.d.ts +113 -0
  114. package/dist/pointer.js +151 -0
  115. package/dist/pool.d.ts +7 -7
  116. package/dist/pool.figures.d.ts +57 -55
  117. package/dist/pool.figures.js +59 -55
  118. package/dist/pool.js +7 -7
  119. package/dist/pool.labels.js +2 -1
  120. package/dist/ranges.names.js +6 -0
  121. package/dist/road.draw.js +3 -2
  122. package/dist/road.js +2 -1
  123. package/dist/road.types.d.ts +3 -0
  124. package/dist/rules.d.ts +138 -0
  125. package/dist/rules.js +511 -0
  126. package/dist/rules.types.d.ts +4 -0
  127. package/dist/rules.types.js +64 -0
  128. package/dist/score.d.ts +3 -0
  129. package/dist/score.js +23 -1
  130. package/dist/situation.d.ts +135 -0
  131. package/dist/situation.draw.d.ts +34 -0
  132. package/dist/situation.draw.js +202 -0
  133. package/dist/situation.js +337 -0
  134. package/dist/situation.style.d.ts +2 -0
  135. package/dist/situation.style.js +45 -0
  136. package/dist/situation.types.d.ts +77 -0
  137. package/dist/situation.types.js +3 -0
  138. package/dist/situation.widgets.d.ts +39 -0
  139. package/dist/situation.widgets.js +129 -0
  140. package/dist/strings.d.ts +175 -1
  141. package/dist/strings.js +364 -20
  142. package/dist/style.js +9 -2
  143. package/dist/surfaces/artistic.d.ts +3 -3
  144. package/dist/surfaces/artistic.js +3 -3
  145. package/dist/surfaces/baseball.js +2 -0
  146. package/dist/surfaces/basketball.js +1 -1
  147. package/dist/surfaces/budo.d.ts +6 -0
  148. package/dist/surfaces/budo.js +104 -0
  149. package/dist/surfaces/dive.d.ts +3 -3
  150. package/dist/surfaces/dive.js +3 -3
  151. package/dist/surfaces/football.js +7 -0
  152. package/dist/surfaces/hockey.js +3 -2
  153. package/dist/surfaces/polo.d.ts +4 -4
  154. package/dist/surfaces/polo.js +5 -5
  155. package/dist/surfaces/pool.d.ts +1 -1
  156. package/dist/surfaces/pool.js +3 -3
  157. package/dist/surfaces/surface.d.ts +32 -0
  158. package/dist/surfaces/venue.d.ts +1 -1
  159. package/dist/surfaces/venue.js +1 -1
  160. package/dist/target-entry.d.ts +2 -0
  161. package/dist/target-entry.js +2 -0
  162. package/dist/target.d.ts +200 -0
  163. package/dist/target.js +525 -0
  164. package/dist/team.common.d.ts +1 -1
  165. package/dist/team.common.js +3 -3
  166. package/dist/team.formation.d.ts +3 -1
  167. package/dist/team.formation.js +3 -3
  168. package/dist/team.layers.d.ts +2 -2
  169. package/dist/team.layers.js +4 -1
  170. package/dist/team.lineup.d.ts +27 -0
  171. package/dist/team.lineup.js +207 -0
  172. package/dist/team.network.js +6 -5
  173. package/dist/team.shape.js +5 -5
  174. package/dist/team.types.d.ts +40 -1
  175. package/dist/tenants.data.js +848 -0
  176. package/dist/turn-entry.d.ts +2 -2
  177. package/dist/turn-entry.js +1 -1
  178. package/dist/turn.camera.d.ts +12 -1
  179. package/dist/turn.camera.js +18 -2
  180. package/dist/turn.dom.js +11 -9
  181. package/dist/turn.kit.d.ts +2 -2
  182. package/dist/turn.style.js +4 -3
  183. package/dist/types.d.ts +43 -7
  184. package/dist/units.js +7 -0
  185. package/dist/uprights.budo.d.ts +17 -0
  186. package/dist/uprights.budo.js +87 -0
  187. package/dist/uprights.js +10 -1
  188. package/dist/uprights.pools.js +4 -4
  189. package/dist/version.d.ts +1 -1
  190. package/dist/version.js +1 -1
  191. package/dist/zones-entry.d.ts +2 -0
  192. package/dist/zones-entry.js +2 -0
  193. package/package.json +39 -3
@@ -0,0 +1,56 @@
1
+ // Where kyogijo gets ready-made emblems from: a renderer that the page plugs in, so that kyogijo bundles no art and keeps zero dependencies. The renderer is
2
+ // `renderEmblem` of @johnmorrisdotca/dougu-sports (or any function with its shape); `useEmblems(renderEmblem)` plugs it in for the page, `emblems: renderEmblem` for one drawing.
3
+ // This module knows nothing of any emblem: it only decides whether a string might be an emblem's id, asks the renderer, and keeps what the renderer gives back.
4
+ let plugged;
5
+ let scoped;
6
+ /**
7
+ * Plug a renderer of ready-made emblems into kyogijo, for every drawing on the page: after this `logo: "crest:shield"` and `emblem: "trophy:hockey-cup"` are drawn. Call it once, at start-up. Without one, an id is
8
+ * an address and is refused. `useEmblems(undefined)` unplugs it.
9
+ * @example
10
+ * ```ts
11
+ * import { useEmblems } from "@johnmorrisdotca/kyogijo-stadiums";
12
+ * import { renderEmblem } from "@johnmorrisdotca/dougu-sports/emblems";
13
+ * useEmblems(renderEmblem);
14
+ * ```
15
+ */
16
+ export function useEmblems(render) {
17
+ plugged = typeof render === "function" ? render : undefined;
18
+ }
19
+ /** Run a drawing with a renderer for that drawing alone (the `emblems` option), putting back whatever was there. Without a renderer it runs as it is. */
20
+ export function withEmblems(render, draw) {
21
+ if (typeof render !== "function")
22
+ return draw();
23
+ const before = scoped;
24
+ scoped = render;
25
+ try {
26
+ return draw();
27
+ }
28
+ finally {
29
+ scoped = before;
30
+ }
31
+ }
32
+ /** The renderer in use: the drawing's own, else the page's, else none. */
33
+ export function emblemRenderer() {
34
+ return scoped ?? plugged;
35
+ }
36
+ /** The look of an id: lower-case words, optionally `group:name`, optionally a style. An address, a path with a dot or a slash, a data address or an SVG document never has it. */
37
+ const ID = /^[a-z0-9]+(?:-[a-z0-9]+)*(?::[a-z0-9]+(?:-[a-z0-9]+)*)?(?:\/(?:metal|line|color))?$/;
38
+ /** An id with its group, which no address has in practice: what a missing renderer is told about. */
39
+ export const GROUPED_ID = /^(?:trophy|medal|award|crest|sport|ball|gear):[a-z0-9]+(?:-[a-z0-9]+)*(?:\/(?:metal|line|color))?$/;
40
+ /** The SVG document for a value that names an emblem, drawn by the renderer in use, or `undefined` (no renderer, not the look of an id, or an id the renderer does not know). */
41
+ export function renderedEmblem(value, options) {
42
+ const render = emblemRenderer();
43
+ if (render === undefined || typeof value !== "string")
44
+ return undefined;
45
+ const text = value.trim();
46
+ if (text.length > 60 || !ID.test(text))
47
+ return undefined;
48
+ let svg;
49
+ try {
50
+ svg = render(text, options);
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ return typeof svg === "string" && /^\s*(?:<\?xml|<svg)\b/i.test(svg) ? svg : undefined;
56
+ }
package/dist/eras.d.ts CHANGED
@@ -54,6 +54,8 @@ export interface NhlRules {
54
54
  } | null;
55
55
  /** The gap between the two hash marks beside an end-zone face-off circle (Rule 1.9). */
56
56
  hashApart: number;
57
+ /** The centre red line judges the offside pass: a pass from inside a team's own defensive zone across both its blue line and the centre line, to a team-mate who has not touched it, stops play. Data only: the lines are drawn the same. */
58
+ twoLinePass: boolean;
57
59
  }
58
60
  /** The NBA court's markings in a season. Lengths are feet. */
59
61
  export interface NbaRules {
@@ -138,7 +140,7 @@ export interface EraChange {
138
140
  * import { eraChanges } from "@johnmorrisdotca/kyogijo-stadiums/eras";
139
141
  * const nhl = eraChanges("nhl");
140
142
  * console.log(nhl.length, nhl[0].id, nhl[0].from);
141
- * // 10 nhl.centreLine.1943 1943
143
+ * // 12 nhl.centreLine.1943 1943
142
144
  * ```
143
145
  */
144
146
  export declare function eraChanges(sport: EraSport): EraChange[];
package/dist/eras.js CHANGED
@@ -29,7 +29,7 @@ const wikipedia = (id, title, revision, note) => ({
29
29
  });
30
30
  /** Every page a change was read from, by id. Wikipedia is cited by revision, for facts only. */
31
31
  export const ERA_SOURCES = Object.freeze(Object.fromEntries([
32
- wikipedia("wp-offside", "Offside (ice hockey)", 1366324643, "the two blue lines of 1928-29, the centre red line introduced in 1943-44"),
32
+ wikipedia("wp-offside", "Offside (ice hockey)", 1366324643, "the two blue lines of 1928-29, the centre red line introduced in 1943-44, the offside pass judged by it until the 2005 collective bargaining agreement"),
33
33
  wikipedia("wp-rink", "Ice hockey rink", 1369579112, "the NHL's blue lines at 75 feet and goal lines at 11 feet; the trapezoid from 2005-06, 18 feet at the goal line, 22 feet from 2014-15"),
34
34
  wikipedia("wp-nhl-rules", "National Hockey League rules", 1379666522, "the trapezoid since 2005-06, lengthened by 2 feet each side in 2014"),
35
35
  {
@@ -152,6 +152,11 @@ const NHL_SPANS = {
152
152
  { from: 2005, value: { atGoalLine: 18, atBoards: 28 }, what: "The goaltender's trapezoid is marked behind each net: 18 feet at the goal line, 28 feet at the end boards.", ja: "各ゴールの裏に、ゴーリーがパックを扱える区域として台形(トラペゾイド)が引かれます。ゴールライン側が18フィート、エンドボード側が28フィートです。", sources: ["wp-rink", "wp-nhl-rules"] },
153
153
  { from: 2014, value: { atGoalLine: NHL.trapezoid.atGoalLine, atBoards: NHL.trapezoid.atBoards }, what: "The trapezoid is widened to 22 feet at the goal line (2 feet each side).", ja: "トラペゾイドのゴールライン側が左右2フィートずつ広がり、22フィートになります。", sources: ["wp-rink", "wp-nhl-rules"] },
154
154
  ],
155
+ twoLinePass: [
156
+ { from: null, value: false, what: "No two-line pass rule: there is no centre line to judge it by.", ja: "ツーライン・パス(2本のラインをまたぐパス)の反則はありません。判定に使うセンターラインがまだないためです。", sources: ["wp-offside"] },
157
+ { from: 1943, value: true, what: "The centre red line judges the two-line pass: a pass across both a team's own blue line and the centre line, to a team-mate who has not touched it, is an offside pass.", ja: "センターレッドラインでツーライン・パスを判定します。自陣のブルーラインとセンターラインの両方をまたぐパスを、まだ触れていない味方が受けると、オフサイドパスの反則になります。", sources: ["wp-offside"] },
158
+ { from: 2005, value: false, what: "The centre line no longer judges the offside pass, under the 2005 collective bargaining agreement, so a pass across two lines is legal.", ja: "2005年の労使協定により、センターラインはオフサイドパスの判定に使われなくなり、ツーライン・パスは反則ではなくなります。", sources: ["wp-offside"] },
159
+ ],
155
160
  hashApart: [
156
161
  { from: 2012, value: 3, what: "The two hash marks beside each end-zone face-off circle are 3 feet apart (Rule 1.9 of 2012-13; no earlier season is cited).", ja: "エンドゾーンのフェイスオフサークルの両脇にある2本のハッシュマークは、間隔が3フィート(約91cm)です(2012-13シーズンのルール1.9。それ以前のシーズンを示す資料は見つかっていません)。", sources: ["nhl-rules-2012", "nhl-hash-2014", "cbs-hash-2014"] },
157
162
  { from: 2014, value: NHL.hashApart, what: "The hash marks move apart to 5 feet 7 inches, more in line with the marks on international ice.", ja: "2本のハッシュマークの間隔が5フィート7インチ(約1.7m)に広がり、国際大会のリンクにあるマークに近づきます。", sources: ["nhl-hash-2014", "cbs-hash-2014"] },
@@ -258,7 +263,7 @@ const SPANS = {
258
263
  function present(sport) {
259
264
  switch (sport) {
260
265
  case "nhl":
261
- return { centreLine: true, goalLine: NHL.goalLine, blueLine: NHL.blueLine, trapezoid: { atGoalLine: NHL.trapezoid.atGoalLine, atBoards: NHL.trapezoid.atBoards }, hashApart: NHL.hashApart };
266
+ return { centreLine: true, goalLine: NHL.goalLine, blueLine: NHL.blueLine, trapezoid: { atGoalLine: NHL.trapezoid.atGoalLine, atBoards: NHL.trapezoid.atBoards }, hashApart: NHL.hashApart, twoLinePass: false };
262
267
  case "nba":
263
268
  return { keyWidth: NBA.lane, threePoint: { radius: NBA.threePoint.radius }, restrictedArea: true };
264
269
  case "nfl":
@@ -298,7 +303,7 @@ const featuresOf = (sport) => Object.entries(SPANS[sport]);
298
303
  * import { eraChanges } from "@johnmorrisdotca/kyogijo-stadiums/eras";
299
304
  * const nhl = eraChanges("nhl");
300
305
  * console.log(nhl.length, nhl[0].id, nhl[0].from);
301
- * // 10 nhl.centreLine.1943 1943
306
+ * // 12 nhl.centreLine.1943 1943
302
307
  * ```
303
308
  */
304
309
  export function eraChanges(sport) {
package/dist/features.js CHANGED
@@ -86,6 +86,73 @@ const SKATING = [
86
86
  f("technical-panel", "--ky-ink", "The technical panel's table."),
87
87
  f("kiss-and-cry", "--ky-red", "The kiss and cry."),
88
88
  ];
89
+ const JUDO = [
90
+ f("apron", "--ky-apron", "The ground round the competition area."),
91
+ f("free-zone", "--ky-free", "The free zone of 50 cm kept round the competition area."),
92
+ f("platform", "--ky-bud-floor", "The platform under the tatami, when there is one."),
93
+ f("floor", "--ky-bud-floor", "The arena floor under the surface, when there is one (the Budokan's)."),
94
+ f("contest-area", "--ky-surface", "The tatami of the contest area."),
95
+ f("safety-area", "--ky-surface-alt", "The tatami of the safety area."),
96
+ f("danger-zone", "--ky-red", "The red tatami of the danger zone inside a contest area (the AJJF's)."),
97
+ f("seams", "--ky-ink", "The seams between the mats."),
98
+ f("start-right", ["--ky-blue", "--ky-red"], "The tape where the contestant to the referee's right starts: blue, or red in the AJJF's."),
99
+ f("start-left", "--ky-line", "The tape where the contestant to the referee's left starts."),
100
+ f("officials", "--ky-ink", "The technical table."),
101
+ ];
102
+ const KARATE = [
103
+ f("apron", "--ky-apron", "The ground round the mats."),
104
+ f("floor", "--ky-bud-floor", "The arena floor under the surface, when there is one (the Budokan's)."),
105
+ f("safety-area", "--ky-surface-alt", "The mats of the safety area."),
106
+ f("boundary-band", "--ky-red", "The outer metre of a kumite area, in another colour."),
107
+ f("competition-area", "--ky-surface", "The mats inside the boundary band."),
108
+ f("start-mats", "--ky-red", "The two mats turned over at the start."),
109
+ f("seams", "--ky-ink", "The seams between the mats."),
110
+ f("judges", "--ky-ink", "The judges' seats."),
111
+ f("referee", "--ky-ink", "The referee's place."),
112
+ f("officials", "--ky-ink", "The officials' table."),
113
+ ];
114
+ const KENDO = [
115
+ f("apron", "--ky-apron", "The ground round the shiai-jo."),
116
+ f("outside", "--ky-free", "The 1.5 m kept clear outside the boundary lines."),
117
+ f("floor", "--ky-bud-floor", "The wooden floor."),
118
+ f("boards", "--ky-ink", "The seams between the floorboards."),
119
+ f("boundary-lines", "--ky-line", "The boundary lines."),
120
+ f("cross", "--ky-line", "The cross at the centre."),
121
+ f("start-lines", "--ky-line", "The two kaishi-sen."),
122
+ f("outer-boundary", "--ky-ink", "The outer boundary, 1.5 m outside."),
123
+ ];
124
+ const SUMO = [
125
+ f("apron", "--ky-apron", "The ground round the dohyō."),
126
+ f("clay", "--ky-dirt", "The clay of the platform and of the ring."),
127
+ f("jano-me", "--ky-sand", "The sand outside the tawara."),
128
+ f("tawara", "--ky-bud-straw", "The tawara of the ring."),
129
+ f("shikiri-sen", "--ky-line", "The two shikiri-sen."),
130
+ ];
131
+ const KYUDO = [
132
+ f("apron", "--ky-apron", "The ground round the range."),
133
+ f("shajo", "--ky-bud-floor", "The floor of the shajō."),
134
+ f("yamichi", "--ky-surface", "The yamichi."),
135
+ f("yatori-michi", "--ky-surface-alt", "The path for fetching the arrows."),
136
+ f("azuchi", "--ky-dirt", "The azuchi, the mound."),
137
+ f("shooting-positions", "--ky-line", "The shooting positions and their line."),
138
+ f("honza", "--ky-line", "The honza and their line."),
139
+ f("targets", "--ky-line", "The targets."),
140
+ f("roofs", "--ky-ink", "The outlines of the roofs of the shajō and the matoba."),
141
+ ];
142
+ const DOJO = [
143
+ f("apron", "--ky-apron", "The ground round the dojo."),
144
+ f("mats", "--ky-surface", "The mats, or the first tone of a checker or a competition floor."),
145
+ f("mats-alt", "--ky-surface-alt", "The second tone of a checker or a competition floor."),
146
+ f("border", "--ky-red", "The border of another colour of a border floor."),
147
+ f("seams", "--ky-ink", "The seams between the mats."),
148
+ f("heri", "--ky-ink", "The heri, the cloth along the long sides of a traditional mat."),
149
+ f("walls", "--ky-boards", "The walls."),
150
+ f("doors", "--ky-apron", "The doors."),
151
+ f("windows", "--ky-blue", "The windows."),
152
+ f("shrine", "--ky-red", "The shinzen, the shrine."),
153
+ f("dais", "--ky-bud-floor", "The raised platform of the seat of honour."),
154
+ f("banner", "--ky-ink", "The banner on the kamiza wall."),
155
+ ];
89
156
  const KEY = ["--ky-key", "--ky-key-left", "--ky-key-right"];
90
157
  const BASKETBALL = [
91
158
  f("apron", "--ky-apron", "The ground round the court."),
@@ -360,6 +427,12 @@ export const FEATURE_INFO = Object.freeze({
360
427
  handball: HANDBALL,
361
428
  athletics: ATHLETICS,
362
429
  skating: SKATING,
430
+ judo: JUDO,
431
+ karate: KARATE,
432
+ kendo: KENDO,
433
+ sumo: SUMO,
434
+ kyudo: KYUDO,
435
+ dojo: DOJO,
363
436
  });
364
437
  /**
365
438
  * The names of the features of each sport: the keys `featureColors` takes. Football's three fields have the same, and so have the five net sports.
@@ -0,0 +1,16 @@
1
+ import type { SurfaceOptions } from "./types.ts";
2
+ /** The `data-box` and `data-rules` of a drawing's surface group, or nothing for a drawing the question does not apply to (a special game). */
3
+ export declare function fieldAttributes(o: SurfaceOptions): {
4
+ "data-box"?: string;
5
+ "data-rules"?: string;
6
+ };
7
+ /** The box and the options a surface group carries, or `undefined` when it carries none. */
8
+ export declare function readField(get: (name: string) => string | null): {
9
+ box: {
10
+ x: number;
11
+ y: number;
12
+ w: number;
13
+ h: number;
14
+ };
15
+ rules: Record<string, unknown>;
16
+ } | undefined;
@@ -0,0 +1,50 @@
1
+ // What a drawing writes on its surface group so that a page can ask the drawing where a click is (pointer.ts): the box of the playing surface in feet in the
2
+ // drawing's wide frame, and the few options that decide its rules (the league, the season, the park, the pitch). The group's own `transform` is the quarter turn of a
3
+ // tall drawing, so its coordinates are always the wide frame's, whatever the drawing's shape on the page.
4
+ import { num } from "./format.js";
5
+ import { outlineOf } from "./outline.js";
6
+ const SIMPLE = ["league", "year", "pitch", "park", "fence", "units", "field"];
7
+ const COMPLEX = ["sheet", "net", "pool", "athletics", "skating"];
8
+ /** The longest the options that hold data of their own (a pool's race, an athletics meeting) may be, written out, before the drawing leaves them out of the page. */
9
+ const MOST = 600;
10
+ /** The `data-box` and `data-rules` of a drawing's surface group, or nothing for a drawing the question does not apply to (a special game). */
11
+ export function fieldAttributes(o) {
12
+ if (o.host !== undefined)
13
+ return {};
14
+ try {
15
+ const { box } = outlineOf(o);
16
+ const rules = {};
17
+ for (const key of SIMPLE)
18
+ if (o[key] !== undefined)
19
+ rules[key] = o[key];
20
+ for (const key of COMPLEX)
21
+ if (o[key] !== undefined && JSON.stringify(o[key]).length <= MOST)
22
+ rules[key] = o[key];
23
+ return { "data-box": [box.x, box.y, box.w, box.h].map(num).join(" "), "data-rules": Object.keys(rules).length === 0 ? undefined : JSON.stringify(rules) };
24
+ }
25
+ catch {
26
+ return {};
27
+ }
28
+ }
29
+ /** The box and the options a surface group carries, or `undefined` when it carries none. */
30
+ export function readField(get) {
31
+ const raw = get("data-box");
32
+ if (raw === null)
33
+ return undefined;
34
+ const [x, y, w, h] = raw.split(" ").map(Number);
35
+ if (![x, y, w, h].every(Number.isFinite))
36
+ return undefined;
37
+ let rules = {};
38
+ const text = get("data-rules");
39
+ if (text !== null) {
40
+ try {
41
+ const parsed = JSON.parse(text);
42
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed))
43
+ rules = parsed;
44
+ }
45
+ catch {
46
+ rules = {};
47
+ }
48
+ }
49
+ return { box: { x, y, w, h }, rules };
50
+ }
@@ -1,4 +1,4 @@
1
- import type { AthleticsMark, SkatingMark, ArcShape, BarShape, BoxShape, Dash, DotShape, LineShape, Outline, PathShape, PolyShape, RingShape } from "./fields.types.ts";
1
+ import type { AthleticsMark, SkatingMark, BudoMark, ArcShape, BarShape, BoxShape, Dash, DotShape, LineShape, Outline, PathShape, PolyShape, RingShape } from "./fields.types.ts";
2
2
  import type { Span } from "./leagues/fields.ts";
3
3
  import { type PlateSpot, type Zone } from "./surfaces/surface.ts";
4
4
  import type { Box } from "./types.ts";
@@ -8,7 +8,7 @@ interface Style {
8
8
  dash?: Dash;
9
9
  /** The least this shape is drawn at, in feet, when the drawing is not at the true widths (a crease on a pitch has to stay thin beside a ground). */
10
10
  least?: number;
11
- cls?: "ky-line" | "ky-red" | AthleticsMark | SkatingMark;
11
+ cls?: "ky-line" | "ky-red" | AthleticsMark | SkatingMark | BudoMark;
12
12
  }
13
13
  /** A line from one point to another. */
14
14
  export declare const line: (id: string, feature: string, x0: number, y0: number, x1: number, y1: number, style?: Style) => LineShape;
@@ -14,7 +14,7 @@ interface Stroked extends Named {
14
14
  /** The least this shape is drawn at, in feet, when the drawing is not at true widths: the plan's `drawnLine` when missing. */
15
15
  least?: number;
16
16
  /** The class it is painted with: the ordinary line (`ky-line`, white) unless it is a red line (`ky-red`), or one of athletics' coloured marks (yellow, blue, green, black or red). */
17
- cls?: "ky-line" | "ky-red" | AthleticsMark | SkatingMark;
17
+ cls?: "ky-line" | "ky-red" | AthleticsMark | SkatingMark | BudoMark;
18
18
  }
19
19
  /** The coloured marks of an athletics track: the yellow of the 4 x 100 m's takeover zones, the blue of the 4 x 400 m's and the 110 m hurdles (red on a blue track), the green of the 400 m hurdles and the breakline, black marks and red ones. */
20
20
  /** The fills of an athletics track's coloured marks (a bar of yellow, blue, green, black or red). */
@@ -22,6 +22,10 @@ export type AthleticsFill = "ky-ath-y-fill" | "ky-ath-b-fill" | "ky-ath-g-fill"
22
22
  export type AthleticsMark = "ky-ath-y" | "ky-ath-b" | "ky-ath-g" | "ky-ath-k" | "ky-ath-r" | "ky-ath-s";
23
23
  /** The coloured marks of a skating rink: the blue lines that demarcate the lanes, the red starting, finishing and coaches' lines, black lines, the dotted blocks of a curve. */
24
24
  export type SkatingMark = "ky-ska-b" | "ky-ska-r" | "ky-ska-k" | "ky-ska-blocks";
25
+ /** The coloured marks of a budō surface: the white line, the blue, white and red tape, the seam between mats. */
26
+ /** The fills of a budō surface's tape: blue, white, red and ink. */
27
+ export type BudoFill = "ky-bud-blue-fill" | "ky-bud-white-fill" | "ky-bud-red-fill" | "ky-bud-ink-fill";
28
+ export type BudoMark = "ky-bud-line" | "ky-bud-blue" | "ky-bud-white" | "ky-bud-red" | "ky-bud-seam" | "ky-bud-ink";
25
29
  /** A line from one point to another. */
26
30
  export interface LineShape extends Stroked {
27
31
  kind: "line";
@@ -74,7 +78,7 @@ export interface DotShape extends Named {
74
78
  export interface BarShape extends Named {
75
79
  kind: "bar";
76
80
  /** The class it is filled with, when it is not the line's colour. */
77
- cls?: "ky-fill-line" | AthleticsFill;
81
+ cls?: "ky-fill-line" | AthleticsFill | BudoFill;
78
82
  x0: number;
79
83
  y0: number;
80
84
  x1: number;
@@ -90,10 +94,12 @@ export type Shape = LineShape | ArcShape | RingShape | BoxShape | PolyShape | Do
90
94
  /** The areas of an athletics stadium: the track, the grass, the sand of a pit, the mat of a jump, the water of a pit, the concrete of a circle and a runway's cover. */
91
95
  /** The areas of a skating rink: the ice, the floor of the infield, the warm-up lane, the padding and the furniture. */
92
96
  export type SkatingArea = "ky-ska-ice" | "ky-ska-floor" | "ky-ska-warm" | "ky-ska-pad" | "ky-ska-desk" | "ky-ska-kiss";
97
+ /** The areas of a budō surface: the mats in three tones, the heri of a mat, the floor, the walls, the platform and the furniture, the clay and the sand and the straw of a dohyō, the azuchi and the yamichi. */
98
+ export type BudoArea = "ky-bud-t1" | "ky-bud-t2" | "ky-bud-t3" | "ky-bud-heri" | "ky-bud-floor" | "ky-bud-wall" | "ky-bud-window" | "ky-bud-door" | "ky-bud-platform" | "ky-bud-free" | "ky-bud-desk" | "ky-bud-clay" | "ky-bud-sand" | "ky-bud-tawara" | "ky-bud-azuchi" | "ky-bud-roof" | "ky-bud-yamichi" | "ky-bud-shrine" | "ky-bud-dais" | "ky-bud-banner" | "ky-bud-lane" | "ky-bud-mato" | "ky-bud-tassel-e" | "ky-bud-tassel-s" | "ky-bud-tassel-w" | "ky-bud-tassel-n" | "ky-bud-seat";
93
99
  export type AthleticsArea = "ky-ath-track" | "ky-ath-grass" | "ky-ath-sand" | "ky-ath-mat" | "ky-ath-water" | "ky-ath-concrete" | "ky-ath-pad" | "ky-ath-board" | "ky-ath-bank";
94
100
  /** A painted area, under the lines: a rectangle or an ellipse filled with a class of the stylesheet (`ky-area`, the tint of a goal area, or `ky-zone`). */
95
101
  export interface Area extends Named {
96
- cls: "ky-area" | "ky-zone" | "ky-dirt" | "ky-key" | "ky-boards" | AthleticsArea | SkatingArea;
102
+ cls: "ky-area" | "ky-zone" | "ky-dirt" | "ky-key" | "ky-boards" | AthleticsArea | SkatingArea | BudoArea;
97
103
  /** Fill the path's insides by the even-odd rule: a ring (the track between its kerb and its outer edge). */
98
104
  evenodd?: boolean;
99
105
  /** A rectangle `[x0, y0, x1, y1]`, an ellipse's centre and radii, a path of your own, or a frame: the ring between a rounded rectangle and the one `thick` outside it (boards). */
@@ -1,6 +1,12 @@
1
+ // Formations (the first five sports' here, the others' in formations.sports.ts): where the players of a team stand, as named positions in a registered coordinate frame, so that a formation lies on a surface of any
2
+ // size and can be read back in a provider's own numbers. The positions are the usual ones of each sport, and the numbers are ours: a formation is a
3
+ // convention that coaches draw a little differently each time, so each place is an example of the shape and not a measurement. The names of the
4
+ // positions are the conventional ones; the rulebooks name few of them (the Laws of the Game, Law 3, name the goalkeeper and no other position; the
5
+ // Official Baseball Rules name the nine fielders, whose numbers 1 to 9 are the scorer's). The sources are in docs/sources.md.
6
+ import { DESIGNATED_HITTER, MORE_FORMATIONS, MORE_NAMES } from "./formations.sports.js";
1
7
  const named = (en, ja) => ({ en, ja });
2
- /** The names of the positions of each sport, by the id a formation uses for them. */
3
- export const POSITION_NAMES = Object.freeze({
8
+ /** The names of the positions of the first five sports (the others are in formations.sports.ts), by the id a formation uses for them. */
9
+ const FIRST_NAMES = {
4
10
  soccer: {
5
11
  GK: named("Goalkeeper", "ゴールキーパー"),
6
12
  RB: named("Right back", "右サイドバック"),
@@ -83,7 +89,9 @@ export const POSITION_NAMES = Object.freeze({
83
89
  CF: named("Centre fielder", "センター"),
84
90
  RF: named("Right fielder", "ライト"),
85
91
  },
86
- });
92
+ };
93
+ /** The names of the positions of each sport, by the id a formation uses for them. */
94
+ export const POSITION_NAMES = Object.freeze(Object.fromEntries(["soccer", "nhl", "nba", "nfl", "mlb", "rugby", "afl", "cricket", "volleyball", "handball", "waterpolo", "fieldhockey", "netball"].map((sport) => [sport, Object.freeze({ ...FIRST_NAMES[sport], ...MORE_NAMES[sport] })])));
87
95
  const at = (id, x, y) => ({ id, x, y });
88
96
  // Soccer, in the `opta` frame: x runs 0 to 100 from the team's own goal to the one it attacks, y runs 0 to 100 up the page, so the team's right flank is the low y.
89
97
  const GK = at("GK", 5, 50);
@@ -149,7 +157,7 @@ export const FORMATIONS = Object.freeze(Object.fromEntries([
149
157
  id: "football-i-formation",
150
158
  sport: "nfl",
151
159
  frame: "nfl-tracking",
152
- name: { en: "Football, I formation", ja: "アメリカンフットボール(Iフォーメーション)" },
160
+ name: { en: "Football, I formation", ja: "アメフト(Iフォーメーション)" },
153
161
  about: { en: "Offence: the quarterback under centre with the fullback and the halfback in a line behind him, a tight end and two wide receivers.", ja: "オフェンス。センターの真後ろにクォーターバック、その後ろにフルバックとハーフバックが縦一列、タイトエンド1人とワイドレシーバー2人。" },
154
162
  positions: [...LINE, at("QB", 58.8, 26.67), at("FB", 55, 26.67), at("HB", 52, 26.67), at("TE", 60, 22.4), at("WR1", 60, 50), at("WR2", 58.5, 4)],
155
163
  },
@@ -157,7 +165,7 @@ export const FORMATIONS = Object.freeze(Object.fromEntries([
157
165
  id: "football-shotgun",
158
166
  sport: "nfl",
159
167
  frame: "nfl-tracking",
160
- name: { en: "Football, shotgun", ja: "アメリカンフットボール(ショットガン)" },
168
+ name: { en: "Football, shotgun", ja: "アメフト(ショットガン)" },
161
169
  about: { en: "Offence: the quarterback a few yards behind the centre with a halfback beside him, a tight end and three wide receivers.", ja: "オフェンス。クォーターバックはセンターの数ヤード後ろに下がり、隣にハーフバック、タイトエンド1人とワイドレシーバー3人。" },
162
170
  positions: [...LINE, at("QB", 54, 26.67), at("HB", 54, 30), at("TE", 60, 22.4), at("WR1", 60, 50), at("WR2", 59, 5), at("WR3", 59, 41)],
163
171
  },
@@ -165,7 +173,7 @@ export const FORMATIONS = Object.freeze(Object.fromEntries([
165
173
  id: "football-4-3",
166
174
  sport: "nfl",
167
175
  frame: "nfl-tracking",
168
- name: { en: "Football, 4-3 defence", ja: "アメリカンフットボール(4-3ディフェンス)" },
176
+ name: { en: "Football, 4-3 defence", ja: "アメフト(4-3ディフェンス)" },
169
177
  about: { en: "Defence against an offence going right: four linemen, three linebackers, two cornerbacks and two safeties. Left and right are the defenders' own.", ja: "右へ進むオフェンスに対するディフェンス。ディフェンスライン4人、ラインバッカー3人、コーナーバック2人、セーフティ2人。左右はディフェンス側から見たものです。" },
170
178
  positions: [at("LDE", 61, 20), at("LDT", 61, 25), at("RDT", 61, 28.4), at("RDE", 61, 33), at("LLB", 65, 17), at("MLB", 65, 26.67), at("RLB", 65, 36), at("LCB", 65, 5), at("RCB", 65, 48), at("FS", 72, 33), at("SS", 72, 20)],
171
179
  },
@@ -173,7 +181,7 @@ export const FORMATIONS = Object.freeze(Object.fromEntries([
173
181
  id: "football-3-4",
174
182
  sport: "nfl",
175
183
  frame: "nfl-tracking",
176
- name: { en: "Football, 3-4 defence", ja: "アメリカンフットボール(3-4ディフェンス)" },
184
+ name: { en: "Football, 3-4 defence", ja: "アメフト(3-4ディフェンス)" },
177
185
  about: { en: "Defence against an offence going right: three linemen, four linebackers, two cornerbacks and two safeties. Left and right are the defenders' own.", ja: "右へ進むオフェンスに対するディフェンス。ディフェンスライン3人、ラインバッカー4人、コーナーバック2人、セーフティ2人。左右はディフェンス側から見たものです。" },
178
186
  positions: [at("LDE", 61, 21), at("NT", 61, 26.67), at("RDE", 61, 32), at("LOLB", 64.5, 15), at("LILB", 64.5, 23), at("RILB", 64.5, 30.5), at("ROLB", 64.5, 38), at("LCB", 65, 5), at("RCB", 65, 48), at("FS", 72, 33), at("SS", 72, 20)],
179
187
  },
@@ -184,6 +192,7 @@ export const FORMATIONS = Object.freeze(Object.fromEntries([
184
192
  name: { en: "Baseball, standard defence", ja: "野球(通常の守備位置)" },
185
193
  about: { en: "The nine fielders where they usually stand: a straight infield and the outfielders in their fields.", ja: "9人の野手の定位置。内野はシフトなしで、外野手はそれぞれ自分の守備範囲に立ちます。" },
186
194
  positions: [at("P", 0, 60.5), at("C", 0, -3), at("1B", 70, 78), at("2B", 36, 140), at("SS", -36, 140), at("3B", -70, 78), at("LF", -120, 260), at("CF", 0, 290), at("RF", 120, 260)],
195
+ extra: DESIGNATED_HITTER,
187
196
  },
188
197
  {
189
198
  id: "baseball-shift",
@@ -192,7 +201,9 @@ export const FORMATIONS = Object.freeze(Object.fromEntries([
192
201
  name: { en: "Baseball, infield shift against a left-handed pull hitter", ja: "野球(左打者の引っ張り対策の内野シフト)" },
193
202
  about: { en: "Three infielders on the right side of second base and the outfield turned the same way. Since 2023 MLB's Rule 5.02 requires two infielders on each side of second base, so this shift is not allowed there.", ja: "二塁ベースの一塁側に内野手3人が寄り、外野手も同じ方向に寄った守備。2023年から、MLBの規則5.02は二塁ベースの一塁側と三塁側に内野手を2人ずつ置くことを求めているため、MLBではこのシフトは認められません。" },
194
203
  positions: [at("P", 0, 60.5), at("C", 0, -3), at("1B", 82, 92), at("2B", 60, 175), at("SS", 24, 135), at("3B", -34, 138), at("LF", -70, 275), at("CF", 60, 295), at("RF", 135, 270)],
204
+ extra: DESIGNATED_HITTER,
195
205
  },
206
+ ...MORE_FORMATIONS,
196
207
  ].map((f) => [f.id, f])));
197
208
  /** The ids of the formations, in the order of the table. */
198
209
  export const FORMATION_IDS = Object.freeze(Object.keys(FORMATIONS));
@@ -0,0 +1,8 @@
1
+ import type { Named } from "./formations.ts";
2
+ import type { Formation, FormationPosition, FormationSport } from "./team.types.ts";
3
+ /** The names of the positions of the sports in this file, and of the places this file adds to the first five, by id. */
4
+ export declare const MORE_NAMES: Readonly<Partial<Record<FormationSport, Readonly<Record<string, Named>>>>>;
5
+ /** The formations of this file, in the order of the table that holds them. */
6
+ export declare const MORE_FORMATIONS: readonly Formation[];
7
+ /** The designated hitter's place, which `baseball-standard` and `baseball-shift` list and do not field. */
8
+ export declare const DESIGNATED_HITTER: readonly FormationPosition[];