@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
@@ -298,6 +298,8 @@ export const GROUND_DATA = [
298
298
  {
299
299
  "id": "olympiastadion-munich",
300
300
  "wikidata": "Q131610",
301
+ "track": true,
302
+ "trackSource": "Wikidata, property P641 (sport) lists athletics",
301
303
  "name": "Munich Olympic Stadium",
302
304
  "nameJa": "ミュンヘン・オリンピアシュタディオン",
303
305
  "localName": "Olympiastadion München",
@@ -391,6 +393,8 @@ export const GROUND_DATA = [
391
393
  {
392
394
  "id": "stadio-olimpico-rome",
393
395
  "wikidata": "Q159884",
396
+ "track": true,
397
+ "trackSource": "Wikidata, property P641 (sport) lists athletics",
394
398
  "name": "Stadio Olimpico",
395
399
  "names": [
396
400
  { "name": "Stadio dei Cipressi", "from": 1928, "to": 1953 },
@@ -450,6 +454,8 @@ export const GROUND_DATA = [
450
454
  {
451
455
  "id": "stade-de-france",
452
456
  "wikidata": "Q13205",
457
+ "track": true,
458
+ "trackSource": "Wikidata, property P641 (sport) lists athletics",
453
459
  "name": "Stade de France",
454
460
  "nameJa": "スタッド・ド・フランス",
455
461
  "localName": "Stade de France",
@@ -476,6 +482,8 @@ export const GROUND_DATA = [
476
482
  {
477
483
  "id": "nissan-stadium-yokohama",
478
484
  "wikidata": "Q116601",
485
+ "track": true,
486
+ "trackSource": "Wikidata, property P641 (sport) lists athletics",
479
487
  "name": "Nissan Stadium",
480
488
  "names": [
481
489
  { "name": "International Stadium Yokohama", "from": 1998, "to": 2004 }
@@ -570,6 +578,8 @@ export const GROUND_DATA = [
570
578
  {
571
579
  "id": "luzhniki",
572
580
  "wikidata": "Q202163",
581
+ "track": true,
582
+ "trackSource": "Wikidata, property P641 (sport) lists athletics",
573
583
  "name": "Luzhniki Stadium",
574
584
  "names": [
575
585
  { "name": "Central Lenin Stadium", "from": 1956, "to": 1992 }
@@ -1092,6 +1102,8 @@ export const GROUND_DATA = [
1092
1102
  {
1093
1103
  "id": "dignity-health-sports-park",
1094
1104
  "wikidata": "Q200684",
1105
+ "track": true,
1106
+ "trackSource": "Wikidata, property P641 (sport) lists athletics",
1095
1107
  "name": "Dignity Health Sports Park",
1096
1108
  "names": [
1097
1109
  { "name": "Home Depot Center", "from": 2003, "to": 2013 },
@@ -0,0 +1,65 @@
1
+ import type { PlaceAlias } from "./names.ts";
2
+ import type { BudoSport, DojoSpec, BudoStyle } from "./types.ts";
3
+ /** What is known of a surface's layout. `documented`: the floor, its size and its contest areas are from a source (the dohyō of the Association's rules). `count`: a source gives the number of mats, and the shape is plausible. `generic`: no source gives the size or the layout, and a plausible one is drawn. */
4
+ export type HallBasis = "documented" | "count" | "generic";
5
+ /** One surface a hall offers: a floor of a sport, with the options that draw it. */
6
+ export interface HallSurface {
7
+ /** The key within the hall: `main-dojo`. */
8
+ id: string;
9
+ name: {
10
+ en: string;
11
+ ja: string;
12
+ };
13
+ sport: BudoSport;
14
+ /** The options (beyond `sport`) that draw it. */
15
+ options: {
16
+ league?: string;
17
+ budo?: BudoStyle;
18
+ dojo?: DojoSpec;
19
+ };
20
+ basis: HallBasis;
21
+ /** The number of mats (jō) a source gives for the floor, where it gives one. */
22
+ mats?: number;
23
+ /** What is known and what is drawn, in a sentence each. */
24
+ note: {
25
+ en: string;
26
+ ja: string;
27
+ };
28
+ }
29
+ /** A hall as the data gives it. */
30
+ export interface Hall {
31
+ id: string;
32
+ name: string;
33
+ nameJa: string;
34
+ readingJa?: string;
35
+ aliases: readonly PlaceAlias[];
36
+ city: string;
37
+ country: string;
38
+ lat: number;
39
+ lon: number;
40
+ wikidata: string;
41
+ /** The first year of the institution or the building (the Kodokan's is its founding, 1882). */
42
+ from: number;
43
+ /** What the first year is, in a phrase. */
44
+ fromWhat: {
45
+ en: string;
46
+ ja: string;
47
+ };
48
+ /** The most the hall seats or holds, where a source gives it, and which source. */
49
+ capacity?: {
50
+ value: number;
51
+ source: string;
52
+ };
53
+ /** The competitions and events it is known for. */
54
+ leagues: readonly string[];
55
+ surfaces: readonly HallSurface[];
56
+ /** Keys of `LEAGUE_SOURCES` that its facts were read from. */
57
+ sources: readonly string[];
58
+ /** What is known of the hall that no surface says, in a sentence. */
59
+ note: {
60
+ en: string;
61
+ ja: string;
62
+ };
63
+ }
64
+ /** The halls, in the order of their surfaces' fame: the Kodokan, the Budokan, the Kokugikan, the Butokuden and the Budokwai. */
65
+ export declare const HALLS: readonly Hall[];
package/dist/halls.js ADDED
@@ -0,0 +1,122 @@
1
+ /** The Kodokan's main dojo as drawn: a square floor of 420 jō's area, four contest areas, the seat of honour, the banner, the wood and the gallery, in the two looks the owner's photographs show. The years of both are unknown. */
2
+ const KODOKAN_MAIN = {
3
+ mats: { width: 26.4, length: 26.4 },
4
+ surround: 1,
5
+ areas: { across: 2, down: 2 },
6
+ dais: true,
7
+ banner: true,
8
+ balcony: true,
9
+ kamiza: "north",
10
+ eras: [
11
+ { name: "earlier", nameJa: "以前", from: null, to: null, look: "green-orange", outline: true },
12
+ { name: "current", nameJa: "現在", from: null, to: null, look: "yellow-green" },
13
+ ],
14
+ };
15
+ const wp = (name, lang, source) => ({ name, lang, kind: "wikipedia", source });
16
+ const official = (name, lang, source) => ({ name, lang, kind: "official", source });
17
+ /** The halls, in the order of their surfaces' fame: the Kodokan, the Budokan, the Kokugikan, the Butokuden and the Budokwai. */
18
+ export const HALLS = Object.freeze([
19
+ {
20
+ id: "kodokan",
21
+ name: "Kodokan",
22
+ nameJa: "講道館",
23
+ readingJa: "こうどうかん",
24
+ aliases: [official("Kodokan Judo Institute", "en", "kdkjudo.org"), wp("Kōdōkan", "en", "Wikidata Q1165384 label"), official("講道館国際柔道センター", "ja", "kdkjudo.org 施設のご案内")],
25
+ city: "Tokyo",
26
+ country: "JP",
27
+ lat: 35.708,
28
+ lon: 139.75344,
29
+ wikidata: "Q1165384",
30
+ from: 1882,
31
+ fromWhat: { en: "founded by Kanō Jigorō (the International Judo Center, the building the dojos are in, was completed in 1984)", ja: "嘉納治五郎が創設(道場のある講道館国際柔道センターは1984年に完成)" },
32
+ leagues: [],
33
+ surfaces: [
34
+ { id: "main-dojo", name: { en: "Main dojo, 7th floor", ja: "大道場(7階)" }, sport: "dojo", options: { dojo: KODOKAN_MAIN }, basis: "count", mats: 420, note: { en: "420 jō on the 7th floor, four contest areas at once, with a gallery on the 8th that seats about 900. Per the owner's photographs: four contest areas in two rows, pale yellow mats on green safety bands and a green border, on a wood surround, a raised seat of honour with a dark banner at the front wall, a gallery on all four sides. The shape of the floor is not documented: a square of 26.4 m, the area of 420 jō, is drawn so that four areas of 8 m fit.", ja: "7階に420畳、同時に4面の試合ができ、8階に約900人が座れる見学席があります。提供された写真では、試合場が2列に4面並び、淡い黄色の畳の外側を緑の安全地帯と緑の縁取りが囲んでいます。周囲は板張りで、正面の上座には一段高い台と濃い色の垂れ幕があり、四方に見学席があります。床の形は資料にないので、420畳の広さにあたる26.4m四方の床に、8m四方の試合場4面が収まるように描いています。" } },
35
+ { id: "main-dojo-earlier", name: { en: "Main dojo, 7th floor (earlier colours)", ja: "大道場(7階・以前の色)" }, sport: "dojo", options: { dojo: { ...KODOKAN_MAIN, era: "earlier" } }, basis: "count", mats: 420, note: { en: "The same room in the colours of the owner's older photograph: all green mats, the four contest areas outlined by red-orange border mats. No source gives the years of either look, so the eras carry none.", ja: "提供された古い写真の色で描いた同じ部屋です。畳はすべて緑で、4面の試合場それぞれを赤橙色の縁の畳が囲んでいます。どちらの色だった時期も資料にないので、年は記していません。" } },
36
+ { id: "school-dojo", name: { en: "Judo School dojo, 6th floor", ja: "学校道場(6階)" }, sport: "dojo", options: { dojo: { jo: 240, look: "green-beige" } }, basis: "count", mats: 240, note: { en: "240 jō on the 6th floor; the shape is plausible.", ja: "6階に240畳。形は推定です。" } },
37
+ { id: "international-dojo", name: { en: "International dojo, 6th floor", ja: "国際部道場(6階)" }, sport: "dojo", options: { dojo: { jo: 192, look: "green-beige" } }, basis: "count", mats: 192, note: { en: "192 jō on the 6th floor; the shape is plausible.", ja: "6階に192畳。形は推定です。" } },
38
+ { id: "womens-dojo", name: { en: "Women's dojo, 5th floor", ja: "女子部道場(5階)" }, sport: "dojo", options: { dojo: { jo: 240, look: "green-beige" } }, basis: "count", mats: 240, note: { en: "240 jō on the 5th floor; the shape is plausible.", ja: "5階に240畳。形は推定です。" } },
39
+ { id: "boys-dojo", name: { en: "Boys' dojo, 5th floor", ja: "少年部道場(5階)" }, sport: "dojo", options: { dojo: { jo: 114, look: "green-beige" } }, basis: "count", mats: 114, note: { en: "114 jō on the 5th floor; the shape is plausible.", ja: "5階に114畳。形は推定です。" } },
40
+ ],
41
+ sources: ["kodokan-facilities", "wikipedia-kodokan", "wikipedia-halls"],
42
+ note: { en: "The Kodokan moved to Kasuga, Bunkyō, in 1958. The Bunkyō ward's page counts the main dojo as 510 jō; the Kodokan's own page says 420, as English Wikipedia does (which also gives 1,206 mats in the five dojos, the sum of the five counts). The 5th floor also has a dojo for special techniques, with no count given, and it is not drawn.", ja: "講道館は1958年に文京区春日に移りました。文京区のページは大道場を510畳としていますが、講道館自身のページは420畳で、English Wikipediaも同じです(5つの道場の畳の合計は1,206畳としていて、これは5つの数の合計です)。5階には特殊技術のための道場もありますが、畳の数が示されていないので描いていません。" },
43
+ },
44
+ {
45
+ id: "nippon-budokan",
46
+ name: "Nippon Budokan",
47
+ nameJa: "日本武道館",
48
+ readingJa: "にっぽんぶどうかん",
49
+ aliases: [official("Budokan", "en", "Wikidata Q386246"), wp("Nippon Budōkan", "en", "Wikidata Q386246 label")],
50
+ city: "Tokyo",
51
+ country: "JP",
52
+ lat: 35.693333,
53
+ lon: 139.75,
54
+ wikidata: "Q386246",
55
+ from: 1964,
56
+ fromWhat: { en: "opened on 3 October 1964, the venue of the Olympic judo that month", ja: "1964年10月3日に開館、その月の東京オリンピックの柔道会場" },
57
+ capacity: { value: 14501, source: "budokan-overview" },
58
+ leagues: ["Olympic Games 1964", "Olympic Games 2020", "All Japan Judo Championships", "All Japan Karate Championships"],
59
+ surfaces: [
60
+ { id: "judo-games", name: { en: "Judo at the Olympic Games, two contest areas", ja: "オリンピックの柔道(試合場2面)" }, sport: "judo", options: { league: "ijf", budo: { hall: "budokan", areas: 2, platform: true, officials: true } }, basis: "generic", note: { en: "The arena is an octagon 55 m across the flats (2,513 m²). That the Games laid mats on a raised platform is reported; how many contest areas, and their colours, were not found: two areas of 10 m on a platform are drawn.", ja: "アリーナは対辺55mの正八角形(2,513㎡)です。大会で畳を台の上に敷いたことは報じられていますが、試合場の数と色は分かりませんでした。10mの試合場2面を台の上に描いています。" } },
61
+ { id: "judo-championships", name: { en: "All Japan Judo Championships, one contest area", ja: "全日本柔道選手権大会(試合場1面)" }, sport: "judo", options: { league: "ajjf", budo: { hall: "budokan" } }, basis: "generic", note: { en: "The Championships are held at the Budokan on 29 April. The layout of the mats is not documented: one contest area with the AJJF's red danger zone is drawn.", ja: "選手権は4月29日に日本武道館で開かれます。畳の配置は分からないので、全柔連の赤い危険地帯のある試合場1面を描いています。" } },
62
+ { id: "karate", name: { en: "Karate at the Olympic Games", ja: "オリンピックの空手道" }, sport: "karate", options: { league: "wkf-kumite", budo: { hall: "budokan", officials: true } }, basis: "generic", note: { en: "Karate was held at the Budokan at the 2020 Games. The number of competition areas was not found: one WKF kumite area is drawn in the middle of the arena.", ja: "2020年大会では空手道が日本武道館で行われました。試合場の数は分からないので、アリーナの中央に世界空手連盟の組手の試合場1面を描いています。" } },
63
+ { id: "kendo", name: { en: "Kendo, one shiai-jo", ja: "剣道(試合場1面)" }, sport: "kendo", options: { budo: { hall: "budokan", size: 11 } }, basis: "generic", note: { en: "Kendo's national championships are held at the Budokan. The size of the shiai-jo used was not found: one of 11 m, the greatest the regulations allow, is drawn in the middle of the arena.", ja: "剣道の全国大会は日本武道館で開かれます。使う試合場の大きさは分からないので、規則が認める最大の11m四方を中央に描いています。" } },
64
+ ],
65
+ sources: ["budokan-overview", "wikipedia-halls"],
66
+ note: { en: "The Budokan's own leaflet gives a maximum of 14,501 people; Wikidata and English Wikipedia give 14,471.", ja: "日本武道館のリーフレットは最大収容数を14,501人とし、WikidataとEnglish Wikipediaは14,471人としています。" },
67
+ },
68
+ {
69
+ id: "ryogoku-kokugikan",
70
+ name: "Ryōgoku Kokugikan",
71
+ nameJa: "両国国技館",
72
+ readingJa: "りょうごくこくぎかん",
73
+ aliases: [wp("Ryōgoku Kokugikan", "en", "Wikidata Q176821 label"), official("Kokugikan", "en", "Wikidata Q176821")],
74
+ city: "Tokyo",
75
+ country: "JP",
76
+ lat: 35.696944,
77
+ lon: 139.793333,
78
+ wikidata: "Q176821",
79
+ from: 1985,
80
+ fromWhat: { en: "opened on 9 January 1985", ja: "1985年1月9日に開館" },
81
+ capacity: { value: 11098, source: "wikipedia-halls" },
82
+ leagues: ["Grand Sumo Tournament"],
83
+ surfaces: [{ id: "dohyo", name: { en: "The dohyō", ja: "土俵" }, sport: "sumo", options: { budo: { tassels: true } }, basis: "documented", note: { en: "The clay square of 6.7 m and the ring of 4.55 m are the Association's own figures (Sumo Rules, Dohyō Regulations, Article 1); the Kokugikan holds the Tokyo tournaments in January, May and September, and its ring is movable.", ja: "一辺6.7mの土の正方形と直径4.55mの円は日本相撲協会の規則(相撲規則 土俵規定 第一条)の数値です。国技館では1月、5月、9月の東京場所が開かれ、土俵は移動式です。" } }],
84
+ sources: ["jsa-dohyo", "jsa-quiz", "wikipedia-halls"],
85
+ note: { en: "The Kokugikan seats 11,098 (Wikidata, English Wikipedia).", ja: "国技館の収容人数は11,098人です(Wikidata、English Wikipedia)。" },
86
+ },
87
+ {
88
+ id: "kyu-butokuden",
89
+ name: "Kyū Butokuden",
90
+ nameJa: "旧武徳殿",
91
+ readingJa: "きゅうぶとくでん",
92
+ aliases: [wp("Butokuden", "en", "Wikidata Q1017987 label"), official("Kyoto Butokuden", "en", "Wikidata Q1017987"), official("京都市武道センター旧武徳殿", "ja", "Wikidata Q1017987")],
93
+ city: "Kyoto",
94
+ country: "JP",
95
+ lat: 35.016389,
96
+ lon: 135.780833,
97
+ wikidata: "Q1017987",
98
+ from: 1899,
99
+ fromWhat: { en: "built as a hall for martial arts by the Dai Nippon Butokukai, designed by Matsumuro Shigemitsu; an Important Cultural Property since 1996", ja: "大日本武徳会が演武場として造営、設計は松室重光、1996年に国の重要文化財に指定" },
100
+ leagues: [],
101
+ surfaces: [{ id: "hall", name: { en: "The hall", ja: "旧武徳殿の床" }, sport: "dojo", options: { dojo: { jo: 100, look: "green-beige", kamiza: "north", shinzen: true, balcony: true } }, basis: "generic", note: { en: "The hall seats 1,200 and is part of the Kyoto Municipal Budo Center. The size of its floor and its mats were not found in a source: a floor of 100 jō is drawn as plausible.", ja: "旧武徳殿の座席は1,200席で、京都市武道センターの施設の一つです。床の大きさと畳の数は資料で確認できなかったので、100畳の床を推定して描いています。" } }],
102
+ sources: ["butokuden-ja"],
103
+ note: { en: "The hall was requisitioned after 1946 and used by the city's police school and art college, and is now a facility of the Kyoto Municipal Budo Center.", ja: "1946年以降は接収され、京都市警察学校や京都市立芸術大学が使い、今は京都市武道センターの施設です。" },
104
+ },
105
+ {
106
+ id: "budokwai",
107
+ name: "The Budokwai",
108
+ nameJa: "ブドクワイ",
109
+ aliases: [wp("Budokwai", "en", "Wikidata Q3646473 label")],
110
+ city: "London",
111
+ country: "GB",
112
+ lat: 51.4867,
113
+ lon: -0.180556,
114
+ wikidata: "Q3646473",
115
+ from: 1918,
116
+ fromWhat: { en: "opened on 26 January 1918 by Gunji Koizumi, at 15 Lower Grosvenor Place; at 4 Gilston Road since 1954", ja: "1918年1月26日に小泉軍治が開設(最初はロウアー・グロブナー・プレイス15番地)、1954年から現在のギルストン・ロード4番地" },
117
+ leagues: [],
118
+ surfaces: [{ id: "dojo", name: { en: "The dojo", ja: "道場" }, sport: "dojo", options: { dojo: { jo: 50, look: "green-beige" } }, basis: "generic", note: { en: "The size of the dojo and the number of its mats were not found in a source: a floor of 50 jō is drawn as plausible.", ja: "道場の大きさと畳の数は資料で確認できなかったので、50畳の床を推定して描いています。" } }],
119
+ sources: ["wikipedia-halls"],
120
+ note: { en: "A British martial arts club, read from English Wikipedia and Wikidata.", ja: "英国の武道クラブです。English WikipediaとWikidataによります。" },
121
+ },
122
+ ]);
@@ -0,0 +1,31 @@
1
+ import type { CourtStyle } from "./types.ts";
2
+ /** The options of a hardwood floor, read: every part has its value. */
3
+ export interface Hardwood {
4
+ seed: number;
5
+ /** True for the seams, ends, grain, soft shadows, table and benches; false for broad boards and one shadow. */
6
+ fine: boolean;
7
+ /** The width of a board, in feet. */
8
+ board: number;
9
+ stain: number;
10
+ sheen: number;
11
+ hoops: boolean;
12
+ bench: boolean;
13
+ }
14
+ /** The width of a drawing in pixels when the options say it (`480` or `"480px"`), else `undefined` (a percentage or an em says nothing of the screen). */
15
+ export declare function pixelWidth(width: unknown): number | undefined;
16
+ /** The width in pixels under which a drawing is a thumbnail, and its boards a blur: the `auto` detail is `plain` below it. */
17
+ export declare const HARDWOOD_SMALL = 480;
18
+ /** The hardwood the options ask for, or `undefined` for the usual clean floor. `simple` is the drawing's `detail: "simple"`; `width` its `width` option. */
19
+ export declare function resolveHardwood(court: CourtStyle | undefined, simple: boolean, width: unknown): Hardwood | undefined;
20
+ /** A small, fast generator (mulberry32): the same seed gives the same numbers on every machine. */
21
+ export declare function generator(seed: number): () => number;
22
+ /** The width of a tile, in feet: longer than any court of the package, so that the boards do not repeat along it. */
23
+ export declare const TILE = 96;
24
+ /** The two tiles of a floor and the size they are laid at: the tones and grain (under the paint) and the seams and ends (over it). */
25
+ export declare function floorTiles(h: Hardwood): {
26
+ height: number;
27
+ under: string;
28
+ over: string;
29
+ };
30
+ /** The rules of the hardwood floor's classes, written into a drawing that has one (and in `KYOGIJO_STYLE`, for a page that supplies the stylesheet). */
31
+ export declare const KYOGIJO_HARDWOOD_STYLE: string;
@@ -0,0 +1,157 @@
1
+ // The realistic basketball floor (`court.hardwood`): the options read once, and the boards. A maple strip floor is laid in boards of one width that run the length of the
2
+ // court, each row's boards ending at different places so that no two neighbours' ends line up; each board has a tone of its own and a little grain. All of it is made here
3
+ // from a seed with a small generator of our own (no `Math.random`), so the same options give the same floor, and it is written as two tiles of a pattern (the tones and
4
+ // grain under the paint, the seams and ends over it), so that the SVG holds a few shapes however large the court is. Written for this package from the way a strip floor
5
+ // is laid; no photograph or other drawing was copied.
6
+ import { el, num } from "./format.js";
7
+ const finite = (value) => typeof value === "number" && Number.isFinite(value);
8
+ const clamp = (value, low, high) => Math.min(high, Math.max(low, value));
9
+ /** The width of a drawing in pixels when the options say it (`480` or `"480px"`), else `undefined` (a percentage or an em says nothing of the screen). */
10
+ export function pixelWidth(width) {
11
+ if (finite(width))
12
+ return width > 0 ? width : undefined;
13
+ const match = typeof width === "string" ? /^\s*(\d+(?:\.\d+)?)(?:px)?\s*$/.exec(width) : null;
14
+ return match === null ? undefined : Number(match[1]);
15
+ }
16
+ /** The width in pixels under which a drawing is a thumbnail, and its boards a blur: the `auto` detail is `plain` below it. */
17
+ export const HARDWOOD_SMALL = 480;
18
+ /** The hardwood the options ask for, or `undefined` for the usual clean floor. `simple` is the drawing's `detail: "simple"`; `width` its `width` option. */
19
+ export function resolveHardwood(court, simple, width) {
20
+ const given = court?.hardwood;
21
+ if (given === undefined || given === false)
22
+ return undefined;
23
+ const o = given === true ? {} : given;
24
+ const px = pixelWidth(width);
25
+ const fine = o.detail === "fine" || (o.detail !== "plain" && !simple && (px === undefined || px >= HARDWOOD_SMALL));
26
+ return {
27
+ seed: finite(o.seed) ? Math.trunc(o.seed) : 1,
28
+ fine,
29
+ board: clamp(finite(o.board) ? o.board : 2.25, 1.5, 6) / 12,
30
+ stain: clamp(finite(o.stain) ? o.stain : 0.82, 0.3, 1),
31
+ sheen: clamp(finite(o.sheen) ? o.sheen : 1, 0, 1.5),
32
+ hoops: o.hoops !== false,
33
+ bench: o.bench !== false && fine,
34
+ };
35
+ }
36
+ /** A small, fast generator (mulberry32): the same seed gives the same numbers on every machine. */
37
+ export function generator(seed) {
38
+ let a = seed >>> 0;
39
+ return () => {
40
+ a = (a + 0x6d2b79f5) >>> 0;
41
+ let t = a;
42
+ t = Math.imul(t ^ (t >>> 15), t | 1);
43
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
44
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
45
+ };
46
+ }
47
+ /** The width of a tile, in feet: longer than any court of the package, so that the boards do not repeat along it. */
48
+ export const TILE = 96;
49
+ const WARM = "#fff0c4";
50
+ const DEEP = "#4a280b";
51
+ const TONES = [
52
+ { colour: WARM, opacity: 0.19, upTo: 90 },
53
+ { colour: WARM, opacity: 0.1, upTo: 310 },
54
+ { colour: DEEP, opacity: 0.1, upTo: 520 },
55
+ { colour: DEEP, opacity: 0.2, upTo: 640 },
56
+ ];
57
+ /** The least two ends of boards in neighbouring rows come to one another, in feet. */
58
+ const APART = 1.2;
59
+ /** True when an end at `x` is within `APART` of any end of the rows given, going round the tile. */
60
+ const near = (x, rows) => rows.some((row) => row?.some((end) => {
61
+ const d = Math.abs(x - end) % TILE;
62
+ return Math.min(d, TILE - d) < APART;
63
+ }) === true);
64
+ /** An end moved on, a little at a time, until it is clear of the ends of the rows next to it (and of its own row's, `own`). */
65
+ function clear(x, rows, own, least) {
66
+ let at = x;
67
+ for (let tries = 0; tries < 40 && (near(at, rows) || own.some((end) => Math.abs(at - end) < least)); tries += 1)
68
+ at += 0.6;
69
+ return at;
70
+ }
71
+ /**
72
+ * The rows of boards of a tile: for each row the places its boards end, going round the tile. A row's ends are at random distances apart, between `lengths`, and are
73
+ * moved on until none is within a foot of an end in the row above or the one above that, as boards are laid so that no joint lines up with a neighbour's.
74
+ */
75
+ function rows(count, lengths, next) {
76
+ const [low, high] = lengths;
77
+ const made = [];
78
+ for (let r = 0; r < count; r += 1) {
79
+ // The rows next to it: the two above, and for the last rows the first ones, which lie under them when the tile repeats.
80
+ const above = [made[r - 1], made[r - 2], ...(r >= count - 2 ? made.slice(0, r === count - 1 ? 2 : 1) : [])];
81
+ const start = next() * high;
82
+ const ends = [clear(start, above, [], low)];
83
+ for (let at = ends[0] + low + next() * (high - low); at < start + TILE - low * 0.6; at += low + next() * (high - low)) {
84
+ const placed = clear(at, above, ends, low * 0.6);
85
+ ends.push(placed);
86
+ at = placed;
87
+ }
88
+ made.push(ends.map((end) => end % TILE).sort((x, y) => x - y));
89
+ }
90
+ return made;
91
+ }
92
+ /** A number for a path: one decimal, no leading zero's loss (`.5`), never `-0`. */
93
+ const n1 = (value) => {
94
+ const text = (Math.round(value * 10) / 10).toString();
95
+ return text === "-0" ? "0" : text;
96
+ };
97
+ /** The pieces of one row's board between two ends, going round the tile: one piece, or two when the board crosses its edge. */
98
+ function spans(from, to) {
99
+ return to > from ? [[from, to]] : [[from, TILE], [0, to]];
100
+ }
101
+ /** The two tiles of a floor and the size they are laid at: the tones and grain (under the paint) and the seams and ends (over it). */
102
+ export function floorTiles(h) {
103
+ const next = generator(h.seed);
104
+ const pitch = h.fine ? h.board : h.board * 4;
105
+ const count = Math.max(4, Math.round(6 / pitch));
106
+ const height = count * pitch;
107
+ const ends = rows(count, h.fine ? [5, 12] : [10, 26], next);
108
+ // Each board's tone: a stroke across the whole width of its row, so that the rows meet with no gap.
109
+ const byTone = TONES.map(() => []);
110
+ ends.forEach((row, r) => {
111
+ const y = num((r + 0.5) * pitch);
112
+ for (let i = 0; i < row.length; i += 1) {
113
+ const pick = next() * 1000;
114
+ const tone = TONES.findIndex((t) => pick < t.upTo);
115
+ if (tone < 0)
116
+ continue;
117
+ for (const [a, b] of spans(row[i], row[(i + 1) % row.length]))
118
+ byTone[tone].push(`M${n1(a)} ${y}h${n1(b - a)}`);
119
+ }
120
+ });
121
+ let under = "";
122
+ TONES.forEach((tone, i) => {
123
+ if (byTone[i].length > 0)
124
+ under += el("path", { d: byTone[i].join(""), stroke: tone.colour, "stroke-opacity": tone.opacity, "stroke-width": num(pitch + 0.004), fill: "none" });
125
+ });
126
+ if (!h.fine)
127
+ return { height, under, over: "" };
128
+ // The grain: fine streaks along the boards, short and faint, a few of them bowed.
129
+ const grain = [];
130
+ for (let i = 0; i < 70; i += 1) {
131
+ const x = next() * TILE;
132
+ const y = (Math.floor(next() * count) + 0.15 + next() * 0.7) * pitch;
133
+ const length = 1.2 + next() * 5.5;
134
+ const bow = (next() - 0.5) * pitch * 0.5;
135
+ grain.push(i % 4 === 0 ? `M${n1(x)} ${num(y)}q${n1(length / 2)} ${num(bow)} ${n1(length)} 0` : `M${n1(x)} ${num(y)}h${n1(length)}`);
136
+ }
137
+ under += el("path", { d: grain.join(""), stroke: DEEP, "stroke-opacity": 0.2, "stroke-width": num(pitch * 0.09), fill: "none", "stroke-linecap": "round" });
138
+ // The seams between the boards and the butt joints where they end.
139
+ const seam = [];
140
+ for (let r = 0; r < count; r += 1)
141
+ seam.push(`M0 ${num(r * pitch)}H${TILE}`);
142
+ ends.forEach((row, r) => {
143
+ for (const x of row)
144
+ seam.push(`M${n1(x)} ${num(r * pitch)}v${num(pitch)}`);
145
+ });
146
+ const over = el("path", { d: seam.join(""), stroke: "#2a1506", "stroke-opacity": 0.3, "stroke-width": num(pitch * 0.17), fill: "none" });
147
+ return { height, under, over };
148
+ }
149
+ /** The rules of the hardwood floor's classes, written into a drawing that has one (and in `KYOGIJO_STYLE`, for a page that supplies the stylesheet). */
150
+ export const KYOGIJO_HARDWOOD_STYLE = `
151
+ .kyogijo .ky-hw-end-l{fill:var(--ky-hw-end-left,var(--ky-boards))}
152
+ .kyogijo .ky-hw-end-r{fill:var(--ky-hw-end-right,var(--ky-boards))}
153
+ .kyogijo .ky-hw-pad{fill:var(--ky-hw-pad,#2c333c);stroke:#fff;stroke-opacity:.2;stroke-width:.1}
154
+ .kyogijo .ky-hw-arm{fill:var(--ky-hw-arm,#454d58);stroke:#fff;stroke-opacity:.15;stroke-width:.06}
155
+ .kyogijo .ky-hw-glass{fill:#eef4f8;stroke:#7d8791;stroke-width:.06}
156
+ .kyogijo .ky-hw-net{fill:none;stroke:#fff;stroke-opacity:.7}
157
+ .kyogijo .ky-hw-furniture{fill:#7b838c;fill-opacity:.35;stroke:#7b838c;stroke-opacity:.35;stroke-width:.18;stroke-linejoin:round}`.trim();
package/dist/heat.js CHANGED
@@ -7,7 +7,7 @@ import { FRAMES } from "./frames.js";
7
7
  import { resolveRamp, stepOf } from "./heat.colour.js";
8
8
  import { binGrid, contourRings, densityAt, densityGrid, gridValues, hexBins, hexCorners, massThresholds, needsValues, newBin, niceTicks, reduceBin, scottBandwidth, uniformEdges, } from "./heat.stats.js";
9
9
  import { buildZoneSet } from "./heat.zones.js";
10
- import { clamp01, isNum, newMade, opacityOf, place, placeBack, toArray, unitOfLayer } from "./layers.env.js";
10
+ import { clamp01, isNum, markAttrs, newMade, opacityOf, place, placeBack, toArray, unitOfLayer } from "./layers.env.js";
11
11
  import { rampColour } from "./layers.marks.js";
12
12
  import { fill } from "./strings.js";
13
13
  import { textWidth } from "./text.js";
@@ -330,8 +330,8 @@ function formatter(percent, decimals) {
330
330
  }
331
331
  /** The legend's marks: a plate, the heading, the steps as a bar and the ticks. Laid out as the eye sees it, then placed on the surface and turned back when the surface is turned. */
332
332
  function legendMarks(env, spec) {
333
- const box = env.shown;
334
- const b = env.base;
333
+ const box = spec.region ?? env.shown;
334
+ const b = spec.region === undefined ? env.base : Math.max(box.w, box.h) * 0.013;
335
335
  const fs = b * 1.1;
336
336
  const barH = b * 1.3;
337
337
  const pad = b * 1;
@@ -483,7 +483,8 @@ export function drawHeat(layer, env, gid, known) {
483
483
  spec.levels.forEach((level, i) => {
484
484
  if (level.d === "")
485
485
  return;
486
- marks.push(spec.filled ? `<path class="ky-cf" style="fill:${fillOf(colours, i)}" fill-rule="evenodd" d="${level.d}"/>` : `<path class="ky-cl" style="stroke:${fillOf(colours, i)}" d="${level.d}"/>`);
486
+ const mark = env.marks ? ` data-mark-id="${i}" data-index="${i}"` : "";
487
+ marks.push(spec.filled ? `<path class="ky-cf" style="fill:${fillOf(colours, i)}" fill-rule="evenodd" d="${level.d}"${mark}/>` : `<path class="ky-cl" style="stroke:${fillOf(colours, i)}" d="${level.d}"${mark}/>`);
487
488
  });
488
489
  made.style = `--w:${num(env.base * (spec.filled ? 0.1 : 0.32))}`;
489
490
  }
@@ -491,20 +492,26 @@ export function drawHeat(layer, env, gid, known) {
491
492
  colours = coloursFor(layer, present);
492
493
  const step = (v) => stepOf(v, colours.domain, colours.steps);
493
494
  if (c.noun === "zones") {
494
- for (const it of c.items) {
495
+ c.items.forEach((it, i) => {
495
496
  const title = `<title>${esc(`${it.name ?? ""}${it.value === null ? "" : `: ${fmt(it.value)}`} (${it.n})`)}</title>`;
496
- marks.push(`<path class="ky-zn" d="${it.d}" fill-rule="evenodd" style="fill:${it.value === null ? "none" : fillOf(colours, step(it.value))}">${title}</path>`);
497
- }
497
+ const zone = it.id === undefined || !env.marks ? "" : ` data-mark-id="${esc(it.id)}" data-index="${i}" data-zone="${esc(it.id)}"`;
498
+ marks.push(`<path class="ky-zn" d="${it.d}" fill-rule="evenodd" style="fill:${it.value === null ? "none" : fillOf(colours, step(it.value))}"${zone}>${title}</path>`);
499
+ });
498
500
  made.style = `--w:${num(env.base * 0.12)}`;
499
501
  }
500
502
  else {
503
+ // Each cell is a path of its own, so that a listener can tell which one it was on; the cells of a colour share a group that holds the fill.
501
504
  const byStep = Array.from({ length: colours.steps }, () => []);
502
- for (const it of c.items)
503
- if (it.value !== null)
504
- byStep[step(it.value)].push(it.d);
505
+ const pointable = env.marks;
506
+ c.items.forEach((it, i) => {
507
+ if (it.value === null)
508
+ return;
509
+ byStep[step(it.value)].push(pointable ? `<path d="${it.d}"${markAttrs(env, undefined, i, [it.cx, it.cy])}/>` : it.d);
510
+ });
505
511
  byStep.forEach((list, k) => {
506
- if (list.length > 0)
507
- marks.push(`<path style="fill:${fillOf(colours, k)}" d="${list.join("")}"/>`);
512
+ if (list.length === 0)
513
+ return;
514
+ marks.push(pointable ? `<g style="fill:${fillOf(colours, k)}">${list.join("")}</g>` : `<path style="fill:${fillOf(colours, k)}" d="${list.join("")}"/>`);
508
515
  });
509
516
  }
510
517
  }
@@ -518,6 +525,7 @@ export function drawHeat(layer, env, gid, known) {
518
525
  title: legend.title ?? c.stat,
519
526
  ticks: legend.ticks ?? 5,
520
527
  position: legend.position ?? (env.o.sport === "mlb" ? "bottom-right" : "bottom"),
528
+ region: legend.region,
521
529
  format: formatter(c.percent, undefined),
522
530
  at: contour === undefined || contour.levels.length > 6 ? undefined : contour.levels.map((l) => 100 * l.label),
523
531
  }));
@@ -566,7 +574,7 @@ export function drawLegend(layer, env, gid, known) {
566
574
  const title = typeof layer.name === "string" && layer.name.trim() !== "" ? layer.name.trim() : target?.stat ?? words.stat.custom;
567
575
  made.cls = "ky-hm";
568
576
  made.opacity = opacityOf(layer.opacity);
569
- made.marks = legendMarks(env, { colours, title, ticks: layer.ticks ?? 5, position: layer.position ?? (env.o.sport === "mlb" ? "bottom-right" : "bottom"), format: formatter(percent, undefined) });
577
+ made.marks = legendMarks(env, { colours, title, ticks: layer.ticks ?? 5, position: layer.position ?? (env.o.sport === "mlb" ? "bottom-right" : "bottom"), region: layer.region, format: formatter(percent, undefined) });
570
578
  made.css = darkRules(colours, [gid]);
571
579
  made.title = fill(words.legendTitle, { name: title });
572
580
  made.text = fill(words.range, { min: formatter(percent, undefined)(colours.domain[0]), max: formatter(percent, undefined)(colours.domain[1]) });
@@ -2,6 +2,7 @@ import type { HeatRamp } from "./heat.colour.ts";
2
2
  import type { HexOrientation, Reducer, StatisticName } from "./heat.stats.ts";
3
3
  import type { ZoneSetId } from "./heat.zones.ts";
4
4
  import type { LayerBase, MarkDatum } from "./layers.types.ts";
5
+ import type { Box } from "./types.ts";
5
6
  export type { HeatRamp, HeatRampName } from "./heat.colour.ts";
6
7
  export type { HexOrientation, Reducer, StatisticName } from "./heat.stats.ts";
7
8
  export type { ZoneSetId } from "./heat.zones.ts";
@@ -33,6 +34,8 @@ export interface HeatLegend {
33
34
  ticks?: number;
34
35
  /** The opacity of the legend, 0 to 1. */
35
36
  opacity?: number;
37
+ /** Size and place the legend against this part of the surface, in feet in the drawing's frame (x along the surface, y across it), instead of the whole of what is shown: the half of a curling sheet that is drawn, say. */
38
+ region?: Box;
36
39
  }
37
40
  /** What the heat layers take beyond a layer's places. */
38
41
  export interface HeatBase extends LayerBase {
@@ -142,4 +145,6 @@ export interface LegendLayer extends Omit<LayerBase, "from" | "attacking" | "sur
142
145
  ticks?: number;
143
146
  /** The opacity of the legend, 0 to 1. */
144
147
  opacity?: number;
148
+ /** Size and place the legend against this part of the surface, as `HeatLegend.region` does. */
149
+ region?: Box;
145
150
  }
@@ -2,7 +2,7 @@ import type { Outline } from "./outline.ts";
2
2
  import type { KyogijoWords } from "./strings.ts";
3
3
  import type { Sport, SurfaceOptions } from "./types.ts";
4
4
  /** The zone sets. */
5
- export type ZoneSetId = "field-thirds" | "cricket-ground" | "soccer-positional" | "soccer-thirds" | "soccer-channels" | "soccer-18" | "nba-shot" | "nhl-slot" | "nhl-home-plate" | "baseball-spray" | "baseball-retrosheet" | "football-pass" | "curling-house" | "net-court";
5
+ export type ZoneSetId = "field-thirds" | "cricket-ground" | "soccer-positional" | "soccer-thirds" | "soccer-channels" | "soccer-18" | "nba-shot" | "nhl-slot" | "nhl-home-plate" | "baseball-spray" | "baseball-retrosheet" | "football-pass" | "athletics-track" | "skating-track" | "budo-areas" | "curling-house" | "net-court" | "wall-court" | "roundnet-rings" | "pool-lanes" | "water-polo-areas" | "pool-thirds";
6
6
  type Pt = readonly [number, number];
7
7
  /** One zone: its shape on the surface and whether a point lies in it. */
8
8
  export interface ZoneShape {
@@ -30,7 +30,7 @@ export interface ZoneSet {
30
30
  }
31
31
  /** What a zone set needs to know about the drawing and the layer. */
32
32
  export interface ZoneContext {
33
- o: Pick<SurfaceOptions, "sport" | "pitch" | "units"> & Partial<Pick<SurfaceOptions, "league" | "net" | "field">>;
33
+ o: Pick<SurfaceOptions, "sport" | "pitch" | "units"> & Partial<Pick<SurfaceOptions, "league" | "net" | "field" | "pool" | "athletics" | "skating" | "budo" | "dojo">>;
34
34
  outline: Outline;
35
35
  /** The way the team attacks as the surface is drawn wide: names the sides and counts the bands from the team's own end. `right` by default. */
36
36
  direction: "left" | "right";
@@ -49,6 +49,8 @@ export declare const ZONE_SETS: Readonly<Record<ZoneSetId, {
49
49
  source: string;
50
50
  }>>;
51
51
  export declare const ZONE_SET_IDS: readonly ZoneSetId[];
52
+ /** 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. */
53
+ export declare function infieldReach(angle: number): number;
52
54
  /** The zones of a set on the surface the context describes. Throws for a set that is not for the surface's sport. */
53
55
  export declare function buildZoneSet(id: ZoneSetId, ctx: ZoneContext): ZoneSet;
54
56
  export {};