@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.
Files changed (361) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/NOTICE.md +182 -2
  3. package/README.md +106 -19
  4. package/dist/annotate.js +1 -1
  5. package/dist/arenas-entry.d.ts +4 -0
  6. package/dist/arenas-entry.js +3 -0
  7. package/dist/arenas.d.ts +125 -0
  8. package/dist/arenas.data.d.ts +2 -0
  9. package/dist/arenas.data.js +3763 -0
  10. package/dist/arenas.js +72 -0
  11. package/dist/athletics/describe.d.ts +8 -0
  12. package/dist/athletics/describe.js +41 -0
  13. package/dist/athletics/events.d.ts +17 -0
  14. package/dist/athletics/events.js +48 -0
  15. package/dist/athletics/facilities.d.ts +80 -0
  16. package/dist/athletics/facilities.js +176 -0
  17. package/dist/athletics/infield.d.ts +79 -0
  18. package/dist/athletics/infield.js +166 -0
  19. package/dist/athletics/layout.d.ts +13 -0
  20. package/dist/athletics/layout.js +98 -0
  21. package/dist/athletics/oval.d.ts +57 -0
  22. package/dist/athletics/oval.js +116 -0
  23. package/dist/athletics/plan.d.ts +97 -0
  24. package/dist/athletics/plan.js +355 -0
  25. package/dist/athletics/races.d.ts +102 -0
  26. package/dist/athletics/races.js +355 -0
  27. package/dist/athletics/steeplechase.d.ts +72 -0
  28. package/dist/athletics/steeplechase.js +196 -0
  29. package/dist/athletics/stencil.d.ts +13 -0
  30. package/dist/athletics/stencil.js +85 -0
  31. package/dist/athletics/track.d.ts +54 -0
  32. package/dist/athletics/track.js +105 -0
  33. package/dist/athletics/types.d.ts +77 -0
  34. package/dist/athletics/types.js +1 -0
  35. package/dist/athletics-entry.d.ts +17 -0
  36. package/dist/athletics-entry.js +11 -0
  37. package/dist/athletics.style.d.ts +16 -0
  38. package/dist/athletics.style.js +51 -0
  39. package/dist/atlas-entry.d.ts +6 -2
  40. package/dist/atlas-entry.js +4 -2
  41. package/dist/atlas.d.ts +117 -23
  42. package/dist/atlas.js +197 -12
  43. package/dist/background.js +2 -1
  44. package/dist/budo/describe.d.ts +13 -0
  45. package/dist/budo/describe.js +120 -0
  46. package/dist/budo/dojo.api.d.ts +64 -0
  47. package/dist/budo/dojo.api.js +46 -0
  48. package/dist/budo/dojo.d.ts +72 -0
  49. package/dist/budo/dojo.js +300 -0
  50. package/dist/budo/judo.d.ts +61 -0
  51. package/dist/budo/judo.js +109 -0
  52. package/dist/budo/karate.d.ts +29 -0
  53. package/dist/budo/karate.js +80 -0
  54. package/dist/budo/kendo.d.ts +18 -0
  55. package/dist/budo/kendo.js +44 -0
  56. package/dist/budo/kimarite.d.ts +19 -0
  57. package/dist/budo/kimarite.js +33 -0
  58. package/dist/budo/kit.d.ts +16 -0
  59. package/dist/budo/kit.js +24 -0
  60. package/dist/budo/kyudo.d.ts +28 -0
  61. package/dist/budo/kyudo.js +66 -0
  62. package/dist/budo/looks.d.ts +28 -0
  63. package/dist/budo/looks.js +58 -0
  64. package/dist/budo/parts.d.ts +32 -0
  65. package/dist/budo/parts.js +10 -0
  66. package/dist/budo/plan.d.ts +64 -0
  67. package/dist/budo/plan.js +139 -0
  68. package/dist/budo/room.d.ts +133 -0
  69. package/dist/budo/room.js +111 -0
  70. package/dist/budo/sumo.d.ts +31 -0
  71. package/dist/budo/sumo.js +71 -0
  72. package/dist/budo/tatami.d.ts +55 -0
  73. package/dist/budo/tatami.js +156 -0
  74. package/dist/budo/types.d.ts +192 -0
  75. package/dist/budo/types.js +2 -0
  76. package/dist/budo-entry.d.ts +22 -0
  77. package/dist/budo-entry.js +13 -0
  78. package/dist/budo.board.d.ts +28 -0
  79. package/dist/budo.board.js +81 -0
  80. package/dist/budo.score.d.ts +18 -0
  81. package/dist/budo.score.js +52 -0
  82. package/dist/budo.style.d.ts +6 -0
  83. package/dist/budo.style.js +67 -0
  84. package/dist/charts-entry.d.ts +6 -1
  85. package/dist/charts-entry.js +3 -0
  86. package/dist/charts.athletics.d.ts +183 -0
  87. package/dist/charts.athletics.js +455 -0
  88. package/dist/charts.baseball.js +1 -1
  89. package/dist/charts.curling.heat.d.ts +24 -0
  90. package/dist/charts.curling.heat.js +116 -0
  91. package/dist/charts.curling.js +14 -3
  92. package/dist/charts.js +4 -4
  93. package/dist/charts.pool.d.ts +67 -0
  94. package/dist/charts.pool.js +76 -0
  95. package/dist/charts.skating.d.ts +204 -0
  96. package/dist/charts.skating.js +426 -0
  97. package/dist/charts.soccer.js +3 -3
  98. package/dist/charts.types.d.ts +63 -1
  99. package/dist/colour.d.ts +4 -4
  100. package/dist/colour.js +4 -4
  101. package/dist/court.d.ts +85 -2
  102. package/dist/court.js +102 -7
  103. package/dist/court.more.d.ts +46 -0
  104. package/dist/court.more.js +219 -0
  105. package/dist/courts.style.d.ts +14 -2
  106. package/dist/courts.style.js +51 -4
  107. package/dist/crowd.d.ts +164 -0
  108. package/dist/crowd.draw.d.ts +17 -0
  109. package/dist/crowd.draw.js +204 -0
  110. package/dist/crowd.js +480 -0
  111. package/dist/crowd.park.d.ts +19 -0
  112. package/dist/crowd.park.js +153 -0
  113. package/dist/curling.stats.d.ts +271 -0
  114. package/dist/curling.stats.js +301 -0
  115. package/dist/draw.d.ts +16 -0
  116. package/dist/draw.js +462 -54
  117. package/dist/element-entry.d.ts +3 -1
  118. package/dist/element-entry.js +2 -1
  119. package/dist/element.d.ts +13 -2
  120. package/dist/element.js +79 -4
  121. package/dist/emblems-source.d.ts +50 -0
  122. package/dist/emblems-source.js +56 -0
  123. package/dist/eras.d.ts +3 -1
  124. package/dist/eras.js +8 -3
  125. package/dist/features.js +204 -0
  126. package/dist/field.data.d.ts +16 -0
  127. package/dist/field.data.js +50 -0
  128. package/dist/fields.kit.d.ts +2 -2
  129. package/dist/fields.types.d.ts +24 -4
  130. package/dist/formations.js +18 -7
  131. package/dist/formations.sports.d.ts +8 -0
  132. package/dist/formations.sports.js +251 -0
  133. package/dist/frames.providers.js +71 -8
  134. package/dist/geojson.js +3 -0
  135. package/dist/geometry-entry.d.ts +2 -1
  136. package/dist/geometry-entry.js +2 -1
  137. package/dist/geometry.d.ts +20 -0
  138. package/dist/geometry.js +78 -1
  139. package/dist/grounds.d.ts +4 -0
  140. package/dist/grounds.data.js +12 -0
  141. package/dist/halls.d.ts +65 -0
  142. package/dist/halls.js +122 -0
  143. package/dist/hardwood.d.ts +31 -0
  144. package/dist/hardwood.js +157 -0
  145. package/dist/heat.js +21 -13
  146. package/dist/heat.types.d.ts +5 -0
  147. package/dist/heat.zones.d.ts +4 -2
  148. package/dist/heat.zones.js +207 -7
  149. package/dist/homeside.js +24 -0
  150. package/dist/index.d.ts +30 -4
  151. package/dist/index.js +18 -2
  152. package/dist/layers-entry.d.ts +2 -1
  153. package/dist/layers-entry.js +1 -0
  154. package/dist/layers.d.ts +2 -1
  155. package/dist/layers.env.d.ts +12 -1
  156. package/dist/layers.env.js +36 -4
  157. package/dist/layers.js +32 -13
  158. package/dist/layers.types.d.ts +9 -2
  159. package/dist/leagues/athletics.d.ts +63 -0
  160. package/dist/leagues/athletics.js +87 -0
  161. package/dist/leagues/budo.d.ts +196 -0
  162. package/dist/leagues/budo.js +105 -0
  163. package/dist/leagues/courts.d.ts +269 -4
  164. package/dist/leagues/courts.js +155 -1
  165. package/dist/leagues/hockey.js +41 -19
  166. package/dist/leagues/skating.d.ts +145 -0
  167. package/dist/leagues/skating.js +73 -0
  168. package/dist/leagues/sources.js +41 -0
  169. package/dist/leagues/types.d.ts +1 -1
  170. package/dist/leagues-entry.d.ts +4 -2
  171. package/dist/leagues-entry.js +2 -1
  172. package/dist/leagues.d.ts +17 -4
  173. package/dist/leagues.js +246 -5
  174. package/dist/lineup.codes.d.ts +23 -0
  175. package/dist/lineup.codes.js +122 -0
  176. package/dist/logo.d.ts +25 -0
  177. package/dist/logo.js +47 -0
  178. package/dist/look.d.ts +3 -3
  179. package/dist/look.js +39 -6
  180. package/dist/outline.d.ts +1 -1
  181. package/dist/outline.js +46 -4
  182. package/dist/pageant.d.ts +120 -0
  183. package/dist/pageant.draw.d.ts +21 -0
  184. package/dist/pageant.draw.js +171 -0
  185. package/dist/pageant.js +211 -0
  186. package/dist/pageant.style.d.ts +8 -0
  187. package/dist/pageant.style.js +42 -0
  188. package/dist/png.d.ts +8 -1
  189. package/dist/png.js +21 -1
  190. package/dist/pointer-entry.d.ts +2 -0
  191. package/dist/pointer-entry.js +2 -0
  192. package/dist/pointer.d.ts +113 -0
  193. package/dist/pointer.js +151 -0
  194. package/dist/pool.d.ts +176 -0
  195. package/dist/pool.figures.d.ts +306 -0
  196. package/dist/pool.figures.js +148 -0
  197. package/dist/pool.js +304 -0
  198. package/dist/pool.kit.d.ts +48 -0
  199. package/dist/pool.kit.js +141 -0
  200. package/dist/pool.labels.d.ts +20 -0
  201. package/dist/pool.labels.js +258 -0
  202. package/dist/pool.race.d.ts +65 -0
  203. package/dist/pool.race.js +140 -0
  204. package/dist/pool.replay.d.ts +46 -0
  205. package/dist/pool.replay.js +127 -0
  206. package/dist/pool.section.d.ts +13 -0
  207. package/dist/pool.section.js +83 -0
  208. package/dist/pool.style.d.ts +20 -0
  209. package/dist/pool.style.js +169 -0
  210. package/dist/pool.types.d.ts +145 -0
  211. package/dist/pool.types.js +3 -0
  212. package/dist/pool.words.d.ts +13 -0
  213. package/dist/pool.words.js +101 -0
  214. package/dist/ranges.names.js +53 -3
  215. package/dist/replay-entry.d.ts +3 -0
  216. package/dist/replay-entry.js +2 -0
  217. package/dist/restyle.js +1 -1
  218. package/dist/road.draw.js +3 -2
  219. package/dist/road.js +2 -1
  220. package/dist/road.types.d.ts +3 -0
  221. package/dist/rules.d.ts +138 -0
  222. package/dist/rules.js +511 -0
  223. package/dist/rules.types.d.ts +4 -0
  224. package/dist/rules.types.js +64 -0
  225. package/dist/score.d.ts +3 -0
  226. package/dist/score.js +93 -6
  227. package/dist/sheet.d.ts +3 -0
  228. package/dist/sheet.js +7 -3
  229. package/dist/situation.d.ts +135 -0
  230. package/dist/situation.draw.d.ts +34 -0
  231. package/dist/situation.draw.js +202 -0
  232. package/dist/situation.js +337 -0
  233. package/dist/situation.style.d.ts +2 -0
  234. package/dist/situation.style.js +45 -0
  235. package/dist/situation.types.d.ts +77 -0
  236. package/dist/situation.types.js +3 -0
  237. package/dist/situation.widgets.d.ts +39 -0
  238. package/dist/situation.widgets.js +129 -0
  239. package/dist/skating/describe.d.ts +7 -0
  240. package/dist/skating/describe.js +44 -0
  241. package/dist/skating/events.d.ts +24 -0
  242. package/dist/skating/events.js +47 -0
  243. package/dist/skating/figure.d.ts +24 -0
  244. package/dist/skating/figure.js +37 -0
  245. package/dist/skating/long.d.ts +54 -0
  246. package/dist/skating/long.js +111 -0
  247. package/dist/skating/parts.d.ts +43 -0
  248. package/dist/skating/parts.js +40 -0
  249. package/dist/skating/plan.d.ts +55 -0
  250. package/dist/skating/plan.js +197 -0
  251. package/dist/skating/short.d.ts +47 -0
  252. package/dist/skating/short.js +89 -0
  253. package/dist/skating/track.d.ts +66 -0
  254. package/dist/skating/track.js +94 -0
  255. package/dist/skating/types.d.ts +57 -0
  256. package/dist/skating/types.js +3 -0
  257. package/dist/skating-entry.d.ts +17 -0
  258. package/dist/skating-entry.js +11 -0
  259. package/dist/skating.style.d.ts +4 -0
  260. package/dist/skating.style.js +24 -0
  261. package/dist/strings.d.ts +470 -0
  262. package/dist/strings.js +674 -13
  263. package/dist/style.d.ts +2 -0
  264. package/dist/style.js +19 -2
  265. package/dist/surfaces/artistic.d.ts +9 -0
  266. package/dist/surfaces/artistic.js +94 -0
  267. package/dist/surfaces/athletics.d.ts +16 -0
  268. package/dist/surfaces/athletics.js +132 -0
  269. package/dist/surfaces/baseball.js +17 -0
  270. package/dist/surfaces/basketball.floor.d.ts +27 -0
  271. package/dist/surfaces/basketball.floor.js +83 -0
  272. package/dist/surfaces/basketball.gear.d.ts +27 -0
  273. package/dist/surfaces/basketball.gear.js +90 -0
  274. package/dist/surfaces/basketball.js +44 -22
  275. package/dist/surfaces/budo.d.ts +6 -0
  276. package/dist/surfaces/budo.js +104 -0
  277. package/dist/surfaces/curling.d.ts +16 -0
  278. package/dist/surfaces/curling.fold.d.ts +67 -0
  279. package/dist/surfaces/curling.fold.js +107 -0
  280. package/dist/surfaces/curling.js +37 -3
  281. package/dist/surfaces/dive.d.ts +9 -0
  282. package/dist/surfaces/dive.js +128 -0
  283. package/dist/surfaces/field.d.ts +7 -2
  284. package/dist/surfaces/field.js +15 -9
  285. package/dist/surfaces/football.js +7 -0
  286. package/dist/surfaces/hockey.js +4 -2
  287. package/dist/surfaces/net.d.ts +2 -1
  288. package/dist/surfaces/net.js +160 -15
  289. package/dist/surfaces/polo.d.ts +12 -0
  290. package/dist/surfaces/polo.js +159 -0
  291. package/dist/surfaces/pool.d.ts +27 -0
  292. package/dist/surfaces/pool.js +198 -0
  293. package/dist/surfaces/skating.d.ts +6 -0
  294. package/dist/surfaces/skating.js +62 -0
  295. package/dist/surfaces/soccer.js +2 -1
  296. package/dist/surfaces/surface.d.ts +76 -0
  297. package/dist/surfaces/venue.d.ts +15 -0
  298. package/dist/surfaces/venue.js +95 -0
  299. package/dist/target-entry.d.ts +2 -0
  300. package/dist/target-entry.js +2 -0
  301. package/dist/target.d.ts +200 -0
  302. package/dist/target.js +525 -0
  303. package/dist/team.common.d.ts +1 -1
  304. package/dist/team.common.js +3 -3
  305. package/dist/team.formation.d.ts +3 -1
  306. package/dist/team.formation.js +3 -3
  307. package/dist/team.layers.d.ts +2 -2
  308. package/dist/team.layers.js +4 -1
  309. package/dist/team.lineup.d.ts +27 -0
  310. package/dist/team.lineup.js +207 -0
  311. package/dist/team.network.js +6 -5
  312. package/dist/team.shape.js +5 -5
  313. package/dist/team.types.d.ts +40 -1
  314. package/dist/tenants.d.ts +77 -0
  315. package/dist/tenants.data.d.ts +8 -0
  316. package/dist/tenants.data.js +1793 -0
  317. package/dist/tenants.js +46 -0
  318. package/dist/turn-entry.d.ts +12 -0
  319. package/dist/turn-entry.js +7 -0
  320. package/dist/turn.camera.d.ts +116 -0
  321. package/dist/turn.camera.js +184 -0
  322. package/dist/turn.dom.d.ts +40 -0
  323. package/dist/turn.dom.js +353 -0
  324. package/dist/turn.kit.d.ts +86 -0
  325. package/dist/turn.kit.js +110 -0
  326. package/dist/turn.markup.d.ts +48 -0
  327. package/dist/turn.markup.js +108 -0
  328. package/dist/turn.model.d.ts +78 -0
  329. package/dist/turn.model.js +91 -0
  330. package/dist/turn.style.d.ts +5 -0
  331. package/dist/turn.style.js +56 -0
  332. package/dist/types.d.ts +221 -20
  333. package/dist/units.d.ts +1 -1
  334. package/dist/units.js +22 -1
  335. package/dist/uprights.board.d.ts +17 -0
  336. package/dist/uprights.board.js +59 -0
  337. package/dist/uprights.budo.d.ts +17 -0
  338. package/dist/uprights.budo.js +87 -0
  339. package/dist/uprights.d.ts +37 -0
  340. package/dist/uprights.fields.d.ts +32 -0
  341. package/dist/uprights.fields.js +172 -0
  342. package/dist/uprights.goal.d.ts +49 -0
  343. package/dist/uprights.goal.js +69 -0
  344. package/dist/uprights.js +169 -0
  345. package/dist/uprights.more.d.ts +7 -0
  346. package/dist/uprights.more.js +183 -0
  347. package/dist/uprights.net.d.ts +12 -0
  348. package/dist/uprights.net.js +109 -0
  349. package/dist/uprights.netkit.d.ts +28 -0
  350. package/dist/uprights.netkit.js +67 -0
  351. package/dist/uprights.pools.d.ts +8 -0
  352. package/dist/uprights.pools.js +190 -0
  353. package/dist/uprights.rinks.d.ts +27 -0
  354. package/dist/uprights.rinks.js +106 -0
  355. package/dist/uprights.track.d.ts +50 -0
  356. package/dist/uprights.track.js +246 -0
  357. package/dist/version.d.ts +1 -1
  358. package/dist/version.js +1 -1
  359. package/dist/zones-entry.d.ts +2 -0
  360. package/dist/zones-entry.js +2 -0
  361. package/package.json +56 -3
