prographs 0.12.0 → 0.13.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 (269) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +6 -4
  3. package/dist/AutoGraph-PDPEAIXL.cjs +145 -0
  4. package/dist/GraphType.js +19 -0
  5. package/dist/autograph/chartIndex.js +521 -0
  6. package/dist/autograph/chartModules.js +2 -1
  7. package/dist/autograph/index.cjs +98 -93
  8. package/dist/catalog-DI4XZ46L.cjs +142 -0
  9. package/dist/catalog.js +2 -1
  10. package/dist/charts/biologycharts/BiologySamples.js +59 -0
  11. package/dist/charts/biologycharts/PunnettSquare.js +342 -0
  12. package/dist/charts/biologycharts/biologyEnums.js +22 -1
  13. package/dist/charts/biologycharts/index.js +5 -3
  14. package/dist/charts/doecharts/DoeSamples.js +78 -0
  15. package/dist/charts/doecharts/SipocDiagram.js +453 -0
  16. package/dist/charts/doecharts/index.js +4 -2
  17. package/dist/charts/fieldcharts/SpeciesAccumulationCurve.js +350 -0
  18. package/dist/charts/fieldcharts/fieldEnums.js +8 -1
  19. package/dist/charts/fieldcharts/index.js +5 -3
  20. package/dist/charts/signals/AntennaPatternChart.js +492 -0
  21. package/dist/charts/signals/SignalSamples.js +17 -0
  22. package/dist/charts/signals/index.js +5 -3
  23. package/dist/charts/softwarediagrams/ComponentDiagram.js +504 -0
  24. package/dist/charts/softwarediagrams/DeploymentDiagram.js +419 -0
  25. package/dist/charts/softwarediagrams/SoftwareSamples.js +283 -1
  26. package/dist/charts/softwarediagrams/index.js +7 -3
  27. package/dist/charts/softwarediagrams/softwareEnums.js +45 -1
  28. package/dist/charts/sportscharts/PowerDurationCurve.js +301 -0
  29. package/dist/charts/sportscharts/SportsSamples.js +102 -0
  30. package/dist/charts/sportscharts/TrainingLoadChart.js +325 -0
  31. package/dist/charts/sportscharts/index.js +6 -2
  32. package/dist/charts/strategycharts/BassDiffusionChart.js +362 -0
  33. package/dist/charts/strategycharts/BassModel.js +96 -0
  34. package/dist/charts/strategycharts/BurnRunwayChart.js +284 -0
  35. package/dist/charts/strategycharts/CapTableChart.js +366 -0
  36. package/dist/charts/strategycharts/KanbanBoard.js +324 -0
  37. package/dist/charts/strategycharts/OkrTree.js +339 -0
  38. package/dist/charts/strategycharts/StrategyPane.js +27 -0
  39. package/dist/charts/strategycharts/StrategySamples.js +251 -0
  40. package/dist/charts/strategycharts/index.js +15 -3
  41. package/dist/charts/threefields/BsfcMap3DChart.js +231 -0
  42. package/dist/charts/threefields/CompressorMap3DChart.js +217 -0
  43. package/dist/charts/threefields/FieldGrid.js +50 -0
  44. package/dist/charts/threefields/LossLandscape3DChart.js +201 -0
  45. package/dist/charts/threefields/MapSheet.js +77 -0
  46. package/dist/charts/threefields/TerrainRoute3DChart.js +201 -0
  47. package/dist/charts/threefields/TerrainRouteMath.js +40 -0
  48. package/dist/charts/threefields/ThreeFieldBase.js +117 -0
  49. package/dist/charts/threefields/ThreeFieldsSamples.js +80 -0
  50. package/dist/charts/threefields/WaferMap3DChart.js +218 -0
  51. package/dist/charts/threefields/index.js +19 -0
  52. package/dist/charts/threesurfaces/index.js +2 -2
  53. package/dist/charts/tradingcharts/KeltnerChannelChart.js +171 -0
  54. package/dist/charts/tradingcharts/TradingMath.js +20 -0
  55. package/dist/charts/tradingcharts/index.js +4 -2
  56. package/dist/{chunk-ZL6XDXMK.cjs → chunk-26PSLEP4.cjs} +8 -8
  57. package/dist/{chunk-W3US6EFP.cjs → chunk-2BO5DZUP.cjs} +12 -12
  58. package/dist/{chunk-5DP7OUSE.cjs → chunk-2GG5YYSC.cjs} +6 -6
  59. package/dist/{chunk-7FG4JSVO.cjs → chunk-2GL2VNJU.cjs} +253 -33
  60. package/dist/{chunk-LCWMRCLF.cjs → chunk-2PYOI7OY.cjs} +21 -21
  61. package/dist/{chunk-JFWJAEBD.cjs → chunk-3U4MCSKI.cjs} +4 -4
  62. package/dist/{chunk-CUPLHZRR.cjs → chunk-3ZMM3FSK.cjs} +4 -4
  63. package/dist/{chunk-L2AV62DP.cjs → chunk-4767WQJ7.cjs} +6 -6
  64. package/dist/{chunk-DA2EYIIP.cjs → chunk-4E7FSSBF.cjs} +1210 -168
  65. package/dist/{chunk-VS5LQEZB.cjs → chunk-526STI2S.cjs} +5 -5
  66. package/dist/{chunk-RXIMEK6C.cjs → chunk-55767YPI.cjs} +20 -20
  67. package/dist/{chunk-JXLSKIUV.cjs → chunk-5FBQOMMT.cjs} +26 -26
  68. package/dist/{chunk-27PZV5BR.cjs → chunk-5N4Z7MTS.cjs} +4 -4
  69. package/dist/{chunk-KEWCUIQA.cjs → chunk-5WEV6YWA.cjs} +22 -22
  70. package/dist/chunk-5XOVVC5X.cjs +3281 -0
  71. package/dist/{chunk-HK5J7Q2W.cjs → chunk-6HLXVWXU.cjs} +9 -9
  72. package/dist/{chunk-7JG47RW4.cjs → chunk-6LQT4WJ5.cjs} +25 -25
  73. package/dist/{chunk-OCVTI6X4.cjs → chunk-6YTWOUFD.cjs} +329 -36
  74. package/dist/{chunk-W7IQCAVN.cjs → chunk-7F6W6HKL.cjs} +11 -11
  75. package/dist/{chunk-F2DCJXDM.cjs → chunk-7L6KYU5A.cjs} +21 -21
  76. package/dist/{chunk-GTGR6LPR.cjs → chunk-A4GIN4FE.cjs} +17 -17
  77. package/dist/{chunk-B2CETSR6.cjs → chunk-A4US7SA7.cjs} +5 -5
  78. package/dist/{chunk-3DIF2YYW.cjs → chunk-AOXPBLPW.cjs} +10 -10
  79. package/dist/{chunk-7TTR4UF5.cjs → chunk-ATI45Z4M.cjs} +2 -2
  80. package/dist/{chunk-5BFCIX2V.cjs → chunk-CPPMO4IQ.cjs} +434 -148
  81. package/dist/{chunk-AYZZQ6AC.cjs → chunk-CZ5KGF6Q.cjs} +9 -9
  82. package/dist/{chunk-7THJ3ZBK.cjs → chunk-D4I35MCE.cjs} +2 -2
  83. package/dist/{chunk-MCPPFRLN.cjs → chunk-DCGAAN3Z.cjs} +2 -2
  84. package/dist/{chunk-VABL6CVX.cjs → chunk-DEY36N37.cjs} +21 -21
  85. package/dist/{chunk-RNCKGJCC.cjs → chunk-DXHXD3DK.cjs} +3 -3
  86. package/dist/{chunk-A56ZGMVZ.cjs → chunk-E7B45DBZ.cjs} +11 -11
  87. package/dist/{chunk-DOR6L4MT.cjs → chunk-EJC6EAC5.cjs} +18 -18
  88. package/dist/{chunk-UPGNM7MA.cjs → chunk-EULJOOMA.cjs} +11 -11
  89. package/dist/{chunk-G4AZL4GO.cjs → chunk-EYM6LEIF.cjs} +474 -70
  90. package/dist/{chunk-NJ4X6XGV.cjs → chunk-EZTYX2GH.cjs} +5 -5
  91. package/dist/chunk-FDD4UP73.cjs +521 -0
  92. package/dist/{chunk-WJ3VH2Q4.cjs → chunk-GEAIGM3J.cjs} +110 -615
  93. package/dist/{chunk-P3SBHF43.cjs → chunk-GRUYVXTS.cjs} +2 -2
  94. package/dist/{chunk-NX4Z5LMS.cjs → chunk-H3SZXND5.cjs} +5 -5
  95. package/dist/{chunk-EE4S4TOE.cjs → chunk-HS45TOFJ.cjs} +21 -21
  96. package/dist/chunk-INGOG6OV.cjs +899 -0
  97. package/dist/{chunk-UDKA6DGT.cjs → chunk-J3CDXZHF.cjs} +4 -4
  98. package/dist/{chunk-YO6G7TKI.cjs → chunk-JAU5ADEU.cjs} +11 -11
  99. package/dist/{chunk-22LBK4GA.cjs → chunk-JQEBSHX3.cjs} +4 -4
  100. package/dist/{chunk-RXX3U7VQ.cjs → chunk-KLXGLMFU.cjs} +10 -10
  101. package/dist/chunk-KVOX36J3.cjs +327 -0
  102. package/dist/chunk-L6BGNHFL.cjs +139 -0
  103. package/dist/{chunk-GMER35L3.cjs → chunk-L7TB7PU5.cjs} +20 -20
  104. package/dist/{chunk-AFXYNBL2.cjs → chunk-LBTRYEM2.cjs} +4 -4
  105. package/dist/{chunk-WYYCKIOD.cjs → chunk-LLULNJSP.cjs} +11 -11
  106. package/dist/{chunk-J27XOSLP.cjs → chunk-LSO46AFV.cjs} +8 -8
  107. package/dist/{chunk-5XJO45ES.cjs → chunk-LZ2KJ7ZX.cjs} +11 -11
  108. package/dist/chunk-M4IQ5LIZ.cjs +422 -0
  109. package/dist/{chunk-Y2KIUKJF.cjs → chunk-MPDHDKYZ.cjs} +11 -11
  110. package/dist/{chunk-4EMPKRZU.cjs → chunk-MRQ42ZJE.cjs} +3 -3
  111. package/dist/{chunk-EU5D2MF4.cjs → chunk-MYV4KZWP.cjs} +9 -9
  112. package/dist/{chunk-XD7KN4UN.cjs → chunk-MZXVLC24.cjs} +6 -6
  113. package/dist/{chunk-PPSONARU.cjs → chunk-NLBVDFIR.cjs} +41 -2
  114. package/dist/{chunk-L3PEGMGM.cjs → chunk-NY3TBZY4.cjs} +33 -33
  115. package/dist/{chunk-6YNYXXB6.cjs → chunk-OGVVSFAR.cjs} +3 -3
  116. package/dist/{chunk-MLV7QLB6.cjs → chunk-OMTQIQMN.cjs} +6 -6
  117. package/dist/{chunk-BEEOSNK7.cjs → chunk-PEJJ6TXJ.cjs} +15 -144
  118. package/dist/{chunk-SOKOWUF5.cjs → chunk-PPGWHIU7.cjs} +2 -2
  119. package/dist/{chunk-IELWOM2J.cjs → chunk-PPO6SDAN.cjs} +6 -6
  120. package/dist/{chunk-6JTZZCSL.cjs → chunk-PUMKX5F2.cjs} +3 -3
  121. package/dist/{chunk-RFOXFY2U.cjs → chunk-PXBYWCNB.cjs} +190 -799
  122. package/dist/{chunk-3BYXOISI.cjs → chunk-Q3HB3IX6.cjs} +4 -4
  123. package/dist/{chunk-RXCOVONX.cjs → chunk-RBMUOIXE.cjs} +289 -34
  124. package/dist/{chunk-MSBNHCSE.cjs → chunk-RJHGCUUD.cjs} +6 -6
  125. package/dist/{chunk-I6VG7F6Z.cjs → chunk-RSONDMYW.cjs} +708 -141
  126. package/dist/{chunk-GZDNPHMT.cjs → chunk-SHMPFCUE.cjs} +19 -19
  127. package/dist/{chunk-ZIBVCOW6.cjs → chunk-SN4FCXFC.cjs} +19 -19
  128. package/dist/{chunk-7KM52NMN.cjs → chunk-SN5T7WYO.cjs} +2 -2
  129. package/dist/{chunk-7MSZR65Z.cjs → chunk-SQJZGVDR.cjs} +7 -7
  130. package/dist/chunk-SYABFMD7.cjs +633 -0
  131. package/dist/{chunk-2RRFEYFH.cjs → chunk-TICB3MAC.cjs} +16 -16
  132. package/dist/{chunk-AOOKHUV5.cjs → chunk-U7Z7XYR2.cjs} +5 -5
  133. package/dist/{chunk-JEWQAXVG.cjs → chunk-UA2THQFV.cjs} +6 -6
  134. package/dist/{chunk-LHZPAHU3.cjs → chunk-VIK4L2YF.cjs} +112 -521
  135. package/dist/{chunk-4YWMAQ4J.cjs → chunk-VM2Y6BDY.cjs} +4 -4
  136. package/dist/{chunk-IRRKE2ZE.cjs → chunk-VMS3KWYI.cjs} +21 -21
  137. package/dist/{chunk-4SLARW6F.cjs → chunk-VU5NUD46.cjs} +17 -17
  138. package/dist/{chunk-XHY6TVYG.cjs → chunk-VV5CVOF7.cjs} +13 -13
  139. package/dist/{chunk-CCIBPGPZ.cjs → chunk-VYSAWPSS.cjs} +57 -57
  140. package/dist/{chunk-TTNEMQ2A.cjs → chunk-W7YRWEWQ.cjs} +22 -22
  141. package/dist/{chunk-C7MUOGEW.cjs → chunk-X7R5SY62.cjs} +6 -6
  142. package/dist/{chunk-ILR5KBMB.cjs → chunk-XOK3KTSS.cjs} +6 -6
  143. package/dist/{chunk-2CZM2I3T.cjs → chunk-XUIX45VU.cjs} +19 -19
  144. package/dist/{chunk-TGRMPS3A.cjs → chunk-XWH46PVJ.cjs} +165 -43
  145. package/dist/{chunk-WQYXXECR.cjs → chunk-Y5XVMK3K.cjs} +6 -6
  146. package/dist/{chunk-AK4TX2WG.cjs → chunk-YCNKEDTG.cjs} +13 -13
  147. package/dist/{chunk-PJJB24DU.cjs → chunk-YEF7SE3X.cjs} +20 -20
  148. package/dist/{chunk-RVLV4XW6.cjs → chunk-YMTVPMU3.cjs} +22 -22
  149. package/dist/data/index.cjs +2 -2
  150. package/dist/entries/autograph-lazy.cjs +2 -2
  151. package/dist/entries/charts/acoustictransport.cjs +3 -3
  152. package/dist/entries/charts/analysischarts.cjs +3 -3
  153. package/dist/entries/charts/astrocharts.cjs +3 -3
  154. package/dist/entries/charts/bars.cjs +3 -3
  155. package/dist/entries/charts/bayesiancharts.cjs +3 -3
  156. package/dist/entries/charts/biocharts.cjs +3 -3
  157. package/dist/entries/charts/biologycharts.cjs +11 -3
  158. package/dist/entries/charts/biologycharts.d.ts +1 -1
  159. package/dist/entries/charts/biologycharts.js +3 -2
  160. package/dist/entries/charts/business.cjs +3 -3
  161. package/dist/entries/charts/carecharts.cjs +3 -3
  162. package/dist/entries/charts/chemistrycharts.cjs +3 -3
  163. package/dist/entries/charts/civicscharts.cjs +3 -3
  164. package/dist/entries/charts/clinicalcharts.cjs +3 -3
  165. package/dist/entries/charts/comparison.cjs +3 -3
  166. package/dist/entries/charts/demography.cjs +3 -3
  167. package/dist/entries/charts/density.cjs +3 -3
  168. package/dist/entries/charts/diagrams.cjs +3 -3
  169. package/dist/entries/charts/distribution.cjs +3 -3
  170. package/dist/entries/charts/doecharts.cjs +13 -3
  171. package/dist/entries/charts/doecharts.d.ts +1 -1
  172. package/dist/entries/charts/doecharts.js +2 -1
  173. package/dist/entries/charts/earthscience.cjs +3 -3
  174. package/dist/entries/charts/economicscharts.cjs +3 -3
  175. package/dist/entries/charts/energycharts.cjs +3 -3
  176. package/dist/entries/charts/engineering.cjs +3 -3
  177. package/dist/entries/charts/fieldcharts.cjs +7 -3
  178. package/dist/entries/charts/fieldcharts.d.ts +1 -1
  179. package/dist/entries/charts/fieldcharts.js +3 -2
  180. package/dist/entries/charts/financial.cjs +3 -3
  181. package/dist/entries/charts/flow.cjs +3 -3
  182. package/dist/entries/charts/frameworks.cjs +3 -3
  183. package/dist/entries/charts/genomics.cjs +3 -3
  184. package/dist/entries/charts/geoflows.cjs +3 -3
  185. package/dist/entries/charts/geomaps.cjs +3 -3
  186. package/dist/entries/charts/geosciencecharts.cjs +3 -3
  187. package/dist/entries/charts/hierarchy.cjs +3 -3
  188. package/dist/entries/charts/indicators.cjs +3 -3
  189. package/dist/entries/charts/inferencecharts.cjs +3 -3
  190. package/dist/entries/charts/layoutcharts.cjs +3 -3
  191. package/dist/entries/charts/lifescience.cjs +4 -4
  192. package/dist/entries/charts/linesareas.cjs +3 -3
  193. package/dist/entries/charts/logisticscharts.cjs +3 -3
  194. package/dist/entries/charts/machinecharts.cjs +7 -3
  195. package/dist/entries/charts/machinecharts.d.ts +1 -1
  196. package/dist/entries/charts/machinecharts.js +2 -1
  197. package/dist/entries/charts/massive.cjs +3 -3
  198. package/dist/entries/charts/mathematical.cjs +3 -3
  199. package/dist/entries/charts/matrix.cjs +3 -3
  200. package/dist/entries/charts/medicalcharts.cjs +4 -4
  201. package/dist/entries/charts/mlcharts.cjs +4 -4
  202. package/dist/entries/charts/modelcharts.cjs +6 -5
  203. package/dist/entries/charts/multivariate.cjs +3 -3
  204. package/dist/entries/charts/musiccharts.cjs +3 -3
  205. package/dist/entries/charts/network.cjs +3 -3
  206. package/dist/entries/charts/physicscharts.cjs +3 -3
  207. package/dist/entries/charts/pictorial.cjs +4 -4
  208. package/dist/entries/charts/portfoliocharts.cjs +3 -3
  209. package/dist/entries/charts/productcharts.cjs +3 -3
  210. package/dist/entries/charts/proportion.cjs +3 -3
  211. package/dist/entries/charts/qualitycharts.cjs +3 -3
  212. package/dist/entries/charts/radial.cjs +3 -3
  213. package/dist/entries/charts/reliabilitycharts.cjs +5 -3
  214. package/dist/entries/charts/scatter.cjs +3 -3
  215. package/dist/entries/charts/scientific.cjs +3 -3
  216. package/dist/entries/charts/seriescharts.cjs +3 -3
  217. package/dist/entries/charts/signals.cjs +7 -3
  218. package/dist/entries/charts/signals.d.ts +1 -1
  219. package/dist/entries/charts/signals.js +2 -1
  220. package/dist/entries/charts/softwarediagrams.cjs +21 -3
  221. package/dist/entries/charts/softwarediagrams.d.ts +1 -1
  222. package/dist/entries/charts/softwarediagrams.js +4 -2
  223. package/dist/entries/charts/sportscharts.cjs +13 -3
  224. package/dist/entries/charts/sportscharts.d.ts +1 -1
  225. package/dist/entries/charts/sportscharts.js +3 -1
  226. package/dist/entries/charts/statistics.cjs +6 -6
  227. package/dist/entries/charts/strategycharts.cjs +30 -3
  228. package/dist/entries/charts/strategycharts.d.ts +1 -1
  229. package/dist/entries/charts/strategycharts.js +6 -1
  230. package/dist/entries/charts/structure.cjs +3 -3
  231. package/dist/entries/charts/surveycharts.cjs +3 -3
  232. package/dist/entries/charts/systemscharts.cjs +3 -3
  233. package/dist/entries/charts/textcharts.cjs +5 -5
  234. package/dist/entries/charts/thematicmaps.cjs +4 -4
  235. package/dist/entries/charts/threebars.cjs +3 -3
  236. package/dist/entries/charts/threefields.cjs +53 -0
  237. package/dist/entries/charts/threefields.d.ts +1 -0
  238. package/dist/entries/charts/threefields.js +6 -0
  239. package/dist/entries/charts/threeglobe.cjs +3 -3
  240. package/dist/entries/charts/threenetwork.cjs +3 -3
  241. package/dist/entries/charts/threestrata.cjs +3 -3
  242. package/dist/entries/charts/threesurfaces.cjs +7 -3
  243. package/dist/entries/charts/threesurfaces.d.ts +1 -1
  244. package/dist/entries/charts/threesurfaces.js +2 -1
  245. package/dist/entries/charts/threevolume.cjs +4 -4
  246. package/dist/entries/charts/timeline.cjs +3 -3
  247. package/dist/entries/charts/tracecharts.cjs +3 -3
  248. package/dist/entries/charts/trackscharts.cjs +3 -3
  249. package/dist/entries/charts/tradingcharts.cjs +6 -4
  250. package/dist/entries/charts/tradingcharts.d.ts +1 -1
  251. package/dist/entries/charts/tradingcharts.js +2 -1
  252. package/dist/entries/three.cjs +60 -20
  253. package/dist/entries/three.d.ts +1 -1
  254. package/dist/entries/three.js +7 -1
  255. package/dist/index.cjs +258 -97
  256. package/dist/index.d.cts +1953 -10
  257. package/dist/index.d.ts +1953 -10
  258. package/dist/index.js +26 -5
  259. package/dist/page/index.cjs +2 -2
  260. package/dist/react/components.js +58 -1
  261. package/dist/react/index.cjs +135 -92
  262. package/dist/react/index.d.ts +1 -1
  263. package/dist/react/index.js +2 -2
  264. package/package.json +1 -1
  265. package/dist/AutoGraph-XLBJQDRB.cjs +0 -140
  266. package/dist/catalog-O7XGDD2H.cjs +0 -137
  267. package/dist/chunk-77K2HTRC.cjs +0 -3220
  268. package/dist/chunk-XEK47TVD.cjs +0 -323
  269. /package/dist/{chunk-UMEKIIHJ.cjs → chunk-LNWTC72Y.cjs} +0 -0
