@sportsdataverse/sdvplot 0.0.0-stage → 0.2.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 (245) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +109 -0
  3. package/README.md +984 -2
  4. package/dist/_web-D7Aa5Rd8.d.ts +69 -0
  5. package/dist/aaf-GJ3SH34T.js +13 -0
  6. package/dist/aaf-HCYN5T6Y.js +37 -0
  7. package/dist/aaf-ZAE5KS2Y.js +13 -0
  8. package/dist/ahl-E66MDVCU.js +66 -0
  9. package/dist/ahl-NPQQWZEV.js +249 -0
  10. package/dist/ahl-QRDU73XX.js +309 -0
  11. package/dist/axis-CraWQRUJ.d.ts +49 -0
  12. package/dist/bins.d.ts +174 -0
  13. package/dist/bins.js +4 -0
  14. package/dist/bins.js.map +1 -0
  15. package/dist/cfb-F42SVS4X.js +5000 -0
  16. package/dist/cfb-P3SHEYRZ.js +692 -0
  17. package/dist/cfb-WXRZANLP.js +10226 -0
  18. package/dist/chartjs-surface.d.ts +42 -0
  19. package/dist/chartjs-surface.js +65 -0
  20. package/dist/chartjs-surface.js.map +1 -0
  21. package/dist/chartjs.d.ts +162 -0
  22. package/dist/chartjs.js +342 -0
  23. package/dist/chartjs.js.map +1 -0
  24. package/dist/chunk-4C3GX6QO.js +92 -0
  25. package/dist/chunk-4C3GX6QO.js.map +1 -0
  26. package/dist/chunk-57WFSI4Q.js +128 -0
  27. package/dist/chunk-57WFSI4Q.js.map +1 -0
  28. package/dist/chunk-7ULOCCFL.js +313 -0
  29. package/dist/chunk-7ULOCCFL.js.map +1 -0
  30. package/dist/chunk-AMXASQHT.js +120 -0
  31. package/dist/chunk-AMXASQHT.js.map +1 -0
  32. package/dist/chunk-B2MP37SR.js +175 -0
  33. package/dist/chunk-B2MP37SR.js.map +1 -0
  34. package/dist/chunk-C2CDY5OG.js +137 -0
  35. package/dist/chunk-C2CDY5OG.js.map +1 -0
  36. package/dist/chunk-DYMUVE6K.js +127 -0
  37. package/dist/chunk-DYMUVE6K.js.map +1 -0
  38. package/dist/chunk-E7G7VSLV.js +43 -0
  39. package/dist/chunk-E7G7VSLV.js.map +1 -0
  40. package/dist/chunk-H2C3FMMA.js +300 -0
  41. package/dist/chunk-H2C3FMMA.js.map +1 -0
  42. package/dist/chunk-J4P4HDBF.js +175 -0
  43. package/dist/chunk-J4P4HDBF.js.map +1 -0
  44. package/dist/chunk-J6R2LEJ7.js +58 -0
  45. package/dist/chunk-J6R2LEJ7.js.map +1 -0
  46. package/dist/chunk-M3XD2OSN.js +132 -0
  47. package/dist/chunk-M3XD2OSN.js.map +1 -0
  48. package/dist/chunk-OIILARXI.js +30 -0
  49. package/dist/chunk-OIILARXI.js.map +1 -0
  50. package/dist/chunk-RPVVJY74.js +170 -0
  51. package/dist/chunk-RPVVJY74.js.map +1 -0
  52. package/dist/chunk-UL5M6KDE.js +205 -0
  53. package/dist/chunk-UL5M6KDE.js.map +1 -0
  54. package/dist/chunk-WQT4IVLX.js +10 -0
  55. package/dist/chunk-WQT4IVLX.js.map +1 -0
  56. package/dist/chunk-ZAEQXFJM.js +556 -0
  57. package/dist/chunk-ZAEQXFJM.js.map +1 -0
  58. package/dist/cricket-KPCYG2HL.js +493 -0
  59. package/dist/cricket-NDXLE25B.js +116 -0
  60. package/dist/cricket-YUUF7P6M.js +160 -0
  61. package/dist/cytoscape.d.ts +188 -0
  62. package/dist/cytoscape.js +219 -0
  63. package/dist/cytoscape.js.map +1 -0
  64. package/dist/d3.d.ts +234 -0
  65. package/dist/d3.js +198 -0
  66. package/dist/d3.js.map +1 -0
  67. package/dist/deckgl.d.ts +232 -0
  68. package/dist/deckgl.js +197 -0
  69. package/dist/deckgl.js.map +1 -0
  70. package/dist/echarts.d.ts +121 -0
  71. package/dist/echarts.js +228 -0
  72. package/dist/echarts.js.map +1 -0
  73. package/dist/echl-3CR4RGFC.js +241 -0
  74. package/dist/echl-NPC32C23.js +107 -0
  75. package/dist/echl-PI33DGJC.js +64 -0
  76. package/dist/export.d.ts +130 -0
  77. package/dist/export.js +258 -0
  78. package/dist/export.js.map +1 -0
  79. package/dist/g2.d.ts +251 -0
  80. package/dist/g2.js +102 -0
  81. package/dist/g2.js.map +1 -0
  82. package/dist/headshots-B2J_LOO8.d.ts +40 -0
  83. package/dist/index.d.ts +183 -0
  84. package/dist/index.js +9 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/interact.d.ts +567 -0
  87. package/dist/interact.js +809 -0
  88. package/dist/interact.js.map +1 -0
  89. package/dist/lightweight-charts.d.ts +217 -0
  90. package/dist/lightweight-charts.js +155 -0
  91. package/dist/lightweight-charts.js.map +1 -0
  92. package/dist/maplibre.d.ts +271 -0
  93. package/dist/maplibre.js +175 -0
  94. package/dist/maplibre.js.map +1 -0
  95. package/dist/marks-DH-tQIP-.d.ts +75 -0
  96. package/dist/mbb-3TRLVW3H.js +3619 -0
  97. package/dist/mbb-DQUHCHZP.js +5111 -0
  98. package/dist/mbb-PRAIO2P5.js +371 -0
  99. package/dist/milb-6IQ6NCEW.js +291 -0
  100. package/dist/milb-EYY5MD4T.js +1752 -0
  101. package/dist/milb-EYZ4SZLI.js +797 -0
  102. package/dist/mlb-4PBUJSVQ.js +35 -0
  103. package/dist/mlb-FHPY3GQJ.js +701 -0
  104. package/dist/mlb-REVGL3N2.js +665 -0
  105. package/dist/mui.d.ts +338 -0
  106. package/dist/mui.js +184 -0
  107. package/dist/mui.js.map +1 -0
  108. package/dist/nba-ATT775GS.js +485 -0
  109. package/dist/nba-LKM4UHVU.js +482 -0
  110. package/dist/nba-YX7PXM3R.js +35 -0
  111. package/dist/nbagl-3WGZCZ4S.js +37 -0
  112. package/dist/nbagl-LP4XJRAL.js +229 -0
  113. package/dist/nbagl-VTTOU7LN.js +499 -0
  114. package/dist/ncaa_baseball-UV75LNVR.js +2670 -0
  115. package/dist/ncaa_baseball-VD5J5C72.js +419 -0
  116. package/dist/ncaa_baseball-YRBS32D6.js +4592 -0
  117. package/dist/ncaa_mhockey-IMYHS7QS.js +1033 -0
  118. package/dist/ncaa_mhockey-TXTKWHE3.js +115 -0
  119. package/dist/ncaa_mhockey-U3MFW5VT.js +663 -0
  120. package/dist/ncaa_softball-6WR6KS64.js +420 -0
  121. package/dist/ncaa_softball-RZCTIE56.js +2654 -0
  122. package/dist/ncaa_softball-VOD4PVGY.js +4599 -0
  123. package/dist/ncaa_whockey-6XXGUTBK.js +607 -0
  124. package/dist/ncaa_whockey-AKKYKY67.js +53 -0
  125. package/dist/ncaa_whockey-KBEKXFBB.js +293 -0
  126. package/dist/nfl-BDB2HYAR.js +625 -0
  127. package/dist/nfl-EHYHDLJD.js +37 -0
  128. package/dist/nfl-VF4NJCHY.js +514 -0
  129. package/dist/nfl_gsis-UY64JO37.js +4 -0
  130. package/dist/nhl-6WPHME7H.js +511 -0
  131. package/dist/nhl-EMIJFZHY.js +884 -0
  132. package/dist/nhl-ISFUKRFU.js +37 -0
  133. package/dist/nivo.d.ts +193 -0
  134. package/dist/nivo.js +8 -0
  135. package/dist/nivo.js.map +1 -0
  136. package/dist/ohl-2FEM554G.js +113 -0
  137. package/dist/ohl-C5Q4W6JB.js +32 -0
  138. package/dist/ohl-TQ4J46VC.js +66 -0
  139. package/dist/perspective.d.ts +198 -0
  140. package/dist/perspective.js +171 -0
  141. package/dist/perspective.js.map +1 -0
  142. package/dist/phf-H7POU2KW.js +32 -0
  143. package/dist/phf-K5IFMZUM.js +13 -0
  144. package/dist/phf-TWJI3BOW.js +20 -0
  145. package/dist/placement-UWkqUzpa.d.ts +32 -0
  146. package/dist/plot.d.ts +451 -0
  147. package/dist/plot.js +712 -0
  148. package/dist/plot.js.map +1 -0
  149. package/dist/plotly.d.ts +129 -0
  150. package/dist/plotly.js +360 -0
  151. package/dist/plotly.js.map +1 -0
  152. package/dist/pwhl-OX3BO4JI.js +53 -0
  153. package/dist/pwhl-W44OC3C6.js +17 -0
  154. package/dist/pwhl-ZJGG3H7W.js +23 -0
  155. package/dist/qmjhl-5HISEHLL.js +35 -0
  156. package/dist/qmjhl-DA3UHKE5.js +125 -0
  157. package/dist/qmjhl-YG4BOQPF.js +614 -0
  158. package/dist/react.d.ts +377 -0
  159. package/dist/react.js +522 -0
  160. package/dist/react.js.map +1 -0
  161. package/dist/recharts.d.ts +162 -0
  162. package/dist/recharts.js +8 -0
  163. package/dist/recharts.js.map +1 -0
  164. package/dist/resolve-CQW-jzvr.d.ts +28 -0
  165. package/dist/selection-D4T3PkRt.d.ts +140 -0
  166. package/dist/shadcn.d.ts +83 -0
  167. package/dist/shadcn.js +88 -0
  168. package/dist/shadcn.js.map +1 -0
  169. package/dist/shots.d.ts +364 -0
  170. package/dist/shots.js +86 -0
  171. package/dist/shots.js.map +1 -0
  172. package/dist/soccer-7BH3ZLVL.js +7898 -0
  173. package/dist/soccer-MRU25OGE.js +2636 -0
  174. package/dist/soccer-PF4IPPVA.js +12342 -0
  175. package/dist/surface-TR7YFJW3.js +4 -0
  176. package/dist/surface-TR7YFJW3.js.map +1 -0
  177. package/dist/surfaces-MIG7HOFU.js +6 -0
  178. package/dist/surfaces-MIG7HOFU.js.map +1 -0
  179. package/dist/surfaces-W-odWLpT.d.ts +47 -0
  180. package/dist/svelte/HeadshotMark.svelte +25 -0
  181. package/dist/svelte/HeadshotMark.svelte.d.ts +10 -0
  182. package/dist/svelte/HeadshotMark.svelte.d.ts.map +1 -0
  183. package/dist/svelte/LogoMark.svelte +25 -0
  184. package/dist/svelte/LogoMark.svelte.d.ts +10 -0
  185. package/dist/svelte/LogoMark.svelte.d.ts.map +1 -0
  186. package/dist/svelte/Marks.svelte +25 -0
  187. package/dist/svelte/Marks.svelte.d.ts +10 -0
  188. package/dist/svelte/Marks.svelte.d.ts.map +1 -0
  189. package/dist/svelte/Surface.svelte +29 -0
  190. package/dist/svelte/Surface.svelte.d.ts +9 -0
  191. package/dist/svelte/Surface.svelte.d.ts.map +1 -0
  192. package/dist/svelte/SurfaceBackdrop.svelte +26 -0
  193. package/dist/svelte/SurfaceBackdrop.svelte.d.ts +11 -0
  194. package/dist/svelte/SurfaceBackdrop.svelte.d.ts.map +1 -0
  195. package/dist/svelte/index.d.ts +13 -0
  196. package/dist/svelte/index.d.ts.map +1 -0
  197. package/dist/svelte/index.js +11 -0
  198. package/dist/svelte-core.d.ts +139 -0
  199. package/dist/svelte-core.js +123 -0
  200. package/dist/svelte-core.js.map +1 -0
  201. package/dist/tanstack.d.ts +240 -0
  202. package/dist/tanstack.js +110 -0
  203. package/dist/tanstack.js.map +1 -0
  204. package/dist/testing.d.ts +75 -0
  205. package/dist/testing.js +239 -0
  206. package/dist/testing.js.map +1 -0
  207. package/dist/three.d.ts +223 -0
  208. package/dist/three.js +50 -0
  209. package/dist/three.js.map +1 -0
  210. package/dist/tiers-BN4md-GB.d.ts +65 -0
  211. package/dist/types-C7n6gJF3.d.ts +62 -0
  212. package/dist/ufl-7VLZTLTT.js +143 -0
  213. package/dist/ufl-CCMBLPSW.js +100 -0
  214. package/dist/ufl-F2BJRXME.js +16 -0
  215. package/dist/unovis.d.ts +127 -0
  216. package/dist/unovis.js +108 -0
  217. package/dist/unovis.js.map +1 -0
  218. package/dist/uplot.d.ts +120 -0
  219. package/dist/uplot.js +110 -0
  220. package/dist/uplot.js.map +1 -0
  221. package/dist/usfl-4CR5RMZJ.js +32 -0
  222. package/dist/usfl-LD7HP2YK.js +14 -0
  223. package/dist/usfl-VU4YSJQD.js +19 -0
  224. package/dist/ushl-CPG2LB4L.js +73 -0
  225. package/dist/ushl-PQL6HJAD.js +88 -0
  226. package/dist/ushl-ZT2ATPHK.js +22 -0
  227. package/dist/vega.d.ts +85 -0
  228. package/dist/vega.js +362 -0
  229. package/dist/vega.js.map +1 -0
  230. package/dist/victory.d.ts +107 -0
  231. package/dist/victory.js +38 -0
  232. package/dist/victory.js.map +1 -0
  233. package/dist/wbb-3KHCDYTK.js +5087 -0
  234. package/dist/wbb-BMX53Q3Q.js +369 -0
  235. package/dist/wbb-QNRN2CJJ.js +3620 -0
  236. package/dist/whl-4ATYZWUB.js +97 -0
  237. package/dist/whl-RVFPL6MH.js +79 -0
  238. package/dist/whl-Y7ASKYMM.js +28 -0
  239. package/dist/wnba-FWX5SFVI.js +232 -0
  240. package/dist/wnba-GX6HZR4B.js +220 -0
  241. package/dist/wnba-NTMWIPP6.js +20 -0
  242. package/dist/xfl-43R2JMJK.js +30 -0
  243. package/dist/xfl-H3BXQPZZ.js +16 -0
  244. package/dist/xfl-XON7A7FI.js +69 -0
  245. package/package.json +366 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chartjs.ts"],"names":["redraws","paint"],"mappings":"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","file":"chartjs.js","sourcesContent":["/**\n * Chart.js 4 helpers: team logo / wordmark / headshot point styles, axis-tick logos, faint logo watermarks, team\n * colours and a sporty surface background. `chart.js` is a type-only import (optional peer, 4.4 or later): everything\n * here is a dataset option or a plugin object, so Svelte, Astro, React or plain scripts pass it to `new Chart(...)`\n * unchanged.\n * The sporty court background lives in `sdvplot/chartjs/surface`, so this entry never needs `@sportsdataverse/sporty`.\n * Call after `loadLeague(league)` / `preloadAll()`; point styles and plugins need a DOM (build them client-side) unless\n * given `loadImage`, which in Node is `@napi-rs/canvas`'s.\n */\nimport type { Chart, Plugin, PointStyle, Scale, Tick } from \"chart.js\";\nimport { colorPalette } from \"./_web.js\";\nimport { teamColorsSync } from \"./colors.js\";\nimport { contrast, hex6, onColor } from \"./contrast.js\";\nimport { InputError, UnsupportedTargetError, warn } from \"./errors.js\";\nimport type { EspnHeadshotLeague } from \"./headshots.js\";\nimport { type Kind, type PlaceOptions, checkAlpha, placeSync } from \"./placement.js\";\nimport type { Value } from \"./resolve.js\";\nimport type { HeadshotIdSystem, IdSystem, League, SeasonInput, Variant, Which } from \"./types.js\";\n\nexport interface PointOptions {\n league: League;\n /** Half the image height in px; also the dataset's `pointRadius` (hit area). Default 12. */\n radius?: number;\n season?: SeasonInput | readonly SeasonInput[];\n variant?: Variant;\n idSystem?: IdSystem;\n /** What an unresolved value draws: `\"text\"` (its own label, the default) or any Chart.js point style. */\n fallback?: PointStyle | \"text\";\n /** The chart's background colour, so the text fallback reads on it (default white, or black with `variant: \"dark\"`). */\n background?: string;\n /**\n * Loads each image instead of a DOM image element, so this also runs in Node: pass `@napi-rs/canvas`'s `loadImage`.\n * See {@link ImageLike}.\n */\n loadImage?: (url: string) => Promise<ImageLike>;\n}\nexport interface HeadshotPointOptions {\n league: EspnHeadshotLeague;\n radius?: number;\n idSystem?: HeadshotIdSystem;\n fallback?: PointStyle | \"text\";\n /** The chart's background colour, so the text fallback reads on it (default white). */\n background?: string;\n /**\n * Loads each image instead of a DOM image element, so this also runs in Node: pass `@napi-rs/canvas`'s `loadImage`.\n * See {@link ImageLike}.\n */\n loadImage?: (url: string) => Promise<ImageLike>;\n}\n/** Spread into a scatter / bubble / line dataset: one style per data point, in data order. */\nexport interface PointStyles {\n pointStyle: PointStyle[];\n pointRadius: number;\n}\n\n/**\n * An image a `loadImage` option resolves: anything the chart's 2D context can `drawImage`, such as `@napi-rs/canvas`'s\n * `Image` in Node or an `HTMLImageElement` in the browser. `loadImage` is called once per URL and drawn size, and the\n * image's `width` and `height` are then set to that size (Chart.js draws an image point style at its own size), so\n * resolve a new image on every call, as `@napi-rs/canvas`'s `loadImage` does.\n */\nexport interface ImageLike {\n readonly width: number;\n readonly height: number;\n}\n\nfunction needDom(what: string): Document {\n if (typeof document === \"undefined\")\n throw new UnsupportedTargetError(\n `${what} needs a DOM: build it in the browser (onMount, $effect, an Astro client:only island), not during SSR`,\n );\n return document;\n}\nfunction checkSize(size: number, what: string): number {\n if (!(Number.isFinite(size) && size > 0))\n throw new InputError(`${what} is an image height in px > 0, got ${size}`);\n return size;\n}\n// ponytail: unbounded cache keyed by size + url; a page holds a few hundred marks at most.\nconst images = new Map<string, HTMLImageElement>();\nfunction image(url: string, h: number, aspect: number): HTMLImageElement {\n const w = Math.round(h * aspect);\n const key = `${w}x${h} ${url}`;\n let img = images.get(key);\n if (img === undefined) {\n img = needDom(\"an image point style\").createElement(\"img\");\n img.width = w; // Chart.js draws an image point style at the element's own width x height\n img.height = h;\n img.crossOrigin = \"anonymous\"; // keeps chart.toBase64Image() usable\n img.src = url;\n images.set(key, img);\n }\n return img;\n}\ntype LoadImage = (url: string) => Promise<ImageLike>;\n/** A `loadImage` image at its drawn size: `img` is undefined while it loads and null if it failed. */\nclass Loading {\n img: ImageLike | null | undefined = undefined;\n /** Point-style slots to fill, then charts to redraw, all in the first reaction to the loader's promise. */\n readonly slots: [PointStyle[], number][] = [];\n readonly on = new Set<() => void>();\n constructor(\n readonly width: number,\n readonly height: number,\n ) {}\n}\ntype Mark = HTMLImageElement | Loading;\n/** The size each loaded image was set to, to catch a loader that hands the same image out for two sizes. */\nconst sizes = new WeakMap<object, { width: number; height: number }>();\nconst DRAWN = [\"[object HTMLImageElement]\", \"[object HTMLCanvasElement]\"];\n/** Chart.js draws a point-style image at its own width x height, and only one that stringifies as a DOM image or canvas. */\nfunction sized(img: ImageLike, w: number, h: number): ImageLike | null {\n const was = sizes.get(img);\n if (was !== undefined && (was.width !== w || was.height !== h)) {\n warn(\n \"chartjs:loadImage:shared\",\n \"loadImage returned an image already sized for another drawn size, so that use is not drawn: loadImage must return a fresh image per call (wrap a cache so each call returns a new image)\",\n );\n return null;\n }\n const own = (value: unknown): PropertyDescriptor => ({ value, writable: true, configurable: true });\n const tag: PropertyDescriptorMap = DRAWN.includes(String(img)) ? {} : { toString: own(() => DRAWN[0]) };\n try {\n Object.defineProperties(img, { width: own(w), height: own(h), ...tag });\n } catch (e) {\n warn(\n \"chartjs:loadImage:unsizable\",\n `loadImage returned an image that cannot be sized (${String(e)}), so it is not drawn`,\n );\n return null;\n }\n sizes.set(img, { width: w, height: h });\n return img;\n}\n// ponytail: unbounded like `images`; per loader, so two loaders never share an image.\nconst loads = new WeakMap<LoadImage, Map<string, Loading>>();\nfunction loading(load: LoadImage, url: string, h: number, aspect: number): Loading {\n const w = Math.round(h * aspect);\n const key = `${w}x${h} ${url}`;\n const byKey = loads.get(load) ?? new Map<string, Loading>();\n loads.set(load, byKey);\n let m = byKey.get(key);\n if (m === undefined) {\n const it = new Loading(w, h);\n // everything runs here, in the promise's first reaction, so a caller awaiting the same promises sees it all done\n const land = (img: ImageLike | null): void => {\n it.img = img;\n if (img !== null) for (const [styles, i] of it.slots) styles[i] = img as unknown as PointStyle;\n it.slots.length = 0;\n const redraws = [...it.on];\n it.on.clear();\n for (const f of redraws) f();\n };\n void load(url).then(\n (img) => land(sized(img, w, h)),\n (e: unknown) => {\n warn(`chartjs:loadImage:${url}`, `loadImage failed for ${url} (${String(e)}), so it is not drawn`);\n land(null);\n },\n );\n m = it;\n byKey.set(key, m);\n }\n return m;\n}\n/** Game on Paper's light-theme or dark-theme canvas text colour, whichever reads better on `background`. */\nfunction textInk(background: string): string {\n return contrast(\"#555555\", background) >= contrast(\"#e8e6e3\", background) ? \"#555555\" : \"#e8e6e3\";\n}\nfunction textStyle(label: string, h: number, ink: string): HTMLCanvasElement | \"circle\" {\n // ponytail: Node (only reachable with loadImage) has no canvas to letter the label on, so it draws a circle\n if (typeof document === \"undefined\") return \"circle\";\n const c = document.createElement(\"canvas\");\n const g = c.getContext(\"2d\");\n if (g === null) return \"circle\";\n const font = `bold ${Math.round(h * 0.45)}px sans-serif`;\n g.font = font;\n c.width = Math.max(h, Math.ceil(g.measureText(label).width) + 4);\n c.height = h;\n g.font = font; // resizing a canvas resets its context\n g.textAlign = \"center\";\n g.textBaseline = \"middle\";\n g.fillStyle = ink;\n g.fillText(label, c.width / 2, h / 2);\n return c;\n}\n/** One image per resolvable value at `h` px tall, indexed like `values` (gaps where nothing can be drawn); warns once per call (J28). */\nfunction imagesFor(\n values: readonly Value[],\n h: number,\n place: PlaceOptions,\n load: LoadImage | undefined,\n): (Mark | undefined)[] {\n const out = new Array<Mark | undefined>(values.length);\n // The row index as x keeps data order; placeSync drops what it cannot draw and warns once per call (J28).\n const idx = values.map((_, i) => i);\n for (const p of placeSync(idx, idx, values, place))\n out[p.index] =\n load === undefined ? image(p.url, h, p.aspect ?? 1) : loading(load, p.url, h, p.aspect ?? 1);\n return out;\n}\n/** The point-style arrays still waiting on a `loadImage` image, for `pointImages` to refresh. */\nconst pending = new WeakMap<object, Loading[]>();\nfunction points(\n values: readonly Value[],\n kind: Kind,\n radius: number | undefined,\n fallback: PointStyle | \"text\" | undefined,\n background: string | undefined,\n place: PlaceOptions,\n load: LoadImage | undefined,\n): PointStyles {\n if (load === undefined) needDom(\"point styles\"); // before resolving, so SSR fails without a resolve warning\n const r = radius ?? 12;\n if (!(Number.isFinite(r) && r > 0))\n throw new InputError(`radius is a point radius in px > 0, got ${String(radius)}`);\n const ink = textInk(background ?? (place.variant === \"dark\" ? \"#000000\" : \"#ffffff\")); // a bad colour throws here\n const styles = new Array<PointStyle>(values.length);\n const waiting: Loading[] = [];\n imagesFor(values, 2 * r, { ...place, kind }, load).forEach((m, i) => {\n if (m === undefined) return;\n if (!(m instanceof Loading)) {\n styles[i] = m;\n return;\n }\n // until it lands the slot draws nothing, as a loading image does; Chart.js re-reads the array on update\n styles[i] = (m.img ?? false) as PointStyle;\n if (m.img !== undefined) return;\n m.slots.push([styles, i]);\n waiting.push(m);\n });\n if (waiting.length > 0) pending.set(styles, waiting);\n for (let i = 0; i < values.length; i++)\n styles[i] ??=\n fallback === undefined || fallback === \"text\"\n ? textStyle(String(values[i] ?? \"\"), 2 * r, ink)\n : fallback;\n return { pointStyle: styles, pointRadius: r };\n}\nfunction teamPoints(teams: readonly Value[], kind: \"logo\" | \"wordmark\", o: PointOptions): PointStyles {\n const { league, radius, fallback, background, loadImage, ...rest } = o;\n return points(teams, kind, radius, fallback, background, { league, ...rest }, loadImage);\n}\n/** Team logos as point styles: `{ data, ...logoPoints(teams, { league: \"nfl\", radius: 12 }) }`. Add `pointImages` to `plugins`. */\nexport function logoPoints(teams: readonly Value[], o: PointOptions): PointStyles {\n return teamPoints(teams, \"logo\", o);\n}\n/** As `logoPoints`, with wordmarks. */\nexport function wordmarkPoints(teams: readonly Value[], o: PointOptions): PointStyles {\n return teamPoints(teams, \"wordmark\", o);\n}\n/** ESPN player headshots as point styles; `idSystem: \"gsis\"` needs `loadGsis()` first. */\nexport function headshotPoints(players: readonly Value[], o: HeadshotPointOptions): PointStyles {\n return points(\n players,\n \"headshot\",\n o.radius,\n o.fallback,\n o.background,\n { league: o.league, idSystem: o.idSystem ?? \"espn\" },\n o.loadImage,\n );\n}\n\ntype Redraws = { redraw: () => void; refresh: () => void; stop: AbortController };\nconst redraws = new WeakMap<Chart, Redraws>();\nconst isImage = (v: unknown): v is HTMLImageElement =>\n Object.prototype.toString.call(v) === \"[object HTMLImageElement]\"; // Chart.js's own test (drawPointLegend)\nfunction redrawsOf(chart: Chart): Redraws {\n let r = redraws.get(chart);\n if (r === undefined) {\n r = {\n redraw: () => {\n if (chart.ctx) chart.draw(); // null once destroyed\n },\n refresh: () => {\n if (chart.ctx) chart.update(\"none\"); // re-reads the point styles, which a draw does not\n },\n stop: new AbortController(),\n };\n redraws.set(chart, r);\n }\n return r;\n}\n/** Redraw `chart` once `img` loads; one listener per (image, chart) because addEventListener ignores a repeat. */\nfunction redrawOnLoad(chart: Chart, img: HTMLImageElement): void {\n if (img.complete) return;\n const r = redrawsOf(chart);\n img.addEventListener(\"load\", r.redraw, { once: true, signal: r.stop.signal });\n}\n/** As `redrawOnLoad`, for a `loadImage` image still loading; the same per-chart abort drops it on destroy. */\nfunction redrawOnLanding(chart: Chart, m: Loading, how: \"redraw\" | \"refresh\"): void {\n const r = redrawsOf(chart);\n const f = r[how];\n if (m.on.has(f)) return;\n m.on.add(f);\n r.stop.signal.addEventListener(\"abort\", () => m.on.delete(f), { once: true });\n}\n/** The image to paint now, or undefined with a redraw arranged for when it loads (a broken image is skipped). */\nfunction paint(chart: Chart, m: Mark | undefined): HTMLImageElement | undefined {\n if (m === undefined) return undefined;\n if (m instanceof Loading) {\n if (m.img === undefined) redrawOnLanding(chart, m, \"redraw\");\n return (m.img ?? undefined) as HTMLImageElement | undefined; // drawImage takes it as one; only its size is read\n }\n if (!m.complete || m.naturalWidth === 0) {\n redrawOnLoad(chart, m);\n return undefined;\n }\n return m;\n}\n/** `afterDestroy`: drop the chart's pending load listeners, so a late (or never-loading) image cannot hold or redraw it. */\nfunction forget(chart: Chart): void {\n redraws.get(chart)?.stop.abort();\n redraws.delete(chart);\n}\n/** Redraws the chart as each image point style finishes loading (Chart.js does not watch them). */\nexport const pointImages: Plugin = {\n id: \"sdvplotPointImages\",\n afterDestroy: forget,\n afterDraw(chart) {\n for (const ds of chart.data.datasets) {\n const s = (ds as { pointStyle?: unknown }).pointStyle;\n for (const v of Array.isArray(s) ? s : [s]) if (isImage(v)) redrawOnLoad(chart, v);\n for (const m of (Array.isArray(s) && pending.get(s)) || [])\n if (m.img === undefined) redrawOnLanding(chart, m, \"refresh\");\n }\n },\n};\n\nexport interface TeamColorOptions {\n which?: Which;\n season?: SeasonInput;\n idSystem?: IdSystem;\n /** Opacity in [0, 1]; below 1 the colour is written `rgba(r, g, b, a)`. */\n alpha?: number;\n /** The colour of an unresolved team (default `#808080`). */\n fallback?: string;\n /** Return black or white, whichever reads on the team colour (labels, point borders). */\n onColor?: boolean;\n}\nexport type ColorsFor<T> = T extends readonly Value[] ? string[] : string;\n/** Team colour(s) for `backgroundColor` / `borderColor`: one team gives one string, an array gives one per team. */\nexport function teamColor<T extends Value | readonly Value[]>(\n teams: T,\n league: League,\n o: TeamColorOptions = {},\n): ColorsFor<T> {\n const { alpha = 1, fallback = \"#808080\", onColor: ink = false, ...co } = o;\n const a = checkAlpha(alpha);\n const paint = (c: unknown): string => {\n const hex = hex6(typeof c === \"string\" ? c : fallback, { dropAlpha: true });\n if (ink) return onColor(hex);\n if (a === 1) return hex;\n const n = Number.parseInt(hex.slice(1), 16);\n return `rgba(${n >> 16}, ${(n >> 8) & 255}, ${n & 255}, ${a})`;\n };\n const got: unknown = teamColorsSync(league, teams, co);\n return (Array.isArray(got) ? got.map(paint) : paint(got)) as ColorsFor<T>;\n}\n/** `teamColorPalette` options. */\nexport interface ChartjsColorOptions {\n which?: Which;\n season?: SeasonInput;\n idSystem?: IdSystem;\n /** The colour of an unresolved team. Default \"#808080\". A hex colour when `background` is given. */\n fallback?: string;\n /**\n * The chart's background, as an opaque hex colour (`#181a1b` or `#000`; a CSS colour name or `rgb()` throws).\n * Given, a team colour under 3:1 contrast against it is swapped for the team's other\n * colour, else moved towards white (on a dark background) or black (a light one) until it reads: dark mode. A\n * colour that would then sit too close to an earlier team's (CIE76 ΔE under 20) takes the team's other colour, or\n * the nearest colour to its own that is distinct and still reads; failing that it is kept, with one warning.\n */\n background?: string;\n}\n/**\n * One colour per team, in order, for `backgroundColor` / `borderColor`. With `background`, every colour keeps 3:1\n * contrast against it (dark mode) and stays distinct from the others, as every sdvplot adapter's `teamColorPalette`.\n *\n * @example\n * ```ts\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { teamColorPalette } from \"@sportsdataverse/sdvplot/chartjs\";\n *\n * await loadLeague(\"nfl\");\n * teamColorPalette(\"nfl\", [\"KC\", \"LAC\", \"DEN\", \"LV\"], { background: \"#181a1b\" });\n * ```\n */\nexport function teamColorPalette(\n league: League,\n teams: readonly unknown[],\n o: ChartjsColorOptions = {},\n): string[] {\n return colorPalette(league, teams, o);\n}\n/** `teamColor` at 0.2 opacity by default: the fill under a radar or area dataset. */\nexport function teamFill<T extends Value | readonly Value[]>(\n teams: T,\n league: League,\n o: TeamColorOptions = {},\n): ColorsFor<T> {\n return teamColor(teams, league, { alpha: 0.2, ...o });\n}\n\nexport interface AxisLogoOptions {\n league: League;\n /** Image height in px (default 24); the width follows the mark's aspect. */\n size?: number;\n season?: SeasonInput;\n variant?: Variant;\n markType?: \"logo\" | \"wordmark\";\n idSystem?: IdSystem;\n /** The category scale's id (default: the axis letter). */\n scaleId?: string;\n /**\n * Loads each image instead of a DOM image element, so this also runs in Node: pass `@napi-rs/canvas`'s `loadImage`.\n * See {@link ImageLike}.\n */\n loadImage?: (url: string) => Promise<ImageLike>;\n}\ntype TickCallback = (this: Scale, value: number | string, index: number, ticks: Tick[]) => unknown;\n/**\n * Swap a category axis's tick labels for team logos: resolved labels are painted as images (after the datasets, under\n * the tooltip) and their text is blanked; unresolved labels keep their text, with one warning per distinct label set\n * (J28). Any other scale type is left as it is, with one warning.\n */\nexport function axisLogos(axis: \"x\" | \"y\", o: AxisLogoOptions): Plugin {\n if (axis !== \"x\" && axis !== \"y\")\n throw new InputError(`axis must be \"x\" or \"y\", got ${JSON.stringify(axis)}`);\n const { league, size = 24, markType = \"logo\", scaleId = axis, loadImage, ...rest } = o;\n checkSize(size, \"size\");\n const byChart = new WeakMap<Chart, { m: Map<string, Mark>; band: number }>();\n const bases = new WeakMap<TickCallback, number>(); // each wired callback -> the padding it was wired over\n return {\n id: `sdvplotAxisLogos${axis.toUpperCase()}`,\n afterDestroy: forget,\n beforeUpdate(chart) {\n // Chart.js merges options.scales into a fresh copy on every update (and `chart.options = next` replaces it), so\n // the tick wiring is (re)applied to that copy here, once per copy: never in beforeInit, never the caller's object.\n const conf = chart.config as unknown as {\n options: {\n scales?: Record<string, { type?: string; ticks?: { callback?: TickCallback; padding?: number } }>;\n };\n };\n const scale = conf.options.scales?.[scaleId];\n if (scale?.type !== \"category\") {\n byChart.delete(chart);\n warn(\n `chartjs:axisLogos:${scaleId}`,\n `axisLogos needs a category scale; scale ${JSON.stringify(scaleId)} is ${scale?.type ?? \"missing\"}, so its ticks are left as they are`,\n );\n return;\n }\n const labels = (chart.data.labels ?? []).map(String);\n const m = new Map<string, Mark>();\n imagesFor(labels, size, { league, kind: markType, ...rest }, loadImage).forEach((img, i) => {\n if (img !== undefined) m.set(labels[i] ?? \"\", img);\n });\n // the band the images fill: their height on x, the widest mark on y (a wordmark is several times its height)\n const band = axis === \"y\" ? Math.max(size, ...[...m.values()].map((img) => img.width)) : size;\n byChart.set(chart, { m, band });\n scale.ticks ??= {};\n const ticks = scale.ticks;\n const user = ticks.callback;\n let base = user === undefined ? undefined : bases.get(user);\n if (base === undefined) {\n base = ticks.padding ?? 3; // 3 = Chart.js's default padding\n const callback: TickCallback = function (this: Scale, value, index, all) {\n const label = this.getLabelForValue(Number(value));\n if (byChart.get(chart)?.m.has(label)) return \"\";\n return user === undefined ? label : user.call(this, value, index, all);\n };\n bases.set(callback, base);\n ticks.callback = callback;\n }\n ticks.padding = base + band;\n },\n afterDatasetsDraw(chart) {\n const scale = chart.scales[scaleId];\n const got = byChart.get(chart);\n if (scale === undefined || got === undefined) return;\n const { m, band } = got;\n // resolved options: Chart.js has filled every default by draw time\n const { grid, ticks } = scale.options as unknown as {\n grid: { display: boolean; drawTicks: boolean; tickLength: number };\n ticks: { padding: number };\n };\n const gap = (grid.display && grid.drawTicks ? grid.tickLength : 0) + ticks.padding - band;\n scale.ticks.forEach((t, i) => {\n const img = paint(chart, m.get(scale.getLabelForValue(t.value)));\n if (img === undefined) return;\n const at = scale.getPixelForTick(i);\n const { width: w, height: h } = img;\n const x =\n axis === \"y\" ? (scale.position === \"right\" ? scale.left + gap : scale.right - gap - w) : at - w / 2;\n const y =\n axis === \"x\" ? (scale.position === \"top\" ? scale.bottom - gap - h : scale.top + gap) : at - h / 2;\n chart.ctx.drawImage(img, x, y, w, h);\n });\n },\n };\n}\n\nexport interface WatermarkOptions {\n league: League;\n /** Image height in px (default 75, Game on Paper's win-probability chart); the width follows the mark's aspect. */\n size?: number;\n /** Opacity of the watermarks (default 0.4). */\n alpha?: number;\n /** Gap in px from the chart area's left edge and from its top / bottom (default 8). */\n inset?: number;\n season?: SeasonInput | readonly SeasonInput[];\n variant?: Variant;\n idSystem?: IdSystem;\n /**\n * Loads each image instead of a DOM image element, so this also runs in Node: pass `@napi-rs/canvas`'s `loadImage`.\n * See {@link ImageLike}.\n */\n loadImage?: (url: string) => Promise<ImageLike>;\n}\n/**\n * Faint team logos behind the datasets (Game on Paper's win-probability chart): the first team sits top-left of the\n * chart area, the last bottom-left, any between spaced evenly down the left edge, so pass `[home, away]` under a home\n * win-probability line. Unknown teams are skipped with one warning per call (J28); `variant: \"dark\"` falls back to a\n * light mark by polarity, so no `onerror` retry is needed.\n */\nexport function logoWatermarks(teams: readonly Value[], o: WatermarkOptions): Plugin {\n if (o.loadImage === undefined) needDom(\"logo watermarks\"); // before resolving, so SSR fails without a resolve warning\n const { league, size = 75, alpha = 0.4, inset = 8, loadImage, ...rest } = o;\n checkSize(size, \"size\");\n const a = checkAlpha(alpha);\n const imgs = imagesFor(teams, size, { league, kind: \"logo\", ...rest }, loadImage);\n const n = imgs.length;\n return {\n id: \"sdvplotLogoWatermarks\",\n afterDestroy: forget,\n beforeDatasetsDraw(chart) {\n const { ctx, chartArea: ar } = chart;\n if (!ar) return; // a draw before the first layout\n ctx.save();\n ctx.globalAlpha = a;\n imgs.forEach((m, i) => {\n const img = paint(chart, m);\n if (img === undefined) return;\n const t = n > 1 ? i / (n - 1) : 0;\n const y = ar.top + inset + t * (ar.bottom - ar.top - 2 * inset - img.height);\n ctx.drawImage(img, ar.left + inset, y, img.width, img.height);\n });\n ctx.restore();\n },\n };\n}\n"]}
