@invinite-org/chartlang-runtime 1.0.2

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 (984) hide show
  1. package/CHANGELOG.md +2690 -0
  2. package/LICENSE +21 -0
  3. package/README.md +57 -0
  4. package/dist/buildComputeContext.d.ts +21 -0
  5. package/dist/buildComputeContext.d.ts.map +1 -0
  6. package/dist/buildComputeContext.js +48 -0
  7. package/dist/buildComputeContext.js.map +1 -0
  8. package/dist/createScriptRunner.d.ts +111 -0
  9. package/dist/createScriptRunner.d.ts.map +1 -0
  10. package/dist/createScriptRunner.js +234 -0
  11. package/dist/createScriptRunner.js.map +1 -0
  12. package/dist/emit/alert.d.ts +46 -0
  13. package/dist/emit/alert.d.ts.map +1 -0
  14. package/dist/emit/alert.js +71 -0
  15. package/dist/emit/alert.js.map +1 -0
  16. package/dist/emit/alertConditionEmission.d.ts +15 -0
  17. package/dist/emit/alertConditionEmission.d.ts.map +1 -0
  18. package/dist/emit/alertConditionEmission.js +53 -0
  19. package/dist/emit/alertConditionEmission.js.map +1 -0
  20. package/dist/emit/draw/annotations/arrow.d.ts +42 -0
  21. package/dist/emit/draw/annotations/arrow.d.ts.map +1 -0
  22. package/dist/emit/draw/annotations/arrow.js +40 -0
  23. package/dist/emit/draw/annotations/arrow.js.map +1 -0
  24. package/dist/emit/draw/annotations/arrowMarkDown.d.ts +36 -0
  25. package/dist/emit/draw/annotations/arrowMarkDown.d.ts.map +1 -0
  26. package/dist/emit/draw/annotations/arrowMarkDown.js +40 -0
  27. package/dist/emit/draw/annotations/arrowMarkDown.js.map +1 -0
  28. package/dist/emit/draw/annotations/arrowMarkUp.d.ts +36 -0
  29. package/dist/emit/draw/annotations/arrowMarkUp.d.ts.map +1 -0
  30. package/dist/emit/draw/annotations/arrowMarkUp.js +40 -0
  31. package/dist/emit/draw/annotations/arrowMarkUp.js.map +1 -0
  32. package/dist/emit/draw/annotations/arrowMarker.d.ts +40 -0
  33. package/dist/emit/draw/annotations/arrowMarker.d.ts.map +1 -0
  34. package/dist/emit/draw/annotations/arrowMarker.js +40 -0
  35. package/dist/emit/draw/annotations/arrowMarker.js.map +1 -0
  36. package/dist/emit/draw/annotations/text.d.ts +41 -0
  37. package/dist/emit/draw/annotations/text.d.ts.map +1 -0
  38. package/dist/emit/draw/annotations/text.js +44 -0
  39. package/dist/emit/draw/annotations/text.js.map +1 -0
  40. package/dist/emit/draw/boxes/circle.d.ts +42 -0
  41. package/dist/emit/draw/boxes/circle.d.ts.map +1 -0
  42. package/dist/emit/draw/boxes/circle.js +44 -0
  43. package/dist/emit/draw/boxes/circle.js.map +1 -0
  44. package/dist/emit/draw/boxes/ellipse.d.ts +42 -0
  45. package/dist/emit/draw/boxes/ellipse.d.ts.map +1 -0
  46. package/dist/emit/draw/boxes/ellipse.js +40 -0
  47. package/dist/emit/draw/boxes/ellipse.js.map +1 -0
  48. package/dist/emit/draw/boxes/marker.d.ts +43 -0
  49. package/dist/emit/draw/boxes/marker.d.ts.map +1 -0
  50. package/dist/emit/draw/boxes/marker.js +49 -0
  51. package/dist/emit/draw/boxes/marker.js.map +1 -0
  52. package/dist/emit/draw/boxes/path.d.ts +43 -0
  53. package/dist/emit/draw/boxes/path.d.ts.map +1 -0
  54. package/dist/emit/draw/boxes/path.js +40 -0
  55. package/dist/emit/draw/boxes/path.js.map +1 -0
  56. package/dist/emit/draw/boxes/polyline.d.ts +43 -0
  57. package/dist/emit/draw/boxes/polyline.d.ts.map +1 -0
  58. package/dist/emit/draw/boxes/polyline.js +40 -0
  59. package/dist/emit/draw/boxes/polyline.js.map +1 -0
  60. package/dist/emit/draw/boxes/rectangle.d.ts +40 -0
  61. package/dist/emit/draw/boxes/rectangle.d.ts.map +1 -0
  62. package/dist/emit/draw/boxes/rectangle.js +40 -0
  63. package/dist/emit/draw/boxes/rectangle.js.map +1 -0
  64. package/dist/emit/draw/boxes/rotatedRectangle.d.ts +45 -0
  65. package/dist/emit/draw/boxes/rotatedRectangle.d.ts.map +1 -0
  66. package/dist/emit/draw/boxes/rotatedRectangle.js +40 -0
  67. package/dist/emit/draw/boxes/rotatedRectangle.js.map +1 -0
  68. package/dist/emit/draw/boxes/triangle.d.ts +42 -0
  69. package/dist/emit/draw/boxes/triangle.d.ts.map +1 -0
  70. package/dist/emit/draw/boxes/triangle.js +40 -0
  71. package/dist/emit/draw/boxes/triangle.js.map +1 -0
  72. package/dist/emit/draw/channels/disjointChannel.d.ts +43 -0
  73. package/dist/emit/draw/channels/disjointChannel.d.ts.map +1 -0
  74. package/dist/emit/draw/channels/disjointChannel.js +40 -0
  75. package/dist/emit/draw/channels/disjointChannel.js.map +1 -0
  76. package/dist/emit/draw/channels/flatTopBottom.d.ts +44 -0
  77. package/dist/emit/draw/channels/flatTopBottom.d.ts.map +1 -0
  78. package/dist/emit/draw/channels/flatTopBottom.js +40 -0
  79. package/dist/emit/draw/channels/flatTopBottom.js.map +1 -0
  80. package/dist/emit/draw/channels/regressionTrend.d.ts +49 -0
  81. package/dist/emit/draw/channels/regressionTrend.d.ts.map +1 -0
  82. package/dist/emit/draw/channels/regressionTrend.js +44 -0
  83. package/dist/emit/draw/channels/regressionTrend.js.map +1 -0
  84. package/dist/emit/draw/channels/trendChannel.d.ts +43 -0
  85. package/dist/emit/draw/channels/trendChannel.d.ts.map +1 -0
  86. package/dist/emit/draw/channels/trendChannel.js +40 -0
  87. package/dist/emit/draw/channels/trendChannel.js.map +1 -0
  88. package/dist/emit/draw/containers/frame.d.ts +42 -0
  89. package/dist/emit/draw/containers/frame.d.ts.map +1 -0
  90. package/dist/emit/draw/containers/frame.js +47 -0
  91. package/dist/emit/draw/containers/frame.js.map +1 -0
  92. package/dist/emit/draw/containers/group.d.ts +47 -0
  93. package/dist/emit/draw/containers/group.d.ts.map +1 -0
  94. package/dist/emit/draw/containers/group.js +44 -0
  95. package/dist/emit/draw/containers/group.js.map +1 -0
  96. package/dist/emit/draw/curves/arc.d.ts +44 -0
  97. package/dist/emit/draw/curves/arc.d.ts.map +1 -0
  98. package/dist/emit/draw/curves/arc.js +40 -0
  99. package/dist/emit/draw/curves/arc.js.map +1 -0
  100. package/dist/emit/draw/curves/brush.d.ts +44 -0
  101. package/dist/emit/draw/curves/brush.d.ts.map +1 -0
  102. package/dist/emit/draw/curves/brush.js +43 -0
  103. package/dist/emit/draw/curves/brush.js.map +1 -0
  104. package/dist/emit/draw/curves/curve.d.ts +43 -0
  105. package/dist/emit/draw/curves/curve.d.ts.map +1 -0
  106. package/dist/emit/draw/curves/curve.js +40 -0
  107. package/dist/emit/draw/curves/curve.js.map +1 -0
  108. package/dist/emit/draw/curves/doubleCurve.d.ts +46 -0
  109. package/dist/emit/draw/curves/doubleCurve.d.ts.map +1 -0
  110. package/dist/emit/draw/curves/doubleCurve.js +40 -0
  111. package/dist/emit/draw/curves/doubleCurve.js.map +1 -0
  112. package/dist/emit/draw/curves/highlighter.d.ts +43 -0
  113. package/dist/emit/draw/curves/highlighter.d.ts.map +1 -0
  114. package/dist/emit/draw/curves/highlighter.js +43 -0
  115. package/dist/emit/draw/curves/highlighter.js.map +1 -0
  116. package/dist/emit/draw/curves/pen.d.ts +41 -0
  117. package/dist/emit/draw/curves/pen.d.ts.map +1 -0
  118. package/dist/emit/draw/curves/pen.js +40 -0
  119. package/dist/emit/draw/curves/pen.js.map +1 -0
  120. package/dist/emit/draw/cycles/cyclicLines.d.ts +41 -0
  121. package/dist/emit/draw/cycles/cyclicLines.d.ts.map +1 -0
  122. package/dist/emit/draw/cycles/cyclicLines.js +44 -0
  123. package/dist/emit/draw/cycles/cyclicLines.js.map +1 -0
  124. package/dist/emit/draw/cycles/sineLine.d.ts +40 -0
  125. package/dist/emit/draw/cycles/sineLine.d.ts.map +1 -0
  126. package/dist/emit/draw/cycles/sineLine.js +44 -0
  127. package/dist/emit/draw/cycles/sineLine.js.map +1 -0
  128. package/dist/emit/draw/cycles/timeCycles.d.ts +40 -0
  129. package/dist/emit/draw/cycles/timeCycles.d.ts.map +1 -0
  130. package/dist/emit/draw/cycles/timeCycles.js +44 -0
  131. package/dist/emit/draw/cycles/timeCycles.js.map +1 -0
  132. package/dist/emit/draw/elliott/elliottCorrectionWave.d.ts +39 -0
  133. package/dist/emit/draw/elliott/elliottCorrectionWave.d.ts.map +1 -0
  134. package/dist/emit/draw/elliott/elliottCorrectionWave.js +43 -0
  135. package/dist/emit/draw/elliott/elliottCorrectionWave.js.map +1 -0
  136. package/dist/emit/draw/elliott/elliottDoubleCombo.d.ts +44 -0
  137. package/dist/emit/draw/elliott/elliottDoubleCombo.d.ts.map +1 -0
  138. package/dist/emit/draw/elliott/elliottDoubleCombo.js +43 -0
  139. package/dist/emit/draw/elliott/elliottDoubleCombo.js.map +1 -0
  140. package/dist/emit/draw/elliott/elliottImpulseWave.d.ts +42 -0
  141. package/dist/emit/draw/elliott/elliottImpulseWave.d.ts.map +1 -0
  142. package/dist/emit/draw/elliott/elliottImpulseWave.js +43 -0
  143. package/dist/emit/draw/elliott/elliottImpulseWave.js.map +1 -0
  144. package/dist/emit/draw/elliott/elliottTriangleWave.d.ts +41 -0
  145. package/dist/emit/draw/elliott/elliottTriangleWave.d.ts.map +1 -0
  146. package/dist/emit/draw/elliott/elliottTriangleWave.js +43 -0
  147. package/dist/emit/draw/elliott/elliottTriangleWave.js.map +1 -0
  148. package/dist/emit/draw/elliott/elliottTripleCombo.d.ts +44 -0
  149. package/dist/emit/draw/elliott/elliottTripleCombo.d.ts.map +1 -0
  150. package/dist/emit/draw/elliott/elliottTripleCombo.js +47 -0
  151. package/dist/emit/draw/elliott/elliottTripleCombo.js.map +1 -0
  152. package/dist/emit/draw/fibA/fibChannel.d.ts +41 -0
  153. package/dist/emit/draw/fibA/fibChannel.d.ts.map +1 -0
  154. package/dist/emit/draw/fibA/fibChannel.js +40 -0
  155. package/dist/emit/draw/fibA/fibChannel.js.map +1 -0
  156. package/dist/emit/draw/fibA/fibRetracement.d.ts +40 -0
  157. package/dist/emit/draw/fibA/fibRetracement.d.ts.map +1 -0
  158. package/dist/emit/draw/fibA/fibRetracement.js +44 -0
  159. package/dist/emit/draw/fibA/fibRetracement.js.map +1 -0
  160. package/dist/emit/draw/fibA/fibTimeZone.d.ts +41 -0
  161. package/dist/emit/draw/fibA/fibTimeZone.d.ts.map +1 -0
  162. package/dist/emit/draw/fibA/fibTimeZone.js +44 -0
  163. package/dist/emit/draw/fibA/fibTimeZone.js.map +1 -0
  164. package/dist/emit/draw/fibA/fibTrendExtension.d.ts +42 -0
  165. package/dist/emit/draw/fibA/fibTrendExtension.d.ts.map +1 -0
  166. package/dist/emit/draw/fibA/fibTrendExtension.js +44 -0
  167. package/dist/emit/draw/fibA/fibTrendExtension.js.map +1 -0
  168. package/dist/emit/draw/fibA/fibWedge.d.ts +42 -0
  169. package/dist/emit/draw/fibA/fibWedge.d.ts.map +1 -0
  170. package/dist/emit/draw/fibA/fibWedge.js +40 -0
  171. package/dist/emit/draw/fibA/fibWedge.js.map +1 -0
  172. package/dist/emit/draw/fibB/fibCircles.d.ts +41 -0
  173. package/dist/emit/draw/fibB/fibCircles.d.ts.map +1 -0
  174. package/dist/emit/draw/fibB/fibCircles.js +44 -0
  175. package/dist/emit/draw/fibB/fibCircles.js.map +1 -0
  176. package/dist/emit/draw/fibB/fibSpeedArcs.d.ts +39 -0
  177. package/dist/emit/draw/fibB/fibSpeedArcs.d.ts.map +1 -0
  178. package/dist/emit/draw/fibB/fibSpeedArcs.js +44 -0
  179. package/dist/emit/draw/fibB/fibSpeedArcs.js.map +1 -0
  180. package/dist/emit/draw/fibB/fibSpeedFan.d.ts +39 -0
  181. package/dist/emit/draw/fibB/fibSpeedFan.d.ts.map +1 -0
  182. package/dist/emit/draw/fibB/fibSpeedFan.js +44 -0
  183. package/dist/emit/draw/fibB/fibSpeedFan.js.map +1 -0
  184. package/dist/emit/draw/fibB/fibSpiral.d.ts +41 -0
  185. package/dist/emit/draw/fibB/fibSpiral.d.ts.map +1 -0
  186. package/dist/emit/draw/fibB/fibSpiral.js +44 -0
  187. package/dist/emit/draw/fibB/fibSpiral.js.map +1 -0
  188. package/dist/emit/draw/fibB/fibTrendTime.d.ts +45 -0
  189. package/dist/emit/draw/fibB/fibTrendTime.d.ts.map +1 -0
  190. package/dist/emit/draw/fibB/fibTrendTime.js +44 -0
  191. package/dist/emit/draw/fibB/fibTrendTime.js.map +1 -0
  192. package/dist/emit/draw/gann/gannBox.d.ts +39 -0
  193. package/dist/emit/draw/gann/gannBox.d.ts.map +1 -0
  194. package/dist/emit/draw/gann/gannBox.js +44 -0
  195. package/dist/emit/draw/gann/gannBox.js.map +1 -0
  196. package/dist/emit/draw/gann/gannFan.d.ts +39 -0
  197. package/dist/emit/draw/gann/gannFan.d.ts.map +1 -0
  198. package/dist/emit/draw/gann/gannFan.js +44 -0
  199. package/dist/emit/draw/gann/gannFan.js.map +1 -0
  200. package/dist/emit/draw/gann/gannSquare.d.ts +38 -0
  201. package/dist/emit/draw/gann/gannSquare.d.ts.map +1 -0
  202. package/dist/emit/draw/gann/gannSquare.js +44 -0
  203. package/dist/emit/draw/gann/gannSquare.js.map +1 -0
  204. package/dist/emit/draw/gann/gannSquareFixed.d.ts +35 -0
  205. package/dist/emit/draw/gann/gannSquareFixed.d.ts.map +1 -0
  206. package/dist/emit/draw/gann/gannSquareFixed.js +44 -0
  207. package/dist/emit/draw/gann/gannSquareFixed.js.map +1 -0
  208. package/dist/emit/draw/handle.d.ts +37 -0
  209. package/dist/emit/draw/handle.d.ts.map +1 -0
  210. package/dist/emit/draw/handle.js +118 -0
  211. package/dist/emit/draw/handle.js.map +1 -0
  212. package/dist/emit/draw/index.d.ts +5 -0
  213. package/dist/emit/draw/index.d.ts.map +1 -0
  214. package/dist/emit/draw/index.js +13 -0
  215. package/dist/emit/draw/index.js.map +1 -0
  216. package/dist/emit/draw/lines/crossLine.d.ts +37 -0
  217. package/dist/emit/draw/lines/crossLine.d.ts.map +1 -0
  218. package/dist/emit/draw/lines/crossLine.js +40 -0
  219. package/dist/emit/draw/lines/crossLine.js.map +1 -0
  220. package/dist/emit/draw/lines/horizontalLine.d.ts +33 -0
  221. package/dist/emit/draw/lines/horizontalLine.d.ts.map +1 -0
  222. package/dist/emit/draw/lines/horizontalLine.js +40 -0
  223. package/dist/emit/draw/lines/horizontalLine.js.map +1 -0
  224. package/dist/emit/draw/lines/horizontalRay.d.ts +36 -0
  225. package/dist/emit/draw/lines/horizontalRay.d.ts.map +1 -0
  226. package/dist/emit/draw/lines/horizontalRay.js +40 -0
  227. package/dist/emit/draw/lines/horizontalRay.js.map +1 -0
  228. package/dist/emit/draw/lines/line.d.ts +43 -0
  229. package/dist/emit/draw/lines/line.d.ts.map +1 -0
  230. package/dist/emit/draw/lines/line.js +43 -0
  231. package/dist/emit/draw/lines/line.js.map +1 -0
  232. package/dist/emit/draw/lines/trendAngle.d.ts +38 -0
  233. package/dist/emit/draw/lines/trendAngle.d.ts.map +1 -0
  234. package/dist/emit/draw/lines/trendAngle.js +40 -0
  235. package/dist/emit/draw/lines/trendAngle.js.map +1 -0
  236. package/dist/emit/draw/lines/verticalLine.d.ts +33 -0
  237. package/dist/emit/draw/lines/verticalLine.d.ts.map +1 -0
  238. package/dist/emit/draw/lines/verticalLine.js +40 -0
  239. package/dist/emit/draw/lines/verticalLine.js.map +1 -0
  240. package/dist/emit/draw/namespace.d.ts +26 -0
  241. package/dist/emit/draw/namespace.d.ts.map +1 -0
  242. package/dist/emit/draw/namespace.js +186 -0
  243. package/dist/emit/draw/namespace.js.map +1 -0
  244. package/dist/emit/draw/patterns/abcdPattern.d.ts +40 -0
  245. package/dist/emit/draw/patterns/abcdPattern.d.ts.map +1 -0
  246. package/dist/emit/draw/patterns/abcdPattern.js +40 -0
  247. package/dist/emit/draw/patterns/abcdPattern.js.map +1 -0
  248. package/dist/emit/draw/patterns/cypherPattern.d.ts +43 -0
  249. package/dist/emit/draw/patterns/cypherPattern.d.ts.map +1 -0
  250. package/dist/emit/draw/patterns/cypherPattern.js +41 -0
  251. package/dist/emit/draw/patterns/cypherPattern.js.map +1 -0
  252. package/dist/emit/draw/patterns/headAndShoulders.d.ts +42 -0
  253. package/dist/emit/draw/patterns/headAndShoulders.d.ts.map +1 -0
  254. package/dist/emit/draw/patterns/headAndShoulders.js +49 -0
  255. package/dist/emit/draw/patterns/headAndShoulders.js.map +1 -0
  256. package/dist/emit/draw/patterns/threeDrivesPattern.d.ts +43 -0
  257. package/dist/emit/draw/patterns/threeDrivesPattern.d.ts.map +1 -0
  258. package/dist/emit/draw/patterns/threeDrivesPattern.js +44 -0
  259. package/dist/emit/draw/patterns/threeDrivesPattern.js.map +1 -0
  260. package/dist/emit/draw/patterns/trianglePattern.d.ts +41 -0
  261. package/dist/emit/draw/patterns/trianglePattern.d.ts.map +1 -0
  262. package/dist/emit/draw/patterns/trianglePattern.js +50 -0
  263. package/dist/emit/draw/patterns/trianglePattern.js.map +1 -0
  264. package/dist/emit/draw/patterns/xabcdPattern.d.ts +41 -0
  265. package/dist/emit/draw/patterns/xabcdPattern.d.ts.map +1 -0
  266. package/dist/emit/draw/patterns/xabcdPattern.js +40 -0
  267. package/dist/emit/draw/patterns/xabcdPattern.js.map +1 -0
  268. package/dist/emit/draw/pitchforks/pitchfan.d.ts +39 -0
  269. package/dist/emit/draw/pitchforks/pitchfan.d.ts.map +1 -0
  270. package/dist/emit/draw/pitchforks/pitchfan.js +40 -0
  271. package/dist/emit/draw/pitchforks/pitchfan.js.map +1 -0
  272. package/dist/emit/draw/pitchforks/pitchfork.d.ts +51 -0
  273. package/dist/emit/draw/pitchforks/pitchfork.d.ts.map +1 -0
  274. package/dist/emit/draw/pitchforks/pitchfork.js +50 -0
  275. package/dist/emit/draw/pitchforks/pitchfork.js.map +1 -0
  276. package/dist/emit/draw/pushDrawing.d.ts +45 -0
  277. package/dist/emit/draw/pushDrawing.d.ts.map +1 -0
  278. package/dist/emit/draw/pushDrawing.js +107 -0
  279. package/dist/emit/draw/pushDrawing.js.map +1 -0
  280. package/dist/emit/draw/subIdAllocator.d.ts +34 -0
  281. package/dist/emit/draw/subIdAllocator.d.ts.map +1 -0
  282. package/dist/emit/draw/subIdAllocator.js +42 -0
  283. package/dist/emit/draw/subIdAllocator.js.map +1 -0
  284. package/dist/emit/draw/table/table.d.ts +39 -0
  285. package/dist/emit/draw/table/table.d.ts.map +1 -0
  286. package/dist/emit/draw/table/table.js +39 -0
  287. package/dist/emit/draw/table/table.js.map +1 -0
  288. package/dist/emit/emissionsQueue.d.ts +65 -0
  289. package/dist/emit/emissionsQueue.d.ts.map +1 -0
  290. package/dist/emit/emissionsQueue.js +140 -0
  291. package/dist/emit/emissionsQueue.js.map +1 -0
  292. package/dist/emit/hash.d.ts +13 -0
  293. package/dist/emit/hash.d.ts.map +1 -0
  294. package/dist/emit/hash.js +24 -0
  295. package/dist/emit/hash.js.map +1 -0
  296. package/dist/emit/hline.d.ts +42 -0
  297. package/dist/emit/hline.d.ts.map +1 -0
  298. package/dist/emit/hline.js +59 -0
  299. package/dist/emit/hline.js.map +1 -0
  300. package/dist/emit/index.d.ts +11 -0
  301. package/dist/emit/index.d.ts.map +1 -0
  302. package/dist/emit/index.js +13 -0
  303. package/dist/emit/index.js.map +1 -0
  304. package/dist/emit/logEmission.d.ts +25 -0
  305. package/dist/emit/logEmission.d.ts.map +1 -0
  306. package/dist/emit/logEmission.js +127 -0
  307. package/dist/emit/logEmission.js.map +1 -0
  308. package/dist/emit/paneResolver.d.ts +19 -0
  309. package/dist/emit/paneResolver.d.ts.map +1 -0
  310. package/dist/emit/paneResolver.js +45 -0
  311. package/dist/emit/paneResolver.js.map +1 -0
  312. package/dist/emit/plot.d.ts +45 -0
  313. package/dist/emit/plot.d.ts.map +1 -0
  314. package/dist/emit/plot.js +126 -0
  315. package/dist/emit/plot.js.map +1 -0
  316. package/dist/emit/runtimeError.d.ts +27 -0
  317. package/dist/emit/runtimeError.d.ts.map +1 -0
  318. package/dist/emit/runtimeError.js +33 -0
  319. package/dist/emit/runtimeError.js.map +1 -0
  320. package/dist/execution/dispose.d.ts +23 -0
  321. package/dist/execution/dispose.d.ts.map +1 -0
  322. package/dist/execution/dispose.js +57 -0
  323. package/dist/execution/dispose.js.map +1 -0
  324. package/dist/execution/drain.d.ts +22 -0
  325. package/dist/execution/drain.d.ts.map +1 -0
  326. package/dist/execution/drain.js +40 -0
  327. package/dist/execution/drain.js.map +1 -0
  328. package/dist/execution/index.d.ts +6 -0
  329. package/dist/execution/index.d.ts.map +1 -0
  330. package/dist/execution/index.js +8 -0
  331. package/dist/execution/index.js.map +1 -0
  332. package/dist/execution/onBarClose.d.ts +25 -0
  333. package/dist/execution/onBarClose.d.ts.map +1 -0
  334. package/dist/execution/onBarClose.js +78 -0
  335. package/dist/execution/onBarClose.js.map +1 -0
  336. package/dist/execution/onBarTick.d.ts +24 -0
  337. package/dist/execution/onBarTick.d.ts.map +1 -0
  338. package/dist/execution/onBarTick.js +77 -0
  339. package/dist/execution/onBarTick.js.map +1 -0
  340. package/dist/execution/onHistory.d.ts +31 -0
  341. package/dist/execution/onHistory.d.ts.map +1 -0
  342. package/dist/execution/onHistory.js +59 -0
  343. package/dist/execution/onHistory.js.map +1 -0
  344. package/dist/execution/secondaryStream.d.ts +36 -0
  345. package/dist/execution/secondaryStream.d.ts.map +1 -0
  346. package/dist/execution/secondaryStream.js +45 -0
  347. package/dist/execution/secondaryStream.js.map +1 -0
  348. package/dist/index.d.ts +25 -0
  349. package/dist/index.d.ts.map +1 -0
  350. package/dist/index.js +24 -0
  351. package/dist/index.js.map +1 -0
  352. package/dist/inputs/index.d.ts +2 -0
  353. package/dist/inputs/index.d.ts.map +1 -0
  354. package/dist/inputs/index.js +4 -0
  355. package/dist/inputs/index.js.map +1 -0
  356. package/dist/inputs/resolveInputs.d.ts +18 -0
  357. package/dist/inputs/resolveInputs.d.ts.map +1 -0
  358. package/dist/inputs/resolveInputs.js +93 -0
  359. package/dist/inputs/resolveInputs.js.map +1 -0
  360. package/dist/persistentStateStore.d.ts +40 -0
  361. package/dist/persistentStateStore.d.ts.map +1 -0
  362. package/dist/persistentStateStore.js +30 -0
  363. package/dist/persistentStateStore.js.map +1 -0
  364. package/dist/persistentStateStore.runtime.d.ts +57 -0
  365. package/dist/persistentStateStore.runtime.d.ts.map +1 -0
  366. package/dist/persistentStateStore.runtime.js +163 -0
  367. package/dist/persistentStateStore.runtime.js.map +1 -0
  368. package/dist/persistentStateStore.validate.d.ts +14 -0
  369. package/dist/persistentStateStore.validate.d.ts.map +1 -0
  370. package/dist/persistentStateStore.validate.js +63 -0
  371. package/dist/persistentStateStore.validate.js.map +1 -0
  372. package/dist/primitives.d.ts +23 -0
  373. package/dist/primitives.d.ts.map +1 -0
  374. package/dist/primitives.js +25 -0
  375. package/dist/primitives.js.map +1 -0
  376. package/dist/request/alignHtfSeriesCache.d.ts +20 -0
  377. package/dist/request/alignHtfSeriesCache.d.ts.map +1 -0
  378. package/dist/request/alignHtfSeriesCache.js +50 -0
  379. package/dist/request/alignHtfSeriesCache.js.map +1 -0
  380. package/dist/request/alignHtfSeriesToLtf.d.ts +26 -0
  381. package/dist/request/alignHtfSeriesToLtf.d.ts.map +1 -0
  382. package/dist/request/alignHtfSeriesToLtf.js +47 -0
  383. package/dist/request/alignHtfSeriesToLtf.js.map +1 -0
  384. package/dist/request/bucketLtfBarsByMainContainment.d.ts +22 -0
  385. package/dist/request/bucketLtfBarsByMainContainment.d.ts.map +1 -0
  386. package/dist/request/bucketLtfBarsByMainContainment.js +41 -0
  387. package/dist/request/bucketLtfBarsByMainContainment.js.map +1 -0
  388. package/dist/request/bucketLtfBarsCache.d.ts +14 -0
  389. package/dist/request/bucketLtfBarsCache.d.ts.map +1 -0
  390. package/dist/request/bucketLtfBarsCache.js +30 -0
  391. package/dist/request/bucketLtfBarsCache.js.map +1 -0
  392. package/dist/request/index.d.ts +4 -0
  393. package/dist/request/index.d.ts.map +1 -0
  394. package/dist/request/index.js +6 -0
  395. package/dist/request/index.js.map +1 -0
  396. package/dist/request/lowerTf.d.ts +14 -0
  397. package/dist/request/lowerTf.d.ts.map +1 -0
  398. package/dist/request/lowerTf.js +65 -0
  399. package/dist/request/lowerTf.js.map +1 -0
  400. package/dist/request/pushOnce.d.ts +13 -0
  401. package/dist/request/pushOnce.d.ts.map +1 -0
  402. package/dist/request/pushOnce.js +26 -0
  403. package/dist/request/pushOnce.js.map +1 -0
  404. package/dist/request/requestNamespace.d.ts +17 -0
  405. package/dist/request/requestNamespace.d.ts.map +1 -0
  406. package/dist/request/requestNamespace.js +39 -0
  407. package/dist/request/requestNamespace.js.map +1 -0
  408. package/dist/request/security.d.ts +25 -0
  409. package/dist/request/security.d.ts.map +1 -0
  410. package/dist/request/security.js +172 -0
  411. package/dist/request/security.js.map +1 -0
  412. package/dist/request/streamBars.d.ts +27 -0
  413. package/dist/request/streamBars.d.ts.map +1 -0
  414. package/dist/request/streamBars.js +55 -0
  415. package/dist/request/streamBars.js.map +1 -0
  416. package/dist/ringBuffer.d.ts +95 -0
  417. package/dist/ringBuffer.d.ts.map +1 -0
  418. package/dist/ringBuffer.js +146 -0
  419. package/dist/ringBuffer.js.map +1 -0
  420. package/dist/runtimeContext.d.ts +238 -0
  421. package/dist/runtimeContext.d.ts.map +1 -0
  422. package/dist/runtimeContext.js +24 -0
  423. package/dist/runtimeContext.js.map +1 -0
  424. package/dist/seriesView.d.ts +59 -0
  425. package/dist/seriesView.d.ts.map +1 -0
  426. package/dist/seriesView.js +109 -0
  427. package/dist/seriesView.js.map +1 -0
  428. package/dist/state/index.d.ts +6 -0
  429. package/dist/state/index.d.ts.map +1 -0
  430. package/dist/state/index.js +6 -0
  431. package/dist/state/index.js.map +1 -0
  432. package/dist/state/lifecycle.d.ts +75 -0
  433. package/dist/state/lifecycle.d.ts.map +1 -0
  434. package/dist/state/lifecycle.js +87 -0
  435. package/dist/state/lifecycle.js.map +1 -0
  436. package/dist/state/stateNamespace.d.ts +14 -0
  437. package/dist/state/stateNamespace.d.ts.map +1 -0
  438. package/dist/state/stateNamespace.js +56 -0
  439. package/dist/state/stateNamespace.js.map +1 -0
  440. package/dist/state/stateSlot.d.ts +59 -0
  441. package/dist/state/stateSlot.d.ts.map +1 -0
  442. package/dist/state/stateSlot.js +74 -0
  443. package/dist/state/stateSlot.js.map +1 -0
  444. package/dist/stateStore.d.ts +40 -0
  445. package/dist/stateStore.d.ts.map +1 -0
  446. package/dist/stateStore.js +34 -0
  447. package/dist/stateStore.js.map +1 -0
  448. package/dist/streamState.d.ts +178 -0
  449. package/dist/streamState.d.ts.map +1 -0
  450. package/dist/streamState.js +313 -0
  451. package/dist/streamState.js.map +1 -0
  452. package/dist/ta/adl.d.ts +27 -0
  453. package/dist/ta/adl.d.ts.map +1 -0
  454. package/dist/ta/adl.js +92 -0
  455. package/dist/ta/adl.js.map +1 -0
  456. package/dist/ta/adr.d.ts +38 -0
  457. package/dist/ta/adr.d.ts.map +1 -0
  458. package/dist/ta/adr.js +143 -0
  459. package/dist/ta/adr.js.map +1 -0
  460. package/dist/ta/adx.d.ts +31 -0
  461. package/dist/ta/adx.d.ts.map +1 -0
  462. package/dist/ta/adx.js +167 -0
  463. package/dist/ta/adx.js.map +1 -0
  464. package/dist/ta/alma.d.ts +35 -0
  465. package/dist/ta/alma.d.ts.map +1 -0
  466. package/dist/ta/alma.js +121 -0
  467. package/dist/ta/alma.js.map +1 -0
  468. package/dist/ta/anchoredVolumeProfile.d.ts +22 -0
  469. package/dist/ta/anchoredVolumeProfile.d.ts.map +1 -0
  470. package/dist/ta/anchoredVolumeProfile.js +104 -0
  471. package/dist/ta/anchoredVolumeProfile.js.map +1 -0
  472. package/dist/ta/anchoredVwap.d.ts +36 -0
  473. package/dist/ta/anchoredVwap.d.ts.map +1 -0
  474. package/dist/ta/anchoredVwap.js +134 -0
  475. package/dist/ta/anchoredVwap.js.map +1 -0
  476. package/dist/ta/ao.d.ts +21 -0
  477. package/dist/ta/ao.d.ts.map +1 -0
  478. package/dist/ta/ao.js +74 -0
  479. package/dist/ta/ao.js.map +1 -0
  480. package/dist/ta/aroon.d.ts +26 -0
  481. package/dist/ta/aroon.d.ts.map +1 -0
  482. package/dist/ta/aroon.js +166 -0
  483. package/dist/ta/aroon.js.map +1 -0
  484. package/dist/ta/aroonOsc.d.ts +19 -0
  485. package/dist/ta/aroonOsc.d.ts.map +1 -0
  486. package/dist/ta/aroonOsc.js +68 -0
  487. package/dist/ta/aroonOsc.js.map +1 -0
  488. package/dist/ta/atr.d.ts +25 -0
  489. package/dist/ta/atr.d.ts.map +1 -0
  490. package/dist/ta/atr.js +132 -0
  491. package/dist/ta/atr.js.map +1 -0
  492. package/dist/ta/barssince.d.ts +21 -0
  493. package/dist/ta/barssince.d.ts.map +1 -0
  494. package/dist/ta/barssince.js +96 -0
  495. package/dist/ta/barssince.js.map +1 -0
  496. package/dist/ta/bb.d.ts +28 -0
  497. package/dist/ta/bb.d.ts.map +1 -0
  498. package/dist/ta/bb.js +123 -0
  499. package/dist/ta/bb.js.map +1 -0
  500. package/dist/ta/bbPercentB.d.ts +23 -0
  501. package/dist/ta/bbPercentB.d.ts.map +1 -0
  502. package/dist/ta/bbPercentB.js +84 -0
  503. package/dist/ta/bbPercentB.js.map +1 -0
  504. package/dist/ta/bbw.d.ts +23 -0
  505. package/dist/ta/bbw.d.ts.map +1 -0
  506. package/dist/ta/bbw.js +84 -0
  507. package/dist/ta/bbw.js.map +1 -0
  508. package/dist/ta/bop.d.ts +22 -0
  509. package/dist/ta/bop.d.ts.map +1 -0
  510. package/dist/ta/bop.js +75 -0
  511. package/dist/ta/bop.js.map +1 -0
  512. package/dist/ta/cci.d.ts +25 -0
  513. package/dist/ta/cci.d.ts.map +1 -0
  514. package/dist/ta/cci.js +149 -0
  515. package/dist/ta/cci.js.map +1 -0
  516. package/dist/ta/chaikinOsc.d.ts +33 -0
  517. package/dist/ta/chaikinOsc.d.ts.map +1 -0
  518. package/dist/ta/chaikinOsc.js +100 -0
  519. package/dist/ta/chaikinOsc.js.map +1 -0
  520. package/dist/ta/chandeKrollStop.d.ts +36 -0
  521. package/dist/ta/chandeKrollStop.d.ts.map +1 -0
  522. package/dist/ta/chandeKrollStop.js +185 -0
  523. package/dist/ta/chandeKrollStop.js.map +1 -0
  524. package/dist/ta/chandelier.d.ts +36 -0
  525. package/dist/ta/chandelier.d.ts.map +1 -0
  526. package/dist/ta/chandelier.js +114 -0
  527. package/dist/ta/chandelier.js.map +1 -0
  528. package/dist/ta/change.d.ts +19 -0
  529. package/dist/ta/change.d.ts.map +1 -0
  530. package/dist/ta/change.js +83 -0
  531. package/dist/ta/change.js.map +1 -0
  532. package/dist/ta/chop.d.ts +29 -0
  533. package/dist/ta/chop.d.ts.map +1 -0
  534. package/dist/ta/chop.js +167 -0
  535. package/dist/ta/chop.js.map +1 -0
  536. package/dist/ta/cmf.d.ts +26 -0
  537. package/dist/ta/cmf.d.ts.map +1 -0
  538. package/dist/ta/cmf.js +126 -0
  539. package/dist/ta/cmf.js.map +1 -0
  540. package/dist/ta/cmo.d.ts +23 -0
  541. package/dist/ta/cmo.d.ts.map +1 -0
  542. package/dist/ta/cmo.js +130 -0
  543. package/dist/ta/cmo.js.map +1 -0
  544. package/dist/ta/connorsRsi.d.ts +31 -0
  545. package/dist/ta/connorsRsi.d.ts.map +1 -0
  546. package/dist/ta/connorsRsi.js +207 -0
  547. package/dist/ta/connorsRsi.js.map +1 -0
  548. package/dist/ta/coppock.d.ts +25 -0
  549. package/dist/ta/coppock.d.ts.map +1 -0
  550. package/dist/ta/coppock.js +151 -0
  551. package/dist/ta/coppock.js.map +1 -0
  552. package/dist/ta/crossover.d.ts +29 -0
  553. package/dist/ta/crossover.d.ts.map +1 -0
  554. package/dist/ta/crossover.js +108 -0
  555. package/dist/ta/crossover.js.map +1 -0
  556. package/dist/ta/crossunder.d.ts +23 -0
  557. package/dist/ta/crossunder.d.ts.map +1 -0
  558. package/dist/ta/crossunder.js +101 -0
  559. package/dist/ta/crossunder.js.map +1 -0
  560. package/dist/ta/dema.d.ts +25 -0
  561. package/dist/ta/dema.d.ts.map +1 -0
  562. package/dist/ta/dema.js +72 -0
  563. package/dist/ta/dema.js.map +1 -0
  564. package/dist/ta/dmi.d.ts +36 -0
  565. package/dist/ta/dmi.d.ts.map +1 -0
  566. package/dist/ta/dmi.js +107 -0
  567. package/dist/ta/dmi.js.map +1 -0
  568. package/dist/ta/donchian.d.ts +29 -0
  569. package/dist/ta/donchian.d.ts.map +1 -0
  570. package/dist/ta/donchian.js +93 -0
  571. package/dist/ta/donchian.js.map +1 -0
  572. package/dist/ta/dpo.d.ts +25 -0
  573. package/dist/ta/dpo.d.ts.map +1 -0
  574. package/dist/ta/dpo.js +111 -0
  575. package/dist/ta/dpo.js.map +1 -0
  576. package/dist/ta/ema.d.ts +27 -0
  577. package/dist/ta/ema.d.ts.map +1 -0
  578. package/dist/ta/ema.js +116 -0
  579. package/dist/ta/ema.js.map +1 -0
  580. package/dist/ta/envelope.d.ts +29 -0
  581. package/dist/ta/envelope.d.ts.map +1 -0
  582. package/dist/ta/envelope.js +119 -0
  583. package/dist/ta/envelope.js.map +1 -0
  584. package/dist/ta/eom.d.ts +35 -0
  585. package/dist/ta/eom.d.ts.map +1 -0
  586. package/dist/ta/eom.js +185 -0
  587. package/dist/ta/eom.js.map +1 -0
  588. package/dist/ta/fisher.d.ts +33 -0
  589. package/dist/ta/fisher.d.ts.map +1 -0
  590. package/dist/ta/fisher.js +174 -0
  591. package/dist/ta/fisher.js.map +1 -0
  592. package/dist/ta/fixedRangeVolumeProfile.d.ts +30 -0
  593. package/dist/ta/fixedRangeVolumeProfile.d.ts.map +1 -0
  594. package/dist/ta/fixedRangeVolumeProfile.js +141 -0
  595. package/dist/ta/fixedRangeVolumeProfile.js.map +1 -0
  596. package/dist/ta/highest.d.ts +21 -0
  597. package/dist/ta/highest.d.ts.map +1 -0
  598. package/dist/ta/highest.js +131 -0
  599. package/dist/ta/highest.js.map +1 -0
  600. package/dist/ta/historicalVolatility.d.ts +28 -0
  601. package/dist/ta/historicalVolatility.d.ts.map +1 -0
  602. package/dist/ta/historicalVolatility.js +199 -0
  603. package/dist/ta/historicalVolatility.js.map +1 -0
  604. package/dist/ta/hma.d.ts +28 -0
  605. package/dist/ta/hma.d.ts.map +1 -0
  606. package/dist/ta/hma.js +64 -0
  607. package/dist/ta/hma.js.map +1 -0
  608. package/dist/ta/ichimoku.d.ts +42 -0
  609. package/dist/ta/ichimoku.d.ts.map +1 -0
  610. package/dist/ta/ichimoku.js +188 -0
  611. package/dist/ta/ichimoku.js.map +1 -0
  612. package/dist/ta/index.d.ts +5 -0
  613. package/dist/ta/index.d.ts.map +1 -0
  614. package/dist/ta/index.js +5 -0
  615. package/dist/ta/index.js.map +1 -0
  616. package/dist/ta/kama.d.ts +35 -0
  617. package/dist/ta/kama.d.ts.map +1 -0
  618. package/dist/ta/kama.js +141 -0
  619. package/dist/ta/kama.js.map +1 -0
  620. package/dist/ta/keltner.d.ts +31 -0
  621. package/dist/ta/keltner.d.ts.map +1 -0
  622. package/dist/ta/keltner.js +125 -0
  623. package/dist/ta/keltner.js.map +1 -0
  624. package/dist/ta/klinger.d.ts +32 -0
  625. package/dist/ta/klinger.d.ts.map +1 -0
  626. package/dist/ta/klinger.js +165 -0
  627. package/dist/ta/klinger.js.map +1 -0
  628. package/dist/ta/kst.d.ts +31 -0
  629. package/dist/ta/kst.d.ts.map +1 -0
  630. package/dist/ta/kst.js +139 -0
  631. package/dist/ta/kst.js.map +1 -0
  632. package/dist/ta/lib/adxFromDi.d.ts +29 -0
  633. package/dist/ta/lib/adxFromDi.d.ts.map +1 -0
  634. package/dist/ta/lib/adxFromDi.js +72 -0
  635. package/dist/ta/lib/adxFromDi.js.map +1 -0
  636. package/dist/ta/lib/applyOffset.d.ts +19 -0
  637. package/dist/ta/lib/applyOffset.d.ts.map +1 -0
  638. package/dist/ta/lib/applyOffset.js +38 -0
  639. package/dist/ta/lib/applyOffset.js.map +1 -0
  640. package/dist/ta/lib/computeMa.d.ts +25 -0
  641. package/dist/ta/lib/computeMa.d.ts.map +1 -0
  642. package/dist/ta/lib/computeMa.js +43 -0
  643. package/dist/ta/lib/computeMa.js.map +1 -0
  644. package/dist/ta/lib/computeMaOfFloat64.d.ts +24 -0
  645. package/dist/ta/lib/computeMaOfFloat64.d.ts.map +1 -0
  646. package/dist/ta/lib/computeMaOfFloat64.js +45 -0
  647. package/dist/ta/lib/computeMaOfFloat64.js.map +1 -0
  648. package/dist/ta/lib/directionalState.d.ts +90 -0
  649. package/dist/ta/lib/directionalState.d.ts.map +1 -0
  650. package/dist/ta/lib/directionalState.js +204 -0
  651. package/dist/ta/lib/directionalState.js.map +1 -0
  652. package/dist/ta/lib/donchianMid.d.ts +21 -0
  653. package/dist/ta/lib/donchianMid.d.ts.map +1 -0
  654. package/dist/ta/lib/donchianMid.js +56 -0
  655. package/dist/ta/lib/donchianMid.js.map +1 -0
  656. package/dist/ta/lib/emaFloat64.d.ts +22 -0
  657. package/dist/ta/lib/emaFloat64.d.ts.map +1 -0
  658. package/dist/ta/lib/emaFloat64.js +60 -0
  659. package/dist/ta/lib/emaFloat64.js.map +1 -0
  660. package/dist/ta/lib/linearRegression.d.ts +50 -0
  661. package/dist/ta/lib/linearRegression.d.ts.map +1 -0
  662. package/dist/ta/lib/linearRegression.js +86 -0
  663. package/dist/ta/lib/linearRegression.js.map +1 -0
  664. package/dist/ta/lib/maTypes.d.ts +37 -0
  665. package/dist/ta/lib/maTypes.d.ts.map +1 -0
  666. package/dist/ta/lib/maTypes.js +4 -0
  667. package/dist/ta/lib/maTypes.js.map +1 -0
  668. package/dist/ta/lib/pearson.d.ts +31 -0
  669. package/dist/ta/lib/pearson.d.ts.map +1 -0
  670. package/dist/ta/lib/pearson.js +79 -0
  671. package/dist/ta/lib/pearson.js.map +1 -0
  672. package/dist/ta/lib/pickCandleSource.d.ts +24 -0
  673. package/dist/ta/lib/pickCandleSource.d.ts.map +1 -0
  674. package/dist/ta/lib/pickCandleSource.js +45 -0
  675. package/dist/ta/lib/pickCandleSource.js.map +1 -0
  676. package/dist/ta/lib/readSourceField.d.ts +29 -0
  677. package/dist/ta/lib/readSourceField.d.ts.map +1 -0
  678. package/dist/ta/lib/readSourceField.js +37 -0
  679. package/dist/ta/lib/readSourceField.js.map +1 -0
  680. package/dist/ta/lib/rollingStddev.d.ts +22 -0
  681. package/dist/ta/lib/rollingStddev.d.ts.map +1 -0
  682. package/dist/ta/lib/rollingStddev.js +60 -0
  683. package/dist/ta/lib/rollingStddev.js.map +1 -0
  684. package/dist/ta/lib/smaFloat64.d.ts +20 -0
  685. package/dist/ta/lib/smaFloat64.d.ts.map +1 -0
  686. package/dist/ta/lib/smaFloat64.js +59 -0
  687. package/dist/ta/lib/smaFloat64.js.map +1 -0
  688. package/dist/ta/lib/smmaFloat64.d.ts +23 -0
  689. package/dist/ta/lib/smmaFloat64.d.ts.map +1 -0
  690. package/dist/ta/lib/smmaFloat64.js +60 -0
  691. package/dist/ta/lib/smmaFloat64.js.map +1 -0
  692. package/dist/ta/lib/sourceValue.d.ts +31 -0
  693. package/dist/ta/lib/sourceValue.d.ts.map +1 -0
  694. package/dist/ta/lib/sourceValue.js +21 -0
  695. package/dist/ta/lib/sourceValue.js.map +1 -0
  696. package/dist/ta/lib/trSeries.d.ts +48 -0
  697. package/dist/ta/lib/trSeries.d.ts.map +1 -0
  698. package/dist/ta/lib/trSeries.js +81 -0
  699. package/dist/ta/lib/trSeries.js.map +1 -0
  700. package/dist/ta/lib/volume-profile/bucketEdges.d.ts +14 -0
  701. package/dist/ta/lib/volume-profile/bucketEdges.d.ts.map +1 -0
  702. package/dist/ta/lib/volume-profile/bucketEdges.js +42 -0
  703. package/dist/ta/lib/volume-profile/bucketEdges.js.map +1 -0
  704. package/dist/ta/lib/volume-profile/bucketizeVolume.d.ts +26 -0
  705. package/dist/ta/lib/volume-profile/bucketizeVolume.d.ts.map +1 -0
  706. package/dist/ta/lib/volume-profile/bucketizeVolume.js +115 -0
  707. package/dist/ta/lib/volume-profile/bucketizeVolume.js.map +1 -0
  708. package/dist/ta/lib/volume-profile/developingSeries.d.ts +35 -0
  709. package/dist/ta/lib/volume-profile/developingSeries.d.ts.map +1 -0
  710. package/dist/ta/lib/volume-profile/developingSeries.js +97 -0
  711. package/dist/ta/lib/volume-profile/developingSeries.js.map +1 -0
  712. package/dist/ta/lib/volume-profile/index.d.ts +11 -0
  713. package/dist/ta/lib/volume-profile/index.d.ts.map +1 -0
  714. package/dist/ta/lib/volume-profile/index.js +15 -0
  715. package/dist/ta/lib/volume-profile/index.js.map +1 -0
  716. package/dist/ta/lib/volume-profile/intercept.d.ts +15 -0
  717. package/dist/ta/lib/volume-profile/intercept.d.ts.map +1 -0
  718. package/dist/ta/lib/volume-profile/intercept.js +31 -0
  719. package/dist/ta/lib/volume-profile/intercept.js.map +1 -0
  720. package/dist/ta/lib/volume-profile/scaffold.d.ts +165 -0
  721. package/dist/ta/lib/volume-profile/scaffold.d.ts.map +1 -0
  722. package/dist/ta/lib/volume-profile/scaffold.js +209 -0
  723. package/dist/ta/lib/volume-profile/scaffold.js.map +1 -0
  724. package/dist/ta/lib/volume-profile/tooHeavy.d.ts +45 -0
  725. package/dist/ta/lib/volume-profile/tooHeavy.d.ts.map +1 -0
  726. package/dist/ta/lib/volume-profile/tooHeavy.js +92 -0
  727. package/dist/ta/lib/volume-profile/tooHeavy.js.map +1 -0
  728. package/dist/ta/lib/volume-profile/types.d.ts +188 -0
  729. package/dist/ta/lib/volume-profile/types.d.ts.map +1 -0
  730. package/dist/ta/lib/volume-profile/types.js +17 -0
  731. package/dist/ta/lib/volume-profile/types.js.map +1 -0
  732. package/dist/ta/lib/volume-profile/valueArea.d.ts +14 -0
  733. package/dist/ta/lib/volume-profile/valueArea.d.ts.map +1 -0
  734. package/dist/ta/lib/volume-profile/valueArea.js +90 -0
  735. package/dist/ta/lib/volume-profile/valueArea.js.map +1 -0
  736. package/dist/ta/lib/volume-profile/volumeProfileShared.d.ts +35 -0
  737. package/dist/ta/lib/volume-profile/volumeProfileShared.d.ts.map +1 -0
  738. package/dist/ta/lib/volume-profile/volumeProfileShared.js +136 -0
  739. package/dist/ta/lib/volume-profile/volumeProfileShared.js.map +1 -0
  740. package/dist/ta/lib/vwmaFloat64.d.ts +28 -0
  741. package/dist/ta/lib/vwmaFloat64.d.ts.map +1 -0
  742. package/dist/ta/lib/vwmaFloat64.js +70 -0
  743. package/dist/ta/lib/vwmaFloat64.js.map +1 -0
  744. package/dist/ta/lib/wilderDirectional.d.ts +53 -0
  745. package/dist/ta/lib/wilderDirectional.d.ts.map +1 -0
  746. package/dist/ta/lib/wilderDirectional.js +121 -0
  747. package/dist/ta/lib/wilderDirectional.js.map +1 -0
  748. package/dist/ta/lib/wilderSmoothing.d.ts +16 -0
  749. package/dist/ta/lib/wilderSmoothing.d.ts.map +1 -0
  750. package/dist/ta/lib/wilderSmoothing.js +26 -0
  751. package/dist/ta/lib/wilderSmoothing.js.map +1 -0
  752. package/dist/ta/lib/wmaFloat64.d.ts +22 -0
  753. package/dist/ta/lib/wmaFloat64.d.ts.map +1 -0
  754. package/dist/ta/lib/wmaFloat64.js +61 -0
  755. package/dist/ta/lib/wmaFloat64.js.map +1 -0
  756. package/dist/ta/lowest.d.ts +20 -0
  757. package/dist/ta/lowest.d.ts.map +1 -0
  758. package/dist/ta/lowest.js +113 -0
  759. package/dist/ta/lowest.js.map +1 -0
  760. package/dist/ta/lsma.d.ts +31 -0
  761. package/dist/ta/lsma.d.ts.map +1 -0
  762. package/dist/ta/lsma.js +127 -0
  763. package/dist/ta/lsma.js.map +1 -0
  764. package/dist/ta/maRibbon.d.ts +52 -0
  765. package/dist/ta/maRibbon.d.ts.map +1 -0
  766. package/dist/ta/maRibbon.js +125 -0
  767. package/dist/ta/maRibbon.js.map +1 -0
  768. package/dist/ta/macd.d.ts +30 -0
  769. package/dist/ta/macd.d.ts.map +1 -0
  770. package/dist/ta/macd.js +122 -0
  771. package/dist/ta/macd.js.map +1 -0
  772. package/dist/ta/massIndex.d.ts +29 -0
  773. package/dist/ta/massIndex.d.ts.map +1 -0
  774. package/dist/ta/massIndex.js +149 -0
  775. package/dist/ta/massIndex.js.map +1 -0
  776. package/dist/ta/mcginley.d.ts +26 -0
  777. package/dist/ta/mcginley.d.ts.map +1 -0
  778. package/dist/ta/mcginley.js +118 -0
  779. package/dist/ta/mcginley.js.map +1 -0
  780. package/dist/ta/median.d.ts +24 -0
  781. package/dist/ta/median.d.ts.map +1 -0
  782. package/dist/ta/median.js +112 -0
  783. package/dist/ta/median.js.map +1 -0
  784. package/dist/ta/mfi.d.ts +38 -0
  785. package/dist/ta/mfi.d.ts.map +1 -0
  786. package/dist/ta/mfi.js +152 -0
  787. package/dist/ta/mfi.js.map +1 -0
  788. package/dist/ta/momentum.d.ts +21 -0
  789. package/dist/ta/momentum.d.ts.map +1 -0
  790. package/dist/ta/momentum.js +46 -0
  791. package/dist/ta/momentum.js.map +1 -0
  792. package/dist/ta/netVolume.d.ts +31 -0
  793. package/dist/ta/netVolume.d.ts.map +1 -0
  794. package/dist/ta/netVolume.js +118 -0
  795. package/dist/ta/netVolume.js.map +1 -0
  796. package/dist/ta/nvi.d.ts +35 -0
  797. package/dist/ta/nvi.d.ts.map +1 -0
  798. package/dist/ta/nvi.js +140 -0
  799. package/dist/ta/nvi.js.map +1 -0
  800. package/dist/ta/nz.d.ts +17 -0
  801. package/dist/ta/nz.d.ts.map +1 -0
  802. package/dist/ta/nz.js +25 -0
  803. package/dist/ta/nz.js.map +1 -0
  804. package/dist/ta/obv.d.ts +25 -0
  805. package/dist/ta/obv.d.ts.map +1 -0
  806. package/dist/ta/obv.js +109 -0
  807. package/dist/ta/obv.js.map +1 -0
  808. package/dist/ta/persistence.d.ts +40 -0
  809. package/dist/ta/persistence.d.ts.map +1 -0
  810. package/dist/ta/persistence.js +306 -0
  811. package/dist/ta/persistence.js.map +1 -0
  812. package/dist/ta/pivotsHighLow.d.ts +41 -0
  813. package/dist/ta/pivotsHighLow.d.ts.map +1 -0
  814. package/dist/ta/pivotsHighLow.js +191 -0
  815. package/dist/ta/pivotsHighLow.js.map +1 -0
  816. package/dist/ta/pivotsStandard.d.ts +46 -0
  817. package/dist/ta/pivotsStandard.d.ts.map +1 -0
  818. package/dist/ta/pivotsStandard.js +323 -0
  819. package/dist/ta/pivotsStandard.js.map +1 -0
  820. package/dist/ta/pmo.d.ts +31 -0
  821. package/dist/ta/pmo.d.ts.map +1 -0
  822. package/dist/ta/pmo.js +185 -0
  823. package/dist/ta/pmo.js.map +1 -0
  824. package/dist/ta/ppo.d.ts +37 -0
  825. package/dist/ta/ppo.d.ts.map +1 -0
  826. package/dist/ta/ppo.js +130 -0
  827. package/dist/ta/ppo.js.map +1 -0
  828. package/dist/ta/psar.d.ts +36 -0
  829. package/dist/ta/psar.d.ts.map +1 -0
  830. package/dist/ta/psar.js +283 -0
  831. package/dist/ta/psar.js.map +1 -0
  832. package/dist/ta/pvi.d.ts +32 -0
  833. package/dist/ta/pvi.d.ts.map +1 -0
  834. package/dist/ta/pvi.js +127 -0
  835. package/dist/ta/pvi.js.map +1 -0
  836. package/dist/ta/pvo.d.ts +34 -0
  837. package/dist/ta/pvo.d.ts.map +1 -0
  838. package/dist/ta/pvo.js +123 -0
  839. package/dist/ta/pvo.js.map +1 -0
  840. package/dist/ta/pvt.d.ts +26 -0
  841. package/dist/ta/pvt.d.ts.map +1 -0
  842. package/dist/ta/pvt.js +128 -0
  843. package/dist/ta/pvt.js.map +1 -0
  844. package/dist/ta/registry.d.ts +395 -0
  845. package/dist/ta/registry.d.ts.map +1 -0
  846. package/dist/ta/registry.js +440 -0
  847. package/dist/ta/registry.js.map +1 -0
  848. package/dist/ta/roc.d.ts +19 -0
  849. package/dist/ta/roc.d.ts.map +1 -0
  850. package/dist/ta/roc.js +80 -0
  851. package/dist/ta/roc.js.map +1 -0
  852. package/dist/ta/rsi.d.ts +28 -0
  853. package/dist/ta/rsi.d.ts.map +1 -0
  854. package/dist/ta/rsi.js +166 -0
  855. package/dist/ta/rsi.js.map +1 -0
  856. package/dist/ta/rvgi.d.ts +27 -0
  857. package/dist/ta/rvgi.d.ts.map +1 -0
  858. package/dist/ta/rvgi.js +139 -0
  859. package/dist/ta/rvgi.js.map +1 -0
  860. package/dist/ta/rvi.d.ts +31 -0
  861. package/dist/ta/rvi.d.ts.map +1 -0
  862. package/dist/ta/rvi.js +195 -0
  863. package/dist/ta/rvi.js.map +1 -0
  864. package/dist/ta/sessionVolumeProfile.d.ts +23 -0
  865. package/dist/ta/sessionVolumeProfile.d.ts.map +1 -0
  866. package/dist/ta/sessionVolumeProfile.js +164 -0
  867. package/dist/ta/sessionVolumeProfile.js.map +1 -0
  868. package/dist/ta/sma.d.ts +23 -0
  869. package/dist/ta/sma.d.ts.map +1 -0
  870. package/dist/ta/sma.js +112 -0
  871. package/dist/ta/sma.js.map +1 -0
  872. package/dist/ta/smi.d.ts +41 -0
  873. package/dist/ta/smi.d.ts.map +1 -0
  874. package/dist/ta/smi.js +134 -0
  875. package/dist/ta/smi.js.map +1 -0
  876. package/dist/ta/smma.d.ts +26 -0
  877. package/dist/ta/smma.d.ts.map +1 -0
  878. package/dist/ta/smma.js +105 -0
  879. package/dist/ta/smma.js.map +1 -0
  880. package/dist/ta/stdev.d.ts +25 -0
  881. package/dist/ta/stdev.d.ts.map +1 -0
  882. package/dist/ta/stdev.js +125 -0
  883. package/dist/ta/stdev.js.map +1 -0
  884. package/dist/ta/stoch.d.ts +32 -0
  885. package/dist/ta/stoch.d.ts.map +1 -0
  886. package/dist/ta/stoch.js +91 -0
  887. package/dist/ta/stoch.js.map +1 -0
  888. package/dist/ta/stochRsi.d.ts +35 -0
  889. package/dist/ta/stochRsi.d.ts.map +1 -0
  890. package/dist/ta/stochRsi.js +98 -0
  891. package/dist/ta/stochRsi.js.map +1 -0
  892. package/dist/ta/supertrend.d.ts +34 -0
  893. package/dist/ta/supertrend.d.ts.map +1 -0
  894. package/dist/ta/supertrend.js +181 -0
  895. package/dist/ta/supertrend.js.map +1 -0
  896. package/dist/ta/tema.d.ts +27 -0
  897. package/dist/ta/tema.d.ts.map +1 -0
  898. package/dist/ta/tema.js +75 -0
  899. package/dist/ta/tema.js.map +1 -0
  900. package/dist/ta/trendStrengthIndex.d.ts +35 -0
  901. package/dist/ta/trendStrengthIndex.d.ts.map +1 -0
  902. package/dist/ta/trendStrengthIndex.js +183 -0
  903. package/dist/ta/trendStrengthIndex.js.map +1 -0
  904. package/dist/ta/trix.d.ts +34 -0
  905. package/dist/ta/trix.d.ts.map +1 -0
  906. package/dist/ta/trix.js +135 -0
  907. package/dist/ta/trix.js.map +1 -0
  908. package/dist/ta/tsi.d.ts +37 -0
  909. package/dist/ta/tsi.d.ts.map +1 -0
  910. package/dist/ta/tsi.js +127 -0
  911. package/dist/ta/tsi.js.map +1 -0
  912. package/dist/ta/ulcerIndex.d.ts +34 -0
  913. package/dist/ta/ulcerIndex.d.ts.map +1 -0
  914. package/dist/ta/ulcerIndex.js +120 -0
  915. package/dist/ta/ulcerIndex.js.map +1 -0
  916. package/dist/ta/ultimateOsc.d.ts +27 -0
  917. package/dist/ta/ultimateOsc.d.ts.map +1 -0
  918. package/dist/ta/ultimateOsc.js +174 -0
  919. package/dist/ta/ultimateOsc.js.map +1 -0
  920. package/dist/ta/valuewhen.d.ts +27 -0
  921. package/dist/ta/valuewhen.d.ts.map +1 -0
  922. package/dist/ta/valuewhen.js +115 -0
  923. package/dist/ta/valuewhen.js.map +1 -0
  924. package/dist/ta/visibleRangeVolumeProfile.d.ts +26 -0
  925. package/dist/ta/visibleRangeVolumeProfile.d.ts.map +1 -0
  926. package/dist/ta/visibleRangeVolumeProfile.js +107 -0
  927. package/dist/ta/visibleRangeVolumeProfile.js.map +1 -0
  928. package/dist/ta/vol.d.ts +23 -0
  929. package/dist/ta/vol.d.ts.map +1 -0
  930. package/dist/ta/vol.js +58 -0
  931. package/dist/ta/vol.js.map +1 -0
  932. package/dist/ta/volatilityStop.d.ts +36 -0
  933. package/dist/ta/volatilityStop.d.ts.map +1 -0
  934. package/dist/ta/volatilityStop.js +203 -0
  935. package/dist/ta/volatilityStop.js.map +1 -0
  936. package/dist/ta/vortex.d.ts +30 -0
  937. package/dist/ta/vortex.d.ts.map +1 -0
  938. package/dist/ta/vortex.js +210 -0
  939. package/dist/ta/vortex.js.map +1 -0
  940. package/dist/ta/vwap.d.ts +33 -0
  941. package/dist/ta/vwap.d.ts.map +1 -0
  942. package/dist/ta/vwap.js +138 -0
  943. package/dist/ta/vwap.js.map +1 -0
  944. package/dist/ta/vwma.d.ts +24 -0
  945. package/dist/ta/vwma.d.ts.map +1 -0
  946. package/dist/ta/vwma.js +112 -0
  947. package/dist/ta/vwma.js.map +1 -0
  948. package/dist/ta/williamsFractal.d.ts +43 -0
  949. package/dist/ta/williamsFractal.d.ts.map +1 -0
  950. package/dist/ta/williamsFractal.js +171 -0
  951. package/dist/ta/williamsFractal.js.map +1 -0
  952. package/dist/ta/williamsR.d.ts +24 -0
  953. package/dist/ta/williamsR.d.ts.map +1 -0
  954. package/dist/ta/williamsR.js +75 -0
  955. package/dist/ta/williamsR.js.map +1 -0
  956. package/dist/ta/wma.d.ts +24 -0
  957. package/dist/ta/wma.d.ts.map +1 -0
  958. package/dist/ta/wma.js +106 -0
  959. package/dist/ta/wma.js.map +1 -0
  960. package/dist/ta/zigZag.d.ts +40 -0
  961. package/dist/ta/zigZag.d.ts.map +1 -0
  962. package/dist/ta/zigZag.js +296 -0
  963. package/dist/ta/zigZag.js.map +1 -0
  964. package/dist/views/barstateView.d.ts +44 -0
  965. package/dist/views/barstateView.d.ts.map +1 -0
  966. package/dist/views/barstateView.js +27 -0
  967. package/dist/views/barstateView.js.map +1 -0
  968. package/dist/views/index.d.ts +37 -0
  969. package/dist/views/index.d.ts.map +1 -0
  970. package/dist/views/index.js +28 -0
  971. package/dist/views/index.js.map +1 -0
  972. package/dist/views/refreshRuntimeViews.d.ts +15 -0
  973. package/dist/views/refreshRuntimeViews.d.ts.map +1 -0
  974. package/dist/views/refreshRuntimeViews.js +29 -0
  975. package/dist/views/refreshRuntimeViews.js.map +1 -0
  976. package/dist/views/symInfoView.d.ts +42 -0
  977. package/dist/views/symInfoView.d.ts.map +1 -0
  978. package/dist/views/symInfoView.js +32 -0
  979. package/dist/views/symInfoView.js.map +1 -0
  980. package/dist/views/timeframeView.d.ts +17 -0
  981. package/dist/views/timeframeView.d.ts.map +1 -0
  982. package/dist/views/timeframeView.js +47 -0
  983. package/dist/views/timeframeView.js.map +1 -0
  984. package/package.json +46 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,2690 @@