package/dist/court.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { type BadmintonFigures, type BadmintonLeague, type FreeZone, type NetSport, type PickleballFigures, type PickleballLeague, type TableTennisFigures, type TableTennisLeague, type TennisFigures, type TennisLeague, type VolleyballFigures, type VolleyballLeague } from "./leagues/courts.ts";
1
+ import { type League } from "./leagues.ts";
2
+ import { type BadmintonFigures, type BadmintonLeague, type FreeZone, type NetLeague, type NetSport, type NetballFigures, type NetballLeague, type PadelFigures, type PadelLeague, type PickleballFigures, type PickleballLeague, type RacquetballFigures, type RacquetballLeague, type RoundnetFigures, type RoundnetLeague, type SepakTakrawFigures, type SepakTakrawLeague, type SquashFigures, type SquashLeague, type TableTennisFigures, type TableTennisLeague, type TennisFigures, type TennisLeague, type TeqballFigures, type TeqballLeague, type VolleyballFigures, type VolleyballLeague } from "./leagues/courts.ts";
2
3
  import type { SurfaceOptions } from "./types.ts";
3
4
  /** A rectangle as `[x0, y0, x1, y1]`, in feet. */
4
5
  export type Rect = readonly [x0: number, y0: number, x1: number, y1: number];
