@nowline/layout 0.8.6 → 0.10.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 (338) 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/calendar-resolver.d.ts +27 -0
  6. package/dist/calendar-resolver.d.ts.map +1 -0
  7. package/dist/calendar-resolver.js +132 -0
  8. package/dist/calendar-resolver.js.map +1 -0
  9. package/dist/calendar.d.ts +0 -19
  10. package/dist/calendar.d.ts.map +1 -1
  11. package/dist/calendar.js +4 -44
  12. package/dist/calendar.js.map +1 -1
  13. package/dist/canvas-width.d.ts +23 -0
  14. package/dist/canvas-width.d.ts.map +1 -0
  15. package/dist/canvas-width.js +26 -0
  16. package/dist/canvas-width.js.map +1 -0
  17. package/dist/capacity.d.ts +28 -0
  18. package/dist/capacity.d.ts.map +1 -1
  19. package/dist/capacity.js +64 -29
  20. package/dist/capacity.js.map +1 -1
  21. package/dist/chart-translation.d.ts +22 -0
  22. package/dist/chart-translation.d.ts.map +1 -0
  23. package/dist/chart-translation.js +83 -0
  24. package/dist/chart-translation.js.map +1 -0
  25. package/dist/container-header-geometry.d.ts +64 -0
  26. package/dist/container-header-geometry.d.ts.map +1 -0
  27. package/dist/container-header-geometry.js +89 -0
  28. package/dist/container-header-geometry.js.map +1 -0
  29. package/dist/dsl-utils.d.ts +3 -4
  30. package/dist/dsl-utils.d.ts.map +1 -1
  31. package/dist/dsl-utils.js +8 -25
  32. package/dist/dsl-utils.js.map +1 -1
  33. package/dist/edge-routing.d.ts +69 -78
  34. package/dist/edge-routing.d.ts.map +1 -1
  35. package/dist/edge-routing.js +271 -401
  36. package/dist/edge-routing.js.map +1 -1
  37. package/dist/frame-tab-geometry.d.ts +24 -14
  38. package/dist/frame-tab-geometry.d.ts.map +1 -1
  39. package/dist/frame-tab-geometry.js +69 -23
  40. package/dist/frame-tab-geometry.js.map +1 -1
  41. package/dist/header-card-geometry.d.ts +12 -0
  42. package/dist/header-card-geometry.d.ts.map +1 -1
  43. package/dist/header-card-geometry.js +14 -2
  44. package/dist/header-card-geometry.js.map +1 -1
  45. package/dist/header-logo.d.ts +28 -0
  46. package/dist/header-logo.d.ts.map +1 -0
  47. package/dist/header-logo.js +51 -0
  48. package/dist/header-logo.js.map +1 -0
  49. package/dist/i18n.d.ts +11 -0
  50. package/dist/i18n.d.ts.map +1 -1
  51. package/dist/i18n.js +11 -1
  52. package/dist/i18n.js.map +1 -1
  53. package/dist/index.d.ts +20 -8
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +17 -7
  56. package/dist/index.js.map +1 -1
  57. package/dist/inline-date-pin-geometry.d.ts +19 -11
  58. package/dist/inline-date-pin-geometry.d.ts.map +1 -1
  59. package/dist/inline-date-pin-geometry.js +45 -46
  60. package/dist/inline-date-pin-geometry.js.map +1 -1
  61. package/dist/item-bar-geometry.d.ts +192 -4
  62. package/dist/item-bar-geometry.d.ts.map +1 -1
  63. package/dist/item-bar-geometry.js +258 -5
  64. package/dist/item-bar-geometry.js.map +1 -1
  65. package/dist/item-port-geometry.d.ts +13 -0
  66. package/dist/item-port-geometry.d.ts.map +1 -0
  67. package/dist/item-port-geometry.js +63 -0
  68. package/dist/item-port-geometry.js.map +1 -0
  69. package/dist/layout-context.d.ts +115 -51
  70. package/dist/layout-context.d.ts.map +1 -1
  71. package/dist/layout-context.js +96 -5
  72. package/dist/layout-context.js.map +1 -1
  73. package/dist/layout-insights.d.ts.map +1 -1
  74. package/dist/layout-insights.js +73 -1
  75. package/dist/layout-insights.js.map +1 -1
  76. package/dist/layout.d.ts +35 -0
  77. package/dist/layout.d.ts.map +1 -1
  78. package/dist/layout.js +18 -1315
  79. package/dist/layout.js.map +1 -1
  80. package/dist/nodes/anchor-node.d.ts.map +1 -1
  81. package/dist/nodes/anchor-node.js +11 -4
  82. package/dist/nodes/anchor-node.js.map +1 -1
  83. package/dist/nodes/content-extent.d.ts +24 -0
  84. package/dist/nodes/content-extent.d.ts.map +1 -0
  85. package/dist/nodes/content-extent.js +100 -0
  86. package/dist/nodes/content-extent.js.map +1 -0
  87. package/dist/nodes/dependency-edges.d.ts +6 -0
  88. package/dist/nodes/dependency-edges.d.ts.map +1 -0
  89. package/dist/nodes/dependency-edges.js +148 -0
  90. package/dist/nodes/dependency-edges.js.map +1 -0
  91. package/dist/nodes/footnote-node.d.ts +24 -3
  92. package/dist/nodes/footnote-node.d.ts.map +1 -1
  93. package/dist/nodes/footnote-node.js +129 -25
  94. package/dist/nodes/footnote-node.js.map +1 -1
  95. package/dist/nodes/group-node.d.ts +10 -21
  96. package/dist/nodes/group-node.d.ts.map +1 -1
  97. package/dist/nodes/group-node.js +79 -152
  98. package/dist/nodes/group-node.js.map +1 -1
  99. package/dist/nodes/header-node.d.ts +56 -0
  100. package/dist/nodes/header-node.d.ts.map +1 -0
  101. package/dist/nodes/header-node.js +163 -0
  102. package/dist/nodes/header-node.js.map +1 -0
  103. package/dist/nodes/include-node.d.ts +22 -12
  104. package/dist/nodes/include-node.d.ts.map +1 -1
  105. package/dist/nodes/include-node.js +95 -62
  106. package/dist/nodes/include-node.js.map +1 -1
  107. package/dist/nodes/item-measure.d.ts +135 -0
  108. package/dist/nodes/item-measure.d.ts.map +1 -0
  109. package/dist/nodes/item-measure.js +514 -0
  110. package/dist/nodes/item-measure.js.map +1 -0
  111. package/dist/nodes/item-node.d.ts +162 -9
  112. package/dist/nodes/item-node.d.ts.map +1 -1
  113. package/dist/nodes/item-node.js +256 -69
  114. package/dist/nodes/item-node.js.map +1 -1
  115. package/dist/nodes/marker-band.d.ts +118 -0
  116. package/dist/nodes/marker-band.d.ts.map +1 -0
  117. package/dist/nodes/marker-band.js +303 -0
  118. package/dist/nodes/marker-band.js.map +1 -0
  119. package/dist/nodes/marker-geometry.js +1 -1
  120. package/dist/nodes/marker-geometry.js.map +1 -1
  121. package/dist/nodes/milestone-node.d.ts +112 -15
  122. package/dist/nodes/milestone-node.d.ts.map +1 -1
  123. package/dist/nodes/milestone-node.js +246 -95
  124. package/dist/nodes/milestone-node.js.map +1 -1
  125. package/dist/nodes/nowline-node.d.ts +8 -0
  126. package/dist/nodes/nowline-node.d.ts.map +1 -0
  127. package/dist/nodes/nowline-node.js +74 -0
  128. package/dist/nodes/nowline-node.js.map +1 -0
  129. package/dist/nodes/parallel-node.d.ts +7 -12
  130. package/dist/nodes/parallel-node.d.ts.map +1 -1
  131. package/dist/nodes/parallel-node.js +66 -30
  132. package/dist/nodes/parallel-node.js.map +1 -1
  133. package/dist/nodes/region-markers.d.ts +41 -0
  134. package/dist/nodes/region-markers.d.ts.map +1 -0
  135. package/dist/nodes/region-markers.js +130 -0
  136. package/dist/nodes/region-markers.js.map +1 -0
  137. package/dist/nodes/roadmap-node.d.ts +9 -72
  138. package/dist/nodes/roadmap-node.d.ts.map +1 -1
  139. package/dist/nodes/roadmap-node.js +38 -788
  140. package/dist/nodes/roadmap-node.js.map +1 -1
  141. package/dist/nodes/row-track.d.ts +33 -0
  142. package/dist/nodes/row-track.d.ts.map +1 -0
  143. package/dist/nodes/row-track.js +170 -0
  144. package/dist/nodes/row-track.js.map +1 -0
  145. package/dist/nodes/sequence-item.d.ts +25 -0
  146. package/dist/nodes/sequence-item.d.ts.map +1 -0
  147. package/dist/nodes/sequence-item.js +396 -0
  148. package/dist/nodes/sequence-item.js.map +1 -0
  149. package/dist/nodes/sequence-one.d.ts +5 -0
  150. package/dist/nodes/sequence-one.d.ts.map +1 -0
  151. package/dist/nodes/sequence-one.js +26 -0
  152. package/dist/nodes/sequence-one.js.map +1 -0
  153. package/dist/nodes/swimlane-node.d.ts +5 -17
  154. package/dist/nodes/swimlane-node.d.ts.map +1 -1
  155. package/dist/nodes/swimlane-node.js +62 -145
  156. package/dist/nodes/swimlane-node.js.map +1 -1
  157. package/dist/nodes/wave-node.d.ts +52 -0
  158. package/dist/nodes/wave-node.d.ts.map +1 -0
  159. package/dist/nodes/wave-node.js +483 -0
  160. package/dist/nodes/wave-node.js.map +1 -0
  161. package/dist/non-working-display.d.ts +14 -0
  162. package/dist/non-working-display.d.ts.map +1 -0
  163. package/dist/non-working-display.js +28 -0
  164. package/dist/non-working-display.js.map +1 -0
  165. package/dist/phases/date-window.d.ts +48 -0
  166. package/dist/phases/date-window.d.ts.map +1 -0
  167. package/dist/phases/date-window.js +130 -0
  168. package/dist/phases/date-window.js.map +1 -0
  169. package/dist/phases/finalize.d.ts +198 -0
  170. package/dist/phases/finalize.d.ts.map +1 -0
  171. package/dist/phases/finalize.js +1058 -0
  172. package/dist/phases/finalize.js.map +1 -0
  173. package/dist/phases/measure.d.ts +77 -0
  174. package/dist/phases/measure.d.ts.map +1 -0
  175. package/dist/phases/measure.js +222 -0
  176. package/dist/phases/measure.js.map +1 -0
  177. package/dist/phases/place.d.ts +28 -0
  178. package/dist/phases/place.d.ts.map +1 -0
  179. package/dist/phases/place.js +225 -0
  180. package/dist/phases/place.js.map +1 -0
  181. package/dist/renderable.d.ts.map +1 -1
  182. package/dist/renderable.js +23 -3
  183. package/dist/renderable.js.map +1 -1
  184. package/dist/resolve-today.d.ts +11 -1
  185. package/dist/resolve-today.d.ts.map +1 -1
  186. package/dist/resolve-today.js +26 -12
  187. package/dist/resolve-today.js.map +1 -1
  188. package/dist/row-packer.d.ts +42 -16
  189. package/dist/row-packer.d.ts.map +1 -1
  190. package/dist/row-packer.js +51 -78
  191. package/dist/row-packer.js.map +1 -1
  192. package/dist/schedule.d.ts +58 -1
  193. package/dist/schedule.d.ts.map +1 -1
  194. package/dist/schedule.js +280 -106
  195. package/dist/schedule.js.map +1 -1
  196. package/dist/start-rules.d.ts +27 -0
  197. package/dist/start-rules.d.ts.map +1 -0
  198. package/dist/start-rules.js +91 -0
  199. package/dist/start-rules.js.map +1 -0
  200. package/dist/start-terms.d.ts +23 -0
  201. package/dist/start-terms.d.ts.map +1 -0
  202. package/dist/start-terms.js +27 -0
  203. package/dist/start-terms.js.map +1 -0
  204. package/dist/status-dot.d.ts +46 -0
  205. package/dist/status-dot.d.ts.map +1 -0
  206. package/dist/status-dot.js +78 -0
  207. package/dist/status-dot.js.map +1 -0
  208. package/dist/style-resolution.d.ts.map +1 -1
  209. package/dist/style-resolution.js +23 -43
  210. package/dist/style-resolution.js.map +1 -1
  211. package/dist/text-measure.d.ts +28 -0
  212. package/dist/text-measure.d.ts.map +1 -0
  213. package/dist/text-measure.js +70 -0
  214. package/dist/text-measure.js.map +1 -0
  215. package/dist/themes/contrast.d.ts +4 -0
  216. package/dist/themes/contrast.d.ts.map +1 -0
  217. package/dist/themes/contrast.js +32 -0
  218. package/dist/themes/contrast.js.map +1 -0
  219. package/dist/themes/dark.d.ts.map +1 -1
  220. package/dist/themes/dark.js +28 -1
  221. package/dist/themes/dark.js.map +1 -1
  222. package/dist/themes/grayscale.d.ts.map +1 -1
  223. package/dist/themes/grayscale.js +28 -1
  224. package/dist/themes/grayscale.js.map +1 -1
  225. package/dist/themes/index.d.ts +4 -11
  226. package/dist/themes/index.d.ts.map +1 -1
  227. package/dist/themes/index.js +6 -4
  228. package/dist/themes/index.js.map +1 -1
  229. package/dist/themes/light.d.ts.map +1 -1
  230. package/dist/themes/light.js +28 -1
  231. package/dist/themes/light.js.map +1 -1
  232. package/dist/themes/shape.d.ts +31 -0
  233. package/dist/themes/shape.d.ts.map +1 -1
  234. package/dist/themes/shared.d.ts +44 -50
  235. package/dist/themes/shared.d.ts.map +1 -1
  236. package/dist/themes/shared.js +79 -83
  237. package/dist/themes/shared.js.map +1 -1
  238. package/dist/time-scale.d.ts +42 -6
  239. package/dist/time-scale.d.ts.map +1 -1
  240. package/dist/time-scale.js +109 -17
  241. package/dist/time-scale.js.map +1 -1
  242. package/dist/types.d.ts +528 -11
  243. package/dist/types.d.ts.map +1 -1
  244. package/dist/view-preset.d.ts +61 -6
  245. package/dist/view-preset.d.ts.map +1 -1
  246. package/dist/view-preset.js +439 -24
  247. package/dist/view-preset.js.map +1 -1
  248. package/dist/wave-barrier.d.ts +107 -0
  249. package/dist/wave-barrier.d.ts.map +1 -0
  250. package/dist/wave-barrier.js +174 -0
  251. package/dist/wave-barrier.js.map +1 -0
  252. package/dist/wave-hatch.d.ts +4 -0
  253. package/dist/wave-hatch.d.ts.map +1 -0
  254. package/dist/wave-hatch.js +21 -0
  255. package/dist/wave-hatch.js.map +1 -0
  256. package/dist/wave-layout.d.ts +99 -0
  257. package/dist/wave-layout.d.ts.map +1 -0
  258. package/dist/wave-layout.js +130 -0
  259. package/dist/wave-layout.js.map +1 -0
  260. package/dist/working-calendar.d.ts +128 -4
  261. package/dist/working-calendar.d.ts.map +1 -1
  262. package/dist/working-calendar.js +725 -51
  263. package/dist/working-calendar.js.map +1 -1
  264. package/dist/working-span.d.ts +11 -0
  265. package/dist/working-span.d.ts.map +1 -0
  266. package/dist/working-span.js +18 -0
  267. package/dist/working-span.js.map +1 -0
  268. package/package.json +4 -4
  269. package/src/axis-columns.ts +140 -0
  270. package/src/calendar-resolver.ts +161 -0
  271. package/src/calendar.ts +4 -45
  272. package/src/canvas-width.ts +36 -0
  273. package/src/capacity.ts +71 -30
  274. package/src/chart-translation.ts +88 -0
  275. package/src/container-header-geometry.ts +116 -0
  276. package/src/dsl-utils.ts +8 -26
  277. package/src/edge-routing.ts +347 -491
  278. package/src/frame-tab-geometry.ts +78 -25
  279. package/src/header-card-geometry.ts +17 -2
  280. package/src/header-logo.ts +67 -0
  281. package/src/i18n.ts +22 -1
  282. package/src/index.ts +97 -12
  283. package/src/inline-date-pin-geometry.ts +55 -58
  284. package/src/item-bar-geometry.ts +341 -5
  285. package/src/item-port-geometry.ts +69 -0
  286. package/src/layout-context.ts +210 -72
  287. package/src/layout-insights.ts +109 -2
  288. package/src/layout.ts +57 -1530
  289. package/src/nodes/anchor-node.ts +11 -4
  290. package/src/nodes/content-extent.ts +107 -0
  291. package/src/nodes/dependency-edges.ts +171 -0
  292. package/src/nodes/footnote-node.ts +171 -31
  293. package/src/nodes/group-node.ts +92 -214
  294. package/src/nodes/header-node.ts +255 -0
  295. package/src/nodes/include-node.ts +124 -110
  296. package/src/nodes/item-measure.ts +723 -0
  297. package/src/nodes/item-node.ts +358 -80
  298. package/src/nodes/marker-band.ts +406 -0
  299. package/src/nodes/marker-geometry.ts +1 -1
  300. package/src/nodes/milestone-node.ts +321 -136
  301. package/src/nodes/nowline-node.ts +87 -0
  302. package/src/nodes/parallel-node.ts +69 -38
  303. package/src/nodes/region-markers.ts +194 -0
  304. package/src/nodes/roadmap-node.ts +46 -950
  305. package/src/nodes/row-track.ts +217 -0
  306. package/src/nodes/sequence-item.ts +433 -0
  307. package/src/nodes/sequence-one.ts +40 -0
  308. package/src/nodes/swimlane-node.ts +66 -205
  309. package/src/nodes/wave-node.ts +609 -0
  310. package/src/non-working-display.ts +32 -0
  311. package/src/phases/date-window.ts +191 -0
  312. package/src/phases/finalize.ts +1303 -0
  313. package/src/phases/measure.ts +329 -0
  314. package/src/phases/place.ts +318 -0
  315. package/src/renderable.ts +23 -3
  316. package/src/resolve-today.ts +28 -25
  317. package/src/row-packer.ts +85 -84
  318. package/src/schedule.ts +362 -114
  319. package/src/start-rules.ts +113 -0
  320. package/src/start-terms.ts +38 -0
  321. package/src/status-dot.ts +81 -0
  322. package/src/style-resolution.ts +27 -57
  323. package/src/text-measure.ts +71 -0
  324. package/src/themes/contrast.ts +34 -0
  325. package/src/themes/dark.ts +28 -1
  326. package/src/themes/grayscale.ts +28 -1
  327. package/src/themes/index.ts +10 -7
  328. package/src/themes/light.ts +28 -1
  329. package/src/themes/shape.ts +38 -0
  330. package/src/themes/shared.ts +85 -93
  331. package/src/time-scale.ts +117 -19
  332. package/src/types.ts +529 -20
  333. package/src/view-preset.ts +520 -27
  334. package/src/wave-barrier.ts +242 -0
  335. package/src/wave-hatch.ts +25 -0
  336. package/src/wave-layout.ts +203 -0
  337. package/src/working-calendar.ts +875 -57
  338. package/src/working-span.ts +19 -0