1
+ # @invinite-org/chartlang-runtime
2
+
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 9f5d7cb: `onHistory` now accumulates emissions across the bulk history walk so a single `drain` after a `history` event returns every bar's emissions (PLAN §6.1), instead of only the final bar's. Previously the per-bar reset inside `onBarClose` (correct for per-event drains) discarded the prior bars' emissions because `onHistory` walked the bars with no accumulator. Visible symptom in adapter consumers: indicator plots only rendered for the streamed tail after warmup, not the bulk-filled history.
8
+
9
+ ## 1.0.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 98599b2: Clamp `adxFromDi` outputs to [0, 100]: the Wilder seed mean and recurrence could overshoot 100 by a few ulps of floating-point error.
14
+ - d1de692: Fix end-user-blocking Node-ESM packaging bug. Every published `dist/index.js` previously failed to load under Node's strict ESM resolver because `tsc` had been configured with `moduleResolution: "Bundler"` and emitted relative specifiers verbatim, so `dist/index.js` carried `from "./api"` (extensionless) and Node rejected the resolution. Workspace consumers never saw this because tsx / vitest / Vite resolve loosely, but `npm install @invinite-org/chartlang-compiler` followed by `import` failed immediately for any Node consumer, and `examples/react-demo/vite.config.ts`'s server-side compile plugin broke at dev-config-load time.
15
+
16
+ This release switches `tsconfig.base.json` to `module: "NodeNext"` / `moduleResolution: "NodeNext"`, and rewrites every relative import / export / dynamic-import / `typeof import("…")` specifier across all packages' source to carry an explicit `.js` (or `/index.js`) suffix. The new resolution mode also surfaces this bug class as a compile error rather than runtime breakage, so it cannot regress.
17
+
18
+ No behavioural change for runtime consumers — the rewritten specifiers resolve to the same TypeScript sources at build time and the same `dist/<path>.js` files at consumer-load time.
19
+
20
+ - Updated dependencies [4d44a9c]
21
+ - Updated dependencies [d1de692]
22
+ - Updated dependencies [98599b2]
23
+ - @invinite-org/chartlang-adapter-kit@1.1.0
24
+ - @invinite-org/chartlang-core@1.0.1
25
+
26
+ ## 1.0.0
27
+
28
+ ### Major Changes
29
+
30
+ - chartlang `1.0.0` -- the `apiVersion: 1` standard.
31
+
32
+ - `apiVersion: 1` frozen: compiler accepts only the frozen language
33
+ version; `STATEFUL_PRIMITIVES` locked at 172 entries by exact
34
+ name-set; every shipping export `@stable`; pre-1.0 deprecations
35
+ removed (`PHASE_1_SCENARIOS`).
36
+ - Canonical language spec published (`docs/spec/`): grammar,
37
+ semantics, manifest, emissions, versioning -- self-contained for
38
+ alternate implementations. The `v1.0.0` tag is the frozen spec
39
+ snapshot.
40
+ - Public conformance reports: `pnpm conformance --report` emits
41
+ `CONFORMANCE.md` + `conformance-report.json`; canvas2d reference
42
+ report published and drift-gated.
43
+ - Adapter-author path proven end-to-end: scaffolded adapters ship a
44
+ wired conformance test; full writing-an-adapter tutorial +
45
+ Lightweight Charts porting walkthrough.
46
+ - Pine migration guide finalised with a pattern-coverage matrix
47
+ audited against the top ~50 Pine scripts.
48
+
49
+ ### Minor Changes
50
+
51
+ - d14a034: Add phase 5 server alerts, multi-timeframe request handling, runtime persistence, QuickJS hosting, expanded plot and table rendering, color helpers, alert conditions, and volume profile primitives.
52
+ - 3cfff10: Add lower-timeframe bar bucketing and cache helpers.
53
+ - 3cfff10: Phase 6 closeout for Tier-3 ergonomics and lower-timeframe support.
54
+ - 3cfff10: Wire runtime `request.lowerTf`, advertise sub-minute canvas2d intervals, and add LTF conformance scenarios.
55
+
56
+ ### Patch Changes
57
+
58
+ - Pre-1.0 surface cleanup: remove the deprecated `PHASE_1_SCENARIOS`
59
+ alias (use `ALL_SCENARIOS`) and promote every shipping export from
60
+ `@experimental` to `@stable` ahead of the `apiVersion: 1` freeze.
61
+ - Updated dependencies [d14a034]
62
+ - Updated dependencies [3cfff10]
63
+ - Updated dependencies [3cfff10]
64
+ - Updated dependencies [3cfff10]
65
+ - Updated dependencies [3cfff10]
66
+ - Updated dependencies
67
+ - Updated dependencies
68
+ - Updated dependencies
69
+ - @invinite-org/chartlang-adapter-kit@1.0.0
70
+ - @invinite-org/chartlang-core@1.0.0
71
+
72
+ ## 0.5.0
73
+
74
+ ### Phase 5
75
+
76
+ #### Minor Changes
77
+
78
+ - Ship Phase 5 `defineAlertCondition`, compiler manifest extraction, runtime `signal()` emissions, adapter validation, and conformance coverage per PLAN §11.2.
79
+ - Add `draw.table` with `TableCell`/`TablePosition` types, runtime emission,
80
+ viewport-anchored canvas2d rendering, and conformance coverage per PLAN §10.2.
81
+ - Add Phase 5 plot kinds, runtime emission dispatch, validation, conformance scenarios, and canvas2d reference renderers.
82
+ - Add the PLAN.md §6.8 HTF-to-LTF alignment kernel and WeakMap cache ported from invinite commit 3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4.
83
+ - Add the Phase 5 `runtime.log.*` and `runtime.error()` surface, log emissions, runtime halt diagnostics, and conformance coverage.
84
+ - Add the PLAN.md §6.9 persistent runtime snapshot store, warm-start restore flow, close/dispose snapshot saves, and snapshot diagnostics.
85
+ - Replace the Phase 4 `request.security` NaN-only path with real
86
+ multi-timeframe secondary stream alignment per PLAN.md §6.8 and §7.2.
87
+ Adapters can route tagged `CandleEvent.streamKey` candles, the worker
88
+ host dispatches them through `ScriptRunner.push`, conformance includes
89
+ MTF scenarios, and the private canvas2d reference adapter now declares
90
+ `multiTimeframe: true`.
91
+ - Port `ta.anchoredVolumeProfile` from invinite commit 3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4, adding the PLAN §9.2 horizontal-histogram volume-profile primitive and PLAN §10.1.1 input-time anchor workflow.
92
+ - Add `ta.fixedRangeVolumeProfile`, completing the Phase 5 volume-profile set
93
+ from PLAN §9.2 and §10.1.1 with fixed `[from, to]` anchors, frozen post-range
94
+ histograms, and `fixed-range-inverted` diagnostics. Ported from invinite
95
+ commit `3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4`.
96
+ - Port `ta.sessionVolumeProfile` from invinite commit 3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4, adding the PLAN §9.2 horizontal-histogram session volume-profile primitive, PLAN §4.8 syminfo-session fallback diagnostics, and compiler/runtime registration.
97
+ - Add `ta.visibleRangeVolumeProfile` per PLAN §9.2, ported from invinite commit `3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4`, with runtime histogram emission, compiler/core type surfaces, conformance coverage, and generated docs.
98
+
99
+ #### Patch Changes
100
+
101
+ - Snapshot alert metadata at emission time so later Proxy revocation or source
102
+ mutation cannot corrupt host drain serialization.
103
+ - Port the Phase 5 volume-profile shared math helpers for PLAN §9.2 and the §10.1.1 anchored profile primitives from invinite commit 3234c8c0c3f9880d9d1e3a3ee63ebd55ddd535f4.
104
+ - Updated dependencies
105
+ - Updated dependencies
106
+ - Updated dependencies
107
+ - Updated dependencies
108
+ - Updated dependencies
109
+ - Updated dependencies
110
+ - Updated dependencies
111
+ - Updated dependencies
112
+ - Updated dependencies
113
+ - Updated dependencies
114
+ - Updated dependencies
115
+ - Updated dependencies
116
+ - @invinite-org/chartlang-core@0.5.0
117
+ - @invinite-org/chartlang-adapter-kit@0.5.0
118
+
119
+ ## 0.4.0
120
+
121
+ ### Minor Changes
122
+
123
+ - 3f3ce38: Replace the Phase-0 placeholder with the Phase-1 runtime data
124
+ structures: `RingBuffer<T>` + `Float64RingBuffer` per PLAN.md §6.6,
125
+ `makeSeriesView` Proxy with stable identity across bars,
126
+ `createStreamState` (10-field OHLCV ring-buffer set + mutable `BarView`
127
+ - cached `Series<number>` views + `taSlots` map), `StateStore`
128
+ interface + `inMemoryStateStore` default, and `RuntimeContext` +
129
+ `ACTIVE_RUNTIME_CONTEXT` slot. Add `@invinite-org/chartlang-core` and
130
+ `@invinite-org/chartlang-adapter-kit` as workspace dependencies and
131
+ `fast-check ^3.20.0` as a devDep (first consumer; Tasks 6-7 reuse).
132
+ The execution loop and primitives land in Tasks 6-8.
133
+ - 3f3ce38: Add the Phase-1 emission primitives (`plot` / `hline` / `alert`) plus
134
+ the supporting `emissionsQueue` push helpers, the shared pane
135
+ resolver, and the FNV-1a alert dedupe-key hash. Each primitive runs
136
+ against `ACTIVE_RUNTIME_CONTEXT`, gates against the adapter's
137
+ `Capabilities` per PLAN §7.4 silent-no-op semantics, validates via
138
+ `@invinite-org/chartlang-adapter-kit`'s `validateEmission` at the
139
+ push boundary, and dedupes on `(slotId, bar)`. The runtime exports
140
+ expose dual signatures — script-facing `(value, opts?)` matches the
141
+ `ComputeContext` typing while the compiler-injected `(slotId, value,
142
+ opts?)` is what actually executes. Replaces the Task-6 throw-stub
143
+ bodies in `primitives.ts`; identity is preserved through the barrel
144
+ chain.
145
+ - 3f3ce38: Add `createScriptRunner` + the per-bar execution loop (`onHistory` /
146
+ `onBarClose` / `onBarTick` / `drain` / `dispose`) per PLAN §6.1 + §6.7.
147
+ The runner owns the `bar` / `series` synchronisation invariants, the
148
+ per-bar emission queue reset, and the `ACTIVE_RUNTIME_CONTEXT` slot
149
+ mutation around `compute`. Introduces a throw-stub `primitives.ts`
150
+ seam at `ta` / `plot` / `hline` / `alert` that Tasks 7-8 replace with
151
+ the real stateful implementations. End-to-end no-primitive `compute`
152
+ scripts now run through the full lifecycle, pinned by a 500-bar
153
+ determinism test and four §6.7 property invariants under fast-check.
154
+ - 3f3ce38: Port the nine Phase-1 `ta.*` primitives (`sma` / `ema` / `stdev` / `bb`
155
+ / `rsi` / `macd` / `atr` / `crossover` / `crossunder`) plus the shared
156
+ math helpers (`applyOffset`, `readSourceField`, `pickCandleSource`,
157
+ `smaFloat64`, `emaFloat64`, `rollingStddev`, `trSeries`,
158
+ `wilderSmoothing`) from the invinite reference math at HEAD
159
+ `d2d1043c1b039f66d2f3674526d303d31cf2f1e0`. Each primitive ships with
160
+ the §16.6 five-file test set (impl + unit + property + golden +
161
+ bench-threshold pair) and uses the chartlang primitive shape — a
162
+ slot-aware function with cached `Series<T>` output identity, an
163
+ `onBarTick` head-replace mode, and JSON-clean slot state for Phase-5
164
+ persistence. The runtime barrel re-exports `ta` (the script-facing
165
+ namespace, identity-equal to `TA_REGISTRY`), `TA_REGISTRY` (the
166
+ frozen 9-entry map Task 9's worker boot iterates), and
167
+ `RuntimeTaNamespace` (the slot-prefixed type). `primitives.ts` swaps
168
+ its `ta` throw-stub body for the real registry while preserving
169
+ identity, so `buildComputeContext` and `createScriptRunner` need no
170
+ change. BB and MACD compose their sub-EMAs / SMA / stdev via derived
171
+ sub-slot ids — a fix to a leaf primitive propagates for free.
172
+ - 38fb475: Phase 2 — `0.2` full indicator parity.
173
+
174
+ - 81 new `ta.*` primitives (6 cross-functional + 75 §9.2 ports);
175
+ `TA_REGISTRY` cardinality 9 -> 90; `STATEFUL_PRIMITIVES`
176
+ cardinality 12 -> 93.
177
+ - 5 new chained-MA helpers + 5 new stats/volatility helpers in
178
+ `packages/runtime/src/ta/lib/`.
179
+ - 6 new `PlotKind`s (histogram, bars, area, filled-band, label,
180
+ marker) + canvas2d renderers + `validateEmission` arms.
181
+ - `Bar` extended with `hl2` / `hlc3` / `ohlc4` / `hlcc4` derived
182
+ source fields — runtime already pre-computes on `BarView`.
183
+ - `Scenario` extended with `inlineSource?: string` so Phase-2
184
+ scenarios stay self-contained without bloating
185
+ `examples/scripts/`.
186
+ - `STATEFUL_PRIMITIVES` shape widened from `ReadonlySet<string>`
187
+ to `ReadonlySet<{ name: string; slot: boolean }>` to support
188
+ `ta.nz` (the only stateless `ta.*`).
189
+ - Universal `opts.offset` honoured on every `ta.*` primitive
190
+ (Phase-1 backfill in Task 29).
191
+ - `chartlang docs` subcommand generates
192
+ `docs/primitives/ta/<id>.md` per primitive.
193
+ - `PHASE_2_INDICATORS` + `PHASE_5_DEFERRED` inventories exported
194
+ from `@invinite-org/chartlang-conformance` and pinned by
195
+ `phase2Coverage.test.ts` (Task 30).
196
+ - 100% coverage maintained across every published package.
197
+ - `apiVersion: 1` script header unchanged; Phase 2 is additive
198
+ at runtime.
199
+
200
+ - 38fb475: Phase-2 Task 5 — cross-functional `ta.*` primitives + `STATEFUL_PRIMITIVES`
201
+ shape evolution.
202
+
203
+ Ships six new Pine-canonical `ta.*` primitives under
204
+ `packages/runtime/src/ta/`:
205
+
206
+ - `ta.nz(value, replacement?)` — stateless NaN-replacement.
207
+ - `ta.highest(source, length)` — rolling max (monotone deque + window
208
+ recompute).
209
+ - `ta.lowest(source, length)` — rolling min (mirror of `highest`).
210
+ - `ta.change(source, opts)` — first-difference `source[0] − source[length]`.
211
+ - `ta.valuewhen(condition, source, occurrence)` — source value at the
212
+ n-th most recent matching bar.
213
+ - `ta.barssince(condition)` — bars since the last `condition === true`.
214
+
215
+ Each primitive ships the §22.10 set: impl + unit + property + golden +
216
+ bench pair + conformance scenario (using the Phase-2 `inlineSource`
217
+ extension from Task 1) + auto-generated `docs/primitives/ta/<id>.md`.
218
+
219
+ `STATEFUL_PRIMITIVES` widens from `ReadonlySet<string>` to
220
+ `ReadonlySet<{ name: string; slot: boolean }>` so `ta.nz` (the only
221
+ stateless cross-functional primitive) can opt out of compiler slot-id
222
+ injection. Phase-1 entries flip to `slot: true`; `ta.nz` is the only
223
+ `slot: false` entry; the set cardinality grows from 12 → 18. The shape
224
+ update cascades through every compiler consumer
225
+ (`packages/compiler/src/api.ts`, `program.ts`,
226
+ `analysis/statefulCallInLoop.ts`, `transformers/callsiteIdInjection.ts`,
227
+ and their tests). The `statefulCallInLoop` analysis still flags every
228
+ entry inside a loop body — `slot: false` primitives are forbidden in
229
+ loops by Pine-parity convention.
230
+
231
+ `TA_REGISTRY` cardinality grows from 9 → 15. `RuntimeTaNamespace`
232
+ mirrors core's `TaNamespace` 1:1 with the standard `slotId` first-arg
233
+ on every method except `nz` (which carries the script-author signature
234
+ verbatim).
235
+
236
+ Compiler change is `patch`-level — the public API surface is
237
+ unchanged; only the internal `STATEFUL_PRIMITIVES` parameter shape
238
+ widens. Core/runtime/conformance bump `minor` for the new exports and
239
+ the new scenarios.
240
+
241
+ - 38fb475: Phase-2 Task 4 — stats / volatility / regression / pearson helpers.
242
+
243
+ Ports five new internal helpers into `packages/runtime/src/ta/lib/`:
244
+
245
+ - `donchianMid(high, low, length)` — `(max(high) + min(low)) / 2`
246
+ over a trailing window. Consumed by `ta.donchian` (Task 18) and
247
+ `ta.ichimoku` (Task 17).
248
+ - `wilderDirectional(high, low, close, length)` — Wilder `+DM` /
249
+ `-DM` + `+DI` / `-DI` per bar, smoothed via `wilderStep` (reused
250
+ from Phase-1 `lib/wilderSmoothing.ts`). Consumed by `ta.dmi` and
251
+ `ta.adx` (Task 16).
252
+ - `adxFromDi(plusDi, minusDi, length)` — `DX = 100 * |+DI - -DI| /
253
+ (+DI + -DI)`, Wilder-smoothed over `length`. Consumed by `ta.adx`
254
+ (Task 16).
255
+ - `linearRegression(source, length)` — rolling OLS slope /
256
+ intercept / value at the last bar of the window. Consumed by
257
+ `ta.lsma` (Task 8), `ta.dpo` (Task 10), and Phase-3's
258
+ `regressionTrend` drawing.
259
+ - `pearson(a, b, length)` — rolling Pearson correlation of two
260
+ equal-length series, output clamped to `[-1, 1]`. Consumed by
261
+ `ta.trendStrengthIndex` (Task 17); future Phase-5
262
+ `correlationCoeff` shares the helper.
263
+
264
+ Each helper carries the §16.6 test set scoped to its hot-path
265
+ status: unit + property tests for all five; bench pair for
266
+ `wilderDirectional`, `linearRegression`, and `pearson`
267
+ (`donchianMid` and `adxFromDi` reduce to two Math.max/min scans
268
+ and a Wilder smooth respectively — the consumer primitive benches
269
+ in Tasks 16, 18 cover the perf surface).
270
+
271
+ All five helpers carry the 4-line provenance header pinned at
272
+ invinite commit `078f41fe2569d659d5aba726da8bcb5d3e2ced02`.
273
+
274
+ - 38fb475: Phase-2 Task 7 — MA ports (`ta.dema`, `ta.tema`, `ta.kama`, `ta.alma`).
275
+
276
+ Adds four chained / adaptive moving averages on top of the Phase-1
277
+ EMA primitive + the Task-6 MA backbone. DEMA / TEMA compose EMA
278
+ sub-slots through `TA_REGISTRY` (`${slotId}/ema1` / `/ema2` / `/ema3`);
279
+ KAMA is Kaufman's adaptive MA with an efficiency-ratio-driven
280
+ smoothing constant; ALMA is the Arnaud Legoux MA with a precomputed
281
+ Gaussian weight kernel.
282
+
283
+ Each primitive ships the §22.10 set (impl + four test layers +
284
+ conformance scenario + auto-generated docs page). ALMA's `offset`
285
+ opt is the Gaussian-centre position in `[0, 1]` (default `0.85`) —
286
+ distinct from the universal bar-shift, which lives on `opts.barShift`
287
+ for ALMA only.
288
+
289
+ Compiler patch: the ambient shim mirrors the four new
290
+ `TaNamespace` methods + opt bags.
291
+
292
+ - 38fb475: Phase-2 Task 8 — final §9.2 MA ports (`ta.lsma`, `ta.mcginley`, `ta.maRibbon`).
293
+
294
+ Closes out the §9.2 moving-averages list. `ta.lsma` is the linear-
295
+ regression value at the trailing window (reuses Task-4's
296
+ `linearRegression` helper for the property-test reference);
297
+ `ta.mcginley` is the McGinley Dynamic recurrence with NaN-correct
298
+ zero-anchor handling; `ta.maRibbon` is a fan of K MAs at different
299
+ lengths, dispatched per-bar through `TA_REGISTRY`'s registered MA
300
+ primitives (`sma` / `ema` / `wma` / `smma`) via sub-slot ids
301
+ `${slotId}/ma_<length>`.
302
+
303
+ `MaRibbonResult` is a dynamic-keyed record `{ ma_<length>:
304
+ Series<number> }`. The exported `maRibbonOutputKeys(opts)` helper
305
+ returns the ordered keys for stable iteration. `maRibbon` is
306
+ registry-tagged as multi-output via `TA_REGISTRY_METADATA` with its
307
+ default `primarySeriesKey: "ma_50"` + default visible keys
308
+ `["ma_10", "ma_20", "ma_30", "ma_40", "ma_50"]` + `{ kind: "auto" }`
309
+ y-domain — runtime metadata for legend chips and pane axes.
310
+
311
+ Core also adds the `MaTypeNoVolume` string-literal union (parallel to
312
+ the runtime's `lib/maTypes.ts` alias) so script authors can type the
313
+ `maType` opt directly. Each primitive ships the §22.10 set (impl +
314
+ four test layers + conformance scenario + auto-generated docs page).
315
+
316
+ Compiler patch: the ambient shim mirrors the three new `TaNamespace`
317
+ methods + opt bags + `MaTypeNoVolume` alias + `MaRibbonResult` type.
318
+
319
+ - 38fb475: Phase-2 Task 6 — MA ports (`ta.wma`, `ta.vwma`, `ta.hma`, `ta.smma`).
320
+
321
+ Adds four moving-average primitives on top of the Task-3 chained-MA
322
+ helpers. `ta.wma` is a linear-weighted MA over the trailing window;
323
+ `ta.vwma` is the volume-weighted variant; `ta.smma` is Wilder's
324
+ smoothed MA (α = 1/N); `ta.hma` is the Hull MA composed via three WMA
325
+ sub-slots derived from the parent slot id (`${slotId}/half`,
326
+ `${slotId}/full`, `${slotId}/final`).
327
+
328
+ Each primitive ships the §22.10 set (impl + four test layers +
329
+ conformance scenario + auto-generated docs page). The opts bags
330
+ (`WmaOpts`, `VwmaOpts`, `HmaOpts`, `SmmaOpts`) carry the universal
331
+ `offset` + `lineStyle` fields — typed surface only; the runtime
332
+ wiring lands in Task 29's universal-offset backfill.
333
+
334
+ Compiler patch: the ambient shim mirrors the four new
335
+ `TaNamespace` methods + opt bags.
336
+
337
+ - 38fb475: Phase-2 Task 13 — momentum ports (`ta.ao`, `ta.cmo`, `ta.momentum`,
338
+ `ta.roc`).
339
+
340
+ Ships four new momentum primitives under `packages/runtime/src/ta/`:
341
+
342
+ - `ta.ao(opts?)` — Awesome Oscillator. `SMA(hl2, fastLength) − SMA(hl2,
343
+ slowLength)`. Defaults to Pine-canonical `5` / `34`. Composes two
344
+ `ta.sma` sub-slots (`${slotId}/fastSma`, `${slotId}/slowSma`); a fix
345
+ to `sma` flows in for free.
346
+ - `ta.cmo(source, length, opts?)` — Chande Momentum Oscillator. Range
347
+ `[-100, 100]`. Trailing-window of per-bar gain / loss diffs with
348
+ incremental sum maintenance + flat-line (zero-denominator) NaN
349
+ guard.
350
+ - `ta.momentum(source, length, opts?)` — Pine `mom`. First-difference
351
+ `source[0] − source[length]`. Implemented as a thin shim around
352
+ `ta.change` (`${slotId}/change` sub-slot) — no private subtraction
353
+ loop.
354
+ - `ta.roc(source, length, opts?)` — Rate of Change. `100 ×
355
+ (source[0] − source[length]) / source[length]`. Zero lookback →
356
+ NaN.
357
+
358
+ Each primitive ships the §22.10 set: impl + unit + property + golden +
359
+ bench pair + conformance scenario (using the Phase-2 `inlineSource`
360
+ extension from Task 1) + auto-generated `docs/primitives/ta/<id>.md`.
361
+
362
+ `STATEFUL_PRIMITIVES` gains four new `slot: true` entries; `TaNamespace`
363
+
364
+ - `RuntimeTaNamespace` gain four new methods; `TA_REGISTRY` gains four
365
+ new entries. Four new opts types exported from core: `AoOpts`,
366
+ `CmoOpts`, `MomentumOpts`, `RocOpts` (each carries `offset?: number` and
367
+ `lineStyle?: PlotLineStyle` forward-compat fields; `AoOpts` also
368
+ carries `fastLength?: number`, `slowLength?: number`).
369
+
370
+ Provenance: ported from `invinite/src/components/trading-chart/
371
+ indicators/{ao,cmo,momentum,roc}.ts` at commit
372
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`.
373
+
374
+ - 38fb475: Phase-2 Task 14 — momentum ports (`ta.pmo`, `ta.smi`, `ta.tsi`).
375
+
376
+ Ships three double-smoothed momentum primitives under
377
+ `packages/runtime/src/ta/`:
378
+
379
+ - `ta.pmo(source, opts?)` — Carl Swenlin's Price Momentum Oscillator
380
+ (`{ pmo, signal }`). Three-pass smoothing of the 1-bar ROC, scaled
381
+ to PMO's characteristic ±10 swing range. The two inner stages use
382
+ a non-canonical "Swenlin EMA" factor (`α = 2 / length`) instead of
383
+ the standard `α = 2 / (length + 1)`; the signal-line EMA composes
384
+ the canonical `ta.ema` via a `${slotId}/signal` sub-slot. Defaults
385
+ `(firstSmoothing, secondSmoothing, signalLength) = (35, 20, 10)`
386
+ per TradingView's published formula.
387
+ - `ta.smi(opts?)` — William Blau's Stochastic Momentum Index
388
+ (`{ smi, signal }`). Composes `ta.highest` over `bar.high` and
389
+ `ta.lowest` over `bar.low` (`kLength` window) for the rolling
390
+ midpoint and range, then double-EMA-smooths both numerator
391
+ (`bar.close − midpoint`) and denominator (`range / 2`) through two
392
+ EMA layers each, then computes `100 × numSmoothed / denSmoothed`
393
+ and feeds it through a signal EMA. Bounded `[-100, 100]` (flat
394
+ range → NaN at smi). Defaults `(kLength, firstSmoothing,
395
+ secondSmoothing, dLength) = (10, 3, 5, 3)`.
396
+ - `ta.tsi(source, opts?)` — William Blau's True Strength Index
397
+ (momentum-class; `{ tsi, signal }`). Double-EMA-smoothed ratio of
398
+ one-bar price changes vs their absolute values, scaled ×100.
399
+ Bounded `[-100, 100]` (flat input → NaN at tsi). Defaults
400
+ `(firstSmoothing, secondSmoothing, signalLength) = (25, 13, 13)`
401
+ per TradingView's published TSI study. Note: this is the
402
+ **momentum**-class TSI; the **trend**-class True Strength Index
403
+ ships in Task 17 as `ta.trendStrengthIndex`.
404
+
405
+ Each primitive ships the §22.10 set: impl + unit + property +
406
+ golden + bench pair + conformance scenario (using the Phase-2
407
+ `inlineSource` extension from Task 1) + auto-generated
408
+ `docs/primitives/ta/<id>.md` page.
409
+
410
+ `TA_REGISTRY_METADATA` extends with three new entries: `pmo` and
411
+ `tsi` advertise `primarySeriesKey` + `visibleSeriesKeys` with
412
+ `yDomain: { kind: "auto" }`; `smi` is `{ kind: "fixed", min: -100,
413
+ max: 100 }`.
414
+
415
+ Core surface widens with `PmoOpts` / `PmoResult`, `SmiOpts` /
416
+ `SmiResult`, `TsiOpts` / `TsiResult` plus matching `TaNamespace`
417
+ methods and throw-sentinel stubs. `STATEFUL_PRIMITIVES` extends
418
+ with `ta.pmo` / `ta.smi` / `ta.tsi` (all `slot: true`).
419
+
420
+ Three conformance scenarios (`taPmo.scenario.ts`,
421
+ `taSmi.scenario.ts`, `taTsi.scenario.ts`) registered against
422
+ `ALL_SCENARIOS` via the Task-1 `inlineSource` extension.
423
+ Plot-hash pinning deferred to Phase-2 closeout (Task 30) per the
424
+ established cross-functional scenario convention.
425
+
426
+ Provenance: ported from `invinite/src/components/trading-chart/
427
+ indicators/{pmo,smi,tsi}.ts` at commit
428
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`.
429
+
430
+ - 38fb475: Phase-2 Task 29 — Universal `opts.offset` backfill on Phase-1 primitives.
431
+
432
+ Wires the universal `opts.offset` (PLAN.md §9.1) onto every Phase-1
433
+ `ta.*` primitive: `sma`, `ema`, `stdev`, `bb`, `rsi`, `macd`, `atr`,
434
+ `crossover`, `crossunder`. Positive `offset` shifts the returned
435
+ series so `series.current` reads the value `offset` bars ago
436
+ (matching `lib/applyOffset`'s `out[i] = values[i − offset]`
437
+ semantics); negative `offset` reads into the future (NaN /
438
+ undefined at the head). `offset === 0` is the strict identity
439
+ fast path — returns the slot's cached un-shifted Series with the
440
+ same reference as before this change (existing identity-pinned
441
+ tests continue to pass).
442
+
443
+ Surface expansion (core, minor):
444
+
445
+ - `offset?: number` added to `SmaOpts`, `EmaOpts`, `StdevOpts`,
446
+ `BbOpts`, `RsiOpts`, `MacdOpts`, `AtrOpts` (Phase-1 opts types
447
+ that previously had no `offset` field).
448
+ - New `CrossoverOpts` / `CrossunderOpts` types (the two cross
449
+ primitives previously took no opts bag); `TaNamespace.crossover`
450
+ / `crossunder` signatures gain an optional 3rd opts arg.
451
+ - New `makeShiftedSeriesView` runtime helper next to
452
+ `makeSeriesView` (in `packages/runtime/src/seriesView.ts`,
453
+ re-exported from the runtime barrel) — wraps a `RingBufferLike<T>`
454
+ in a Proxy that adjusts `at(n)` reads by `offset`.
455
+
456
+ Composite primitives (`bb`, `macd`) shift all outputs in lockstep
457
+ under a single `offset` value, returning a frozen result record
458
+ cached per offset on the slot. Sub-slot outputs (sma's middle,
459
+ ema's signal) are accessed through their captured ring-buffer
460
+ reference so the parent primitive doesn't re-enter the sub-slot's
461
+ compute on the shifted-view lookup.
462
+
463
+ Compiler patch: the ambient shim in `packages/compiler/src/program.ts`
464
+ mirrors the core type changes (new `offset?` fields + new
465
+ `CrossoverOpts` / `CrossunderOpts` types + extended `TaNamespace`
466
+ signatures).
467
+
468
+ Goldens, bench thresholds, and conformance scenarios are
469
+ unchanged — `offset === 0` is the default and exercises the
470
+ existing code paths. New per-primitive `<id>.test.ts` and
471
+ `<id>.property.test.ts` cases cover positive, negative, zero, and
472
+ identity-cache behaviour for offset.
473
+
474
+ - 38fb475: Phase-2 Task 9 — oscillator ports: `ta.cci`, `ta.stoch`, `ta.williamsR`.
475
+
476
+ Ships three foundational momentum / oscillator primitives under
477
+ `packages/runtime/src/ta/`:
478
+
479
+ - `ta.cci(source, length, opts?)` — Commodity Channel Index over a
480
+ configurable source (typically `bar.hlc3`). Lambert constant
481
+ `scaling = 0.015` hard-coded; flat-window (`meanDev === 0`) emits
482
+ `NaN`. Unbounded by construction.
483
+ - `ta.stoch(opts?)` — Stochastic Oscillator (`%K` + `%D`) over
484
+ `bar.high` / `bar.low` / `bar.close`. Composes `ta.highest` +
485
+ `ta.lowest` + two chained `ta.sma` smoothing layers via sub-slot
486
+ ids. Bounded `[0, 100]` (or `NaN`). Defaults `(kLength=14,
487
+ kSmoothing=3, dLength=3)`.
488
+ - `ta.williamsR(length, opts?)` — Williams %R over `bar.high` /
489
+ `bar.low` / `bar.close`. Composes `ta.highest` + `ta.lowest`.
490
+ Bounded `[-100, 0]` (or `NaN`).
491
+
492
+ Each primitive ships the §22.10 set: impl + unit + property + golden
493
+
494
+ - bench pair + conformance scenario (inlined per Task 1) +
495
+ auto-generated `docs/primitives/ta/<id>.md`.
496
+
497
+ Introduces a new metadata layer on the runtime registry:
498
+
499
+ - `TA_REGISTRY_METADATA: Readonly<Partial<Record<keyof typeof
500
+ TA_REGISTRY, PrimitiveMetadata>>>` — per-primitive `primarySeriesKey`,
501
+ `visibleSeriesKeys`, and `yDomain` hints for renderers (pane layout,
502
+ legend ordering, y-axis scaling). `ta.stoch` records
503
+ `primarySeriesKey: "k"`, `visibleSeriesKeys: ["k", "d"]`,
504
+ `yDomain: { kind: "fixed", min: 0, max: 100 }`; `ta.williamsR`
505
+ records `yDomain: { kind: "fixed", min: -100, max: 0 }`. Unbounded
506
+ primitives (e.g. `ta.cci`, `ta.sma`) carry no metadata entry —
507
+ consumers default to `auto`.
508
+
509
+ Core surface widens with `CciOpts`, `StochOpts`, `WilliamsROpts` opts
510
+ bags + `StochResult` two-output type, plus the matching `TaNamespace`
511
+ methods and throw-sentinel stubs. `STATEFUL_PRIMITIVES` extends with
512
+ `ta.cci` / `ta.stoch` / `ta.williamsR` (all `slot: true`). Compiler
513
+ shim mirrors the new core surface.
514
+
515
+ Three conformance scenarios (`taCci.scenario.ts`, `taStoch.scenario.ts`,
516
+ `taWilliamsR.scenario.ts`) registered against `ALL_SCENARIOS` via
517
+ the Task-1 `inlineSource` extension. Plot-hash pinning deferred to
518
+ Phase-2 closeout (Task 30) per the established cross-functional
519
+ scenario convention.
520
+
521
+ DIVERGENCE from invinite reference (`stoch.ts`): the spec requires
522
+ flat-window (`hh === ll`) → `NaN` at `k`, whereas invinite falls back
523
+ to the prior valid kRaw (or 50 on the first slot, per TradingView).
524
+ The task spec overrides; documented in the impl's provenance header.
525
+
526
+ `CciOpts` intentionally narrows away invinite's `scaling` knob —
527
+ chartlang hard-codes the canonical Lambert constant.
528
+
529
+ - 38fb475: Phase-2 Task 12 — oscillator ports: `ta.kst`, `ta.fisher`,
530
+ `ta.klinger`, `ta.rvgi`.
531
+
532
+ Ships four more multi-output oscillator primitives under
533
+ `packages/runtime/src/ta/`:
534
+
535
+ - `ta.kst(source, opts?)` — Know Sure Thing (Martin Pring, 1992).
536
+ Weighted sum of four SMA-smoothed percentage ROCs plus an SMA
537
+ signal line. Composes 4 `ta.sma` sub-slots for the per-ROC
538
+ smoothing plus one `ta.sma` for the signal; the four percentage
539
+ ROCs are computed inline against a shared `sourceWindow` ring
540
+ (mirrors `ta.coppock` — `ta.change` emits absolute deltas, while
541
+ KST needs percentage rate-of-change). Defaults
542
+ `(10, 15, 20, 30, 10, 10, 10, 15, 9)`.
543
+ - `ta.fisher(length, opts?)` — John Ehlers' Fisher Transform over
544
+ rolling `bar.hl2`. Composes `ta.highest` + `ta.lowest` sub-slots;
545
+ the clamp / atanh / EMA-blend recurrence is bespoke. The `trigger`
546
+ output is the prior bar's `fisher` value (1-bar lag); first bar's
547
+ `trigger` is NaN. Diverges from invinite's ±0.999 clamp per task
548
+ spec — when the recurrence would drive `|x| ≥ 1` we emit NaN at
549
+ `fisher` and hold the recurrence state.
550
+ - `ta.klinger(opts?)` — Klinger Volume Oscillator. Per-bar Volume
551
+ Force accumulator drives the difference of two `ta.ema` sub-slots
552
+ (`fastLength` / `slowLength`); the `signal` is a third
553
+ `ta.ema(klinger, signalLength)`. Defaults `(34, 55, 13)`.
554
+ - `ta.rvgi(opts?)` — Relative Vigor Index (John Ehlers, 2002).
555
+ 4-bar `(1, 2, 2, 1) / 6` weighted numerator (`close − open`) and
556
+ denominator (`high − low`), each smoothed via `ta.sma` sub-slot;
557
+ `rvgi = numSma / denSma`. Signal is a 4-bar weighted sum of the
558
+ rvgi line. Defaults `length = 10`; flat-range bars emit NaN.
559
+
560
+ Each primitive ships the §22.10 set: impl + unit + property + golden
561
+
562
+ - bench pair + conformance scenario (inlined per Task 1) +
563
+ auto-generated `docs/primitives/ta/<id>.md`.
564
+
565
+ Extends `TA_REGISTRY_METADATA` with four new entries (all
566
+ `primarySeriesKey` + `visibleSeriesKeys`; all `yDomain: { kind:
567
+ "auto" }` per task §5):
568
+
569
+ - `kst`: `primarySeriesKey: "kst"`, `visibleSeriesKeys: ["kst", "signal"]`.
570
+ - `fisher`: `primarySeriesKey: "fisher"`, `visibleSeriesKeys: ["fisher", "trigger"]`.
571
+ - `klinger`: `primarySeriesKey: "klinger"`, `visibleSeriesKeys: ["klinger", "signal"]`.
572
+ - `rvgi`: `primarySeriesKey: "rvgi"`, `visibleSeriesKeys: ["rvgi", "signal"]`.
573
+
574
+ Core surface widens with `KstOpts`, `FisherOpts`, `KlingerOpts`,
575
+ `RvgiOpts` opts bags + `KstResult`, `FisherResult`, `KlingerResult`,
576
+ `RvgiResult` two-output types, plus the matching `TaNamespace`
577
+ methods and throw-sentinel stubs. `STATEFUL_PRIMITIVES` extends
578
+ with `ta.kst` / `ta.fisher` / `ta.klinger` / `ta.rvgi` (all
579
+ `slot: true`). Compiler shim mirrors the new core surface.
580
+
581
+ Four conformance scenarios (`taKst.scenario.ts`,
582
+ `taFisher.scenario.ts`, `taKlinger.scenario.ts`,
583
+ `taRvgi.scenario.ts`) registered against `ALL_SCENARIOS` via the
584
+ Task-1 `inlineSource` extension. Plot-hash pinning deferred to
585
+ Phase-2 closeout (Task 30) per the established multi-output scenario
586
+ convention.
587
+
588
+ - 38fb475: Phase-2 Task 10 — oscillator ports: `ta.ppo`, `ta.dpo`,
589
+ `ta.connorsRsi`.
590
+
591
+ Ships three derived oscillator primitives under
592
+ `packages/runtime/src/ta/`:
593
+
594
+ - `ta.ppo(source, opts?)` — Percentage Price Oscillator, the
595
+ scale-invariant cousin of MACD. Three outputs (`{ ppo, signal,
596
+ hist }`) over `100 * (fastEma - slowEma) / slowEma`. Composes three
597
+ `ta.ema` sub-slots (`${slotId}/fast`, `${slotId}/slow`,
598
+ `${slotId}/signal`) per §9.4 — folds invinite's private EMA copy
599
+ onto the canonical primitive. Defaults `(12, 26, 9)`. `slow === 0`
600
+ emits `NaN` at the PPO line; signal can still be defined off prior
601
+ values.
602
+ - `ta.dpo(source, length, opts?)` — Detrended Price Oscillator
603
+ (non-centered, TradingView default). `dpo[i] = source[i -
604
+ displacement] - sma[i]` with `displacement = floor(length / 2) +
605
+ 1`. Composes one `ta.sma` sub-slot plus a per-slot source-window
606
+ Float64RingBuffer for the O(1) per-bar shifted-source lookup.
607
+ - `ta.connorsRsi(source, opts?)` — Connors RSI, a `[0, 100]`-bounded
608
+ blend of `RSI(source, rsiLength)`, `RSI(streak, streakLength)`,
609
+ and `PercentRank(ROC(source, 1), rocLength)`. Composes two
610
+ `ta.rsi` sub-slots — no private RSI math duplication. Defaults
611
+ `(3, 2, 100)`. Sub-component NaN → component skipped in the
612
+ average (per task spec §6, diverges from invinite's stricter
613
+ all-finite requirement to align with the Pine semantic).
614
+
615
+ Each primitive ships the §22.10 set: impl + unit + property +
616
+ golden + bench pair + conformance scenario (inlined per Task 1) +
617
+ auto-generated `docs/primitives/ta/<id>.md`.
618
+
619
+ `TA_REGISTRY_METADATA` extends with:
620
+
621
+ - `ppo`: `primarySeriesKey: "ppo"`, `visibleSeriesKeys: ["ppo",
622
+ "signal", "hist"]`, `yDomain: { kind: "auto" }`.
623
+ - `connorsRsi`: `yDomain: { kind: "fixed", min: 0, max: 100 }`.
624
+ - `dpo`: no metadata entry (unbounded — consumers default to
625
+ `auto`).
626
+
627
+ Core surface widens with `PpoOpts`, `DpoOpts`, `ConnorsRsiOpts`
628
+ opts bags + `PpoResult` three-output type, plus the matching
629
+ `TaNamespace` methods and throw-sentinel stubs.
630
+ `STATEFUL_PRIMITIVES` extends with `ta.ppo` / `ta.dpo` /
631
+ `ta.connorsRsi` (all `slot: true`). Compiler shim mirrors the new
632
+ core surface.
633
+
634
+ Three conformance scenarios (`taPpo.scenario.ts`,
635
+ `taDpo.scenario.ts`, `taConnorsRsi.scenario.ts`) registered against
636
+ `ALL_SCENARIOS` via the Task-1 `inlineSource` extension.
637
+ Plot-hash pinning deferred to Phase-2 closeout (Task 30) per the
638
+ established cross-functional scenario convention.
639
+
640
+ DEVIATIONS from invinite reference (commit
641
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`):
642
+
643
+ - `ppo.ts` — invinite carries a private EMA copy
644
+ (`computeMaSeries(oscillatorMaType, ...)`); chartlang routes
645
+ through the canonical `ta.ema` primitive via sub-slot
646
+ composition (matches `ta.macd`). §9.4 fold satisfied.
647
+ - `dpo.ts` — only the non-centered (TradingView default) render
648
+ mode is shipped. Invinite's `centered: true` mode emits
649
+ `dpo[i] = src[i] - sma[i + displacement]`, which depends on the
650
+ future SMA; chartlang's append-only ring-buffer contract can't
651
+ backfill, so that mode is deferred. Documented in the impl's
652
+ provenance header.
653
+ - `connorsRsi.ts` — invinite requires all three components finite
654
+ for the CRSI line to define; the task spec (§6) overrides with
655
+ "sub-component NaN → component skipped in the average". We
656
+ follow the spec, which tightens alignment with the Pine
657
+ `ta.connorsRsi` semantic where streak-RSI warmup doesn't gate
658
+ the rsi-on-close component.
659
+
660
+ - 38fb475: Phase-2 Task 11 — oscillator ports: `ta.stochRsi`, `ta.ultimateOsc`,
661
+ `ta.coppock`.
662
+
663
+ Ships three more oscillator primitives under
664
+ `packages/runtime/src/ta/`:
665
+
666
+ - `ta.stochRsi(source, opts?)` — Stochastic RSI (`%K` + `%D`).
667
+ Composes `ta.rsi` + `ta.highest` + `ta.lowest` + two chained
668
+ `ta.sma` smoothing layers via sub-slot ids. Bounded `[0, 100]`
669
+ (or `NaN`). Defaults `(rsiLength=14, stochLength=14, kSmoothing=3,
670
+ dSmoothing=3)`. Flat-RSI-window (`hh === ll`) emits `NaN` at `k`
671
+ — diverges from invinite's prev-or-50 fallback per task spec.
672
+ - `ta.ultimateOsc(opts?)` — Larry Williams' Ultimate Oscillator over
673
+ `bar.high` / `bar.low` / `bar.close`. Weighted average of three
674
+ buying-pressure / true-range ratios across `shortLength` /
675
+ `mediumLength` / `longLength` windows (defaults `7` / `14` / `28`).
676
+ Bounded `[0, 100]` (or `NaN`); zero-TR window emits `NaN`.
677
+ - `ta.coppock(source, opts?)` — Edwin Coppock's Curve.
678
+ `WMA(ROC(source, roc1Length) + ROC(source, roc2Length),
679
+ wmaLength)` over percentage ROC. Defaults `(11, 14, 10)`. Unbounded;
680
+ zero-crossings are the canonical signal. Inlines the percentage-ROC
681
+ computation against its own `sourceWindow` (the spec's hint to
682
+ compose `ta.change` does not fit — `ta.change` emits absolute
683
+ deltas, not percentages).
684
+
685
+ Each primitive ships the §22.10 set: impl + unit + property + golden
686
+
687
+ - bench pair + conformance scenario (inlined per Task 1) +
688
+ auto-generated `docs/primitives/ta/<id>.md`.
689
+
690
+ Extends `TA_REGISTRY_METADATA` with two new bounded-oscillator
691
+ entries:
692
+
693
+ - `stochRsi`: `primarySeriesKey: "k"`, `visibleSeriesKeys: ["k", "d"]`,
694
+ `yDomain: { kind: "fixed", min: 0, max: 100 }`.
695
+ - `ultimateOsc`: `yDomain: { kind: "fixed", min: 0, max: 100 }`.
696
+
697
+ `ta.coppock` is unbounded — no metadata entry; consumers default to
698
+ `auto`.
699
+
700
+ Core surface widens with `StochRsiOpts`, `UltimateOscOpts`,
701
+ `CoppockOpts` opts bags + `StochRsiResult` two-output type, plus the
702
+ matching `TaNamespace` methods and throw-sentinel stubs.
703
+ `STATEFUL_PRIMITIVES` extends with `ta.stochRsi` / `ta.ultimateOsc` /
704
+ `ta.coppock` (all `slot: true`). Compiler shim mirrors the new core
705
+ surface.
706
+
707
+ Three conformance scenarios (`taStochRsi.scenario.ts`,
708
+ `taUltimateOsc.scenario.ts`, `taCoppock.scenario.ts`) registered
709
+ against `ALL_SCENARIOS` via the Task-1 `inlineSource` extension.
710
+ Plot-hash pinning deferred to Phase-2 closeout (Task 30) per the
711
+ established cross-functional scenario convention.
712
+
713
+ - 38fb475: Phase-2 Task 26 — S/R ports: `ta.chandelier`, `ta.chandeKrollStop`,
714
+ `ta.williamsFractal`.
715
+
716
+ Ships three new S/R `ta.*` primitives under
717
+ `packages/runtime/src/ta/`:
718
+
719
+ - `ta.chandelier(opts?)` — Chandelier Exit returning
720
+ `{ long, short }`. Composes Phase-1 `ta.atr` plus Task-5
721
+ `ta.highest` / `ta.lowest` at sub-slots `${slotId}/atr` /
722
+ `${slotId}/highHigh` / `${slotId}/lowLow`. `long = highest(high,
723
+ length) − multiplier · atr(length)`; `short` symmetric. Defaults
724
+ `length = 22`, `multiplier = 3` per Pine canonical. Source
725
+ hard-coded to `bar.high` / `bar.low` (deliberate divergence from
726
+ invinite's `source` parameter — matches Pine `ta.chandelier_exit`).
727
+
728
+ - `ta.chandeKrollStop(opts?)` — Chande Kroll Stop returning
729
+ `{ long, short }`. Two-pass smoothed trailing stop: first pass
730
+ computes `firstHigh = highest(high, length) − multiplier · atr` /
731
+ `firstLow = lowest(low, length) + multiplier · atr` (composed via
732
+ `ta.atr` + `ta.highest` / `ta.lowest` sub-slots); second pass
733
+ walks a slot-owned `Float64RingBuffer` of size `smoothingLength`
734
+ for the rolling max / min. Defaults `length = 10`, `multiplier = 1`,
735
+ `smoothingLength = 9` (matches Chande Kroll's 1995 paper).
736
+
737
+ - `ta.williamsFractal(opts?)` — Williams Fractal returning
738
+ `{ up, down }` as **price-level series** (NaN when no fractal,
739
+ `bar.high(centre)` for up-fractal, `bar.low(centre)` for down).
740
+ Self-contained centred-window scan over a `2 · length + 1` ring
741
+ buffer per side. Output is centred: at live bar `t`, the value
742
+ emitted reflects bar `t − length`'s fractal status (when bar `t`
743
+ closes, we now have the right-window bars to confirm bar
744
+ `t − length`). Default `length = 2` (5-bar window). Strict
745
+ comparison: tied highs/lows in the window → no fractal.
746
+
747
+ Deviation from the task spec's literal `Series<boolean>` wording:
748
+ emits price levels instead so the `marker` plot has a meaningful
749
+ y-anchor. Matches invinite's `upFractals[i] = high` shape.
750
+
751
+ Each primitive ships the §22.10 set (impl + unit + property + golden
752
+ hash + bench pair) plus a `taChandelier.scenario.ts`,
753
+ `taChandeKrollStop.scenario.ts`, and `taWilliamsFractal.scenario.ts`
754
+ conformance scenario. JSDoc per §17.2 with `@formula`, `@warmup`,
755
+ `@since 0.2`, `@experimental`, `@example`, and `@anchors`.
756
+
757
+ **`PlotOptsStyle` marker widening (core + runtime + compiler shim).**
758
+ Adds the `marker` variant to `PlotOptsStyle` in core (mirrors the
759
+ adapter-kit's `PlotStyle.marker` shape declared by Task 1), the
760
+ matching dispatch branch to `buildStyle` in
761
+ `packages/runtime/src/emit/plot.ts`, and the same widening in the
762
+ compiler's ambient shim. The Williams Fractal scenario is the first
763
+ to exercise the marker plot kind end-to-end. The cap-gated dispatch
764
+ path is unit-covered in `plot.test.ts`'s new marker case.
765
+
766
+ `TaNamespace` (core) and `RuntimeTaNamespace` (runtime) extend with
767
+ three new methods + matching opts / result types. `STATEFUL_PRIMITIVES`
768
+ appends three new `slot: true` entries. `TA_REGISTRY` adds three
769
+ entries plus `TA_REGISTRY_METADATA` records for each
770
+ (`primarySeriesKey` / `visibleSeriesKeys` / `yDomain = auto`).
771
+
772
+ Auto-generated documentation pages land at
773
+ `docs/primitives/ta/{chandelier,chandeKrollStop,williamsFractal}.md`
774
+ via the Task-2 generator. The `docs/primitives/ta/index.md` carries a
775
+ new "S/R (Task 26)" subsection.
776
+
777
+ - 38fb475: Phase-2 Task 25 — S/R ports: `ta.psar` and `ta.supertrend`.
778
+
779
+ Ships two new flagship trend-following S/R `ta.*` primitives under
780
+ `packages/runtime/src/ta/`:
781
+
782
+ - `ta.psar(opts?)` — Wilder Parabolic SAR returning
783
+ `{ sar, direction }`. Self-contained state machine over
784
+ `bar.high` / `bar.low` / `bar.close` with extreme-point +
785
+ acceleration-factor tracking and trend-flip semantics. Defaults
786
+ `accelerationStart = 0.02`, `accelerationStep = 0.02`,
787
+ `accelerationMax = 0.2` per Pine / Wilder. Bar 0 emits the seed
788
+ (`sar = bar.low`, `direction = +1`); bar 1 decides the initial
789
+ direction from `close[1] >= close[0]`; bar 2+ runs the standard
790
+ recurrence with the lower/upper-bound clamps against the prior
791
+ two bars' lows/highs.
792
+ - `ta.supertrend(opts?)` — ATR-driven trailing-stop trend follower
793
+ returning `{ line, direction }`. Composes Phase-1 `ta.atr` at
794
+ sub-slot `${slotId}/atr`, so a fix to ATR flows in for free.
795
+ Defaults `length = 10`, `multiplier = 3`. Reads `bar.hl2` for the
796
+ band midpoint (Pine-canonical). The final-band persistence rule
797
+ carries the prior band forward unless the prior close pierced it;
798
+ direction flips when the current close crosses the prior
799
+ `finalUpper` / `finalLower`.
800
+
801
+ Both primitives suspend their recurrence state on NaN OHLC so the
802
+ next finite bar resumes from the prior state. `replaceHead`
803
+ correctness is asserted via append-vs-replaceHead property tests
804
+ over adversarial sharp-reversal sequences — both implementations
805
+ snapshot the state at the start of each bar BEFORE the close-side
806
+ recurrence advances so a final tick replays from the seed.
807
+
808
+ Each primitive ships the §22.10 set: impl + unit + property +
809
+ golden + bench pair + conformance scenario (using the Phase-2
810
+ `inlineSource` extension from Task 1) + auto-generated
811
+ `docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA` carries the
812
+ multi-output / y-domain hints (`psar: { primarySeriesKey: "sar",
813
+ visibleSeriesKeys: ["sar", "direction"], yDomain: auto }`,
814
+ `supertrend: { primarySeriesKey: "line", visibleSeriesKeys:
815
+ ["line", "direction"], yDomain: auto }`).
816
+
817
+ Core adds `PsarOpts`, `PsarResult`, `SupertrendOpts`,
818
+ `SupertrendResult` exports + the two `TaNamespace` methods.
819
+ `STATEFUL_PRIMITIVES` grows by 2 (`ta.psar`, `ta.supertrend`; both
820
+ `slot: true`). `TA_REGISTRY` mirrors with the leading
821
+ `slotId: string` on each method.
822
+
823
+ - 38fb475: Phase-2 Task 27 — S/R ports: `ta.zigZag`, `ta.pivotsHighLow`,
824
+ `ta.pivotsStandard`, and `ta.volatilityStop` (closes §9.2's S/R
825
+ list).
826
+
827
+ Ships four new S/R `ta.*` primitives under
828
+ `packages/runtime/src/ta/`:
829
+
830
+ - `ta.zigZag(opts?)` — streaming swing-pivot detector. Walks the
831
+ close series tracking a running candidate pivot; confirms a new
832
+ pivot when the price has reversed by ≥ `deviation %` AND `depth`
833
+ bars have elapsed. Returns `{ value, direction }` where `value`
834
+ carries the most-recently-confirmed pivot price (held constant
835
+ between confirmations, NaN before the first) and `direction` is
836
+ `+1` / `-1` / NaN. Defaults `deviation = 5`, `depth = 10`.
837
+ Streaming adaptation of invinite's batch ZigZag — invinite's
838
+ linear-interpolation rendering between pivots isn't representable
839
+ in the append-only `Series` model, so the output is the closest
840
+ surface (a "trailing reference level").
841
+ - `ta.pivotsHighLow(opts?)` — centred-window swing-pivot detector
842
+ with asymmetric `(leftLength, rightLength)` confirmation windows.
843
+ Returns `{ high, low }` (price-level series — `bar.high(centre)`
844
+ or `bar.low(centre)` when a pivot confirms, NaN otherwise).
845
+ Mirrors invinite's tie-break: strict-greater on the left window,
846
+ geq on the right (matches Pine `ta.pivothigh`). Defaults
847
+ `leftLength = rightLength = 4` (9-bar window).
848
+ - `ta.pivotsStandard(opts?)` — classical daily pivot-point levels
849
+ (P, R1..R3, S1..S3) derived from the previous UTC-day's HLC.
850
+ Returns seven `Series<number>` (`{ pp, r1, s1, r2, s2, r3, s3 }`).
851
+ Four formula systems: `"classic"` (default), `"fibonacci"`,
852
+ `"camarilla"`, `"woodie"`. UTC-day boundary detection via
853
+ `Math.floor(bar.time / 86_400_000)`. R4 / R5 / S4 / S5 levels
854
+ (Camarilla's full table) and DeMark / Traditional systems
855
+ intentionally defer per the Phase-2 README "Deferred / Follow-Up
856
+ Work" footnote.
857
+ - `ta.volatilityStop(opts?)` — PSAR-like trend-following stop
858
+ driven by ATR. Composes Phase-1 `ta.atr` at sub-slot
859
+ `${slotId}/atr`. Returns `{ value, direction }` (`+1` uptrend →
860
+ stop is BELOW price; `-1` downtrend → stop ABOVE). Defaults
861
+ `length = 20`, `multiplier = 2`. Source hard-coded to `bar.close`
862
+ (Pine `ta.vstop` convention; invinite's `source` field is
863
+ omitted, a `source` opt could land in a follow-up).
864
+
865
+ All four primitives suspend their recurrence state on NaN OHLC so
866
+ the next finite bar resumes from the prior state. `replaceHead`
867
+ correctness is asserted via append-vs-replaceHead property tests
868
+ over `arbBar` fixtures — ZigZag and Volatility Stop snapshot their
869
+ state-machine state at the start of each bar BEFORE the close-side
870
+ recurrence advances so a final tick replays from the seed
871
+ (mirrors Task 25's PSAR / Supertrend pattern).
872
+
873
+ Each primitive ships the §22.10 set: impl + unit + property +
874
+ golden + bench pair + conformance scenario (using the Phase-2
875
+ `inlineSource` extension from Task 1) + auto-generated
876
+ `docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA` carries the
877
+ multi-output / y-domain hints (all four use `yDomain: { kind:
878
+ "auto" }`).
879
+
880
+ Core adds `ZigZagOpts`, `ZigZagResult`, `PivotsHighLowOpts`,
881
+ `PivotsHighLowResult`, `PivotsStandardOpts`,
882
+ `PivotsStandardResult`, `PivotsStandardSystem`,
883
+ `VolatilityStopOpts`, and `VolatilityStopResult` exports + four
884
+ `TaNamespace` methods. `STATEFUL_PRIMITIVES` grows by 4 (all
885
+ `slot: true`). `TA_REGISTRY` mirrors with the leading
886
+ `slotId: string` on each method.
887
+
888
+ Compiler patch: the ambient shim mirrors the four new methods +
889
+ nine new types.
890
+
891
+ - 38fb475: Phase-2 Task 28 — statistical `ta.*` ports: `ta.median`, `ta.adr`,
892
+ `ta.ulcerIndex`.
893
+
894
+ Ships three new statistical primitives under
895
+ `packages/runtime/src/ta/`:
896
+
897
+ - `ta.median(source, length, opts?)` — rolling median over the
898
+ trailing `length` source values. Odd-`length` → middle value;
899
+ even-`length` → mean of the two middle values. NaN slots are
900
+ dropped from the sort (window length effectively shrinks). Range
901
+ invariant pinned: `min(window) ≤ out ≤ max(window)`. Tick-mode
902
+ substitutes the head value before sorting (closed window
903
+ unchanged).
904
+ - `ta.adr(opts?)` — Average Daily Range. SMA of `high − low` over
905
+ the trailing `length` (default `14`) completed UTC calendar days.
906
+ Reads `bar.high` / `bar.low` / `bar.time` directly (no `source`
907
+ param). Phase-2 keys "daily" on the UTC midnight boundary
908
+ (`Math.floor(bar.time / 86_400_000)`); Phase 4 lifts this onto
909
+ `syminfo.session`. The in-progress (currently-aggregating) day is
910
+ NEVER included in the average — matches invinite's "completed N
911
+ daily bars" semantics. Tick mode emits the cached SMA (no day-
912
+ boundary advance per the runtime tick invariant).
913
+ - `ta.ulcerIndex(source, length, opts?)` — drawdown-based volatility
914
+ (rolling RMS of percent declines from the rolling-window high).
915
+ Composes `ta.highest` via sub-slot id `${slotId}/highest`. Range
916
+ invariant pinned: `out ≥ 0`. NaN source → NaN output (window
917
+ unchanged).
918
+
919
+ Each primitive ships the §22.10 set: impl + unit + property +
920
+ golden + bench pair + conformance scenario (inline-source per Task
921
+ 1's extension) + auto-generated `docs/primitives/ta/<id>.md`.
922
+
923
+ `STATEFUL_PRIMITIVES` grows by `+3` (`ta.median`, `ta.adr`,
924
+ `ta.ulcerIndex` — all `slot: true`). `TA_REGISTRY` grows by `+3`.
925
+ `TaNamespace` and `RuntimeTaNamespace` extend in lockstep with
926
+ `MedianOpts`, `AdrOpts` (`{ length?: number; offset?: number;
927
+ lineStyle?: PlotLineStyle }`), and `UlcerIndexOpts`.
928
+
929
+ `ALL_SCENARIOS` (conformance) grows by `+3`. The three new
930
+ scenarios assert `alert-count: 0` + the standard
931
+ `lookback-exceeded` / `malformed-emission` diagnostic-absent gates
932
+ (no `plot-hash` — the rolling primitives' outputs are pinned
933
+ elsewhere via the runtime golden tests).
934
+
935
+ - 38fb475: Phase-2 Task 16 — trend ports: `ta.adx`, `ta.dmi`, `ta.trix`.
936
+
937
+ Ships three new trend `ta.*` primitives under
938
+ `packages/runtime/src/ta/`:
939
+
940
+ - `ta.adx(length, opts?)` — Wilder's Average Directional Index
941
+ (single Series bounded `[0, 100]`). Reads `bar.high` /
942
+ `bar.low` / `bar.close` directly (mirrors Pine's `ta.adx(length)`
943
+ — no source param). Composes the same Wilder DI recurrence
944
+ `ta.dmi` runs, then folds DX through a second
945
+ Wilder-smoothing window of length `opts.smoothing ?? 14`.
946
+ - `ta.dmi(length, opts?)` — Wilder's Directional Movement Index
947
+ (`{ plusDi, minusDi }`, both ∈ [0, 100]). Reads OHLC directly
948
+ per Pine's `ta.dmi(length)`. Incremental `wilderStep` over
949
+ `+DM` / `−DM` / TR; output validated against the
950
+ full-recompute reference `lib/wilderDirectional`.
951
+ - `ta.trix(source, length, opts?)` — TRIX triple-smoothed EMA
952
+ rate-of-change with an EMA-signal line (`{ trix, signal }`).
953
+ Composes three EMA sub-slots (`${slotId}/ema1` / `/ema2` /
954
+ `/ema3`) for the triple chain + a fourth `${slotId}/signal`
955
+ EMA, mirroring the MACD sub-slot composition pattern.
956
+
957
+ Each primitive ships the §22.10 set: impl + unit + property +
958
+ golden + bench pair + conformance scenario (using the Phase-2
959
+ `inlineSource` extension from Task 1) + auto-generated
960
+ `docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA` carries
961
+ y-domain + multi-output hints (`adx: { yDomain: fixed 0-100 }`,
962
+ `dmi: { primarySeriesKey: "plusDi", visibleSeriesKeys: ["plusDi",
963
+ "minusDi"], yDomain: fixed 0-100 }`, `trix: { primarySeriesKey:
964
+ "trix", visibleSeriesKeys: ["trix", "signal"], yDomain: auto }`).
965
+
966
+ ADX / DMI reuse Phase-1 `lib/wilderSmoothing` (`wilderStep`) for
967
+ the per-bar Wilder recurrence and Wave-3 Task-4
968
+ `lib/wilderDirectional` + `lib/adxFromDi` as the property-test
969
+ reference (Float64Array-in / Float64Array-out full-recompute).
970
+ TRIX reuses Phase-1 `lib/emaFloat64` (`computeEmaOfFloat64`) as
971
+ the property-test reference plus the runtime `ta.ema` primitive
972
+ for the four composed sub-slots.
973
+
974
+ Core adds `AdxOpts`, `DmiOpts`, `DmiResult`, `TrixOpts`,
975
+ `TrixResult` exports plus three new methods on `TaNamespace`.
976
+ `STATEFUL_PRIMITIVES` grows by 3 (`ta.adx`, `ta.dmi`, `ta.trix`;
977
+ all `slot: true`). `TA_REGISTRY` mirrors with the leading
978
+ `slotId: string` on each method.
979
+
980
+ - 38fb475: Phase-2 Task 15 — trend ports: `ta.aroon` and `ta.aroonOsc`.
981
+
982
+ Ships two new trend `ta.*` primitives under
983
+ `packages/runtime/src/ta/`:
984
+
985
+ - `ta.aroon(length, opts?)` — Aroon Up / Down (`{ up, down }`,
986
+ both ∈ [0, 100]). Reads `bar.high` / `bar.low` directly per
987
+ Pine's `ta.aroon(length)` signature (no source param). Scans the
988
+ trailing `length + 1` window per close for the argmax / argmin
989
+ using strict `>` / `<` so the most-recent tied bar wins
990
+ (TradingView convention). Tick replay substitutes the head value
991
+ without mutating the closed window.
992
+ - `ta.aroonOsc(length, opts?)` — `aroon.up − aroon.down`, bounded
993
+ in [-100, 100]. Composes `ta.aroon` at sub-slot
994
+ `${slotId}/aroon` so a fix to Aroon flows in for free.
995
+
996
+ Each primitive ships the §22.10 set: impl + unit + property + golden
997
+
998
+ - bench pair + conformance scenario (using the Phase-2 `inlineSource`
999
+ extension from Task 1) + auto-generated `docs/primitives/ta/<id>.md`.
1000
+ `TA_REGISTRY_METADATA` carries the multi-output / y-domain hints
1001
+ (`aroon: { primarySeriesKey: "up", visibleSeriesKeys: ["up", "down"],
1002
+ yDomain: fixed 0-100 }`, `aroonOsc: { yDomain: fixed -100-100 }`).
1003
+
1004
+ Core adds `AroonOpts`, `AroonOscOpts`, `AroonResult` exports + the
1005
+ two `TaNamespace` methods. `STATEFUL_PRIMITIVES` grows by 2
1006
+ (`ta.aroon`, `ta.aroonOsc`; both `slot: true`). `TA_REGISTRY`
1007
+ mirrors with the leading `slotId: string` on each method.
1008
+
1009
+ - 38fb475: Phase-2 Task 17 — trend ports: `ta.vortex`, `ta.trendStrengthIndex`,
1010
+ `ta.ichimoku`.
1011
+
1012
+ Ships three new trend `ta.*` primitives under
1013
+ `packages/runtime/src/ta/`:
1014
+
1015
+ - `ta.vortex(length, opts?)` — Botes & Siepman (2010) Vortex
1016
+ Indicator. Reads `bar.high` / `bar.low` / `bar.close` directly
1017
+ (mirrors Pine's `ta.vortex(length)` — no source param). Returns
1018
+ `{ plus, minus }` (the +VI / −VI lines). Maintains rolling
1019
+ running-sum windows over per-bar `vmPlus`, `vmMinus`, and TR for
1020
+ O(1) per-bar updates. NaN-on-zero-TR semantic per chartlang task
1021
+ spec §6 (invinite emits 0 on zero TR; chartlang surfaces the
1022
+ degenerate window).
1023
+ - `ta.trendStrengthIndex(source, length, opts?)` — TradingView's
1024
+ Trend Strength Index: Pearson correlation between `source` and
1025
+ bar index over each trailing `length`-bar window. Bounded
1026
+ `[-1, +1]`. Default `length = 20` (chartlang task spec; invinite
1027
+ default is 14). Distinct from `ta.tsi` (Task 14's True Strength
1028
+ Index momentum oscillator) — name collision avoided via the
1029
+ longer `trendStrengthIndex` surface.
1030
+ - `ta.ichimoku(opts?)` — Ichimoku Cloud (Tenkan / Kijun / Senkou A
1031
+ / Senkou B / Chikou). Defaults `(conversionLength=9, baseLength=
1032
+ 26, leadingSpanBLength=52, displacement=26)`. Composes six
1033
+ `ta.highest` / `ta.lowest` sub-slots (one pair each for Tenkan /
1034
+ Kijun / Senkou B) — the same composition seam `ta.donchian` uses
1035
+ — so a fix to either rolling-extreme primitive flows in for free.
1036
+ Forward-displaced Senkou A / Senkou B and backward-displaced
1037
+ Chikou are produced via per-slot delay ring buffers of capacity
1038
+ `displacement + 1`. `chikou.current` returns `close[t −
1039
+ displacement]` (the backward-shifted close — programmatic
1040
+ semantic for script-author conditionals).
1041
+
1042
+ Each primitive ships the §22.10 set: impl + unit + property +
1043
+ golden + bench pair + conformance scenario (using the Phase-2
1044
+ `inlineSource` extension from Task 1) + auto-generated
1045
+ `docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA` carries
1046
+ y-domain + multi-output hints:
1047
+
1048
+ - `vortex: { primarySeriesKey: "plus", visibleSeriesKeys:
1049
+ ["plus", "minus"], yDomain: auto }`
1050
+ - `trendStrengthIndex: { yDomain: fixed [-1, 1] }`
1051
+ - `ichimoku: { primarySeriesKey: "tenkan", visibleSeriesKeys:
1052
+ ["tenkan", "kijun", "senkouA", "senkouB", "chikou"], yDomain:
1053
+ auto }` (the cloud renders via the Task-1 `filled-band` PlotKind
1054
+ between `senkouA` and `senkouB` — script-author drives the
1055
+ styling in their `plot()` call).
1056
+
1057
+ Reuse:
1058
+
1059
+ - Vortex's property test uses Phase-1 `lib/trSeries.ts`
1060
+ (`computeTrSeries`) as the per-bar TR reference; golden test
1061
+ pins the per-output hashes of a 100-bar Mulberry32 fixture.
1062
+ - TrendStrengthIndex's property test uses Wave-3 `lib/pearson.ts`
1063
+ against a linear bar-index series as the reference.
1064
+ - Ichimoku's property test uses Wave-3 `lib/donchianMid.ts` as the
1065
+ per-line reference (Tenkan / Kijun / SenkouB raw all share the
1066
+ same Donchian-midpoint math).
1067
+
1068
+ Core adds `VortexOpts`, `VortexResult`, `TrendStrengthIndexOpts`,
1069
+ `IchimokuOpts`, `IchimokuResult` exports plus three new methods
1070
+ on `TaNamespace` + three throwing stubs on the `ta` const.
1071
+ `STATEFUL_PRIMITIVES` grows by 3 (`ta.vortex`,
1072
+ `ta.trendStrengthIndex`, `ta.ichimoku`; all `slot: true`) — final
1073
+ Phase-2 size 93. `TA_REGISTRY` grows by 3 — final size 90.
1074
+ Conformance scenarios + `ALL_SCENARIOS` array grow by 3.
1075
+
1076
+ - 38fb475: Phase-2 Task 18 — volatility ports: `ta.bbPercentB`, `ta.bbw`, and
1077
+ `ta.donchian`.
1078
+
1079
+ Ships three new volatility `ta.*` primitives under
1080
+ `packages/runtime/src/ta/`:
1081
+
1082
+ - `ta.bbPercentB(source, length, opts?)` — Bollinger %B,
1083
+ `(src − lower) / (upper − lower)` over the BB envelope. NaN
1084
+ when the band collapses (zero width). Composes `ta.bb` via
1085
+ sub-slot `${slotId}/bb` so a fix to the envelope flows in for
1086
+ free. Default `multiplier = 2`.
1087
+ - `ta.bbw(source, length, opts?)` — Bollinger BandWidth,
1088
+ `(upper − lower) / middle` over the BB envelope. Raw ratio
1089
+ scale (multiply by 100 in the script for TradingView-parity
1090
+ display). NaN on zero middle. Composes `ta.bb` via the same
1091
+ sub-slot pattern. Default `multiplier = 2`.
1092
+ - `ta.donchian(length, opts?)` — Donchian Channels,
1093
+ `{ upper, middle, lower }` over a fixed `length`-bar window.
1094
+ `upper = highest(bar.high, length)` and `lower =
1095
+ lowest(bar.low, length)` via sub-slots `${slotId}/highest` /
1096
+ `${slotId}/lowest` — the slot-aware composition of the
1097
+ registered Task-5 primitives; equivalent to `lib/donchianMid`
1098
+ but routed through the registry so a fix flows in for free.
1099
+ Mid = `(upper + lower) / 2`.
1100
+
1101
+ Each primitive ships the §22.10 set: impl + unit + property +
1102
+ golden + bench pair + conformance scenario (using the Phase-2
1103
+ `inlineSource` extension from Task 1) + auto-generated
1104
+ `docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA.donchian`
1105
+ records the multi-output hints (`primarySeriesKey: "middle"`,
1106
+ `visibleSeriesKeys: ["upper", "middle", "lower"]`,
1107
+ `yDomain: { kind: "auto" }`).
1108
+
1109
+ Core adds `BbPercentBOpts`, `BbwOpts`, `DonchianOpts`,
1110
+ `DonchianResult` exports + the three `TaNamespace` methods.
1111
+ `STATEFUL_PRIMITIVES` grows by 3 (all three `slot: true`).
1112
+ `TA_REGISTRY` mirrors with the leading `slotId: string` on each
1113
+ method.
1114
+
1115
+ - 38fb475: Phase-2 Task 20 — volatility ports: `ta.historicalVolatility`,
1116
+ `ta.rvi`, and `ta.massIndex`.
1117
+
1118
+ Ships three new volatility `ta.*` primitives under
1119
+ `packages/runtime/src/ta/`:
1120
+
1121
+ - `ta.historicalVolatility(source, length, opts?)` — annualised
1122
+ stddev of log returns ×100. Default `annualisationFactor = 365`
1123
+ (TradingView's "Crypto" convention; use `252` for trading-day
1124
+ equity series). NaN through `[0, length − 1]` warmup; non-positive
1125
+ or non-finite source short-circuits log returns to NaN.
1126
+ - `ta.rvi(source, length, opts?)` — Relative Volatility Index, the
1127
+ RSI-style oscillator that uses rolling stddev of the source as
1128
+ the magnitude instead of absolute close changes. Bounded `[0, 100]`.
1129
+ Composes `ta.ema` via sub-slots `${slotId}/upEma` and
1130
+ `${slotId}/downEma` so a fix to EMA's recurrence flows in for
1131
+ free. Warmup `2 · length − 1`. NaN on zero-denominator (both EMA
1132
+ arms zero).
1133
+ - `ta.massIndex(opts?)` — sub-pane volatility line that tracks the
1134
+ range-EMA "bulge" ratio to flag trend-reversal setups via the
1135
+ canonical 27 threshold. Reads `bar.high − bar.low` directly (no
1136
+ source param). Composes two chained `ta.ema` sub-slots
1137
+ (`${slotId}/ema1`, `${slotId}/ema2`). Defaults `emaLength = 9`,
1138
+ `sumLength = 25`. Warmup `2 · emaLength + sumLength − 3`.
1139
+
1140
+ Adds the §22.10 five-file set per primitive (impl + unit + property
1141
+
1142
+ - golden + bench pair) and a conformance scenario per primitive
1143
+ under `packages/conformance/src/scenarios/`.
1144
+
1145
+ Extends core's `TaNamespace` + `STATEFUL_PRIMITIVES` and the
1146
+ runtime's `RuntimeTaNamespace` + `TA_REGISTRY` accordingly. Three
1147
+ auto-generated docs pages under `docs/primitives/ta/` ship via the
1148
+ Task-2 `chartlang docs` generator.
1149
+
1150
+ Provenance: ported from invinite at commit
1151
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`. The RVI math follows
1152
+ invinite's TradingView-reference shape (EMA-smoothed up/down stddev
1153
+ arms), not the spec's draft Wilder-smoothing description.
1154
+
1155
+ - 38fb475: Phase-2 Task 19 — volatility ports: `ta.keltner`, `ta.envelope`, and
1156
+ `ta.chop`.
1157
+
1158
+ Ships three new volatility `ta.*` primitives under
1159
+ `packages/runtime/src/ta/`:
1160
+
1161
+ - `ta.keltner(opts?)` — Keltner Channels overlay envelope.
1162
+ `middle = MA(close, length, maType)` with `upper / lower =
1163
+ middle ± multiplier · ATR(length)`. Defaults `length = 20`,
1164
+ `multiplier = 2`, `maType = "ema"` (TradingView / Linda Raschke
1165
+ canonical form). Composes `ta.atr` via sub-slot `${slotId}/atr`
1166
+ and the registered MA primitive (`sma` / `ema` / `wma` / `smma`)
1167
+ via sub-slot `${slotId}/<maType>` — fixes to either flow in for
1168
+ free.
1169
+ - `ta.envelope(source, opts?)` — price-percent envelope overlay.
1170
+ `middle = MA(source, length, maType)` with `upper / lower =
1171
+ middle · (1 ± percent / 100)`. Defaults `length = 20`,
1172
+ `percent = 10`, `maType = "sma"`. Composes the registered MA
1173
+ primitive via sub-slot `${slotId}/<maType>` so fixes flow in
1174
+ for free.
1175
+ - `ta.chop(length, opts?)` — Choppiness Index sub-pane regime
1176
+ gauge. `chop = 100 · log10(sumTR(length) / (highest(high,
1177
+ length) − lowest(low, length))) / log10(length)`, clamped to
1178
+ `[0, 100]`. High values flag sideways / choppy markets; low
1179
+ values flag strong trends. Composes `ta.highest` / `ta.lowest`
1180
+ via sub-slots; the TR-sum numerator is a sliding-window sum
1181
+ inside the slot (same internal TR math as `ta.atr`, but raw —
1182
+ Pine `ta.chop` does NOT use the Wilder-smoothed ATR).
1183
+
1184
+ Each primitive ships the §22.10 set: impl + unit + property +
1185
+ golden + bench pair + conformance scenario (using the Phase-2
1186
+ `inlineSource` extension from Task 1) + auto-generated
1187
+ `docs/primitives/ta/<id>.md`. `TA_REGISTRY_METADATA.keltner` and
1188
+ `.envelope` record the multi-output hints
1189
+ (`primarySeriesKey: "middle"`,
1190
+ `visibleSeriesKeys: ["upper", "middle", "lower"]`,
1191
+ `yDomain: { kind: "auto" }`); `TA_REGISTRY_METADATA.chop` pins
1192
+ the bounded `{ yDomain: { kind: "fixed", min: 0, max: 100 } }`
1193
+ oscillator range.
1194
+
1195
+ Core adds `KeltnerOpts`, `KeltnerResult`, `EnvelopeOpts`,
1196
+ `EnvelopeResult`, `ChopOpts` exports + the three `TaNamespace`
1197
+ methods. `STATEFUL_PRIMITIVES` grows by 3 (all three `slot: true`).
1198
+ `TA_REGISTRY` mirrors with the leading `slotId: string` on each
1199
+ method.
1200
+
1201
+ - 38fb475: Phase-2 Task 23 — volume ports `ta.chaikinOsc`, `ta.mfi`,
1202
+ `ta.netVolume`, `ta.pvo`.
1203
+
1204
+ Ports four volume primitives from invinite (commit
1205
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`) onto the chartlang
1206
+ runtime — each lands the §22.10 five-file set (impl + unit +
1207
+ property + golden + bench pair) alongside an inline conformance
1208
+ scenario and an auto-generated docs page:
1209
+
1210
+ - `ta.chaikinOsc(opts?)` — Chaikin Oscillator, `EMA(ADL, fast) −
1211
+ EMA(ADL, slow)`. Defaults `(3, 10)`. Composes one `ta.adl`
1212
+ sub-slot + two `ta.ema` sub-slots; a fix to either flows in for
1213
+ free. Warmup `slowLength − 1`.
1214
+ - `ta.mfi(length, opts?)` — Money Flow Index, volume-weighted RSI
1215
+ over a trailing window of typical-price comparisons. Bounded
1216
+ `[0, 100]`; emits 100 on perfect upflow, 0 on perfect downflow,
1217
+ NaN on zero total flow (invinite's zero-denominator guard).
1218
+ Warmup `length + 1`.
1219
+ - `ta.netVolume(opts?)` — cumulative `sign(close − prevClose) ·
1220
+ volume`. **Math is identical to `ta.obv`** (both primitives
1221
+ exist in invinite under their own names; chartlang mirrors the
1222
+ public surface for naming parity). Property-tested for
1223
+ hash-equality against `ta.obv` over a 100-bar synthetic walk.
1224
+ Warmup 1 (bar 0 emits 0).
1225
+ - `ta.pvo(opts?)` — Percentage Volume Oscillator, MACD shape on
1226
+ `bar.volume`. Defaults `(12, 26, 9)`. Composes three `ta.ema`
1227
+ sub-slots over volume. Multi-output `{ pvo, signal, hist }`;
1228
+ `TA_REGISTRY_METADATA.pvo` records `primarySeriesKey: "pvo"`,
1229
+ `visibleSeriesKeys: ["pvo", "signal", "hist"]`, `yDomain: {
1230
+ kind: "auto" }`. Warmup `slowLength + signalLength − 2`.
1231
+
1232
+ Surface deltas:
1233
+
1234
+ - `TaNamespace` extends with the four new methods + opts types
1235
+ (`ChaikinOscOpts`, `MfiOpts`, `NetVolumeOpts`, `PvoOpts` +
1236
+ `PvoResult`).
1237
+ - `STATEFUL_PRIMITIVES` grows by four `slot: true` entries.
1238
+ - `TA_REGISTRY` + `RuntimeTaNamespace` mirror the same delta;
1239
+ `TA_REGISTRY_METADATA.pvo` carries the multi-series metadata;
1240
+ `ALL_SCENARIOS` grows by four inline scenarios.
1241
+
1242
+ All four primitives carry the §16.6 100% coverage gate via their
1243
+ five-file test set; golden hashes pinned against `syntheticBars(100,
1244
+ 42)` (placeholder pin in the initial commit — repinned on first
1245
+ deterministic green). Per-port bench thresholds reuse the
1246
+ `THRESHOLD_MS = 300` ceiling from the existing volume primitives.
1247
+
1248
+ - 38fb475: Phase-2 Task 22 — volume ports `ta.obv`, `ta.adl`, `ta.bop`, `ta.cmf`.
1249
+
1250
+ Ports four volume primitives from invinite (commit
1251
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`) onto the chartlang
1252
+ runtime — each lands the §22.10 five-file set (impl + unit +
1253
+ property + golden + bench pair) alongside an inline conformance
1254
+ scenario and an auto-generated docs page:
1255
+
1256
+ - `ta.obv()` — On-Balance Volume, cumulative `sign(close − prevClose) ·
1257
+ volume`. Warmup 1 (bar 0 emits 0). Slot snapshots
1258
+ `prevClosedCumObv` / `prevClosedPrevClose` for tick-mode replay.
1259
+ NaN volume carries the accumulator forward without an update.
1260
+ - `ta.adl()` — Accumulation / Distribution Line, cumulative
1261
+ `((C − L) − (H − C)) / (H − L) · volume`. Warmup 0. Zero-range
1262
+ bars (`high === low`) contribute 0 (matches invinite's CLV
1263
+ guard); NaN OHLC / volume contributes 0.
1264
+ - `ta.bop()` — Balance of Power, raw per-bar `(C − O) / (H − L)`.
1265
+ Warmup 0; stateless math, output buffer only.
1266
+ - `ta.cmf(length)` — Chaikin Money Flow, trailing-window
1267
+ `Σ MFV / Σ volume`. Warmup `length − 1`; bounded `[-1, 1]`.
1268
+ Tick-mode substitutes the head slot's contribution without
1269
+ mutating the rolling window (matches `ulcerIndex`'s shape).
1270
+
1271
+ Surface deltas:
1272
+
1273
+ - `TaNamespace` extends with the four new methods + opts types
1274
+ (`ObvOpts`, `AdlOpts`, `BopOpts`, `CmfOpts` — each `{ offset?;
1275
+ lineStyle? }`).
1276
+ - `STATEFUL_PRIMITIVES` grows by four `slot: true` entries.
1277
+ - `TA_REGISTRY` + `RuntimeTaNamespace` mirror the same delta;
1278
+ `ALL_SCENARIOS` grows by four inline scenarios.
1279
+
1280
+ All four primitives carry the §16.6 100% coverage gate via their
1281
+ five-file test set; golden hashes pinned against `syntheticBars(100,
1282
+ 42)`. Per-port bench thresholds reuse the `THRESHOLD_MS = 300`
1283
+ ceiling from the existing volume primitives.
1284
+
1285
+ - 38fb475: Phase-2 Task 24 — volume ports `ta.pvt`, `ta.eom`, `ta.nvi`,
1286
+ `ta.pvi`. Closes the §9.2 volume list (excluding the 4 volume-
1287
+ profile primitives deferred to Phase 5).
1288
+
1289
+ Ports four volume primitives from invinite (commit
1290
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`) onto the chartlang
1291
+ runtime — each lands the §22.10 five-file set (impl + unit +
1292
+ property + golden + bench pair) alongside an inline conformance
1293
+ scenario and an auto-generated docs page:
1294
+
1295
+ - `ta.pvt(opts?)` — Price Volume Trend, cumulative `volume ·
1296
+ (close − prevClose) / prevClose`. First bar emits 0;
1297
+ zero-prevClose bars emit NaN AND carry the accumulator forward;
1298
+ NaN volume contributes 0. Warmup 1.
1299
+ - `ta.eom(length, opts?)` — Ease of Movement, `length`-bar SMA of
1300
+ per-bar `((midpointMove) / boxRatio)` where `boxRatio = (volume
1301
+ / 10000) / (high − low)`. Hard-codes invinite's default divisor
1302
+ of 10000. Zero-range / zero-volume / NaN-input bars propagate
1303
+ NaN through the trailing window (forces a clean restart after
1304
+ any defective bar). Warmup `length`.
1305
+ - `ta.nvi(opts?)` — Negative Volume Index, cumulative
1306
+ close-pct-change on bars whose volume is strictly LOWER than the
1307
+ prior bar's; bars with equal-or-higher volume carry the prior
1308
+ value unchanged. Seeded at 1000 (anchor pinned by property
1309
+ test). Warmup 1.
1310
+ - `ta.pvi(opts?)` — Positive Volume Index, mirror of NVI on bars
1311
+ whose volume is strictly HIGHER than the prior bar's. Seeded at 1000. Warmup 1.
1312
+
1313
+ Surface deltas:
1314
+
1315
+ - `TaNamespace` extends with the four new methods + opts types
1316
+ (`PvtOpts`, `EomOpts`, `NviOpts`, `PviOpts`). All four opts
1317
+ bags share the `{ offset?: number; lineStyle?: PlotLineStyle }`
1318
+ shape.
1319
+ - `STATEFUL_PRIMITIVES` grows by four `slot: true` entries
1320
+ (86 → 90; `slot: true` count 85 → 89).
1321
+ - `TA_REGISTRY` + `RuntimeTaNamespace` mirror the same delta
1322
+ (83 → 87). No new `TA_REGISTRY_METADATA` rows — all four are
1323
+ single-output `Series<number>` with auto y-domain.
1324
+ - `ALL_SCENARIOS` grows by four inline scenarios.
1325
+
1326
+ All four primitives carry the §16.6 100% coverage gate via their
1327
+ five-file test set; golden hashes pinned against
1328
+ `syntheticBars(100, 42)` (placeholder pin in the initial commit —
1329
+ repinned on first deterministic green). Per-port bench thresholds
1330
+ reuse the `THRESHOLD_MS = 300` ceiling from the existing volume
1331
+ primitives.
1332
+
1333
+ - 38fb475: Phase-2 Task 21 — port the three foundational volume primitives:
1334
+
1335
+ - **`ta.vol(opts?)`** — passthrough of `bar.volume` as a `Series<number>`.
1336
+ Warmup 0; NaN volume propagates to NaN output.
1337
+ - **`ta.vwap(opts?)`** — session-anchored VWAP keyed on the UTC
1338
+ calendar-day boundary (`floor(bar.time / 86_400_000)`). Phase 4
1339
+ lifts the session detection to `syminfo.session.regularStart` per
1340
+ invinite; until then `ta.vwap` is a UTC-day-anchored VWAP.
1341
+ Source defaults to `"hlc3"` per Pine; accepts `"close"` / `"hl2"` /
1342
+ `"ohlc4"` / `"hlcc4"`.
1343
+ - **`ta.anchoredVwap(anchorTime, opts?)`** — anchored VWAP that
1344
+ starts accumulating at the first bar with `bar.time >= anchorTime`
1345
+ and never resets. The anchor is sticky (captured on the first
1346
+ call; later anchor args are ignored). Phase 4's `input.time()`
1347
+ lifts the anchor to a runtime user input.
1348
+
1349
+ All three carry the §22.10 five-file set + JSDoc with
1350
+ `@formula`/`@warmup`/`@since 0.2`/`@experimental`/`@example`; all
1351
+ register in `STATEFUL_PRIMITIVES` as `slot: true` and in
1352
+ `TA_REGISTRY` / `RuntimeTaNamespace`.
1353
+
1354
+ ### `PlotOpts.style?` widening
1355
+
1356
+ To exercise the Task-1 `histogram` PlotKind end-to-end on
1357
+ `ta.vol`, this PR widens the script-facing `PlotOpts` with an
1358
+ optional `style?: PlotOptsStyle` discriminated-union field
1359
+ (`{ kind: "line" }` | `{ kind: "step-line" }` |
1360
+ `{ kind: "histogram"; baseline?: number }`). The runtime's
1361
+ `plot()` impl honours the field; the canvas2d reference adapter
1362
+ dispatches `kind: "histogram"` through Task-1's `drawHistogram`
1363
+ renderer. Backward-compatible — omitting `opts.style` keeps the
1364
+ existing `kind: "line"` default.
1365
+
1366
+ Future ports adding their own PlotKind (e.g. MACD-hist in Task 16,
1367
+ `bars` / `area` / `filled-band` / `label` / `marker` in their
1368
+ consumer ports) extend this same `PlotOptsStyle` union additively
1369
+ and add their dispatch arm to `createCanvas2dAdapter.applyPlot`.
1370
+
1371
+ ### Conformance scenarios
1372
+
1373
+ - `taVol.scenario.ts` — `plot(ta.vol(), { style: { kind: "histogram", baseline: 0 } })`.
1374
+ - `taVwap.scenario.ts` — `plot(ta.vwap({ source: "hlc3" }))`.
1375
+ - `taAnchoredVwap.scenario.ts` — `plot(ta.anchoredVwap(1_700_000_000_000))`.
1376
+
1377
+ ### Provenance
1378
+
1379
+ All three ports trace to `invinite/src/components/trading-chart/
1380
+ indicators/{vol,vwap,anchored-vwap}.ts` at commit
1381
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`.
1382
+
1383
+ - b0d296b: Phase 3 closeout — `0.3` "Full Drawing Parity".
1384
+
1385
+ 61 drawing kinds across 13 categories ship under `draw.*` with the
1386
+ full §22.10 set per kind (impl + property + golden + bench + JSDoc
1387
+
1388
+ - conformance scenario + auto-generated docs page). 5-bucket
1389
+ `DrawingCounts` budget, per-kind capability gating, `DrawingHandle`
1390
+ across-bar stability, real-impl `validateEmission` + `decodeDrawing`,
1391
+ `drawing-hash` conformance assertion variant, 13 category + 1
1392
+ umbrella capability builders, canvas2d reference adapter renders
1393
+ every kind, `defineDrawing` constructor for interactive tools.
1394
+
1395
+ Final cardinalities: `STATEFUL_PRIMITIVES.size === 154` (93 Phase-2
1396
+
1397
+ - 61 Phase-3 `draw.*` entries); `DRAWING_KINDS.length === 61`.
1398
+
1399
+ Per-bucket kind tally pinned by `bucketFor` (6 + 5 + 6 + 25 + 19 = 61):
1400
+
1401
+ - `lines` (6): `line`, `horizontal-line`, `horizontal-ray`,
1402
+ `vertical-line`, `cross-line`, `trend-angle`.
1403
+ - `boxes` (5): `rectangle`, `rotated-rectangle`, `triangle`,
1404
+ `circle`, `ellipse`.
1405
+ - `labels` (6): `marker`, `text`, `arrow`, `arrow-marker`,
1406
+ `arrow-mark-up`, `arrow-mark-down`.
1407
+ - `polylines` (25): `polyline`, `path`, `arc`, `curve`,
1408
+ `double-curve`, `pen`, `highlighter`, `brush`,
1409
+ `trend-channel`, `flat-top-bottom`, `disjoint-channel`,
1410
+ `regression-trend`, `pitchfork`, `pitchfan`, `xabcd-pattern`,
1411
+ `cypher-pattern`, `head-and-shoulders`, `abcd-pattern`,
1412
+ `triangle-pattern`, `three-drives-pattern`,
1413
+ `elliott-impulse-wave`, `elliott-correction-wave`,
1414
+ `elliott-triangle-wave`, `elliott-double-combo`,
1415
+ `elliott-triple-combo`.
1416
+ - `other` (19): 10 `fib-*` + 4 `gann-*` + 3 cycles
1417
+ (`cyclic-lines`, `time-cycles`, `sine-line`) + 2 containers
1418
+ (`group`, `frame`).
1419
+
1420
+ Conformance scenarios: 61 per-kind + 12 task bundles +
1421
+ `drawAll61` + `drawBudgetOverflow` + `drawUnsupportedKind` = **76**.
1422
+ Docs: 61 auto-generated `docs/primitives/draw/<kind>.md` pages +
1423
+ 1 hand-written `index.md`.
1424
+
1425
+ Variant collapses pinned in Task 1 (carried forward unchanged):
1426
+
1427
+ - `pitchfork.variant: "standard" | "schiff" | "modified-schiff" | "inside"`
1428
+ collapses the 4 invinite pitchfork tools.
1429
+ - `line.{extendLeft, extendRight}` collapses the `ray` /
1430
+ `extended-line` tools.
1431
+ - `cypherPattern` ships as a `defineDrawing`-only kind (no
1432
+ standalone interactive tool).
1433
+
1434
+ Compiler: `callsiteIdInjection` recognises every `draw.*` callable
1435
+ via the widened 154-entry `STATEFUL_PRIMITIVES`;
1436
+ `statefulCallInLoop` flags `draw.*` in unbounded loops with the
1437
+ existing `stateful-call-inside-loop` error.
1438
+
1439
+ Bench thresholds (re-verified post-Phase-3 on Apple-silicon):
1440
+
1441
+ - `pushDrawing.bench.test.ts` — 10 000 line drawings under 2 000ms
1442
+ wall-clock (`ceil(median × 3)` per §22.10; no drift across
1443
+ Tasks 4–18 — the budget/validate path is independent of
1444
+ per-kind canvas renderers). `pnpm bench:ci` median ~180ms.
1445
+ - The Phase-2 ta / ringBuffer / seriesView / onBarClose /
1446
+ plot / hline bench thresholds were bumped from the
1447
+ `200/250/300/400/500/600ms` solo-run pins to a uniform `1500ms`
1448
+ (3000ms for plot + hline) to absorb the parallel-worker
1449
+ scheduling overhead during workspace `pnpm test` (665 test
1450
+ files in parallel). Solo `pnpm bench:ci` medians remain in the
1451
+ 10–200ms range — well under both old and new thresholds — so
1452
+ this is a noise-floor adjustment, not a perf-regression
1453
+ accommodation.
1454
+
1455
+ `apiVersion: 1` script header unchanged; Phase 3 is additive at
1456
+ runtime.
1457
+
1458
+ - b0d296b: Phase 3 Task 10 — Channels (`trendChannel` / `flatTopBottom` /
1459
+ `disjointChannel` / `regressionTrend`).
1460
+
1461
+ - **adapter-kit** — 4 new per-kind validators (`validateTrendChannelState`,
1462
+ `validateFlatTopBottomState`, `validateDisjointChannelState`,
1463
+ `validateRegressionTrendState`) + 1 file-local style helper
1464
+ (`validateRegressionTrendOpts` with the
1465
+ `close|open|high|low|hl2|hlc3|ohlc4|hlcc4` source whitelist). The
1466
+ `regression-trend` validator enforces `anchors[0].time <
1467
+ anchors[1].time` and `stdevMultiplier >= 0`.
1468
+ - **runtime** — 4 new emit functions under
1469
+ `packages/runtime/src/emit/draw/channels/` wired into `DRAW_NAMESPACE`.
1470
+ `regressionTrend` carries the 4-arg form
1471
+ `(slotId, a: WorldPoint, b: WorldPoint, opts?)`. The Phase-2
1472
+ `linearRegression` + `LinearRegressionFrame` helper graduates to the
1473
+ public runtime surface so consumer adapters can compute the OLS fit
1474
+ without duplicating math.
1475
+ - **canvas2d-adapter** — 4 new renderers + dispatch wiring. The
1476
+ `regression-trend` renderer strokes a placeholder anchor-to-anchor
1477
+ line; the actual OLS fit + σ bands require bar-buffer access not
1478
+ exposed by the current `Viewport` (see
1479
+ `tasks/phase-3-drawing-parity/10-channels.plan.md` §3). `trendChannel`
1480
+ / `flatTopBottom` / `disjointChannel` are stroke-only (no fill polygon
1481
+ between rails — see plan §5).
1482
+ - **conformance** — 5 new scenarios (4 per-kind + 1
1483
+ `drawChannelsAll` bundle) with pinned `drawing-hash` assertions.
1484
+
1485
+ See `tasks/phase-3-drawing-parity/10-channels.plan.md` for the full
1486
+ audit + divergence flags.
1487
+
1488
+ - b0d296b: Phase 3 Task 11 — Fibonacci A (`fibRetracement` / `fibTrendExtension`
1489
+ / `fibChannel` / `fibTimeZone` / `fibWedge`).
1490
+
1491
+ - **core** — `DrawNamespace` flattened: the four sub-namespace types
1492
+ (`FibSubNamespace`, `GannSubNamespace`, `ElliottSubNamespace`,
1493
+ `PatternSubNamespace`) are removed; every kind now lives as a flat
1494
+ method directly on `DrawNamespace` matching the canonical
1495
+ `STATEFUL_PRIMITIVES` names (`draw.fibRetracement(...)`,
1496
+ `draw.gannBox(...)`, `draw.elliottImpulseWave(...)`,
1497
+ `draw.xabcdPattern(...)`, etc.). The throwing-stub `draw` Proxy
1498
+ drops the sub-namespace branch. Script authors use the flat
1499
+ Pine/invinite-parity surface; the compiler resolves callsites
1500
+ through its existing 2-segment property-access path. The 30
1501
+ not-yet-ported method signatures (Tasks 12–18 fib-B / gann /
1502
+ pitchfork / pattern / elliott / cycle / container kinds) are
1503
+ declared as flat stubs so Tasks 12–18 only need to extend the
1504
+ runtime `KIND_IMPLS` map. **BREAKING** for any consumer that
1505
+ referenced `draw.fib.retracement(...)` or one of the four
1506
+ sub-namespace types — none currently exist outside Phase-3 work.
1507
+ - **adapter-kit** — 5 new per-kind validators
1508
+ (`validateFibRetracementState`, `validateFibTrendExtensionState`,
1509
+ `validateFibChannelState`, `validateFibTimeZoneState`,
1510
+ `validateFibWedgeState`) + 1 file-local style helper
1511
+ (`validateFibOpts`) covering FibOpts (`levels` finite-array,
1512
+ `showLabels` / `color` / `extendLeft` / `extendRight`).
1513
+ - **runtime** — 5 new emit functions under
1514
+ `packages/runtime/src/emit/draw/fibA/` wired into `DRAW_NAMESPACE`
1515
+ as flat methods. `fibRetracement` / `fibTimeZone` use the 4-arg
1516
+ form `(slotId, a, b, opts?)`; the other 3 use the 3-arg
1517
+ `(slotId, anchors, opts?)` form. No new sub-namespace wiring.
1518
+ - **canvas2d-adapter** — 5 new renderers reusing Task-4's
1519
+ `FIB_LEVELS` + `formatLevel` and Task-5's `extendLineSegment` for
1520
+ the `fib-retracement` viewport extension. Default colour
1521
+ `"#facc15"` (warm yellow) per invinite's fib-tool palette.
1522
+ - **conformance** — 6 new scenarios (5 per-kind + 1
1523
+ `drawFibA` bundle) with pinned `drawing-hash` assertions.
1524
+ Conformance + scenarios test-capability fixtures grow `other`
1525
+ bucket from 0 to 100 and add the 5 fib-A kebab kinds.
1526
+
1527
+ Divergences flagged in `tasks/phase-3-drawing-parity/11-fibonacci-a.plan.md`:
1528
+
1529
+ - `fib-time-zone` uses the canonical ratio array (`FIB_LEVELS`),
1530
+ NOT the integer Fibonacci sequence; `fibSequence.ts` helper is
1531
+ NOT created (Task-1 reshape follow-up).
1532
+ - `fib-wedge` rays are drawn with a fixed length
1533
+ `max(pxWidth, pxHeight) * 2` rather than via a directional
1534
+ `extendLineSegment` variant.
1535
+ - Per-kind property / golden test files deferred to the pragmatic
1536
+ 1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–10.
1537
+
1538
+ See `tasks/phase-3-drawing-parity/11-fibonacci-a.plan.md` for the
1539
+ full audit + divergence list.
1540
+
1541
+ - b0d296b: Phase 3 Task 12 — Fibonacci B (`fibSpeedFan` / `fibSpeedArcs` /
1542
+ `fibSpiral` / `fibCircles` / `fibTrendTime`).
1543
+
1544
+ - **adapter-kit** — 5 new per-kind validators
1545
+ (`validateFibSpeedFanState`, `validateFibSpeedArcsState`,
1546
+ `validateFibSpiralState`, `validateFibCirclesState`,
1547
+ `validateFibTrendTimeState`), reusing Task-11's `validateFibOpts`
1548
+ style helper. The permissive-default test fixture moves from
1549
+ `fib-speed-fan` to `gann-box` (Task 13's first kind, still
1550
+ unported).
1551
+ - **runtime** — 5 new emit functions under
1552
+ `packages/runtime/src/emit/draw/fibB/` wired into the
1553
+ `DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Four use the
1554
+ 4-arg form `(slotId, a, b, opts?)`; `fibTrendTime` uses the 3-arg
1555
+ `(slotId, anchors, opts?)`. Fall-through-stub fixture in
1556
+ `namespace.test.ts` / `primitives.test.ts` /
1557
+ `buildComputeContext.test.ts` moves from `fibSpeedFan` to
1558
+ `gannBox`.
1559
+ - **canvas2d-adapter** — 5 new renderers reusing Task-4's
1560
+ `FIB_LEVELS` + `formatLevel`. `fibSpiral` additionally reuses
1561
+ `sampleCubic` for the chained quarter-Bezier approximation of the
1562
+ golden spiral. Default colour `"#facc15"` per invinite's fib-tool
1563
+ palette.
1564
+ - **conformance** — 5 new per-kind scenarios + 1 bundle
1565
+ (`drawFibAll.scenario.ts` covering all 10 fib kinds, superseding
1566
+ Task 11's `drawFibA.scenario.ts` which is deleted). Conformance +
1567
+ scenarios test-capability fixtures switch from the explicit
1568
+ fib-A kebab list to `capabilities.allFibDrawings()` (covers all
1569
+ 10 kinds). All 6 hashes pinned against the deterministic-run
1570
+ actuals.
1571
+
1572
+ Divergences flagged in `tasks/phase-3-drawing-parity/12-fibonacci-b.plan.md`:
1573
+
1574
+ - `fibSpiral` is clockwise-only — invinite's `counterClockwise`
1575
+ flag is deferred (Task-1 reshape follow-up; landed `FibSpiralState`
1576
+ - `FibOpts` don't carry the field).
1577
+ - `fibSpeedArcs` is full-circle only — invinite's half-disk variant
1578
+ is deferred (Phase-3-deferred UX nuance).
1579
+ - `fibCircles` + `fibTrendTime` use the ratio array (`FIB_LEVELS`),
1580
+ NOT the integer Fibonacci sequence. Same precedent as Task-11's
1581
+ `fib-time-zone`.
1582
+ - `gen-docs` regeneration for the 5 new kinds deferred to Task 21
1583
+ (the existing `chartlang docs` command only walks `ta.*`; the
1584
+ `draw.*` walker extension is an explicit Task-21 deliverable).
1585
+ - Per-kind property / golden test files deferred to the pragmatic
1586
+ 1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–11.
1587
+
1588
+ See `tasks/phase-3-drawing-parity/12-fibonacci-b.plan.md` for the
1589
+ full audit + divergence list.
1590
+
1591
+ - b0d296b: Phase 3 Task 13 — Gann (`gannBox` / `gannSquareFixed` / `gannSquare` /
1592
+ `gannFan`).
1593
+
1594
+ - **adapter-kit** — 4 new per-kind validators
1595
+ (`validateGannBoxState`, `validateGannSquareFixedState`,
1596
+ `validateGannSquareState`, `validateGannFanState`), reusing
1597
+ Task-5's `validateLineDrawStyle` style helper. The
1598
+ permissive-default test fixture moves from `gann-box` to
1599
+ `pitchfork` (Task 14's first kind, still unported).
1600
+ - **runtime** — 4 new emit functions under
1601
+ `packages/runtime/src/emit/draw/gann/` wired into the
1602
+ `DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Three use the
1603
+ 4-arg form `(slotId, a, b, opts?)`; `gannSquareFixed` uses the
1604
+ 3-arg `(slotId, anchor, opts?)`. Fall-through-stub fixture in
1605
+ `namespace.test.ts` / `primitives.test.ts` /
1606
+ `buildComputeContext.test.ts` moves from `gannBox` to `pitchfork`.
1607
+ - **canvas2d-adapter** — 4 new renderers + a shared `gannLevels.ts`
1608
+ helper exporting `GANN_LEVELS` (`[0, 0.25, 0.5, 0.75, 1]`),
1609
+ `GANN_FAN_RATIOS` (9-entry tuple covering 1×1, 1×2, …, 8×1),
1610
+ `GANN_FAN_LABELS`, and `formatGannRatio`. Default colour
1611
+ `"#a855f7"` (purple/violet, mirroring invinite's gann-tool
1612
+ palette).
1613
+ - **conformance** — 4 new per-kind scenarios + 1 bundle
1614
+ (`drawGannAll.scenario.ts` covering all 4 gann kinds).
1615
+ Conformance + scenarios test-capability fixtures widen
1616
+ `drawings` with `capabilities.allGannDrawings()`. All 5 hashes
1617
+ pinned against the deterministic-run actuals.
1618
+
1619
+ Divergences flagged in `tasks/phase-3-drawing-parity/13-gann.plan.md`:
1620
+
1621
+ - `gannBox.levels` custom override deferred — landed `GannBoxState`
1622
+ carries only `style: LineDrawStyle`. Renderer uses the shared
1623
+ `GANN_LEVELS` constant only (Task-1 reshape follow-up).
1624
+ - `gannSquareFixed.sizePrice` custom override deferred — landed
1625
+ `GannSquareFixedState` carries only `anchor + style`. Renderer
1626
+ uses a fixed `80px` side (Task-1 reshape follow-up).
1627
+ - `gannSquare.ratio` custom override deferred — landed
1628
+ `GannSquareState` carries only `anchors + style`. Renderer uses
1629
+ canvas-space `max(|dx|, |dy|)` (1×1 default, Task-1 reshape
1630
+ follow-up).
1631
+ - `gannFan.showLabels` flag deferred — `LineDrawStyle` has no
1632
+ `showLabels` field. Phase-3 pins unlabeled rays (Task-1 reshape
1633
+ follow-up).
1634
+ - `gen-docs` regeneration for the 4 new kinds deferred to Task 21
1635
+ (the existing `chartlang docs` command only walks `ta.*`; the
1636
+ `draw.*` walker extension is an explicit Task-21 deliverable).
1637
+ - Per-kind property / golden test files deferred to the pragmatic
1638
+ 1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–12.
1639
+
1640
+ See `tasks/phase-3-drawing-parity/13-gann.plan.md` for the full
1641
+ audit + divergence list.
1642
+
1643
+ - b0d296b: Phase 3 Task 14 — Pitchforks (`pitchfork` / `pitchfan`). The
1644
+ `pitchfork` kind collapses the four invinite tools (`standard` /
1645
+ `schiff` / `modifiedSchiff` / `inside`) into one kind with a
1646
+ `variant` discriminator per PLAN.md §3.1.
1647
+
1648
+ - **adapter-kit** — 2 new per-kind validators
1649
+ (`validatePitchforkState`, `validatePitchfanState`), reusing
1650
+ Task-2's `validateAnchorTriple` + Task-5's `validateLineDrawStyle`
1651
+ helpers. `validatePitchforkState` also pins the 4-entry variant
1652
+ enum (`standard | schiff | modifiedSchiff | inside`). The
1653
+ permissive-default test fixture moves from `pitchfork` to
1654
+ `xabcd-pattern` (Task 15's first kind, still unported).
1655
+ - **runtime** — 2 new emit functions under
1656
+ `packages/runtime/src/emit/draw/pitchforks/` wired into the
1657
+ `DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Both use the
1658
+ 3-arg form `(slotId, anchors, opts?)`. `pitchfork` accepts
1659
+ `opts: LineDrawStyle & { variant? }` — the impl destructures
1660
+ `variant` (defaulting to `"standard"`), strips it from the
1661
+ style payload, and builds the `PitchforkState`. Fall-through-stub
1662
+ fixture in `namespace.test.ts` / `primitives.test.ts` /
1663
+ `buildComputeContext.test.ts` moves from `pitchfork` to
1664
+ `xabcdPattern`.
1665
+ - **canvas2d-adapter** — 2 new renderers + a shared
1666
+ `pitchforkGeom.ts` helper exporting `medianOriginFor(variant, a,
1667
+ b, c)` and `medianTargetFor(variant, a, b, c)` (per-variant
1668
+ median-rail endpoints in canvas space). Default colour
1669
+ `"#ec4899"` (pink/magenta, mirroring invinite's pitchfork-tool
1670
+ palette family). The pitchfork renderer emits 3 strokes per
1671
+ emission (median + 2 parallel handles through `b` and `c`); the
1672
+ pitchfan renderer emits 3 rays from `a` through `b`, `mid(b, c)`,
1673
+ `c`.
1674
+ - **conformance** — 2 new per-kind scenarios + 1 bundle
1675
+ (`drawPitchforksAll.scenario.ts` covering 4 pitchfork variants +
1676
+ 1 pitchfan = 5 emissions). Conformance + scenarios + index
1677
+ test-capability fixtures widen `drawings` with
1678
+ `capabilities.allPitchforkDrawings()`. All 3 hashes pinned
1679
+ against the deterministic-run actuals.
1680
+
1681
+ Divergences flagged in
1682
+ `tasks/phase-3-drawing-parity/14-pitchforks.plan.md`:
1683
+
1684
+ - `extendLeft` / `extendRight` flags from invinite's
1685
+ `PitchforkDrawing` not on landed `PitchforkState`. Phase-3 pins
1686
+ the default extend-forward behaviour for each rail (Task-1
1687
+ reshape follow-up).
1688
+ - Per-instance `levels` array not on landed state. Phase-3 renders
1689
+ the median + 2 parallel-handle pattern only — no per-level
1690
+ offsets (Task-1 reshape follow-up).
1691
+ - `medianColor` / `medianLineStyle` / `medianStrokeWidthPx` not on
1692
+ landed state. Phase-3 paints the median with the same
1693
+ `LineDrawStyle` as the handles (Task-1 reshape follow-up).
1694
+ - `gen-docs` regeneration for the 2 new kinds deferred to Task 21
1695
+ (the existing `chartlang docs` command only walks `ta.*`; the
1696
+ `draw.*` walker extension is an explicit Task-21 deliverable).
1697
+ - Per-kind property / golden test files deferred to the pragmatic
1698
+ 1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–13.
1699
+
1700
+ See `tasks/phase-3-drawing-parity/14-pitchforks.plan.md` for the
1701
+ full audit + divergence list.
1702
+
1703
+ - b0d296b: Phase 3 Task 15 — Harmonic Patterns (`xabcdPattern` / `cypherPattern`
1704
+ / `headAndShoulders` / `abcdPattern` / `trianglePattern` /
1705
+ `threeDrivesPattern`). All 6 kinds map to the `polylines` bucket and
1706
+ ship as flat methods (`draw.<kind>(...)`) per the Task-11 Option-C
1707
+ decision.
1708
+
1709
+ - **adapter-kit** — 6 new per-kind validators
1710
+ (`validateXabcdPatternState`, `validateCypherPatternState`,
1711
+ `validateHeadAndShouldersState`, `validateAbcdPatternState`,
1712
+ `validateTrianglePatternState`,
1713
+ `validateThreeDrivesPatternState`) plus a new
1714
+ `validateAnchorHept` helper covering the 7-anchor
1715
+ `three-drives-pattern` shape. All 6 validators reuse Task-5's
1716
+ `validateLineDrawStyle` and Task-2's per-anchor-arity helpers.
1717
+ The permissive-default test fixture moves from `xabcd-pattern`
1718
+ → `elliott-impulse-wave` (Task 16's first kind, still unported).
1719
+ - **runtime** — 6 new emit functions under
1720
+ `packages/runtime/src/emit/draw/patterns/` wired into the
1721
+ `DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Each uses the
1722
+ 3-arg form `(slotId, anchors, opts?)` with the dual-overload
1723
+ pattern. Fall-through-stub fixture in `namespace.test.ts` /
1724
+ `primitives.test.ts` / `buildComputeContext.test.ts` moves from
1725
+ `xabcdPattern` to `elliottImpulseWave`.
1726
+ - **canvas2d-adapter** — 6 new renderers plus a shared
1727
+ `namedPolyline.ts` helper exporting `renderNamedPolyline(ctx,
1728
+ points, labels, style)` — strokes an open polyline through the
1729
+ pre-projected canvas-space points and fills one text label
1730
+ above each anchor (textAlign `center` + textBaseline `bottom`,
1731
+ 6 px above the anchor). Default colour `#f59e0b` (amber/orange,
1732
+ matching invinite's pattern-tool palette family).
1733
+ `headAndShoulders` adds a neckline stroke between the two
1734
+ trough anchors (`anchors[1]` → `anchors[3]`), totalling 2
1735
+ strokes per emission; the other 5 kinds emit 1 polyline stroke - N point labels.
1736
+ - **conformance** — 6 new per-kind scenarios + 1 bundle
1737
+ (`drawPatternsAll.scenario.ts` covering all 6 kinds = 6
1738
+ emissions). Conformance + scenarios + index test-capability
1739
+ fixtures widen `drawings` with
1740
+ `capabilities.allPatternDrawings()`. All 7 hashes pinned
1741
+ against the deterministic-run actuals.
1742
+
1743
+ **Provenance carve-out — `cypherPattern`.** Per the team-lead
1744
+ brief + PLAN.md §3.1, `cypher-pattern` has no standalone invinite
1745
+ tool — only the y-doc-bridge type. The runtime emit
1746
+ (`packages/runtime/src/emit/draw/patterns/cypherPattern.ts`) and
1747
+ the canvas2d renderer
1748
+ (`examples/canvas2d-adapter/src/render/draw/cypherPattern.ts`)
1749
+ both cite **only** `invinite/shared/trading-chart-collab-yjs/y-doc-bridge.ts`
1750
+ in their relicense headers (no `*-tool.ts` line). The UI surface
1751
+ for cypher lives in `defineDrawing` (Task 20).
1752
+
1753
+ Divergences flagged in
1754
+ `tasks/phase-3-drawing-parity/15-patterns.plan.md`:
1755
+
1756
+ - **`headAndShoulders` is 5-anchor on the landed state** (Task 1's
1757
+ `HeadAndShouldersState.anchors: AnchorQuint`), not the 7-anchor
1758
+ invinite shape (`start, leftShoulder, leftTrough, head,
1759
+ rightTrough, rightShoulder, end`). The renderer treats the 5
1760
+ anchors as `[LS, LL, H, RL, RS]` and strokes a neckline between
1761
+ the two trough anchors only (no start/end projection). Flagged
1762
+ as a Task-1 reshape follow-up.
1763
+ - **`trianglePattern` is 3-anchor on the landed state**
1764
+ (`TrianglePatternState.anchors: AnchorTriple`), not the 4-anchor
1765
+ invinite shape (`a, b, c, d`). The renderer treats the 3 anchors
1766
+ as `[apex, baseHigh, baseLow]` matching the landed type's
1767
+ `@anchors` annotation. Flagged as a Task-1 reshape follow-up.
1768
+ Distinct from `draw.triangle` (Task 6), a solid-shape primitive
1769
+ with `ShapeStyle` — `draw.trianglePattern` is a harmonic-pattern
1770
+ outline with `LineDrawStyle`. JSDoc cross-references the
1771
+ distinction.
1772
+ - `gen-docs` regeneration for the 6 new kinds deferred to Task 21
1773
+ (the existing `chartlang docs` command only walks `ta.*`; the
1774
+ `draw.*` walker extension is an explicit Task-21 deliverable).
1775
+ - Per-kind property / golden test files deferred to the pragmatic
1776
+ 1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–14.
1777
+
1778
+ See `tasks/phase-3-drawing-parity/15-patterns.plan.md` for the
1779
+ full audit + divergence list.
1780
+
1781
+ - b0d296b: Phase 3 Task 16 — Elliott Waves (`elliottImpulseWave` /
1782
+ `elliottCorrectionWave` / `elliottTriangleWave` / `elliottDoubleCombo`
1783
+ / `elliottTripleCombo`). All 5 kinds map to the `polylines` bucket
1784
+ and ship as flat methods (`draw.<kind>(...)`) per the Task-11
1785
+ Option-C decision.
1786
+
1787
+ - **adapter-kit** — 5 new per-kind validators
1788
+ (`validateElliottImpulseWaveState`,
1789
+ `validateElliottCorrectionWaveState`,
1790
+ `validateElliottTriangleWaveState`,
1791
+ `validateElliottDoubleComboState`,
1792
+ `validateElliottTripleComboState`) plus a new
1793
+ `validateOptionalLabels(v, path, expectedCount)` helper that
1794
+ validates the optional script-author `state.labels` override
1795
+ (when present: array of strings whose length exactly matches the
1796
+ per-kind anchor count). All 5 validators reuse Task-5's
1797
+ `validateLineDrawStyle` and Task-2/15's
1798
+ `validateAnchorTriple` / `validateAnchorQuint` /
1799
+ `validateAnchorHept`. The permissive-default test fixture moves
1800
+ from `elliott-impulse-wave` → `cyclic-lines` (Task 17's first
1801
+ kind, still unported).
1802
+ - **runtime** — 5 new emit functions under
1803
+ `packages/runtime/src/emit/draw/elliott/` wired into the
1804
+ `DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Each uses the
1805
+ 3-arg form `(slotId, anchors, opts?)` with the dual-overload
1806
+ pattern. The runtime widens `opts` to
1807
+ `LineDrawStyle & { labels?: ReadonlyArray<string> }` — the impl
1808
+ destructures `labels` from `opts`, strips it from the style
1809
+ payload, and stores it on `state.labels` only when present
1810
+ (preserving the optional field's `undefined` state when omitted
1811
+ so emission hashes stay stable). Fall-through-stub fixture in
1812
+ `namespace.test.ts` / `primitives.test.ts` /
1813
+ `buildComputeContext.test.ts` moves from `elliottImpulseWave` to
1814
+ `cyclicLines`.
1815
+ - **canvas2d-adapter** — 5 new renderers reusing Task-15's
1816
+ `renderNamedPolyline` helper. Default colour `#14b8a6` (teal —
1817
+ free palette slot distinct from blue/yellow/purple/pink/amber).
1818
+ Each renderer honours the optional `state.labels` override when
1819
+ present and its length matches the anchor count (defensive
1820
+ fallback to the per-kind default `LABELS` constant). Per-kind
1821
+ default labels: impulse `["1","2","3","4","5"]`, correction
1822
+ `["A","B","C"]`, triangle `["a","b","c","d","e"]`, double-combo
1823
+ `["S","W","x1","X","x2","Yi","Y"]`, triple-combo
1824
+ `["S","W","X1","Y","X2","Zi","Z"]`. Dispatch test's describe
1825
+ label bumps from "Task-16+ stubs" to "Task-17+ stubs".
1826
+ - **conformance** — 5 new per-kind scenarios + 1 bundle
1827
+ (`drawElliottAll.scenario.ts` covering all 5 kinds = 5
1828
+ emissions). Conformance + scenarios + index test-capability
1829
+ fixtures widen `drawings` with `capabilities.allElliottDrawings()`.
1830
+ All 6 hashes pinned against the deterministic-run actuals.
1831
+
1832
+ Divergences flagged in
1833
+ `tasks/phase-3-drawing-parity/16-elliott.plan.md`:
1834
+
1835
+ - **`WaveDegree` enum + label-decoration helper NOT on landed state**
1836
+ (Task 1's `Elliott*State` shapes carry no `degree` field — they
1837
+ carry an optional `labels?: ReadonlyArray<string>` field instead,
1838
+ letting the script author override the per-kind default labels
1839
+ directly). The 9-level `WaveDegree` enum + the
1840
+ `elliottLabels.ts` decoration helper are dropped from Phase 3.
1841
+ Flagged as a Task-1 reshape follow-up.
1842
+ - **`elliottImpulseWave` is 5-anchor on the landed state** (Task 1's
1843
+ `ElliottImpulseWaveState.anchors: AnchorQuint`), not the 6-anchor
1844
+ invinite shape. The renderer treats the 5 anchors as the wave1End
1845
+ → wave5End pivots and strokes 4 connecting legs. Same precedent
1846
+ for `elliottCorrectionWave` (landed 3-anchor vs invinite 4),
1847
+ `elliottTriangleWave` (landed 5-anchor vs invinite 6), and
1848
+ `elliottTripleCombo` (landed 7-anchor vs invinite 10). All
1849
+ flagged as Task-1 reshape follow-ups.
1850
+ - `gen-docs` regeneration for the 5 new kinds deferred to Task 21
1851
+ (the existing `chartlang docs` command only walks `ta.*`; the
1852
+ `draw.*` walker extension is an explicit Task-21 deliverable).
1853
+ - Per-kind property / golden test files deferred to the pragmatic
1854
+ 1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–15.
1855
+
1856
+ See `tasks/phase-3-drawing-parity/16-elliott.plan.md` for the full
1857
+ audit + divergence list.
1858
+
1859
+ - b0d296b: Phase 3 Task 17 — Cycles (`cyclicLines` / `timeCycles` / `sineLine`).
1860
+ All 3 kinds map to the `other` bucket and ship as flat methods
1861
+ (`draw.<kind>(a, b, opts?)`) per the Task-11 Option-C decision.
1862
+
1863
+ - **adapter-kit** — 3 new per-kind validators
1864
+ (`validateCyclicLinesState`, `validateTimeCyclesState`,
1865
+ `validateSineLineState`). All 3 reuse Task-2's `validateAnchorPair`
1866
+ - Task-5's `validateLineDrawStyle`; no new helpers needed (cycle
1867
+ states carry no `labels` field, so Task-16's
1868
+ `validateOptionalLabels` is not consumed). The permissive-default
1869
+ test fixture moves from `cyclic-lines` → `group` (Task 18's first
1870
+ kind, still unported).
1871
+ - **runtime** — 3 new emit functions under
1872
+ `packages/runtime/src/emit/draw/cycles/` wired into the
1873
+ `DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. Each uses the
1874
+ 4-arg dual-overload form `(slotId, a, b, opts?)` mirroring `line`
1875
+ (the script-author surface is the 3-arg `(a, b, opts?)`; the
1876
+ compiler injects the leading slot id). State is assembled as
1877
+ `anchors: [a, b]`. Fall-through-stub fixture in
1878
+ `namespace.test.ts` / `primitives.test.ts` /
1879
+ `buildComputeContext.test.ts` moves from `cyclicLines` to `group`.
1880
+ - **canvas2d-adapter** — 3 new renderers reusing Task-4's
1881
+ `worldPointToCanvas` + Phase-1 `dashPattern`. Default colour
1882
+ `#0ea5e9` (sky blue — free palette slot distinct from
1883
+ blue/yellow/purple/pink/amber/teal/green/red used by prior port
1884
+ tasks). Per-kind geometry:
1885
+
1886
+ - `cyclicLines` — repeated full-height vertical strokes at
1887
+ `fromX + n * periodPx` for n ∈ [0, viewport+overscan/periodPx],
1888
+ capped at 256 iterations. Skips silently on degenerate period.
1889
+ - `timeCycles` — concentric upper-half arcs centred at the
1890
+ midpoint of `(from, to)` on the `from.price` baseline, radius =
1891
+ `|toX − fromX| / 2`. Arcs tile across the viewport at multiples
1892
+ of the diameter (64 per side). Skips silently on degenerate
1893
+ diameter.
1894
+ - `sineLine` — sampled sinusoidal polyline. Half-period =
1895
+ `|toX − fromX|` (full period doubled). Baseline = midpoint of
1896
+ `(fromY, toY)`. Amplitude = `|fromY − toY| / 2`. 32 samples per
1897
+ full period; wave starts at the `from` extreme (peak vs trough
1898
+ flipped by `fromPx.y < toPx.y` — mirrors invinite's
1899
+ `extremeIsPeak` flag). Skips silently on degenerate half-period.
1900
+
1901
+ Dispatch test's describe labels bump from "Tasks 5–15 shipped" to
1902
+ "Tasks 5–17 shipped" and "Task-17+ stubs" to "Task-18+ stubs".
1903
+
1904
+ - **conformance** — 3 new per-kind scenarios + 1 bundle
1905
+ (`drawCyclesAll.scenario.ts` covering all 3 kinds = 3 emissions).
1906
+ Conformance + scenarios + index test-capability fixtures widen
1907
+ `drawings` with `capabilities.allCycleDrawings()`. All 4 hashes
1908
+ pinned against the deterministic-run actuals:
1909
+ `drawCyclicLines` = `975166fe…aae16`,
1910
+ `drawTimeCycles` = `1bdaca36…d88c0`,
1911
+ `drawSineLine` = `9f88b689…3ba8`,
1912
+ `drawCyclesAll` = `ef46754f…cc80b`.
1913
+
1914
+ Divergences flagged in
1915
+ `tasks/phase-3-drawing-parity/17-cycles.plan.md`:
1916
+
1917
+ - **`SineLineState.period: number` field NOT on landed state**
1918
+ (Task 1's `SineLineState` carries only `anchors` + `style` —
1919
+ the renderer derives the half-period from `|to.time − from.time|`,
1920
+ matching invinite's tool source). The explicit `period: number`
1921
+ field is dropped from Phase 3; flagged as a Task-1 reshape
1922
+ follow-up.
1923
+ - **`TimeCyclesState.style.fill` / `fillAlpha` NOT on landed state**
1924
+ (Task 1's `TimeCyclesState` uses `LineDrawStyle`, not
1925
+ `ShapeStyle`). The renderer strokes the arcs only — invinite's
1926
+ tool source DOES fill the half-circles. Flagged as a Task-1
1927
+ reshape follow-up.
1928
+ - **`to.time > from.time` reject NOT enforced** — Phase-3 renderer
1929
+ no-ops silently on degenerate input, matching every other Phase-3
1930
+ drawing port (gann / fib / elliott all silently no-op on
1931
+ collapsed anchors). The validator accepts reversed anchors per
1932
+ `validateAnchorPair`'s finite-only contract.
1933
+ - `gen-docs` regeneration for the 3 new kinds deferred to Task 21
1934
+ (the existing `chartlang docs` command only walks `ta.*`; the
1935
+ `draw.*` walker extension is an explicit Task-21 deliverable).
1936
+ - Per-kind property / golden test files deferred to the pragmatic
1937
+ 1-file-per-emit + 1-file-per-renderer set, mirroring Tasks 5–16.
1938
+
1939
+ See `tasks/phase-3-drawing-parity/17-cycles.plan.md` for the full
1940
+ audit + divergence list.
1941
+
1942
+ - b0d296b: Phase 3 Task 18 — Containers (`group` / `frame`). The FINAL per-port
1943
+ task: after this lands all 61 `DrawingKind`s have real validator /
1944
+ emit / renderer / dispatch arms. Both kinds map to the `other`
1945
+ bucket and ship as flat methods (`draw.group(childHandleIds)` /
1946
+ `draw.frame(a, b, opts?)`) per the Task-11 Option-C decision.
1947
+
1948
+ - **adapter-kit** — 2 new per-kind validators (`validateGroupState`,
1949
+ `validateFrameState`) + 2 tiny shared helpers
1950
+ (`validateOptionalChildHandleIds`, `validateFrameOpts`). `group`
1951
+ pins `childHandleIds.length ≤ 100`; `frame` reuses Task-2's
1952
+ `validateAnchorPair`, accepts degenerate anchors (silent no-op at
1953
+ the renderer per the rest of Phase-3's degenerate-input
1954
+ precedent). The permissive-default test fixture
1955
+ (`validateEmission.test.ts:1516`) flips from
1956
+ `permissively-accepts` to a rejecting `validateGroupState`
1957
+ assertion + a new gate-only test that asserts unknown kinds drop
1958
+ with `unsupported-drawing-kind` upstream. After Task 18 every
1959
+ `DrawingKind` has a real validator arm — the
1960
+ `default: return { ok: true };` arm in `validateStateByKind` is
1961
+ removed; TS's exhaustiveness check now catches a future
1962
+ `DrawingKind` addition without a validator.
1963
+ - **runtime** — 2 new emit functions under
1964
+ `packages/runtime/src/emit/draw/containers/` wired into the
1965
+ `DRAW_NAMESPACE` `KIND_IMPLS` map as flat methods. `group` is a
1966
+ 2-arg dual-overload `(slotId, childHandleIds)`; `frame` is a 4-arg
1967
+ dual-overload `(slotId, a, b, opts?)` mirroring `line`. After Task
1968
+ 18 `IMPL_KIND_NAMES.size === 61`; the Proxy's else-branch
1969
+ fall-through to core's throwing-stub is dead code on the
1970
+ `DrawNamespace` type surface — kept as defence-in-depth for
1971
+ property access outside that type. The pre-Task-18
1972
+ "still-stubbed" assertions in `namespace.test.ts` /
1973
+ `primitives.test.ts` / `buildComputeContext.test.ts` are replaced
1974
+ with a positive cardinality sweep that asserts every
1975
+ `DrawingKind` resolves to a real runtime impl that throws the
1976
+ in-step-only sentinel (NOT the core stub sentinel).
1977
+ - **canvas2d-adapter** — 1 real renderer (`renderFrame`) + 1 pure
1978
+ no-op renderer (`renderGroup`). `renderFrame` strokes a closed
1979
+ 4-corner rectangle defaulting to slate `#64748b`, optionally
1980
+ paints a `fillRect` background when `style.bgColor` is set, and
1981
+ optionally paints a `fillText` label inset 6 px from the top-left
1982
+ when `style.label` is set. Degenerate anchors (zero width or zero
1983
+ height in canvas space) silently no-op. `renderGroup` is a pure
1984
+ no-op for Phase 3 — the visible bounding-box envelope around
1985
+ grouped drawings is a Phase-4 follow-up tied to
1986
+ `Viewport.drawingsById` plumbing (Viewport currently exposes only
1987
+ `xMin/xMax/yMin/yMax/pxWidth/pxHeight`). `drawingDispatch`'s
1988
+ `// Containers (Task 18)` arms flip from `return;` no-ops to
1989
+ `return renderGroup(...)` / `return renderFrame(...)`. The
1990
+ `drawingDispatch.test.ts` describe labels bump:
1991
+ `Task-18+ stubs` → `'group' no-op + exhaustiveness`;
1992
+ `Tasks 5–17 shipped` → `Tasks 5–18 shipped`.
1993
+ - **conformance** — 2 new per-kind scenarios (`drawGroup`,
1994
+ `drawFrame`) + 1 bundle (`drawContainersAll`, 2 emissions).
1995
+ Pinned `drawing-hash` assertions for each:
1996
+ - `draw-group`:
1997
+ `6e32e387543ef421d1e53c1c15612cc32a814c85c2d969ad86d9f47b8d0359a2`
1998
+ - `draw-frame`:
1999
+ `4b54e0b6e75ad40904e0f70ac5b34067afa6c1237d43060823889f04b86d900b`
2000
+ - `draw-containers-all`:
2001
+ `e6ba183dfc04145a5126e6ea75a4cb7117694adc13eea84853239c68810e91fe`
2002
+ `TEST_CAPABILITIES.drawings` widens with
2003
+ `...capBuilders.allContainerDrawings()`; the `ALL_SCENARIOS`
2004
+ `toEqual` array (in `scenarios.test.ts` and `index.test.ts`)
2005
+ appends the 3 new scenarios under
2006
+ `// Phase 3 Task 18 — Containers.`.
2007
+
2008
+ ### Divergences from spec (`tasks/phase-3-drawing-parity/18-containers.md`)
2009
+
2010
+ 1. **Spec § Runtime Notes says `draw.group(children:
2011
+ ReadonlyArray<DrawingHandle>)` accepts handle objects.** Landed
2012
+ core surface takes `ReadonlyArray<string>` (handle ids) directly
2013
+ — the runtime impl uses the landed shape so the wire payload is
2014
+ 1:1 with what the script passes. Documented in `draw.group`'s
2015
+ JSDoc with the canonical `draw.group([a.id, b.id])` pattern.
2016
+ 2. **Spec § Renderer Notes says `group` renders a dashed bounding
2017
+ box derived from children's `view.drawingsById.get(childId).state`
2018
+ extrema.** Landed `Viewport` exposes no `drawingsById` field;
2019
+ adding it is a foundation-level Viewport change beyond a per-port
2020
+ task. Phase 3 ships `renderGroup` as a pure no-op (children
2021
+ render themselves per `GroupState`'s metadata contract);
2022
+ bounding-box envelope deferred to Phase 4.
2023
+ 3. **Spec § Kinds Landed says `group.style: { lineWidth?; color? }`
2024
+ for the boundary box.** Landed `GroupState` has no `style` field
2025
+ (only `childHandleIds` + optional `meta`). Use the landed shape;
2026
+ the boundary-box style lands with the Phase-4 renderer rework.
2027
+ 4. **Spec § Tests says degenerate `frame` anchors are a warning
2028
+ diagnostic.** Landed `validateAnchorPair` only enforces finite
2029
+ `time`/`price`; degenerate frames pass validation and the
2030
+ renderer silently no-ops on `width === 0 || height === 0`. This
2031
+ matches the rest of Phase 3's "no-op on degenerate input"
2032
+ precedent (gann/fib/elliott/cycles).
2033
+ 5. **Per-kind property tests skipped** — same Tasks 5–17 precedent.
2034
+ The per-kind validator describe arms cover happy + wrong-shape
2035
+ per kind; the `childHandleIds.length ≤ 100` cap is exercised
2036
+ directly in the group describe block.
2037
+
2038
+ ### Open / deferred
2039
+
2040
+ - `GroupState` boundary-box style + `view.drawingsById` plumbing for
2041
+ the visible group envelope land in Phase 4 (Divergence §2 + §3).
2042
+ - `gen-docs` regeneration for `docs/primitives/draw/{group,frame}.md`
2043
+ defers to Task 21 (same precedent as Tasks 11–17 — the
2044
+ draw-namespace docs walker is Task 21's deliverable).
2045
+ - Workspace-wide gates (`pnpm typecheck`, `pnpm test` at the root)
2046
+ defer to Task 22's phase closeout. Per-package gates
2047
+ (adapter-kit / runtime / canvas2d / conformance) all green and
2048
+ 100% coverage held.
2049
+
2050
+ - b0d296b: Phase-3 Task 3 — runtime `draw.*` emission infrastructure.
2051
+
2052
+ **Runtime** — new `packages/runtime/src/emit/draw/` subtree:
2053
+
2054
+ - `createDrawingHandle(slotId, subId, kind, initialState)` allocates
2055
+ a per-handle slot in `ctx.drawingSlots` keyed by `slotId#subId`,
2056
+ emits the first `op: "create"`, and returns a `DrawingHandle`
2057
+ whose `update(patch)` re-emits the FULL merged state under
2058
+ `op: "update"` (PLAN.md §10.3 full-state semantic) and whose
2059
+ `remove()` emits one final `op: "remove"` and flags the slot
2060
+ `removed: true`. Subsequent `update` / `remove` calls on a removed
2061
+ handle no-op. Cross-bar re-entry at the same `slotId#subId`
2062
+ resurrects the slot and emits `op: "update"`.
2063
+ - `pushDrawing(ctx, e)` enforces capability gating
2064
+ (`unsupported-drawing-kind`), wire-shape validation
2065
+ (`malformed-emission`), per-bucket budget on
2066
+ `op: "create"`/`"remove"` against
2067
+ `min(scriptMaxDrawings, adapter.maxDrawingsPerScript)`
2068
+ (`drawing-budget-exceeded`, clamped at zero on remove), and
2069
+ per-bar `(handleId, bar)` dedup (last-write-wins).
2070
+ - `nextSubId(ctx, slotId)` / `resetSubIdCounters(ctx)` —
2071
+ per-callsite per-bar counter; reset at the top of every
2072
+ `onBarClose` / `onBarTick` so iteration `i` at the same callsite
2073
+ yields the same `slotId#i` across bars.
2074
+ - `draw` re-exports core's throwing-stub Proxy verbatim. Per-kind
2075
+ Tasks 5–18 swap real impls into this seam (mirroring how the
2076
+ Phase-2 `ta` re-export switched to `TA_REGISTRY`).
2077
+
2078
+ `RuntimeContext` widens with four new fields: `drawingSlots`,
2079
+ `drawingSubIdCounters`, `drawingBucketCounters`, `scriptMaxDrawings`.
2080
+ `createScriptRunner` initialises them and reads
2081
+ `compiled.manifest.maxDrawings` for the script-side cap. `dispose`
2082
+ clears the slots and resets counters.
2083
+
2084
+ `buildComputeContext` now injects `draw` into the `ComputeContext`
2085
+ the runner hands the compiled script.
2086
+
2087
+ **Core** — `ComputeContext.draw: DrawNamespace` field added (the
2088
+ script-facing surface). Phase-1/-2 scripts that do not consume
2089
+ `draw` keep compiling unchanged; new scripts pick up the namespace
2090
+ through the same destructure pattern as `ta` / `plot` / `hline` /
2091
+ `alert`.
2092
+
2093
+ **Conformance** — `ScenarioAssertion` grows a sixth `drawing-hash`
2094
+ variant. `BufferedRun.drawings` carries the per-bar drained
2095
+ emissions; `hashDrawingSeries(drawings, handleId?)` hashes
2096
+ JSON-stringified `{ handleId, kind, op, state, bar }` tuples in
2097
+ emission order. Failure messages mirror `plot-hash`:
2098
+ `drawing-hash[<label>]: expected <pinned>, actual <computed>
2099
+ (<N> emissions)` — copy `actual` to re-pin.
2100
+
2101
+ No behaviour change for Phase-1/-2 scenarios — the runtime still
2102
+ emits no drawings until the per-kind ports (Tasks 5–18) land.
2103
+
2104
+ - b0d296b: Phase-3 Task 5 — first per-port task. Lands the 6 line-family drawing
2105
+ kinds (`line`, `horizontalLine`, `horizontalRay`, `verticalLine`,
2106
+ `crossLine`, `trendAngle`) per PLAN.md §10 and §22.10.
2107
+
2108
+ `@invinite-org/chartlang-runtime` ships 6 new `draw.<kind>(...)` emit
2109
+ functions under `src/emit/draw/lines/` plus the `DRAW_NAMESPACE` swap
2110
+ seam at `src/emit/draw/namespace.ts` — the namespace re-exports core's
2111
+ throwing-stub Proxy for the 55 kinds that haven't shipped yet and
2112
+ routes the 6 line kinds through their runtime impls. Each impl uses
2113
+ the dual-overload pattern (`(a, b, opts?)` script-facing throw +
2114
+ `(slotId, a, b, opts?)` compiler-injected) mirroring `plot` / `alert`.
2115
+ Returns a `DrawingHandle` per PLAN.md §10.3; subsequent in-bar
2116
+ `update(patch)` calls merge into the slot's state and re-emit the
2117
+ full payload.
2118
+
2119
+ `@invinite-org/chartlang-compiler` widens the core ambient shim
2120
+ (`program.ts`) with `WorldPoint`, `LineDrawStyle`, `DrawingHandle`,
2121
+ `DrawNamespace` declarations + `export const draw: DrawNamespace` so
2122
+ the callsite-id transformer recognises `draw.<kind>(...)` calls and
2123
+ injects the slot id (entries already shipped in `STATEFUL_PRIMITIVES`
2124
+ via Task 1).
2125
+
2126
+ `chartlang-example-canvas2d-adapter` ships 6 new renderers under
2127
+ `src/render/draw/` — `line.ts`, `horizontalLine.ts`,
2128
+ `horizontalRay.ts`, `verticalLine.ts`, `crossLine.ts`,
2129
+ `trendAngle.ts` — plus the shared `extendLineSegment` helper that
2130
+ projects a segment to the viewport edges (consumed by `line` when its
2131
+ `extendLeft`/`extendRight` flags are set, and by `horizontalRay`
2132
+ which always extends right). The `drawingDispatch` switch arms for
2133
+ the 6 line kinds flip from no-op stubs to real-impl calls; the
2134
+ exhaustive `satisfies never` default and `op: "remove"` short-circuit
2135
+ are unaffected. The `trendAngle` renderer additionally draws a small
2136
+ arc + angle text at the `from` anchor, mirroring the invinite tool's
2137
+ `paintTrendAngleArc`.
2138
+
2139
+ `@invinite-org/chartlang-conformance` lands 7 new bundled scenarios:
2140
+ 6 per-kind (`DRAW_LINE_SCENARIO`, `DRAW_HORIZONTAL_LINE_SCENARIO`,
2141
+ `DRAW_HORIZONTAL_RAY_SCENARIO`, `DRAW_VERTICAL_LINE_SCENARIO`,
2142
+ `DRAW_CROSS_LINE_SCENARIO`, `DRAW_TREND_ANGLE_SCENARIO`) plus one
2143
+ category bundle (`DRAW_LINES_AND_RAYS_SCENARIO`). Each uses
2144
+ `inlineSource` and pins one `drawing-hash` assertion + asserts
2145
+ `unsupported-drawing-kind` and `drawing-budget-exceeded` are absent.
2146
+ The `TEST_CAPABILITIES` bag in the conformance test suite widens
2147
+ `drawings` to `capabilities.allLineDrawings()` and lifts the `lines`
2148
+ bucket budget from `0` to `100` so the new scenarios reach
2149
+ `pushDrawing`'s happy path. All 7 scenarios pass against the
2150
+ canvas2d default adapter (which already declared
2151
+ `drawings: capabilities.allPhase3Drawings()` via Task 4).
2152
+
2153
+ All Phase-1 / Phase-2 / Tasks-1–4 gates remain green. 100% coverage
2154
+ maintained across `runtime`, `canvas2d-adapter`, and `conformance`.
2155
+
2156
+ - b0d296b: Phase-3 Task 6 — second per-port task. Lands the 4 straight-edged
2157
+ box-family drawing kinds (`rectangle`, `rotatedRectangle`, `triangle`,
2158
+ `polyline`) per PLAN.md §10 and §22.10. Behaviour ports from invinite
2159
+ commit `078f41fe2569d659d5aba726da8bcb5d3e2ced02`:
2160
+ `tools/rectangle-tool.ts`, `tools/rotated-rectangle-tool.ts`,
2161
+ `tools/triangle-tool.ts`, `tools/polyline-tool.ts`, and the matching
2162
+ `y-doc-bridge.ts` `DrawingMetadata` variants.
2163
+
2164
+ `@invinite-org/chartlang-adapter-kit` adds per-kind state validators
2165
+ for the 4 box-A kinds — `validateRectangleState`,
2166
+ `validateRotatedRectangleState`, `validateTriangleState`,
2167
+ `validatePolylineState` — wired into the existing
2168
+ `validateStateByKind` dispatch. New file-local helpers
2169
+ `validateAnchorTriple` / `validateAnchorQuad` /
2170
+ `validateAnchorVariable(min, max)` / `validateShapeStyle` cover the
2171
+ anchor cardinalities and the `ShapeStyle` payload bag. `polyline`
2172
+ pins `3 ≤ anchors.length ≤ 20` (mirrors invinite's 20-point cap).
2173
+ Wire shape is stricter than before — payloads previously passing the
2174
+ permissive default arm now reject with `malformed-emission`.
2175
+
2176
+ `@invinite-org/chartlang-runtime` ships 4 new `draw.<kind>(...)` emit
2177
+ functions under `src/emit/draw/boxes/` and extends the
2178
+ `DRAW_NAMESPACE` swap-seam at `src/emit/draw/namespace.ts`. Each impl
2179
+ uses the dual-overload pattern (`(...)` script-facing throw +
2180
+ `(slotId, ...)` compiler-injected) mirroring Task 5 / `plot` /
2181
+ `alert`. Returns a `DrawingHandle` per PLAN.md §10.3.
2182
+
2183
+ `chartlang-example-canvas2d-adapter` ships 4 new renderers under
2184
+ `src/render/draw/` plus a shared `shapeStyle.ts` helper exporting
2185
+ `applyShapeStyle(ctx, style): AppliedShapeStyle` — sets stroke /
2186
+ lineWidth / dash and returns the resolved fill payload so the
2187
+ renderer can wrap `ctx.fill()` in a `globalAlpha` bracket. The
2188
+ `drawingDispatch` switch flips the 4 box-A arms from no-op stubs to
2189
+ real `renderXxx(ctx, e, view)` calls; exhaustiveness is preserved.
2190
+ Fill defaults to no-op, stroke defaults to `"#000000"`, lineWidth
2191
+ defaults to `1`. Rectangle is rendered as a closed 4-corner polygon
2192
+ (no `strokeRect` in the structural `RenderCtx`); rotatedRectangle
2193
+ walks the four world anchors directly (no canvas matrix ops);
2194
+ triangle walks 3 vertices; polyline auto-closes via `closePath()`.
2195
+
2196
+ `@invinite-org/chartlang-conformance` ships 5 new scenarios under
2197
+ `src/scenarios/` — 4 per-kind (`drawRectangle`, `drawRotatedRectangle`,
2198
+ `drawTriangle`, `drawPolyline`) and 1 bundle (`drawBoxesA`). All five
2199
+ use `inlineSource` against the bundled 10 000-bar `goldenBars.json`
2200
+ fixture with anchor times pulled from `bars[0]` / `bars[500]` /
2201
+ `bars[1000]`. The `TEST_CAPABILITIES` bag in
2202
+ `runConformanceSuite.test.ts` + `scenarios.test.ts` widens to include
2203
+ `allBoxDrawings()` plus `boxes: 100` / `polylines: 100` budgets so
2204
+ the new scenarios reach `pushDrawing`'s happy path. The 5 new
2205
+ scenarios extend `ALL_SCENARIOS` (now 96 entries) and the public
2206
+ re-export surface.
2207
+
2208
+ No core edits — the `DrawingState` variants and `DrawNamespace`
2209
+ signatures Task 1 shipped are the canonical shape and Task 6 wires
2210
+ real impls to them.
2211
+
2212
+ Deviations from spec, flagged for review:
2213
+
2214
+ - Spec's `rotatedRectangle` "3 anchors (a, b, widthOffset)"
2215
+ ergonomics — Task 1's `AnchorQuad` (4 corners) is the persisted
2216
+ shape. Callers supply the 4 corners directly; the
2217
+ (a, b, widthOffset) reshape belongs to Task 20's `defineDrawing`
2218
+ if it remains a hard requirement.
2219
+ - Spec's `polyline` `ShapeStyle` + auto-close — Task 1 ships
2220
+ `LineDrawStyle` (no fill). Renderer strokes the closed path; fill
2221
+ would require widening the variant in a follow-up.
2222
+ - Per-kind §22.10 5-file test set deferred to pragmatic 1-file set
2223
+ (mirrors Task 5) — Task 3's `pushDrawing.*` and `handle.*` suite
2224
+ covers the underlying infra exhaustively.
2225
+ - `gen-docs` doc-page generation deferred to Task 21 (mirrors Task 5).
2226
+
2227
+ - b0d296b: Phase-3 Task 7 — third per-port task. Lands the 4 curved-edge /
2228
+ single-anchor box-family drawing kinds (`circle`, `ellipse`, `path`,
2229
+ `marker`) per PLAN.md §10 and §22.10. Behaviour ports from invinite
2230
+ commit `078f41fe2569d659d5aba726da8bcb5d3e2ced02`:
2231
+ `tools/circle-tool.ts`, `tools/ellipse-tool.ts`, `tools/path-tool.ts`,
2232
+ `tools/marker-tool.ts`, and the matching `y-doc-bridge.ts` variants.
2233
+
2234
+ `@invinite-org/chartlang-adapter-kit` adds per-kind state validators
2235
+ for the 4 box-B kinds — `validateCircleState`, `validateEllipseState`,
2236
+ `validatePathState`, `validateMarkerState` — wired into the existing
2237
+ `validateStateByKind` dispatch. New file-local helpers
2238
+ `validatePathOpts` (LineDrawStyle + optional `closed: boolean`) and
2239
+ `validateTextOpts` (color / size / halign / valign / bgColor enums)
2240
+ cover the path / marker style bags. `path` pins
2241
+ `2 ≤ anchors.length ≤ 20` (mirrors invinite's 20-point cap and is
2242
+ narrower than `polyline`'s 3..20 because path supports a 2-point
2243
+ segment with optional caps). Wire shape is stricter than before —
2244
+ payloads previously passing the permissive default arm now reject
2245
+ with `malformed-emission`.
2246
+
2247
+ `@invinite-org/chartlang-runtime` ships 4 new `draw.<kind>(...)` emit
2248
+ functions under `src/emit/draw/boxes/` and extends the
2249
+ `DRAW_NAMESPACE` swap-seam at `src/emit/draw/namespace.ts`. Each impl
2250
+ uses the dual-overload pattern Tasks 5 + 6 pinned. `draw.marker`
2251
+ splits its `opts` bag — top-level `text` / `value` land on
2252
+ `MarkerState` while the remaining `TextOpts` fields nest under
2253
+ `state.style`.
2254
+
2255
+ `chartlang-example-canvas2d-adapter` ships 4 new renderers under
2256
+ `src/render/draw/`. `renderCircle` derives the radius in canvas-pixel
2257
+ space from `|edge - centre|` (matches invinite's circle-tool) and
2258
+ issues a single `ctx.arc(...)`. `renderEllipse` paints a 64-segment
2259
+ polyline approximation (Phase-1 `RenderCtx` exposes `arc(...)` but
2260
+ not `ellipse(...)` — a polyline keeps the renderer pure on the
2261
+ existing structural surface without widening it). `renderPath` paints
2262
+ an OPEN polyline (no `closePath` by default; `style.closed === true`
2263
+ toggles closure). `renderMarker` projects the anchor + paints
2264
+ `text` (when set) via `ctx.fillText` with `TextOpts`-derived font +
2265
+ alignment. Empty / undefined text is a pure no-op — icon-glyph
2266
+ painting belongs to Task 20's `defineDrawing` follow-up. The
2267
+ `drawingDispatch` switch flips the 4 box-B arms from no-op stubs to
2268
+ real `renderXxx(ctx, e, view)` calls; exhaustiveness is preserved.
2269
+
2270
+ `@invinite-org/chartlang-conformance` ships 4 new per-kind scenarios
2271
+ under `src/scenarios/` (`drawCircle`, `drawEllipse`, `drawPath`,
2272
+ `drawMarker`). Per README §22.10 the Task-6 `drawBoxesA.scenario.ts`
2273
+ is REPLACED (deleted) by the wider `drawBoxesAll.scenario.ts`
2274
+ covering all 8 box kinds across Tasks 6 + 7 (rectangle /
2275
+ rotated-rectangle / triangle / polyline / circle / ellipse / path /
2276
+ marker). All five new scenarios use `inlineSource` against the
2277
+ bundled 10 000-bar `goldenBars.json` fixture with anchor times pulled
2278
+ from `bars[0]` / `bars[500]` / `bars[1000]`. The `TEST_CAPABILITIES`
2279
+ bag in `runConformanceSuite.test.ts` + `scenarios.test.ts` bumps
2280
+ `labels` budget from 0 to 100 to host the marker scenario (marker
2281
+ maps to the `labels` bucket). The 4 + 1 new scenarios extend
2282
+ `ALL_SCENARIOS` and the public re-export surface; `DRAW_BOXES_A_SCENARIO`
2283
+ is removed from the public surface (downstream consumers move to
2284
+ `DRAW_BOXES_ALL_SCENARIO`).
2285
+
2286
+ No core edits — the `DrawingState` variants and `DrawNamespace`
2287
+ signatures Task 1 shipped are the canonical shape and Task 7 wires
2288
+ real impls to them.
2289
+
2290
+ Deviations from spec, flagged for review:
2291
+
2292
+ - `MarkerState` shape divergence — task spec's `markerKind` (`emoji` /
2293
+ `icon`) discriminator + `value: string` + `MAX_LENGTH = 32` + icon
2294
+ registry NOT implemented. Uses Task 1's landed
2295
+ `{ anchor, text?, value?, style: TextOpts }` shape (anchor not
2296
+ from/to pair; value is a number; no discriminator). Re-shaping
2297
+ belongs to a follow-up that widens core; mid-phase Task-1 reshapes
2298
+ cascade through the `DrawingState` union + adapter-kit decoder +
2299
+ Task-6 permissive-default tests.
2300
+ - `Ellipse` rendered as 64-segment polyline approximation because
2301
+ `RenderCtx` exposes `arc(...)` but not `ellipse(...)`. Widening
2302
+ the structural type would touch Phase-1's `RenderCtx`; the
2303
+ polyline path stays on the existing surface.
2304
+ - Per-kind §22.10 5-file test set deferred to pragmatic 1-file set
2305
+ (mirrors Tasks 5 + 6) — Task 3's `pushDrawing.*` and `handle.*`
2306
+ suite covers the underlying infra exhaustively.
2307
+ - `gen-docs` doc-page generation deferred to Task 21 (mirrors Tasks
2308
+ 5 + 6).
2309
+
2310
+ - b0d296b: Phase-3 Task 8 — fourth per-port task. Lands the 6 curve + freehand
2311
+ drawing kinds (`arc`, `curve`, `doubleCurve`, `pen`, `highlighter`,
2312
+ `brush`) per PLAN.md §10 and §22.10. Behaviour ports from invinite
2313
+ commit `078f41fe2569d659d5aba726da8bcb5d3e2ced02`:
2314
+ `tools/arc-tool.ts`, `tools/curve-tool.ts`,
2315
+ `tools/double-curve-tool.ts`, `tools/pen-tool.ts`,
2316
+ `tools/highlighter-tool.ts`, `tools/brush-tool.ts`, and the matching
2317
+ `y-doc-bridge.ts` variants (`ArcDrawing`, `CurveDrawing`,
2318
+ `DoubleCurveDrawing`, `PenDrawing`, `HighlighterDrawing`,
2319
+ `BrushDrawing`). All 6 kinds map to the `polylines` bucket.
2320
+
2321
+ `@invinite-org/chartlang-adapter-kit` adds per-kind state validators
2322
+ for the 6 curve + freehand kinds — `validateArcState`,
2323
+ `validateCurveState`, `validateDoubleCurveState`, `validatePenState`,
2324
+ `validateHighlighterState`, `validateBrushState` — wired into the
2325
+ existing `validateStateByKind` dispatch. Three new file-local helpers
2326
+ land alongside: `validateAnchorQuint` (5-tuple for `double-curve`),
2327
+ `validateHighlighterStyle` (required `color: string` + required
2328
+ `alpha ∈ [0, 1]`), and `validateBrushStyle` (required `stroke` + `fill`
2329
+ colour strings). Freehand kinds pin `2 ≤ anchors.length ≤ 500`
2330
+ (matches invinite's stroke cap; broader than the 2..20 path cap).
2331
+ Wire shape is stricter than before — payloads previously passing the
2332
+ permissive default arm now reject with `malformed-emission`.
2333
+
2334
+ `@invinite-org/chartlang-runtime` ships 6 new `draw.<kind>(...)` emit
2335
+ functions under `src/emit/draw/curves/` and extends the
2336
+ `DRAW_NAMESPACE` swap-seam at `src/emit/draw/namespace.ts`. Each impl
2337
+ uses the dual-overload pattern Tasks 5–7 pinned. `draw.highlighter`
2338
+ and `draw.brush` differ from the other emit fns — their `opts`
2339
+ parameter is REQUIRED on the script-facing overload (no `?` because
2340
+ `HighlighterStyle` / `BrushStyle` carry required fields).
2341
+
2342
+ `chartlang-example-canvas2d-adapter` ships 6 new renderers under
2343
+ `src/render/draw/`. The 3 curve renderers (`renderArc`, `renderCurve`,
2344
+ `renderDoubleCurve`) sample the curve via Task 4's `sampleQuadratic` /
2345
+ `sampleCubic` helpers at `CURVE_SAMPLES = 32` segments and stroke as a
2346
+ polyline — the structural `RenderCtx` exposes neither
2347
+ `quadraticCurveTo` nor `bezierCurveTo`, so this keeps the renderer
2348
+ pure on the Phase-1 surface (mirrors Task 7's `ellipse` 64-segment
2349
+ polyline approximation). `renderArc` derives the Bezier control point
2350
+ from `apex` via inverse-quadratic interpolation so the curve passes
2351
+ through `apex` at `t = 0.5`; `renderCurve` uses `anchors[1]` as the
2352
+ Bezier control directly (curve does NOT pass through control);
2353
+ `renderDoubleCurve` paints a single cubic from `anchors[0]` to
2354
+ `anchors[4]` with off-curve controls `anchors[1]` / `anchors[3]` (the
2355
+ middle stitch anchor `anchors[2]` is preserved in state but unused by
2356
+ the current render path — flagged for future split-rendering). The 3
2357
+ freehand renderers paint polylines: `renderPen` strokes open;
2358
+ `renderHighlighter` wraps the stroke in a `globalAlpha` set/reset
2359
+ bracket (default 6 px line width); `renderBrush` paints
2360
+ fill-then-stroke with `closePath` for a closed filled region. The
2361
+ `drawingDispatch` switch flips the 6 arms from no-op stubs to real
2362
+ `renderXxx(ctx, e, view)` calls; exhaustiveness is preserved.
2363
+
2364
+ `@invinite-org/chartlang-conformance` ships 6 new per-kind scenarios
2365
+ under `src/scenarios/` (`drawArc`, `drawCurve`, `drawDoubleCurve`,
2366
+ `drawPen`, `drawHighlighter`, `drawBrush`) plus one bundle scenario
2367
+ `drawCurvesAndFreehandAll` that emits one drawing per curve + freehand
2368
+ kind on the first bar (per README §22.10 Task 8 collapses both
2369
+ categories into ONE bundle). All seven scenarios use `inlineSource`
2370
+ against the bundled 10 000-bar `goldenBars.json` fixture with anchor
2371
+ times pulled from `bars[0]` / `bars[500]` / `bars[1000]` (plus
2372
+ `bars[1500]` for the 4-point freehand strokes). The `TEST_CAPABILITIES`
2373
+ bags in `runConformanceSuite.test.ts` + `scenarios/scenarios.test.ts`
2374
+ extend the `drawings` set with `allCurveDrawings()` +
2375
+ `allFreehandDrawings()`; the existing `polylines: 100` bucket budget
2376
+ covers the bundle scenarios with headroom. `ALL_SCENARIOS` extends
2377
+ additively.
2378
+
2379
+ No core edits — the `DrawingState` variants and `DrawNamespace`
2380
+ signatures Task 1 shipped are the canonical shape and Task 8 wires
2381
+ real impls to them.
2382
+
2383
+ Deviations from spec, flagged for review:
2384
+
2385
+ - `PressurePoint` type widening NOT applied — Task 1's `PenState`
2386
+ shape (`anchors: ReadonlyArray<WorldPoint>`) preserved per Tasks
2387
+ 6/7 precedent of not reshaping Task-1 mid-phase. Adapter-level
2388
+ pressure-driven stroke-width variance is a follow-up concern.
2389
+ - `freehand.ts` smoothing helper NOT created. Per-renderer inline
2390
+ polyline loops suffice for Phase-3 deterministic `drawing-hash`
2391
+ assertions. If pressure-driven smoothing lands later, the helper
2392
+ can ship then.
2393
+ - `double-curve` middle anchor (`anchors[2]`, the stitch point) is
2394
+ preserved in state but currently unused by the renderer (single
2395
+ cubic from `anchors[0]` to `anchors[4]` with controls `[1]` / `[3]`).
2396
+ Future split-rendering can stitch two cubics through `mid`.
2397
+ - `arc` / `curve` / `doubleCurve` fill-path NOT rendered.
2398
+ `LineDrawStyle` has no fill fields; invinite's tools do support
2399
+ fill on these kinds. Widening to support fill is a Task-1 reshape
2400
+ and out of scope.
2401
+ - Bezier rendered as 32-segment polyline approximation because
2402
+ `RenderCtx` exposes `arc(...)` but not `quadraticCurveTo` /
2403
+ `bezierCurveTo`. Mirrors Task 7's `ellipse` 64-segment approach;
2404
+ widening would touch Phase-1 surface.
2405
+ - Per-kind §22.10 5-file test set deferred to pragmatic 1-file set
2406
+ (mirrors Tasks 5–7) — Task 3's `pushDrawing.*` and `handle.*`
2407
+ suite covers the underlying infra exhaustively.
2408
+ - `gen-docs` doc-page generation deferred to Task 21 (mirrors Tasks
2409
+ 5–7).
2410
+
2411
+ - b0d296b: Phase-3 Task 9 — fifth per-port task. Lands the 5 annotation drawing
2412
+ kinds (`text`, `arrow`, `arrowMarker`, `arrowMarkUp`, `arrowMarkDown`)
2413
+ per PLAN.md §10 and §22.10. Behaviour ports from invinite commit
2414
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`: `tools/text-tool.ts`,
2415
+ `tools/arrow-tool.ts`, `tools/arrow-marker-tool.ts`,
2416
+ `tools/arrow-mark-up-tool.ts`, `tools/arrow-mark-down-tool.ts`, and the
2417
+ matching `y-doc-bridge.ts` variants (`TextDrawing`, `ArrowDrawing`,
2418
+ `ArrowMarkerDrawing`, `ArrowMarkUpDrawing`, `ArrowMarkDownDrawing`).
2419
+ All 5 kinds map to the `labels` bucket.
2420
+
2421
+ `@invinite-org/chartlang-adapter-kit` adds per-kind state validators
2422
+ for the 5 annotation kinds — `validateTextState`, `validateArrowState`,
2423
+ `validateArrowMarkerState`, `validateArrowMarkUpState`,
2424
+ `validateArrowMarkDownState` — wired into the existing
2425
+ `validateStateByKind` dispatch. Two new file-local style helpers land
2426
+ alongside: `validateArrowOpts` (`LineDrawStyle` + optional string
2427
+ `label`) and `validateArrowMarkerOpts` (optional `color` + optional
2428
+ `text`). `text.body` is validated through `walkMeta` (catches
2429
+ non-JsonValue payloads like bigint / function / symbol) and then
2430
+ pinned as a non-empty string with `TEXT_BODY_MAX_LENGTH = 256` (longer
2431
+ than the 128 cap on plot labels — annotation strings carry short
2432
+ rationales like "Inverse Head and Shoulders Confirmed"). Wire shape
2433
+ is stricter than before — payloads previously passing the permissive
2434
+ default arm now reject with `malformed-emission`.
2435
+
2436
+ `@invinite-org/chartlang-runtime` ships 5 new `draw.<kind>(...)` emit
2437
+ functions under `src/emit/draw/annotations/` and extends the
2438
+ `DRAW_NAMESPACE` swap-seam at `src/emit/draw/namespace.ts`. Each impl
2439
+ uses the dual-overload pattern Tasks 5–8 pinned. `draw.text` is the
2440
+ first emit fn with three script-facing arguments (`anchor`, `body`,
2441
+ `opts?`); the compiler-injected form is `(slotId, anchor, body,
2442
+ opts?)` and the impl signature carries four arguments.
2443
+
2444
+ `chartlang-example-canvas2d-adapter` ships 5 new renderers under
2445
+ `src/render/draw/` plus three new shared helpers: `arrowhead.ts`
2446
+ (`drawArrowhead(ctx, from, to, size?)` — filled triangular arrowhead
2447
+ at `to` pointing along the shaft direction; used by `arrow` +
2448
+ `arrowMarker`), `chevron.ts` (`drawChevron(ctx, at, direction, color,
2449
+ baseWidth?, height?)` — filled up/down triangle glyph; used by
2450
+ `arrowMarkUp` + `arrowMarkDown`), and `textStyle.ts` (`SIZE_TO_PX` /
2451
+ `HALIGN_TO_TEXTALIGN` / `VALIGN_TO_TEXTBASELINE` maps +
2452
+ `resolveTextOpts(opts)` helper that turns a `TextOpts` bag into the
2453
+ four canvas text-state values). The Task-7 `marker.ts` renderer is
2454
+ refactored to consume `textStyle.ts` for the same maps — its call
2455
+ sequence is preserved exactly so `marker.test.ts` continues to pass
2456
+ unchanged. Default colours follow invinite's paint-time defaults:
2457
+ `#3b82f6` (toolbar blue) for `arrowMarker`, `#22c55e` (green) for
2458
+ `arrowMarkUp`, `#ef4444` (red) for `arrowMarkDown`. The `drawingDispatch`
2459
+ switch flips the 5 arms from no-op stubs to real `renderXxx(ctx, e,
2460
+ view)` calls; exhaustiveness is preserved.
2461
+
2462
+ `@invinite-org/chartlang-conformance` ships 5 new per-kind scenarios
2463
+ under `src/scenarios/` (`drawText`, `drawArrow`, `drawArrowMarker`,
2464
+ `drawArrowMarkUp`, `drawArrowMarkDown`) plus one bundle scenario
2465
+ `drawAnnotationsAll` that emits one drawing per annotation kind on
2466
+ the first bar (per README §22.10 Task 9 collapses the category into
2467
+ ONE bundle). All six scenarios use `inlineSource` against the bundled
2468
+ 10 000-bar `goldenBars.json` fixture with anchor times pulled from
2469
+ `bars[0]` / `bars[500]` / `bars[1000]`. The `TEST_CAPABILITIES` bags
2470
+ in `runConformanceSuite.test.ts` + `scenarios/scenarios.test.ts`
2471
+ extend the `drawings` set with `allAnnotationDrawings()`; the existing
2472
+ `labels: 100` bucket budget (added when Task 7's `marker` scenario
2473
+ landed) covers the bundle scenarios with headroom. `ALL_SCENARIOS`
2474
+ extends additively.
2475
+
2476
+ No core edits — the `DrawingState` variants and `DrawNamespace`
2477
+ signatures Task 1 shipped are the canonical shape and Task 9 wires
2478
+ real impls to them.
2479
+
2480
+ Deviations from spec, flagged for review:
2481
+
2482
+ - `text.bgColor` background-rectangle paint NOT rendered. The
2483
+ structural `RenderCtx` exposes neither `measureText` nor a
2484
+ background-rect path; widening would touch the Phase-1 structural
2485
+ type. The `bgColor` field is preserved on the wire (validator
2486
+ accepts string) but the canvas2d renderer does not paint a
2487
+ background rect. Mirror Task 7's `marker` precedent.
2488
+ - `ArrowOpts.label` rotation NOT rendered. `RenderCtx` has no
2489
+ `rotate / translate / save / restore`. Label paints un-rotated at
2490
+ the shaft midpoint with `textAlign = "center"` /
2491
+ `textBaseline = "bottom"`. Pure on the Phase-1 surface.
2492
+ - `ArrowMarkerState` ↔ spec shape delta. Task 1's core landed
2493
+ `ArrowMarkerState` with single `anchor: WorldPoint`; the spec
2494
+ README §13 says `2 (from, to)`. Per Tasks 6/7's "don't reshape
2495
+ Task-1 mid-phase" precedent, Task 9 uses the single-anchor form
2496
+ and the renderer paints a self-contained glyph (dot + stub line +
2497
+ arrowhead + optional text) at the anchor — a "annotation lives
2498
+ here" marker that fits in ~24px. Reshape can ship in a follow-up.
2499
+ - `marker.ts` refactor crosses Task 7 boundary by ~5 lines to
2500
+ consume the new shared `textStyle.ts` helper. The call sequence is
2501
+ preserved exactly; `marker.test.ts` continues to pass without
2502
+ modifications.
2503
+ - Per-kind §22.10 5-file test set deferred to pragmatic 1-file set
2504
+ (mirrors Tasks 5–8) — Task 3's `pushDrawing.*` and `handle.*`
2505
+ suite covers the underlying infra exhaustively.
2506
+ - `gen-docs` doc-page generation deferred to Task 21 (mirrors Tasks
2507
+ 5–8).
2508
+
2509
+ - Phase 4 - Editor + Inputs + Timeframes + Tier-1 Pine parity.
2510
+ Adds: input._ builders, state._ / state.tick.\* slots,
2511
+ barstate / syminfo / timeframe views, request.security typed
2512
+ surface (NaN fallback), defineIndicator overrides,
2513
+ Capabilities triad (intervals / multiTimeframe / subPanes /
2514
+ symInfoFields / maxDrawingsPerScript / alertConditions / logs),
2515
+ language-service hover registry + LSP-style API, CodeMirror 6
2516
+ editor shell + /react sub-export, Inputs UI ViewModel + React
2517
+ form. See tasks/phase-4-editor-tier1/README.md.
2518
+ - Add runtime `state.*` and `state.tick.*` slot storage with committed/tentative lifecycle semantics and StateStore snapshot restore.
2519
+ - Wire runtime `barstate`, `syminfo`, and `timeframe` views, and add optional adapter symbol metadata for `syminfo` population.
2520
+ - Wire runtime `request.security` with Phase-4 NaN fallback bars, capability diagnostics, and per-slot caches.
2521
+ - Resolve runtime `input.*` overrides at mount, add adapter input resolver wiring, and audit universal `ta.*` offset support.
2522
+
2523
+ ### Patch Changes
2524
+
2525
+ - 3f3ce38: Phase-1 walking-skeleton: ship the canvas2d reference adapter
2526
+ (`examples/canvas2d-adapter`). The private example package now
2527
+ exports `createCanvas2dAdapter`, `runRendererLoop`,
2528
+ `CANVAS2D_CAPABILITIES`, `DEFAULT_PALETTE`, plus a
2529
+ `./testing` sub-path entry carrying `MockCanvas2DContext` +
2530
+ `hashCallLog` for sibling-package conformance tests (Task 12).
2531
+
2532
+ Two cross-package adjustments rode along:
2533
+
2534
+ - `@invinite-org/chartlang-host-worker` adds `createWorkerBoot`
2535
+ and `WorkerBootScope` to its public barrel so consumer-repo
2536
+ tests (and Task 10's integration test) can pair the worker host
2537
+ against a `MessageChannel`-backed scope. The boot factory was
2538
+ always testable from within the package; this exposes it as a
2539
+ stable surface.
2540
+ - `@invinite-org/chartlang-runtime`'s `makeSeriesView` Proxy now
2541
+ defines a `has` trap so `"current" in series` (and
2542
+ `"length" in series`, `"<n>" in series`) returns `true`. This
2543
+ unblocks `runtime/src/emit/plot.ts`'s `isSeriesNumber` check —
2544
+ previously the Proxy reported `false` for `in`, so calls like
2545
+ `plot(ta.ema(...))` with the real runtime Series threw the
2546
+ "outside an active script step" sentinel. Discovered via Task
2547
+ 10's end-to-end integration test driving an EMA-cross bundle
2548
+ through the worker host into the canvas2d renderer.
2549
+
2550
+ - 38fb475: Hoist shared `ta.*` primitive helpers to `lib/`: relocate
2551
+ `DirectionalState` + the 3 directional-state helpers from `dmi.ts`
2552
+ to `lib/directionalState.ts` so `ta.adx` no longer cross-imports
2553
+ into a sibling primitive's `src/` file. Relocate
2554
+ `ScalarOrSeries` + `readSourceValue` from top-level `sourceValue.ts`
2555
+ to `lib/sourceValue.ts` to consolidate the shared helper surface.
2556
+ Widen `packages/runtime/src/ta/lib/CLAUDE.md` to document the
2557
+ shared-primitive-helper carve-out alongside the Float64-only compute
2558
+ cores.
2559
+
2560
+ Reconcile `ALL_SCENARIOS` cardinality with `scripts/run-conformance.ts`
2561
+ by renaming the export to `ALL_SCENARIOS` with a `@deprecated since 0.2.1`
2562
+ alias retained for one release. Add iteration-parity test so script
2563
+ and canonical export can never drift again.
2564
+
2565
+ Investigation note: found 78 scenarios in script (stale local
2566
+ `dist/` build), 85 in array, gap is the script's `dist/`-first import
2567
+ preference loading a stale snapshot — the runner iterates all 85
2568
+ entries with no silent skip (`report.passed + report.failed ===
2569
+ ALL_SCENARIOS.length`). CI is unaffected because `pnpm build` runs
2570
+ before `pnpm conformance`. Resolution: option (a) — rename to
2571
+ `ALL_SCENARIOS`, keep `ALL_SCENARIOS` as deprecated alias.
2572
+
2573
+ - 38fb475: Phase-2 Task 3 — chained-MA helper family.
2574
+
2575
+ Ports the WMA / SMMA / VWMA cores from invinite (commit
2576
+ `078f41fe2569d659d5aba726da8bcb5d3e2ced02`) into
2577
+ `packages/runtime/src/ta/lib/` and adds the MA-kind dispatcher pair
2578
+ (`computeMaOfFloat64` excludes `vwma` at the type level via
2579
+ `MaTypeNoVolume`; `computeMa` routes `vwma` through the volume-aware
2580
+ `vwmaFloat64` helper and throws a structured `TypeError`
2581
+ (`code = "ta-lib-vwma-requires-volume"`) when called with a null
2582
+ volume array). The `maTypes.ts` module exports the canonical
2583
+ `MaType` union + the `MaTypeNoVolume` excluder.
2584
+
2585
+ NaN propagation matches invinite per-helper: the recurrence-based
2586
+ `smmaFloat64` holds the prior value forward on a mid-stream NaN
2587
+ (matches `emaFloat64`); the full-recompute window helpers
2588
+ `wmaFloat64` and `vwmaFloat64` short-circuit a window to NaN if any
2589
+ slot in it is NaN. VWMA also emits NaN when the trailing-window
2590
+ volume sum is zero.
2591
+
2592
+ These helpers back ~22 of the §9.2 ports landing in Tasks 6–28:
2593
+ every MA primitive (Tasks 6–8), every BB / Keltner / Envelope / Chop
2594
+ / Donchian middle override (Tasks 18–19), every MACD / PPO / PVO
2595
+ signal line (Tasks 10, 23). No public surface change yet — runtime-
2596
+ internal helpers only; the public delta lands per-port in subsequent
2597
+ tasks. Each new compute core ships the §16.3 four-file test set
2598
+ (`.test.ts`, `.property.test.ts`, `.bench.ts`, `.bench.test.ts`);
2599
+ the two dispatchers ship `.test.ts` only (they delegate the entire
2600
+ hot loop to the cores).
2601
+
2602
+ - 38fb475: Phase 2 quality-pass fixes (cross-cutting).
2603
+
2604
+ - `@invinite-org/chartlang-core`: new `STATEFUL_PRIMITIVES_BY_NAME`
2605
+ export — a `ReadonlyMap<string, StatefulPrimitiveEntry>` derived
2606
+ from the same canonical entry list as `STATEFUL_PRIMITIVES`. Lets
2607
+ the compiler look up entries by callee name in O(1) instead of an
2608
+ O(n) scan over the 93-entry set on every visited call site.
2609
+ - `@invinite-org/chartlang-compiler`: `callsiteIdInjection` and
2610
+ `statefulCallInLoop` now consume `STATEFUL_PRIMITIVES_BY_NAME`
2611
+ via a `statefulByName: ReadonlyMap<string, StatefulPrimitiveEntry>`
2612
+ parameter (was `statefulSet: ReadonlySet<StatefulPrimitiveEntry>`).
2613
+ Internal-only API change — neither pass is publicly exported from
2614
+ `packages/compiler/src/index.ts`. The per-pass `hasName` /
2615
+ `findEntry` helpers are dropped.
2616
+ - `@invinite-org/chartlang-runtime`: `ta/lib/maTypes.ts` re-exports
2617
+ `MaTypeNoVolume` from `@invinite-org/chartlang-core` instead of
2618
+ re-declaring it locally — keeps the two definitions from drifting
2619
+ when a 6th MA kind is added. `MaType` (which adds `"vwma"`) stays
2620
+ local since core has no equivalent. `__fixtures__/syntheticBars.ts`
2621
+ and `nanTick.test.ts`'s inline `Bar` literals now carry the
2622
+ `hl2` / `hlc3` / `ohlc4` / `hlcc4` fields the Phase-2 `Bar`
2623
+ extension made required (the per-package tsconfig had been hiding
2624
+ the typecheck miss).
2625
+
2626
+ Also: `examples/canvas2d-adapter` — extracted the duplicated
2627
+ `dashPattern(LineStyle)` from `render/area.ts` + `render/horizontalLine.ts`
2628
+ into `render/lineDash.ts`, re-exported from `render/index.ts`. No
2629
+ behaviour change.
2630
+
2631
+ - Updated dependencies [3f3ce38]
2632
+ - Updated dependencies [3f3ce38]
2633
+ - Updated dependencies [38fb475]
2634
+ - Updated dependencies [38fb475]
2635
+ - Updated dependencies [38fb475]
2636
+ - Updated dependencies [38fb475]
2637
+ - Updated dependencies [38fb475]
2638
+ - Updated dependencies [38fb475]
2639
+ - Updated dependencies [38fb475]
2640
+ - Updated dependencies [38fb475]
2641
+ - Updated dependencies [38fb475]
2642
+ - Updated dependencies [38fb475]
2643
+ - Updated dependencies [38fb475]
2644
+ - Updated dependencies [38fb475]
2645
+ - Updated dependencies [38fb475]
2646
+ - Updated dependencies [38fb475]
2647
+ - Updated dependencies [38fb475]
2648
+ - Updated dependencies [38fb475]
2649
+ - Updated dependencies [38fb475]
2650
+ - Updated dependencies [38fb475]
2651
+ - Updated dependencies [38fb475]
2652
+ - Updated dependencies [38fb475]
2653
+ - Updated dependencies [38fb475]
2654
+ - Updated dependencies [38fb475]
2655
+ - Updated dependencies [38fb475]
2656
+ - Updated dependencies [38fb475]
2657
+ - Updated dependencies [38fb475]
2658
+ - Updated dependencies [38fb475]
2659
+ - Updated dependencies [38fb475]
2660
+ - Updated dependencies [38fb475]
2661
+ - Updated dependencies [b0d296b]
2662
+ - Updated dependencies [b0d296b]
2663
+ - Updated dependencies [b0d296b]
2664
+ - Updated dependencies [b0d296b]
2665
+ - Updated dependencies [b0d296b]
2666
+ - Updated dependencies [b0d296b]
2667
+ - Updated dependencies [b0d296b]
2668
+ - Updated dependencies [b0d296b]
2669
+ - Updated dependencies [b0d296b]
2670
+ - Updated dependencies [b0d296b]
2671
+ - Updated dependencies [b0d296b]
2672
+ - Updated dependencies [b0d296b]
2673
+ - Updated dependencies [b0d296b]
2674
+ - Updated dependencies [b0d296b]
2675
+ - Updated dependencies [b0d296b]
2676
+ - Updated dependencies [b0d296b]
2677
+ - Updated dependencies [b0d296b]
2678
+ - Updated dependencies [b0d296b]
2679
+ - Updated dependencies
2680
+ - Updated dependencies
2681
+ - Updated dependencies
2682
+ - Updated dependencies
2683
+ - Updated dependencies
2684
+ - Updated dependencies
2685
+ - Updated dependencies
2686
+ - Updated dependencies
2687
+ - Updated dependencies
2688
+ - Updated dependencies
2689
+ - @invinite-org/chartlang-adapter-kit@0.4.0
2690
+ - @invinite-org/chartlang-core@0.4.0