@@ -16,10 +17,46 @@ export interface NetLine {
16
17
  y0: number;
17
18
  y1: number;
18
19
  }
20
+ /**
21
+ * A line drawn as a circle or an arc of one: `r` is the outer radius (the rulebooks measure to the outside of a line), `w` the line's width and `a0` to `a1` the arc,
22
+ * in radians from the +x axis towards +y (down the page), the whole circle when they are missing.
23
+ */
24
+ export interface Ring {
25
+ cx: number;
26
+ cy: number;
27
+ r: number;
28
+ w: number;
29
+ a0?: number;
30
+ a1?: number;
31
+ }
32
+ /**
33
+ * Something that stands round or beside the court, as a rectangle: a wall (solid), the metal fence between a padel court's walls (`mesh`), the front wall of a squash court
34
+ * laid out flat beside it (`face`) with its tin (`tin`).
35
+ */
36
+ export interface Band {
37
+ rect: Rect;
38
+ kind: "wall" | "mesh" | "face" | "tin";
39
+ }
40
+ /** A solid object on the court: a teqball table (a rectangle) or a roundnet set (a disc). */
41
+ export type Solid = {
42
+ kind: "table";
43
+ rect: Rect;
44
+ } | {
45
+ kind: "set";
46
+ cx: number;
47
+ cy: number;
48
+ r: number;
49
+ };
19
50
  /** The looks each sport has, the sport's default first. */