@@ -1,22 +1,44 @@
1
- import type { EntityProperty, GroupBlock, ItemDeclaration, LabelDeclaration, ParallelBlock, SymbolDeclaration } from '@nowline/core';
1
+ import { type GroupBlock, type ItemDeclaration, type LabelDeclaration, type ParallelBlock, type ResolvedConfig, type ResolvedContent, type SymbolDeclaration, type TeamDeclaration } from '@nowline/core';
2
+ import type { AxisColumns } from './axis-columns.js';
2
3
  import type { BandScale } from './band-scale.js';
3
- import type { resolveCalendar } from './calendar.js';
4
+ import { type resolveCalendar } from './calendar.js';
5
+ import type { FootnoteIndex } from './nodes/footnote-node.js';
6
+ import type { RoadmapSchedule } from './schedule.js';
4
7
  import type { StyleContext } from './style-resolution.js';
8
+ import type { Theme } from './themes/shape.js';
5
9
  import type { TimeScale } from './time-scale.js';
6
10
  import type { MarkerRowPlacement, Point, PositionedItem, PositionedTimelineScale, PositionedTrackChild, ResolvedSize, SlackCorridor } from './types.js';
11
+ import type { WaveLayoutState } from './wave-layout.js';
7
12
  import type { WorkingCalendar } from './working-calendar.js';
