@nowline/layout 0.8.6 → 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.
- package/dist/axis-columns.d.ts +70 -0
- package/dist/axis-columns.d.ts.map +1 -0
- package/dist/axis-columns.js +104 -0
- package/dist/axis-columns.js.map +1 -0
- package/dist/calendar-resolver.d.ts +27 -0
- package/dist/calendar-resolver.d.ts.map +1 -0
- package/dist/calendar-resolver.js +132 -0
- package/dist/calendar-resolver.js.map +1 -0
- package/dist/calendar.d.ts +0 -19
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +4 -44
- package/dist/calendar.js.map +1 -1
- package/dist/canvas-width.d.ts +23 -0
- package/dist/canvas-width.d.ts.map +1 -0
- package/dist/canvas-width.js +26 -0
- package/dist/canvas-width.js.map +1 -0
- package/dist/capacity.d.ts +28 -0
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +64 -29
- package/dist/capacity.js.map +1 -1
- package/dist/chart-translation.d.ts +22 -0
- package/dist/chart-translation.d.ts.map +1 -0
- package/dist/chart-translation.js +83 -0
- package/dist/chart-translation.js.map +1 -0
- package/dist/container-header-geometry.d.ts +64 -0
- package/dist/container-header-geometry.d.ts.map +1 -0
- package/dist/container-header-geometry.js +89 -0
- package/dist/container-header-geometry.js.map +1 -0
- package/dist/dsl-utils.d.ts +3 -4
- package/dist/dsl-utils.d.ts.map +1 -1
- package/dist/dsl-utils.js +8 -25
- package/dist/dsl-utils.js.map +1 -1
- package/dist/edge-routing.d.ts +69 -78
- package/dist/edge-routing.d.ts.map +1 -1
- package/dist/edge-routing.js +271 -401
- package/dist/edge-routing.js.map +1 -1
- package/dist/frame-tab-geometry.d.ts +24 -14
- package/dist/frame-tab-geometry.d.ts.map +1 -1
- package/dist/frame-tab-geometry.js +69 -23
- package/dist/frame-tab-geometry.js.map +1 -1
- package/dist/header-card-geometry.d.ts +12 -0
- package/dist/header-card-geometry.d.ts.map +1 -1
- package/dist/header-card-geometry.js +14 -2
- package/dist/header-card-geometry.js.map +1 -1
- package/dist/header-logo.d.ts +28 -0
- package/dist/header-logo.d.ts.map +1 -0
- package/dist/header-logo.js +51 -0
- package/dist/header-logo.js.map +1 -0
- package/dist/i18n.d.ts +11 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +11 -1
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +20 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/inline-date-pin-geometry.d.ts +19 -11
- package/dist/inline-date-pin-geometry.d.ts.map +1 -1
- package/dist/inline-date-pin-geometry.js +45 -46
- package/dist/inline-date-pin-geometry.js.map +1 -1
- package/dist/item-bar-geometry.d.ts +192 -4
- package/dist/item-bar-geometry.d.ts.map +1 -1
- package/dist/item-bar-geometry.js +258 -5
- package/dist/item-bar-geometry.js.map +1 -1
- package/dist/item-port-geometry.d.ts +13 -0
- package/dist/item-port-geometry.d.ts.map +1 -0
- package/dist/item-port-geometry.js +63 -0
- package/dist/item-port-geometry.js.map +1 -0
- package/dist/layout-context.d.ts +115 -51
- package/dist/layout-context.d.ts.map +1 -1
- package/dist/layout-context.js +96 -5
- package/dist/layout-context.js.map +1 -1
- package/dist/layout-insights.d.ts.map +1 -1
- package/dist/layout-insights.js +73 -1
- package/dist/layout-insights.js.map +1 -1
- package/dist/layout.d.ts +35 -0
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +18 -1315
- package/dist/layout.js.map +1 -1
- package/dist/nodes/anchor-node.d.ts.map +1 -1
- package/dist/nodes/anchor-node.js +11 -4
- package/dist/nodes/anchor-node.js.map +1 -1
- package/dist/nodes/content-extent.d.ts +24 -0
- package/dist/nodes/content-extent.d.ts.map +1 -0
- package/dist/nodes/content-extent.js +100 -0
- package/dist/nodes/content-extent.js.map +1 -0
- package/dist/nodes/dependency-edges.d.ts +6 -0
- package/dist/nodes/dependency-edges.d.ts.map +1 -0
- package/dist/nodes/dependency-edges.js +148 -0
- package/dist/nodes/dependency-edges.js.map +1 -0
- package/dist/nodes/footnote-node.d.ts +24 -3
- package/dist/nodes/footnote-node.d.ts.map +1 -1
- package/dist/nodes/footnote-node.js +129 -25
- package/dist/nodes/footnote-node.js.map +1 -1
- package/dist/nodes/group-node.d.ts +10 -21
- package/dist/nodes/group-node.d.ts.map +1 -1
- package/dist/nodes/group-node.js +79 -152
- package/dist/nodes/group-node.js.map +1 -1
- package/dist/nodes/header-node.d.ts +56 -0
- package/dist/nodes/header-node.d.ts.map +1 -0
- package/dist/nodes/header-node.js +163 -0
- package/dist/nodes/header-node.js.map +1 -0
- package/dist/nodes/include-node.d.ts +22 -12
- package/dist/nodes/include-node.d.ts.map +1 -1
- package/dist/nodes/include-node.js +95 -62
- package/dist/nodes/include-node.js.map +1 -1
- package/dist/nodes/item-measure.d.ts +135 -0
- package/dist/nodes/item-measure.d.ts.map +1 -0
- package/dist/nodes/item-measure.js +514 -0
- package/dist/nodes/item-measure.js.map +1 -0
- package/dist/nodes/item-node.d.ts +162 -9
- package/dist/nodes/item-node.d.ts.map +1 -1
- package/dist/nodes/item-node.js +256 -69
- package/dist/nodes/item-node.js.map +1 -1
- package/dist/nodes/marker-band.d.ts +118 -0
- package/dist/nodes/marker-band.d.ts.map +1 -0
- package/dist/nodes/marker-band.js +303 -0
- package/dist/nodes/marker-band.js.map +1 -0
- package/dist/nodes/marker-geometry.js +1 -1
- package/dist/nodes/marker-geometry.js.map +1 -1
- package/dist/nodes/milestone-node.d.ts +112 -15
- package/dist/nodes/milestone-node.d.ts.map +1 -1
- package/dist/nodes/milestone-node.js +246 -95
- package/dist/nodes/milestone-node.js.map +1 -1
- package/dist/nodes/nowline-node.d.ts +8 -0
- package/dist/nodes/nowline-node.d.ts.map +1 -0
- package/dist/nodes/nowline-node.js +74 -0
- package/dist/nodes/nowline-node.js.map +1 -0
- package/dist/nodes/parallel-node.d.ts +7 -12
- package/dist/nodes/parallel-node.d.ts.map +1 -1
- package/dist/nodes/parallel-node.js +66 -30
- package/dist/nodes/parallel-node.js.map +1 -1
- package/dist/nodes/region-markers.d.ts +41 -0
- package/dist/nodes/region-markers.d.ts.map +1 -0
- package/dist/nodes/region-markers.js +130 -0
- package/dist/nodes/region-markers.js.map +1 -0
- package/dist/nodes/roadmap-node.d.ts +9 -72
- package/dist/nodes/roadmap-node.d.ts.map +1 -1
- package/dist/nodes/roadmap-node.js +38 -788
- package/dist/nodes/roadmap-node.js.map +1 -1
- package/dist/nodes/row-track.d.ts +33 -0
- package/dist/nodes/row-track.d.ts.map +1 -0
- package/dist/nodes/row-track.js +170 -0
- package/dist/nodes/row-track.js.map +1 -0
- package/dist/nodes/sequence-item.d.ts +25 -0
- package/dist/nodes/sequence-item.d.ts.map +1 -0
- package/dist/nodes/sequence-item.js +396 -0
- package/dist/nodes/sequence-item.js.map +1 -0
- package/dist/nodes/sequence-one.d.ts +5 -0
- package/dist/nodes/sequence-one.d.ts.map +1 -0
- package/dist/nodes/sequence-one.js +26 -0
- package/dist/nodes/sequence-one.js.map +1 -0
- package/dist/nodes/swimlane-node.d.ts +5 -17
- package/dist/nodes/swimlane-node.d.ts.map +1 -1
- package/dist/nodes/swimlane-node.js +62 -145
- package/dist/nodes/swimlane-node.js.map +1 -1
- package/dist/nodes/wave-node.d.ts +52 -0
- package/dist/nodes/wave-node.d.ts.map +1 -0
- package/dist/nodes/wave-node.js +483 -0
- package/dist/nodes/wave-node.js.map +1 -0
- package/dist/non-working-display.d.ts +14 -0
- package/dist/non-working-display.d.ts.map +1 -0
- package/dist/non-working-display.js +28 -0
- package/dist/non-working-display.js.map +1 -0
- package/dist/phases/date-window.d.ts +48 -0
- package/dist/phases/date-window.d.ts.map +1 -0
- package/dist/phases/date-window.js +130 -0
- package/dist/phases/date-window.js.map +1 -0
- package/dist/phases/finalize.d.ts +198 -0
- package/dist/phases/finalize.d.ts.map +1 -0
- package/dist/phases/finalize.js +1058 -0
- package/dist/phases/finalize.js.map +1 -0
- package/dist/phases/measure.d.ts +77 -0
- package/dist/phases/measure.d.ts.map +1 -0
- package/dist/phases/measure.js +222 -0
- package/dist/phases/measure.js.map +1 -0
- package/dist/phases/place.d.ts +28 -0
- package/dist/phases/place.d.ts.map +1 -0
- package/dist/phases/place.js +225 -0
- package/dist/phases/place.js.map +1 -0
- package/dist/renderable.d.ts.map +1 -1
- package/dist/renderable.js +23 -3
- package/dist/renderable.js.map +1 -1
- package/dist/resolve-today.d.ts +11 -1
- package/dist/resolve-today.d.ts.map +1 -1
- package/dist/resolve-today.js +26 -12
- package/dist/resolve-today.js.map +1 -1
- package/dist/row-packer.d.ts +42 -16
- package/dist/row-packer.d.ts.map +1 -1
- package/dist/row-packer.js +51 -78
- package/dist/row-packer.js.map +1 -1
- package/dist/schedule.d.ts +58 -1
- package/dist/schedule.d.ts.map +1 -1
- package/dist/schedule.js +280 -106
- package/dist/schedule.js.map +1 -1
- package/dist/start-rules.d.ts +27 -0
- package/dist/start-rules.d.ts.map +1 -0
- package/dist/start-rules.js +91 -0
- package/dist/start-rules.js.map +1 -0
- package/dist/start-terms.d.ts +23 -0
- package/dist/start-terms.d.ts.map +1 -0
- package/dist/start-terms.js +27 -0
- package/dist/start-terms.js.map +1 -0
- package/dist/status-dot.d.ts +46 -0
- package/dist/status-dot.d.ts.map +1 -0
- package/dist/status-dot.js +78 -0
- package/dist/status-dot.js.map +1 -0
- package/dist/style-resolution.d.ts.map +1 -1
- package/dist/style-resolution.js +23 -43
- package/dist/style-resolution.js.map +1 -1
- package/dist/text-measure.d.ts +28 -0
- package/dist/text-measure.d.ts.map +1 -0
- package/dist/text-measure.js +70 -0
- package/dist/text-measure.js.map +1 -0
- package/dist/themes/contrast.d.ts +4 -0
- package/dist/themes/contrast.d.ts.map +1 -0
- package/dist/themes/contrast.js +32 -0
- package/dist/themes/contrast.js.map +1 -0
- package/dist/themes/dark.d.ts.map +1 -1
- package/dist/themes/dark.js +28 -1
- package/dist/themes/dark.js.map +1 -1
- package/dist/themes/grayscale.d.ts.map +1 -1
- package/dist/themes/grayscale.js +28 -1
- package/dist/themes/grayscale.js.map +1 -1
- package/dist/themes/index.d.ts +4 -11
- package/dist/themes/index.d.ts.map +1 -1
- package/dist/themes/index.js +6 -4
- package/dist/themes/index.js.map +1 -1
- package/dist/themes/light.d.ts.map +1 -1
- package/dist/themes/light.js +28 -1
- package/dist/themes/light.js.map +1 -1
- package/dist/themes/shape.d.ts +31 -0
- package/dist/themes/shape.d.ts.map +1 -1
- package/dist/themes/shared.d.ts +44 -50
- package/dist/themes/shared.d.ts.map +1 -1
- package/dist/themes/shared.js +79 -83
- package/dist/themes/shared.js.map +1 -1
- package/dist/time-scale.d.ts +42 -6
- package/dist/time-scale.d.ts.map +1 -1
- package/dist/time-scale.js +109 -17
- package/dist/time-scale.js.map +1 -1
- package/dist/types.d.ts +528 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/view-preset.d.ts +61 -6
- package/dist/view-preset.d.ts.map +1 -1
- package/dist/view-preset.js +439 -24
- package/dist/view-preset.js.map +1 -1
- package/dist/wave-barrier.d.ts +107 -0
- package/dist/wave-barrier.d.ts.map +1 -0
- package/dist/wave-barrier.js +174 -0
- package/dist/wave-barrier.js.map +1 -0
- package/dist/wave-hatch.d.ts +4 -0
- package/dist/wave-hatch.d.ts.map +1 -0
- package/dist/wave-hatch.js +21 -0
- package/dist/wave-hatch.js.map +1 -0
- package/dist/wave-layout.d.ts +99 -0
- package/dist/wave-layout.d.ts.map +1 -0
- package/dist/wave-layout.js +130 -0
- package/dist/wave-layout.js.map +1 -0
- package/dist/working-calendar.d.ts +128 -4
- package/dist/working-calendar.d.ts.map +1 -1
- package/dist/working-calendar.js +725 -51
- package/dist/working-calendar.js.map +1 -1
- package/dist/working-span.d.ts +11 -0
- package/dist/working-span.d.ts.map +1 -0
- package/dist/working-span.js +18 -0
- package/dist/working-span.js.map +1 -0
- package/package.json +4 -4
- package/src/axis-columns.ts +140 -0
- package/src/calendar-resolver.ts +161 -0
- package/src/calendar.ts +4 -45
- package/src/canvas-width.ts +36 -0
- package/src/capacity.ts +71 -30
- package/src/chart-translation.ts +88 -0
- package/src/container-header-geometry.ts +116 -0
- package/src/dsl-utils.ts +8 -26
- package/src/edge-routing.ts +347 -491
- package/src/frame-tab-geometry.ts +78 -25
- package/src/header-card-geometry.ts +17 -2
- package/src/header-logo.ts +67 -0
- package/src/i18n.ts +22 -1
- package/src/index.ts +97 -12
- package/src/inline-date-pin-geometry.ts +55 -58
- package/src/item-bar-geometry.ts +341 -5
- package/src/item-port-geometry.ts +69 -0
- package/src/layout-context.ts +210 -72
- package/src/layout-insights.ts +109 -2
- package/src/layout.ts +57 -1530
- package/src/nodes/anchor-node.ts +11 -4
- package/src/nodes/content-extent.ts +107 -0
- package/src/nodes/dependency-edges.ts +171 -0
- package/src/nodes/footnote-node.ts +171 -31
- package/src/nodes/group-node.ts +92 -214
- package/src/nodes/header-node.ts +255 -0
- package/src/nodes/include-node.ts +124 -110
- package/src/nodes/item-measure.ts +723 -0
- package/src/nodes/item-node.ts +358 -80
- package/src/nodes/marker-band.ts +406 -0
- package/src/nodes/marker-geometry.ts +1 -1
- package/src/nodes/milestone-node.ts +321 -136
- package/src/nodes/nowline-node.ts +87 -0
- package/src/nodes/parallel-node.ts +69 -38
- package/src/nodes/region-markers.ts +194 -0
- package/src/nodes/roadmap-node.ts +46 -950
- package/src/nodes/row-track.ts +217 -0
- package/src/nodes/sequence-item.ts +433 -0
- package/src/nodes/sequence-one.ts +40 -0
- package/src/nodes/swimlane-node.ts +66 -205
- package/src/nodes/wave-node.ts +609 -0
- package/src/non-working-display.ts +32 -0
- package/src/phases/date-window.ts +191 -0
- package/src/phases/finalize.ts +1303 -0
- package/src/phases/measure.ts +329 -0
- package/src/phases/place.ts +318 -0
- package/src/renderable.ts +23 -3
- package/src/resolve-today.ts +28 -25
- package/src/row-packer.ts +85 -84
- package/src/schedule.ts +362 -114
- package/src/start-rules.ts +113 -0
- package/src/start-terms.ts +38 -0
- package/src/status-dot.ts +81 -0
- package/src/style-resolution.ts +27 -57
- package/src/text-measure.ts +71 -0
- package/src/themes/contrast.ts +34 -0
- package/src/themes/dark.ts +28 -1
- package/src/themes/grayscale.ts +28 -1
- package/src/themes/index.ts +10 -7
- package/src/themes/light.ts +28 -1
- package/src/themes/shape.ts +38 -0
- package/src/themes/shared.ts +85 -93
- package/src/time-scale.ts +117 -19
- package/src/types.ts +529 -20
- package/src/view-preset.ts +520 -27
- package/src/wave-barrier.ts +242 -0
- package/src/wave-hatch.ts +25 -0
- package/src/wave-layout.ts +203 -0
- package/src/working-calendar.ts +875 -57
- package/src/working-span.ts +19 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { TimeScale } from './time-scale.js';
|
|
2
|
+
import { type ScaleUnit } from './view-preset.js';
|
|
3
|
+
import type { WorkingCalendar } from './working-calendar.js';
|
|
4
|
+
/** What `AxisColumns` reads from the date window. */
|
|
5
|
+
export interface AxisColumnsWindow {
|
|
6
|
+
startDate: Date;
|
|
7
|
+
/** Working days in the natural window. */
|
|
8
|
+
spanDays: number;
|
|
9
|
+
preset: {
|
|
10
|
+
unit: ScaleUnit;
|
|
11
|
+
};
|
|
12
|
+
calendar: WorkingCalendar;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* How far (px) past the axis end a spilled caption may run before it is
|
|
16
|
+
* truncated, when one column is narrower than this: about 20 characters of
|
|
17
|
+
* a 13 px title.
|
|
18
|
+
*/
|
|
19
|
+
export declare const CAPTION_OVERHANG_BUDGET_PX = 160;
|
|
20
|
+
export declare class AxisColumns {
|
|
21
|
+
private readonly scale;
|
|
22
|
+
private readonly startDate;
|
|
23
|
+
private readonly spanDays;
|
|
24
|
+
private readonly unit;
|
|
25
|
+
private readonly calendar;
|
|
26
|
+
/** `scale` is the natural window's scale, before f2 extends it. */
|
|
27
|
+
constructor(window: AxisColumnsWindow, scale: TimeScale);
|
|
28
|
+
/** True when `x` lies past the working-day index `days` (float noise aside). */
|
|
29
|
+
isPast(x: number, days: number): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The working-day index of the first column boundary at or after `x`
|
|
32
|
+
* (the rounding f2 applies to a content box).
|
|
33
|
+
*/
|
|
34
|
+
boundaryAtOrAfterX(x: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* The working-day index of the first column boundary at or after the
|
|
37
|
+
* working-day index `days`: `days` itself on a boundary, else the end
|
|
38
|
+
* of the partial column it falls in (an explicit `length:` can end the
|
|
39
|
+
* drawn axis mid-column).
|
|
40
|
+
*/
|
|
41
|
+
boundaryAtOrAfter(days: number): number;
|
|
42
|
+
/**
|
|
43
|
+
* The one column a spilled caption past the axis end `axisDays` may
|
|
44
|
+
* run into, as working-day indices: from the boundary at or after the
|
|
45
|
+
* axis end (the end of a partial last column) to the next boundary.
|
|
46
|
+
*/
|
|
47
|
+
captionColumn(axisDays: number): {
|
|
48
|
+
start: number;
|
|
49
|
+
end: number;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* The farthest working-day index a spilled caption past the axis end
|
|
53
|
+
* `axisDays` may reach: the end of the first column after the axis end
|
|
54
|
+
* (`captionColumn`), or further, whole columns at a time, while the
|
|
55
|
+
* overhang past the axis end stays within `CAPTION_OVERHANG_BUDGET_PX`.
|
|
56
|
+
*/
|
|
57
|
+
captionLimit(axisDays: number): number;
|
|
58
|
+
/** The column boundary one column after the boundary `days`. */
|
|
59
|
+
nextBoundary(days: number): number;
|
|
60
|
+
/** The x of the working-day index `days`, past the natural end too. */
|
|
61
|
+
xAt(days: number): number;
|
|
62
|
+
/**
|
|
63
|
+
* Where a spilled caption beside a bar ending at `barRightX` may end at
|
|
64
|
+
* most: the column boundary `captionLimit` gives past the axis end. The axis
|
|
65
|
+
* end is the natural one, or the boundary f2 grows it to for this bar
|
|
66
|
+
* when the bar itself runs past it.
|
|
67
|
+
*/
|
|
68
|
+
captionCapX(barRightX: number): number;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=axis-columns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axis-columns.d.ts","sourceRoot":"","sources":["../src/axis-columns.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,KAAK,SAAS,EAAyB,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,IAAI,CAAC;IAChB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IAC5B,QAAQ,EAAE,eAAe,CAAC;CAC7B;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAQ9C,qBAAa,WAAW;IAShB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAR1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAO;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAE3C,mEAAmE;IACnE,YACI,MAAM,EAAE,iBAAiB,EACR,KAAK,EAAE,SAAS,EAMpC;IAED,gFAAgF;IAChF,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvC;IAED;;;OAGG;IACH,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpC;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQtC;IAED;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAG9D;IAED;;;;;OAKG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUrC;IAED,gEAAgE;IAChE,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQjC;IAED,uEAAuE;IACvE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExB;IAED;;;;;OAKG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKrC;CACJ"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Axis columns — the date axis as a run of tick columns, read off the
|
|
2
|
+
// natural scale (specs/rendering.md § "Caption cap at the chart's end",
|
|
3
|
+
// specs/scheduler-unification.md §8 decision 12). A spilled caption that
|
|
4
|
+
// would run past the axis end may run on for whole columns while it stays
|
|
5
|
+
// within max(one column, CAPTION_OVERHANG_BUDGET_PX) of the axis end (of a
|
|
6
|
+
// partial last column's end, when an explicit `length:` ends the axis
|
|
7
|
+
// mid-column): the item measure truncates the title to `captionCapX`, and
|
|
8
|
+
// finalize step f2 (`extendTimeline`) grows the axis by the columns that
|
|
9
|
+
// hold it, labelled by the axis's usual rules. Both read `captionLimit`,
|
|
10
|
+
// so the cap and the extension agree.
|
|
11
|
+
import { tickBoundaryAtOrAfter } from './view-preset.js';
|
|
12
|
+
/**
|
|
13
|
+
* How far (px) past the axis end a spilled caption may run before it is
|
|
14
|
+
* truncated, when one column is narrower than this: about 20 characters of
|
|
15
|
+
* a 13 px title.
|
|
16
|
+
*/
|
|
17
|
+
export const CAPTION_OVERHANG_BUDGET_PX = 160;
|
|
18
|
+
/** Bounds the column walk in `captionLimit` (a day-scale axis has ~4 px columns). */
|
|
19
|
+
const MAX_CAPTION_COLUMNS = 64;
|
|
20
|
+
/** Days of float noise `isPast` ignores, as `tickBoundaryAtOrAfter` does. */
|
|
21
|
+
const PAST_TOLERANCE_DAYS = 1e-6;
|
|
22
|
+
export class AxisColumns {
|
|
23
|
+
scale;
|
|
24
|
+
startDate;
|
|
25
|
+
spanDays;
|
|
26
|
+
unit;
|
|
27
|
+
calendar;
|
|
28
|
+
/** `scale` is the natural window's scale, before f2 extends it. */
|
|
29
|
+
constructor(window, scale) {
|
|
30
|
+
this.scale = scale;
|
|
31
|
+
this.startDate = window.startDate;
|
|
32
|
+
this.spanDays = window.spanDays;
|
|
33
|
+
this.unit = window.preset.unit;
|
|
34
|
+
this.calendar = window.calendar;
|
|
35
|
+
}
|
|
36
|
+
/** True when `x` lies past the working-day index `days` (float noise aside). */
|
|
37
|
+
isPast(x, days) {
|
|
38
|
+
return this.scale.indexAtX(x) > days + PAST_TOLERANCE_DAYS;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The working-day index of the first column boundary at or after `x`
|
|
42
|
+
* (the rounding f2 applies to a content box).
|
|
43
|
+
*/
|
|
44
|
+
boundaryAtOrAfterX(x) {
|
|
45
|
+
return this.boundaryAtOrAfter(this.scale.indexAtX(x));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The working-day index of the first column boundary at or after the
|
|
49
|
+
* working-day index `days`: `days` itself on a boundary, else the end
|
|
50
|
+
* of the partial column it falls in (an explicit `length:` can end the
|
|
51
|
+
* drawn axis mid-column).
|
|
52
|
+
*/
|
|
53
|
+
boundaryAtOrAfter(days) {
|
|
54
|
+
return tickBoundaryAtOrAfter(this.startDate, days, this.unit, this.calendar.daysPerUnit(this.unit), this.calendar);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The one column a spilled caption past the axis end `axisDays` may
|
|
58
|
+
* run into, as working-day indices: from the boundary at or after the
|
|
59
|
+
* axis end (the end of a partial last column) to the next boundary.
|
|
60
|
+
*/
|
|
61
|
+
captionColumn(axisDays) {
|
|
62
|
+
const start = this.boundaryAtOrAfter(axisDays);
|
|
63
|
+
return { start, end: this.nextBoundary(start) };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The farthest working-day index a spilled caption past the axis end
|
|
67
|
+
* `axisDays` may reach: the end of the first column after the axis end
|
|
68
|
+
* (`captionColumn`), or further, whole columns at a time, while the
|
|
69
|
+
* overhang past the axis end stays within `CAPTION_OVERHANG_BUDGET_PX`.
|
|
70
|
+
*/
|
|
71
|
+
captionLimit(axisDays) {
|
|
72
|
+
const { start, end } = this.captionColumn(axisDays);
|
|
73
|
+
const startX = this.xAt(start);
|
|
74
|
+
let limit = end;
|
|
75
|
+
for (let i = 0; i < MAX_CAPTION_COLUMNS; i++) {
|
|
76
|
+
const next = this.nextBoundary(limit);
|
|
77
|
+
if (next <= limit || this.xAt(next) - startX > CAPTION_OVERHANG_BUDGET_PX)
|
|
78
|
+
break;
|
|
79
|
+
limit = next;
|
|
80
|
+
}
|
|
81
|
+
return limit;
|
|
82
|
+
}
|
|
83
|
+
/** The column boundary one column after the boundary `days`. */
|
|
84
|
+
nextBoundary(days) {
|
|
85
|
+
return tickBoundaryAtOrAfter(this.startDate, days + 0.5, this.unit, this.calendar.daysPerUnit(this.unit), this.calendar);
|
|
86
|
+
}
|
|
87
|
+
/** The x of the working-day index `days`, past the natural end too. */
|
|
88
|
+
xAt(days) {
|
|
89
|
+
return this.scale.forward(this.calendar.dateAtWorkingIndex(this.startDate, days));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Where a spilled caption beside a bar ending at `barRightX` may end at
|
|
93
|
+
* most: the column boundary `captionLimit` gives past the axis end. The axis
|
|
94
|
+
* end is the natural one, or the boundary f2 grows it to for this bar
|
|
95
|
+
* when the bar itself runs past it.
|
|
96
|
+
*/
|
|
97
|
+
captionCapX(barRightX) {
|
|
98
|
+
const axisDays = this.isPast(barRightX, this.spanDays)
|
|
99
|
+
? Math.max(this.spanDays, this.boundaryAtOrAfterX(barRightX))
|
|
100
|
+
: this.spanDays;
|
|
101
|
+
return this.xAt(this.captionLimit(axisDays));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=axis-columns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axis-columns.js","sourceRoot":"","sources":["../src/axis-columns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { NowlineFile, ResolveResult } from '@nowline/core';
|
|
2
|
+
import { type CalendarConfig } from './calendar.js';
|
|
3
|
+
import { type WorkingCalendar } from './working-calendar.js';
|
|
4
|
+
export interface ResolvedCalendar {
|
|
5
|
+
/** The preset or `calendar` block day counts. */
|
|
6
|
+
config: CalendarConfig;
|
|
7
|
+
/**
|
|
8
|
+
* The working calendar of the preset and the file's declarations (its
|
|
9
|
+
* own and its merged includes'). A `non-working` declaration named
|
|
10
|
+
* `weekend` replaces the preset's rules. Its `rules` are in a canonical
|
|
11
|
+
* order, so nothing downstream depends on file or include order.
|
|
12
|
+
*/
|
|
13
|
+
working: WorkingCalendar;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the calendar a roadmap declares (`calendar:` on the roadmap plus
|
|
17
|
+
* the `config` block's `calendar` section, business when it declares none)
|
|
18
|
+
* and the non-working days its declarations add or take away.
|
|
19
|
+
*
|
|
20
|
+
* A malformed declaration is left out (the validator reports it in the root
|
|
21
|
+
* file; includes are not validated). Rules that leave an unbounded stretch
|
|
22
|
+
* with no working day (an include that closes the whole week; the root file
|
|
23
|
+
* would have had NL.E0906) fall back to the preset calendar rather than
|
|
24
|
+
* failing layout or export.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveWorkingCalendar(file: NowlineFile, resolved: ResolveResult): ResolvedCalendar;
|
|
27
|
+
//# sourceMappingURL=calendar-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-resolver.d.ts","sourceRoot":"","sources":["../src/calendar-resolver.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAER,WAAW,EACX,aAAa,EAEhB,MAAM,eAAe,CAAC;AAMvB,OAAO,EAAE,KAAK,cAAc,EAAmB,MAAM,eAAe,CAAC;AACrE,OAAO,EAIH,KAAK,eAAe,EACvB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,gBAAgB;IAC7B,iDAAiD;IACjD,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,OAAO,EAAE,eAAe,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAClC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,aAAa,GACxB,gBAAgB,CASlB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// The file's calendar, resolved once for every consumer (specs/working-
|
|
2
|
+
// calendar.md §8): the layout, engine C and the three exporters read the
|
|
3
|
+
// same `CalendarConfig` (duration arithmetic) and `WorkingCalendar`
|
|
4
|
+
// (non-working days), so the chart and every export agree on what `1w` is.
|
|
5
|
+
//
|
|
6
|
+
// It is also the one place the file's `non-working` and `working`
|
|
7
|
+
// declarations (its own and its merged includes', specs/working-calendar.md
|
|
8
|
+
// §4) become `CalendarRule`s, so every consumer picks them up unchanged.
|
|
9
|
+
//
|
|
10
|
+
// It lives apart from `calendar.ts` because `working-calendar.ts` already
|
|
11
|
+
// imports values from there; building a `WorkingCalendar` in `calendar.ts`
|
|
12
|
+
// would close a value-import cycle.
|
|
13
|
+
import { classifyCalendarDeclaration, parseIsoDate, replacesPresetWeekend, } from '@nowline/core/internal';
|
|
14
|
+
import { resolveCalendar } from './calendar.js';
|
|
15
|
+
import { fromCalendarConfig, presetRules, } from './working-calendar.js';
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the calendar a roadmap declares (`calendar:` on the roadmap plus
|
|
18
|
+
* the `config` block's `calendar` section, business when it declares none)
|
|
19
|
+
* and the non-working days its declarations add or take away.
|
|
20
|
+
*
|
|
21
|
+
* A malformed declaration is left out (the validator reports it in the root
|
|
22
|
+
* file; includes are not validated). Rules that leave an unbounded stretch
|
|
23
|
+
* with no working day (an include that closes the whole week; the root file
|
|
24
|
+
* would have had NL.E0906) fall back to the preset calendar rather than
|
|
25
|
+
* failing layout or export.
|
|
26
|
+
*/
|
|
27
|
+
export function resolveWorkingCalendar(file, resolved) {
|
|
28
|
+
const config = resolveCalendar(file, resolved.config.calendar);
|
|
29
|
+
const rules = calendarRules(config, resolved.config.calendarDeclarations);
|
|
30
|
+
try {
|
|
31
|
+
return { config, working: fromCalendarConfig(config, rules) };
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (!(err instanceof RangeError))
|
|
35
|
+
throw err;
|
|
36
|
+
return { config, working: fromCalendarConfig(config) };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The preset's rules, unless a `non-working` declaration is named `weekend`
|
|
41
|
+
* (decision 14), plus one rule per well-formed declaration, in canonical
|
|
42
|
+
* order.
|
|
43
|
+
*/
|
|
44
|
+
function calendarRules(config, declarations) {
|
|
45
|
+
const rules = replacesPresetWeekend(declarations) ? [] : presetRules(config.mode);
|
|
46
|
+
for (const decl of declarations) {
|
|
47
|
+
const rule = declarationRule(decl);
|
|
48
|
+
if (rule)
|
|
49
|
+
rules.push(rule);
|
|
50
|
+
}
|
|
51
|
+
return rules.sort(compareRules);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The rule one declaration stands for, or undefined when core's classifier
|
|
55
|
+
* finds its shape or a value malformed. Only the first `date:`, `start:`,
|
|
56
|
+
* `end:` and `every:` count; any other key is the validator's NL.E0901 and
|
|
57
|
+
* changes nothing here.
|
|
58
|
+
*/
|
|
59
|
+
function declarationRule(decl) {
|
|
60
|
+
const facts = classifyCalendarDeclaration(decl);
|
|
61
|
+
if (!facts.wellFormed)
|
|
62
|
+
return undefined;
|
|
63
|
+
const rule = { working: decl.$type === 'WorkingDeclaration' };
|
|
64
|
+
if (decl.name)
|
|
65
|
+
rule.id = decl.name;
|
|
66
|
+
if (decl.title !== undefined)
|
|
67
|
+
rule.title = decl.title;
|
|
68
|
+
if (facts.dates)
|
|
69
|
+
rule.dates = facts.dates.map(utcDate);
|
|
70
|
+
if (facts.start)
|
|
71
|
+
rule.start = utcDate(facts.start);
|
|
72
|
+
if (facts.end)
|
|
73
|
+
rule.end = utcDate(facts.end);
|
|
74
|
+
if (facts.weekdays)
|
|
75
|
+
rule.every = new Set(facts.weekdays);
|
|
76
|
+
return rule;
|
|
77
|
+
}
|
|
78
|
+
/** A real `YYYY-MM-DD` the classifier already checked, at UTC midnight. */
|
|
79
|
+
function utcDate(iso) {
|
|
80
|
+
return parseIsoDate(iso);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Canonical rule order (decision 18): first date (none first), then title,
|
|
84
|
+
* id, `working`, the `every` mask, start and end, then the remaining dates.
|
|
85
|
+
* The engine breaks ties between titled runs by input order, so sorting
|
|
86
|
+
* here keeps `rules`, run titles and every downstream list independent of
|
|
87
|
+
* file and include order.
|
|
88
|
+
*/
|
|
89
|
+
function compareRules(a, b) {
|
|
90
|
+
return (compareOptional(firstDay(a), firstDay(b)) ||
|
|
91
|
+
compareOptional(a.title, b.title) ||
|
|
92
|
+
compareOptional(a.id, b.id) ||
|
|
93
|
+
Number(a.working) - Number(b.working) ||
|
|
94
|
+
compareOptional(everyMask(a), everyMask(b)) ||
|
|
95
|
+
compareOptional(a.start?.getTime(), b.start?.getTime()) ||
|
|
96
|
+
compareOptional(a.end?.getTime(), b.end?.getTime()) ||
|
|
97
|
+
compareDates(a.dates ?? [], b.dates ?? []));
|
|
98
|
+
}
|
|
99
|
+
/** The earliest date a rule names (its first `date:` or its `start:`); undefined for none. */
|
|
100
|
+
function firstDay(rule) {
|
|
101
|
+
if (rule.dates)
|
|
102
|
+
return Math.min(...rule.dates.map((date) => date.getTime()));
|
|
103
|
+
return rule.start?.getTime();
|
|
104
|
+
}
|
|
105
|
+
function everyMask(rule) {
|
|
106
|
+
if (!rule.every)
|
|
107
|
+
return undefined;
|
|
108
|
+
let mask = 0;
|
|
109
|
+
for (const weekday of rule.every)
|
|
110
|
+
mask |= 1 << weekday;
|
|
111
|
+
return mask;
|
|
112
|
+
}
|
|
113
|
+
/** Undefined sorts first; strings compare by code unit, never by locale. */
|
|
114
|
+
function compareOptional(a, b) {
|
|
115
|
+
if (a === b)
|
|
116
|
+
return 0;
|
|
117
|
+
if (a === undefined)
|
|
118
|
+
return -1;
|
|
119
|
+
if (b === undefined)
|
|
120
|
+
return 1;
|
|
121
|
+
return a < b ? -1 : 1;
|
|
122
|
+
}
|
|
123
|
+
function compareDates(a, b) {
|
|
124
|
+
const left = a.map((date) => date.getTime()).sort((x, y) => x - y);
|
|
125
|
+
const right = b.map((date) => date.getTime()).sort((x, y) => x - y);
|
|
126
|
+
for (let i = 0; i < Math.min(left.length, right.length); i++) {
|
|
127
|
+
if (left[i] !== right[i])
|
|
128
|
+
return left[i] - right[i];
|
|
129
|
+
}
|
|
130
|
+
return left.length - right.length;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=calendar-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-resolver.js","sourceRoot":"","sources":["../src/calendar-resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/calendar.d.ts
CHANGED
|
@@ -48,25 +48,6 @@ export declare function deriveItemDurationDays(props: EntityProperty[], sizes: M
|
|
|
48
48
|
* skip normalization safely.
|
|
49
49
|
*/
|
|
50
50
|
export declare function deriveTotalEffortDays(props: EntityProperty[], sizes: Map<string, ResolvedSize>, cal: CalendarConfig): number;
|
|
51
|
-
/**
|
|
52
|
-
* Format a calendar day count back into the largest unit literal that
|
|
53
|
-
* divides cleanly under the active calendar. Used by the meta line for
|
|
54
|
-
* sized items so the displayed duration reflects the *derived* calendar
|
|
55
|
-
* duration rather than the raw effort literal — `size:m capacity:5`
|
|
56
|
-
* with `effort:1w` paints a 1d bar and the meta should read `M 1d`,
|
|
57
|
-
* not `M 1w`.
|
|
58
|
-
*
|
|
59
|
-
* - Whole-unit folds happen in descending order (`y` → `q` → `m` →
|
|
60
|
-
* `w`); the first one that yields an integer wins so `5d` →
|
|
61
|
-
* `"1w"` and `22d` (business calendar) → `"1m"`.
|
|
62
|
-
* - Anything left over collapses to a `Nd` literal with up to two
|
|
63
|
-
* decimal places, trailing zeros trimmed (`"3d"`, `"1.5d"`,
|
|
64
|
-
* `"1.67d"`). Matches the `DURATION_LITERAL` shape the parser
|
|
65
|
-
* accepts so round-tripping through the renderer reads naturally.
|
|
66
|
-
* - `0` (or anything sub-1d) returns `"0d"` rather than an empty
|
|
67
|
-
* string so callers always get a renderable token.
|
|
68
|
-
*/
|
|
69
|
-
export declare function formatDurationDays(days: number, cal: CalendarConfig): string;
|
|
70
51
|
/**
|
|
71
52
|
* Build the layout's `Map<string, ResolvedSize>` once the calendar is
|
|
72
53
|
* known. Skips sizes whose `effort:` literal is missing or unparseable —
|
package/dist/calendar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../src/calendar.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../src/calendar.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAKjG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACvB;AAkBD,wBAAgB,eAAe,CAC3B,IAAI,EAAE,WAAW,EACjB,WAAW,EAAE,aAAa,GAAG,SAAS,GACvC,cAAc,CAoBhB;AAKD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,MAAM,CAkB1E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAChC,GAAG,EAAE,cAAc,GACpB,MAAM,CAIR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAChC,GAAG,EAAE,cAAc,GACpB,MAAM,CAUR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACjC,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAChC,GAAG,EAAE,cAAc,GACpB,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CACxB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACnC,GAAG,EAAE,cAAc,GACpB,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAgB3B;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,MAAM,CAGxD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAItD"}
|
package/dist/calendar.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// effort:<literal>` declaration whose effort literal is calendar-resolved
|
|
4
4
|
// once into a `ResolvedSize`. The calendar block controls how literal units
|
|
5
5
|
// translate into absolute days.
|
|
6
|
+
import { findProp } from '@nowline/core/internal';
|
|
6
7
|
import { parseCapacityValue } from './capacity.js';
|
|
7
8
|
import { propValue } from './dsl-utils.js';
|
|
8
9
|
const BUSINESS = {
|
|
@@ -20,7 +21,7 @@ const FULL = {
|
|
|
20
21
|
daysPerYear: 365,
|
|
21
22
|
};
|
|
22
23
|
export function resolveCalendar(file, customBlock) {
|
|
23
|
-
const calProp = file.roadmapDecl?.properties
|
|
24
|
+
const calProp = findProp(file.roadmapDecl?.properties ?? [], 'calendar');
|
|
24
25
|
const mode = calProp?.value ?? 'business';
|
|
25
26
|
if (mode === 'business')
|
|
26
27
|
return { ...BUSINESS };
|
|
@@ -28,7 +29,7 @@ export function resolveCalendar(file, customBlock) {
|
|
|
28
29
|
return { ...FULL };
|
|
29
30
|
if (customBlock) {
|
|
30
31
|
const get = (key, fallback) => {
|
|
31
|
-
const p = customBlock.properties
|
|
32
|
+
const p = findProp(customBlock.properties, key);
|
|
32
33
|
const n = p ? parseInt(p.value, 10) : NaN;
|
|
33
34
|
return Number.isFinite(n) && n > 0 ? n : fallback;
|
|
34
35
|
};
|
|
@@ -130,44 +131,6 @@ export function deriveTotalEffortDays(props, sizes, cal) {
|
|
|
130
131
|
}
|
|
131
132
|
return 0;
|
|
132
133
|
}
|
|
133
|
-
/**
|
|
134
|
-
* Format a calendar day count back into the largest unit literal that
|
|
135
|
-
* divides cleanly under the active calendar. Used by the meta line for
|
|
136
|
-
* sized items so the displayed duration reflects the *derived* calendar
|
|
137
|
-
* duration rather than the raw effort literal — `size:m capacity:5`
|
|
138
|
-
* with `effort:1w` paints a 1d bar and the meta should read `M 1d`,
|
|
139
|
-
* not `M 1w`.
|
|
140
|
-
*
|
|
141
|
-
* - Whole-unit folds happen in descending order (`y` → `q` → `m` →
|
|
142
|
-
* `w`); the first one that yields an integer wins so `5d` →
|
|
143
|
-
* `"1w"` and `22d` (business calendar) → `"1m"`.
|
|
144
|
-
* - Anything left over collapses to a `Nd` literal with up to two
|
|
145
|
-
* decimal places, trailing zeros trimmed (`"3d"`, `"1.5d"`,
|
|
146
|
-
* `"1.67d"`). Matches the `DURATION_LITERAL` shape the parser
|
|
147
|
-
* accepts so round-tripping through the renderer reads naturally.
|
|
148
|
-
* - `0` (or anything sub-1d) returns `"0d"` rather than an empty
|
|
149
|
-
* string so callers always get a renderable token.
|
|
150
|
-
*/
|
|
151
|
-
export function formatDurationDays(days, cal) {
|
|
152
|
-
const EPSILON = 1e-6;
|
|
153
|
-
const isWhole = (n) => n >= 1 && Math.abs(n - Math.round(n)) < EPSILON;
|
|
154
|
-
const folds = [
|
|
155
|
-
[cal.daysPerYear, 'y'],
|
|
156
|
-
[cal.daysPerQuarter, 'q'],
|
|
157
|
-
[cal.daysPerMonth, 'm'],
|
|
158
|
-
[cal.daysPerWeek, 'w'],
|
|
159
|
-
];
|
|
160
|
-
for (const [unitDays, suffix] of folds) {
|
|
161
|
-
const n = days / unitDays;
|
|
162
|
-
if (isWhole(n))
|
|
163
|
-
return `${Math.round(n)}${suffix}`;
|
|
164
|
-
}
|
|
165
|
-
if (Math.abs(days - Math.round(days)) < EPSILON) {
|
|
166
|
-
return `${Math.round(days)}d`;
|
|
167
|
-
}
|
|
168
|
-
// parseFloat strips trailing zeros: `1.50` → `1.5`, `1.67` → `1.67`.
|
|
169
|
-
return `${parseFloat(days.toFixed(2))}d`;
|
|
170
|
-
}
|
|
171
134
|
/**
|
|
172
135
|
* Build the layout's `Map<string, ResolvedSize>` once the calendar is
|
|
173
136
|
* known. Skips sizes whose `effort:` literal is missing or unparseable —
|
|
@@ -177,7 +140,7 @@ export function formatDurationDays(days, cal) {
|
|
|
177
140
|
export function resolveSizes(decls, cal) {
|
|
178
141
|
const out = new Map();
|
|
179
142
|
for (const [name, decl] of decls) {
|
|
180
|
-
const effortProp = decl.properties
|
|
143
|
+
const effortProp = findProp(decl.properties, 'effort');
|
|
181
144
|
const effortLiteral = effortProp?.value;
|
|
182
145
|
if (!effortLiteral)
|
|
183
146
|
continue;
|
|
@@ -193,9 +156,6 @@ export function resolveSizes(decls, cal) {
|
|
|
193
156
|
}
|
|
194
157
|
return out;
|
|
195
158
|
}
|
|
196
|
-
function stripColon(key) {
|
|
197
|
-
return key.endsWith(':') ? key.slice(0, -1) : key;
|
|
198
|
-
}
|
|
199
159
|
// Date arithmetic in day units. All coordinates are relative to the roadmap
|
|
200
160
|
// start date; today is computed in days since start.
|
|
201
161
|
export function daysBetween(from, to) {
|
package/dist/calendar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar.js","sourceRoot":"","sources":["../src/calendar.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,sEAAsE;AACtE,0EAA0E;AAC1E,4EAA4E;AAC5E,gCAAgC;
|
|
1
|
+
{"version":3,"file":"calendar.js","sourceRoot":"","sources":["../src/calendar.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,sEAAsE;AACtE,0EAA0E;AAC1E,4EAA4E;AAC5E,gCAAgC;AAGhC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAa3C,MAAM,QAAQ,GAAmB;IAC7B,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,CAAC;IACd,YAAY,EAAE,EAAE;IAChB,cAAc,EAAE,EAAE;IAClB,WAAW,EAAE,GAAG;CACnB,CAAC;AAEF,MAAM,IAAI,GAAmB;IACzB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,CAAC;IACd,YAAY,EAAE,EAAE;IAChB,cAAc,EAAE,EAAE;IAClB,WAAW,EAAE,GAAG;CACnB,CAAC;AAEF,MAAM,UAAU,eAAe,CAC3B,IAAiB,EACjB,WAAsC;IAEtC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;IACzE,MAAM,IAAI,GAAkB,OAAO,EAAE,KAAsB,IAAI,UAAU,CAAC;IAC1E,IAAI,IAAI,KAAK,UAAU;QAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IAChD,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;IACxC,IAAI,WAAW,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,QAAgB,EAAU,EAAE;YAClD,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YAChD,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACtD,CAAC,CAAC;QACF,OAAO;YACH,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,WAAW,CAAC;YACvD,YAAY,EAAE,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAC,YAAY,CAAC;YAC1D,cAAc,EAAE,GAAG,CAAC,kBAAkB,EAAE,QAAQ,CAAC,cAAc,CAAC;YAChE,WAAW,EAAE,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,WAAW,CAAC;SAC1D,CAAC;IACN,CAAC;IACD,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;AAC3B,CAAC;AAED,iFAAiF;AACjF,MAAM,WAAW,GAAG,4BAA4B,CAAC;AAEjD,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,GAAmB;IAC9D,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACX,KAAK,GAAG;YACJ,OAAO,CAAC,CAAC;QACb,KAAK,GAAG;YACJ,OAAO,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;QAC/B,KAAK,GAAG;YACJ,OAAO,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC;QAChC,KAAK,GAAG;YACJ,OAAO,CAAC,GAAG,GAAG,CAAC,cAAc,CAAC;QAClC,KAAK,GAAG;YACJ,OAAO,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;QAC/B;YACI,OAAO,CAAC,CAAC;IACjB,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC3B,KAAyB,EACzB,KAAgC,EAChC,GAAmB;IAEnB,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IACrB,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,UAAU,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CAClC,KAAuB,EACvB,KAAgC,EAChC,GAAmB;IAEnB,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjD,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/C,OAAO,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;IACvE,OAAO,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CACjC,KAAuB,EACvB,KAAgC,EAChC,GAAmB;IAEnB,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC,UAAU,CAAC;IACjC,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjD,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;QACvE,OAAO,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CACxB,KAAmC,EACnC,GAAmB;IAEnB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACvD,MAAM,aAAa,GAAG,UAAU,EAAE,KAAK,CAAC;QACxC,IAAI,CAAC,aAAa;YAAE,SAAS;QAC7B,MAAM,UAAU,GAAG,aAAa,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACrD,IAAI,UAAU,IAAI,CAAC;YAAE,SAAS;QAC9B,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE;YACV,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;YAC9B,UAAU;YACV,aAAa;SAChB,CAAC,CAAC;IACP,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,4EAA4E;AAC5E,qDAAqD;AACrD,MAAM,UAAU,WAAW,CAAC,IAAU,EAAE,EAAQ;IAC5C,MAAM,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,IAAY;IAC5C,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;IACxC,OAAO,GAAG,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lowest pixels-per-day a width cap may shrink the timeline to. Below one
|
|
3
|
+
* pixel a working day stops being visible, and short bars collapse into
|
|
4
|
+
* one-pixel slivers that no longer read as durations.
|
|
5
|
+
*/
|
|
6
|
+
export declare const MIN_PIXELS_PER_DAY = 1;
|
|
7
|
+
export interface CappedPixelsPerDayInput {
|
|
8
|
+
/** Density from the scale (`pixelsPerUnit / daysPerUnit`). */
|
|
9
|
+
naturalPixelsPerDay: number;
|
|
10
|
+
/** Days the timeline spans at that density (working or calendar days). */
|
|
11
|
+
dayCount: number;
|
|
12
|
+
/** Canvas width that isn't timeline: header card plus both gutters. */
|
|
13
|
+
chromeWidth: number;
|
|
14
|
+
/** The cap; `undefined` means content-fit. */
|
|
15
|
+
maxWidth: number | undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Pixels-per-day under an optional canvas cap. Only ever shrinks the natural
|
|
19
|
+
* density, and never below `MIN_PIXELS_PER_DAY` (a density already below the
|
|
20
|
+
* floor is left alone rather than raised).
|
|
21
|
+
*/
|
|
22
|
+
export declare function cappedPixelsPerDay(input: CappedPixelsPerDayInput): number;
|
|
23
|
+
//# sourceMappingURL=canvas-width.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-width.d.ts","sourceRoot":"","sources":["../src/canvas-width.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,MAAM,WAAW,uBAAuB;IACpC,8DAA8D;IAC9D,mBAAmB,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAOzE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// `LayoutOptions.width` caps the canvas (specs/rendering.md § Canvas width).
|
|
2
|
+
// The cap is best-effort: it shrinks pixels-per-day so chrome plus timeline
|
|
3
|
+
// fits, but text does not scale, so spilled captions, run labels and the
|
|
4
|
+
// header card can still push the final canvas past it.
|
|
5
|
+
/**
|
|
6
|
+
* Lowest pixels-per-day a width cap may shrink the timeline to. Below one
|
|
7
|
+
* pixel a working day stops being visible, and short bars collapse into
|
|
8
|
+
* one-pixel slivers that no longer read as durations.
|
|
9
|
+
*/
|
|
10
|
+
export const MIN_PIXELS_PER_DAY = 1;
|
|
11
|
+
/**
|
|
12
|
+
* Pixels-per-day under an optional canvas cap. Only ever shrinks the natural
|
|
13
|
+
* density, and never below `MIN_PIXELS_PER_DAY` (a density already below the
|
|
14
|
+
* floor is left alone rather than raised).
|
|
15
|
+
*/
|
|
16
|
+
export function cappedPixelsPerDay(input) {
|
|
17
|
+
const { naturalPixelsPerDay, dayCount, chromeWidth, maxWidth } = input;
|
|
18
|
+
if (maxWidth === undefined)
|
|
19
|
+
return naturalPixelsPerDay;
|
|
20
|
+
if (chromeWidth + dayCount * naturalPixelsPerDay <= maxWidth)
|
|
21
|
+
return naturalPixelsPerDay;
|
|
22
|
+
const fitted = (maxWidth - chromeWidth) / dayCount;
|
|
23
|
+
const floor = Math.min(naturalPixelsPerDay, MIN_PIXELS_PER_DAY);
|
|
24
|
+
return Math.max(floor, fitted);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=canvas-width.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-width.js","sourceRoot":"","sources":["../src/canvas-width.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,4EAA4E;AAC5E,yEAAyE;AACzE,uDAAuD;AAEvD;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAapC;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA8B;IAC7D,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACvE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,mBAAmB,CAAC;IACvD,IAAI,WAAW,GAAG,QAAQ,GAAG,mBAAmB,IAAI,QAAQ;QAAE,OAAO,mBAAmB,CAAC;IACzF,MAAM,MAAM,GAAG,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/capacity.d.ts
CHANGED
|
@@ -69,4 +69,32 @@ export declare function resolveCapacityIcon(icon: string, symbols: Map<string, S
|
|
|
69
69
|
* trigger spill rather than clip.
|
|
70
70
|
*/
|
|
71
71
|
export declare function estimateCapacitySuffixWidth(text: string, icon: ResolvedCapacityIcon | null, fontSizePx: number): number;
|
|
72
|
+
/**
|
|
73
|
+
* Em-distance the renderer reserves between an item's metaText and its
|
|
74
|
+
* capacity suffix (or any inline trailing token). Half a space's worth
|
|
75
|
+
* — wide enough to read as a separator, narrow enough not to look like
|
|
76
|
+
* a stray gap. SVG `<tspan dx>` honors this exactly so we don't depend
|
|
77
|
+
* on per-character estimation for the gap itself.
|
|
78
|
+
*/
|
|
79
|
+
export declare const META_SUFFIX_DX_EM = 0.6;
|
|
80
|
+
/**
|
|
81
|
+
* Where a built-in SVG capacity icon (person, people, points, time) sits:
|
|
82
|
+
* the px terms that, added in order to the start x of the text run the
|
|
83
|
+
* suffix is painted in, give the icon's x, at `fontSizePx`. Undefined for
|
|
84
|
+
* every other glyph (`null`, the multiplier, a literal), which the
|
|
85
|
+
* renderer paints inside the `<text>`.
|
|
86
|
+
*
|
|
87
|
+
* The terms are kept apart rather than summed so the renderer adds them to
|
|
88
|
+
* its x one at a time, in this order, exactly as it did when it measured
|
|
89
|
+
* them itself; a pre-summed offset can round differently at the last bit.
|
|
90
|
+
*
|
|
91
|
+
* With `metaText`, the run is the item meta line: the meta text's
|
|
92
|
+
* `estimateTextWidth` width and the `META_SUFFIX_DX_EM` separator (the
|
|
93
|
+
* first two terms are where the renderer starts the number), then the
|
|
94
|
+
* number's width and the gap. Without it, the number starts the run (an
|
|
95
|
+
* item with no meta text, or a lane badge): its width, then the gap.
|
|
96
|
+
* Both paths place the icon from the same number estimate and gap, so an
|
|
97
|
+
* item suffix reads like a lane badge.
|
|
98
|
+
*/
|
|
99
|
+
export declare function capacityIconDxTerms(text: string, icon: ResolvedCapacityIcon | null, fontSizePx: number, metaText?: string): readonly number[] | undefined;
|
|
72
100
|
//# sourceMappingURL=capacity.d.ts.map
|
package/dist/capacity.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capacity.d.ts","sourceRoot":"","sources":["../src/capacity.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"capacity.d.ts","sourceRoot":"","sources":["../src/capacity.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAe1D;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAezE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,CAAC;AAS3D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,GACxC,oBAAoB,GAAG,IAAI,CAc7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACvC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,oBAAoB,GAAG,IAAI,EACjC,UAAU,EAAE,MAAM,GACnB,MAAM,CAgBR;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAUrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,oBAAoB,GAAG,IAAI,EACjC,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAClB,SAAS,MAAM,EAAE,GAAG,SAAS,CAY/B"}
|