@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/leagues.js CHANGED
@@ -8,10 +8,14 @@ import { BASKETBALL_LEAGUES, courtInFeet } from "./leagues/basketball.js";
8
8
  import { FOOTBALL_LEAGUES } from "./leagues/football.js";
9
9
  import { HOCKEY_LEAGUES, rinkInFeet } from "./leagues/hockey.js";
10
10
  import { CURLING_LEAGUES, sheetInFeet } from "./leagues/curling.js";
11
- import { BADMINTON_LEAGUES, PICKLEBALL_LEAGUES, TABLE_TENNIS_LEAGUES, TENNIS_LEAGUES, VOLLEYBALL_LEAGUES, netInFeet } from "./leagues/courts.js";
11
+ 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, netInFeet } from "./leagues/courts.js";
12
12
  import { AFL_LEAGUES, aflInFeet } from "./leagues/aussie.js";
13
13
  import { CRICKET_LEAGUES, cricketInFeet } from "./leagues/cricket.js";
14
14
  import { FIELD_HOCKEY_LEAGUES, fieldHockeyInFeet } from "./leagues/fieldhockey.js";
15
+ import { ATHLETICS_LEAGUES, athleticsInFeet } from "./leagues/athletics.js";
16
+ import { longOval, outerEdge } from "./skating/track.js";
17
+ import { SKATING_LEAGUES, skatingInFeet } from "./leagues/skating.js";
18
+ import { BUDO_LEAGUES, DOJO_LEAGUES, JUDO_LEAGUES, KARATE_LEAGUES, KENDO_LEAGUES, KYUDO_LEAGUES, SUMO_LEAGUES } from "./leagues/budo.js";
15
19
  import { GAELIC_LEAGUES, gaelicInFeet } from "./leagues/gaelic.js";
16
20
  import { HANDBALL_LEAGUES, handballInFeet } from "./leagues/handball.js";
17
21
  import { LACROSSE_LEAGUES, lacrosseInFeet } from "./leagues/lacrosse.js";
@@ -21,11 +25,14 @@ import { inFeet } from "./leagues/types.js";
21
25
  import { convertLength } from "./units.js";
22
26
  export { LEAGUE_SOURCES };
23
27
  export { AFL_GROUNDS } from "./leagues/aussie.js";
28
+ export { WA_STANDARD_TRACK, WA_SHORT_TRACK, WA_STAGGER_TABLE, WA_SHORT_STAGGER_TABLE } from "./leagues/athletics.js";
29
+ export { ISU_LONG_TRACK, ISU_SHORT_TRACK, ISU_FIGURE_RINK, ISU_LONG_TRACK_TABLE } from "./leagues/skating.js";
30
+ export { AJJF_CONTEST, BUDO_LEAGUES, ENTEKI, FIK_SHIAI_JO, IJF_CONTEST, IJF_KATA, JSA_DOHYO, KINTEKI, WKF_KATA, WKF_KUMITE } from "./leagues/budo.js";
24
31
  /** The family of surface each sport draws; soccer's variants are its pitches (`pitch`), not leagues. */
25
- export const FAMILY_OF = Object.freeze({ nfl: "football", cfl: "football", ifaf: "football", nhl: "hockey", nba: "basketball", mlb: "baseball", soccer: undefined, curling: "curling", tennis: "tennis", volleyball: "volleyball", badminton: "badminton", pickleball: "pickleball", tabletennis: "tabletennis", lacrosse: "lacrosse", rugby: "rugby", afl: "afl", gaelic: "gaelic", cricket: "cricket", fieldhockey: "fieldhockey", handball: "handball" });
32
+ export const FAMILY_OF = Object.freeze({ nfl: "football", cfl: "football", ifaf: "football", nhl: "hockey", nba: "basketball", mlb: "baseball", soccer: undefined, curling: "curling", tennis: "tennis", volleyball: "volleyball", badminton: "badminton", pickleball: "pickleball", tabletennis: "tabletennis", padel: "padel", squash: "squash", racquetball: "racquetball", sepaktakraw: "sepaktakraw", teqball: "teqball", roundnet: "roundnet", netball: "netball", lacrosse: "lacrosse", rugby: "rugby", afl: "afl", gaelic: "gaelic", cricket: "cricket", fieldhockey: "fieldhockey", handball: "handball", swimming: undefined, waterpolo: undefined, diving: undefined, artisticswimming: undefined, athletics: "athletics", skating: "skating", judo: "judo", karate: "karate", kendo: "kendo", sumo: "sumo", kyudo: "kyudo", dojo: "dojo" });
26
33
  /**
27
34
  * The leagues each sport can draw, in the order a menu lists them, the sport's own first (the three football sports share their
28
- * list, the football leagues). Soccer has none.
35
+ * list, the football leagues). Soccer and the pools have none.
29
36
  */