8
13
  /** Slim accumulator used while sequencing items into a track. */
9
14
  export interface TrackCursor {
10
- /** Left edge where the next item begins. */
15
+ /**
16
+ * Where the next item begins, in time: the last child's duration end
17
+ * (a block's latest track end), never a caption spill. A bar spans
18
+ * exactly its dates, so this is also its painted end
19
+ * (specs/true-width-layout.md §3.1).
20
+ */
11
21
  x: number;
22
+ /**
23
+ * Where the child placed last begins, in time: an item's start date, a
24
+ * block's earliest child start. A container's bracket and body open
25
+ * here (specs/true-width-layout.md §3.3).
26
+ */
27
+ startX: number;
12
28
  /** Top edge of the current row. */
13
29
  y: number;
14
30
  /** Accumulated height of the track. */
15
31
  height: number;
16
- /** Rightmost edge reached. */
17
- maxX: number;
18
32
  }
19
33
  export declare function newCursor(x: number, y: number): TrackCursor;
34
+ /**
35
+ * The working-day duration the day schedule gave `item`. Every item engine A
36
+ * lays out is in `schedule.byNode` (the main lanes and the first-level
37
+ * isolated regions it draws), so a miss is an invariant violation, a
38
+ * schedule built for another roadmap or a walker that skipped a node, and
39
+ * throws instead of falling back to a second derivation that could drift.
40
+ */
41
+ export declare function scheduledItemDays(ctx: LayoutContext, item: ItemDeclaration): number;
20
42
  /**
21
43
  * Shared layout state passed through the per-entity sequencers and
22
44
  * Renderable nodes. Owns the resolved calendar/timeline/style scope plus
@@ -24,10 +46,18 @@ export declare function newCursor(x: number, y: number): TrackCursor;
24
46
  */
