@nowline/layout 0.8.5 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/dist/axis-columns.d.ts +70 -0
  2. package/dist/axis-columns.d.ts.map +1 -0
  3. package/dist/axis-columns.js +104 -0
  4. package/dist/axis-columns.js.map +1 -0
  5. package/dist/band-scale.d.ts.map +1 -1
  6. package/dist/calendar-resolver.d.ts +27 -0
  7. package/dist/calendar-resolver.d.ts.map +1 -0
  8. package/dist/calendar-resolver.js +132 -0
  9. package/dist/calendar-resolver.js.map +1 -0
  10. package/dist/calendar.d.ts +0 -19
  11. package/dist/calendar.d.ts.map +1 -1
  12. package/dist/calendar.js +4 -44
  13. package/dist/calendar.js.map +1 -1
  14. package/dist/canvas-width.d.ts +23 -0
  15. package/dist/canvas-width.d.ts.map +1 -0
  16. package/dist/canvas-width.js +26 -0
  17. package/dist/canvas-width.js.map +1 -0
  18. package/dist/capacity.d.ts +28 -0
  19. package/dist/capacity.d.ts.map +1 -1
  20. package/dist/capacity.js +64 -29
  21. package/dist/capacity.js.map +1 -1
  22. package/dist/chart-translation.d.ts +22 -0
  23. package/dist/chart-translation.d.ts.map +1 -0
  24. package/dist/chart-translation.js +83 -0
  25. package/dist/chart-translation.js.map +1 -0
  26. package/dist/container-header-geometry.d.ts +64 -0
  27. package/dist/container-header-geometry.d.ts.map +1 -0
  28. package/dist/container-header-geometry.js +89 -0
  29. package/dist/container-header-geometry.js.map +1 -0
  30. package/dist/dsl-utils.d.ts +3 -4
  31. package/dist/dsl-utils.d.ts.map +1 -1
  32. package/dist/dsl-utils.js +8 -25
  33. package/dist/dsl-utils.js.map +1 -1
  34. package/dist/edge-routing.d.ts +69 -78
  35. package/dist/edge-routing.d.ts.map +1 -1
  36. package/dist/edge-routing.js +271 -401
  37. package/dist/edge-routing.js.map +1 -1
  38. package/dist/frame-tab-geometry.d.ts +24 -14
  39. package/dist/frame-tab-geometry.d.ts.map +1 -1
  40. package/dist/frame-tab-geometry.js +69 -23
  41. package/dist/frame-tab-geometry.js.map +1 -1
  42. package/dist/header-card-geometry.d.ts +12 -0
  43. package/dist/header-card-geometry.d.ts.map +1 -1
  44. package/dist/header-card-geometry.js +14 -2
  45. package/dist/header-card-geometry.js.map +1 -1
  46. package/dist/header-logo.d.ts +28 -0
  47. package/dist/header-logo.d.ts.map +1 -0
  48. package/dist/header-logo.js +51 -0
  49. package/dist/header-logo.js.map +1 -0
  50. package/dist/i18n.d.ts +11 -0
  51. package/dist/i18n.d.ts.map +1 -1
  52. package/dist/i18n.js +11 -1
  53. package/dist/i18n.js.map +1 -1
  54. package/dist/index.d.ts +20 -8
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +17 -7
  57. package/dist/index.js.map +1 -1
  58. package/dist/inline-date-pin-geometry.d.ts +19 -11
  59. package/dist/inline-date-pin-geometry.d.ts.map +1 -1
  60. package/dist/inline-date-pin-geometry.js +45 -46
  61. package/dist/inline-date-pin-geometry.js.map +1 -1
  62. package/dist/item-bar-geometry.d.ts +192 -4
  63. package/dist/item-bar-geometry.d.ts.map +1 -1
  64. package/dist/item-bar-geometry.js +258 -5
  65. package/dist/item-bar-geometry.js.map +1 -1
  66. package/dist/item-port-geometry.d.ts +13 -0
  67. package/dist/item-port-geometry.d.ts.map +1 -0
  68. package/dist/item-port-geometry.js +63 -0
  69. package/dist/item-port-geometry.js.map +1 -0
  70. package/dist/layout-context.d.ts +115 -51
  71. package/dist/layout-context.d.ts.map +1 -1
  72. package/dist/layout-context.js +96 -5
  73. package/dist/layout-context.js.map +1 -1
  74. package/dist/layout-insights.d.ts.map +1 -1
  75. package/dist/layout-insights.js +73 -1
  76. package/dist/layout-insights.js.map +1 -1
  77. package/dist/layout.d.ts +35 -0
  78. package/dist/layout.d.ts.map +1 -1
  79. package/dist/layout.js +18 -1315
  80. package/dist/layout.js.map +1 -1
  81. package/dist/nodes/anchor-node.d.ts.map +1 -1
  82. package/dist/nodes/anchor-node.js +11 -4
  83. package/dist/nodes/anchor-node.js.map +1 -1
  84. package/dist/nodes/content-extent.d.ts +24 -0
  85. package/dist/nodes/content-extent.d.ts.map +1 -0
  86. package/dist/nodes/content-extent.js +100 -0
  87. package/dist/nodes/content-extent.js.map +1 -0
  88. package/dist/nodes/dependency-edges.d.ts +6 -0
  89. package/dist/nodes/dependency-edges.d.ts.map +1 -0
  90. package/dist/nodes/dependency-edges.js +148 -0
  91. package/dist/nodes/dependency-edges.js.map +1 -0
  92. package/dist/nodes/footnote-node.d.ts +24 -3
  93. package/dist/nodes/footnote-node.d.ts.map +1 -1
  94. package/dist/nodes/footnote-node.js +129 -25
  95. package/dist/nodes/footnote-node.js.map +1 -1
  96. package/dist/nodes/group-node.d.ts +10 -21
  97. package/dist/nodes/group-node.d.ts.map +1 -1
  98. package/dist/nodes/group-node.js +79 -154
  99. package/dist/nodes/group-node.js.map +1 -1
  100. package/dist/nodes/header-node.d.ts +56 -0
  101. package/dist/nodes/header-node.d.ts.map +1 -0
  102. package/dist/nodes/header-node.js +163 -0
  103. package/dist/nodes/header-node.js.map +1 -0
  104. package/dist/nodes/include-node.d.ts +22 -12
  105. package/dist/nodes/include-node.d.ts.map +1 -1
  106. package/dist/nodes/include-node.js +95 -62
  107. package/dist/nodes/include-node.js.map +1 -1
  108. package/dist/nodes/item-measure.d.ts +135 -0
  109. package/dist/nodes/item-measure.d.ts.map +1 -0
  110. package/dist/nodes/item-measure.js +514 -0
  111. package/dist/nodes/item-measure.js.map +1 -0
  112. package/dist/nodes/item-node.d.ts +162 -9
  113. package/dist/nodes/item-node.d.ts.map +1 -1
  114. package/dist/nodes/item-node.js +256 -69
  115. package/dist/nodes/item-node.js.map +1 -1
  116. package/dist/nodes/marker-band.d.ts +118 -0
  117. package/dist/nodes/marker-band.d.ts.map +1 -0
  118. package/dist/nodes/marker-band.js +303 -0
  119. package/dist/nodes/marker-band.js.map +1 -0
  120. package/dist/nodes/marker-geometry.js +1 -1
  121. package/dist/nodes/marker-geometry.js.map +1 -1
  122. package/dist/nodes/milestone-node.d.ts +112 -15
  123. package/dist/nodes/milestone-node.d.ts.map +1 -1
  124. package/dist/nodes/milestone-node.js +246 -95
  125. package/dist/nodes/milestone-node.js.map +1 -1
  126. package/dist/nodes/nowline-node.d.ts +8 -0
  127. package/dist/nodes/nowline-node.d.ts.map +1 -0
  128. package/dist/nodes/nowline-node.js +74 -0
  129. package/dist/nodes/nowline-node.js.map +1 -0
  130. package/dist/nodes/parallel-node.d.ts +7 -12
  131. package/dist/nodes/parallel-node.d.ts.map +1 -1
  132. package/dist/nodes/parallel-node.js +66 -32
  133. package/dist/nodes/parallel-node.js.map +1 -1
  134. package/dist/nodes/region-markers.d.ts +41 -0
  135. package/dist/nodes/region-markers.d.ts.map +1 -0
  136. package/dist/nodes/region-markers.js +130 -0
  137. package/dist/nodes/region-markers.js.map +1 -0
  138. package/dist/nodes/roadmap-node.d.ts +9 -72
  139. package/dist/nodes/roadmap-node.d.ts.map +1 -1
  140. package/dist/nodes/roadmap-node.js +38 -788
  141. package/dist/nodes/roadmap-node.js.map +1 -1
  142. package/dist/nodes/row-track.d.ts +33 -0
  143. package/dist/nodes/row-track.d.ts.map +1 -0
  144. package/dist/nodes/row-track.js +170 -0
  145. package/dist/nodes/row-track.js.map +1 -0
  146. package/dist/nodes/sequence-item.d.ts +25 -0
  147. package/dist/nodes/sequence-item.d.ts.map +1 -0
  148. package/dist/nodes/sequence-item.js +396 -0
  149. package/dist/nodes/sequence-item.js.map +1 -0
  150. package/dist/nodes/sequence-one.d.ts +5 -0
  151. package/dist/nodes/sequence-one.d.ts.map +1 -0
  152. package/dist/nodes/sequence-one.js +26 -0
  153. package/dist/nodes/sequence-one.js.map +1 -0
  154. package/dist/nodes/swimlane-node.d.ts +5 -17
  155. package/dist/nodes/swimlane-node.d.ts.map +1 -1
  156. package/dist/nodes/swimlane-node.js +62 -147
  157. package/dist/nodes/swimlane-node.js.map +1 -1
  158. package/dist/nodes/wave-node.d.ts +52 -0
  159. package/dist/nodes/wave-node.d.ts.map +1 -0
  160. package/dist/nodes/wave-node.js +483 -0
  161. package/dist/nodes/wave-node.js.map +1 -0
  162. package/dist/non-working-display.d.ts +14 -0
  163. package/dist/non-working-display.d.ts.map +1 -0
  164. package/dist/non-working-display.js +28 -0
  165. package/dist/non-working-display.js.map +1 -0
  166. package/dist/phases/date-window.d.ts +48 -0
  167. package/dist/phases/date-window.d.ts.map +1 -0
  168. package/dist/phases/date-window.js +130 -0
  169. package/dist/phases/date-window.js.map +1 -0
  170. package/dist/phases/finalize.d.ts +198 -0
  171. package/dist/phases/finalize.d.ts.map +1 -0
  172. package/dist/phases/finalize.js +1058 -0
  173. package/dist/phases/finalize.js.map +1 -0
  174. package/dist/phases/measure.d.ts +77 -0
  175. package/dist/phases/measure.d.ts.map +1 -0
  176. package/dist/phases/measure.js +222 -0
  177. package/dist/phases/measure.js.map +1 -0
  178. package/dist/phases/place.d.ts +28 -0
  179. package/dist/phases/place.d.ts.map +1 -0
  180. package/dist/phases/place.js +225 -0
  181. package/dist/phases/place.js.map +1 -0
  182. package/dist/renderable.d.ts.map +1 -1
  183. package/dist/renderable.js +23 -3
  184. package/dist/renderable.js.map +1 -1
  185. package/dist/resolve-today.d.ts +11 -1
  186. package/dist/resolve-today.d.ts.map +1 -1
  187. package/dist/resolve-today.js +26 -12
  188. package/dist/resolve-today.js.map +1 -1
  189. package/dist/row-packer.d.ts +42 -16
  190. package/dist/row-packer.d.ts.map +1 -1
  191. package/dist/row-packer.js +51 -78
  192. package/dist/row-packer.js.map +1 -1
  193. package/dist/schedule.d.ts +58 -1
  194. package/dist/schedule.d.ts.map +1 -1
  195. package/dist/schedule.js +280 -106
  196. package/dist/schedule.js.map +1 -1
  197. package/dist/start-rules.d.ts +27 -0
  198. package/dist/start-rules.d.ts.map +1 -0
  199. package/dist/start-rules.js +91 -0
  200. package/dist/start-rules.js.map +1 -0
  201. package/dist/start-terms.d.ts +23 -0
  202. package/dist/start-terms.d.ts.map +1 -0
  203. package/dist/start-terms.js +27 -0
  204. package/dist/start-terms.js.map +1 -0
  205. package/dist/status-dot.d.ts +46 -0
  206. package/dist/status-dot.d.ts.map +1 -0
  207. package/dist/status-dot.js +78 -0
  208. package/dist/status-dot.js.map +1 -0
  209. package/dist/style-resolution.d.ts.map +1 -1
  210. package/dist/style-resolution.js +23 -43
  211. package/dist/style-resolution.js.map +1 -1
  212. package/dist/text-measure.d.ts +28 -0
  213. package/dist/text-measure.d.ts.map +1 -0
  214. package/dist/text-measure.js +70 -0
  215. package/dist/text-measure.js.map +1 -0
  216. package/dist/themes/contrast.d.ts +4 -0
  217. package/dist/themes/contrast.d.ts.map +1 -0
  218. package/dist/themes/contrast.js +32 -0
  219. package/dist/themes/contrast.js.map +1 -0
  220. package/dist/themes/dark.d.ts.map +1 -1
  221. package/dist/themes/dark.js +28 -1
  222. package/dist/themes/dark.js.map +1 -1
  223. package/dist/themes/grayscale.d.ts.map +1 -1
  224. package/dist/themes/grayscale.js +28 -1
  225. package/dist/themes/grayscale.js.map +1 -1
  226. package/dist/themes/index.d.ts +4 -11
  227. package/dist/themes/index.d.ts.map +1 -1
  228. package/dist/themes/index.js +6 -4
  229. package/dist/themes/index.js.map +1 -1
  230. package/dist/themes/light.d.ts.map +1 -1
  231. package/dist/themes/light.js +28 -1
  232. package/dist/themes/light.js.map +1 -1
  233. package/dist/themes/shape.d.ts +31 -0
  234. package/dist/themes/shape.d.ts.map +1 -1
  235. package/dist/themes/shared.d.ts +44 -50
  236. package/dist/themes/shared.d.ts.map +1 -1
  237. package/dist/themes/shared.js +79 -83
  238. package/dist/themes/shared.js.map +1 -1
  239. package/dist/time-scale.d.ts +42 -6
  240. package/dist/time-scale.d.ts.map +1 -1
  241. package/dist/time-scale.js +109 -17
  242. package/dist/time-scale.js.map +1 -1
  243. package/dist/types.d.ts +528 -11
  244. package/dist/types.d.ts.map +1 -1
  245. package/dist/view-preset.d.ts +61 -6
  246. package/dist/view-preset.d.ts.map +1 -1
  247. package/dist/view-preset.js +439 -24
  248. package/dist/view-preset.js.map +1 -1
  249. package/dist/wave-barrier.d.ts +107 -0
  250. package/dist/wave-barrier.d.ts.map +1 -0
  251. package/dist/wave-barrier.js +174 -0
  252. package/dist/wave-barrier.js.map +1 -0
  253. package/dist/wave-hatch.d.ts +4 -0
  254. package/dist/wave-hatch.d.ts.map +1 -0
  255. package/dist/wave-hatch.js +21 -0
  256. package/dist/wave-hatch.js.map +1 -0
  257. package/dist/wave-layout.d.ts +99 -0
  258. package/dist/wave-layout.d.ts.map +1 -0
  259. package/dist/wave-layout.js +130 -0
  260. package/dist/wave-layout.js.map +1 -0
  261. package/dist/working-calendar.d.ts +128 -4
  262. package/dist/working-calendar.d.ts.map +1 -1
  263. package/dist/working-calendar.js +725 -51
  264. package/dist/working-calendar.js.map +1 -1
  265. package/dist/working-span.d.ts +11 -0
  266. package/dist/working-span.d.ts.map +1 -0
  267. package/dist/working-span.js +18 -0
  268. package/dist/working-span.js.map +1 -0
  269. package/package.json +7 -7
  270. package/src/axis-columns.ts +140 -0
  271. package/src/calendar-resolver.ts +161 -0
  272. package/src/calendar.ts +4 -45
  273. package/src/canvas-width.ts +36 -0
  274. package/src/capacity.ts +71 -30
  275. package/src/chart-translation.ts +88 -0
  276. package/src/container-header-geometry.ts +116 -0
  277. package/src/dsl-utils.ts +8 -26
  278. package/src/edge-routing.ts +347 -491
  279. package/src/frame-tab-geometry.ts +78 -25
  280. package/src/header-card-geometry.ts +17 -2
  281. package/src/header-logo.ts +67 -0
  282. package/src/i18n.ts +22 -1
  283. package/src/index.ts +97 -12
  284. package/src/inline-date-pin-geometry.ts +55 -58
  285. package/src/item-bar-geometry.ts +341 -5
  286. package/src/item-port-geometry.ts +69 -0
  287. package/src/layout-context.ts +210 -72
  288. package/src/layout-insights.ts +109 -2
  289. package/src/layout.ts +57 -1530
  290. package/src/nodes/anchor-node.ts +11 -4
  291. package/src/nodes/content-extent.ts +107 -0
  292. package/src/nodes/dependency-edges.ts +171 -0
  293. package/src/nodes/footnote-node.ts +171 -31
  294. package/src/nodes/group-node.ts +92 -215
  295. package/src/nodes/header-node.ts +255 -0
  296. package/src/nodes/include-node.ts +124 -110
  297. package/src/nodes/item-measure.ts +723 -0
  298. package/src/nodes/item-node.ts +358 -80
  299. package/src/nodes/marker-band.ts +406 -0
  300. package/src/nodes/marker-geometry.ts +1 -1
  301. package/src/nodes/milestone-node.ts +321 -136
  302. package/src/nodes/nowline-node.ts +87 -0
  303. package/src/nodes/parallel-node.ts +69 -39
  304. package/src/nodes/region-markers.ts +194 -0
  305. package/src/nodes/roadmap-node.ts +46 -950
  306. package/src/nodes/row-track.ts +217 -0
  307. package/src/nodes/sequence-item.ts +433 -0
  308. package/src/nodes/sequence-one.ts +40 -0
  309. package/src/nodes/swimlane-node.ts +66 -206
  310. package/src/nodes/wave-node.ts +609 -0
  311. package/src/non-working-display.ts +32 -0
  312. package/src/phases/date-window.ts +191 -0
  313. package/src/phases/finalize.ts +1303 -0
  314. package/src/phases/measure.ts +329 -0
  315. package/src/phases/place.ts +318 -0
  316. package/src/renderable.ts +23 -3
  317. package/src/resolve-today.ts +28 -25
  318. package/src/row-packer.ts +85 -84
  319. package/src/schedule.ts +362 -114
  320. package/src/start-rules.ts +113 -0
  321. package/src/start-terms.ts +38 -0
  322. package/src/status-dot.ts +81 -0
  323. package/src/style-resolution.ts +27 -57
  324. package/src/text-measure.ts +71 -0
  325. package/src/themes/contrast.ts +34 -0
  326. package/src/themes/dark.ts +28 -1
  327. package/src/themes/grayscale.ts +28 -1
  328. package/src/themes/index.ts +10 -7
  329. package/src/themes/light.ts +28 -1
  330. package/src/themes/shape.ts +38 -0
  331. package/src/themes/shared.ts +85 -93
  332. package/src/time-scale.ts +117 -19
  333. package/src/types.ts +529 -20
  334. package/src/view-preset.ts +520 -27
  335. package/src/wave-barrier.ts +242 -0
  336. package/src/wave-hatch.ts +25 -0
  337. package/src/wave-layout.ts +203 -0
  338. package/src/working-calendar.ts +875 -57
  339. package/src/working-span.ts +19 -0