20
51
  export declare const LOOKS: Readonly<Record<NetSport, readonly string[]>>;
52
+ /** How each sport's board counts: in sets, in games, or (netball) as one total, as any other score is drawn. */
53
+ export declare const BOARD: Readonly<Record<NetSport, "sets" | "games" | "total">>;
21
54
  /** True for a sport whose court is one of these. */
22
55
  export declare const isNetSport: (sport: string) => sport is NetSport;
56
+ /** True for a league of one of these courts. */
57
+ export declare const isNetLeague: (league: League) => league is NetLeague;
58
+ /** True for a sport whose score is a board of sets or games (all of these courts but netball's). */
59
+ export declare const hasSetsBoard: (sport: string) => sport is NetSport;
23
60
  interface Common {
24
61
  /** The look: a name from `LOOKS`. */
25
62
  look: string;
@@ -51,6 +88,34 @@ export type CourtPlan = (Common & {
51
88
  sport: "tabletennis";
52
89
  league: TableTennisLeague;
53
90
  figures: TableTennisFigures;
91
+ }) | (Common & {
92
+ sport: "padel";
93
+ league: PadelLeague;
94
+ figures: PadelFigures;
95
+ }) | (Common & {
96
+ sport: "squash";
97
+ league: SquashLeague;
98
+ figures: SquashFigures;
99
+ }) | (Common & {
100
+ sport: "racquetball";
101
+ league: RacquetballLeague;
102
+ figures: RacquetballFigures;
103
+ }) | (Common & {
104
+ sport: "sepaktakraw";
105
+ league: SepakTakrawLeague;
106
+ figures: SepakTakrawFigures;
107
+ }) | (Common & {
108
+ sport: "teqball";
109
+ league: TeqballLeague;
110
+ figures: TeqballFigures;
111
+ }) | (Common & {
112
+ sport: "roundnet";
113
+ league: RoundnetLeague;
114
+ figures: RoundnetFigures;
115
+ }) | (Common & {
116
+ sport: "netball";
117
+ league: NetballLeague;
118
+ figures: NetballFigures;
54
119
  });
55
120
  /**
56
121
  * The court the options ask for. A `league` picks the rulebook (the sport's own by default; `fivb-beach` for beach volleyball); `net.look` a named look, `net.free`
@@ -73,10 +138,21 @@ export interface CourtGeometry {
73
138
  areas: Rect[];
74
139
  /** Short lines outside the court (the attack line's extension, the service zone's limits), a part of `lines` that is drawn only in the full detail. */
75
140
  small: Rect[];
76
- net: NetLine;
141
+ /** The net across the middle, or `null` for a court without one (squash, racquetball, roundnet's circle, netball). */
142
+ net: NetLine | null;
77
143
  posts: Fixture[];
78
144
  antennae: Fixture[];
79
145
  sticks: Fixture[];
146
+ /** Lines drawn as circles and arcs (sepak takraw, netball, roundnet). */
147
+ rings: Ring[];
148
+ /** Walls, fences and the like round or beside the court, outside its rectangle. */
149
+ bands: Band[];
150
+ /** A table or a set standing on the court. */
151
+ solids: Solid[];
152
+ /** Lines painted on a wall, laid flat beside the court (squash's front wall): they may be another colour than the floor's. */
153
+ wallLines: Rect[];
154
+ /** The width of a line that runs beneath the net from side to side (volleyball's and sepak takraw's centre line): it shows between the net's edges. */
155
+ underNet: number | null;
80
156
  }
81
157
  /**
82
158
  * Where everything stands, from the figures of the league in feet. A line's rectangle covers the line's width: the court's dimensions are to the outside edge of the
@@ -86,4 +162,11 @@ export interface CourtGeometry {
86
162
  export declare function courtGeometry(plan: CourtPlan): CourtGeometry;
87
163
  /** How far the court's fixtures reach beyond its side lines: the net's posts and the antennae's marks. */
88
164
  export declare function sideReach(geometry: CourtGeometry): number;
165
+ /** How far the walls, fences and the like stand beyond each edge of the court's rectangle: nothing for a court without any. */
166
+ export declare function bandReach(geometry: CourtGeometry): {
167
+ left: number;
168
+ right: number;
169
+ top: number;
170
+ bottom: number;
171
+ };
89
172
  export {};
package/dist/court.js CHANGED
@@ -1,9 +1,11 @@
1
1
  // What a net sport's court is for a set of options: the league's figures in feet, the look, the free zone, and the lines, areas and fixtures that follow from
2
- // them, as plain rectangles in the frame of a drawing lying wide (x along the court from the left end line, y across it from the top side line, both in feet).
2
+ // them, as plain rectangles (and, for the circles of a few sports, rings) in the frame of a drawing lying wide (x along the court from the left end line, y across it from
3
+ // the top side line, both in feet).
3
4
  // Kept apart from the drawing so that the outline, the description, the tests and the drawing agree. Every length that is a rulebook's figure is cited in
4
5
  // docs/sources.md; the sizes of the symbols (a post, an antenna, the net's line) are ours and are said to be.
5
6
  import { chooseLeague, netOf } from "./leagues.js";
6
- import { BADMINTON_LEAGUES, PICKLEBALL_LEAGUES, TABLE_TENNIS_LEAGUES, TENNIS_LEAGUES, VOLLEYBALL_LEAGUES } from "./leagues/courts.js";
7
+ import { BADMINTON_LEAGUES, NETBALL_LEAGUES, PADEL_LEAGUES, PICKLEBALL_LEAGUES, RACQUETBALL_LEAGUES, ROUNDNET_LEAGUES, SEPAK_TAKRAW_LEAGUES, SQUASH_LEAGUES, TABLE_TENNIS_LEAGUES, TENNIS_LEAGUES, TEQBALL_LEAGUES, VOLLEYBALL_LEAGUES } from "./leagues/courts.js";
8
+ import { netballGeometry, none, padelGeometry, racquetballGeometry, roundnetGeometry, sepakTakrawGeometry, squashGeometry, teqballGeometry } from "./court.more.js";
7
9
  import { convertLength } from "./units.js";
8
10
  /** The looks each sport has, the sport's default first. */
