@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
@@ -11,6 +11,13 @@ import { fill } from "./strings.js";
11
11
  import { lengthUnit } from "./common.js";
12
12
  import { courtFor, courtSize } from "./court.js";
13
13
  import { fieldPlan } from "./fields.js";
14
+ import { WATER_POLO } from "./pool.figures.js";
15
+ import { swimPlan } from "./pool.js";
16
+ import { athleticsLanes, athleticsLeague } from "./athletics/plan.js";
17
+ import { skatingPlan } from "./skating/plan.js";
18
+ import { budoPlan } from "./budo/plan.js";
19
+ import { laneEdges } from "./skating/track.js";
20
+ import { iceRadius } from "./skating/long.js";
14
21
  import { LEAGUES, chooseLeague, cricketOf } from "./leagues.js";
15
22
  /** Every zone set, with the sports it is for, the source of its definition and its title. */
16
23
  export const ZONE_SETS = Object.freeze({
@@ -24,8 +31,16 @@ export const ZONE_SETS = Object.freeze({
24
31
  "baseball-spray": { sports: ["mlb"], title: "Spray zones: pull, centre, opposite by infield and outfield", source: "docs/sources.md#zone-sets" },
25
32
  "baseball-retrosheet": { sports: ["mlb"], title: "Retrosheet hit locations as the nearest sector", source: "https://www.retrosheet.org/location.htm" },
26
33
  "curling-house": { sports: ["curling"], title: "The house: the button, the 4-, 8- and 12-foot rings, and the free guard zone", source: "docs/sources.md#zone-sets" },
27
- "net-court": { sports: ["tennis", "volleyball", "badminton", "pickleball", "tabletennis"], title: "Each side of the net: the front court and the back court, split by the court's own line", source: "docs/sources.md#zone-sets" },
28
- "field-thirds": { sports: ["lacrosse", "rugby", "afl", "gaelic", "fieldhockey", "handball"], title: "Thirds: defensive, middle and attacking", source: "docs/sources.md#zone-sets" },
34
+ "net-court": { sports: ["tennis", "volleyball", "badminton", "pickleball", "tabletennis", "padel", "sepaktakraw", "teqball"], title: "Each side of the net: the front court and the back court, split by the court's own line", source: "docs/sources.md#zone-sets" },
35
+ "wall-court": { sports: ["squash", "racquetball"], title: "The front court and the back court, split by the short line", source: "docs/sources.md#zone-sets" },
36
+ "roundnet-rings": { sports: ["roundnet"], title: "The no hit zone, the ring out to the serving line, and the rest of the court", source: "docs/sources.md#zone-sets" },
37
+ "pool-lanes": { sports: ["swimming"], title: "Lanes: each lane of the pool, the whole length of it", source: "docs/sources.md#zone-sets" },
38
+ "water-polo-areas": { sports: ["waterpolo"], title: "The goal area, the ground from 2 to 6 m, and the rest of the field, at each end", source: "docs/sources.md#zone-sets" },
39
+ "pool-thirds": { sports: ["diving", "artisticswimming"], title: "Thirds along the pool, from the wall the boards or the judges stand at", source: "docs/sources.md#zone-sets" },
40
+ "budo-areas": { sports: ["judo", "karate", "kendo", "sumo", "kyudo", "dojo"], title: "The surface in its areas: the contest and the safety areas, the boundary band, the clay and the ring of a dohyō, the shajō, the yamichi and the azuchi, a dojo's floor", source: "docs/sources.md#zone-sets" },
41
+ "field-thirds": { sports: ["lacrosse", "rugby", "afl", "gaelic", "fieldhockey", "handball", "netball"], title: "Thirds: defensive, middle and attacking", source: "docs/sources.md#zone-sets" },
42
+ "skating-track": { sports: ["skating"], title: "The rink in parts: the finish straight, the first curve, the crossing straight, the second curve and the infield (a figure skating rink in thirds)", source: "docs/sources.md#zone-sets" },
43
+ "athletics-track": { sports: ["athletics"], title: "The track in parts: the finish straight, the first bend, the back straight, the second bend, and the infield", source: "docs/sources.md#zone-sets" },
29
44
  "cricket-ground": { sports: ["cricket"], title: "The pitch, the ground inside the fielding circle, and the outfield", source: "docs/sources.md#zone-sets" },
30
45
  "football-pass": { sports: ["nfl", "cfl", "ifaf"], title: "Pass grid: short and deep by left, middle and right", source: "https://nflreadr.nflverse.com/articles/dictionary_pbp.html" },
31
46
  });
@@ -184,7 +199,7 @@ function nhlZones(id, ctx) {
184
199
  return out;
185
200
  }
186
201
  /** The distance from home plate along a ray at `angle` (degrees, 0 straight out to centre field, negative to left) to the edge of the infield: the arc 95 feet round the pitcher's plate. */
187
- function infieldReach(angle) {
202
+ export function infieldReach(angle) {
188
203
  const a = (angle * Math.PI) / 180;
189
204
  const along = MLB.pitcher * Math.cos(a);
190
205
  return along + Math.sqrt(along * along + MLB.skinRadius * MLB.skinRadius - MLB.pitcher * MLB.pitcher);
@@ -346,14 +361,15 @@ function curlingZones(ctx) {
346
361
  }
347
362
  /**
348
363
  * The court of a net sport on each side of the net: the front court, between the net and the line that the sport's own rules draw there, and the back court behind it.
349
- * That line is tennis's service line (21 ft), volleyball's attack line (3 m), badminton's short service line (1.98 m) and pickleball's non-volley zone line (7 ft); beach
350
- * volleyball and table tennis have none, so each side is one zone. The zones are ours: the rules name the lines, not the areas.
364
+ * That line is tennis's service line (21 ft), volleyball's attack line (3 m; sitting volleyball's 2 m), badminton's short service line (1.98 m), pickleball's non-volley zone
365
+ * line (7 ft), padel's service line (6.95 m) and teqball's service line (3.5 m); beach volleyball, table tennis and sepak takraw have none, so each side is one zone. The
366
+ * zones are ours: the rules name the lines, not the areas.
351
367
  */
352
368
  function netZones(ctx) {
353
369
  const plan = courtFor({ sport: ctx.o.sport, league: ctx.o.league, net: ctx.o.net });
354
370
  const { length: L, width: W } = courtSize(plan);
355
371
  const w = ctx.words;
356
- const front = plan.sport === "tennis" ? plan.figures.serviceLine : plan.sport === "volleyball" ? plan.figures.attackLine : plan.sport === "badminton" ? plan.figures.shortServiceLine : plan.sport === "pickleball" ? plan.figures.nonVolley : null;
372
+ const front = plan.sport === "tennis" || plan.sport === "padel" || plan.sport === "teqball" ? plan.figures.serviceLine : plan.sport === "volleyball" ? plan.figures.attackLine : plan.sport === "badminton" ? plan.figures.shortServiceLine : plan.sport === "pickleball" ? plan.figures.nonVolley : null;
357
373
  const cx = L / 2;
358
374
  const both = ctx.end === "both";
359
375
  const ends = ctx.end === "both" ? ["left", "right"] : [ctx.end];
@@ -375,6 +391,37 @@ function netZones(ctx) {
375
391
  }
376
392
  return out;
377
393
  }
394
+ /**
395
+ * A squash or racquetball court in two: the front court, from the front wall to the short line, and the back court behind it. The split is the short line's axis. The zones are
396
+ * ours: the rules name the lines, not the areas.
397
+ */
398
+ function wallZones(ctx) {
399
+ const plan = courtFor({ sport: ctx.o.sport, league: ctx.o.league, net: ctx.o.net });
400
+ const { length: L, width: W } = courtSize(plan);
401
+ const w = ctx.words;
402
+ const split = plan.sport === "squash" || plan.sport === "racquetball" ? L - plan.figures.shortLine - plan.figures.lineWidth / 2 : L / 2;
403
+ return [rect("front-court", w.frontCourt, 0, 0, split, W, false, true), rect("back-court", w.backCourt, split, 0, L, W, true, true)];
404
+ }
405
+ /**
406
+ * A roundnet court in three: the no hit zone (the circle of 0.9 m), the ring from it out to the serving line (the circle of 2.6 m), and the rest of the court. The zones are ours:
407
+ * the rules name the lines, not the areas.
408
+ */
409
+ function roundnetZones(ctx) {
410
+ const plan = courtFor({ sport: "roundnet", league: ctx.o.league, net: ctx.o.net });
411
+ const { length: L, width: W } = courtSize(plan);
412
+ if (plan.sport !== "roundnet")
413
+ return [];
414
+ const [cx, cy] = [L / 2, W / 2];
415
+ const { noHitRadius: n, servingRadius: R } = plan.figures;
416
+ const w = ctx.words;
417
+ const circle = (r) => `M${num(cx - r)} ${num(cy)}a${num(r)} ${num(r)} 0 1 0 ${num(2 * r)} 0a${num(r)} ${num(r)} 0 1 0 ${num(-2 * r)} 0Z`;
418
+ const dist = (x, y) => Math.hypot(x - cx, y - cy);
419
+ return [
420
+ { id: "outside-circles", name: w.outsideCircles, d: rectPath(0, 0, L, W) + circle(R), label: [cx, (cy + R + W) / 2], room: [L * 0.8, W / 2 - R], has: (x, y) => x >= 0 && x <= L && y >= 0 && y <= W && dist(x, y) > R },
421
+ { id: "serving-ring", name: w.servingRing, d: circle(R) + circle(n), label: [cx, cy - (R + n) / 2], room: [R - n, R - n], has: (x, y) => dist(x, y) > n && dist(x, y) <= R },
422
+ { id: "no-hit-zone", name: w.noHitZone, d: circle(n), label: [cx, cy], room: [2 * n, 2 * n], has: (x, y) => dist(x, y) <= n },
423
+ ];
424
+ }
378
425
  /** The surface in thirds along it, counted from the team's own end: the same for every field sport with ends. */
379
426
  function fieldThirds(ctx) {
380
427
  const { box } = ctx.outline;
@@ -408,6 +455,159 @@ function cricketZones(ctx) {
408
455
  out.push({ id: "pitch", name: w.pitchZone, d: rectPath(px0, py0, px1, py1), label: [cx, cy], room: [px1 - px0, py1 - py0], has: inPitch });
409
456
  return out;
410
457
  }
458
+ /** A swimming pool in lanes: each lane across the whole length of the pool, from the top of the drawing down. The lane's edges are the ropes'. */
459
+ function poolLanes(ctx) {
460
+ const plan = swimPlan({ sport: "swimming", pool: ctx.o.pool });
461
+ const L = ctx.outline.box.w;
462
+ const per = FEET_PER_METRE;
463
+ const lanes = plan.lanes;
464
+ return lanes.map((lane, i) => rect(`lane-${lane.number}`, fill(ctx.words.poolLane, { n: lane.number }), 0, i === 0 ? 0 : lane.top * per, L, i === lanes.length - 1 ? ctx.outline.box.h : lane.bottom * per, true, i === lanes.length - 1));
465
+ }
466
+ /**
467
+ * A water polo field at each end: the goal area (to the 2 m line), the ground from 2 to 6 m (where the penalty foul applies), and the rest, split at the half distance line. The marks are the rules' (Part Six,
468
+ * Article 21.7, February 2026; Appendix 4, 20.4.1.5 in the June 2025 edition); the zones are ours.
469
+ */
470
+ function waterPoloAreas(ctx) {
471
+ const { box } = ctx.outline;
472
+ const L = box.w;
473
+ const W = box.h;
474
+ const w = ctx.words;
475
+ const post = WATER_POLO.goal.netClear * FEET_PER_METRE;
476
+ const two = WATER_POLO.twoMetre * FEET_PER_METRE;
477
+ const six = WATER_POLO.sixMetre * FEET_PER_METRE;
478
+ const goalLeft = post;
479
+ const goalRight = L - post;
480
+ return [
481
+ rect("goal-area-left", `${w.poloGoalArea} (${w.endLeft})`, 0, 0, goalLeft + two, W, false, true),
482
+ rect("two-to-six-left", `${w.poloTwoToSix} (${w.endLeft})`, goalLeft + two, 0, goalLeft + six, W, false, true),
483
+ rect("beyond-six-left", `${w.poloBeyondSix} (${w.endLeft})`, goalLeft + six, 0, L / 2, W, false, true),
484
+ rect("beyond-six-right", `${w.poloBeyondSix} (${w.endRight})`, L / 2, 0, goalRight - six, W, false, true),
485
+ rect("two-to-six-right", `${w.poloTwoToSix} (${w.endRight})`, goalRight - six, 0, goalRight - two, W, false, true),
486
+ rect("goal-area-right", `${w.poloGoalArea} (${w.endRight})`, goalRight - two, 0, L, W, true, true),
487
+ ];
488
+ }
489
+ /** The pool in thirds along its length. */
490
+ function poolThirds(ctx) {
491
+ const { box } = ctx.outline;
492
+ const w = ctx.words;
493
+ return [w.poolNear, w.poolMiddle, w.poolFar].map((name, i) => rect(["near", "middle", "far"][i] + "-third", name, (box.w * i) / 3, 0, (box.w * (i + 1)) / 3, box.h, i === 2, true));
494
+ }
495
+ /**
496
+ * The athletics track in parts, each a part of the oval as the Manual lays it out (2.2.1.1): the finish straight and the back straight between the centres of the semicircles, the first bend (the right-hand one, which
497
+ * the athletes enter from the finish line) and the second, and the infield inside the kerb. The zones are ours: the rules name no area of the track. Lane by lane is the lane lines' business, not a zone's.
498
+ */
499
+ function athleticsZones(ctx) {
500
+ const league = athleticsLeague({ sport: "athletics", league: ctx.o.league });
501
+ const fig = league.dimensions;
502
+ const lanes = athleticsLanes({ sport: "athletics", league: ctx.o.league, athletics: ctx.o.athletics });
503
+ const k = FEET_PER_METRE;
504
+ const { box } = ctx.outline;
505
+ const cx = box.w / 2;
506
+ const cy = box.h / 2;
507
+ const S = fig.straight;
508
+ const R = fig.radius;
509
+ const Ro = R + lanes * fig.lane;
510
+ const w = ctx.words;
511
+ const p = (u, v) => `${num(cx + u * k)} ${num(cy + v * k)}`;
512
+ const arc = (r, sweep) => `A${num(r * k)} ${num(r * k)} 0 0 ${sweep}`;
513
+ const inside = (u, v, r) => Math.abs(v) <= r && (Math.abs(u) <= S / 2 || Math.hypot(Math.abs(u) - S / 2, v) <= r);
514
+ const m = (x, y) => [(x - cx) / k, (y - cy) / k];
515
+ const onTrack = (u, v) => inside(u, v, Ro) && !inside(u, v, R);
516
+ const stadium = (r) => `M${p(-S / 2, -r)}H${num(cx + (S / 2) * k)}${arc(r, 1)} ${p(S / 2, r)}H${num(cx - (S / 2) * k)}${arc(r, 1)} ${p(-S / 2, -r)}Z`;
517
+ const east = `M${p(S / 2, -Ro)}${arc(Ro, 1)} ${p(S / 2, Ro)}V${num(cy + R * k)}${arc(R, 0)} ${p(S / 2, -R)}Z`;
518
+ const west = `M${p(-S / 2, Ro)}${arc(Ro, 1)} ${p(-S / 2, -Ro)}V${num(cy - R * k)}${arc(R, 0)} ${p(-S / 2, R)}Z`;
519
+ return [
520
+ { id: "infield", name: w.trackInfield, d: stadium(R), label: [cx, cy], room: [S * k, R * k], has: (x, y) => { const [u, v] = m(x, y); return inside(u, v, R); } },
521
+ { id: "home-straight", name: w.homeStraight, d: `M${p(-S / 2, R)}H${num(cx + (S / 2) * k)}V${num(cy + Ro * k)}H${num(cx - (S / 2) * k)}Z`, label: [cx, cy + ((R + Ro) / 2) * k], room: [S * k, (Ro - R) * k], has: (x, y) => { const [u, v] = m(x, y); return onTrack(u, v) && Math.abs(u) <= S / 2 && v > 0; } },
522
+ { id: "first-bend", name: w.firstBend, d: east, label: [cx + (S / 2 + (R + Ro) / 2) * k, cy], room: [(Ro - R) * k, R * k], has: (x, y) => { const [u, v] = m(x, y); return onTrack(u, v) && u > S / 2; } },
523
+ { id: "back-straight", name: w.backStraight, d: `M${p(-S / 2, -Ro)}H${num(cx + (S / 2) * k)}V${num(cy - R * k)}H${num(cx - (S / 2) * k)}Z`, label: [cx, cy - ((R + Ro) / 2) * k], room: [S * k, (Ro - R) * k], has: (x, y) => { const [u, v] = m(x, y); return onTrack(u, v) && Math.abs(u) <= S / 2 && v < 0; } },
524
+ { id: "second-bend", name: w.secondBend, d: west, label: [cx - (S / 2 + (R + Ro) / 2) * k, cy], room: [(Ro - R) * k, R * k], has: (x, y) => { const [u, v] = m(x, y); return onTrack(u, v) && u < -S / 2; } },
525
+ ];
526
+ }
527
+ /**
528
+ * The skating rink in parts: for a track, the infield inside the inner edge, the finish straight, the first curve, the crossing straight and the second curve between the centres of the curves, each as the
529
+ * plan lays it out (the long track's ice out to its padding, the short track's rink); for a figure skating rink, its length in thirds. The zones are ours: the Rules name no area of the ice.
530
+ */
531
+ function skatingZones(ctx) {
532
+ const plan = skatingPlan({ sport: "skating", league: ctx.o.league, skating: ctx.o.skating });
533
+ const k = FEET_PER_METRE;
534
+ const { box } = ctx.outline;
535
+ const w = ctx.words;
536
+ const cx = box.w / 2;
537
+ const cy = box.h / 2;
538
+ if (plan.discipline === "figure") {
539
+ const part = (i, id, name) => rect(id, name, (box.w * i) / 3, 0, (box.w * (i + 1)) / 3, box.h, i === 2, true);
540
+ return [part(0, "left", w.rinkLeft), part(1, "middle", w.rinkMiddle), part(2, "right", w.rinkRight)];
541
+ }
542
+ const S = plan.oval === undefined ? plan.short.straight : plan.oval.straight;
543
+ const R = plan.oval === undefined ? plan.short.blocks : laneEdges(plan.oval, 0).inner;
544
+ const Ro = plan.oval === undefined ? plan.short.width / 2 : iceRadius(plan.oval);
545
+ const p = (u, v) => `${num(cx + u * k)} ${num(cy + v * k)}`;
546
+ const arc = (r, sweep) => `A${num(r * k)} ${num(r * k)} 0 0 ${sweep}`;
547
+ const inside = (u, v, r) => Math.abs(v) <= r && (Math.abs(u) <= S / 2 || Math.hypot(Math.abs(u) - S / 2, v) <= r);
548
+ const m = (x, y) => [(x - cx) / k, (y - cy) / k];
549
+ const onIce = (u, v) => inside(u, v, Ro) && !inside(u, v, R);
550
+ const stadium = (r) => `M${p(-S / 2, -r)}H${num(cx + (S / 2) * k)}${arc(r, 1)} ${p(S / 2, r)}H${num(cx - (S / 2) * k)}${arc(r, 1)} ${p(-S / 2, -r)}Z`;
551
+ const east = `M${p(S / 2, -Ro)}${arc(Ro, 1)} ${p(S / 2, Ro)}V${num(cy + R * k)}${arc(R, 0)} ${p(S / 2, -R)}Z`;
552
+ const west = `M${p(-S / 2, Ro)}${arc(Ro, 1)} ${p(-S / 2, -Ro)}V${num(cy - R * k)}${arc(R, 0)} ${p(-S / 2, R)}Z`;
553
+ return [
554
+ { id: "infield", name: w.trackInfield, d: stadium(R), label: [cx, cy], room: [S * k, R * k], has: (x, y) => { const [u, v] = m(x, y); return inside(u, v, R); } },
555
+ { id: "home-straight", name: w.finishStraight, d: `M${p(-S / 2, R)}H${num(cx + (S / 2) * k)}V${num(cy + Ro * k)}H${num(cx - (S / 2) * k)}Z`, label: [cx, cy + ((R + Ro) / 2) * k], room: [S * k, (Ro - R) * k], has: (x, y) => { const [u, v] = m(x, y); return onIce(u, v) && Math.abs(u) <= S / 2 && v > 0; } },
556
+ { id: "first-curve", name: w.firstCurve, d: east, label: [cx + (S / 2 + (R + Ro) / 2) * k, cy], room: [(Ro - R) * k, R * k], has: (x, y) => { const [u, v] = m(x, y); return onIce(u, v) && u > S / 2; } },
557
+ { id: "crossing-straight", name: w.crossingStraight, d: `M${p(-S / 2, -Ro)}H${num(cx + (S / 2) * k)}V${num(cy - R * k)}H${num(cx - (S / 2) * k)}Z`, label: [cx, cy - ((R + Ro) / 2) * k], room: [S * k, (Ro - R) * k], has: (x, y) => { const [u, v] = m(x, y); return onIce(u, v) && Math.abs(u) <= S / 2 && v < 0; } },
558
+ { id: "second-curve", name: w.secondCurve, d: west, label: [cx - (S / 2 + (R + Ro) / 2) * k, cy], room: [(Ro - R) * k, R * k], has: (x, y) => { const [u, v] = m(x, y); return onIce(u, v) && u < -S / 2; } },
559
+ ];
560
+ }
561
+ /**
562
+ * The budō surface in its areas, each as the plan lays it out (budo/plan.ts): a judo or karate area's mats by the colour they are laid in (the safety area under, the contest area, and for karate the boundary band, over
563
+ * it); a dohyō's clay, the jano-me and the ring; a kyūdōjō's shajō, yamichi and azuchi; a kendo floor and a dojo's in two parts (a dojo's kamiza end and the rest). The zones are ours: no rule names them.
564
+ */
565
+ function budoZones(ctx) {
566
+ const plan = budoPlan({ sport: ctx.o.sport, league: ctx.o.league, budo: ctx.o.budo, dojo: ctx.o.dojo });
567
+ const k = FEET_PER_METRE;
568
+ const ox = plan.box.x0;
569
+ const oy = plan.box.y0;
570
+ const w = ctx.words;
571
+ const box = (b) => [(b.x0 - ox) * k, (b.y0 - oy) * k, (b.x1 - ox) * k, (b.y1 - oy) * k];
572
+ const one = (id, name, b) => {
573
+ const [x0, y0, x1, y1] = box(b);
574
+ return rect(id, name, x0, y0, x1, y1, true, true);
575
+ };
576
+ const whole = one("surface", w.budoSafety, plan.box);
577
+ // The zones do not overlap: a zone is what is in it and in none of the zones laid over it.
578
+ const inBox = (b, x, y) => x >= (b.x0 - ox) * k - 1e-9 && x <= (b.x1 - ox) * k + 1e-9 && y >= (b.y0 - oy) * k - 1e-9 && y <= (b.y1 - oy) * k + 1e-9;
579
+ const without = (z, over) => ({ ...z, has: (x, y) => z.has(x, y) && !over.some((b) => inBox(b, x, y)) });
580
+ if (plan.judo !== undefined)
581
+ return [without(one("safety-area", w.budoSafety, plan.judo.tatami), plan.judo.contests), ...plan.judo.contests.map((c, i) => one(`contest-area-${i + 1}`, w.budoContest, c))];
582
+ if (plan.karate !== undefined)
583
+ return [without(one("safety-area", w.budoSafety, plan.karate.mats), plan.karate.areas), ...plan.karate.areas.map((c, i) => without(one(`boundary-band-${i + 1}`, w.budoBand, c), plan.karate.inner)), ...plan.karate.inner.map((c, i) => one(`contest-area-${i + 1}`, w.budoContest, c))];
584
+ if (plan.sumo !== undefined) {
585
+ const L = plan.sumo;
586
+ const [cx, cy] = [(L.centre[0] - ox) * k, (L.centre[1] - oy) * k];
587
+ const ring = (r) => `M${num(cx - r * k)} ${num(cy)}A${num(r * k)} ${num(r * k)} 0 1 0 ${num(cx + r * k)} ${num(cy)}A${num(r * k)} ${num(r * k)} 0 1 0 ${num(cx - r * k)} ${num(cy)}Z`;
588
+ const jano = L.outer + plan.figures.jano;
589
+ const dist = (x, y) => Math.hypot(x - cx, y - cy) / k;
590
+ const base = one("clay", w.budoClay, L.platform);
591
+ const inner = L.ring + plan.figures.bale.width;
592
+ return [
593
+ { ...base, has: (x, y) => base.has(x, y) && dist(x, y) > jano },
594
+ { id: "jano-me", name: w.budoJano, d: ring(jano), label: [cx, cy - ((L.outer + jano) / 2) * k], room: [(jano - L.outer) * k, (jano - L.outer) * k], has: (x, y) => dist(x, y) <= jano && dist(x, y) > inner },
595
+ { id: "ring", name: w.budoRing, d: ring(L.ring), label: [cx, cy - L.ring * 0.5 * k], room: [L.ring * k, L.ring * k * 0.4], has: (x, y) => dist(x, y) <= inner },
596
+ ];
597
+ }
598
+ if (plan.kyudo !== undefined) {
599
+ const parts = [plan.kyudo.shajo, plan.kyudo.yamichi, plan.kyudo.azuchi];
600
+ return [without({ ...whole, id: "range", name: w.budoRest }, parts), one("shajo", w.budoShajo, plan.kyudo.shajo), without(one("yamichi", w.budoYamichi, plan.kyudo.yamichi), [plan.kyudo.shajo, plan.kyudo.azuchi]), without(one("azuchi", w.budoAzuchi, plan.kyudo.azuchi), [plan.kyudo.shajo, plan.kyudo.yamichi])];
601
+ }
602
+ const ranges = plan.ranges;
603
+ const kamiza = ranges.kamiza;
604
+ if (plan.dojo !== undefined && kamiza !== undefined && !("left" in kamiza))
605
+ return [without({ ...whole, id: "floor", name: w.budoRest }, [kamiza]), one("kamiza", w.budoKamiza, kamiza)];
606
+ const halves = ranges.half;
607
+ if (halves !== undefined && "left" in halves)
608
+ return [one("left", w.endLeft, halves.left), without(one("right", w.endRight, halves.right), [halves.left])];
609
+ return [whole];
610
+ }
411
611
  /** The zones of a set on the surface the context describes. Throws for a set that is not for the surface's sport. */
412
612
  export function buildZoneSet(id, ctx) {
413
613
  if (!Object.prototype.hasOwnProperty.call(ZONE_SETS, id))
@@ -419,6 +619,6 @@ export function buildZoneSet(id, ctx) {
419
619
  const { zones, which } = retrosheetZones(ctx);
420
620
  return { id, zones, which };
421
621
  }
422
- const zones = id === "field-thirds" ? fieldThirds(ctx) : id === "cricket-ground" ? cricketZones(ctx) : id.startsWith("soccer") ? soccerZones(id, ctx) : id === "nba-shot" ? nbaZones(ctx) : id.startsWith("nhl") ? nhlZones(id, ctx) : id === "baseball-spray" ? baseballSpray(ctx) : id === "curling-house" ? curlingZones(ctx) : id === "net-court" ? netZones(ctx) : footballPass(ctx);
622
+ const zones = id === "budo-areas" ? budoZones(ctx) : id === "skating-track" ? skatingZones(ctx) : id === "athletics-track" ? athleticsZones(ctx) : id === "field-thirds" ? fieldThirds(ctx) : id === "cricket-ground" ? cricketZones(ctx) : id.startsWith("soccer") ? soccerZones(id, ctx) : id === "nba-shot" ? nbaZones(ctx) : id.startsWith("nhl") ? nhlZones(id, ctx) : id === "baseball-spray" ? baseballSpray(ctx) : id === "curling-house" ? curlingZones(ctx) : id === "net-court" ? netZones(ctx) : id === "wall-court" ? wallZones(ctx) : id === "roundnet-rings" ? roundnetZones(ctx) : id === "pool-lanes" ? poolLanes(ctx) : id === "water-polo-areas" ? waterPoloAreas(ctx) : id === "pool-thirds" ? poolThirds(ctx) : footballPass(ctx);
423
623
  return { id, zones, which: lastWins(zones) };
424
624
  }
package/dist/homeside.js CHANGED
@@ -10,6 +10,11 @@ export const HOME_FIRST = Object.freeze({
10
10
  fieldhockey: true,
11
11
  handball: true,
12
12
  cricket: true,
13
+ // Water polo lists the home team first. A swimming, diving or artistic swimming dual meet follows the North American convention: the visitor is listed first.
14
+ waterpolo: true,
15
+ swimming: false,
16
+ diving: false,
17
+ artisticswimming: false,
13
18
  // North American professional and college leagues, and the leagues that follow them: the visitor is listed first.
14
19
  lacrosse: false,
15
20
  nfl: false,
@@ -25,6 +30,25 @@ export const HOME_FIRST = Object.freeze({
25
30
  badminton: false,
26
31
  pickleball: false,
27
32
  tabletennis: false,
33
+ padel: false,
34
+ squash: false,
35
+ racquetball: false,
36
+ sepaktakraw: false,
37
+ teqball: false,
38
+ roundnet: false,
39
+ // Netball is scored as a goals sport, not in sets, and is listed "home v away" in the Commonwealth countries where it is played most: the home team is first, on the left.
40
+ netball: true,
41
+ // A track meeting has no home and away.
42
+ athletics: false,
43
+ // A skating race has no home and away.
44
+ skating: false,
45
+ // A budō contest is between the first contestant called and the second (judo: blue to the referee's right, white to his left; karate: aka and ao; kendo: aka and shiro; sumo: east and west): no home side.
46
+ judo: false,
47
+ karate: false,
48
+ kendo: false,
49
+ sumo: false,
50
+ kyudo: false,
51
+ dojo: false,
28
52
  });
29
53
  /** The leagues whose convention is not their sport's: the international federation's lacrosse lists the home team first. */
30
54
  export const HOME_FIRST_LEAGUES = Object.freeze({
package/dist/index.d.ts CHANGED
@@ -1,13 +1,28 @@
1
- export { COLOR_PROPERTIES, SPORTS, describe, drawBadge, drawKyogijo, drawScore, drawSurface, isPortrait, statusLabel, statusText, winnerOf } from "./draw.ts";
1
+ export { COLOR_PROPERTIES, SPORTS, crowdStands, describe, drawBadge, drawKyogijo, drawScore, drawSurface, isPortrait, statusLabel, statusText, winnerOf } from "./draw.ts";
2
2
  export { HOME_FIRST, HOME_FIRST_LEAGUES, homeSideFor } from "./homeside.ts";
3
- export { inkOn, luminance, rgbOf, safeColour, safeLogo } from "./colour.ts";
3
+ export { inkOn, luminance, rgbOf, safeColour, safePicture } from "./colour.ts";
4
+ export { safeLogo } from "./logo.ts";
5
+ export { useEmblems } from "./emblems-source.ts";
6
+ export type { EmblemDrawOptions, EmblemId, EmblemRef, EmblemRenderer, EmblemStyleName } from "./emblems-source.ts";
4
7
  export { OUTCOMES, drawLayers, layerTable } from "./layers.ts";
5
8
  export { RANGES } from "./ranges.names.ts";
6
9
  export { BACKGROUND_OPACITY, BACKGROUND_PATTERNS, KYOGIJO_BACKGROUND_STYLE } from "./background.ts";
7
10
  export type { Background, BackgroundFit, BackgroundOptions, BackgroundPattern } from "./background.ts";
8
11
  export { FIELD_SPORTS, fieldPlan, isFieldSport } from "./fields.ts";
12
+ export { POOL_SPORTS, isPoolSport, poolPlan, swimPlan, venueLayout } from "./pool.ts";
13
+ export type { ArtisticPlan, Board, DivePlan, LanePlan, PoloPlan, PoolPlan, Rope, RopeColour, SwimPlan, VenueItem, VenueLayout } from "./pool.ts";
14
+ export { formatTime, parseTime } from "./pool.race.ts";
15
+ export type { DeckLook, DivingPlatform, PaceOptions, PoolKind, PoolLook, PoolRace, PoolSection, RaceShow, Swimmer, SwimmerStatus, VenueOptions, VenuePool } from "./pool.types.ts";
9
16
  export type { Area as FieldArea, FieldPlan, GoalPlan as FieldGoalPlan, Outline as FieldOutline, Shape as FieldShape } from "./fields.types.ts";
10
17
  export { KYOGIJO_FIELDS_STYLE } from "./fields.style.ts";
18
+ export { KYOGIJO_ATHLETICS_STYLE, KYOGIJO_TRACK_STYLE } from "./athletics.style.ts";
19
+ export { KYOGIJO_SKATING_STYLE } from "./skating.style.ts";
20
+ export { KYOGIJO_BUDO_STYLE } from "./budo.style.ts";
21
+ export { dojo, drawDojo } from "./budo/dojo.api.ts";
22
+ export type { Dojo, Tatami } from "./budo/dojo.api.ts";
23
+ export type { BudoScore, BudoStyle, DojoSpec } from "./budo/types.ts";
24
+ export type { SkatingDiscipline, SkatingFurniture, SkatingInfield, SkatingRace, SkatingStyle } from "./skating/types.ts";
25
+ export type { AthleticsFieldEvent, AthleticsInfield, AthleticsRace, AthleticsStyle, AthleticsTrackLook, WaterJump } from "./athletics/types.ts";
11
26
  export type { RangeInfo } from "./ranges.names.ts";
12
27
  export { rampColour } from "./layers.marks.ts";
13
28
  export { HEAT_RAMPS, HEAT_RAMP_NAMES } from "./heat.colour.ts";
@@ -17,13 +32,22 @@ export type { ArrowsLayer, Comet, Layer, LayerBase, LayerKind, LayerTeam, LineDa
17
32
  export { KYOGIJO_STRINGS } from "./strings.ts";
18
33
  export type { KyogijoWords } from "./strings.ts";
19
34
  export { KYOGIJO_COURTS_STYLE } from "./courts.style.ts";
35
+ export { HARDWOOD_SMALL, KYOGIJO_HARDWOOD_STYLE } from "./hardwood.ts";
36
+ export { KYOGIJO_CROWD_STYLE } from "./crowd.draw.ts";
37
+ export { GRIDIRON_GROUNDS, WALL_SEATS, outlinePath, outlinePoints } from "./crowd.ts";
38
+ export type { CrowdStands, StandGap, StandRing, StandSector, Outline as StandOutline } from "./crowd.ts";
20
39
  export { KYOGIJO_MARK_STYLE } from "./mark.ts";
40
+ export { DRIVE_CODES, readSituation, situationText } from "./situation.ts";
41
+ export type { BaseballSituation, DriveLeg, DriveResult, FootballSituation, HockeySituation, ShootoutAttempt, ShootoutRound, Situation, SituationContext, SituationRead, SituationTeam, HockeyRead, BaseballRead, FootballRead, DriveRead } from "./situation.ts";
42
+ export { KYOGIJO_SITUATION_STYLE } from "./situation.style.ts";
43
+ export { KYOGIJO_PAGEANT_MOTION, KYOGIJO_PAGEANT_STYLE } from "./pageant.style.ts";
44
+ export { KYOGIJO_POOL_STYLE } from "./pool.style.ts";
21
45
  export { KYOGIJO_CURLING_STYLE, KYOGIJO_HEAT_STYLE, KYOGIJO_NOTE_STYLE, KYOGIJO_STYLE, KYOGIJO_TEAM_STYLE, KYOGIJO_WALLS_STYLE } from "./style.ts";
22
46
  export { KYOGIJO_LOOK_STYLE, LOOKS, LOOK_NAMES, LOOK_PAIRS, contrastOf, groupOf, lookPalette, lookStyle } from "./look.ts";
23
47
  export type { Group as LookGroup, Look, Palette as LookPalette, PaletteKey as LookPaletteKey } from "./look.ts";
24
48
  export { FEATURES, FEATURE_INFO, KYOGIJO_FEATURE_STYLE } from "./features.ts";
25
49
  export type { Feature } from "./features.ts";
26
- export type { DelaunayLayer, FlowLayer, Formation, FormationLayer, FormationPlayer, FormationPosition, FormationSport, HullLayer, MoveDatum, NetworkLayer, NetworkNode, PassDatum, PlayerDatum, SonarLayer, VoronoiLayer } from "./team.types.ts";
50
+ export type { DelaunayLayer, FlowLayer, Formation, FormationLayer, FormationPlayer, FormationPosition, FormationSport, HullLayer, LineupLayer, LineupPlayer, MoveDatum, NetworkLayer, NetworkNode, PassDatum, PlayerDatum, SonarLayer, VoronoiLayer } from "./team.types.ts";
27
51
  export { COURT_THEMES } from "./themes.ts";
28
52
  export { abbreviate, capitals, fitLines, textWidth } from "./text.ts";
29
53
  export type { FittedLines } from "./text.ts";
@@ -33,6 +57,8 @@ export type { PlaceAlias, PlaceNameKind } from "./names.ts";
33
57
  export type { CoverQuirk, DugoutSide, HillQuirk, OverhangQuirk, Park, ParkData, ParkDugouts, ParkPeriod, ParkPeriodData, ParkQuirk, ParkSource, ParkWall, ParkWallData, PointQuirk, QuirkKind, WallPlace } from "./parks.ts";
34
58
  export { ERA_CURRENT, ERA_SOURCES, ERA_SPORTS, eraChanges, eraRange, eraStates, footballIn, rulesFor, seasonLabel } from "./eras.ts";
35
59
  export type { EraChange, EraRules, EraRulesOf, EraSource, EraSpan, EraSport, FootballRules, MlbRules, NbaRules, NhlRules } from "./eras.ts";
60
+ export { ARENA_IDS, ARENAS, arenaById, arenaByName, arenaByWikidata, arenaCourtIn, arenaNameIn, arenaOfficialName, arenaRinkIn, arenaSourceUrl, arenasByName } from "./arenas.ts";
61
+ export type { Arena, ArenaCapacity, ArenaData, ArenaName, ArenaSize, ArenaSource } from "./arenas.ts";
36
62
  export { GROUND_IDS, GROUNDS, groundById, groundByName, groundByWikidata, groundNameIn, groundOfficialName, groundSourceUrl, groundsByName, groundsHosting } from "./grounds.ts";
37
63
  export type { Ground, GroundCompetition, GroundData, GroundName, GroundSource, GroundTournament } from "./grounds.ts";
38
64
  export { AFL_GROUNDS, FAMILY_OF, LEAGUES, LEAGUE_SOURCES, VARIANTS, chooseLeague, hasHistory, leagueAt, leagueById, leagueChanges, leagueFigures, leagueIds, leagueSeason, leagueSize } from "./leagues.ts";
@@ -44,4 +70,4 @@ export type { SoccerPitchClass, SoccerPitchId, SoccerSize, SoccerSpec } from "./
44
70
  export { SOCCER_PROVIDER_IDS, SOCCER_PROVIDERS, frameMatrix, rescale, soccerFrame, soccerLandmarks } from "./surfaces/soccer-providers.ts";
45
71
  export type { Rescaler, SoccerFrame, SoccerProvider, SoccerProviderId } from "./surfaces/soccer-providers.ts";
46
72
  export { VERSION } from "./version.ts";
47
- export type { AxesOptions, Box, Colors, CourtStyle, Detail, DirectionOptions, FieldSport, FieldStyle, Fence, GoalInfo, GoalStyle, Language, NetStyle, LineDash, LineWidth, LookName, Orientation, QuirkName, QuirkOptions, RangeBox, RangeName, RangeNamed, ScoreOptions, Side, Size, Sport, StatusWord, StripePattern, SurfaceOptions, Team, TeamMark, Theme, WallOptions, } from "./types.ts";
73
+ export type { AxesOptions, Box, Colors, CourtStyle, CrowdOptions, CrowdShape, Detail, DirectionOptions, BudoSport, FieldSport, FieldStyle, Fence, GoalInfo, GoalStyle, HardwoodOptions, Language, NetStyle, LineDash, LineWidth, LookName, Orientation, PoolSport, PoolStyle, QuirkName, QuirkOptions, RangeBox, PageantOptions, PageantStyle, RangeName, RangeNamed, ScoreOptions, Side, Size, Sport, StatusWord, StripePattern, SurfaceOptions, Team, TeamMark, Theme, WallOptions, } from "./types.ts";
package/dist/index.js CHANGED
@@ -1,18 +1,33 @@
1
1
  // Kyogijo Stadiums 競技場: sports surfaces as SVG, drawn to scale, with the teams and the score on them.
2
- export { COLOR_PROPERTIES, SPORTS, describe, drawBadge, drawKyogijo, drawScore, drawSurface, isPortrait, statusLabel, statusText, winnerOf } from "./draw.js";
2
+ export { COLOR_PROPERTIES, SPORTS, crowdStands, describe, drawBadge, drawKyogijo, drawScore, drawSurface, isPortrait, statusLabel, statusText, winnerOf } from "./draw.js";
3
3
  export { HOME_FIRST, HOME_FIRST_LEAGUES, homeSideFor } from "./homeside.js";
4
- export { inkOn, luminance, rgbOf, safeColour, safeLogo } from "./colour.js";
4
+ export { inkOn, luminance, rgbOf, safeColour, safePicture } from "./colour.js";
5
+ export { safeLogo } from "./logo.js";
6
+ export { useEmblems } from "./emblems-source.js";
5
7
  export { OUTCOMES, drawLayers, layerTable } from "./layers.js";
6
8
  export { RANGES } from "./ranges.names.js";
7
9
  export { BACKGROUND_OPACITY, BACKGROUND_PATTERNS, KYOGIJO_BACKGROUND_STYLE } from "./background.js";
8
10
  export { FIELD_SPORTS, fieldPlan, isFieldSport } from "./fields.js";
11
+ export { POOL_SPORTS, isPoolSport, poolPlan, swimPlan, venueLayout } from "./pool.js";
12
+ export { formatTime, parseTime } from "./pool.race.js";
9
13
  export { KYOGIJO_FIELDS_STYLE } from "./fields.style.js";
14
+ export { KYOGIJO_ATHLETICS_STYLE, KYOGIJO_TRACK_STYLE } from "./athletics.style.js";
15
+ export { KYOGIJO_SKATING_STYLE } from "./skating.style.js";
16
+ export { KYOGIJO_BUDO_STYLE } from "./budo.style.js";
17
+ export { dojo, drawDojo } from "./budo/dojo.api.js";
10
18
  export { rampColour } from "./layers.marks.js";
11
19
  export { HEAT_RAMPS, HEAT_RAMP_NAMES } from "./heat.colour.js";
12
20
  export { ZONE_SETS, ZONE_SET_IDS } from "./heat.zones.js";
13
21
  export { KYOGIJO_STRINGS } from "./strings.js";
14
22
  export { KYOGIJO_COURTS_STYLE } from "./courts.style.js";
23
+ export { HARDWOOD_SMALL, KYOGIJO_HARDWOOD_STYLE } from "./hardwood.js";
24
+ export { KYOGIJO_CROWD_STYLE } from "./crowd.draw.js";
25
+ export { GRIDIRON_GROUNDS, WALL_SEATS, outlinePath, outlinePoints } from "./crowd.js";
15
26
  export { KYOGIJO_MARK_STYLE } from "./mark.js";
27
+ export { DRIVE_CODES, readSituation, situationText } from "./situation.js";
28
+ export { KYOGIJO_SITUATION_STYLE } from "./situation.style.js";
29
+ export { KYOGIJO_PAGEANT_MOTION, KYOGIJO_PAGEANT_STYLE } from "./pageant.style.js";
30
+ export { KYOGIJO_POOL_STYLE } from "./pool.style.js";
16
31
  export { KYOGIJO_CURLING_STYLE, KYOGIJO_HEAT_STYLE, KYOGIJO_NOTE_STYLE, KYOGIJO_STYLE, KYOGIJO_TEAM_STYLE, KYOGIJO_WALLS_STYLE } from "./style.js";
17
32
  export { KYOGIJO_LOOK_STYLE, LOOKS, LOOK_NAMES, LOOK_PAIRS, contrastOf, groupOf, lookPalette, lookStyle } from "./look.js";
18
33
  export { FEATURES, FEATURE_INFO, KYOGIJO_FEATURE_STYLE } from "./features.js";
@@ -21,6 +36,7 @@ export { abbreviate, capitals, fitLines, textWidth } from "./text.js";
21
36
  export { PARKS, PARK_IDS, fenceFor, parkById, parkByName, parkByWikidata, parkNameIn, parkOfficialName, parkPointsIn, parkQuirksIn, parkSourceUrl, parkUnit, parkWallsIn, parksByName } from "./parks.js";
22
37
  export { officialName, plainName } from "./names.js";
23
38
  export { ERA_CURRENT, ERA_SOURCES, ERA_SPORTS, eraChanges, eraRange, eraStates, footballIn, rulesFor, seasonLabel } from "./eras.js";
39
+ export { ARENA_IDS, ARENAS, arenaById, arenaByName, arenaByWikidata, arenaCourtIn, arenaNameIn, arenaOfficialName, arenaRinkIn, arenaSourceUrl, arenasByName } from "./arenas.js";
24
40
  export { GROUND_IDS, GROUNDS, groundById, groundByName, groundByWikidata, groundNameIn, groundOfficialName, groundSourceUrl, groundsByName, groundsHosting } from "./grounds.js";
25
41
  export { AFL_GROUNDS, FAMILY_OF, LEAGUES, LEAGUE_SOURCES, VARIANTS, chooseLeague, hasHistory, leagueAt, leagueById, leagueChanges, leagueFigures, leagueIds, leagueSeason, leagueSize } from "./leagues.js";
26
42
  export { SURFACE_UNITS, UNITS, convertLength, isUnit } from "./units.js";
@@ -13,7 +13,8 @@ export { KYOGIJO_HEAT_STYLE } from "./style.ts";
13
13
  export type { ArrowsLayer, Comet, Layer, LayerBase, LayerKind, LayerTeam, LineDatum, LineStyle, LinesLayer, MarkDatum, MarkShape, OutcomeStyle, Paint, PointDatum, PointStyle, PointsLayer, Scale, TableOptions, TextDatum, TextLayer, TextStyle } from "./layers.types.ts";
14
14
  export { KYOGIJO_TEAM_STYLE } from "./style.ts";
15
15
  export { FORMATIONS, FORMATION_IDS, POSITION_NAMES, formationById, formationsOf, positionName } from "./formations.ts";
16
+ export { LINEUP_CODES } from "./lineup.codes.ts";
16
17
  export type { Named } from "./formations.ts";
17
18
  export { clipNearer, convexHull, delaunay, neighbours, polygonArea, polygonCentroid, triangulationEdges, voronoiCells } from "./team.geometry.ts";
18
19
  export type { Pt, Triangulation } from "./team.geometry.ts";
19
- export type { DelaunayLayer, FlowLayer, Formation, FormationLayer, FormationPlayer, FormationPosition, FormationSport, HullLayer, MoveDatum, NetworkLayer, NetworkNode, PassDatum, PlayerDatum, SonarLayer, VoronoiLayer } from "./team.types.ts";
20
+ export type { DelaunayLayer, FlowLayer, Formation, FormationLayer, FormationPlayer, FormationPosition, FormationSport, HullLayer, LineupLayer, LineupPlayer, MoveDatum, NetworkLayer, NetworkNode, PassDatum, PlayerDatum, SonarLayer, VoronoiLayer } from "./team.types.ts";
@@ -8,4 +8,5 @@ export { ZONE_SETS, ZONE_SET_IDS, buildZoneSet } from "./heat.zones.js";
8
8
  export { KYOGIJO_HEAT_STYLE } from "./style.js";
9
9
  export { KYOGIJO_TEAM_STYLE } from "./style.js";
10
10
  export { FORMATIONS, FORMATION_IDS, POSITION_NAMES, formationById, formationsOf, positionName } from "./formations.js";
11
+ export { LINEUP_CODES } from "./lineup.codes.js";
11
12
  export { clipNearer, convexHull, delaunay, neighbours, polygonArea, polygonCentroid, triangulationEdges, voronoiCells } from "./team.geometry.js";
package/dist/layers.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type Env } from "./layers.env.ts";
1
2
  import type { Layer, OutcomeStyle, TableOptions } from "./layers.types.ts";
2
3
  import type { Box, ScoreOptions, SurfaceOptions } from "./types.ts";
3
4
  /**
@@ -11,7 +12,7 @@ export interface RenderedLayers {
11
12
  summaries: string[];
12
13
  }
13
14
  /** The layers of a drawing as markup, and a sentence for each. `turned` says whether the surface group is turned a quarter. */
14
- export declare function renderLayers(o: SurfaceOptions | ScoreOptions, layers: readonly Layer[] | undefined, turned?: boolean, range?: Box): RenderedLayers;
15
+ export declare function renderLayers(o: SurfaceOptions | ScoreOptions, layers: readonly Layer[] | undefined, turned?: boolean, range?: Box, upright?: number, zone?: Env["zone"]): RenderedLayers;
15
16
  /**
16
17
  * The layers of a drawing as one SVG group, in the surface's own frame, for a caller who composes the drawing's parts. Put it inside the
17
18
  * surface's group (the one with the quarter turn, when the drawing is tall) and the marks lie on the surface, cut to its outline, with
@@ -14,6 +14,8 @@ export interface Env {
14
14
  o: SurfaceOptions | ScoreOptions;
15
15
  id: string;
16
16
  turned: boolean;
17
+ /** The turn, in degrees, that texts and logos are given to read upright: the quarter back (-90) when the surface is turned a quarter, else 0, or the surface's own (a close-up of an athletics start is turned to any angle). */
18
+ back: number;
17
19
  unit: Unit;
18
20
  outline: Outline;
19
21
  /**
@@ -30,7 +32,16 @@ export interface Env {
30
32
  home?: string;
31
33
  away?: string;
32
34
  };
35
+ /** Whether the layer being drawn writes `data-mark-id`, `data-index` and `data-zone` on its marks: set for each layer by `renderLayers`. */
36
+ marks: boolean;
37
+ /** The finest zone of the surface a place (feet, the drawing's wide frame) lies in, by id: what a mark carries as `data-zone`. `undefined` where the sport has none there. */
38
+ zone: (x: number, y: number) => string | undefined;
33
39
  }
40
+ /**
41
+ * The data attributes every mark carries, so that one listener on the drawing can link a mark to a table: `data-mark-id` (the id the caller gave the datum, else its index),
42
+ * `data-index` (its place in the layer's data) and `data-zone` (the zone it lies in, from `zoneAt`'s rules). The place is in feet in the drawing's wide frame.
43
+ */
44
+ export declare function markAttrs(env: Env, id: unknown, index: number, at?: readonly [number, number], name?: string): string;
34
45
  /** What a layer made. */
35
46
  export interface Made {
36
47
  /** The elements of the layer, and its gradients as `defs`. */
@@ -69,4 +80,4 @@ export declare function place(layer: LayerBase, env: Env, points: readonly P[],
69
80
  /** The inverse of `place`: places on the surface, in feet, as the layer's own coordinates (its frame and unit). */
70
81
  export declare function placeBack(layer: LayerBase, env: Env, points: readonly P[], unit: Unit): P[];
71
82
  export declare function newMade(): Made;
72
- export declare function envFor(o: SurfaceOptions | ScoreOptions, turned: boolean | undefined, range?: Box): Env;
83
+ export declare function envFor(o: SurfaceOptions | ScoreOptions, turned: boolean | undefined, range?: Box, upright?: number, zone?: Env["zone"]): Env;
@@ -1,8 +1,10 @@
1
1
  // What every kind of data layer is drawn against: the drawing's id, its unit and outline, the words, and what a layer made. Kept apart
2
2
  // from layers.ts so that the heat maps, which are written in files of their own, can use it without importing the file that imports them.
3
- import { safeLogo } from "./colour.js";
3
+ import { safeLogo } from "./logo.js";
4
+ import { esc } from "./format.js";
4
5
  import { drawingId, isPortrait, lengthUnit } from "./common.js";
5
6
  import { fromSurface, toSurface } from "./frames.js";
7
+ import { zoneResolver } from "./rules.js";
6
8
  import "./frames.providers.js";
7
9
  import { chooseLeague } from "./leagues.js";
8
10
  import { frameSizeOf, outlineOf } from "./outline.js";
@@ -12,6 +14,32 @@ export const isNum = (value) => typeof value === "number" && Number.isFinite(val
12
14
  export const clamp01 = (value) => Math.max(0, Math.min(1, value));
13
15
  export const own = (table, key) => Object.prototype.hasOwnProperty.call(table, key);
14
16
  export const opacityOf = (value) => (isNum(value) ? clamp01(value) : undefined);
17
+ /** The zone of a drawing's marks, made when the first mark asks: a surface the rules cannot be made for (a special game) has none. */
18
+ function zonesOf(o) {
19
+ let resolver;
20
+ return (x, y) => {
21
+ if (resolver === undefined) {
22
+ try {
23
+ resolver = o.host !== undefined ? () => undefined : zoneResolver(o.sport, o);
24
+ }
25
+ catch {
26
+ resolver = () => undefined;
27
+ }
28
+ }
29
+ return resolver(x, y);
30
+ };
31
+ }
32
+ /**
33
+ * The data attributes every mark carries, so that one listener on the drawing can link a mark to a table: `data-mark-id` (the id the caller gave the datum, else its index),
34
+ * `data-index` (its place in the layer's data) and `data-zone` (the zone it lies in, from `zoneAt`'s rules). The place is in feet in the drawing's wide frame.
35
+ */
36
+ export function markAttrs(env, id, index, at, name = "data-zone") {
37
+ if (!env.marks)
38
+ return "";
39
+ const given = typeof id === "string" && id !== "" ? id : typeof id === "number" && Number.isFinite(id) ? String(id) : String(index);
40
+ const zone = at === undefined ? undefined : env.zone(at[0], at[1]);
41
+ return ` data-mark-id="${esc(given)}" data-index="${index}"${zone === undefined ? "" : ` ${name}="${esc(zone)}"`}`;
42
+ }
15
43
  export const toArray = (value, what) => {
16
44
  if (!Array.isArray(value))
17
45
  throw new TypeError(`${what} needs data: a list of marks`);
@@ -60,20 +88,24 @@ export function placeBack(layer, env, points, unit) {
60
88
  export function newMade() {
61
89
  return { marks: "", defs: "", style: "", attr: "", opacity: undefined, drawn: 0, skipped: 0, outcomes: new Map(), teams: new Map(), low: Infinity, high: -Infinity };
62
90
  }
63
- export function envFor(o, turned, range) {
91
+ export function envFor(o, turned, range, upright, zone) {
64
92
  const language = o.language === "ja" ? "ja" : "en";
65
93
  const outline = outlineOf(o);
66
94
  const teams = o;
95
+ const quarter = turned ?? (isPortrait(o) && o.sport !== "mlb");
67
96
  return {
68
97
  o,
69
98
  id: drawingId(o),
70
- turned: turned ?? (isPortrait(o) && o.sport !== "mlb"),
99
+ turned: quarter,
100
+ back: upright ?? (quarter ? -90 : 0),
71
101
  unit: lengthUnit(o),
72
102
  outline,
73
103
  shown: range ?? outline.box,
74
104
  cropped: range !== undefined,
75
105
  base: Math.max((range ?? outline.box).w, (range ?? outline.box).h) * 0.013,
76
106
  words: KYOGIJO_STRINGS[language],
77
- logos: { home: safeLogo(teams.home?.logo), away: safeLogo(teams.away?.logo) },
107
+ logos: { home: safeLogo(teams.home?.logo, { color: teams.home?.color, accent: teams.home?.textColor }), away: safeLogo(teams.away?.logo, { color: teams.away?.color, accent: teams.away?.textColor }) },
108
+ marks: o.marks === true || o.pointer === true,
109
+ zone: zone ?? zonesOf(o),
78
110
  };
79
111
  }