@@ -0,0 +1,118 @@
1
+ import type { AnchorDeclaration, MilestoneDeclaration } from '@nowline/core';
2
+ import type { TimeScale } from '../time-scale.js';
3
+ import type { BoundingBox, MarkerRowPlacement, PositionedNonWorkingRun, PositionedWorkingException } from '../types.js';
4
+ import type { MilestonePlacement } from './milestone-node.js';
5
+ /** A packed marker band: its rows and each marker's placement at the band's y. */
6
+ export interface MarkerBand {
7
+ /** Rows the band holds: at least 1 when it has any marker, else 0. */
8
+ rowCount: number;
9
+ placements: Map<string, MarkerRowPlacement>;
10
+ }
11
+ /** A marker pinned by its `date:`: a dated anchor or milestone inside the window. */
12
+ export type DatePinnedMarker = MarkerEntity & {
13
+ date: Date;
14
+ isMilestone: boolean;
15
+ };
16
+ /**
17
+ * The date-pinned anchors, then the date-pinned milestones, each at the x
18
+ * of its `date:`. A marker with no date, or a date outside the window,
19
+ * is left out; after-only milestones are placed with the lanes.
20
+ */
21
+ export declare function datePinnedMarkerEntries(anchors: ReadonlyMap<string, AnchorDeclaration>, milestones: ReadonlyMap<string, MilestoneDeclaration>, scale: TimeScale): DatePinnedMarker[];
22
+ /**
23
+ * The calendar's marker-row entries: the titled non-working runs, then the
24
+ * working exceptions. Callers append them after the anchors and
25
+ * milestones.
26
+ */
27
+ export declare function calendarMarkerEntries(runs: ReadonlyArray<PositionedNonWorkingRun> | undefined, exceptions: ReadonlyArray<PositionedWorkingException> | undefined): MarkerEntity[];
28
+ /**
29
+ * Each packed placement at the band's y: row `r`'s centre sits
30
+ * `MARKER_ROW_CENTER_OFFSET_PX + r * MARKER_ROW_PITCH_PX` below
31
+ * `markerRowY`, and its label box 4 px above the centre.
32
+ */
33
+ export declare function markerRowPlacements(packed: ReadonlyMap<string, PackedPlacement>, markerRowY: number): Map<string, MarkerRowPlacement>;
34
+ /** The marker-row id of a titled non-working run: `nonworking:<ISO from>`. */
35
+ export declare function nonWorkingRunMarkerId(run: PositionedNonWorkingRun): string;
36
+ /** The marker-row id of a working exception: `working:<ISO from>`. */
37
+ export declare function workingExceptionMarkerId(exception: PositionedWorkingException): string;
38
+ /**
39
+ * The canvas right edge the marker-row labels need. A label (anchor,
40
+ * milestone, titled run or working exception) that fits neither right of
41
+ * its x (against `chartRightX`) nor left of it (against `chartLeftX`)
42
+ * would fall back to the left and draw over a beside header card, so the
43
+ * canvas grows to hold it on the right instead. A slipped milestone's
44
+ * label never fits on the left, where its span runs.
45
+ */
46
+ export declare function markerLabelsRightX(entries: ReadonlyArray<MarkerEntity>, chartLeftX: number, chartRightX: number, estimateTextWidth: (text: string, fontSize: number) => number): number;
47
+ export interface MarkerEntity {
48
+ id: string;
49
+ centerX: number;
50
+ radius: number;
51
+ title: string;
52
+ fontSize: number;
53
+ bold: boolean;
54
+ /**
55
+ * A slipped milestone's planned x: its entry sits at the slipped x
56
+ * (`centerX`, where the label goes), and the span from the planned
57
+ * diamond to it is reserved on its row.
58
+ */
59
+ slipFromX?: number;
60
+ }
61
+ export interface PackedPlacement {
62
+ rowIndex: number;
63
+ labelBox: BoundingBox;
64
+ labelSide: 'left' | 'right';
65
+ }
66
+ /**
67
+ * A slack or overrun arrow between two markers, drawn on `from`'s row
68
+ * between the two diamonds (specs/rendering.md, Milestones, "Marker
69
+ * predecessors"). A milestone's arrow from a group or parallel starts on
70
+ * the milestone's own row and is not one.
71
+ */
72
+ export interface MarkerArrow {
73
+ from: string;
74
+ to: string;
75
+ }
76
+ /** The arrows between markers that `placements` draw, source to target. */
77
+ export declare function markerArrows(placements: readonly MilestonePlacement[]): MarkerArrow[];
78
+ /**
79
+ * Pack anchors + milestones into marker rows using a bottom-first
80
+ * tick-order strategy. Markers default to the row CLOSEST to the
81
+ * chart; conflicts push them UP toward the date ticks (the inverse of
82
+ * swimlane items which default to the top and push down).
83
+ *
84
+ * Walk order is left-to-right by `centerX` (tick order, not file
85
+ * declaration). For each marker:
86
+ * 1. Try the bottommost existing row (highest `rowIndex`), right
87
+ * side first then left, working UP through the rows.
88
+ * 2. If neither side fits at any existing row, GROW: prepend a new
89
+ * row at `rowIndex = 0`. Every previously-placed marker has its
90
+ * `rowIndex` incremented by 1 so the bottom corridor stays
91
+ * stable as the band expands upward toward the ticks.
92
+ *
93
+ * `arrows` (the marker-to-marker arrows, `markerArrows`) add three rules,
94
+ * so an arrow crosses no other marker and ends on its target's line:
95
+ * - An arrow's run, on its source's row between the two diamonds, is
96
+ * reserved on that row like a label: no other diamond, label or run
97
+ * may overlap it.
98
+ * - A target sits at or above each source's row (cut lines run down
99
+ * from a diamond). A source whose target is placed and that fits no
100
+ * allowed row grows a fresh row right below the target instead of
101
+ * at the top; when the rules contradict (a marker both a source and
102
+ * a target on one row), it grows at the top.
103
+ * - A label takes a side its own arrows do not run along, when that
104
+ * side fits; otherwise it keeps the usual right-then-left order.
105
+ * With no arrows the pack is unchanged.
106
+ *
107
+ * Returns row-relative placements (no centerY yet — caller fills that
108
+ * in once `markerRowY` is known). Row indices follow the existing
109
+ * convention: 0 = top of band (closest to ticks), `rowCount - 1` =
110
+ * bottom of band (closest to chart). The "bottom-first" preference
111
+ * lives entirely in the search order and grow direction; geometry
112
+ * stays anchored to `markerRowY` at the top.
113
+ */
114
+ export declare function packMarkerRow(entries: MarkerEntity[], chartLeftX: number, chartRightX: number, estimateTextWidth: (text: string, fontSize: number) => number, arrows?: readonly MarkerArrow[]): {
115
+ placements: Map<string, PackedPlacement>;
116
+ rowCount: number;
117
+ };
118
+ //# sourceMappingURL=marker-band.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker-band.d.ts","sourceRoot":"","sources":["../../src/nodes/marker-band.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,303 @@
1
+ // MarkerBand — the marker row's entries, packer and placements. Anchors,
2
+ // milestones, the titled non-working runs and the working exceptions all
3
+ // pack into one band of rows above the chart. The measure phase packs an
4
+ // estimate to size the band before any lane is placed; finalize packs
5
+ // every marker once the canvas is final (specs/layout-phases.md §3.3).
6
+ // Both build their entries and turn the packed rows into y positions
7
+ // with the helpers here; `markerLabelsRightX` sizes the canvas for the
8
+ // labels that fit on neither side.
9
+ import { parseIsoDate, propValue } from '../dsl-utils.js';
10
+ import { GUTTER_PX } from '../themes/shared.js';
11
+ import { MARKER_BOLD_WIDTH_FACTOR, MARKER_DIAMOND_RADIUS_PX, MARKER_LABEL_GAP_PX, MARKER_LABEL_HEIGHT_PX, MARKER_ROW_CENTER_OFFSET_PX, MARKER_ROW_PITCH_PX, } from './marker-geometry.js';
12
+ /**
13
+ * The date-pinned anchors, then the date-pinned milestones, each at the x
14
+ * of its `date:`. A marker with no date, or a date outside the window,
15
+ * is left out; after-only milestones are placed with the lanes.
16
+ */
17
+ export function datePinnedMarkerEntries(anchors, milestones, scale) {
18
+ const entries = [];
19
+ const add = (id, decl, isMilestone) => {
20
+ const date = parseIsoDate(propValue(decl.properties, 'date'));
21
+ if (!date)
22
+ return;
23
+ const x = scale.forwardWithinDomain(date);
24
+ if (x === null)
25
+ return;
26
+ entries.push({
27
+ id,
28
+ centerX: x,
29
+ radius: MARKER_DIAMOND_RADIUS_PX,
30
+ title: decl.title ?? id,
31
+ fontSize: 10,
32
+ bold: isMilestone,
33
+ date,
34
+ isMilestone,
35
+ });
36
+ };
37
+ for (const [id, anchor] of anchors)
38
+ add(id, anchor, false);
39
+ for (const [id, milestone] of milestones)
40
+ add(id, milestone, true);
41
+ return entries;
42
+ }
43
+ /**
44
+ * The calendar's marker-row entries: the titled non-working runs, then the
45
+ * working exceptions. Callers append them after the anchors and
46
+ * milestones.
47
+ */
48
+ export function calendarMarkerEntries(runs, exceptions) {
49
+ return [...nonWorkingRunEntries(runs), ...workingExceptionEntries(exceptions)];
50
+ }
51
+ /**
52
+ * Each packed placement at the band's y: row `r`'s centre sits
53
+ * `MARKER_ROW_CENTER_OFFSET_PX + r * MARKER_ROW_PITCH_PX` below
54
+ * `markerRowY`, and its label box 4 px above the centre.
55
+ */
56
+ export function markerRowPlacements(packed, markerRowY) {
57
+ const out = new Map();
58
+ for (const [id, p] of packed) {
59
+ const centerY = markerRowY + MARKER_ROW_CENTER_OFFSET_PX + p.rowIndex * MARKER_ROW_PITCH_PX;
60
+ out.set(id, {
61
+ rowIndex: p.rowIndex,
62
+ centerY,
63
+ labelBox: { ...p.labelBox, y: centerY - 4 },
64
+ labelSide: p.labelSide,
65
+ });
66
+ }
67
+ return out;
68
+ }
69
+ /** The marker-row id of a titled non-working run: `nonworking:<ISO from>`. */
70
+ export function nonWorkingRunMarkerId(run) {
71
+ return `nonworking:${run.from.toISOString().slice(0, 10)}`;
72
+ }
73
+ /** The marker-row id of a working exception: `working:<ISO from>`. */
74
+ export function workingExceptionMarkerId(exception) {
75
+ return `working:${exception.from.toISOString().slice(0, 10)}`;
76
+ }
77
+ /** A zero-radius marker-row entry for a calendar label at `x`. */
78
+ function calendarLabelEntry(id, x, label) {
79
+ return { id, centerX: x, radius: 0, title: label, fontSize: 10, bold: false };
80
+ }
81
+ /**
82
+ * Marker-row entries for the titled runs (specs/working-calendar.md
83
+ * §7.4): a zero-radius marker at the run's x (the seam under `hide`, the
84
+ * band's left edge under `show`) whose title is the run's label. Callers
85
+ * append them after the anchors and milestones, so the stable sort in
86
+ * `packMarkerRow` places a marker that ties a run on x first.
87
+ */
88
+ function nonWorkingRunEntries(runs) {
89
+ const entries = [];
90
+ for (const run of runs ?? []) {
91
+ if (run.label === undefined)
92
+ continue;
93
+ entries.push(calendarLabelEntry(nonWorkingRunMarkerId(run), run.x, run.label));
94
+ }
95
+ return entries;
96
+ }
97
+ /**
98
+ * Marker-row entries for the working exceptions (specs/working-calendar.md
99
+ * §7.4), packed beside the titled runs' and on the same terms: a zero-radius
100
+ * marker at the first turned day's x.
101
+ */
102
+ function workingExceptionEntries(exceptions) {
103
+ return (exceptions ?? []).map((exception) => calendarLabelEntry(workingExceptionMarkerId(exception), exception.x, exception.label));
104
+ }
105
+ /**
106
+ * The canvas right edge the marker-row labels need. A label (anchor,
107
+ * milestone, titled run or working exception) that fits neither right of
108
+ * its x (against `chartRightX`) nor left of it (against `chartLeftX`)
109
+ * would fall back to the left and draw over a beside header card, so the
110
+ * canvas grows to hold it on the right instead. A slipped milestone's
111
+ * label never fits on the left, where its span runs.
112
+ */
113
+ export function markerLabelsRightX(entries, chartLeftX, chartRightX, estimateTextWidth) {
114
+ let rightX = chartRightX;
115
+ for (const e of entries) {
116
+ const labelWidth = markerLabelWidth(e, estimateTextWidth);
117
+ const rightEnd = e.centerX + e.radius + MARKER_LABEL_GAP_PX + labelWidth;
118
+ const leftStart = e.centerX - e.radius - MARKER_LABEL_GAP_PX - labelWidth;
119
+ const fitsLeft = leftStart >= chartLeftX && e.slipFromX === undefined;
120
+ if (rightEnd > chartRightX && !fitsLeft) {
121
+ rightX = Math.max(rightX, rightEnd + GUTTER_PX);
122
+ }
123
+ }
124
+ return rightX;
125
+ }
126
+ /** A marker label's width: bold labels widen by `MARKER_BOLD_WIDTH_FACTOR`. */
127
+ function markerLabelWidth(e, estimateTextWidth) {
128
+ return estimateTextWidth(e.title, e.fontSize) * (e.bold ? MARKER_BOLD_WIDTH_FACTOR : 1);
129
+ }
130
+ /** The arrows between markers that `placements` draw, source to target. */
131
+ export function markerArrows(placements) {
132
+ const out = [];
133
+ for (const p of placements) {
134
+ for (const a of p.slackArrows ?? []) {
135
+ if ('marker' in a && a.marker !== p.id)
136
+ out.push({ from: a.marker, to: p.id });
137
+ }
138
+ }
139
+ return out;
140
+ }
141
+ /**
142
+ * Pack anchors + milestones into marker rows using a bottom-first
143
+ * tick-order strategy. Markers default to the row CLOSEST to the
144
+ * chart; conflicts push them UP toward the date ticks (the inverse of
145
+ * swimlane items which default to the top and push down).
146
+ *
147
+ * Walk order is left-to-right by `centerX` (tick order, not file
148
+ * declaration). For each marker:
149
+ * 1. Try the bottommost existing row (highest `rowIndex`), right
150
+ * side first then left, working UP through the rows.
151
+ * 2. If neither side fits at any existing row, GROW: prepend a new
152
+ * row at `rowIndex = 0`. Every previously-placed marker has its
153
+ * `rowIndex` incremented by 1 so the bottom corridor stays
154
+ * stable as the band expands upward toward the ticks.
155
+ *
156
+ * `arrows` (the marker-to-marker arrows, `markerArrows`) add three rules,
157
+ * so an arrow crosses no other marker and ends on its target's line:
158
+ * - An arrow's run, on its source's row between the two diamonds, is
159
+ * reserved on that row like a label: no other diamond, label or run
160
+ * may overlap it.
161
+ * - A target sits at or above each source's row (cut lines run down
162
+ * from a diamond). A source whose target is placed and that fits no
163
+ * allowed row grows a fresh row right below the target instead of
164
+ * at the top; when the rules contradict (a marker both a source and
165
+ * a target on one row), it grows at the top.
166
+ * - A label takes a side its own arrows do not run along, when that
167
+ * side fits; otherwise it keeps the usual right-then-left order.
168
+ * With no arrows the pack is unchanged.
169
+ *
170
+ * Returns row-relative placements (no centerY yet — caller fills that
171
+ * in once `markerRowY` is known). Row indices follow the existing
172
+ * convention: 0 = top of band (closest to ticks), `rowCount - 1` =
173
+ * bottom of band (closest to chart). The "bottom-first" preference
174
+ * lives entirely in the search order and grow direction; geometry
175
+ * stays anchored to `markerRowY` at the top.
176
+ */
177
+ export function packMarkerRow(entries, chartLeftX, chartRightX, estimateTextWidth, arrows = []) {
178
+ const sorted = [...entries].sort((a, b) => a.centerX - b.centerX);
179
+ const placements = new Map();
180
+ let rowSpans = [];
181
+ const byId = new Map(entries.map((e) => [e.id, e]));
182
+ const knownArrows = arrows.filter((a) => byId.has(a.from) && byId.has(a.to));
183
+ for (const e of sorted) {
184
+ const labelWidth = markerLabelWidth(e, estimateTextWidth);
185
+ const naturalRightX = e.centerX + e.radius + MARKER_LABEL_GAP_PX;
186
+ const naturalLeftX = e.centerX - e.radius - MARKER_LABEL_GAP_PX - labelWidth;
187
+ const fitsRightCanvas = naturalRightX + labelWidth <= chartRightX;
188
+ const fitsLeftCanvas = naturalLeftX >= chartLeftX;
189
+ const diamondLeft = e.centerX - e.radius;
190
+ const diamondRight = e.centerX + e.radius;
191
+ const sideXLeft = (s) => (s === 'right' ? naturalRightX : naturalLeftX);
192
+ const sideFitsCanvas = (s) => s === 'right' ? fitsRightCanvas : fitsLeftCanvas;
193
+ // The runs of e's own arrows, on e's row between the two diamonds,
194
+ // and a slipped milestone's span from its planned diamond.
195
+ const slipRun = e.slipFromX === undefined
196
+ ? []
197
+ : [{ left: e.slipFromX - e.radius, right: e.centerX - e.radius }];
198
+ const runs = knownArrows
199
+ .filter((a) => a.from === e.id)
200
+ .map((a) => {
201
+ const to = byId.get(a.to);
202
+ return {
203
+ left: Math.min(e.centerX, to.centerX) + e.radius,
204
+ right: Math.max(e.centerX, to.centerX) - to.radius,
205
+ };
206
+ })
207
+ .concat(slipRun)
208
+ .filter((r) => r.right > r.left);
209
+ // An arrow meets its target's line only when the target sits at or
210
+ // above the source's row (cut lines run down from a diamond).
211
+ let minRow = -1;
212
+ let maxRow = Number.POSITIVE_INFINITY;
213
+ for (const a of knownArrows) {
214
+ if (a.to === e.id) {
215
+ const from = placements.get(a.from);
216
+ if (from)
217
+ maxRow = Math.min(maxRow, from.rowIndex);
218
+ }
219
+ if (a.from === e.id) {
220
+ const to = placements.get(a.to);
221
+ if (to)
222
+ minRow = Math.max(minRow, to.rowIndex);
223
+ }
224
+ }
225
+ // A label on the side its own arrow leaves would sit on the arrow.
226
+ const crossesOwnRun = (s) => {
227
+ const xLeft = sideXLeft(s);
228
+ return runs.some((r) => r.left < xLeft + labelWidth && r.right > xLeft);
229
+ };
230
+ const freeSide = (s) => sideFitsCanvas(s) && !crossesOwnRun(s);
231
+ // A slipped milestone's label never goes back over its span; the
232
+ // canvas grew for it (`markerLabelsRightX`).
233
+ const growSide = freeSide('right') || e.slipFromX !== undefined
234
+ ? 'right'
235
+ : freeSide('left')
236
+ ? 'left'
237
+ : fitsRightCanvas
238
+ ? 'right'
239
+ : 'left';
240
+ const collidesAt = (xLeft, row) => {
241
+ const extLeft = Math.min(diamondLeft, xLeft);
242
+ const extRight = Math.max(diamondRight, xLeft + labelWidth);
243
+ const own = [{ left: extLeft, right: extRight }, ...runs];
244
+ return rowSpans[row].some((s) => own.some((o) => s.left < o.right && s.right > o.left));
245
+ };
246
+ let placedRow = -1;
247
+ let placedSide = 'right';
248
+ let placedXLeft = naturalRightX;
249
+ // Bottom-first: try the highest existing row first, working up
250
+ // toward row 0 (closest to the ticks).
251
+ outer: for (let row = rowSpans.length - 1; row >= 0; row--) {
252
+ if (row < minRow || row > maxRow)
253
+ continue;
254
+ for (const side of ['right', 'left']) {
255
+ if (!freeSide(side))
256
+ continue;
257
+ const xLeft = sideXLeft(side);
258
+ if (collidesAt(xLeft, row))
259
+ continue;
260
+ placedRow = row;
261
+ placedSide = side;
262
+ placedXLeft = xLeft;
263
+ break outer;
264
+ }
265
+ }
266
+ if (placedRow === -1 && minRow >= 0 && minRow < maxRow) {
267
+ // An arrow source that must stay at or below its target and fits
268
+ // no row there: a fresh row right below the target, which keeps
269
+ // every placed arrow's source at or below its target.
270
+ const at = minRow + 1;
271
+ for (const [id, p] of placements) {
272
+ if (p.rowIndex >= at)
273
+ placements.set(id, { ...p, rowIndex: p.rowIndex + 1 });
274
+ }
275
+ rowSpans.splice(at, 0, []);
276
+ placedRow = at;
277
+ placedSide = growSide;
278
+ placedXLeft = sideXLeft(placedSide);
279
+ }
280
+ else if (placedRow === -1) {
281
+ // No existing row fits — prepend a fresh top row and shift
282
+ // every previous placement DOWN by one slot (rowIndex += 1)
283
+ // so the bottom corridor stays stable.
284
+ for (const [id, p] of placements) {
285
+ placements.set(id, { ...p, rowIndex: p.rowIndex + 1 });
286
+ }
287
+ rowSpans = [[], ...rowSpans];
288
+ placedRow = 0;
289
+ placedSide = growSide;
290
+ placedXLeft = sideXLeft(placedSide);
291
+ }
292
+ const extLeft = Math.min(diamondLeft, placedXLeft);
293
+ const extRight = Math.max(diamondRight, placedXLeft + labelWidth);
294
+ rowSpans[placedRow].push({ left: extLeft, right: extRight }, ...runs);
295
+ placements.set(e.id, {
296
+ rowIndex: placedRow,
297
+ labelBox: { x: placedXLeft, y: 0, width: labelWidth, height: MARKER_LABEL_HEIGHT_PX },
298
+ labelSide: placedSide,
299
+ });
300
+ }
301
+ return { placements, rowCount: rowSpans.length };
302
+ }
303
+ //# sourceMappingURL=marker-band.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker-band.js","sourceRoot":"","sources":["../../src/nodes/marker-band.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@
8
8
  // the timeline header. The marker band stacks N rows tall when