9
11
  export const LOOKS = Object.freeze({
@@ -12,9 +14,35 @@ export const LOOKS = Object.freeze({
12
14
  badminton: ["green", "blue", "wood"],
13
15
  pickleball: ["blue-green", "green", "red"],
14
16
  tabletennis: ["blue", "green"],
17
+ padel: ["blue", "green", "terracotta"],
18
+ squash: ["wood", "blue"],
19
+ racquetball: ["wood", "convertible"],
20
+ sepaktakraw: ["blue", "green", "wood"],
21
+ teqball: ["grey", "blue", "green"],
22
+ roundnet: ["grass", "sand", "indoor"],
23
+ netball: ["wood", "blue", "green"],
24
+ });
25
+ /** How each sport's board counts: in sets, in games, or (netball) as one total, as any other score is drawn. */
26
+ export const BOARD = Object.freeze({
27
+ tennis: "sets",
28
+ volleyball: "sets",
29
+ badminton: "games",
30
+ pickleball: "games",
31
+ tabletennis: "games",
32
+ padel: "sets",
33
+ squash: "games",
34
+ racquetball: "games",
35
+ sepaktakraw: "sets",
36
+ teqball: "sets",
37
+ roundnet: "games",
38
+ netball: "total",
15
39
  });
16
40
  /** True for a sport whose court is one of these. */
17
- export const isNetSport = (sport) => sport === "tennis" || sport === "volleyball" || sport === "badminton" || sport === "pickleball" || sport === "tabletennis";
41
+ export const isNetSport = (sport) => Object.prototype.hasOwnProperty.call(BOARD, sport);
42
+ /** True for a league of one of these courts. */
43
+ export const isNetLeague = (league) => isNetSport(league.family);
44
+ /** True for a sport whose score is a board of sets or games (all of these courts but netball's). */
45
+ export const hasSetsBoard = (sport) => isNetSport(sport) && BOARD[sport] !== "total";
18
46
  const FREE = ["official", "least", "none"];
19
47
  /**
20
48
  * The court the options ask for. A `league` picks the rulebook (the sport's own by default; `fivb-beach` for beach volleyball); `net.look` a named look, `net.free`
@@ -31,7 +59,8 @@ export function courtFor(o) {
31
59
  if (free === undefined)
32
60
  throw new Error(`Unknown free zone "${String(asked.free)}": use one of ${FREE.join(", ")}`);
33
61
  const beach = picked?.family === "volleyball" && picked.id === "fivb-beach";
34
- const names = LOOKS[sport];
62
+ // World ParaVolley asks for a light indoor floor and white lines (Rule 1.2.2): of the volleyball looks only the wooden floor, and not the beach's sand.
63
+ const names = picked?.id === "wpv-sitting" ? LOOKS.volleyball.slice(0, 1) : LOOKS[sport];
35
64
  const look = asked.look === undefined ? (beach ? "sand" : names[0]) : asked.look;
36
65
  if (!names.includes(look))
37
66
  throw new Error(`Unknown look "${String(look)}" for ${sport}: use one of ${names.join(", ")}`);
@@ -58,10 +87,45 @@ export function courtFor(o) {
58
87
  const figures = netOf(league);
59
88
  return { ...common, sport, league, figures, zone: zoneOf(figures.free) };
60
89
  }
61
- default: {
90
+ case "tabletennis": {
62
91
  const league = picked?.family === "tabletennis" ? picked : TABLE_TENNIS_LEAGUES[0];
63
92
  const figures = netOf(league);
64
- return { ...common, sport: "tabletennis", league, figures, zone: zoneOf(figures.free) };
93
+ return { ...common, sport, league, figures, zone: zoneOf(figures.free) };
94
+ }
95
+ case "padel": {
96
+ const league = picked?.family === "padel" ? picked : PADEL_LEAGUES[0];
97
+ const figures = netOf(league);
98
+ return { ...common, sport, league, figures, zone: zoneOf(figures.free) };
99
+ }
100
+ case "squash": {
101
+ const league = picked?.family === "squash" ? picked : SQUASH_LEAGUES[0];
102
+ const figures = netOf(league);
103
+ return { ...common, sport, league, figures, zone: zoneOf(figures.free) };
104
+ }
105
+ case "racquetball": {
106
+ const league = picked?.family === "racquetball" ? picked : RACQUETBALL_LEAGUES[0];
107
+ const figures = netOf(league);
108
+ return { ...common, sport, league, figures, zone: zoneOf(figures.free) };
109
+ }
110
+ case "sepaktakraw": {
111
+ const league = picked?.family === "sepaktakraw" ? picked : SEPAK_TAKRAW_LEAGUES[0];
112
+ const figures = netOf(league);
113
+ return { ...common, sport, league, figures, zone: zoneOf(figures.free) };
114
+ }
115
+ case "teqball": {
116
+ const league = picked?.family === "teqball" ? picked : TEQBALL_LEAGUES[0];
117
+ const figures = netOf(league);
118
+ return { ...common, sport, league, figures, zone: zoneOf(figures.free) };
119
+ }
120
+ case "roundnet": {
121
+ const league = picked?.family === "roundnet" ? picked : ROUNDNET_LEAGUES[0];
122
+ const figures = netOf(league);
123
+ return { ...common, sport, league, figures, zone: zoneOf(figures.free) };
124
+ }
125
+ default: {
126
+ const league = picked?.family === "netball" ? picked : NETBALL_LEAGUES[0];
127
+ const figures = netOf(league);
128
+ return { ...common, sport: "netball", league, figures, zone: zoneOf(figures.free) };
65
129
  }
66
130
  }
67
131
  }
@@ -86,8 +150,22 @@ export function courtGeometry(plan) {
86
150
  return badmintonGeometry(plan.figures);
87
151
  case "pickleball":
88
152
  return pickleballGeometry(plan.figures);
89
- default:
153
+ case "tabletennis":
90
154
  return tableGeometry(plan.figures);
155
+ case "padel":
156
+ return padelGeometry(plan.figures);
157
+ case "squash":
158
+ return squashGeometry(plan.figures);
159
+ case "racquetball":
160
+ return racquetballGeometry(plan.figures);
161
+ case "sepaktakraw":
162
+ return sepakTakrawGeometry(plan.figures);
163
+ case "teqball":
164
+ return teqballGeometry(plan.figures);
165
+ case "roundnet":
166
+ return roundnetGeometry(plan.figures);
167
+ default:
168
+ return netballGeometry(plan.figures);
91
169
  }
92
170
  }
93
171
  function tennisGeometry(f, sticks) {
@@ -120,6 +198,7 @@ function tennisGeometry(f, sticks) {
120
198
  posts: [{ x: cx, y: -out, size: f.net.postSize, shape: "square" }, { x: cx, y: W + out, size: f.net.postSize, shape: "square" }],
121
199
  antennae: [],
122
200
  sticks: sticks ? [{ x: cx, y: inset - f.net.sticksOutside, size: f.net.stickSize, shape: "square" }, { x: cx, y: W - inset + f.net.sticksOutside, size: f.net.stickSize, shape: "square" }] : [],
201
+ ...none(),
123
202
  };
124
203
  }
125
204
  function volleyballGeometry(f, free) {
@@ -165,6 +244,8 @@ function volleyballGeometry(f, free) {
165
244
  // An antenna is fixed at the outer edge of a side band, which stands directly over the side line: at the outer edge of the side line.
166
245
  antennae: [{ x: cx, y: 0, size: antenna, shape: "round" }, { x: cx, y: W, size: antenna, shape: "round" }],
167
246
  sticks: [],
247
+ ...none(),
248
+ underNet: f.attackLine === null ? null : w,
168
249
  };
169
250
  }
170
251
  function badmintonGeometry(f) {
@@ -194,6 +275,7 @@ function badmintonGeometry(f) {
194
275
  posts: [{ x: cx, y: w - post / 2, size: post, shape: "round" }, { x: cx, y: W - w + post / 2, size: post, shape: "round" }],
195
276
  antennae: [],
196
277
  sticks: [],
278
+ ...none(),
197
279
  };
198
280
  }
199
281
  function pickleballGeometry(f) {
@@ -219,6 +301,7 @@ function pickleballGeometry(f) {
219
301
  posts: [{ x: cx, y: -gap - d / 2, size: d, shape: "round" }, { x: cx, y: W + gap + d / 2, size: d, shape: "round" }],
220
302
  antennae: [],
221
303
  sticks: [],
304
+ ...none(),
222
305
  };
223
306
  }
224
307
  function tableGeometry(f) {
@@ -237,6 +320,7 @@ function tableGeometry(f) {
237
320
  posts: [{ x: cx, y: -out + post / 2, size: post, shape: "square" }, { x: cx, y: W + out - post / 2, size: post, shape: "square" }],
238
321
  antennae: [],
239
322
  sticks: [],
323
+ ...none(),
240
324
  };
241
325
  }
242
326
  /** How far the court's fixtures reach beyond its side lines: the net's posts and the antennae's marks. */
@@ -246,3 +330,14 @@ export function sideReach(geometry) {
246
330
  reach = Math.max(reach, -(post.y - post.size / 2), post.y + post.size / 2 - geometry.width);
247
331
  return reach;
248
332
  }
333
+ /** How far the walls, fences and the like stand beyond each edge of the court's rectangle: nothing for a court without any. */
334
+ export function bandReach(geometry) {
335
+ const reach = { left: 0, right: 0, top: 0, bottom: 0 };
336
+ for (const { rect } of geometry.bands) {
337
+ reach.left = Math.max(reach.left, -rect[0]);
338
+ reach.right = Math.max(reach.right, rect[2] - geometry.length);
339
+ reach.top = Math.max(reach.top, -rect[1]);
340
+ reach.bottom = Math.max(reach.bottom, rect[3] - geometry.width);
341
+ }
342
+ return reach;
343
+ }
@@ -0,0 +1,46 @@
1
+ import type { CourtGeometry } from "./court.ts";
2
+ import type { NetballFigures, PadelFigures, RacquetballFigures, RoundnetFigures, SepakTakrawFigures, SquashFigures, TeqballFigures } from "./leagues/courts.ts";
3
+ /** The empty parts of a geometry, which each court fills in as it needs. */
4
+ export declare const none: () => Pick<CourtGeometry, "rings" | "bands" | "solids" | "wallLines" | "underNet">;
5
+ /**
6
+ * A padel court: no lines round it (its walls are its limits), a service line each side of the net, 6.95 m from it to the outside edge (the Rules give no edge: ours, as the
7
+ * other rulebooks measure to the outside of a line), and the central service line from one service line to the other under the net, extending beyond each by the Rules' 20 cm. The
8
+ * enclosure is drawn outside the court: the end walls and, at each end of each side, a wall 4 m long, with metal fence between (Ends and Sides).
9
+ */
10
+ export declare function padelGeometry(f: PadelFigures): CourtGeometry;
11
+ /**
12
+ * A squash court, the front wall at the left. Floor: the short line (its nearest edge 4.26 m from the back wall, across the whole width), the half court line from the back wall to
13
+ * it, and in each back corner a service box, a square of 1.60 m inside its lines (5.05.03). The front wall is laid out flat beside the court, as if hinged on its foot: its tin (the
14
+ * upper 50 mm of it a line), the service line (the lower edge 1.78 m up) and the front wall line (4.57 m up), each across its width. The other walls stand round the court.
15
+ */
16
+ export declare function squashGeometry(f: SquashFigures): CourtGeometry;
17
+ /**
18
+ * A racquetball court, the front wall at the left. The short line's back edge is 20 ft from the back wall, the service line's front edge 5 ft in front of it, a service box's line
19
+ * and a drive serve line at 18 in and 3 ft from each side wall (to the edge nearest the centre) across the service zone, and the receiving line, broken, with its back edge 5 ft
20
+ * behind the short line's: an end segment of 21 in at each wall and sixteen 6 in segments with 6 in spaces between. The walls stand round the court.
21
+ */
22
+ export declare function racquetballGeometry(f: RacquetballFigures): CourtGeometry;
23
+ /**
24
+ * A sepak takraw court: the boundary lines drawn inwards, the centre line across the middle under the net, a quarter circle of 0.9 m radius at each end of the centre line (four, each
25
+ * inside the court on its side of the net), and a service circle of 0.3 m radius on each side of the net, its centre 2.45 m from the back line on the middle of the width. The radius
26
+ * is taken to the outside of the circle's line (the Law gives none: ours). The posts stand 0.3 m outside the sidelines, in line with the centre line.
27
+ */
28
+ export declare function sepakTakrawGeometry(f: SepakTakrawFigures): CourtGeometry;
29
+ /**
30
+ * A teqball court: the table (3 m by 1.5 m) in the exact middle, its net across the middle of its length and parallel to the shorter sides, the halfway line under it across the whole
31
+ * width, and a service line each side 3.5 m from the middle of the table. The line widths are the greatest of the 20 to 50 mm; the Rules give no edge for the service line, so its
32
+ * axis is taken to be 3.5 m from the middle (ours). The court's surrounds stand round it, outside.
33
+ */
34
+ export declare function teqballGeometry(f: TeqballFigures): CourtGeometry;
35
+ /**
36
+ * A roundnet court: the recommended 10 by 10 m of ground (there are no out of bounds), the set (91.4 cm across) at its centre, the no hit zone line (a circle of 0.9 m) and the serving
37
+ * line (a circle of 2.6 m) round it, and a mark across the serving line at each of the four service positions, 90 degrees apart, along the court's axes. The rules give no widths for
38
+ * the lines or the marks: ours.
39
+ */
40
+ export declare function roundnetGeometry(f: RoundnetFigures): CourtGeometry;
41
+ /**
42
+ * A netball court: the boundary lines drawn inwards, the two transverse lines that divide it into thirds (each line common to the two areas it bounds, so its axis is on the third),
43
+ * the centre circle (0.9 m across), the goal circles (semicircles of 4.9 m radius centred on the middle of the outside of each goal line) and the goalposts. The radii are taken to the
44
+ * outside of the lines; the pole is drawn at its greatest, 100 mm, with its back at the outer edge of the goal line, and the ring of each goal is seen from above.
45
+ */
46
+ export declare function netballGeometry(f: NetballFigures): CourtGeometry;
@@ -0,0 +1,219 @@
1
+ import { convertLength } from "./units.js";
2
+ const feet = (metres) => convertLength(metres, "m", "ft");
3
+ /** The empty parts of a geometry, which each court fills in as it needs. */
4
+ export const none = () => ({ rings: [], bands: [], solids: [], wallLines: [], underNet: null });
5
+ /** The four edges of a court's boundary lines, drawn inside its dimensions: each line's width inwards. */
6
+ const boundary = (L, W, w) => [[0, 0, w, W], [L - w, 0, L, W], [0, 0, L, w], [0, W - w, L, W]];
7
+ /** Walls (or surrounds) of a thickness all round the outside of a court, but for the sides named in `omit`, in one piece each, corners included. */
8
+ function walls(L, W, t, omit = []) {
9
+ const out = [{ rect: [0, -t, L, 0], kind: "wall" }, { rect: [0, W, L, W + t], kind: "wall" }];
10
+ if (!omit.includes("left"))
11
+ out.push({ rect: [-t, -t, 0, W + t], kind: "wall" });
12
+ if (!omit.includes("right"))
13
+ out.push({ rect: [L, -t, L + t, W + t], kind: "wall" });
14
+ return out;
15
+ }
16
+ /**
17
+ * A padel court: no lines round it (its walls are its limits), a service line each side of the net, 6.95 m from it to the outside edge (the Rules give no edge: ours, as the
18
+ * other rulebooks measure to the outside of a line), and the central service line from one service line to the other under the net, extending beyond each by the Rules' 20 cm. The
19
+ * enclosure is drawn outside the court: the end walls and, at each end of each side, a wall 4 m long, with metal fence between (Ends and Sides).
20
+ */
21
+ export function padelGeometry(f) {
22
+ const { length: L, width: W, lineWidth: w, serviceLine: S, centreOverrun: ov } = f;
23
+ const cx = L / 2;
24
+ const cy = W / 2;
25
+ const t = feet(0.15);
26
+ const side = f.enclosure.sideWall;
27
+ const bands = [{ rect: [-t, -t, 0, W + t], kind: "wall" }, { rect: [L, -t, L + t, W + t], kind: "wall" }];
28
+ for (const [y0, y1] of [[-t, 0], [W, W + t]]) {
29
+ bands.push({ rect: [0, y0, side, y1], kind: "wall" }, { rect: [side, y0, L - side, y1], kind: "mesh" }, { rect: [L - side, y0, L, y1], kind: "wall" });
30
+ }
31
+ const post = feet(0.1);
32
+ return {
33
+ length: L,
34
+ width: W,
35
+ lines: [[cx - S, 0, cx - S + w, W], [cx + S - w, 0, cx + S, W], [cx - S - ov, cy - w / 2, cx + S + ov, cy + w / 2]],
36
+ areas: [],
37
+ small: [],
38
+ // The net runs from side to side, 10 m: the outer side of each post is the court's lateral limit.
39
+ net: { x: cx, y0: 0, y1: W },
40
+ posts: [{ x: cx, y: post / 2, size: post, shape: "square" }, { x: cx, y: W - post / 2, size: post, shape: "square" }],
41
+ antennae: [],
42
+ sticks: [],
43
+ ...none(),
44
+ bands,
45
+ };
46
+ }
47
+ /**
48
+ * A squash court, the front wall at the left. Floor: the short line (its nearest edge 4.26 m from the back wall, across the whole width), the half court line from the back wall to
49
+ * it, and in each back corner a service box, a square of 1.60 m inside its lines (5.05.03). The front wall is laid out flat beside the court, as if hinged on its foot: its tin (the
50
+ * upper 50 mm of it a line), the service line (the lower edge 1.78 m up) and the front wall line (4.57 m up), each across its width. The other walls stand round the court.
51
+ */
52
+ export function squashGeometry(f) {
53
+ const { length: L, width: W, lineWidth: w, shortLine: sl, serviceBox: sb, wall } = f;
54
+ const cy = W / 2;
55
+ const t = feet(0.15);
56
+ const near = L - sl;
57
+ const lines = [
58
+ // The short line: its nearest edge to the back wall is `sl` from it, so it lies in front of that edge.
59
+ [near - w, 0, near, W],
60
+ // The half court line, from the back wall to the short line.
61
+ [near - w, cy - w / 2, L, cy + w / 2],
62
+ ];
63
+ for (const top of [true, false]) {
64
+ // A service box: inside 1.60 m by 1.60 m behind the short line, bounded by the short line, the side wall, and a line across the back and one along the side.
65
+ lines.push(top ? [near + sb, 0, near + sb + w, sb + w] : [near + sb, W - sb - w, near + sb + w, W]);
66
+ lines.push(top ? [near, sb, near + sb + w, sb + w] : [near, W - sb - w, near + sb + w, W - sb]);
67
+ }
68
+ // The front wall laid flat beside the court: distances to the left of the wall are heights up it. Each line's lower edge is at its height, and it is 50 mm tall.
69
+ const high = wall.frontWallLine + w;
70
+ const wallLines = [[-(wall.serviceLine + w), 0, -wall.serviceLine, W], [-(wall.frontWallLine + w), 0, -wall.frontWallLine, W], [-wall.tin, 0, -(wall.tin - w), W]];
71
+ const bands = [{ rect: [-high, 0, 0, W], kind: "face" }, { rect: [-wall.tin, 0, 0, W], kind: "tin" }, ...walls(L, W, t, ["left"])];
72
+ return { length: L, width: W, lines, areas: [], small: [], net: null, posts: [], antennae: [], sticks: [], ...none(), bands, wallLines };
73
+ }
74
+ /**
75
+ * A racquetball court, the front wall at the left. The short line's back edge is 20 ft from the back wall, the service line's front edge 5 ft in front of it, a service box's line
76
+ * and a drive serve line at 18 in and 3 ft from each side wall (to the edge nearest the centre) across the service zone, and the receiving line, broken, with its back edge 5 ft
77
+ * behind the short line's: an end segment of 21 in at each wall and sixteen 6 in segments with 6 in spaces between. The walls stand round the court.
78
+ */
79
+ export function racquetballGeometry(f) {
80
+ const { length: L, width: W, lineWidth: w, serviceBox: sb, driveServe: ds } = f;
81
+ const t = 0.5;
82
+ const back = L - f.shortLine;
83
+ const front = back - f.serviceLine;
84
+ const lines = [
85
+ [back - w, 0, back, W],
86
+ [front, 0, front + w, W],
87
+ // The service boxes' lines, from one line of the zone to the other, and the drive serve lines.
88
+ [front, sb - w, back, sb], [front, W - sb, back, W - sb + w],
89
+ [front, ds - w, back, ds], [front, W - ds, back, W - ds + w],
90
+ ];
91
+ // The receiving line: its back edge `behind` behind the short line's back edge.
92
+ const rear = back + f.receiving.behind;
93
+ const { end, dash, gap } = f.receiving;
94
+ lines.push([rear - w, 0, rear, end], [rear - w, W - end, rear, W]);
95
+ for (let y = end + gap; y + dash <= W - end - gap + 1e-9; y += dash + gap)
96
+ lines.push([rear - w, y, rear, y + dash]);
97
+ return { length: L, width: W, lines, areas: [], small: [], net: null, posts: [], antennae: [], sticks: [], ...none(), bands: walls(L, W, t) };
98
+ }
99
+ /**
100
+ * A sepak takraw court: the boundary lines drawn inwards, the centre line across the middle under the net, a quarter circle of 0.9 m radius at each end of the centre line (four, each
101
+ * inside the court on its side of the net), and a service circle of 0.3 m radius on each side of the net, its centre 2.45 m from the back line on the middle of the width. The radius
102
+ * is taken to the outside of the circle's line (the Law gives none: ours). The posts stand 0.3 m outside the sidelines, in line with the centre line.
103
+ */
104
+ export function sepakTakrawGeometry(f) {
105
+ const { length: L, width: W, lineWidth: w, centreLine: c, quarterCircle: q, serviceCircle: s } = f;
106
+ const cx = L / 2;
107
+ const cy = W / 2;
108
+ const half = Math.PI / 2;
109
+ const rings = [
110
+ { cx, cy: 0, r: q, w, a0: half, a1: 2 * half },
111
+ { cx, cy: 0, r: q, w, a0: 0, a1: half },
112
+ { cx, cy: W, r: q, w, a0: 2 * half, a1: 3 * half },
113
+ { cx, cy: W, r: q, w, a0: 3 * half, a1: 4 * half },
114
+ { cx: s.fromBack, cy, r: s.radius, w },
115
+ { cx: L - s.fromBack, cy, r: s.radius, w },
116
+ ];
117
+ const out = f.net.postsOutside;
118
+ const post = Math.max(2 * f.net.postRadius, L * 0.006);
119
+ return {
120
+ length: L,
121
+ width: W,
122
+ lines: [...boundary(L, W, w), [cx - c / 2, 0, cx + c / 2, W]],
123
+ areas: [],
124
+ small: [],
125
+ net: { x: cx, y0: -out, y1: W + out },
126
+ posts: [{ x: cx, y: -out, size: post, shape: "round" }, { x: cx, y: W + out, size: post, shape: "round" }],
127
+ antennae: [],
128
+ sticks: [],
129
+ ...none(),
130
+ rings,
131
+ underNet: c,
132
+ };
133
+ }
134
+ /**
135
+ * A teqball court: the table (3 m by 1.5 m) in the exact middle, its net across the middle of its length and parallel to the shorter sides, the halfway line under it across the whole
136
+ * width, and a service line each side 3.5 m from the middle of the table. The line widths are the greatest of the 20 to 50 mm; the Rules give no edge for the service line, so its
137
+ * axis is taken to be 3.5 m from the middle (ours). The court's surrounds stand round it, outside.
138
+ */
139
+ export function teqballGeometry(f) {
140
+ const { length: L, width: W, lineWidth: w, serviceLine: S } = f;
141
+ const cx = L / 2;
142
+ const cy = W / 2;
143
+ const { table, net } = f;
144
+ return {
145
+ length: L,
146
+ width: W,
147
+ lines: [[cx - w / 2, 0, cx + w / 2, W], [cx - S - w / 2, 0, cx - S + w / 2, W], [cx + S - w / 2, 0, cx + S + w / 2, W]],
148
+ areas: [],
149
+ small: [],
150
+ net: { x: cx, y0: cy - net.width / 2, y1: cy + net.width / 2 },
151
+ posts: [],
152
+ antennae: [],
153
+ sticks: [],
154
+ ...none(),
155
+ bands: walls(L, W, feet(0.1)),
156
+ solids: [{ kind: "table", rect: [cx - table.length / 2, cy - table.width / 2, cx + table.length / 2, cy + table.width / 2] }],
157
+ };
158
+ }
159
+ /**
160
+ * A roundnet court: the recommended 10 by 10 m of ground (there are no out of bounds), the set (91.4 cm across) at its centre, the no hit zone line (a circle of 0.9 m) and the serving
161
+ * line (a circle of 2.6 m) round it, and a mark across the serving line at each of the four service positions, 90 degrees apart, along the court's axes. The rules give no widths for
162
+ * the lines or the marks: ours.
163
+ */
164
+ export function roundnetGeometry(f) {
165
+ const { length: L, width: W, lineWidth: w, servingRadius: R, noHitRadius: n } = f;
166
+ const cx = L / 2;
167
+ const cy = W / 2;
168
+ const tick = feet(0.4);
169
+ return {
170
+ length: L,
171
+ width: W,
172
+ lines: [
173
+ [cx + R - tick / 2, cy - w / 2, cx + R + tick / 2, cy + w / 2], [cx - R - tick / 2, cy - w / 2, cx - R + tick / 2, cy + w / 2],
174
+ [cx - w / 2, cy + R - tick / 2, cx + w / 2, cy + R + tick / 2], [cx - w / 2, cy - R - tick / 2, cx + w / 2, cy - R + tick / 2],
175
+ ],
176
+ areas: [],
177
+ small: [],
178
+ net: null,
179
+ posts: [],
180
+ antennae: [],
181
+ sticks: [],
182
+ ...none(),
183
+ rings: [{ cx, cy, r: n, w }, { cx, cy, r: R, w }],
184
+ solids: [{ kind: "set", cx, cy, r: f.set.diameter / 2 }],
185
+ };
186
+ }
187
+ /**
188
+ * A netball court: the boundary lines drawn inwards, the two transverse lines that divide it into thirds (each line common to the two areas it bounds, so its axis is on the third),
189
+ * the centre circle (0.9 m across), the goal circles (semicircles of 4.9 m radius centred on the middle of the outside of each goal line) and the goalposts. The radii are taken to the
190
+ * outside of the lines; the pole is drawn at its greatest, 100 mm, with its back at the outer edge of the goal line, and the ring of each goal is seen from above.
191
+ */
192
+ export function netballGeometry(f) {
193
+ const { length: L, width: W, lineWidth: w } = f;
194
+ const cy = W / 2;
195
+ const half = Math.PI / 2;
196
+ const d = f.post.poleDiameter;
197
+ // The goal ring hangs on a bar that projects from the front of the pole: its nearest edge is a bar's length from the pole, and it is drawn at its rod's width.
198
+ const { inside, rod, bar } = f.post.ring;
199
+ const hoop = (x) => ({ cx: x, cy, r: inside / 2 + rod, w: rod });
200
+ return {
201
+ length: L,
202
+ width: W,
203
+ lines: [...boundary(L, W, w), [L / 3 - w / 2, 0, L / 3 + w / 2, W], [(2 * L) / 3 - w / 2, 0, (2 * L) / 3 + w / 2, W]],
204
+ areas: [],
205
+ small: [],
206
+ net: null,
207
+ posts: [{ x: d / 2, y: cy, size: d, shape: "round" }, { x: L - d / 2, y: cy, size: d, shape: "round" }],
208
+ antennae: [],
209
+ sticks: [],
210
+ ...none(),
211
+ rings: [
212
+ { cx: L / 2, cy, r: f.centreCircle / 2, w },
213
+ { cx: 0, cy, r: f.goalCircle, w, a0: -half, a1: half },
214
+ { cx: L, cy, r: f.goalCircle, w, a0: half, a1: 3 * half },
215
+ hoop(d + bar + inside / 2 + rod),
216
+ hoop(L - d - bar - inside / 2 - rod),
217
+ ],
218
+ };
219
+ }
@@ -1,11 +1,23 @@
1
1
  import type { NetSport } from "./leagues/courts.ts";
2
- /** The colours of a look: the court, the free zone round it, the ground round that, a painted area on the court, and the lines. A look may leave the area and the lines to the theme. */
2
+ /**
3
+ * The colours of a look: the court, the free zone round it, the ground round that, a painted area on the court, and the lines. A look may leave the area and the lines to the
4
+ * theme. The walls of a padel, squash or racquetball court and the surrounds of a teqball court, a padel court's fence (`mesh`), a squash court's front wall laid flat
5
+ * (`face`, with its `tin`), a teqball table and a roundnet set's net are for the sports that have them.
6
+ */
3
7
  interface Look {
4
8
  surface: string;
5
9
  free: string;
6
10
  apron: string;
7
11
  area?: string;
8
12
  line?: string;
13
+ /** The lines on a squash court's front wall, which the specification lets differ from the floor's (clause 10.13). */
14
+ wallLine?: string;
15
+ wall?: string;
16
+ mesh?: string;
17
+ face?: string;
18
+ tin?: string;
19
+ table?: string;
20
+ setnet?: string;
9
21
  }
10
22
  interface Pair {
11
23
  light: Look;
@@ -13,7 +25,7 @@ interface Pair {
13
25
  }
14
26
  /** The looks of every sport, each in light and dark. */
15
27
  export declare const COURT_LOOKS: Readonly<Record<NetSport, Readonly<Record<string, Pair>>>>;
16
- /** The rules of a drawing of this sport in this look: the shared rules and the look's colours. */
28
+ /** The rules of a drawing of this sport in this look: the shared rules, the rules of the fixtures its sport has, and the look's colours. */
17
29
  export declare function courtStyle(sport: NetSport, look: string): string;
18
30
  /** Every net sport's rules and every look, for a page that draws with `style: "none"` and supplies the stylesheet itself. */
19
31
  export declare const KYOGIJO_COURTS_STYLE: string;