@@ -0,0 +1,92 @@
1
+ import { InputError } from './chunk-E7G7VSLV.js';
2
+
3
+ // src/selection.ts
4
+ var sealed = (set) => {
5
+ const deny = () => {
6
+ throw new TypeError("a selection state is read-only: pass the new ids to store.set");
7
+ };
8
+ for (const m of ["add", "delete", "clear"]) Object.defineProperty(set, m, { value: deny });
9
+ return set;
10
+ };
11
+ var EMPTY = sealed(/* @__PURE__ */ new Set());
12
+ function toId(v) {
13
+ return v === null || v === void 0 || v === "" || typeof v === "number" && Number.isNaN(v) ? "" : String(v);
14
+ }
15
+ function sameIds(a, b) {
16
+ if (a === b) return true;
17
+ if (a.size !== b.size) return false;
18
+ for (const id of a) if (!b.has(id)) return false;
19
+ return true;
20
+ }
21
+ function sameCursor(a, b) {
22
+ return a === b || a !== null && b !== null && a.field === b.field && a.value === b.value;
23
+ }
24
+ function focusIds(s) {
25
+ if (s.hover.size === 0 && s.selected.size === 0 && s.predicate === null) return null;
26
+ if (s.hover.size === 0) return s.selected;
27
+ if (s.selected.size === 0) return s.hover;
28
+ return /* @__PURE__ */ new Set([...s.selected, ...s.hover]);
29
+ }
30
+ function createSelection() {
31
+ let state = Object.freeze({
32
+ hover: EMPTY,
33
+ selected: EMPTY,
34
+ predicate: null,
35
+ cursor: null
36
+ });
37
+ const listeners = /* @__PURE__ */ new Set();
38
+ const ids = (next, prev) => {
39
+ if (next === void 0) return prev;
40
+ if (typeof next === "string")
41
+ throw new InputError(
42
+ `selection ids are a collection; pass [${JSON.stringify(next)}], not a bare string`
43
+ );
44
+ const set = /* @__PURE__ */ new Set();
45
+ for (const v of next) {
46
+ const id = toId(v);
47
+ if (id !== "") set.add(id);
48
+ }
49
+ return sameIds(set, prev) ? prev : sealed(set);
50
+ };
51
+ const store = {
52
+ getState: () => state,
53
+ set(patch) {
54
+ const c = patch.cursor;
55
+ if (c != null && (typeof c.field !== "string" || c.field === "" || !Number.isFinite(c.value)))
56
+ throw new InputError(
57
+ `selection cursor needs a non-empty field and a finite value, got field ${JSON.stringify(c.field)}, value ${String(c.value)}`
58
+ );
59
+ const hover = ids(patch.hover, state.hover);
60
+ const selected = ids(patch.selected, state.selected);
61
+ const predicate = patch.predicate === void 0 ? state.predicate : patch.predicate;
62
+ const cursor = c === void 0 || sameCursor(c, state.cursor) ? state.cursor : c === null ? null : Object.freeze({ field: c.field, value: c.value });
63
+ if (hover === state.hover && selected === state.selected && predicate === state.predicate && cursor === state.cursor)
64
+ return;
65
+ state = Object.freeze({ hover, selected, predicate, cursor });
66
+ for (const fn of [...listeners]) {
67
+ if (!listeners.has(fn)) continue;
68
+ try {
69
+ fn(state);
70
+ } catch (e) {
71
+ queueMicrotask(() => {
72
+ throw e;
73
+ });
74
+ }
75
+ }
76
+ },
77
+ clear() {
78
+ store.set({ hover: EMPTY, selected: EMPTY, predicate: null, cursor: null });
79
+ },
80
+ subscribe(fn) {
81
+ listeners.add(fn);
82
+ return () => {
83
+ listeners.delete(fn);
84
+ };
85
+ }
86
+ };
87
+ return store;
88
+ }
89
+
90
+ export { createSelection, focusIds, sameCursor, sameIds, toId };
91
+ //# sourceMappingURL=chunk-4C3GX6QO.js.map
92
+ //# sourceMappingURL=chunk-4C3GX6QO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/selection.ts"],"names":[],"mappings":";;;AA0EA,IAAM,MAAA,GAAS,CAAC,GAAA,KAA0C;AACxD,EAAA,MAAM,OAAO,MAAa;AACxB,IAAA,MAAM,IAAI,UAAU,+DAA+D,CAAA;AAAA,EACrF,CAAA;AACA,EAAA,KAAA,MAAW,CAAA,IAAK,CAAC,KAAA,EAAO,QAAA,EAAU,OAAO,CAAA,EAAG,MAAA,CAAO,cAAA,CAAe,GAAA,EAAK,CAAA,EAAG,EAAE,KAAA,EAAO,MAAM,CAAA;AACzF,EAAA,OAAO,GAAA;AACT,CAAA;AACA,IAAM,KAAA,GAA6B,MAAA,iBAAO,IAAI,GAAA,EAAa,CAAA;AAapD,SAAS,KAAK,CAAA,EAAoB;AACvC,EAAA,OAAO,CAAA,KAAM,IAAA,IAAQ,CAAA,KAAM,MAAA,IAAa,MAAM,EAAA,IAAO,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,KAAA,CAAM,CAAC,CAAA,GACxF,EAAA,GACA,OAAO,CAAC,CAAA;AACd;AAYO,SAAS,OAAA,CAAQ,GAAwB,CAAA,EAAiC;AAC/E,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,IAAA;AACpB,EAAA,IAAI,CAAA,CAAE,IAAA,KAAS,CAAA,CAAE,IAAA,EAAM,OAAO,KAAA;AAC9B,EAAA,KAAA,MAAW,EAAA,IAAM,GAAG,IAAI,CAAC,EAAE,GAAA,CAAI,EAAE,GAAG,OAAO,KAAA;AAC3C,EAAA,OAAO,IAAA;AACT;AAmBO,SAAS,UAAA,CAAW,GAAkB,CAAA,EAA2B;AACtE,EAAA,OAAO,CAAA,KAAM,CAAA,IAAM,CAAA,KAAM,IAAA,IAAQ,CAAA,KAAM,IAAA,IAAQ,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,KAAA;AACtF;AAiBO,SAAS,SAAc,CAAA,EAAoD;AAChF,EAAA,IAAI,CAAA,CAAE,KAAA,CAAM,IAAA,KAAS,CAAA,IAAK,CAAA,CAAE,QAAA,CAAS,IAAA,KAAS,CAAA,IAAK,CAAA,CAAE,SAAA,KAAc,IAAA,EAAM,OAAO,IAAA;AAChF,EAAA,IAAI,CAAA,CAAE,KAAA,CAAM,IAAA,KAAS,CAAA,SAAU,CAAA,CAAE,QAAA;AACjC,EAAA,IAAI,CAAA,CAAE,QAAA,CAAS,IAAA,KAAS,CAAA,SAAU,CAAA,CAAE,KAAA;AACpC,EAAA,uBAAO,IAAI,IAAI,CAAC,GAAG,EAAE,QAAA,EAAU,GAAG,CAAA,CAAE,KAAK,CAAC,CAAA;AAC5C;AAmBO,SAAS,eAAA,GAAsD;AACpE,EAAA,IAAI,KAAA,GAA6B,OAAO,MAAA,CAAO;AAAA,IAC7C,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,SAAA,EAAW,IAAA;AAAA,IACX,MAAA,EAAQ;AAAA,GACT,CAAA;AACD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAsC;AAC5D,EAAA,MAAM,GAAA,GAAM,CAAC,IAAA,EAAoC,IAAA,KAAmD;AAClG,IAAA,IAAI,IAAA,KAAS,QAAW,OAAO,IAAA;AAC/B,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA;AAClB,MAAA,MAAM,IAAI,UAAA;AAAA,QACR,CAAA,sCAAA,EAAyC,IAAA,CAAK,SAAA,CAAU,IAAI,CAAC,CAAA,oBAAA;AAAA,OAC/D;AACF,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,MAAA,MAAM,EAAA,GAAK,KAAK,CAAC,CAAA;AACjB,MAAA,IAAI,EAAA,KAAO,EAAA,EAAI,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAAA,IAC3B;AACA,IAAA,OAAO,QAAQ,GAAA,EAAK,IAAI,CAAA,GAAI,IAAA,GAAO,OAAO,GAAG,CAAA;AAAA,EAC/C,CAAA;AACA,EAAA,MAAM,KAAA,GAA6B;AAAA,IACjC,UAAU,MAAM,KAAA;AAAA,IAChB,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,IAAI,KAAA,CAAM,MAAA;AAChB,MAAA,IAAI,CAAA,IAAK,IAAA,KAAS,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,IAAY,CAAA,CAAE,KAAA,KAAU,EAAA,IAAM,CAAC,MAAA,CAAO,QAAA,CAAS,EAAE,KAAK,CAAA,CAAA;AACzF,QAAA,MAAM,IAAI,UAAA;AAAA,UACR,CAAA,uEAAA,EAA0E,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,KAAK,CAAC,CAAA,QAAA,EAAW,MAAA,CAAO,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,SAC7H;AACF,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,KAAA,EAAO,MAAM,KAAK,CAAA;AAC1C,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,KAAA,CAAM,QAAA,EAAU,MAAM,QAAQ,CAAA;AACnD,MAAA,MAAM,YAAY,KAAA,CAAM,SAAA,KAAc,MAAA,GAAY,KAAA,CAAM,YAAY,KAAA,CAAM,SAAA;AAE1E,MAAA,MAAM,MAAA,GACJ,MAAM,MAAA,IAAa,UAAA,CAAW,GAAG,KAAA,CAAM,MAAM,CAAA,GACzC,KAAA,CAAM,MAAA,GACN,CAAA,KAAM,OACJ,IAAA,GACA,MAAA,CAAO,OAAO,EAAE,KAAA,EAAO,EAAE,KAAA,EAAO,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,CAAA;AACxD,MAAA,IACE,KAAA,KAAU,KAAA,CAAM,KAAA,IAChB,QAAA,KAAa,KAAA,CAAM,YACnB,SAAA,KAAc,KAAA,CAAM,SAAA,IACpB,MAAA,KAAW,KAAA,CAAM,MAAA;AAEjB,QAAA;AACF,MAAA,KAAA,GAAQ,OAAO,MAAA,CAAO,EAAE,OAAO,QAAA,EAAU,SAAA,EAAW,QAAQ,CAAA;AAC5D,MAAA,KAAA,MAAW,EAAA,IAAM,CAAC,GAAG,SAAS,CAAA,EAAG;AAC/B,QAAA,IAAI,CAAC,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA,EAAG;AACxB,QAAA,IAAI;AACF,UAAA,EAAA,CAAG,KAAK,CAAA;AAAA,QACV,SAAS,CAAA,EAAG;AAEV,UAAA,cAAA,CAAe,MAAM;AACnB,YAAA,MAAM,CAAA;AAAA,UACR,CAAC,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,KAAA,GAAQ;AACN,MAAA,KAAA,CAAM,GAAA,CAAI,EAAE,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU,OAAO,SAAA,EAAW,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAA;AAAA,IAC5E,CAAA;AAAA,IACA,UAAU,EAAA,EAAI;AACZ,MAAA,SAAA,CAAU,IAAI,EAAE,CAAA;AAChB,MAAA,OAAO,MAAM;AACX,QAAA,SAAA,CAAU,OAAO,EAAE,CAAA;AAAA,MACrB,CAAA;AAAA,IACF;AAAA,GACF;AACA,EAAA,OAAO,KAAA;AACT","file":"chunk-4C3GX6QO.js","sourcesContent":["import { InputError } from \"./errors.js\";\n\n/**\n * A row test, true to keep the row: the brush region (or any caller's) as a predicate. The one definition: sdvtables\n * re-exports this type for `setExternalFilter`, so a linked table applies a store's predicate as is (not a\n * `ValuePredicate`, which tests one column's cell). Both compare it by identity: the same function again is a no-op.\n */\nexport type RowFilter<Row> = (row: Row) => boolean;\n\n/**\n * A shared hover VALUE (J34): a number along one data field, such as the shot distance under the pointer, that every\n * linked chart draws through its own scale (a rule, a band, a ring). Not an id: it never dims marks or filters a table.\n * Unrelated to sdvtables' `TableCursor` (a grid's keyboard row).\n */\nexport interface Cursor {\n /** The data field the value is in, e.g. `\"shot_distance\"`. Never `\"\"`. */\n readonly field: string;\n /** The value along that field. Always finite. */\n readonly value: number;\n}\n\n/**\n * What a {@link SelectionStore} holds. Immutable: every change replaces it, and a snapshot is read-only at runtime too\n * (its sets' `add`, `delete` and `clear`, and a write to it or its cursor, throw a `TypeError`): pass changes to\n * `store.set`, or copy a set with `new Set(ids)`.\n */\nexport interface SelectionState<Row = unknown> {\n /** Ids under the pointer right now (transient). */\n readonly hover: ReadonlySet<string>;\n /** Ids picked by a table-row click or a brush (sticky). */\n readonly selected: ReadonlySet<string>;\n /** The brush region as a row test; null when nothing is brushed. */\n readonly predicate: RowFilter<Row> | null;\n /** The shared hover value; null when the pointer is on no linked chart. */\n readonly cursor: Cursor | null;\n}\n/**\n * A partial update for {@link SelectionStore.set}: an absent field keeps its value. Each id goes through\n * {@link toId}: a number is stringified (`12` and `\"12\"` are the same id) and null, undefined, NaN and `\"\"` are\n * dropped. A bare string throws `InputError` rather than being split into letters: pass `[\"KC\"]`, not `\"KC\"`.\n */\nexport interface SelectionPatch<Row = unknown> {\n /** The new hover ids (replaces the set; `[]` clears it). */\n readonly hover?: Iterable<string>;\n /** The new selected ids (replaces the set; `[]` clears it). */\n readonly selected?: Iterable<string>;\n /** The new brush region; `null` clears it. */\n readonly predicate?: RowFilter<Row> | null;\n /** The new hover value; `null` clears it. An equal cursor (same field, same value) is a no-op. */\n readonly cursor?: Cursor | null;\n}\n/** The linked-interactivity hub that {@link createSelection} returns. */\nexport interface SelectionStore<Row = unknown> {\n /** Referentially stable until the next change: what `useSyncExternalStore` reads. */\n getState(): SelectionState<Row>;\n /** Apply a patch. ONE notification when anything changed, none when nothing did, so linked components cannot ping-pong. */\n set(patch: SelectionPatch<Row>): void;\n /** Clear hover, selected, predicate and cursor. */\n clear(): void;\n /**\n * Call `fn` after every change; returns the unsubscribe function. A listener that throws stops neither the others\n * nor `set`: its error is rethrown in a microtask, as an `EventTarget` listener's is, so it still reaches\n * `window.onerror` (or Node's `uncaughtException`) but one broken view cannot freeze the rest. A listener removed\n * during a notification is not called for it.\n */\n subscribe(fn: (state: SelectionState<Row>) => void): () => void;\n}\n\n/**\n * Seal one of the store's id sets: read-only at runtime as well as in its type, since a JavaScript caller's `add`\n * would change the state behind the listeners' backs (and EMPTY is shared by every store). The mutators become own,\n * non-enumerable throwing methods, so it stays a plain `Set` to `instanceof` and to deep equality; a copy,\n * `new Set(ids)`, is the caller's own.\n */\nconst sealed = (set: Set<string>): ReadonlySet<string> => {\n const deny = (): never => {\n throw new TypeError(\"a selection state is read-only: pass the new ids to store.set\");\n };\n for (const m of [\"add\", \"delete\", \"clear\"]) Object.defineProperty(set, m, { value: deny });\n return set;\n};\nconst EMPTY: ReadonlySet<string> = sealed(new Set<string>());\n\n/**\n * The link id of a value: `String(v)`, or `\"\"` (never matched) for null, undefined, NaN and `\"\"`. A figure and a table\n * link only when they hold the same ids, so an ESPN team id (`\"12\"`) never matches an abbreviation (`\"KC\"`).\n *\n * @example\n * ```ts\n * import { toId } from \"@sportsdataverse/sdvplot\";\n *\n * [toId(12), toId(\"KC\"), toId(null), toId(Number.NaN)];\n * ```\n */\nexport function toId(v: unknown): string {\n return v === null || v === undefined || v === \"\" || (typeof v === \"number\" && Number.isNaN(v))\n ? \"\"\n : String(v);\n}\n\n/**\n * Whether two id sets hold the same ids, in any order.\n *\n * @example\n * ```ts\n * import { sameIds } from \"@sportsdataverse/sdvplot\";\n *\n * sameIds(new Set([\"KC\", \"BUF\"]), new Set([\"BUF\", \"KC\"]));\n * ```\n */\nexport function sameIds(a: ReadonlySet<string>, b: ReadonlySet<string>): boolean {\n if (a === b) return true;\n if (a.size !== b.size) return false;\n for (const id of a) if (!b.has(id)) return false;\n return true;\n}\n\n/**\n * Whether two cursors are the same: the same field and an `===`-equal value, so `0` and `-0` are one hover value\n * (NaN never gets into the store). `null` equals only `null`.\n *\n * @example\n * ```ts\n * import { sameCursor } from \"@sportsdataverse/sdvplot\";\n *\n * const rim = { field: \"shot_distance\", value: 0.5 }; // the centre of the 0-1 ft bin\n * [\n * sameCursor(rim, { field: \"shot_distance\", value: 0.5 }), // a new object, the same value: true\n * sameCursor(rim, { field: \"shot_distance\", value: 1.5 }), // the next bin: false\n * sameCursor(rim, null), // the pointer left: false\n * sameCursor(null, null),\n * ];\n * ```\n */\nexport function sameCursor(a: Cursor | null, b: Cursor | null): boolean {\n return a === b || (a !== null && b !== null && a.field === b.field && a.value === b.value);\n}\n\n/**\n * What a figure should emphasise. `null`: nothing is active, draw everything normally. A set, possibly EMPTY\n * (a brush that encloses no point): emphasise those ids and dim the rest. Hover and selected are unioned. The\n * cursor is ignored: a shared hover value never dims anything.\n *\n * @example\n * ```ts\n * import { createSelection, focusIds } from \"@sportsdataverse/sdvplot\";\n *\n * const store = createSelection();\n * const idle = focusIds(store.getState()); // null: draw everything normally\n * store.set({ selected: [\"KC\"], hover: [\"BUF\"] });\n * ({ idle, focus: [...(focusIds(store.getState()) ?? [])] });\n * ```\n */\nexport function focusIds<Row>(s: SelectionState<Row>): ReadonlySet<string> | null {\n if (s.hover.size === 0 && s.selected.size === 0 && s.predicate === null) return null;\n if (s.hover.size === 0) return s.selected;\n if (s.selected.size === 0) return s.hover;\n return new Set([...s.selected, ...s.hover]);\n}\n\n/**\n * The linked-interactivity hub (J31): hover and selected id sets plus a row predicate. Pure data, zero deps, no DOM:\n * creating or updating one in Node changes nothing a server renders. Ids are strings, normalised by {@link toId}\n * (see {@link SelectionPatch}).\n *\n * @example\n * ```ts\n * import { createSelection } from \"@sportsdataverse/sdvplot\";\n *\n * const store = createSelection();\n * let updates = 0;\n * store.subscribe(() => updates++);\n * store.set({ selected: [\"KC\", \"BUF\"] });\n * store.set({ selected: [\"BUF\", \"KC\"] }); // the same ids: silent, so linked views cannot ping-pong\n * ({ updates, selected: [...store.getState().selected] });\n * ```\n */\nexport function createSelection<Row = unknown>(): SelectionStore<Row> {\n let state: SelectionState<Row> = Object.freeze({\n hover: EMPTY,\n selected: EMPTY,\n predicate: null,\n cursor: null,\n });\n const listeners = new Set<(s: SelectionState<Row>) => void>();\n const ids = (next: Iterable<string> | undefined, prev: ReadonlySet<string>): ReadonlySet<string> => {\n if (next === undefined) return prev;\n if (typeof next === \"string\")\n throw new InputError(\n `selection ids are a collection; pass [${JSON.stringify(next)}], not a bare string`,\n );\n const set = new Set<string>();\n for (const v of next) {\n const id = toId(v);\n if (id !== \"\") set.add(id);\n }\n return sameIds(set, prev) ? prev : sealed(set);\n };\n const store: SelectionStore<Row> = {\n getState: () => state,\n set(patch) {\n const c = patch.cursor;\n if (c != null && (typeof c.field !== \"string\" || c.field === \"\" || !Number.isFinite(c.value)))\n throw new InputError(\n `selection cursor needs a non-empty field and a finite value, got field ${JSON.stringify(c.field)}, value ${String(c.value)}`,\n );\n const hover = ids(patch.hover, state.hover);\n const selected = ids(patch.selected, state.selected);\n const predicate = patch.predicate === undefined ? state.predicate : patch.predicate;\n // a copy, so a caller mutating its object later cannot change the state behind the listeners' backs\n const cursor =\n c === undefined || sameCursor(c, state.cursor)\n ? state.cursor\n : c === null\n ? null\n : Object.freeze({ field: c.field, value: c.value });\n if (\n hover === state.hover &&\n selected === state.selected &&\n predicate === state.predicate &&\n cursor === state.cursor\n )\n return;\n state = Object.freeze({ hover, selected, predicate, cursor });\n for (const fn of [...listeners]) {\n if (!listeners.has(fn)) continue; // removed by an earlier listener during this notification\n try {\n fn(state);\n } catch (e) {\n // reported, not swallowed, and not thrown at the caller (a pointer handler that cannot fix another view)\n queueMicrotask(() => {\n throw e;\n });\n }\n }\n },\n clear() {\n store.set({ hover: EMPTY, selected: EMPTY, predicate: null, cursor: null });\n },\n subscribe(fn) {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n },\n };\n return store;\n}\n"]}
@@ -0,0 +1,128 @@
1
+ import { teamColorPairSync, LEAGUES } from './chunk-ZAEQXFJM.js';
2
+ import { onColor, contrast } from './chunk-J6R2LEJ7.js';
3
+ import { InputError } from './chunk-E7G7VSLV.js';
4
+ import { displayRanges, UnknownDisplayRangeError, surface } from '@sportsdataverse/sporty';
5
+
6
+ var SURFACES = {
7
+ nfl: ["football", "nfl"],
8
+ aaf: ["football", "nfl"],
9
+ ufl: ["football", "nfl"],
10
+ usfl: ["football", "nfl"],
11
+ xfl: ["football", "nfl"],
12
+ cfb: ["football", "ncaa"],
13
+ cfl: ["football", "cfl"],
14
+ nfhs_football: ["football", "nfhs11"],
15
+ nba: ["basketball", "nba"],
16
+ nbagl: ["basketball", "nba g league"],
17
+ wnba: ["basketball", "wnba"],
18
+ mbb: ["basketball", "ncaa"],
19
+ wbb: ["basketball", "ncaa"],
20
+ fiba: ["basketball", "fiba"],
21
+ nfhs_basketball: ["basketball", "nfhs"],
22
+ mlb: ["baseball", "mlb"],
23
+ milb: ["baseball", "milb"],
24
+ ncaa_baseball: ["baseball", "ncaa"],
25
+ little_league: ["baseball", "little league"],
26
+ pony: ["baseball", "pony"],
27
+ nfhs_baseball: ["baseball", "nfhs"],
28
+ ncaa_softball: ["softball", "ncaa"],
29
+ nhl: ["hockey", "nhl"],
30
+ whl: ["hockey", "nhl"],
31
+ pwhl: ["hockey", "pwhl"],
32
+ ahl: ["hockey", "ahl"],
33
+ echl: ["hockey", "echl"],
34
+ ohl: ["hockey", "ohl"],
35
+ qmjhl: ["hockey", "qmjhl"],
36
+ ushl: ["hockey", "ushl"],
37
+ phf: ["hockey", "phf"],
38
+ iihf: ["hockey", "iihf"],
39
+ nwhl: ["hockey", "nwhl"],
40
+ ncaa_mhockey: ["hockey", "ncaa"],
41
+ ncaa_whockey: ["hockey", "ncaa"],
42
+ soccer: ["soccer", "fifa"],
43
+ // drawn 105 x 68 m (see SOCCER_PITCH)
44
+ fifa: ["soccer", "fifa"],
45
+ epl: ["soccer", "epl"],
46
+ mls: ["soccer", "mls"],
47
+ nwsl: ["soccer", "nwsl"],
48
+ ncaa_soccer: ["soccer", "ncaa"],
49
+ nll: ["lacrosse", "nll"],
50
+ pll: ["lacrosse", "pll"],
51
+ world_lacrosse: ["lacrosse", "world lacrosse"],
52
+ ncaa_mlacrosse: ["lacrosse", "ncaam"],
53
+ ncaa_wlacrosse: ["lacrosse", "ncaaw"],
54
+ usa_mlacrosse: ["lacrosse", "usam"],
55
+ usa_wlacrosse: ["lacrosse", "usaw"],
56
+ atp: ["tennis", "atp"],
57
+ wta: ["tennis", "wta"],
58
+ itf: ["tennis", "itf"],
59
+ ita: ["tennis", "ita"],
60
+ usta: ["tennis", "usta"],
61
+ ncaa_tennis: ["tennis", "ncaa"],
62
+ fivb: ["volleyball", "fivb"],
63
+ usa_volleyball: ["volleyball", "usa volleyball"],
64
+ ncaa_volleyball: ["volleyball", "ncaa"],
65
+ wcf: ["curling", "wcf"],
66
+ curling_canada: ["curling", "curling canada"]
67
+ };
68
+ var SURFACE_BASE = { basketball: "#d2ab6f", football: "#196f0c", hockey: "#ffffff" };
69
+ var SOCCER_PITCH = { pitch_length: 105, pitch_width: 68 };
70
+ function colorUpdates(sport, primary, secondary) {
71
+ if (sport === "basketball") {
72
+ const ink = onColor(primary);
73
+ return {
74
+ painted_area: primary,
75
+ court_apron: primary,
76
+ restricted_arc: ink,
77
+ free_throw_circle_dash: ink,
78
+ baseline_lower_defensive_box: ink,
79
+ lane_lower_defensive_box: ink
80
+ };
81
+ }
82
+ if (sport === "football")
83
+ return { offensive_endzone: primary, defensive_endzone: primary };
84
+ if (sport !== "hockey") return {};
85
+ const ice = SURFACE_BASE.hockey;
86
+ const readable = secondary !== void 0 && contrast(primary, ice) < 3 && contrast(secondary, ice) >= 3;
87
+ const accent = readable ? secondary : primary;
88
+ return {
89
+ center_line: accent,
90
+ center_faceoff_circle: accent,
91
+ center_faceoff_spot: accent,
92
+ boards: primary
93
+ };
94
+ }
95
+ var isTeamLeague = (v) => LEAGUES.includes(v);
96
+ function surfaceScene(league, o = {}) {
97
+ const entry = Object.hasOwn(SURFACES, league) ? SURFACES[league] : void 0;
98
+ if (!entry)
99
+ throw new InputError(
100
+ `no surface for league '${league}'; supported: ${Object.keys(SURFACES).sort().join(", ")}`
101
+ );
102
+ const [sport, key] = entry;
103
+ const { team, season, colorUpdates: user, displayRange, updates, ...rest } = o;
104
+ let paint = {};
105
+ if (team !== void 0 && team !== null) {
106
+ if (!isTeamLeague(league))
107
+ throw new InputError(`no team identities for '${league}': draw the plain surface without a team`);
108
+ const at = season !== void 0 ? { season } : {};
109
+ const { primary, secondary } = teamColorPairSync(league, team, at);
110
+ if (primary !== void 0) paint = colorUpdates(sport, primary, secondary);
111
+ }
112
+ const ranges = displayRanges(sport);
113
+ if (displayRange !== void 0 && !ranges.includes(displayRange))
114
+ throw new UnknownDisplayRangeError(
115
+ `unknown displayRange '${displayRange}'; expected one of: ${ranges.join(", ")}`
116
+ );
117
+ const merged = league === "soccer" ? { ...SOCCER_PITCH, ...updates } : updates;
118
+ return surface(sport, key, {
119
+ ...rest,
120
+ colorUpdates: { ...paint, ...user },
121
+ ...displayRange === void 0 ? {} : { displayRange },
122
+ ...merged === void 0 ? {} : { updates: merged }
123
+ });
124
+ }
125
+
126
+ export { SURFACES, SURFACE_BASE, colorUpdates, surfaceScene };
127
+ //# sourceMappingURL=chunk-57WFSI4Q.js.map
128
+ //# sourceMappingURL=chunk-57WFSI4Q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/surfaces.ts"],"names":["sportySurface"],"mappings":"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","file":"chunk-57WFSI4Q.js","sourcesContent":["// Plot-free: sporty CORE only. Internal (not in the core barrel: sporty is an optional peer); reached via ./plot and ./d3.\nimport {\n type BaseballColorKey,\n type BaseballDisplayRange,\n type BaseballParamUpdates,\n type BasketballColorKey,\n type BasketballDisplayRange,\n type BasketballParamUpdates,\n type CurlingColorKey,\n type CurlingDisplayRange,\n type CurlingParamUpdates,\n type FootballColorKey,\n type FootballDisplayRange,\n type FootballParamUpdates,\n type HockeyColorKey,\n type HockeyDisplayRange,\n type HockeyParamUpdates,\n type LacrosseColorKey,\n type LacrosseDisplayRange,\n type LacrosseParamUpdates,\n type Scene,\n type SoccerColorKey,\n type SoccerDisplayRange,\n type SoccerParamUpdates,\n type SoftballColorKey,\n type SoftballDisplayRange,\n type SoftballParamUpdates,\n type Sport,\n type TennisColorKey,\n type TennisDisplayRange,\n type TennisParamUpdates,\n UnknownDisplayRangeError,\n type VolleyballColorKey,\n type VolleyballDisplayRange,\n type VolleyballParamUpdates,\n displayRanges,\n surface as sportySurface,\n} from \"@sportsdataverse/sporty\";\nimport { teamColorPairSync } from \"./colors.js\";\nimport { contrast, onColor } from \"./contrast.js\";\nimport { LEAGUES } from \"./data/index.js\";\nimport { InputError } from \"./errors.js\";\nimport type { Value } from \"./resolve.js\";\nimport type { League, SeasonInput } from \"./types.js\";\n\nexport type SurfaceSport = Sport;\n/**\n * Maps an sdv surface key to `[sporty sport, sporty league key]`: the SDV surface-key table shared with sdvplot (Python\n * `SURFACES`) and sdvplotR (`surface_map`). Keys that are also sdv team leagues (`nfl`, `ncaa_softball`, ...) take a `team`;\n * the rest (`atp`, `fiba`, `nll`, ...) draw the plain surface.\n */\nexport const SURFACES: Readonly<Record<string, readonly [SurfaceSport, string]>> = {\n nfl: [\"football\", \"nfl\"],\n aaf: [\"football\", \"nfl\"],\n ufl: [\"football\", \"nfl\"],\n usfl: [\"football\", \"nfl\"],\n xfl: [\"football\", \"nfl\"],\n cfb: [\"football\", \"ncaa\"],\n cfl: [\"football\", \"cfl\"],\n nfhs_football: [\"football\", \"nfhs11\"],\n nba: [\"basketball\", \"nba\"],\n nbagl: [\"basketball\", \"nba g league\"],\n wnba: [\"basketball\", \"wnba\"],\n mbb: [\"basketball\", \"ncaa\"],\n wbb: [\"basketball\", \"ncaa\"],\n fiba: [\"basketball\", \"fiba\"],\n nfhs_basketball: [\"basketball\", \"nfhs\"],\n mlb: [\"baseball\", \"mlb\"],\n milb: [\"baseball\", \"milb\"],\n ncaa_baseball: [\"baseball\", \"ncaa\"],\n little_league: [\"baseball\", \"little league\"],\n pony: [\"baseball\", \"pony\"],\n nfhs_baseball: [\"baseball\", \"nfhs\"],\n ncaa_softball: [\"softball\", \"ncaa\"],\n nhl: [\"hockey\", \"nhl\"],\n whl: [\"hockey\", \"nhl\"],\n pwhl: [\"hockey\", \"pwhl\"],\n ahl: [\"hockey\", \"ahl\"],\n echl: [\"hockey\", \"echl\"],\n ohl: [\"hockey\", \"ohl\"],\n qmjhl: [\"hockey\", \"qmjhl\"],\n ushl: [\"hockey\", \"ushl\"],\n phf: [\"hockey\", \"phf\"],\n iihf: [\"hockey\", \"iihf\"],\n nwhl: [\"hockey\", \"nwhl\"],\n ncaa_mhockey: [\"hockey\", \"ncaa\"],\n ncaa_whockey: [\"hockey\", \"ncaa\"],\n soccer: [\"soccer\", \"fifa\"], // drawn 105 x 68 m (see SOCCER_PITCH)\n fifa: [\"soccer\", \"fifa\"],\n epl: [\"soccer\", \"epl\"],\n mls: [\"soccer\", \"mls\"],\n nwsl: [\"soccer\", \"nwsl\"],\n ncaa_soccer: [\"soccer\", \"ncaa\"],\n nll: [\"lacrosse\", \"nll\"],\n pll: [\"lacrosse\", \"pll\"],\n world_lacrosse: [\"lacrosse\", \"world lacrosse\"],\n ncaa_mlacrosse: [\"lacrosse\", \"ncaam\"],\n ncaa_wlacrosse: [\"lacrosse\", \"ncaaw\"],\n usa_mlacrosse: [\"lacrosse\", \"usam\"],\n usa_wlacrosse: [\"lacrosse\", \"usaw\"],\n atp: [\"tennis\", \"atp\"],\n wta: [\"tennis\", \"wta\"],\n itf: [\"tennis\", \"itf\"],\n ita: [\"tennis\", \"ita\"],\n usta: [\"tennis\", \"usta\"],\n ncaa_tennis: [\"tennis\", \"ncaa\"],\n fivb: [\"volleyball\", \"fivb\"],\n usa_volleyball: [\"volleyball\", \"usa volleyball\"],\n ncaa_volleyball: [\"volleyball\", \"ncaa\"],\n wcf: [\"curling\", \"wcf\"],\n curling_canada: [\"curling\", \"curling canada\"],\n};\nexport const SURFACE_BASE = { basketball: \"#d2ab6f\", football: \"#196f0c\", hockey: \"#ffffff\" } as const;\n/** sportyR's \"fifa\" pitch is FIFA's 120 x 90 m maximum; the `soccer` key draws a real 105 x 68 m pitch, as sdvplot and sdvplotR do. */\nconst SOCCER_PITCH = { pitch_length: 105, pitch_width: 68 } as const;\n\ntype Paint<K extends string> = Partial<Record<K, string>>;\ntype AnyColorKey =\n | BaseballColorKey\n | BasketballColorKey\n | CurlingColorKey\n | FootballColorKey\n | HockeyColorKey\n | LacrosseColorKey\n | SoccerColorKey\n | SoftballColorKey\n | TennisColorKey\n | VolleyballColorKey;\n/**\n * Port of `_surface.color_updates`: the team colours a sport's surface takes, keyed by sporty colour key. Sports without a\n * team painting (baseball, softball, soccer and the team-less surfaces) take none, as in sdvplotR.\n */\nexport function colorUpdates(\n sport: \"basketball\",\n primary: string,\n secondary?: string,\n): Paint<BasketballColorKey>;\nexport function colorUpdates(sport: \"football\", primary: string, secondary?: string): Paint<FootballColorKey>;\nexport function colorUpdates(sport: \"hockey\", primary: string, secondary?: string): Paint<HockeyColorKey>;\nexport function colorUpdates(\n sport: SurfaceSport,\n primary: string,\n secondary?: string,\n): Record<string, string>;\nexport function colorUpdates(\n sport: SurfaceSport,\n primary: string,\n secondary?: string,\n): Record<string, string> {\n if (sport === \"basketball\") {\n const ink = onColor(primary);\n return {\n painted_area: primary,\n court_apron: primary,\n restricted_arc: ink,\n free_throw_circle_dash: ink,\n baseline_lower_defensive_box: ink,\n lane_lower_defensive_box: ink,\n } satisfies Paint<BasketballColorKey>;\n }\n if (sport === \"football\")\n return { offensive_endzone: primary, defensive_endzone: primary } satisfies Paint<FootballColorKey>;\n if (sport !== \"hockey\") return {};\n const ice = SURFACE_BASE.hockey;\n const readable = secondary !== undefined && contrast(primary, ice) < 3 && contrast(secondary, ice) >= 3;\n const accent = readable ? secondary : primary;\n return {\n center_line: accent,\n center_faceoff_circle: accent,\n center_faceoff_spot: accent,\n boards: primary,\n } satisfies Paint<HockeyColorKey>;\n}\n\ntype AnyRange =\n | BaseballDisplayRange\n | BasketballDisplayRange\n | CurlingDisplayRange\n | FootballDisplayRange\n | HockeyDisplayRange\n | LacrosseDisplayRange\n | SoccerDisplayRange\n | SoftballDisplayRange\n | TennisDisplayRange\n | VolleyballDisplayRange;\nexport interface SurfaceSceneOptions {\n /** A team of the league, painting the surface; only for keys that are sdv team leagues (otherwise `InputError`). */\n team?: Value;\n season?: SeasonInput;\n /** Overrides on top of the team painting, keyed by sporty colour key. */\n colorUpdates?: Paint<AnyColorKey>;\n rotation?: number;\n /** A sporty display range for the league's sport; one the sport does not know throws sporty's UnknownDisplayRangeError. */\n displayRange?: AnyRange;\n xlim?: readonly [number, number];\n ylim?: readonly [number, number];\n units?: \"ft\" | \"m\" | \"yd\" | \"in\" | \"cm\" | \"mm\";\n /** Sporty parameter overrides (intersected across sports so each sport's own keys type-check). */\n updates?: BaseballParamUpdates &\n BasketballParamUpdates &\n CurlingParamUpdates &\n FootballParamUpdates &\n HockeyParamUpdates &\n LacrosseParamUpdates &\n SoccerParamUpdates &\n SoftballParamUpdates &\n TennisParamUpdates &\n VolleyballParamUpdates;\n arcResolution?: number;\n xTrans?: number;\n yTrans?: number;\n}\n\nconst isTeamLeague = (v: string): v is League => (LEAGUES as readonly string[]).includes(v);\n\n/**\n * Build the sporty scene for an sdv surface key, painted in `team`'s colours. The league check and a `team` on a key\n * without team identities throw `InputError`; sporty's own errors (unknown displayRange/unit, bad arcResolution) escape\n * unwrapped.\n */\nexport function surfaceScene(league: League | (string & {}), o: SurfaceSceneOptions = {}): Scene {\n // own keys only: an inherited name (\"constructor\", \"__proto__\") must take the InputError path, not a TypeError\n const entry = Object.hasOwn(SURFACES, league) ? SURFACES[league] : undefined;\n if (!entry)\n throw new InputError(\n `no surface for league '${league}'; supported: ${Object.keys(SURFACES).sort().join(\", \")}`,\n );\n const [sport, key] = entry;\n const { team, season, colorUpdates: user, displayRange, updates, ...rest } = o;\n let paint: Record<string, string> = {};\n if (team !== undefined && team !== null) {\n if (!isTeamLeague(league))\n throw new InputError(`no team identities for '${league}': draw the plain surface without a team`);\n const at = season !== undefined ? { season } : {};\n const { primary, secondary } = teamColorPairSync(league, team, at);\n if (primary !== undefined) paint = colorUpdates(sport, primary, secondary);\n }\n const ranges = displayRanges(sport);\n if (displayRange !== undefined && !(ranges as readonly string[]).includes(displayRange))\n throw new UnknownDisplayRangeError(\n `unknown displayRange '${displayRange}'; expected one of: ${ranges.join(\", \")}`,\n );\n const merged = league === \"soccer\" ? { ...SOCCER_PITCH, ...updates } : updates;\n // ponytail: one generic call; the per-sport option types are SurfaceSceneOptions' unions, checked above at runtime\n return sportySurface(sport, key, {\n ...rest,\n colorUpdates: { ...paint, ...user },\n ...(displayRange === undefined ? {} : { displayRange }),\n ...(merged === undefined ? {} : { updates: merged }),\n } as never);\n}\n"]}