25
47
  export interface LayoutContext {
26
48
  cal: ReturnType<typeof resolveCalendar>;
49
+ /**
50
+ * The roadmap's day schedule (engine C), shared by the main lanes and
51
+ * every isolated region's context. Item durations in working days come
52
+ * from `schedule.byNode` (`scheduledItemDays`), never from re-deriving
53
+ * them against the sizes (specs/scheduler-unification.md §3.4).
54
+ */
55
+ schedule: RoadmapSchedule;
27
56
  styleCtx: StyleContext;
28
57
  sizes: Map<string, ResolvedSize>;
29
58
  labels: Map<string, LabelDeclaration>;
30
- teams: Map<string, import('@nowline/core').TeamDeclaration>;
59
+ /** Every team by id, the ones nested in another team included. */
60
+ teams: Map<string, TeamDeclaration>;
31
61
  persons: Map<string, import('@nowline/core').PersonDeclaration>;
32
62
  /**
33
63
  * Custom `symbol` declarations from `ResolvedConfig.symbols`. Used by
@@ -42,31 +72,42 @@ export interface LayoutContext {
42
72
  timeline: PositionedTimelineScale;
43
73
  scale: TimeScale;
44
74
  calendar: WorkingCalendar;
75
+ /**
76
+ * The natural axis as tick columns, for the caption cap at the chart's
77
+ * end (`measureItem`). Shared by the main lanes and every isolated
78
+ * region; omitted by contexts built outside the place phase, which then
79
+ * cap no caption.
80
+ */
81
+ axisColumns?: AxisColumns;
45
82
  bandScale: BandScale;
46
83
  entityLeftEdges: Map<string, number>;
47
84
  entityRightEdges: Map<string, number>;
85
+ /**
86
+ * Midpoint per MARKER (anchor or milestone), on the marker row.
87
+ * Dependency arrows from a marker start on its cut line at this `x`.
88
+ * Items are not in this map: their attach geometry is derived from
89
+ * `placedItems`.
90
+ */
48
91
  entityMidpoints: Map<string, Point>;
49
92
  /**
50
- * Visual edges for items (entries with a painted bar). Differs
51
- * from `entityLeftEdges`/`entityRightEdges` (logical column
52
- * boundaries) by `ITEM_INSET_PX` on each side so dependency
53
- * arrows attach to the painted bar edge instead of landing in
54
- * the inter-column gutter. Anchors and milestones are absent —
55
- * their attach geometry uses `(center.x, target.row.midY)` on
56
- * the cut line, computed inline by `buildDependencies`.
93
+ * The ids of the anchors and milestones this context's file declares.
94
+ * A milestone's slack or overrun arrow from one of them starts on its
95
+ * row in the marker band, which only the final pack knows, so
96
+ * placement records the marker instead of a y.
57
97
  */
58
- entityVisualLeftX: Map<string, number>;
59
- entityVisualRightX: Map<string, number>;
98
+ markerIds: ReadonlySet<string>;
60
99
  /**
61
- * Per-item exit point for `after:` dependency arrows leaving
62
- * this entity. Default = `(visualRight, midY)`. When the
63
- * caption spills past the bar's right edge (`textSpills`), the
64
- * exit drops to `(box.x + box.width / 2, box.y + box.height)`
65
- * — the bottom-middle of the progress strip — so the arrow
66
- * doesn't visually pierce the spilled title/meta text to the
67
- * right of the bar.
100
+ * Every placed item, keyed by its draw key (the explicit id, or the
101
+ * synthetic handle of an id-less item; see `syntheticItemKey`). The
102
+ * value is the same `PositionedItem` object the positioned model
103
+ * carries, so it always holds the item's FINAL box, however many
104
+ * times a retroactive row growth or a marker-band growth moved it
105
+ * down after placement. Dependency-arrow ports and slack-arrow attach
106
+ * points are derived from that box when the arrows are built (see
107
+ * `item-port-geometry.ts`), never captured as absolute coordinates
108
+ * while the item is placed.
68
109
  */
69
- itemArrowSource: Map<string, Point>;
110
+ placedItems: Map<string, PositionedItem>;
70
111
  /**
71
112
  * Flow key for each item, used to dedupe milestone slack arrows.
72
113
  * A "flow" is the deepest enclosing single-track container —
@@ -84,15 +125,6 @@ export interface LayoutContext {
84
125
  * value to populate `itemFlowKey`.
85
126
  */
86
127
  currentFlowKey: string;
87
- /**
88
- * Y coordinate where milestone slack arrows attach for each item id.
89
- * Defaults to the item's row midpoint; when an item's caption spills
90
- * past the bar's right edge, drops to the progress-strip's vertical
91
- * center (`box.y + box.height - PROGRESS_STRIP_HEIGHT_PX / 2`) so the
92
- * arrow stays clear of the spilled title/meta line and visually
93
- * aligns with the bottom-edge progress bar instead.
94
- */
95
- itemSlackAttachY: Map<string, number>;
96
128
  /**
97
129
  * Horizontal arrow corridors that the swimlane row-packer must avoid.
98
130
  * Empty during the first layout pass; populated from the first
@@ -102,12 +134,19 @@ export interface LayoutContext {
102
134
  */
103
135
  slackCorridors: SlackCorridor[];
104
136
  /**
105
- * Pre-computed marker-row placement (row index + label box + side)
106
- * for every anchor and date-pinned milestone. After-only milestones
107
- * pack against this map at build time; date-pinned entries are
108
- * snapshot upstream so their (Y, label) survives swimlane reflows.
137
+ * Marker-row placement (row index + label box + side). While lanes
138
+ * are placed it holds a copy of the measure phase's pre-pack of every
139
+ * date-pinned anchor and milestone; finalize then replaces it with the
140
+ * final pack (f5), which adds after-only milestones and the calendar
141
+ * runs, before milestones are positioned (f6) and anchors built (f10).
109
142
  */
110
143
  markerRowPlacements: Map<string, MarkerRowPlacement>;
144
+ /**
145
+ * The chart's top. Placement lays the chart out in local coordinates,
146
+ * with the top at 0; finalize translates every placed y once, by the
147
+ * final top, when the header rows above it stop growing (f7), and
148
+ * sets this to that top. A region's context keeps its local value.
149
+ */
111
150
  chartTopY: number;
112
151
  chartBottomY: number;
113
152
  /**
@@ -119,7 +158,6 @@ export interface LayoutContext {
119
158
  * to thread the entire timeline strip.
120
159
  */
121
160
  swimlaneBottomY: number;
122
- chartRightX: number;
123
161
  /**
124
162
  * Monotonic counters for id-less `parallel` / `group` blocks. Each
125
163
  * swimlane-loop pass resets both to zero; blocks without an explicit
@@ -128,24 +166,50 @@ export interface LayoutContext {
128
166
  */
129
167
  nextParallelId: number;
130
168
  nextGroupId: number;
169
+ /**
170
+ * Wave barrier state (specs/waves.md §8.4), shared by the main lanes
171
+ * and every isolated region's context. Undefined when the roadmap
172
+ * declares no waves.
173
+ */
174
+ waves?: WaveLayoutState;
175
+ }
176
+ /** The per-file half of a context: the root file, or an isolated region. */
177
+ export interface ContextSource {
178
+ config: Pick<ResolvedConfig, 'styles' | 'defaults' | 'symbols'>;
179
+ content: Pick<ResolvedContent, 'sizes' | 'labels' | 'teams' | 'persons' | 'anchors' | 'milestones'>;
131
180
  }