9
9
  // anchors and milestones can't fit on a single row without colliding.
10
10
  // - The bare `13` (= PITCH / 2) midpoint that used to sprinkle
11
- // `roadmap-node.ts` is derived from this constant — bumping the
11
+ // the roadmap composition code is derived from this constant — bumping the
12
12
  // pitch automatically re-centers labels.
13
13
  //
14
14
  // Diamond + label box dimensions are reused by every marker (anchor +
@@ -1 +1 @@
1
- {"version":3,"file":"marker-geometry.js","sourceRoot":"","sources":["../../src/nodes/marker-geometry.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,uEAAuE;AACvE,wDAAwD;AACxD,EAAE;AACF,wCAAwC;AACxC,EAAE;AACF,sEAAsE;AACtE,mEAAmE;AACnE,0EAA0E;AAC1E,iEAAiE;AACjE,oEAAoE;AACpE,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,8DAA8D;AAC9D,gEAAgE;AAEhE,sEAAsE;AACtE,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,GAAG,CAAC,CAAC;AAEnE,uEAAuE;AACvE,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"marker-geometry.js","sourceRoot":"","sources":["../../src/nodes/marker-geometry.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,uEAAuE;AACvE,wDAAwD;AACxD,EAAE;AACF,wCAAwC;AACxC,EAAE;AACF,sEAAsE;AACtE,mEAAmE;AACnE,0EAA0E;AAC1E,iEAAiE;AACjE,+EAA+E;AAC/E,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,8DAA8D;AAC9D,gEAAgE;AAEhE,sEAAsE;AACtE,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,GAAG,CAAC,CAAC;AAEnE,uEAAuE;AACvE,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC"}
@@ -1,25 +1,44 @@
1
1
  import type { MilestoneDeclaration } from '@nowline/core';
2
2
  import type { LayoutContext } from '../layout-context.js';
3
- import type { PositionedMilestone } from '../types.js';
3
+ import type { MarkerRowPlacement, PositionedMilestone, ResolvedStyle, SlackCorridor } from '../types.js';
4
4
  /**
5
- * One predecessor of a milestone with everything the slack-arrow
6
- * pipeline needs: its source x (visual right edge for items, marker
7
- * centerX for anchors / other milestones), its attach y (bar bottom
8
- * strip when text spills, row mid otherwise), and its flow key (used
9
- * to dedupe so a chained-flow's siblings collapse to the last entry).
5
+ * One predecessor of a milestone with everything placement and the
6
+ * slack-arrow pipeline need: its end in time (`endX`, also where its slack
7
+ * or overrun line starts, specs/true-width-layout.md §3.5), an item's
8
+ * attach y in the chart's local frame (bar bottom strip when text spills,
9
+ * nominal row midline otherwise), and its flow key (used to dedupe so a
10
+ * chained-flow's siblings collapse to the last entry).
10
11
  */
11
12
  export interface MilestonePredecessor {
12
13
  ref: string;
13
- x: number;
14
- y: number;
14
+ /**
15
+ * Where the predecessor ends in time: an item's duration end, a
16
+ * marker's x, a wave's `E_k`. The milestone sits on the latest one and
17
+ * overruns a date by it (specs/scheduler-unification.md §8 decision 6);
18
+ * its slack or overrun line starts here.
19
+ */
20
+ endX: number;
21
+ /**
22
+ * An item's attach y. Undefined for every other reference: a marker
23
+ * (its arrow starts on its marker row, known only after the final
24
+ * pack), a wave, a group or a parallel.
25
+ */
26
+ y: number | undefined;
27
+ /** Set when `ref` names an anchor or milestone of this file. */
28
+ marker?: true;
15
29
  flowKey: string;
30
+ /**
31
+ * Set when `ref` names a wave: `endX` is the seeded wave end `E_k`.
32
+ * Wave references draw no slack arrows (specs/waves.md §5.3).
33
+ */
34
+ wave?: string;
16
35
  }
17
36
  /**
18
- * Resolve each `after:` reference into a `MilestonePredecessor`.
19
- * Items use their VISUAL right edge as the slack source so the
20
- * arrow leaves the painted bar instead of landing in the inter-
21
- * column gutter; markers (anchors / other milestones) fall back
22
- * to their cut-line centerX. Refs whose target is unknown drop
37
+ * Resolve each `after:` reference into a `MilestonePredecessor`. Its
38
+ * `endX` is the reference's right edge in time (`entityRightEdges`, an
39
+ * item's duration end, a marker's cut-line x), where its slack line
40
+ * starts: a bar spans exactly its dates, so its end date is its edge
41
+ * (specs/true-width-layout.md §3.5). Refs whose target is unknown drop
23
42
  * silently — matches the legacy continue path.
24
43
  */
25
44
  export declare function collectMilestonePredecessors(refs: string[], ctx: LayoutContext): MilestonePredecessor[];
@@ -33,6 +52,54 @@ export declare function collectMilestonePredecessors(refs: string[], ctx: Layout
33
52
  * each survive as their flow's last entry.
34
53
  */
35
54
  export declare function lastPredecessorPerFlow(preds: MilestonePredecessor[]): MilestonePredecessor[];
55
+ /**
56
+ * Where a milestone's slack or overrun arrow starts: at `x` on a chart y
57
+ * (an item predecessor's attach y, in the chart's local frame), or at `x`
58
+ * on the row of `marker` in the marker band, which `positionMilestones`
59
+ * reads from the final pack.
60
+ */
61
+ export type MilestoneArrowStart = {
62
+ x: number;
63
+ y: number;
64
+ } | {
65
+ x: number;
66
+ marker: string;
67
+ };
68
+ /**
69
+ * The predecessor a dated milestone slips to: the one that ends latest in
70
+ * time and is not a wave (an overrunning wave is taken separately, by
71
+ * `overrunningWave`).
72
+ */
73
+ export declare function latestArrowPredecessor(preds: MilestonePredecessor[]): MilestonePredecessor | null;
74
+ /**
75
+ * A milestone as placement leaves it: its x, slack arrows, overrun and cut
76
+ * lines, but no marker row or label box. Those come from the unified
77
+ * marker re-pack, which needs every milestone's x and the final canvas;
78
+ * `positionMilestones` combines the two.
79
+ */
80
+ export interface MilestonePlacement {
81
+ id: string;
82
+ title: string;
83
+ x: number;
84
+ radius: number;
85
+ /** True for a `date:` milestone, false for an after-only one. */
86
+ fixed: boolean;
87
+ slackArrows: MilestoneArrowStart[] | undefined;
88
+ isOverrun: boolean;
89
+ /**
90
+ * Where an overrun dated milestone actually lands: the end of its
91
+ * latest predecessor (or overrunning wave), past `x`. Omitted when it
92
+ * does not overrun, or when the two diamonds would meet.
93
+ */
94
+ slipX?: number;
95
+ style: ResolvedStyle;
96
+ cutTopY: number;
97
+ cutBottomY: number;
98
+ onWaveBoundary?: true;
99
+ overrunByWave?: string;
100
+ overrunDate?: string;
101
+ hiddenDate?: string;
102
+ }
36
103
  export declare class MilestoneNode {
37
104
  readonly id: string;
38
105
  readonly milestone: MilestoneDeclaration;
@@ -41,8 +108,38 @@ export declare class MilestoneNode {
41
108
  * Returns null when the milestone is neither date-pinned nor has a
42
109
  * resolvable `after:` predecessor (skipped silently — matches the
43
110
  * legacy `buildMilestones` continue-paths).
111
+ *
112
+ * Writes the milestone's entity edges and midpoint; later milestones'
113
+ * `after:` references read the edges. The midpoint's y is an
114
+ * estimate: the pre-pack row of a dated milestone, the band's first
115
+ * row for an after-only one. Nothing reads it before f6 replaces it
116
+ * with the final pack's row, except f6's coverage trace, which
117
+ * reports a milestone whose row differs from it.
44
118
  */
45
- place(ctx: LayoutContext): PositionedMilestone | null;
119
+ place(ctx: LayoutContext): MilestonePlacement | null;
46
120
  }
47
- export declare function buildMilestones(milestones: Map<string, MilestoneDeclaration>, ctx: LayoutContext): PositionedMilestone[];
121
+ export declare function buildMilestones(milestones: Map<string, MilestoneDeclaration>, ctx: LayoutContext): MilestonePlacement[];
122
+ /**
123
+ * Build the positioned milestones from their placements and the unified
124
+ * marker re-pack (`rows`, keyed by id), in placement order. The re-pack
125
+ * packs every placed milestone and anchor, so a missing row is an
126
+ * invariant violation and throws. An arrow that starts on a marker row
127
+ * takes that row's centre, already final; one from an item keeps its
128
+ * chart y. Optional keys stay omitted when the placement omits them.
129
+ */
130
+ export declare function positionMilestones(placements: readonly MilestonePlacement[], rows: ReadonlyMap<string, MarkerRowPlacement>): PositionedMilestone[];
131
+ /**
132
+ * Collect slack-arrow corridors from the resolved milestones using the
133
+ * current entity-edge maps. The result mirrors what
134
+ * `MilestoneNode.place` would emit on `slackArrows`, so the row-packer
135
+ * and the renderer agree on every arrow's geometry.
136
+ *
137
+ * Each non-binding item predecessor (`x < maxEnd`) of an after-only
138
+ * milestone becomes one corridor. A date-pinned milestone draws no arrow
139
+ * (an overrun slips it, in the marker band), so it owns none. An arrow
140
+ * from a marker runs in the marker band, above the lanes, so it owns no
141
+ * corridor; nor does a wave predecessor, which draws no slack arrow (a
142
+ * floating milestone bound by a wave still sets `maxEnd`).
143
+ */
144
+ export declare function collectSlackCorridors(milestones: Map<string, import('@nowline/core').MilestoneDeclaration>, ctx: LayoutContext): SlackCorridor[];
48
145
  //# sourceMappingURL=milestone-node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"milestone-node.d.ts","sourceRoot":"","sources":["../../src/nodes/milestone-node.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAsB,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAQ3E;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CACxC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,aAAa,GACnB,oBAAoB,EAAE,CAaxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CAO5F;AAyBD,qBAAa,aAAa;aAEF,EAAE,EAAE,MAAM;aACV,SAAS,EAAE,oBAAoB;gBAD/B,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,oBAAoB;IAGnD;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,mBAAmB,GAAG,IAAI;CAoIxD;AAED,wBAAgB,eAAe,CAC3B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC7C,GAAG,EAAE,aAAa,GACnB,mBAAmB,EAAE,CAOvB"}
1
+ {"version":3,"file":"milestone-node.d.ts","sourceRoot":"","sources":["../../src/nodes/milestone-node.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EACR,kBAAkB,EAElB,mBAAmB,EACnB,aAAa,EACb,aAAa,EAChB,MAAM,aAAa,CAAC;AAIrB;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtB,gEAAgE;IAChE,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CACxC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,aAAa,GACnB,oBAAoB,EAAE,CAyBxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CAO5F;AAED;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAwB3F;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,GAAG,IAAI,CAOjG;AAoBD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,aAAa;aAEF,EAAE,EAAE,MAAM;aACV,SAAS,EAAE,oBAAoB;IAFnD,YACoB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,oBAAoB,EAC/C;IAEJ;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,kBAAkB,GAAG,IAAI,CA2GnD;CACJ;AAED,wBAAgB,eAAe,CAC3B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC7C,GAAG,EAAE,aAAa,GACnB,kBAAkB,EAAE,CAOtB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAC9B,UAAU,EAAE,SAAS,kBAAkB,EAAE,EACzC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,GAC9C,mBAAmB,EAAE,CAiCvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACjC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,eAAe,EAAE,oBAAoB,CAAC,EACrE,GAAG,EAAE,aAAa,GACnB,aAAa,EAAE,CA8BjB"}