@@ -22,7 +22,7 @@ var _chunkPY4R3IFFcjs = require('./chunk-PY4R3IFF.cjs');
22
22
  var _chunk35CT4Q2Ecjs = require('./chunk-35CT4Q2E.cjs');
23
23
 
24
24
 
25
- var _chunkUMEKIIHJcjs = require('./chunk-UMEKIIHJ.cjs');
25
+ var _chunkLNWTC72Ycjs = require('./chunk-LNWTC72Y.cjs');
26
26
 
27
27
  // src/charts/surveycharts/IrtMath.ts
28
28
  var IrtModel = /* @__PURE__ */ ((IrtModel2) => {
@@ -137,7 +137,7 @@ var STATEMENTS = [
137
137
  var SurveySamples = class {
138
138
  /** `{ item, difficulty, discrimination, guessing }`, one row per calibrated item of a maths test. */
139
139
  static testItems(seed) {
140
- const { n } = _chunkUMEKIIHJcjs.SampleData.rng(seed);
140
+ const { n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
141
141
  return ITEMS.map(([item, a, b, c]) => ({
142
142
  item,
143
143
  difficulty: +(b + n() * 0.08).toFixed(2),
@@ -147,7 +147,7 @@ var SurveySamples = class {
147
147
  }
148
148
  /** `{ role, label, measure, group }`, a Rasch calibration: person rows have a null group, and item rows name a strand. */
149
149
  static calibration(seed) {
150
- const { n, u } = _chunkUMEKIIHJcjs.SampleData.rng(seed), { mean: mean3, sd, low, high } = ABILITY;
150
+ const { n, u } = _chunkLNWTC72Ycjs.SampleData.rng(seed), { mean: mean3, sd, low, high } = ABILITY;
151
151
  const persons = Array.from({ length: PERSONS }, (_, i) => ({
152
152
  role: "person",
153
153
  label: `P${i + 1}`,
@@ -164,7 +164,7 @@ var SurveySamples = class {
164
164
  }
165
165
  /** `{ concept, left, right, value }`, one row per rating on a 1 to 7 scale. */
166
166
  static ratings(seed) {
167
- const { n } = _chunkUMEKIIHJcjs.SampleData.rng(seed);
167
+ const { n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
168
168
  return CONCEPTS.flatMap(([concept, means]) => POLES.flatMap(([left, right], pair) => Array.from({ length: RESPONDENTS }, () => ({
169
169
  concept,
170
170
  left,
@@ -174,7 +174,7 @@ var SurveySamples = class {
174
174
  }
175
175
  /** `{ item, agree, neutral, disagree }`, response counts per statement of a staff survey. */
176
176
  static agreement(seed) {
177
- const { n } = _chunkUMEKIIHJcjs.SampleData.rng(seed);
177
+ const { n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
178
178
  return STATEMENTS.map(([item, agreeing, disagreeing, base]) => {
179
179
  const agree = Math.round(base * (agreeing + n() * 0.015)), disagree = Math.round(base * (disagreeing + n() * 0.015));
180
180
  return { item, agree, neutral: Math.max(0, base - agree - disagree), disagree };
@@ -0,0 +1,521 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;
2
+
3
+ var _chunkXX2YTCORcjs = require('./chunk-XX2YTCOR.cjs');
4
+
5
+
6
+ var _chunkPY4R3IFFcjs = require('./chunk-PY4R3IFF.cjs');
7
+
8
+
9
+ var _chunkLNWTC72Ycjs = require('./chunk-LNWTC72Y.cjs');
10
+
11
+ // src/charts/machinecharts/MachineMesh.ts
12
+ var _d3 = require('d3');
13
+ var lerp = (a, b, t) => ({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t, z: a.z + (b.z - a.z) * t });
14
+ var spline = (a, b, c, d, t) => 0.5 * (2 * b + (c - a) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (3 * b - a - 3 * c + d) * t ** 3);
15
+ var MachineMesh = class {
16
+ /** `nodes[row][column]`: rows run across the lines, columns along them. */
17
+
18
+ /** `lines` in map order, each from one edge of the map to the other. Lines with fewer than two points are left out. */
19
+ constructor(lines, along = 24, between = 5) {
20
+ const usable = lines.filter((line2) => line2.length > 1), all = usable.flat();
21
+ const [x0 = 0, x1 = 1] = _d3.extent.call(void 0, all, (node) => node.x), [y0 = 0, y1 = 1] = _d3.extent.call(void 0, all, (node) => node.y);
22
+ const sx = x1 - x0 || 1, sy = y1 - y0 || 1;
23
+ const even = usable.map((line2) => {
24
+ const reach = [0];
25
+ for (let i = 1; i < line2.length; i++) reach.push(reach[i - 1] + Math.hypot((line2[i].x - line2[i - 1].x) / sx, (line2[i].y - line2[i - 1].y) / sy));
26
+ const total = reach[reach.length - 1] || 1;
27
+ let at = 0;
28
+ return Array.from({ length: along }, (_, step) => {
29
+ const want = step / (along - 1) * total;
30
+ while (at < line2.length - 2 && reach[at + 1] < want) at++;
31
+ return lerp(line2[at], line2[at + 1], Math.max(0, Math.min(1, (want - reach[at]) / (reach[at + 1] - reach[at] || 1))));
32
+ });
33
+ });
34
+ const last = even.length - 1;
35
+ this.nodes = last < 1 ? [] : Array.from({ length: last * between + 1 }, (_, row) => {
36
+ const line2 = Math.min(last - 1, Math.floor(row / between)), t = row / between - line2;
37
+ const [a, b, c, d] = [-1, 0, 1, 2].map((shift) => even[Math.max(0, Math.min(last, line2 + shift))]);
38
+ return b.map((_2, i) => ({ x: spline(a[i].x, b[i].x, c[i].x, d[i].x, t), y: spline(a[i].y, b[i].y, c[i].y, d[i].y, t), z: spline(a[i].z, b[i].z, c[i].z, d[i].z, t) }));
39
+ });
40
+ }
41
+ get rows() {
42
+ return this.nodes.length;
43
+ }
44
+ get columns() {
45
+ return _nullishCoalesce(_optionalChain([this, 'access', _3 => _3.nodes, 'access', _4 => _4[0], 'optionalAccess', _5 => _5.length]), () => ( 0));
46
+ }
47
+ /** The contoured quantity, row by row, as d3's contour generator takes it. */
48
+ get values() {
49
+ return this.nodes.flatMap((row) => row.map((node) => node.z));
50
+ }
51
+ /** Where fractional mesh coordinates sit on the map. */
52
+ at(column, row) {
53
+ const i = Math.max(0, Math.min(this.columns - 2, Math.floor(column))), j = Math.max(0, Math.min(this.rows - 2, Math.floor(row)));
54
+ const top = lerp(this.nodes[j][i], this.nodes[j][i + 1], column - i), bottom = lerp(this.nodes[j + 1][i], this.nodes[j + 1][i + 1], column - i);
55
+ const { x, y } = lerp(top, bottom, row - j);
56
+ return [x, y];
57
+ }
58
+ /** Round contour levels strictly inside the range of the mesh. */
59
+ levels(count = 6) {
60
+ const [low, high] = _d3.extent.call(void 0, this.values);
61
+ return low === void 0 || high === void 0 ? [] : _d3.ticks.call(void 0, low, high, count).filter((level) => level > low && level < high);
62
+ }
63
+ };
64
+
65
+ // src/charts/machinecharts/MachineChart.ts
66
+
67
+ var CHAR = 6.2;
68
+ var SIZE = 11;
69
+ var MachineChart = class extends _chunkXX2YTCORcjs.CartesianChart {
70
+ /** A cell as a finite number, or null for blanks, text and dates. */
71
+ static number(cell) {
72
+ if (typeof cell === "string" && !cell.trim()) return null;
73
+ const value = typeof cell === "number" || typeof cell === "string" ? Number(cell) : NaN;
74
+ return Number.isFinite(value) ? value : null;
75
+ }
76
+ /** Short number for labels and tooltips. */
77
+ static short(value, digits = 3) {
78
+ return String(+value.toPrecision(digits));
79
+ }
80
+ /** Axis titles that depend on the options. A title the caller set wins. */
81
+ axisTitles() {
82
+ return {};
83
+ }
84
+ paint() {
85
+ const { xLabel, yLabel } = this.options, titles = this.axisTitles();
86
+ this.options.xLabel = _nullishCoalesce(xLabel, () => ( titles.x));
87
+ this.options.yLabel = _nullishCoalesce(yLabel, () => ( titles.y));
88
+ try {
89
+ super.paint();
90
+ } finally {
91
+ Object.assign(this.options, { xLabel, yLabel });
92
+ }
93
+ }
94
+ get rows() {
95
+ const { data } = this.options;
96
+ return Array.isArray(data) ? data.filter((row) => row !== null && typeof row === "object") : [];
97
+ }
98
+ /** Padded extent that survives no values and one value. `zero` keeps 0 in view. */
99
+ span(values, pad = 0.05, zero = false) {
100
+ let low = _nullishCoalesce(_d3.min.call(void 0, values), () => ( 0)), high = _nullishCoalesce(_d3.max.call(void 0, values), () => ( 1));
101
+ if (zero) {
102
+ low = Math.min(0, low);
103
+ high = Math.max(0, high);
104
+ }
105
+ if (low === high) {
106
+ const half = Math.abs(low) * 0.5 || 1;
107
+ return [zero && low >= 0 ? 0 : low - half, high + half];
108
+ }
109
+ const room = (high - low) * pad;
110
+ return [zero && low === 0 ? 0 : low - room, zero && high === 0 ? 0 : high + room];
111
+ }
112
+ /** A data point in plot pixels. */
113
+ place({ x, y }, [px, py]) {
114
+ return [_nullishCoalesce(x(px), () => ( NaN)), _nullishCoalesce(y(py), () => ( NaN))];
115
+ }
116
+ curves(ctx, axes, name, list) {
117
+ const path = _d3.line.call(void 0, ).defined((point) => Number.isFinite(point[0]) && Number.isFinite(point[1]));
118
+ const shape = (d) => _nullishCoalesce(path.curve(_nullishCoalesce(d.curve, () => ( _chunkPY4R3IFFcjs.Scales.curve())))(d.points.map((point) => this.place(axes, point))), () => ( ""));
119
+ const marks = ctx.marks(name, "path", list, (d) => d.key).attr("fill", "none").attr("stroke", (d) => d.color).attr("stroke-width", (d) => _nullishCoalesce(d.width, () => ( 2))).attr("stroke-linejoin", "round").attr("stroke-linecap", "round").attr("stroke-dasharray", (d) => _nullishCoalesce(d.dash, () => ( null)));
120
+ return ctx.set(marks, { d: shape });
121
+ }
122
+ /** Ringed dots with a tooltip each. */
123
+ dots(ctx, axes, name, items, at, fill, tip, radius = 4) {
124
+ const spot = (d) => this.place(axes, at(d));
125
+ const shown = items.filter((item) => spot(item).every(Number.isFinite));
126
+ const marks = ctx.marks(name, "circle", shown).attr("fill", fill).attr("stroke", ctx.theme.surface).attr("stroke-width", radius < 3 ? 1 : 2);
127
+ ctx.set(marks, { cx: (d) => spot(d)[0], cy: (d) => spot(d)[1], r: radius }, { r: 0 });
128
+ return ctx.hover(marks, tip);
129
+ }
130
+ /** Halo-backed labels kept inside the plot. A label that would overlap an earlier one, or cannot fit, is dropped. */
131
+ notes(ctx, name, notes) {
132
+ const { width, height } = ctx.plot;
133
+ const taken = [];
134
+ const kept = notes.flatMap((note) => {
135
+ const wide = note.text.length * CHAR;
136
+ if (!Number.isFinite(note.x) || !Number.isFinite(note.y) || wide > width || note.y < -SIZE || note.y > height + SIZE || note.x < -wide || note.x > width + wide) return [];
137
+ const anchor = _nullishCoalesce(note.anchor, () => ( "start")), offset = anchor === "start" ? 0 : anchor === "middle" ? wide / 2 : wide;
138
+ const x = Math.max(offset, Math.min(width - wide + offset, note.x)), y = Math.max(SIZE, Math.min(height - 3, note.y));
139
+ const box = [x - offset - 3, y - SIZE, x - offset + wide + 3, y + 3];
140
+ if (taken.some((other) => box[0] < other[2] && box[2] > other[0] && box[1] < other[3] && box[3] > other[1])) return [];
141
+ taken.push(box);
142
+ return [{ ...note, x, y, anchor }];
143
+ });
144
+ const tones = { ink: ctx.theme.ink, secondary: ctx.theme.inkSecondary, muted: ctx.theme.inkMuted };
145
+ ctx.marks(name, "text", kept, (d) => d.key).attr("x", (d) => d.x).attr("y", (d) => d.y).attr("text-anchor", (d) => d.anchor).attr("font-size", SIZE).attr("font-family", ctx.theme.fontFamily).attr("fill", (d) => d.over ? ctx.palette.inkOn(d.over) : tones[_nullishCoalesce(d.tone, () => ( "secondary"))]).attr("stroke", (d) => _nullishCoalesce(d.over, () => ( ctx.theme.surface))).attr("stroke-width", 3).attr("paint-order", "stroke").text((d) => d.text);
146
+ }
147
+ };
148
+
149
+ // src/charts/machinecharts/GasCycleMath.ts
150
+
151
+ var CLOSE = 1e-3;
152
+ var positive = (values) => values.every((value) => Number.isFinite(value) && value > 0);
153
+ var GasCycleMath = class _GasCycleMath {
154
+ /** Isentropic compression by volume `ratio`, heat added at constant volume up to `peak` K, isentropic expansion, heat rejected at constant volume. */
155
+ static otto(gas, ratio, peak) {
156
+ const { gamma, inletPressure: p1, inletTemperature: t1 } = gas;
157
+ const t2 = t1 * ratio ** (gamma - 1), p2 = p1 * ratio ** gamma, p3 = p2 * peak / t2;
158
+ return _GasCycleMath.ideal(gas, [[p1, t1], [p2, t2], [p3, peak], [p3 / ratio ** gamma, peak / ratio ** (gamma - 1)]]);
159
+ }
160
+ /** Isentropic compression by volume `ratio`, heat added at constant pressure while the volume grows by `cutoff`, isentropic expansion, heat rejected at constant volume. */
161
+ static diesel(gas, ratio, cutoff) {
162
+ const { gamma, inletPressure: p1, inletTemperature: t1 } = gas;
163
+ const t2 = t1 * ratio ** (gamma - 1), p2 = p1 * ratio ** gamma, t3 = t2 * cutoff, expansion = ratio / cutoff;
164
+ return _GasCycleMath.ideal(gas, [[p1, t1], [p2, t2], [p2, t3], [p2 / expansion ** gamma, t3 / expansion ** (gamma - 1)]]);
165
+ }
166
+ /** Isentropic compression by pressure `ratio`, heat added at constant pressure up to `peak` K, isentropic expansion, heat rejected at constant pressure. */
167
+ static brayton(gas, ratio, peak) {
168
+ const { gamma, inletPressure: p1, inletTemperature: t1 } = gas, rise = ratio ** ((gamma - 1) / gamma);
169
+ return _GasCycleMath.ideal(gas, [[p1, t1], [p1 * ratio, t1 * rise], [p1 * ratio, peak], [p1, peak / rise]]);
170
+ }
171
+ /** States at `[pressure, temperature]` corners, numbered in order. None when a number is not above zero or `gamma` is not above 1. */
172
+ static ideal(gas, corners) {
173
+ if (!(gas.gamma > 1) || !positive([gas.gasConstant, ...corners.flat()])) return [];
174
+ return _GasCycleMath.entropies(corners.map(([pressure, temperature], i) => ({ label: `${i + 1}`, pressure, temperature, volume: gas.gasConstant * temperature / pressure })), gas);
175
+ }
176
+ /**
177
+ * States read from rows, in row order. Each needs a pressure and a temperature above zero; a volume the row
178
+ * leaves out comes from `Pv = RT`. A label that repeats, as when the first state closes the list, counts once.
179
+ */
180
+ static states(rows, columns, gas) {
181
+ const found = /* @__PURE__ */ new Map();
182
+ rows.forEach((row, i) => {
183
+ const [pressure, temperature, given] = [columns.pressure, columns.temperature, columns.volume].map((column) => _nullishCoalesce(MachineChart.number(row[column]), () => ( NaN)));
184
+ const label = String(_nullishCoalesce(row[columns.label], () => ( i + 1))), volume = given > 0 ? given : gas.gasConstant * temperature / pressure;
185
+ if (positive([pressure, temperature, volume]) && !found.has(label)) found.set(label, { label, pressure, temperature, volume });
186
+ });
187
+ return _GasCycleMath.entropies([...found.values()], gas);
188
+ }
189
+ /** `s = cv ln(T / T₁) + R ln(v / v₁)`, so the first state sits at zero. A gas whose `gamma` is not above 1 has no states. */
190
+ static entropies(states, { gamma, gasConstant }) {
191
+ const cv = gasConstant / (gamma - 1), [first] = states;
192
+ return states.map((state) => ({ ...state, entropy: cv * Math.log(state.temperature / first.temperature) + gasConstant * Math.log(state.volume / first.volume) })).filter((state) => Number.isFinite(state.entropy));
193
+ }
194
+ /**
195
+ * The legs of the closed cycle, the last one returning to the first state. Along a polytrope `ln P` is linear in `ln v`
196
+ * and `s` in `ln T`, which gives the work `∫P dv` and the heat `∫T ds` in closed form.
197
+ */
198
+ static processes(states) {
199
+ if (states.length < 2) return [];
200
+ return states.map((from, i) => {
201
+ const to = states[(i + 1) % states.length];
202
+ const dv = Math.log(to.volume / from.volume), dp = Math.log(to.pressure / from.pressure), dt = Math.log(to.temperature / from.temperature);
203
+ const heat = (to.entropy - from.entropy) * (Math.abs(dt) < 1e-9 ? from.temperature : (to.temperature - from.temperature) / dt);
204
+ const work = Math.abs(dv + dp) < 1e-9 ? from.pressure * from.volume * dv : dv * (to.pressure * to.volume - from.pressure * from.volume) / (dv + dp);
205
+ const name = Math.abs(dv) < CLOSE ? "Constant volume" : Math.abs(dp) < CLOSE ? "Constant pressure" : Math.abs(dt) < CLOSE ? "Isothermal" : Math.abs(heat) < CLOSE * Math.abs(work) ? "Isentropic" : `Polytropic, n = ${(-dp / dv).toFixed(2)}`;
206
+ return { from, to, name, heat, work };
207
+ });
208
+ }
209
+ /** Heat in is the heat of every leg that takes some in, heat out of every leg that gives some up, and the efficiency is `1 - out / in`. */
210
+ static totals(processes) {
211
+ const heatIn = _d3.sum.call(void 0, processes, (leg) => Math.max(0, leg.heat)), heatOut = _d3.sum.call(void 0, processes, (leg) => Math.max(0, -leg.heat));
212
+ return { heatIn, heatOut, work: _d3.sum.call(void 0, processes, (leg) => leg.work), efficiency: heatIn > heatOut ? 1 - heatOut / heatIn : null };
213
+ }
214
+ /** Points along a leg between two plotted corners. `y` always changes geometrically; `x` does too on P-V (`geometric`), and linearly on T-s. */
215
+ static leg(from, to, geometric, steps = 24) {
216
+ return Array.from({ length: steps + 1 }, (_, i) => {
217
+ const t = i / steps;
218
+ return [geometric ? from[0] * (to[0] / from[0]) ** t : from[0] + (to[0] - from[0]) * t, from[1] * (to[1] / from[1]) ** t];
219
+ });
220
+ }
221
+ };
222
+
223
+ // src/charts/machinecharts/MachineSamples.ts
224
+ var round = (value, digits = 2) => +value.toFixed(digits);
225
+ var MATERIALS = [
226
+ ["Foams", "Polymer foam, low density", 0.035, 2e-3],
227
+ ["Foams", "Polymer foam, rigid", 0.12, 0.08],
228
+ ["Foams", "Metal foam", 0.35, 0.6],
229
+ ["Foams", "Ceramic foam", 0.5, 1.6],
230
+ ["Elastomers", "Natural rubber", 0.93, 2e-3],
231
+ ["Elastomers", "Butyl rubber", 0.92, 15e-4],
232
+ ["Elastomers", "Silicone elastomer", 1.25, 0.012],
233
+ ["Elastomers", "Polyurethane elastomer", 1.15, 0.03],
234
+ ["Natural materials", "Cork", 0.18, 0.03],
235
+ ["Natural materials", "Balsa", 0.16, 3.2],
236
+ ["Natural materials", "Pine", 0.5, 9.5],
237
+ ["Natural materials", "Oak", 0.75, 12],
238
+ ["Natural materials", "Bamboo", 0.7, 17],
239
+ ["Polymers", "Polyethylene", 0.95, 0.75],
240
+ ["Polymers", "Polypropylene", 0.9, 1.4],
241
+ ["Polymers", "Polyamide", 1.14, 2.8],
242
+ ["Polymers", "Polycarbonate", 1.2, 2.3],
243
+ ["Polymers", "Epoxy", 1.25, 3.2],
244
+ ["Composites", "Glass fibre laminate", 1.9, 22],
245
+ ["Composites", "Carbon fibre laminate", 1.55, 110],
246
+ ["Composites", "Aramid laminate", 1.38, 60],
247
+ ["Composites", "Metal matrix composite", 2.8, 95],
248
+ ["Metals", "Magnesium alloys", 1.8, 44],
249
+ ["Metals", "Aluminium alloys", 2.7, 71],
250
+ ["Metals", "Titanium alloys", 4.5, 112],
251
+ ["Metals", "Steels", 7.85, 205],
252
+ ["Metals", "Nickel alloys", 8.6, 200],
253
+ ["Metals", "Copper alloys", 8.7, 125],
254
+ ["Metals", "Lead alloys", 11.2, 15],
255
+ ["Metals", "Tungsten alloys", 18.5, 360],
256
+ ["Ceramics", "Concrete", 2.4, 28],
257
+ ["Ceramics", "Soda-lime glass", 2.5, 70],
258
+ ["Ceramics", "Alumina", 3.9, 370],
259
+ ["Ceramics", "Silicon carbide", 3.15, 420],
260
+ ["Ceramics", "Tungsten carbide", 15.6, 640]
261
+ ];
262
+ var POLARS = [
263
+ ["Clean", 0.22, 0.021, 0.043, 1.6],
264
+ ["Take-off flaps", 0.62, 0.044, 0.049, 2.05],
265
+ ["Landing flaps", 1.02, 0.086, 0.056, 2.5]
266
+ ];
267
+ var HILLS = [[18, 190, 5], [36, 640, 7.5], [58, 260, 4], [74, 1020, 9], [97, 520, 5.5], [110, 150, 3]];
268
+ var MachineSamples = class {
269
+ /** `{ speed, mode, frequency }`: rotor natural frequencies in Hz by speed in rpm, with whirl pairs that split and a mode that stiffens. */
270
+ static campbell(seed) {
271
+ const { u } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
272
+ const first = 48 + u() * 14, second = 128 + u() * 20, torsion = 196 + u() * 24;
273
+ const modes = [
274
+ ["1st bending, backward", (rev) => first - 0.085 * rev],
275
+ ["1st bending, forward", (rev) => first + 0.1 * rev],
276
+ ["2nd bending, backward", (rev) => second - 0.16 * rev],
277
+ ["2nd bending, forward", (rev) => second + 0.19 * rev],
278
+ ["1st torsion", (rev) => Math.hypot(torsion, 0.42 * rev)]
279
+ ];
280
+ return modes.flatMap(([mode, at]) => Array.from({ length: 13 }, (_, i) => ({ speed: i * 1e3, mode, frequency: round(at(i * 1e3 / 60), 1) })));
281
+ }
282
+ /** `{ speed, flow, pressureRatio, efficiency }`: points along each corrected speed line, named as a share of design speed, surge end first. Flow in kg/s, efficiency as a share. */
283
+ static compressor(seed) {
284
+ const { u, n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
285
+ const design = 3.6 + u() * 0.8, flow = 9 + u() * 3;
286
+ return [60, 70, 80, 90, 100, 105].flatMap((speed) => {
287
+ const share = speed / 100, choke = flow * share ** 1.45 * 1.06, surge = choke * (0.66 + 0.16 * share);
288
+ const top = 1 + (design - 1) * share ** 2.3 * 1.07, peak = 0.86 - (share < 0.92 ? 0.9 : 6) * (share - 0.92) ** 2;
289
+ return Array.from({ length: 9 }, (_, i) => {
290
+ const t = i / 8;
291
+ return {
292
+ speed: `${speed}%`,
293
+ flow: round(surge + (choke - surge) * (1 - (1 - t) ** 2.2), 3),
294
+ pressureRatio: round(top - (top - 1) * (0.06 * t + 0.4 * t ** 3.5), 3),
295
+ efficiency: round(peak - 0.3 * (t - 0.36) ** 2 * (t > 0.36 ? 1.7 : 1) + n() * 2e-3, 4)
296
+ };
297
+ });
298
+ });
299
+ }
300
+ /** `{ speed, torque, bsfc }`: load sweeps at each engine speed up to full load. Speed in rpm, torque in N·m, BSFC in g/kWh. */
301
+ static bsfcMap(seed) {
302
+ const { u, n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
303
+ const peak = 255 + u() * 50, best = 2200 + u() * 600, floor = 228 + u() * 14;
304
+ return Array.from({ length: 11 }, (_, i) => 1e3 + i * 500).flatMap((speed) => {
305
+ const rev = speed / 1e3;
306
+ const full = peak * Math.min(1, 0.62 + 0.3 * rev - 0.02 * rev ** 2, 1.62 - 0.14 * rev);
307
+ return Array.from({ length: 10 }, (_, j) => {
308
+ const load = (j + 1) / 10;
309
+ const bsfc = floor + 9 * ((speed - best) / 1e3) ** 2 + 95 * (load - 0.78) ** 2 + 26 * (0.2 / load) ** 1.6 * (1 + rev / 6) + n() * 0.8;
310
+ return { speed, torque: round(full * load, 1), bsfc: round(bsfc, 1) };
311
+ });
312
+ });
313
+ }
314
+ /** `{ time, lateral, longitudinal }`: one lap of accelerations in g, braking negative, sampled through each corner. */
315
+ static lap(seed) {
316
+ const { u, n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
317
+ const grip = 1.25 + u() * 0.25, rows = [];
318
+ let time = 0, [x, y] = [0, 0.35];
319
+ const glide = (toX, toY, steps) => {
320
+ const [fromX, fromY] = [x, y];
321
+ for (let i = 1; i <= steps; i++) {
322
+ const t = i / steps, ease = t * t * (3 - 2 * t);
323
+ x = fromX + (toX - fromX) * ease + n() * 0.03;
324
+ y = fromY + (toY - fromY) * ease + n() * 0.03;
325
+ rows.push({ time: round(time += 0.1, 1), lateral: round(x, 3), longitudinal: round(y, 3) });
326
+ }
327
+ };
328
+ for (let corner = 0; corner < 14; corner++) {
329
+ const side = u() < 0.5 ? -1 : 1, hard = 0.55 + u() * 0.45;
330
+ glide(0, 0.5 - u() * 0.25, 10);
331
+ glide(side * 0.08, -grip * 0.9 * hard, 5);
332
+ glide(side * grip * 0.72 * hard, -grip * 0.55 * hard, 6);
333
+ glide(side * grip * hard, n() * 0.05, 9);
334
+ glide(side * grip * 0.6 * hard, 0.42, 7);
335
+ }
336
+ return rows;
337
+ }
338
+ /** `{ configuration, alpha, cl, cd }`: lift and drag coefficients by angle of attack in degrees, for three flap settings. */
339
+ static dragPolar(seed) {
340
+ const { u, n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
341
+ const tilt = 0.96 + u() * 0.08;
342
+ return POLARS.flatMap(([configuration, cl0, cd0, k, clMax]) => Array.from({ length: 9 }, (_, i) => {
343
+ const alpha = -4 + i * 2, straight = cl0 + 0.098 * alpha * tilt;
344
+ const cl = clMax - Math.log(1 + Math.exp((clMax - straight) * 14)) / 14;
345
+ return { configuration, alpha, cl: round(cl, 3), cd: round(cd0 + k * (straight - 0.12) ** 2 + 0.25 * (straight - cl) + Math.abs(n()) * 6e-4, 4) };
346
+ }));
347
+ }
348
+ /** `{ family, material, density, modulus }`: density in Mg/m³ and Young's modulus in GPa, close to handbook orders of magnitude. */
349
+ static materials(seed) {
350
+ const { n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
351
+ return MATERIALS.map(([family, material, density, modulus]) => ({ family, material, density: +(density * Math.exp(n() * 0.07)).toPrecision(3), modulus: +(modulus * Math.exp(n() * 0.12)).toPrecision(3) }));
352
+ }
353
+ /** `{ wingLoading, thrustRatio, weight, cruiseSpeed }`: a sizing study over wing loading (kg/m²) and thrust-to-weight, with take-off weight in t and cruise speed in km/h. */
354
+ static sizing(seed) {
355
+ const { u } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
356
+ const base = 58 + u() * 14, bend = 0.8 + u() * 0.5;
357
+ return [350, 425, 500, 575, 650].flatMap((wingLoading) => [0.24, 0.28, 0.32, 0.36].map((thrustRatio) => {
358
+ const wing = (650 - wingLoading) / 300, engine = (thrustRatio - 0.24) / 0.12;
359
+ return {
360
+ wingLoading,
361
+ thrustRatio,
362
+ weight: round(base + 7.5 * wing ** 1.6 * bend + 5.2 * engine ** 1.3 + 2.4 * wing * engine, 2),
363
+ cruiseSpeed: Math.round(705 + 0.26 * (wingLoading - 350) + 520 * (thrustRatio - 0.24) + 14 * wing * engine)
364
+ };
365
+ }));
366
+ }
367
+ /** `{ distance, elevation }`: a mountain stage sampled every 250 m, distance in km and elevation in m. */
368
+ static route(seed) {
369
+ const { u, n } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
370
+ const hills = HILLS.map(([centre, rise, width]) => [centre + (u() - 0.5) * 5, rise * (0.8 + u() * 0.4), width * (0.85 + u() * 0.3)]);
371
+ let drift = 0;
372
+ return Array.from({ length: 481 }, (_, i) => {
373
+ const distance = i * 0.25;
374
+ drift = drift * 0.96 + n() * 1.6;
375
+ const ground = 310 + 0.9 * distance + hills.reduce((sum2, [centre, rise, width]) => sum2 + rise * Math.exp(-(((distance - centre) / width) ** 2)), 0);
376
+ return { distance, elevation: Math.round(ground + drift) };
377
+ });
378
+ }
379
+ /** `{ cycle, state, pressure, volume, temperature }`: the four states of an air-standard Otto, Diesel and Brayton cycle, in kPa, m³/kg and K. */
380
+ static gasCycles(seed) {
381
+ const { u } = _chunkLNWTC72Ycjs.SampleData.rng(seed);
382
+ const gas = { gamma: 1.4, gasConstant: 0.287, inletPressure: 95 + u() * 10, inletTemperature: 288 + u() * 22 };
383
+ const cycles = [
384
+ ["Otto", GasCycleMath.otto(gas, 8 + u() * 3, 1900 + u() * 500)],
385
+ ["Diesel", GasCycleMath.diesel(gas, 16 + u() * 5, 1.8 + u() * 0.8)],
386
+ ["Brayton", GasCycleMath.brayton(gas, 8 + u() * 8, 1250 + u() * 350)]
387
+ ];
388
+ return cycles.flatMap(([cycle, states]) => states.map((state) => ({ cycle, state: state.label, pressure: +state.pressure.toPrecision(5), volume: +state.volume.toPrecision(5), temperature: +state.temperature.toPrecision(5) })));
389
+ }
390
+ };
391
+
392
+ // src/charts/machinecharts/BsfcMath.ts
393
+
394
+ var BsfcMath = (_class = class _BsfcMath {
395
+ /** rpm × N·m per kW. */
396
+ static __initStatic() {this.PER_KW = 6e4 / (2 * Math.PI)}
397
+ static power(speed, torque) {
398
+ return speed * torque / _BsfcMath.PER_KW;
399
+ }
400
+ static torque(speed, power) {
401
+ return power * _BsfcMath.PER_KW / speed;
402
+ }
403
+ /** Brake mean effective pressure of a four-stroke engine of `litres` swept volume. */
404
+ static bmep(torque, litres) {
405
+ return 4 * Math.PI * torque / (litres * 100);
406
+ }
407
+ /** Load sweeps, one per engine speed in rising order, each from its lowest torque to full load. Repeated points are averaged. */
408
+ static sweeps(rows, speed, torque, bsfc) {
409
+ const nodes = rows.flatMap((row) => {
410
+ const x = MachineChart.number(row[speed]), y = MachineChart.number(row[torque]), z = MachineChart.number(row[bsfc]);
411
+ return x === null || y === null || z === null ? [] : [{ x, y, z }];
412
+ });
413
+ return [..._d3.group.call(void 0, nodes, (node) => node.x)].sort(([a], [b]) => a - b).map(([x, own]) => [..._d3.group.call(void 0, own, (node) => node.y)].map(([y, same]) => ({ x, y, z: _d3.mean.call(void 0, same, (node) => node.z) })).sort((a, b) => a.y - b.y));
414
+ }
415
+ /**
416
+ * The `[speed, torque]` of least BSFC at each power: where a constant-power line touches its lowest contour. The minimum
417
+ * is shallow, so noise in the map moves it; each speed is averaged with its neighbours in power, weighted 1-2-1.
418
+ */
419
+ static economy(mesh, powers) {
420
+ const found = powers.flatMap((power) => {
421
+ let best = null;
422
+ for (const sweep of mesh.nodes) {
423
+ const speed = sweep[0].x, torque = _BsfcMath.torque(speed, power);
424
+ const i = sweep.findIndex((node, at) => at > 0 && node.y >= torque && sweep[at - 1].y <= torque);
425
+ if (i < 1) continue;
426
+ const below = sweep[i - 1], above = sweep[i], t = (torque - below.y) / (above.y - below.y || 1);
427
+ const bsfc = below.z + (above.z - below.z) * t;
428
+ if (!best || bsfc < best.bsfc) best = { power, speed, bsfc };
429
+ }
430
+ return best ? [best] : [];
431
+ });
432
+ return found.map(({ power, speed }, i) => {
433
+ const smooth = ((_nullishCoalesce(_optionalChain([found, 'access', _6 => _6[i - 1], 'optionalAccess', _7 => _7.speed]), () => ( speed))) + 2 * speed + (_nullishCoalesce(_optionalChain([found, 'access', _8 => _8[i + 1], 'optionalAccess', _9 => _9.speed]), () => ( speed)))) / 4;
434
+ return [smooth, _BsfcMath.torque(smooth, power)];
435
+ });
436
+ }
437
+ }, _class.__initStatic(), _class);
438
+
439
+ // src/charts/machinecharts/ElevationMath.ts
440
+
441
+ var CLASSES = [3, 6, 9];
442
+ var SCORES = [8e3, 16e3, 32e3, 64e3, 8e4];
443
+ var ElevationMath = class _ElevationMath {
444
+ /** The profile ordered by distance, with repeated distances averaged. */
445
+ static profile(rows, distance, elevation) {
446
+ const read = rows.flatMap((row) => {
447
+ const x = MachineChart.number(row[distance]), y = MachineChart.number(row[elevation]);
448
+ return x === null || y === null ? [] : [[x, y]];
449
+ });
450
+ return [..._d3.group.call(void 0, read, (point) => point[0])].map(([x, same]) => [x, _d3.mean.call(void 0, same, (point) => point[1])]).sort((a, b) => a[0] - b[0]);
451
+ }
452
+ /** Elevation at a distance, by linear interpolation, held level past either end. */
453
+ static at(points, distance) {
454
+ const i = points.findIndex((point) => point[0] >= distance);
455
+ if (i < 0) return _nullishCoalesce(_optionalChain([points, 'access', _10 => _10[points.length - 1], 'optionalAccess', _11 => _11[1]]), () => ( NaN));
456
+ if (i === 0) return points[0][1];
457
+ const [x0, y0] = points[i - 1], [x1, y1] = points[i];
458
+ return y0 + (y1 - y0) * (distance - x0) / (x1 - x0);
459
+ }
460
+ /** Total climbed. A rise or fall smaller than `deadband` is treated as noise in the survey and not counted. */
461
+ static ascent(points, deadband = 0) {
462
+ let held = _nullishCoalesce(_optionalChain([points, 'access', _12 => _12[0], 'optionalAccess', _13 => _13[1]]), () => ( 0)), gain = 0;
463
+ for (const [, elevation] of points) {
464
+ if (elevation > held + deadband) gain += elevation - held;
465
+ if (Math.abs(elevation - held) > deadband) held = elevation;
466
+ }
467
+ return gain;
468
+ }
469
+ static steepness(grade) {
470
+ return grade <= -CLASSES[0] ? -1 : CLASSES.filter((bound) => grade >= bound).length;
471
+ }
472
+ /** The route cut into stretches of `length`, each with its mean gradient. */
473
+ static segments(points, length, rise = 1e3) {
474
+ if (points.length < 2 || !(length > 0)) return [];
475
+ const first = points[0][0], last = points[points.length - 1][0];
476
+ return Array.from({ length: Math.min(2e3, Math.ceil((last - first) / length - 1e-9)) }, (_, i) => {
477
+ const from = first + i * length, to = Math.min(last, from + length), start = _ElevationMath.at(points, from), end = _ElevationMath.at(points, to);
478
+ const grade = (end - start) / ((to - from) * rise) * 100;
479
+ return { from, to, start, end, grade, steep: _ElevationMath.steepness(grade) };
480
+ });
481
+ }
482
+ /**
483
+ * Sustained ascents: from a low point to the highest point reached before the road drops by more than `dip`. A climb
484
+ * counts when it gains at least `least` and averages 3% or more from the last point within 8% of its gain above the foot,
485
+ * which trims a flat approach.
486
+ */
487
+ static climbs(points, { rise = 1e3, dip = 30, least = 80 } = {}) {
488
+ const found = [];
489
+ const close = (low2, top2) => {
490
+ const foot = points[low2][1] + 0.08 * (points[top2][1] - points[low2][1]);
491
+ for (let i = top2 - 1; i > low2; i--) if (points[i][1] <= foot) {
492
+ low2 = i;
493
+ break;
494
+ }
495
+ const [from, start] = points[low2], [to, end] = points[top2], gain = end - start, length = to - from, grade = gain / (length * rise) * 100;
496
+ if (gain < least || grade < CLASSES[0]) return;
497
+ const rank = SCORES.filter((score) => length * rise * grade >= score).length;
498
+ found.push({ from, to, start, end, gain, length, grade, category: rank ? Math.max(0, 5 - rank) : null });
499
+ };
500
+ let low = 0, top = 0;
501
+ points.forEach(([, elevation], i) => {
502
+ if (elevation > points[top][1]) top = i;
503
+ else if (top === low && elevation < points[low][1]) low = top = i;
504
+ else if (points[top][1] - elevation > dip) {
505
+ close(low, top);
506
+ low = top = i;
507
+ }
508
+ });
509
+ if (top > low) close(low, top);
510
+ return found;
511
+ }
512
+ };
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+ exports.MachineChart = MachineChart; exports.GasCycleMath = GasCycleMath; exports.MachineSamples = MachineSamples; exports.BsfcMath = BsfcMath; exports.MachineMesh = MachineMesh; exports.ElevationMath = ElevationMath;