132
181
  /**
133
- * Bundle of layout-internal helper callbacks injected from `layout.ts`
134
- * into the per-entity Renderable nodes. Keeping the helpers in
135
- * `layout.ts` (rather than splitting them across many tiny files) means
136
- * the nodes stay small and importable without a runtime cycle: they
137
- * receive the helpers at construction time via this struct.
182
+ * Build a `LayoutContext` for the root file or for an isolated region.
183
+ * `chart` passes the chart extents through unchanged: the root sets
184
+ * `chartTopY` to the local top 0 with both bottoms at 0, a region sets all
185
+ * three y fields to its inner start. The canvas width is not part of a
186
+ * context: placement never reads it (finalize owns the `CanvasExtent`).
187
+ * A region passes its own footnote index, numbered on after the host's,
188
+ * and no marker placements. The caller seeds
189
+ * the wave edges.
190
+ */
191
+ export declare function createLayoutContext(source: ContextSource, shared: {
192
+ theme: Theme;
193
+ cal: ReturnType<typeof resolveCalendar>;
194
+ schedule: RoadmapSchedule;
195
+ timeline: PositionedTimelineScale;
196
+ scale: TimeScale;
197
+ calendar: WorkingCalendar;
198
+ axisColumns?: AxisColumns;
199
+ bandScale: BandScale;
200
+ waves?: WaveLayoutState;
201
+ }, chart: Pick<LayoutContext, 'chartTopY' | 'chartBottomY' | 'swimlaneBottomY'>, init: {
202
+ footnotes?: FootnoteIndex;
203
+ markerRowPlacements?: Map<string, MarkerRowPlacement>;
204
+ }): LayoutContext;
205
+ /**
206
+ * The helpers the place phase injects into the nodes. Everything else a
207
+ * node needs it imports; `sequenceOne` (`nodes/sequence-one.ts`) stays
208
+ * injected because it dispatches to `GroupNode` and `ParallelNode`, which
209
+ * call it for their nested blocks: importing it there would form a cycle
210
+ * (specs/layout-phases.md §3.8, §8 decision 4).
138
211
  */