30
37
  export const LEAGUES = Object.freeze({
31
38
  nba: BASKETBALL_LEAGUES,
@@ -41,6 +48,13 @@ export const LEAGUES = Object.freeze({
41
48
  badminton: BADMINTON_LEAGUES,
42
49
  pickleball: PICKLEBALL_LEAGUES,
43
50
  tabletennis: TABLE_TENNIS_LEAGUES,
51
+ padel: PADEL_LEAGUES,
52
+ squash: SQUASH_LEAGUES,
53
+ racquetball: RACQUETBALL_LEAGUES,
54
+ sepaktakraw: SEPAK_TAKRAW_LEAGUES,
55
+ teqball: TEQBALL_LEAGUES,
56
+ roundnet: ROUNDNET_LEAGUES,
57
+ netball: NETBALL_LEAGUES,
44
58
  lacrosse: LACROSSE_LEAGUES,
45
59
  rugby: RUGBY_LEAGUES,
46
60
  afl: AFL_LEAGUES,
@@ -48,9 +62,22 @@ export const LEAGUES = Object.freeze({
48
62
  cricket: CRICKET_LEAGUES,
49
63
  fieldhockey: FIELD_HOCKEY_LEAGUES,
50
64
  handball: HANDBALL_LEAGUES,
65
+ // The pools have one rulebook, World Aquatics', and no leagues.
66
+ swimming: [],
67
+ waterpolo: [],
68
+ diving: [],
69
+ artisticswimming: [],
70
+ athletics: ATHLETICS_LEAGUES,
71
+ skating: SKATING_LEAGUES,
72
+ judo: JUDO_LEAGUES,
73
+ karate: KARATE_LEAGUES,
74
+ kendo: KENDO_LEAGUES,
75
+ sumo: SUMO_LEAGUES,
76
+ kyudo: KYUDO_LEAGUES,
77
+ dojo: DOJO_LEAGUES,
51
78
  });
52
79
  /** Every league of every family, once each. */
53
- export const VARIANTS = Object.freeze([...BASKETBALL_LEAGUES, ...HOCKEY_LEAGUES, ...FOOTBALL_LEAGUES, ...BASEBALL_LEAGUES, ...CURLING_LEAGUES, ...TENNIS_LEAGUES, ...VOLLEYBALL_LEAGUES, ...BADMINTON_LEAGUES, ...PICKLEBALL_LEAGUES, ...TABLE_TENNIS_LEAGUES, ...LACROSSE_LEAGUES, ...RUGBY_LEAGUES, ...AFL_LEAGUES, ...GAELIC_LEAGUES, ...CRICKET_LEAGUES, ...FIELD_HOCKEY_LEAGUES, ...HANDBALL_LEAGUES]);
80
+ export const VARIANTS = Object.freeze([...BASKETBALL_LEAGUES, ...HOCKEY_LEAGUES, ...FOOTBALL_LEAGUES, ...BASEBALL_LEAGUES, ...CURLING_LEAGUES, ...TENNIS_LEAGUES, ...VOLLEYBALL_LEAGUES, ...BADMINTON_LEAGUES, ...PICKLEBALL_LEAGUES, ...TABLE_TENNIS_LEAGUES, ...PADEL_LEAGUES, ...SQUASH_LEAGUES, ...RACQUETBALL_LEAGUES, ...SEPAK_TAKRAW_LEAGUES, ...TEQBALL_LEAGUES, ...ROUNDNET_LEAGUES, ...NETBALL_LEAGUES, ...LACROSSE_LEAGUES, ...RUGBY_LEAGUES, ...AFL_LEAGUES, ...GAELIC_LEAGUES, ...CRICKET_LEAGUES, ...FIELD_HOCKEY_LEAGUES, ...HANDBALL_LEAGUES, ...ATHLETICS_LEAGUES, ...BUDO_LEAGUES]);
54
81
  /** The ids of a sport's leagues. */
55
82
  export const leagueIds = (sport) => LEAGUES[sport].map((league) => league.id);
56
83
  /** A league by its sport and id, or `undefined`. */
@@ -160,7 +187,7 @@ export const courtOf = (league, year) => courtInFeet(leagueAtOf(league, year).fi
160
187
  export const rinkOf = (league, year) => rinkInFeet(leagueAtOf(league, year).figures, figuresUnit(league));
161
188
  /** A curling sheet of a league, in feet. A sheet has no history; a year is ignored. */
162
189
  export const sheetOf = (league = CURLING_LEAGUES[0]) => sheetInFeet(league.dimensions, league.figuresUnit ?? league.unit);
163
- /** A net sport's court of a league (tennis, volleyball and beach volleyball, badminton, pickleball, table tennis), in feet. These courts have no history; a year is ignored. */
190
+ /** A net sport's court of a league (tennis, volleyball, beach and sitting volleyball, badminton, pickleball, table tennis, padel, squash, racquetball, sepak takraw, teqball, roundnet and netball), in feet. These courts have no history; a year is ignored. */
164
191
  export const netOf = (league) => netInFeet(league.dimensions, figuresUnit(league));
165
192
  /** A lacrosse surface of a league, in feet (the box floor, or a field). These have no history; a year is ignored. */
166
193
  export const lacrosseOf = (league) => lacrosseInFeet(league.dimensions, figuresUnit(league));
@@ -174,6 +201,10 @@ export const gaelicOf = (league) => gaelicInFeet(league.dimensions, figuresUnit(
174
201
  export const cricketOf = (league) => cricketInFeet(league.dimensions, figuresUnit(league));
175
202
  /** A field hockey pitch, in feet. */
176
203
  export const fieldHockeyOf = (league) => fieldHockeyInFeet(league.dimensions, figuresUnit(league));
204
+ /** A skating rink of a league, in feet. */
205
+ export const skatingOf = (league) => skatingInFeet(league.dimensions, figuresUnit(league));
206
+ /** An athletics track of a league, in feet. */
207
+ export const athleticsOf = (league) => athleticsInFeet(league.dimensions, figuresUnit(league));
177
208
  /** A handball court, in feet. */
178
209
  export const handballOf = (league) => handballInFeet(league.dimensions, figuresUnit(league));
179
210
  /** A football field of a league in a season: the spec, in feet. */
@@ -215,6 +246,13 @@ export function leagueSize(sport, id, unit) {
215
246
  case "badminton":
216
247
  case "pickleball":
217
248
  case "tabletennis":
249
+ case "padel":
250
+ case "squash":
251
+ case "racquetball":
252
+ case "sepaktakraw":
253
+ case "teqball":
254
+ case "roundnet":
255
+ case "netball":
218
256
  feet = netOf(league);
219
257
  break;
220
258
  case "football": {
@@ -245,6 +283,57 @@ export function leagueSize(sport, id, unit) {
245
283
  feet = { length: 2 * f.boundary.drawn, width: 2 * f.boundary.drawn };
246
284
  break;
247
285
  }
286
+ case "athletics": {
287
+ // The oval's outer edge with its last lane drawn: two semicircles and a straight long, a diameter wide.
288
+ const f = athleticsOf(league);
289
+ const outer = f.radius + f.lanes.drawn * f.lane;
290
+ feet = { length: f.straight + 2 * outer, width: 2 * outer };
291
+ break;
292
+ }
293
+ case "skating": {
294
+ // The long track: the ice out to the padding; the others: the rink.
295
+ const d = league.dimensions;
296
+ const m = d.kind === "long-track" ? (() => { const o = longOval(undefined, undefined, d); const R = outerEdge(o) + d.padding.clear; return { length: o.straight + 2 * R, width: 2 * R }; })() : d.kind === "short-track" ? d.rink : { length: d.length.drawn, width: d.width.drawn };
297
+ feet = { length: convertLength(m.length, league.unit, "ft"), width: convertLength(m.width, league.unit, "ft") };
298
+ break;
299
+ }
300
+ case "judo": {
301
+ // The contest area with its safety area all round it, in metres.
302
+ const d = league.dimensions;
303
+ const m = d.contest.drawn + 2 * d.safety.drawn;
304
+ feet = { length: convertLength(m, "m", "ft"), width: convertLength(m, "m", "ft") };
305
+ break;
306
+ }
307
+ case "karate": {
308
+ const d = league.dimensions;
309
+ const m = d.area + 2 * d.safety;
310
+ feet = { length: convertLength(m, "m", "ft"), width: convertLength(m, "m", "ft") };
311
+ break;
312
+ }
313
+ case "kendo": {
314
+ const m = league.dimensions.side.drawn;
315
+ feet = { length: convertLength(m, "m", "ft"), width: convertLength(m, "m", "ft") };
316
+ break;
317
+ }
318
+ case "sumo": {
319
+ const m = league.dimensions.platform;
320
+ feet = { length: convertLength(m, "m", "ft"), width: convertLength(m, "m", "ft") };
321
+ break;
322
+ }
323
+ case "kyudo": {
324
+ // The shajō from its back wall to the back of the azuchi, and the width of its frontage with the judges' side.
325
+ const d = league.dimensions;
326
+ const frontage = (d.count - 1) * d.step.drawn + 2 * d.hall.side + d.hall.judges;
327
+ const length = d.hall.rear + d.hall.depth - d.hall.front + d.distance - 1 + d.azuchi.depth;
328
+ feet = { length: convertLength(length, "m", "ft"), width: convertLength(frontage, "m", "ft") };
329
+ break;
330
+ }
331
+ case "dojo": {
332
+ // The usual 20 jō: 5 mats' widths across and 8 along.
333
+ const d = league.dimensions;
334
+ feet = { length: convertLength(8 * d.mat.width, "m", "ft"), width: convertLength(5 * d.mat.width, "m", "ft") };
335
+ break;
336
+ }
248
337
  default:
249
338
  throw new Error(`No fixed size for the ${league.family} league "${id}": a diamond's size is its fence`);
250
339
  }
@@ -356,6 +445,69 @@ export function leagueFigures(league) {
356
445
  ["lines", `${w(t.edgeLine)} at the edges, a ${w(t.centreLine)} centre line`],
357
446
  ];
358
447
  }
448
+ case "padel": {
449
+ const p = netOf(league);
450
+ return [
451
+ ["court", `${w(p.length)} by ${w(p.width)}, inside its walls`],
452
+ ["service line", `${w(p.serviceLine)} from the net`],
453
+ ["net", `${w(p.net.heightCentre)} at the centre, ${w(p.net.heightEnds)} at the ends, ${w(p.net.length)} long`],
454
+ ["walls", `the end walls ${w(p.enclosure.endHeight)} high, the side walls ${w(p.enclosure.sideWall)} long at each end`],
455
+ ];
456
+ }
457
+ case "squash": {
458
+ const q = netOf(league);
459
+ return [
460
+ ["court", `${w(q.length)} by ${w(q.width)}`],
461
+ ["short line", `${w(q.shortLine)} from the back wall to its nearest edge`],
462
+ ["service box", `${w(q.serviceBox)} square inside its lines`],
463
+ ["front wall", `the tin ${w(q.wall.tin)}, the service line ${w(q.wall.serviceLine)} and the front wall line ${w(q.wall.frontWallLine)} up`],
464
+ ];
465
+ }
466
+ case "racquetball": {
467
+ const r = netOf(league);
468
+ return [
469
+ ["court", `${w(r.length)} by ${w(r.width)}, ${w(r.height)} high`],
470
+ ["short line", `${w(r.shortLine)} from the back wall to its back edge`],
471
+ ["service line", `${w(r.serviceLine)} in front of the short line`],
472
+ ["receiving line", `${w(r.receiving.behind)} behind the short line`],
473
+ ];
474
+ }
475
+ case "sepaktakraw": {
476
+ const t = netOf(league);
477
+ return [
478
+ ["court", `${w(t.length)} by ${w(t.width)}`],
479
+ ["quarter circles", `${w(t.quarterCircle)} radius, at the ends of the centre line`],
480
+ ["service circles", `${w(t.serviceCircle.radius)} radius, ${w(t.serviceCircle.fromBack)} from the back line`],
481
+ ["net", `${w(t.net.heightMen)} high at the centre (women's ${w(t.net.heightWomen)})`],
482
+ ];
483
+ }
484
+ case "teqball": {
485
+ const t = netOf(league);
486
+ return [
487
+ ["court", `at least ${w(t.length)} by ${w(t.width)}`],
488
+ ["table", `${w(t.table.length)} by ${w(t.table.width)}`],
489
+ ["service line", `${w(t.serviceLine)} from the middle of the table`],
490
+ ["net", `${w(t.net.width)} wide, ${w(t.net.height)} high`],
491
+ ];
492
+ }
493
+ case "roundnet": {
494
+ const t = netOf(league);
495
+ return [
496
+ ["court", `at least ${w(t.length)} by ${w(t.width)}, with no out of bounds`],
497
+ ["set", `${w(t.set.diameter)} across`],
498
+ ["serving line", `a circle of ${w(t.servingRadius)} radius`],
499
+ ["no hit zone", `a circle of ${w(t.noHitRadius)} radius`],
500
+ ];
501
+ }
502
+ case "netball": {
503
+ const n = netOf(league);
504
+ return [
505
+ ["court", `${w(n.length)} by ${w(n.width)}`],
506
+ ["centre circle", `${w(n.centreCircle)} across`],
507
+ ["goal circles", `semicircles of ${w(n.goalCircle)} radius`],
508
+ ["goalposts", `${w(n.post.height)} high, at the middle of each goal line`],
509
+ ];
510
+ }
359
511
  case "football": {
360
512
  const f = fieldOf(league);
361
513
  return [
@@ -439,6 +591,40 @@ export function leagueFigures(league) {
439
591
  ["goal", `${w(f.goalWidth)} wide and ${w(f.goalHeight)} high`],
440
592
  ];
441
593
  }
594
+ case "skating": {
595
+ const f = skatingOf(league);
596
+ if (f.kind === "long-track") {
597
+ return [
598
+ ["track", `a lap of ${w(f.lap)} measured ${w(f.measure)} outside the inner edge, the inner curve ${w(f.innerRadius.min)} to ${w(f.innerRadius.max)} in radius`],
599
+ ["lanes", `an inner lane of ${w(f.innerLane)} and an outer lane of at least ${w(f.outerLane.min)}, the warm-up lane at least ${w(f.warmUpLane)} wide`],
600
+ ["blocks", `${w(f.blocks.near)} apart for the first ${w(f.blocks.nearLength)} of a curve, ${w(f.blocks.far)} after`],
601
+ ["coaches' area", `a line ${w(f.coaches.offset)} from the outside edge, from ${w(f.coaches.after)} after the end of a curve to ${w(f.coaches.before)} before the next`],
602
+ ["padding", `${w(f.padding.thick)} thick, nothing fixed within ${w(f.padding.clear)} of the edge`],
603
+ ];
604
+ }
605
+ if (f.kind === "short-track") {
606
+ return [
607
+ ["oval", `a lap of ${w(f.lap)}: straights of ${w(f.straight)} between the centres of the curves, a track line of ${w(f.radius)} radius`],
608
+ ["blocks", `${f.blocksPerCurve} in each curve, on a radius of ${w(f.blocks)}`],
609
+ ["rink", `at least ${w(f.rink.length)} by ${w(f.rink.width)}`],
610
+ ["tracks", `5 (${w(f.tracks.five.shift)} apart, starting lines ${w(f.tracks.five.lines)} apart) or 7 (${w(f.tracks.seven.shift)} and ${w(f.tracks.seven.lines)})`],
611
+ ["starting positions", `${f.dots.count} dots every ${w(f.dots.step)}, from ${w(f.dots.from)} out from the inner side`],
612
+ ];
613
+ }
614
+ return [
615
+ ["rink", `${w(f.length.max)} by ${w(f.width.max)} if possible, at least ${w(f.length.min)} by ${w(f.width.min)}`],
616
+ ];
617
+ }
618
+ case "athletics": {
619
+ const f = athleticsOf(league);
620
+ return [
621
+ ["track", `two straights of ${w(f.straight)} and two bends of ${w(f.radius)} radius at the kerb`],
622
+ ["lanes", `${f.lanes.drawn} of ${w(f.lane)} (${f.lanes.min} to ${f.lanes.max})`],
623
+ ["running line", `${w(f.inner)} outside the kerb in lane 1, ${w(f.outer)} outside the line in the others`],
624
+ ["straight", `${f.straightLanes.min} to ${f.straightLanes.max} lanes of ${w(f.straightLane)}, a starting area of ${w(f.startArea)} and a run-out of ${w(f.runOut)}`],
625
+ ["banking", f.banking === null ? "none" : `${f.banking} degrees`],
626
+ ];
627
+ }
442
628
  case "handball": {
443
629
  const f = handballOf(league);
444
630
  return [
@@ -448,6 +634,61 @@ export function leagueFigures(league) {
448
634
  ["goal", `${w(f.goalWidth)} wide and ${w(f.goalHeight)} high`],
449
635
  ];
450
636
  }
637
+ case "judo": {
638
+ const f = league.dimensions;
639
+ return [
640
+ ["contest area", `${w(convertLength(f.contest.min, "m", "ft"))} to ${w(convertLength(f.contest.max, "m", "ft"))} square (${f.contest.drawn} m drawn)`],
641
+ ["safety area", `at least ${w(convertLength(f.safety.min, "m", "ft"))} wide; at least ${w(convertLength(f.common, "m", "ft"))} between two areas`],
642
+ ["tatami", `${f.tatami.length} m by ${f.tatami.width} m by ${f.tatami.thickness * 100} cm`],
643
+ ["free zone", `at least ${f.freeZone * 100} cm round the competition area`],
644
+ ["platform", `${f.platform} m wider and longer than the tatami`],
645
+ ["start tape", f.marks === null ? "none" : `${f.marks.width * 100} cm by ${f.marks.length * 100} cm, ${f.marks.fromCentre} m from the centre`],
646
+ ];
647
+ }
648
+ case "karate": {
649
+ const f = league.dimensions;
650
+ return [
651
+ ["area", `${f.area} m square, measured from the outside`],
652
+ ["boundary band", f.band === 0 ? "none" : `the outer ${f.band} m in another colour`],
653
+ ["safety area", `${f.safety} m, and ${f.between} m between areas`],
654
+ ["start mats", f.startMats === null ? "none" : `${f.startMats.fromCentre} m from the centre`],
655
+ ["referee", `${f.referee} m from the boundary; each judge ${f.judges} m off a corner`],
656
+ ];
657
+ }
658
+ case "kendo": {
659
+ const f = league.dimensions;
660
+ return [
661
+ ["shiai-jo", `${f.side.min} m to ${f.side.max} m a side, wooden floor`],
662
+ ["lines", `${f.lineWidth.min * 100} cm to ${f.lineWidth.max * 100} cm, white`],
663
+ ["centre cross", `${f.cross.min * 100} cm to ${f.cross.max * 100} cm`],
664
+ ["kaishi-sen", `${f.startLine.length * 100} cm long, ${f.startLine.fromCentre} m from the centre`],
665
+ ["outside", `${f.outside} m kept clear`],
666
+ ];
667
+ }
668
+ case "sumo": {
669
+ const f = league.dimensions;
670
+ return [
671
+ ["platform", `${f.platform} m square, ${f.height.min * 100} cm to ${f.height.max * 100} cm high`],
672
+ ["ring", `${f.circle} m across, ${f.tawara.count} tawara (${f.tawara.tokuda} tokudawara)`],
673
+ ["shikiri-sen", `${f.shikiri.length * 100} cm long, ${f.shikiri.width * 100} cm wide, ${f.shikiri.apart * 100} cm apart`],
674
+ ];
675
+ }
676
+ case "kyudo": {
677
+ const f = league.dimensions;
678
+ return [
679
+ ["distance", `${f.distance} m from the shooting position to the target`],
680
+ ["target", `${f.target.diameter * 100} cm across, its centre ${f.target.centre * 100} cm up, tilted ${f.target.tilt} degrees`],
681
+ ["shooters", `${f.step.drawn} m apart (${f.step.min} m to ${f.step.max} m), ${f.honza} m from the shooting position to the honza`],
682
+ ["shajō", `${f.hall.depth} m deep, ${f.hall.side} m from the end shooters to the walls, ceiling ${f.ceiling} m`],
683
+ ];
684
+ }
685
+ case "dojo": {
686
+ const f = league.dimensions;
687
+ return [
688
+ ["tatami", `${f.mat.length} m by ${f.mat.width} m (${f.region.en})`],
689
+ ["area of a mat", `${Math.round(f.mat.length * f.mat.width * 1000) / 1000} square metres`],
690
+ ];
691
+ }
451
692
  default: {
452
693
  const d = diamondOf(league);
453
694
  const f = d.fence;
@@ -0,0 +1,23 @@
1
+ import type { Formation, FormationPosition, FormationSport, LineupPlayer } from "./team.types.ts";
2
+ /** The positions a short code may stand for, by sport, in the order a player takes them: a code that is also an id of the formation is that place first. */
3
+ export declare const LINEUP_CODES: Readonly<Record<FormationSport, Readonly<Record<string, readonly string[]>>>>;
4
+ /** A code as the table has it: upper case, with no spaces, dots or hyphens. */
5
+ export declare const codeOf: (pos: unknown) => string;
6
+ /** The ids a player's code may stand for in a formation of a sport, best first: the id itself, then the table's. A second line's ids end in its number. */
7
+ export declare function candidates(sport: FormationSport, player: LineupPlayer, ids: ReadonlySet<string>): string[];
8
+ /** The places of a formation that a lineup may fill: the side on the surface and, beside it, the places it only lists. */
9
+ export declare const spotsOf: (f: Formation) => FormationPosition[];
10
+ /** Where each player of a lineup stands in a formation, by the index of the player; the places taken; and the players with none. */
11
+ export interface Assignment {
12
+ /** The id of the position of each player, or undefined. */
13
+ of: (string | undefined)[];
14
+ placed: number;
15
+ /** How many took the place their own code names, which settles a tie between formations. */
16
+ exact: number;
17
+ }
18
+ /** Players to places. Those whose code is a place's id take it first, then the others take the first free place their code may stand for; a volleyball team turns by `rotation`. */
19
+ export declare function assign(f: Formation, players: readonly LineupPlayer[], rotation?: number): Assignment;
20
+ /** The formations that may hold a lineup on a surface, in table order. */
21
+ export declare const formationsFor: (sports: readonly FormationSport[]) => Formation[];
22
+ /** The formation that places the most of the players: the first of the table on a tie. */
23
+ export declare function bestFormation(candidatesList: readonly Formation[], players: readonly LineupPlayer[], rotation?: number): Formation | undefined;
@@ -0,0 +1,122 @@
1
+ // How a lineup finds a player's place: the short codes a team sheet uses (`CB`, `D`, `OF`, `PR`, the scorer's numbers 1 to 9) are matched to the ids of a formation's positions,
2
+ // and each player takes the first free place of the codes that fit. Written for this package; the codes are the conventional ones of each sport and are listed in docs/team-shape.md.
3
+ import { FORMATIONS } from "./formations.js";
4
+ /** The positions a short code may stand for, by sport, in the order a player takes them: a code that is also an id of the formation is that place first. */
5
+ export const LINEUP_CODES = Object.freeze({
6
+ soccer: {
7
+ GOALKEEPER: ["GK"], G: ["GK"],
8
+ CB: ["CB", "RCB", "LCB"], D: ["CB", "RCB", "LCB"], DF: ["CB", "RCB", "LCB"],
9
+ RB: ["RB", "RWB"], LB: ["LB", "LWB"], RWB: ["RWB", "RB"], LWB: ["LWB", "LB"],
10
+ DM: ["CDM", "RDM", "LDM"], CDM: ["CDM", "RDM", "LDM"], RDM: ["RDM", "CDM"], LDM: ["LDM", "CDM"],
11
+ CM: ["CM", "RCM", "LCM"], M: ["CM", "RCM", "LCM"], RCM: ["RCM", "CM"], LCM: ["LCM", "CM"],
12
+ AM: ["CAM", "RAM", "LAM"], CAM: ["CAM", "RAM", "LAM"], RAM: ["RAM", "CAM"], LAM: ["LAM", "CAM"],
13
+ RM: ["RM", "RW"], LM: ["LM", "LW"], RW: ["RW", "RM"], LW: ["LW", "LM"],
14
+ ST: ["ST", "RS", "LS"], CF: ["ST", "RS", "LS"], S: ["ST", "RS", "LS"], FW: ["ST", "RS", "LS", "RW", "LW"], RS: ["RS", "ST"], LS: ["LS", "ST"],
15
+ },
16
+ nhl: {
17
+ GOALIE: ["G"], GK: ["G"], D: ["LD", "RD"], W: ["LW", "RW"], F: ["C", "LW", "RW"],
18
+ G2: ["G"],
19
+ },
20
+ nba: { G: ["PG", "SG"], F: ["SF", "PF"], GF: ["SG", "SF"], FC: ["PF", "C"] },
21
+ nfl: {
22
+ WR: ["WR1", "WR2", "WR3"], RB: ["HB", "FB"], OG: ["LG", "RG"], OT: ["LT", "RT"], T: ["LT", "RT"], G: ["LG", "RG"],
23
+ DE: ["LDE", "RDE"], DT: ["LDT", "RDT", "NT"], NT: ["NT"], CB: ["LCB", "RCB"], S: ["FS", "SS"],
24
+ LB: ["MLB", "LLB", "RLB", "LOLB", "LILB", "RILB", "ROLB"], OLB: ["LOLB", "ROLB", "LLB", "RLB"], ILB: ["LILB", "RILB", "MLB"],
25
+ },
26
+ mlb: {
27
+ "1": ["P"], "2": ["C"], "3": ["1B"], "4": ["2B"], "5": ["3B"], "6": ["SS"], "7": ["LF"], "8": ["CF"], "9": ["RF"],
28
+ PITCHER: ["P"], CATCHER: ["C"], OF: ["LF", "CF", "RF"], IF: ["1B", "2B", "SS", "3B"], DESIGNATEDHITTER: ["DH"],
29
+ },
30
+ rugby: {
31
+ LHP: ["1"], PR: ["1", "3"], HK: ["2"], HO: ["2"], THP: ["3"], LK: ["4", "5"], LO: ["4", "5"], L: ["4", "5"], FL: ["6", "7"], BF: ["6"], OF: ["7"], N8: ["8"], NO8: ["8"],
32
+ SH: ["9"], FH: ["10"], SO: ["10"], IC: ["12"], OC: ["13"], CTB: ["12", "13"], C: ["12", "13"], W: ["11", "14"], WG: ["11", "14"], WTB: ["11", "14"], LW: ["11"], RW: ["14"], FB: ["15"],
33
+ },
34
+ afl: {
35
+ BP: ["BPL", "BPR"], HB: ["HBFL", "CHB", "HBFR"], HBF: ["HBFL", "HBFR"], W: ["WL", "WR"], HF: ["HFFL", "CHF", "HFFR"], HFF: ["HFFL", "HFFR"], FP: ["FPL", "FPR"],
36
+ R: ["RUC"], RK: ["RUC"], RUCK: ["RUC"], RUCKROVER: ["RR"], ROVER: ["ROV"], RO: ["ROV"],
37
+ },
38
+ cricket: {
39
+ BOWLER: ["BWL"], KEEPER: ["WK"], SL: ["SL1", "SL2", "SL3"], SLIP: ["SL1", "SL2", "SL3"], GULLY: ["GU"], POINT: ["PT"], COVER: ["CV"], MIDOFF: ["MO"], MIDON: ["MN"],
40
+ MIDWICKET: ["MW"], SQUARELEG: ["SQ"], FINELEG: ["FL"], THIRDMAN: ["TM"], LONGOFF: ["LO"], LONGON: ["LN"], DEEPCOVER: ["DC"], DEEPMIDWICKET: ["DM"],
41
+ },
42
+ volleyball: { "1": ["P1"], "2": ["P2"], "3": ["P3"], "4": ["P4"], "5": ["P5"], "6": ["P6"] },
43
+ handball: { G: ["GK"], P: ["PV"], PIVOT: ["PV"], LINE: ["PV"], W: ["LW", "RW"], B: ["LB", "CB", "RB"] },
44
+ waterpolo: { G: ["GK"], W: ["LW", "RW"], D: ["LD", "RD"], FLAT: ["LD", "RD"], HS: ["CF"], HOLE: ["CF"], H: ["CF"], PT: ["CB"], POINT: ["CB"] },
45
+ fieldhockey: {
46
+ G: ["GK"], FB: ["RB", "LB"], CB: ["CB", "RCB", "LCB"], D: ["CB", "RCB", "LCB"], M: ["CM", "RCM", "LCM"], CM: ["CM", "RCM", "LCM"], RM: ["RM", "RW"], LM: ["LM", "LW"],
47
+ F: ["CF", "RW", "LW"], ST: ["CF"], RW: ["RW", "RM"], LW: ["LW", "LM"],
48
+ },
49
+ netball: {},
50
+ });
51
+ /** A code as the table has it: upper case, with no spaces, dots or hyphens. */
52
+ export const codeOf = (pos) => String(typeof pos === "number" || typeof pos === "string" ? pos : "").trim().toUpperCase().replace(/[\s.\-_]+/g, "");
53
+ /** The ids a player's code may stand for in a formation of a sport, best first: the id itself, then the table's. A second line's ids end in its number. */
54
+ export function candidates(sport, player, ids) {
55
+ const own = typeof player.pos === "string" ? player.pos.trim() : String(player.pos);
56
+ const code = codeOf(player.pos);
57
+ const line = typeof player.line === "number" && Number.isInteger(player.line) && player.line > 1 ? String(player.line) : "";
58
+ const listed = Object.prototype.hasOwnProperty.call(LINEUP_CODES[sport], code) ? LINEUP_CODES[sport][code] : [];
59
+ const base = [own, code, ...listed];
60
+ const wanted = line === "" ? base : base.map((id) => `${id}${line}`);
61
+ return [...new Set(wanted)].filter((id) => ids.has(id));
62
+ }
63
+ /** The places of a formation that a lineup may fill: the side on the surface and, beside it, the places it only lists. */
64
+ export const spotsOf = (f) => [...f.positions, ...(f.extra ?? [])];
65
+ /** Players to places. Those whose code is a place's id take it first, then the others take the first free place their code may stand for; a volleyball team turns by `rotation`. */
66
+ export function assign(f, players, rotation = 1) {
67
+ const ids = new Set(spotsOf(f).map((p) => p.id));
68
+ const turned = f.sport === "volleyball" ? players.map((p) => zoneAfter(p, rotation)) : players;
69
+ const of = new Array(turned.length).fill(undefined);
70
+ const taken = new Set();
71
+ const lists = turned.map((p) => (typeof p === "object" && p !== null ? candidates(f.sport, p, ids) : []));
72
+ // The exact codes first, so that a CB on the sheet cannot take the place an RCB has asked for by name.
73
+ let exact = 0;
74
+ turned.forEach((p, i) => {
75
+ if (typeof p !== "object" || p === null)
76
+ return;
77
+ const line = typeof p.line === "number" && p.line > 1 ? String(p.line) : "";
78
+ const own = lists[i].find((id) => id === `${typeof p.pos === "string" ? p.pos.trim() : String(p.pos)}${line}` || id === `${codeOf(p.pos)}${line}`);
79
+ if (own !== undefined && !taken.has(own)) {
80
+ of[i] = own;
81
+ taken.add(own);
82
+ exact += 1;
83
+ }
84
+ });
85
+ turned.forEach((_, i) => {
86
+ if (of[i] !== undefined)
87
+ return;
88
+ const free = lists[i].find((id) => !taken.has(id));
89
+ if (free !== undefined) {
90
+ of[i] = free;
91
+ taken.add(free);
92
+ }
93
+ });
94
+ return { of, placed: of.filter((id) => id !== undefined).length, exact };
95
+ }
96
+ /** A volleyball player after the rotations: each moves one place clockwise, from 2 to 1, 1 to 6, 6 to 5, 5 to 4, 4 to 3 and 3 to 2. */
97
+ function zoneAfter(p, rotation) {
98
+ if (typeof p !== "object" || p === null)
99
+ return p;
100
+ const code = codeOf(p.pos).replace(/^P/, "");
101
+ if (!/^[1-6]$/.test(code))
102
+ return p;
103
+ const turns = Number.isInteger(rotation) && rotation >= 1 ? (rotation - 1) % 6 : 0;
104
+ const zone = ((((Number(code) - 1 - turns) % 6) + 6) % 6) + 1;
105
+ return { ...p, pos: `P${zone}` };
106
+ }
107
+ /** The formations that may hold a lineup on a surface, in table order. */
108
+ export const formationsFor = (sports) => Object.values(FORMATIONS).filter((f) => sports.includes(f.sport));
109
+ /** The formation that places the most of the players: the first of the table on a tie. */
110
+ export function bestFormation(candidatesList, players, rotation = 1) {
111
+ let best;
112
+ let score = -1;
113
+ for (const f of candidatesList) {
114
+ const a = assign(f, players, rotation);
115
+ const n = a.placed * 1000 + a.exact;
116
+ if (n > score) {
117
+ best = f;
118
+ score = n;
119
+ }
120
+ }
121
+ return best;
122
+ }
package/dist/logo.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ /** What a caller says about the team an emblem stands for: its colours and letters, so a crest id takes them; and the theme of the drawing it goes in. */
2
+ export interface EmblemContext {
3
+ color?: string;
4
+ accent?: string;
5
+ initials?: string;
6
+ theme?: "inherit" | "auto" | "light" | "dark";
7
+ }
8
+ /**
9
+ * The SVG document for a value that names an emblem (`"trophy:cup"`, `"crest:shield"`, `"sport:nhl/line"`), or `undefined` when it does not or when no renderer is plugged in. Drawn for an image: the theme is `auto` unless
10
+ * the context says otherwise. A crest takes the context's colours and letters.
11
+ */
12
+ export declare function emblemDocument(value: unknown, context?: EmblemContext): string | undefined;
13
+ /**
14
+ * A logo as it may be written into an image's `href`, or `undefined`. An `https:` or `http:` address, a relative path, an image `data:` address, an SVG document as text (written as an image, which cannot
15
+ * run scripts), or, with a renderer of emblems plugged in, the id of an emblem (`"trophy:cup"`, `"medal:gold"`, `"sport:nhl"`, `"crest:shield"`, a trophy or award by its short name such as `"cup"`, with `/line`
16
+ * for the outline style), drawn for an image with the outline in dark or pale ink by the device's setting. The second argument gives a crest the team's colours and letters. With a renderer, a name that is
17
+ * an emblem's id is the emblem, not a file of that name: write `./cup` for the file. Without one, an id is an address like any other, and `"trophy:cup"` is refused.
18
+ * @example
19
+ * ```ts
20
+ * import { safeLogo } from "@johnmorrisdotca/kyogijo-stadiums";
21
+ * console.log(safeLogo("https://example.com/gulls.svg"), safeLogo("javascript:alert(1)"));
22
+ * // https://example.com/gulls.svg undefined
23
+ * ```
24
+ */
25
+ export declare function safeLogo(value: unknown, context?: EmblemContext): string | undefined;
package/dist/logo.js ADDED
@@ -0,0 +1,47 @@
1
+ // The one path every logo, flag, emblem and mark takes into a drawing: an address, an image `data:` address, an SVG document as text, or, when a renderer of ready-made emblems is plugged in
2
+ // (`useEmblems`, or the `emblems` option), the id of one (`"trophy:cup"`, `"crest:shield"`, `"sport:hockey/line"`). The result is an address that may be written into an image's `href`, or `undefined`.
3
+ import { safePicture } from "./colour.js";
4
+ import { GROUPED_ID, emblemRenderer, renderedEmblem } from "./emblems-source.js";
5
+ let told = false;
6
+ /** Once, in development: an id with its group was given and nothing is plugged in to draw it. */
7
+ function hint(value) {
8
+ if (told || typeof value !== "string" || !GROUPED_ID.test(value.trim()))
9
+ return;
10
+ const process = globalThis.process;
11
+ if (process?.env?.NODE_ENV === "production")
12
+ return;
13
+ told = true;
14
+ console.warn(`[kyogijo-stadiums] "${value.trim().slice(0, 40)}" is the id of an emblem, but no emblem renderer is plugged in, so it was ignored. Plug in Dougu Sports once: import { renderEmblem } from "@johnmorrisdotca/dougu-sports/emblems"; useEmblems(renderEmblem); (or pass emblems: renderEmblem). See https://johnmorrisdotca.github.io/kyogijo-stadiums/docs/emblems.html`);
15
+ }
16
+ /**
17
+ * The SVG document for a value that names an emblem (`"trophy:cup"`, `"crest:shield"`, `"sport:nhl/line"`), or `undefined` when it does not or when no renderer is plugged in. Drawn for an image: the theme is `auto` unless
18
+ * the context says otherwise. A crest takes the context's colours and letters.
19
+ */
20
+ export function emblemDocument(value, context) {
21
+ const crest = typeof value === "string" && value.trim().startsWith("crest:");
22
+ return renderedEmblem(value, {
23
+ theme: context?.theme ?? "auto",
24
+ ...(crest ? { tint: context?.color, accent: context?.accent, initials: context?.initials } : {}),
25
+ });
26
+ }
27
+ /**
28
+ * A logo as it may be written into an image's `href`, or `undefined`. An `https:` or `http:` address, a relative path, an image `data:` address, an SVG document as text (written as an image, which cannot
29
+ * run scripts), or, with a renderer of emblems plugged in, the id of an emblem (`"trophy:cup"`, `"medal:gold"`, `"sport:nhl"`, `"crest:shield"`, a trophy or award by its short name such as `"cup"`, with `/line`
30
+ * for the outline style), drawn for an image with the outline in dark or pale ink by the device's setting. The second argument gives a crest the team's colours and letters. With a renderer, a name that is
31
+ * an emblem's id is the emblem, not a file of that name: write `./cup` for the file. Without one, an id is an address like any other, and `"trophy:cup"` is refused.
32
+ * @example
33
+ * ```ts
34
+ * import { safeLogo } from "@johnmorrisdotca/kyogijo-stadiums";
35
+ * console.log(safeLogo("https://example.com/gulls.svg"), safeLogo("javascript:alert(1)"));
36
+ * // https://example.com/gulls.svg undefined
37
+ * ```
38
+ */
39
+ export function safeLogo(value, context) {
40
+ const emblem = emblemDocument(value, context);
41
+ if (emblem !== undefined)
42
+ return safePicture(emblem);
43
+ const picture = safePicture(value);
44
+ if (picture === undefined && emblemRenderer() === undefined)
45
+ hint(value);
46
+ return picture;
47
+ }
package/dist/look.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import type { LookName, Sport } from "./types.ts";
2
2
  /** The parts of a palette, each a custom property of the stylesheet. */
3
- export type PaletteKey = "ink" | "line" | "apron" | "surface" | "alt" | "zone" | "boards" | "red" | "blue" | "dirt" | "foul" | "infield" | "crease" | "key" | "court" | "post" | "pylon" | "rgo" | "rgm" | "rgi" | "rgb" | "hog" | "hack" | "fgz" | "pebble" | "free" | "net" | "area";
3
+ export type PaletteKey = "ink" | "line" | "apron" | "surface" | "alt" | "zone" | "boards" | "red" | "blue" | "dirt" | "foul" | "infield" | "crease" | "key" | "court" | "post" | "pylon" | "rgo" | "rgm" | "rgi" | "rgb" | "hog" | "hack" | "fgz" | "pebble" | "free" | "net" | "area" | "ropeg" | "ropeb" | "ropey" | "roper" | "ropew" | "pad" | "block" | "track" | "sand" | "mat" | "water" | "concrete" | "trackpad" | "markY" | "markB" | "markG" | "markR";
4
4
  /** Colours by part. */
5
5
  export type Palette = Partial<Record<PaletteKey, string>>;
6
6
  /** The surfaces that are painted alike: football's three fields are one. */
7
- export type Group = "football" | "nhl" | "nba" | "mlb" | "soccer" | "curling" | "net";
7
+ export type Group = "football" | "nhl" | "nba" | "mlb" | "soccer" | "curling" | "net" | "pool" | "athletics";
8
8
  /** One mode of a look: a palette for every sport, and what a group of sports changes in it. */
9
9
  export interface Mode {
10
10
  base: Palette;
@@ -26,7 +26,7 @@ export declare const groupOf: (sport: Sport | string) => Group | undefined;
26
26
  * import { LOOKS, drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
27
27
  * const svg = drawKyogijo({ sport: "nhl", look: "chalkboard" });
28
28
  * console.log(Object.keys(LOOKS).length, svg.includes('data-palette="chalkboard"'));
29
- * // 7 true
29
+ * // 8 true
30
30
  * ```
31
31
  */
32
32
  export declare const LOOKS: Readonly<Record<LookName, Look>>;