139
212
  export interface LayoutHelpers {
140
- sequenceItem: (child: ItemDeclaration, cursor: TrackCursor, ctx: LayoutContext, ownerOverride?: string) => PositionedItem;
141
213
  sequenceOne: (child: ItemDeclaration | GroupBlock | ParallelBlock, cursor: TrackCursor, ctx: LayoutContext) => PositionedTrackChild;
142
- resolveChildStart: (props: EntityProperty[], seqDefault: number, laneLeftX: number, ctx: LayoutContext) => number;
143
- newCursor: (x: number, y: number) => TrackCursor;
144
- estimateTextWidth: (text: string, fontSize: number) => number;
145
- /** Predict the extra height an item's wrapped label-chip rows will
146
- * add, so callers can size the row pitch BEFORE handing off to
147
- * `sequenceItem`. Returns 0 when the item's labels all fit on a
148
- * single chip row. */
149
- predictItemChipExtraHeight: (item: ItemDeclaration, ctx: LayoutContext) => number;
150
214
  }
151
215
  //# sourceMappingURL=layout-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-context.d.ts","sourceRoot":"","sources":["../src/layout-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout-context.d.ts","sourceRoot":"","sources":["../src/layout-context.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,KAAK,UAAU,EACf,KAAK,eAAe,EAEpB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACvB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,KAAK,eAAe,EAAgB,MAAM,eAAe,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EACR,kBAAkB,EAClB,KAAK,EACL,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,iEAAiE;AACjE,MAAM,WAAW,WAAW;IACxB;;;;;OAKG;IACH,CAAC,EAAE,MAAM,CAAC;IACV;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,CAAC,EAAE,MAAM,CAAC;IACV,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW,CAE3D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,CAQnF;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACtC,kEAAkE;IAClE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACpC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,eAAe,EAAE,iBAAiB,CAAC,CAAC;IAChE;;;;;OAKG;IACH,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACxC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,sEAAsE;IACtE,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrC,QAAQ,EAAE,uBAAuB,CAAC;IAClC,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC;;;;;OAKG;IACH,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACpC;;;;;OAKG;IACH,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACzC;;;;;;;OAOG;IACH,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC;;;;;;OAMG;IACH,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACrD;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;CAC3B;AAoBD,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC,CAAC;IAChE,OAAO,EAAE,IAAI,CACT,eAAe,EACf,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CACtE,CAAC;CACL;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE;IACJ,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IACxC,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,uBAAuB,CAAC;IAClC,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,eAAe,CAAC;CAC3B,EACD,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,cAAc,GAAG,iBAAiB,CAAC,EAC5E,IAAI,EAAE;IACF,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CACzD,GACF,aAAa,CA4Cf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,CACT,KAAK,EAAE,eAAe,GAAG,UAAU,GAAG,aAAa,EACnD,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,aAAa,KACjB,oBAAoB,CAAC;CAC7B"}
@@ -1,8 +1,99 @@
1
- // Layout context — shared internal types used by `layout.ts` and the
2
- // node files under `nodes/`. Extracted so per-entity nodes (e.g.
3
- // `swimlane-node.ts`) can type their inputs without forcing a circular
4
- // import on the production composition root in `layout.ts`.
1
+ // Layout context — shared internal types used by the layout phases
2
+ // (`phases/`) and the node files under `nodes/`. Extracted so per-entity
3
+ // nodes (e.g. `swimlane-node.ts`) can type their inputs without importing
4
+ // the phases that drive them.
5
+ import { isTeamDeclaration, } from '@nowline/core';
6
+ import { resolveSizes } from './calendar.js';
5
7
  export function newCursor(x, y) {
6
- return { x, y, height: 0, maxX: x };
8
+ return { x, startX: x, y, height: 0 };
9
+ }
10
+ /**
11
+ * The working-day duration the day schedule gave `item`. Every item engine A
12
+ * lays out is in `schedule.byNode` (the main lanes and the first-level
13
+ * isolated regions it draws), so a miss is an invariant violation, a
14
+ * schedule built for another roadmap or a walker that skipped a node, and
15
+ * throws instead of falling back to a second derivation that could drift.
16
+ */
17
+ export function scheduledItemDays(ctx, item) {
18
+ const scheduled = ctx.schedule.byNode.get(item);
19
+ if (!scheduled) {
20
+ throw new Error(`layout: item "${item.name ?? item.title ?? '(unnamed)'}" is not in the day schedule`);
21
+ }
22
+ return scheduled.days;
23
+ }
24
+ /**
25
+ * `teams` plus every team nested in one of them, so an `owner:` naming a
26
+ * nested team resolves to its title. The resolved content keys only the
27
+ * file's top-level declarations. A top-level id wins over a nested one.
28
+ */
29
+ function withNestedTeams(teams) {
30
+ const out = new Map(teams);
31
+ const visit = (team) => {
32
+ for (const member of team.content) {
33
+ if (!isTeamDeclaration(member))
34
+ continue;
35
+ if (member.name && !out.has(member.name))
36
+ out.set(member.name, member);
37
+ visit(member);
38
+ }
39
+ };
40
+ for (const team of teams.values())
41
+ visit(team);
42
+ return out;
43
+ }
44
+ /**
45
+ * Build a `LayoutContext` for the root file or for an isolated region.
46
+ * `chart` passes the chart extents through unchanged: the root sets
47
+ * `chartTopY` to the local top 0 with both bottoms at 0, a region sets all
48
+ * three y fields to its inner start. The canvas width is not part of a
49
+ * context: placement never reads it (finalize owns the `CanvasExtent`).
50
+ * A region passes its own footnote index, numbered on after the host's,
51
+ * and no marker placements. The caller seeds
52
+ * the wave edges.
53
+ */
54
+ export function createLayoutContext(source, shared, chart, init) {
55
+ return {
56
+ cal: shared.cal,
57
+ schedule: shared.schedule,
58
+ styleCtx: {
59
+ theme: shared.theme,
60
+ styles: source.config.styles,
61
+ defaults: source.config.defaults,
62
+ labels: source.content.labels,
63
+ },
64
+ // Each file declares its own sizes, resolved under the host's
65
+ // calendar so a region's sized items render at the host's
66
+ // pixels-per-day scale.
67
+ sizes: resolveSizes(source.content.sizes, shared.cal),
68
+ labels: source.content.labels,
69
+ teams: withNestedTeams(source.content.teams),
70
+ persons: source.content.persons,
71
+ symbols: source.config.symbols,
72
+ footnoteIndex: init.footnotes?.index ?? new Map(),
73
+ footnoteHosts: init.footnotes?.hosts ?? new Map(),
74
+ timeline: shared.timeline,
75
+ scale: shared.scale,
76
+ calendar: shared.calendar,
77
+ ...(shared.axisColumns ? { axisColumns: shared.axisColumns } : {}),
78
+ bandScale: shared.bandScale,
79
+ entityLeftEdges: new Map(),
80
+ entityRightEdges: new Map(),
81
+ entityMidpoints: new Map(),
82
+ markerIds: new Set([...source.content.anchors.keys(), ...source.content.milestones.keys()]),
83
+ placedItems: new Map(),
84
+ itemFlowKey: new Map(),
85
+ currentFlowKey: '',
86
+ slackCorridors: [],
87
+ markerRowPlacements: init.markerRowPlacements ?? new Map(),
88
+ chartTopY: chart.chartTopY,
89
+ chartBottomY: chart.chartBottomY,
90
+ swimlaneBottomY: chart.swimlaneBottomY,
91
+ nextParallelId: 0,
92
+ nextGroupId: 0,
93
+ // Wave floors are dates projected with the unclamped scale
94
+ // (specs/waves.md §5.1); a region shares the host's wave state
95
+ // (§8.4) so its lanes are floored and accumulate into the same pass.
96
+ ...(shared.waves ? { waves: shared.waves } : {}),
97
+ };
7
98
  }
8
99
  //# sourceMappingURL=layout-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-context.js","sourceRoot":"","sources":["../src/layout-context.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,iEAAiE;AACjE,uEAAuE;AACvE,4DAA4D;AAqC5D,MAAM,UAAU,SAAS,CAAC,CAAS,EAAE,CAAS;IAC1C,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"layout-context.js","sourceRoot":"","sources":["../src/layout-context.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"layout-insights.d.ts","sourceRoot":"","sources":["../src/layout-insights.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAM,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAER,iBAAiB,EAGpB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CAC9D;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAmGD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,oBAAyB,GACnC,aAAa,EAAE,CAwBjB"}
1
+ {"version":3,"file":"layout-insights.d.ts","sourceRoot":"","sources":["../src/layout-insights.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkB,KAAK,WAAW,EAAM,MAAM,eAAe,CAAC;AAErE,OAAO,KAAK,EAER,iBAAiB,EAGpB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CAC9D;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAwMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,oBAAyB,GACnC,aAAa,EAAE,CA8BjB"}
@@ -6,8 +6,18 @@ import { MIN_BAR_WIDTH_FOR_DOT_PX } from './item-bar-geometry.js';
6
6
  function formatIsoDate(d) {
7
7
  return d.toISOString().slice(0, 10);
8
8
  }
9
+ /**
10
+ * The name an insight echoes for an item: its id, else its title. A title
11
+ * can carry explicit `\n` line breaks (they paint as separate lines in the
12
+ * chart), but an insight message is one line of text, so each break run
13
+ * collapses to a single space.
14
+ */
9
15
  function itemLabel(item) {
10
- return item.id ?? item.title;
16
+ if (item.id !== undefined)
17
+ return item.id;
18
+ return /[\r\n]/.test(item.title)
19
+ ? item.title.replace(/\s*[\r\n]+\s*/g, ' ').trim()
20
+ : item.title;
11
21
  }
12
22
  function walkTrackChildren(children, visit) {
13
23
  for (const child of children) {
@@ -42,6 +52,15 @@ function collectItemInsights(item, locale, out) {
42
52
  if (item.hasOverflow) {
43
53
  out.push(makeInsight(locale, 'NL.I1003', 'info', { name, anchor: item.overflowAnchorId }, name));
44
54
  }
55
+ collectNonWorkingPinInsight(item, locale, out);
56
+ }
57
+ /** NL.I1008 (specs/working-calendar.md §6): an `after:` date on a non-working day set the start. */
58
+ function collectNonWorkingPinInsight(item, locale, out) {
59
+ const pin = item.nonWorkingPin;
60
+ if (!pin)
61
+ return;
62
+ const name = itemLabel(item);
63
+ out.push(makeInsight(locale, 'NL.I1008', 'info', { name, pin: pin.pin, key: pin.key, start: pin.start }, name));
45
64
  }
46
65
  function makeInsight(locale, code, severity, args, entityId) {
47
66
  return {
@@ -72,6 +91,53 @@ function collectSwimlaneInsights(lane, locale, out) {
72
91
  collectSwimlaneInsights(nested, locale, out);
73
92
  }
74
93
  }
94
+ /**
95
+ * Pin insights on the items of an isolated region's lanes. Region items
96
+ * carry only the non-working pin (NL.I1008) here; the other item and lane
97
+ * insights stay main-lane only.
98
+ */
99
+ function collectRegionItemInsights(lane, locale, out) {
100
+ walkTrackChildren(lane.children, (item) => {
101
+ collectNonWorkingPinInsight(item, locale, out);
102
+ });
103
+ for (const nested of lane.nested) {
104
+ collectRegionItemInsights(nested, locale, out);
105
+ }
106
+ }
107
+ /**
108
+ * Roadmap-level wave insights (specs/waves.md WV16-WV18): the barrier
109
+ * driver's pass cap, empty waves (once per roadmap), and dated milestones a
110
+ * wave overruns. No-ops without waves.
111
+ */
112
+ function collectWaveInsights(layout, locale, out) {
113
+ if (layout.waveSolve?.capped) {
114
+ out.push(makeInsight(locale, 'NL.W1002', 'warning', { passes: layout.waveSolve.passes }));
115
+ }
116
+ const waves = layout.waves ?? [];
117
+ const empty = waves.filter((w) => w.empty).map((w) => w.id);
118
+ if (empty.length > 0) {
119
+ // One consolidated message: the empty waves are not drawn (§9.1).
120
+ const args = { names: empty };
121
+ out.push(makeInsight(locale, 'NL.I1006', 'info', args, empty.length === 1 ? empty[0] : undefined));
122
+ }
123
+ for (const m of layout.milestones) {
124
+ // Only dated milestones get `overrunByWave`, and each carries its
125
+ // own date as `overrunDate`: x cannot give it back, since a hidden
126
+ // day shares the next working day's x.
127
+ if (m.overrunByWave === undefined || m.overrunDate === undefined)
128
+ continue;
129
+ const wave = waves.find((w) => w.id === m.overrunByWave);
130
+ if (!wave)
131
+ continue;
132
+ const name = m.id ?? m.title;
133
+ out.push(makeInsight(locale, 'NL.I1007', 'info', {
134
+ name,
135
+ date: m.overrunDate,
136
+ wave: wave.id,
137
+ end: formatIsoDate(wave.endDate),
138
+ }, name));
139
+ }
140
+ }
75
141
  /**
76
142
  * Collect layout-derived insights from a positioned roadmap. These describe
77
143
  * observable reflow consequences (caption spill, lane packing, etc.), not
@@ -83,6 +149,12 @@ export function collectLayoutInsights(layout, context = {}) {
83
149
  for (const lane of layout.swimlanes) {
84
150
  collectSwimlaneInsights(lane, locale, out);
85
151
  }
152
+ for (const region of layout.includes) {
153
+ for (const lane of region.nestedSwimlanes) {
154
+ collectRegionItemInsights(lane, locale, out);
155
+ }
156
+ }
157
+ collectWaveInsights(layout, locale, out);
86
158
  if (context.today) {
87
159
  const today = context.today;
88
160
  const start = layout.timeline.startDate;
@@ -1 +1 @@
1
- {"version":3,"file":"layout-insights.js","sourceRoot":"","sources":["../src/layout-insights.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout-insights.js","sourceRoot":"","sources":["../src/layout-insights.ts"],"names":[],"mappings":"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"}
package/dist/layout.d.ts CHANGED
@@ -1,9 +1,19 @@
1
1
  import type { NowlineFile, ResolveResult } from '@nowline/core';
2
+ import type { LogoDimensions } from './header-logo.js';
3
+ import type { NonWorkingDisplay } from './non-working-display.js';
4
+ import { type RoadmapSchedule } from './schedule.js';
2
5
  import type { ThemeName } from './themes/index.js';
3
6
  import type { PositionedRoadmap } from './types.js';
4
7
  export interface LayoutOptions {
5
8
  theme?: ThemeName;
6
9
  today?: Date;
10
+ /**
11
+ * Best-effort maximum canvas width in px. Unset (the default) sizes the
12
+ * canvas to its content. When the content is wider, pixels-per-day
13
+ * shrinks to fit, down to `MIN_PIXELS_PER_DAY`; spilled captions and
14
+ * run labels can still widen the canvas past it. See
15
+ * `specs/rendering.md` § Canvas width.
16
+ */
7
17
  width?: number;
8
18
  /**
9
19
  * BCP-47 tag controlling axis labels, the now-pill string, and the
@@ -12,6 +22,31 @@ export interface LayoutOptions {
12
22
  * then to `en-US`. See `specs/localization.md`.
13
23
  */
14
24
  locale?: string;
25
+ /**
26
+ * How a calendar's non-working days are drawn (specs/working-calendar.md
27
+ * §4.2). Overrides the file's `default roadmap non-working:` key; when
28
+ * undefined the key applies, then `hide`.
29
+ */
30
+ nonWorking?: NonWorkingDisplay;
31
+ /**
32
+ * Intrinsic size of the roadmap's `logo:` asset, read by the caller
33
+ * before layout (`loadLogo` in @nowline/renderer). Layout scales it to
34
+ * the `logo-size:` slot inside the header card. Leave it undefined when
35
+ * the file declares no logo or the asset could not be loaded: the
36
+ * header then lays out as if no logo were declared.
37
+ */
38
+ logo?: LogoDimensions;
39
+ /**
40
+ * A day schedule the caller already built for this roadmap
41
+ * (`scheduleRoadmap`, with the wave plan as `schedule.plan`). Layout
42
+ * reuses it when `schedule.resolved` is the very `ResolveResult` passed
43
+ * to `layoutRoadmap`, so a staging step that builds the plan and the
44
+ * schedule once hands them on (specs/scheduler-unification.md §3.6).
45
+ * A schedule built from another `ResolveResult` is ignored and rebuilt.
46
+ * Build it with the same `today` as this call's `today`: the window and
47
+ * the default start date come from it.
48
+ */
49
+ schedule?: RoadmapSchedule;
15
50
  }
16
51
  export type LayoutResult = PositionedRoadmap;
17
52
  export declare function layoutRoadmap(file: NowlineFile, resolved: ResolveResult, options?: LayoutOptions): LayoutResult;
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKR,WAAW,EAEX,aAAa,EAEhB,MAAM,eAAe,CAAC;AA2DvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAanD,OAAO,KAAK,EAYR,iBAAiB,EAIpB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,aAAa;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC;AA44C7C,wBAAgB,aAAa,CACzB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,aAAkB,GAC5B,YAAY,CAcd"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,KAAK,eAAe,EAAmB,MAAM,eAAe,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC;AAE7C,wBAAgB,aAAa,CACzB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,aAAkB,GAC5B,YAAY,CAed"}