@kteneyck/cesium-timeline-core 0.7.0 → 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/README.md CHANGED
@@ -133,6 +133,7 @@ Angular components use standalone imports — no NgModule required. Selectors: `
133
133
  - **Clickable datetime** — pass `onDateTimeClick` to open your own date picker; pass the result back via `jumpToTime` to pan the canvas and set the time.
134
134
  - **Token-based datetime format** — built-in presets plus custom format strings with 17 supported tokens.
135
135
  - **Max tick limit** — `maxTicks` prop prevents the canvas from becoming overloaded at wide zoom levels by coarsening the tick scale automatically.
136
+ - **Zoom to selection** — drag in the tick area (away from the needle) to draw a time-range highlight with a crosshair cursor; on release the visible window zooms to exactly the selected span and fires `onRangeSelect` (React) / `rangeSelect` (Angular) with the resulting start and end times.
136
137
  - **Swim lanes** — display time intervals and instants as horizontal rows inside the canvas. Supports customizable styling, click/hover/double-click event hooks, drag-to-reorder, and vertical scrolling when lanes overflow.
137
138
  - **Fully themeable** — 16 theme properties cover every color, size, and font setting, including swim lane item border defaults.
138
139
  - **Localizable labels** — every control-bar label and tooltip is overridable via the `labels` prop; dynamic tooltips accept a `(multiplier: number) => string` callback. See [Labels & i18n](#labels--i18n).
@@ -174,6 +175,7 @@ Angular components use standalone imports — no NgModule required. Selectors: `
174
175
  | `onSwimLaneItemHover` | `(info: SwimLaneEventInfo \| null) => void` | — | Fires when mouse enters/leaves a swim lane item |
175
176
  | `onSwimLaneItemDoubleClick` | `(info: SwimLaneEventInfo) => void` | — | Fires when a swim lane item is double-clicked |
176
177
  | `onSwimLaneReorder` | `(orderedIds: string[]) => void` | — | Fires when swim lanes are reordered via drag. Receives the new lane id order. |
178
+ | `onRangeSelect` | `(start: JulianDate, end: JulianDate) => void` | — | Fires when the user completes a click-and-drag in the tick area. The visible window zooms to the selected span; receives the resulting start and end times. |
177
179
  | `labels` | `Partial<TimelineLabels>` | English defaults | Override any control-bar label or tooltip string. See [Labels & i18n](#labels--i18n). |
178
180
 
179
181
  ---
@@ -596,6 +598,12 @@ const CesiumWithTimeline = () => {
596
598
  onTimeChange={(t) => { clock.currentTime = t; }}
597
599
  onPlayPause={(playing) => { clock.shouldAnimate = playing; }}
598
600
  onMultiplierChange={(m) => { clock.multiplier = m; }}
601
+ onRangeSelect={(start, end) => {
602
+ // Zoom the Cesium clock range to match the selected span
603
+ clock.startTime = start;
604
+ clock.stopTime = end;
605
+ clock.currentTime = start;
606
+ }}
599
607
  />
600
608
  )}
601
609
  </div>
@@ -695,6 +703,60 @@ const StandaloneTimeline = () => {
695
703
  };
696
704
  ```
697
705
 
706
+ ### Zoom to Selection
707
+
708
+ Click-and-drag in the tick area (the bottom strip, away from the needle) to draw a time-range highlight. The cursor becomes a crosshair while dragging. On mouse-up the **visible window zooms to exactly the selected span** and `onRangeSelect` fires with the start and end `JulianDate`.
709
+
710
+ A short click (no drag) in the tick area still moves the needle normally.
711
+
712
+ ```tsx
713
+ import { useState } from 'react';
714
+ import * as Cesium from 'cesium';
715
+ import { Timeline } from '@kteneyck/cesium-timeline-react';
716
+
717
+ const ZoomableTimeline = () => {
718
+ const [selectedRange, setSelectedRange] = useState<{ start: Date; end: Date } | null>(null);
719
+
720
+ return (
721
+ <>
722
+ {selectedRange && (
723
+ <p>
724
+ Selected: {selectedRange.start.toISOString()} → {selectedRange.end.toISOString()}
725
+ </p>
726
+ )}
727
+ <Timeline
728
+ clock={viewer.clock}
729
+ height={120}
730
+ onRangeSelect={(start, end) => {
731
+ setSelectedRange({
732
+ start: Cesium.JulianDate.toDate(start),
733
+ end: Cesium.JulianDate.toDate(end),
734
+ });
735
+ }}
736
+ />
737
+ </>
738
+ );
739
+ };
740
+ ```
741
+
742
+ In Angular, listen to the `(rangeSelect)` output — the event payload is `{ start: Cesium.JulianDate, end: Cesium.JulianDate }`:
743
+
744
+ ```html
745
+ <ct-timeline
746
+ [clock]="viewer.clock"
747
+ [height]="120"
748
+ (rangeSelect)="onRangeSelect($event)"
749
+ />
750
+ ```
751
+
752
+ ```typescript
753
+ onRangeSelect(range: { start: Cesium.JulianDate; end: Cesium.JulianDate }) {
754
+ this.viewer.clock.startTime = range.start;
755
+ this.viewer.clock.stopTime = range.end;
756
+ this.viewer.clock.currentTime = range.start;
757
+ }
758
+ ```
759
+
698
760
  ---
699
761
 
700
762
  ## Swim Lanes
@@ -1,8 +1,8 @@
1
- import * as H from "cesium";
2
- function ke(e, t) {
1
+ import * as A from "cesium";
2
+ function Ce(e, t) {
3
3
  return typeof e == "function" ? e(t) : e;
4
4
  }
5
- const He = {
5
+ const Ye = {
6
6
  dateTimeClickTooltip: "Click to jump to a date/time",
7
7
  liveLabel: "LIVE",
8
8
  liveActiveLabel: "● LIVE",
@@ -21,8 +21,22 @@ const He = {
21
21
  fastForwardTooltip: "Fast forward",
22
22
  fastForwardActiveTooltip: (e) => `${e}× speed — click to increase, click again at max to reset`,
23
23
  collapseSwimLanesTooltip: "Collapse swim lanes",
24
- expandSwimLanesTooltip: "Expand swim lanes"
25
- }, Ce = {
24
+ expandSwimLanesTooltip: "Expand swim lanes",
25
+ months: [
26
+ "Jan",
27
+ "Feb",
28
+ "Mar",
29
+ "Apr",
30
+ "May",
31
+ "Jun",
32
+ "Jul",
33
+ "Aug",
34
+ "Sep",
35
+ "Oct",
36
+ "Nov",
37
+ "Dec"
38
+ ]
39
+ }, we = {
26
40
  backgroundColor: "#1a1a1a",
27
41
  tickColor: "#666666",
28
42
  majorTickColor: "#999999",
@@ -40,8 +54,8 @@ const He = {
40
54
  swimLaneItemBorderColor: "#666666",
41
55
  swimLaneItemBorderWidth: 0
42
56
  };
43
- var ce = /* @__PURE__ */ ((e) => (e[e.FIFTEEN_MIN = 15] = "FIFTEEN_MIN", e[e.THIRTY_MIN = 30] = "THIRTY_MIN", e[e.HOURLY = 60] = "HOURLY", e[e.CUSTOM = -1] = "CUSTOM", e))(ce || {});
44
- const _ = {
57
+ var me = /* @__PURE__ */ ((e) => (e[e.FIFTEEN_MIN = 15] = "FIFTEEN_MIN", e[e.THIRTY_MIN = 30] = "THIRTY_MIN", e[e.HOURLY = 60] = "HOURLY", e[e.CUSTOM = -1] = "CUSTOM", e))(me || {});
58
+ const J = {
45
59
  color: "#4da6ff",
46
60
  borderColor: "#2980b9",
47
61
  borderWidth: 1,
@@ -50,23 +64,23 @@ const _ = {
50
64
  markerSize: 10,
51
65
  labelColor: "#cccccc",
52
66
  backgroundColor: "transparent"
53
- }, $ = 24;
54
- function Ae(e) {
55
- return e instanceof H.JulianDate ? H.JulianDate.clone(e) : H.JulianDate.fromDate(e);
67
+ }, P = 24;
68
+ function Ee(e) {
69
+ return e instanceof A.JulianDate ? A.JulianDate.clone(e) : A.JulianDate.fromDate(e);
56
70
  }
57
71
  function te(e) {
58
- return e instanceof H.JulianDate ? H.JulianDate.toDate(e) : e;
72
+ return e instanceof A.JulianDate ? A.JulianDate.toDate(e) : e;
59
73
  }
60
74
  function F(e) {
61
75
  return te(e).getTime();
62
76
  }
63
- function Ye(e) {
64
- return H.JulianDate.fromDate(new Date(e));
77
+ function $e(e) {
78
+ return A.JulianDate.fromDate(new Date(e));
65
79
  }
66
- function pe(e, t) {
80
+ function ge(e, t) {
67
81
  return F(t) - F(e);
68
82
  }
69
- const Me = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], de = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], fe = {
83
+ const Te = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], Se = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], fe = {
70
84
  /** e.g. "Feb 24 2026 14:04:07" — default */
71
85
  DEFAULT: "MMM DD YYYY HH:mm:ss",
72
86
  /** e.g. "Feb 24 2026 02:04:07 PM" */
@@ -81,7 +95,7 @@ const Me = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct"
81
95
  TIME_ONLY: "HH:mm:ss",
82
96
  /** e.g. "02:04:07 PM" */
83
97
  TIME_12: "hh:mm:ss A"
84
- }, we = {
98
+ }, Ie = {
85
99
  /** Use the browser's local timezone (default behavior). */
86
100
  LOCAL: "local",
87
101
  /** Coordinated Universal Time. */
@@ -89,8 +103,8 @@ const Me = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct"
89
103
  };
90
104
  function oe(e, t) {
91
105
  if (!t || t === "local") {
92
- const M = e.getFullYear(), f = e.getMonth(), u = e.getDate(), D = e.getHours(), L = D % 12 || 12, d = e.getMinutes(), w = e.getSeconds(), E = e.getMilliseconds();
93
- return { yr: M, mo: f, day: u, hr24: D, hr12: L, min: d, sec: w, ms: E, ampm: D < 12 ? "AM" : "PM" };
106
+ const M = e.getFullYear(), h = e.getMonth(), y = e.getDate(), S = e.getHours(), f = S % 12 || 12, u = e.getMinutes(), w = e.getSeconds(), O = e.getMilliseconds();
107
+ return { yr: M, mo: h, day: y, hr24: S, hr12: f, min: u, sec: w, ms: O, ampm: S < 12 ? "AM" : "PM" };
94
108
  }
95
109
  const o = new Intl.DateTimeFormat("en-US", {
96
110
  timeZone: t,
@@ -101,105 +115,105 @@ function oe(e, t) {
101
115
  minute: "2-digit",
102
116
  second: "2-digit",
103
117
  hour12: !1
104
- }), l = {};
118
+ }), s = {};
105
119
  for (const M of o.formatToParts(e))
106
- M.type !== "literal" && (l[M.type] = M.value);
107
- const r = parseInt(l.year), s = parseInt(l.month) - 1, a = parseInt(l.day);
108
- let n = parseInt(l.hour);
109
- n === 24 && (n = 0);
110
- const m = n % 12 || 12, c = parseInt(l.minute), h = parseInt(l.second), p = e.getMilliseconds();
111
- return { yr: r, mo: s, day: a, hr24: n, hr12: m, min: c, sec: h, ms: p, ampm: n < 12 ? "AM" : "PM" };
120
+ M.type !== "literal" && (s[M.type] = M.value);
121
+ const n = parseInt(s.year), l = parseInt(s.month) - 1, a = parseInt(s.day);
122
+ let r = parseInt(s.hour);
123
+ r === 24 && (r = 0);
124
+ const c = r % 12 || 12, m = parseInt(s.minute), d = parseInt(s.second), p = e.getMilliseconds();
125
+ return { yr: n, mo: l, day: a, hr24: r, hr12: c, min: m, sec: d, ms: p, ampm: r < 12 ? "AM" : "PM" };
112
126
  }
113
- function Ee(e, t) {
114
- var r;
127
+ function Re(e, t) {
128
+ var n;
115
129
  if (!t || t === "local") return null;
116
130
  const o = te(e);
117
- return ((r = new Intl.DateTimeFormat("en-US", {
131
+ return ((n = new Intl.DateTimeFormat("en-US", {
118
132
  timeZone: t,
119
133
  timeZoneName: "short"
120
- }).formatToParts(o).find((s) => s.type === "timeZoneName")) == null ? void 0 : r.value) ?? null;
134
+ }).formatToParts(o).find((l) => l.type === "timeZoneName")) == null ? void 0 : n.value) ?? null;
121
135
  }
122
- function ge(e, t = fe.DEFAULT, o) {
123
- const l = te(e), { yr: r, mo: s, day: a, hr24: n, hr12: m, min: c, sec: h, ms: p, ampm: M } = oe(l, o), f = (L) => String(L).padStart(2, "0"), u = (L) => String(L).padStart(3, "0"), D = {
124
- YYYY: String(r),
125
- YY: String(r).slice(-2),
126
- MMMM: de[s],
127
- MMM: Me[s],
128
- MM: f(s + 1),
129
- M: String(s + 1),
130
- DD: f(a),
136
+ function ye(e, t = fe.DEFAULT, o) {
137
+ const s = te(e), { yr: n, mo: l, day: a, hr24: r, hr12: c, min: m, sec: d, ms: p, ampm: M } = oe(s, o), h = (f) => String(f).padStart(2, "0"), y = (f) => String(f).padStart(3, "0"), S = {
138
+ YYYY: String(n),
139
+ YY: String(n).slice(-2),
140
+ MMMM: Se[l],
141
+ MMM: Te[l],
142
+ MM: h(l + 1),
143
+ M: String(l + 1),
144
+ DD: h(a),
131
145
  D: String(a),
132
- HH: f(n),
133
- H: String(n),
134
- hh: f(m),
135
- h: String(m),
136
- mm: f(c),
137
- ss: f(h),
138
- SSS: u(p),
146
+ HH: h(r),
147
+ H: String(r),
148
+ hh: h(c),
149
+ h: String(c),
150
+ mm: h(m),
151
+ ss: h(d),
152
+ SSS: y(p),
139
153
  A: M,
140
154
  a: M.toLowerCase()
141
155
  };
142
156
  return t.replace(
143
157
  /YYYY|YY|MMMM|MMM|MM|M|DD|D|HH|H|hh|h|mm|ss|SSS|A|a/g,
144
- (L) => D[L] ?? L
158
+ (f) => S[f] ?? f
145
159
  );
146
160
  }
147
- function Ie(e = fe.DEFAULT) {
148
- const t = ["YYYY", "YY", "MMMM", "MMM", "MM", "M", "DD", "D"], o = ["HH", "H", "hh", "h", "mm", "ss", "SSS", "A", "a"], l = (a) => a.replace(/\s{2,}/g, " ").trim().replace(/^[\s\W]+|[\s\W]+$/g, "").trim();
149
- let r = e;
150
- for (const a of t) r = r.replace(a, "");
151
- let s = e;
152
- for (const a of o) s = s.replace(a, "");
153
- return { timeFormat: l(r), dateFormat: l(s) };
161
+ function Je(e = fe.DEFAULT) {
162
+ const t = ["YYYY", "YY", "MMMM", "MMM", "MM", "M", "DD", "D"], o = ["HH", "H", "hh", "h", "mm", "ss", "SSS", "A", "a"], s = (a) => a.replace(/\s{2,}/g, " ").trim().replace(/^[\s\W]+|[\s\W]+$/g, "").trim();
163
+ let n = e;
164
+ for (const a of t) n = n.replace(a, "");
165
+ let l = e;
166
+ for (const a of o) l = l.replace(a, "");
167
+ return { timeFormat: s(n), dateFormat: s(l) };
154
168
  }
155
169
  function Pe(e, t = !1) {
156
- return ge(e, t ? "HH:mm:ss" : "HH:mm");
170
+ return ye(e, t ? "HH:mm:ss" : "HH:mm");
157
171
  }
158
- function Te(e, t, o, l) {
159
- const r = F(e), s = F(t), a = F(o);
160
- if (a === s) return 0;
161
- const n = (r - s) / (a - s);
162
- return Math.max(0, Math.min(1, n)) * l;
172
+ function be(e, t, o, s) {
173
+ const n = F(e), l = F(t), a = F(o);
174
+ if (a === l) return 0;
175
+ const r = (n - l) / (a - l);
176
+ return Math.max(0, Math.min(1, r)) * s;
163
177
  }
164
- function Re(e, t, o, l) {
165
- const r = Math.max(0, Math.min(1, e / l)), s = F(t), a = F(o), n = s + r * (a - s);
166
- return H.JulianDate.fromDate(new Date(n));
178
+ function Fe(e, t, o, s) {
179
+ const n = Math.max(0, Math.min(1, e / s)), l = F(t), a = F(o), r = l + n * (a - l);
180
+ return A.JulianDate.fromDate(new Date(r));
167
181
  }
168
- function _e(e, t, o, l) {
169
- const r = [], s = pe(e, t), a = F(e);
170
- let n;
171
- typeof o == "number" && o in ce || typeof o == "number" ? n = o * 60 * 1e3 : n = 3600 * 1e3;
172
- const m = n * 4;
173
- let c = a, h = 0;
174
- for (; c <= a + s; ) {
175
- const p = h * n % m === 0, M = Te(
176
- new Date(c),
182
+ function Ne(e, t, o, s) {
183
+ const n = [], l = ge(e, t), a = F(e);
184
+ let r;
185
+ typeof o == "number" && o in me || typeof o == "number" ? r = o * 60 * 1e3 : r = 3600 * 1e3;
186
+ const c = r * 4;
187
+ let m = a, d = 0;
188
+ for (; m <= a + l; ) {
189
+ const p = d * r % c === 0, M = be(
190
+ new Date(m),
177
191
  e,
178
192
  t,
179
- l
193
+ s
180
194
  );
181
- let f;
195
+ let h;
182
196
  if (p) {
183
- const u = new Date(c), D = u.getHours().toString().padStart(2, "0"), L = u.getMinutes().toString().padStart(2, "0");
184
- f = `${D}:${L}`;
197
+ const y = new Date(m), S = y.getHours().toString().padStart(2, "0"), f = y.getMinutes().toString().padStart(2, "0");
198
+ h = `${S}:${f}`;
185
199
  }
186
- r.push({
200
+ n.push({
187
201
  position: M,
188
202
  isMajor: p,
189
- label: f
190
- }), c += n, h++;
203
+ label: h
204
+ }), m += r, d++;
191
205
  }
192
- return r;
206
+ return n;
193
207
  }
194
- function $e(e, t, o = 10) {
195
- let l = t[0], r = Math.abs(l.position - e);
196
- for (const s of t) {
197
- const a = Math.abs(s.position - e);
198
- a < r && (r = a, l = s);
208
+ function _e(e, t, o = 10) {
209
+ let s = t[0], n = Math.abs(s.position - e);
210
+ for (const l of t) {
211
+ const a = Math.abs(l.position - e);
212
+ a < n && (n = a, s = l);
199
213
  }
200
- return r <= o ? l.position : e;
214
+ return n <= o ? s.position : e;
201
215
  }
202
- const Se = 1e3, ye = 31536e9, S = [
216
+ const De = 1e3, Le = 31536e9, L = [
203
217
  1e-3,
204
218
  2e-3,
205
219
  5e-3,
@@ -248,78 +262,85 @@ const Se = 1e3, ye = 31536e9, S = [
248
262
  126144e5,
249
263
  15768e6,
250
264
  31536e6
251
- ], z = 36, W = 1, be = 6, Q = 6, Fe = 0.3, x = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
252
- function Y(e) {
265
+ ], X = 36, W = 1, ke = 6, x = 6, We = 0.3, He = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
266
+ function E(e) {
253
267
  return e < 10 ? `0${e}` : `${e}`;
254
268
  }
255
- function me(e, t, o) {
256
- const l = new Date(e), { yr: r, mo: s, day: a, hr24: n, min: m, sec: c, ms: h } = oe(l, o);
257
- if (t > 31536e4) return `${r}`;
258
- if (t > 31536e3) return `${x[s]} ${r}`;
259
- if (t > 604800) return `${x[s]} ${a}`;
260
- if (t > 86400) return `${x[s]} ${a} ${Y(n)}:${Y(m)}`;
261
- if (t > 3600) return `${Y(n)}:${Y(m)}`;
262
- if (t > 60) return `${Y(n)}:${Y(m)}:${Y(c)}`;
263
- const p = h > 0 ? `.${String(h).padStart(3, "0")}` : "";
264
- return `${Y(n)}:${Y(m)}:${Y(c)}${p}`;
269
+ function ce(e, t, o, s, n) {
270
+ const l = new Date(e), { yr: a, mo: r, day: c, hr24: m, hr12: d, min: p, sec: M, ms: h, ampm: y } = oe(l, o), S = s ? d : m, f = s ? ` ${y}` : "", u = n ?? He;
271
+ if (t > 31536e4) return `${a}`;
272
+ if (t > 31536e3) return `${u[r]} ${a}`;
273
+ if (t > 604800) return `${u[r]} ${c}`;
274
+ if (t > 86400) return `${u[r]} ${c} ${E(S)}:${E(p)}${f}`;
275
+ if (t > 3600) return `${E(S)}:${E(p)}${f}`;
276
+ if (t > 60) return `${E(S)}:${E(p)}:${E(M)}${f}`;
277
+ const w = h > 0 ? `.${String(h).padStart(3, "0")}` : "";
278
+ return `${E(S)}:${E(p)}:${E(M)}${w}${f}`;
265
279
  }
266
- function De(e, t, o) {
267
- const l = new Date(e);
280
+ function Ae(e, t, o) {
281
+ const s = new Date(e);
268
282
  if (!o || o === "local") {
269
- const m = l.getFullYear(), c = l.getMonth(), h = l.getDate();
270
- return t > 31536e4 ? new Date(Math.floor(m / 100) * 100, 0).getTime() : t > 31536e3 ? new Date(Math.floor(m / 10) * 10, 0).getTime() : t > 86400 ? new Date(m, 0).getTime() : new Date(m, c, h).getTime();
283
+ const c = s.getFullYear(), m = s.getMonth(), d = s.getDate();
284
+ return t > 31536e4 ? new Date(Math.floor(c / 100) * 100, 0).getTime() : t > 31536e3 ? new Date(Math.floor(c / 10) * 10, 0).getTime() : t > 86400 ? new Date(c, 0).getTime() : new Date(c, m, d).getTime();
271
285
  }
272
- const { yr: r, hr24: s, min: a, sec: n } = oe(l, o);
273
- return t > 31536e4 ? Date.UTC(Math.floor(r / 100) * 100, 0, 1) : t > 31536e3 ? Date.UTC(Math.floor(r / 10) * 10, 0, 1) : t > 86400 ? Date.UTC(r, 0, 1) : e - (s * 3600 + a * 60 + n) * 1e3;
286
+ const { yr: n, hr24: l, min: a, sec: r } = oe(s, o);
287
+ return t > 31536e4 ? Date.UTC(Math.floor(n / 100) * 100, 0, 1) : t > 31536e3 ? Date.UTC(Math.floor(n / 10) * 10, 0, 1) : t > 86400 ? Date.UTC(n, 0, 1) : e - (l * 3600 + a * 60 + r) * 1e3;
274
288
  }
275
289
  function ee(e, t) {
276
290
  return Math.ceil(e / t + 0.5) * t;
277
291
  }
278
292
  function ue(e, t, o) {
279
- var l, r, s, a, n, m, c, h, p, M, f, u;
293
+ var s, n, l, a, r, c, m, d, p, M, h, y;
280
294
  return {
281
- color: ((l = t.style) == null ? void 0 : l.color) ?? ((r = e.style) == null ? void 0 : r.color) ?? _.color,
282
- borderColor: ((s = t.style) == null ? void 0 : s.borderColor) ?? ((a = e.style) == null ? void 0 : a.borderColor) ?? (o == null ? void 0 : o.swimLaneItemBorderColor) ?? _.borderColor,
283
- borderWidth: ((n = t.style) == null ? void 0 : n.borderWidth) ?? ((m = e.style) == null ? void 0 : m.borderWidth) ?? (o == null ? void 0 : o.swimLaneItemBorderWidth) ?? _.borderWidth,
284
- opacity: ((c = t.style) == null ? void 0 : c.opacity) ?? ((h = e.style) == null ? void 0 : h.opacity) ?? _.opacity,
285
- markerShape: ((p = t.style) == null ? void 0 : p.markerShape) ?? ((M = e.style) == null ? void 0 : M.markerShape) ?? _.markerShape,
286
- markerSize: ((f = t.style) == null ? void 0 : f.markerSize) ?? ((u = e.style) == null ? void 0 : u.markerSize) ?? _.markerSize
295
+ color: ((s = t.style) == null ? void 0 : s.color) ?? ((n = e.style) == null ? void 0 : n.color) ?? J.color,
296
+ borderColor: ((l = t.style) == null ? void 0 : l.borderColor) ?? ((a = e.style) == null ? void 0 : a.borderColor) ?? (o == null ? void 0 : o.swimLaneItemBorderColor) ?? J.borderColor,
297
+ borderWidth: ((r = t.style) == null ? void 0 : r.borderWidth) ?? ((c = e.style) == null ? void 0 : c.borderWidth) ?? (o == null ? void 0 : o.swimLaneItemBorderWidth) ?? J.borderWidth,
298
+ opacity: ((m = t.style) == null ? void 0 : m.opacity) ?? ((d = e.style) == null ? void 0 : d.opacity) ?? J.opacity,
299
+ markerShape: ((p = t.style) == null ? void 0 : p.markerShape) ?? ((M = e.style) == null ? void 0 : M.markerShape) ?? J.markerShape,
300
+ markerSize: ((h = t.style) == null ? void 0 : h.markerSize) ?? ((y = e.style) == null ? void 0 : y.markerSize) ?? J.markerSize
287
301
  };
288
302
  }
289
- function Le(e) {
290
- return Math.max(Se, Math.min(ye, e));
303
+ function he(e) {
304
+ return Math.max(De, Math.min(Le, e));
305
+ }
306
+ function Oe(e, t, o) {
307
+ const s = t - e, n = (e + t) / 2, l = he(s * o);
308
+ return {
309
+ startMs: n - l / 2,
310
+ endMs: n + l / 2
311
+ };
291
312
  }
292
- function Je(e, t, o) {
293
- const l = t - e, r = (e + t) / 2, s = Le(l * o);
313
+ function Ue(e, t, o, s) {
314
+ const n = t - e, l = he(n * o), a = n > 0 ? (s - e) / n : 0.5;
294
315
  return {
295
- startMs: r - s / 2,
296
- endMs: r + s / 2
316
+ startMs: s - a * l,
317
+ endMs: s + (1 - a) * l
297
318
  };
298
319
  }
299
- function Ne(e) {
320
+ function Be(e) {
300
321
  let t = 0;
301
- for (const o of e) t += (o.height ?? $) + W;
322
+ for (const o of e) t += (o.height ?? P) + W;
302
323
  return t;
303
324
  }
304
- function We(e, t, o, l, r) {
305
- const { swimLanes: s, showSwimLanes: a, scrollTop: n, startMs: m, endMs: c, theme: h } = r;
306
- if (!a || s.length === 0) return null;
307
- const p = Math.max(0, l - z);
325
+ function ve(e, t, o, s, n) {
326
+ const { swimLanes: l, showSwimLanes: a, scrollTop: r, startMs: c, endMs: m, theme: d } = n;
327
+ if (!a || l.length === 0) return null;
328
+ const p = Math.max(0, s - X);
308
329
  if (t < 0 || t >= p) return null;
309
- let M = -n;
310
- for (const f of s) {
311
- const u = f.height ?? $, D = M, L = M + u;
312
- if (M += u + W, !(t < D || t >= L)) {
313
- for (const d of f.items) {
314
- if (d.interval) {
315
- const w = H.JulianDate.toDate(d.interval.start).getTime(), E = H.JulianDate.toDate(d.interval.stop).getTime(), U = (w - m) / (c - m) * o, G = (E - m) / (c - m) * o;
316
- if (e >= Math.max(0, U) && e <= Math.min(o, G))
317
- return { lane: f, item: d };
330
+ let M = -r;
331
+ for (const h of l) {
332
+ const y = h.height ?? P, S = M, f = M + y;
333
+ if (M += y + W, !(t < S || t >= f)) {
334
+ for (const u of h.items) {
335
+ if (u.interval) {
336
+ const w = A.JulianDate.toDate(u.interval.start).getTime(), O = A.JulianDate.toDate(u.interval.stop).getTime(), k = (w - c) / (m - c) * o, U = (O - c) / (m - c) * o;
337
+ if (e >= Math.max(0, k) && e <= Math.min(o, U))
338
+ return { lane: h, item: u };
318
339
  }
319
- if (d.instant) {
320
- const E = (H.JulianDate.toDate(d.instant).getTime() - m) / (c - m) * o, U = ue(f, d, h);
321
- if (Math.abs(e - E) <= U.markerSize / 2 + 2)
322
- return { lane: f, item: d };
340
+ if (u.instant) {
341
+ const O = (A.JulianDate.toDate(u.instant).getTime() - c) / (m - c) * o, k = ue(h, u, d);
342
+ if (Math.abs(e - O) <= k.markerSize / 2 + 2)
343
+ return { lane: h, item: u };
323
344
  }
324
345
  }
325
346
  return null;
@@ -327,192 +348,200 @@ function We(e, t, o, l, r) {
327
348
  }
328
349
  return null;
329
350
  }
330
- function Oe(e, t, o, l) {
331
- const { swimLanes: r, showSwimLanes: s, scrollTop: a } = l;
332
- if (!s || r.length === 0 || e > 80) return null;
333
- const n = Math.max(0, o - z);
334
- if (t < 0 || t >= n) return null;
335
- let m = -a;
336
- for (const c of r) {
337
- const h = c.height ?? $;
338
- if (t >= m && t < m + h) return c;
339
- m += h + W;
351
+ function ze(e, t, o, s) {
352
+ const { swimLanes: n, showSwimLanes: l, scrollTop: a } = s;
353
+ if (!l || n.length === 0 || e > 80) return null;
354
+ const r = Math.max(0, o - X);
355
+ if (t < 0 || t >= r) return null;
356
+ let c = -a;
357
+ for (const m of n) {
358
+ const d = m.height ?? P;
359
+ if (t >= c && t < c + d) return m;
360
+ c += d + W;
340
361
  }
341
362
  return null;
342
363
  }
343
- function Ue(e, t, o) {
364
+ function je(e, t, o) {
344
365
  if (!o.showSwimLanes || o.swimLanes.length === 0) return !1;
345
- const l = Math.max(0, t - z);
346
- return e >= 0 && e < l;
366
+ const s = Math.max(0, t - X);
367
+ return e >= 0 && e < s;
347
368
  }
348
- function ve(e, t, o, l) {
369
+ function Xe(e, t, o, s) {
349
370
  const {
350
- startMs: r,
351
- endMs: s,
371
+ startMs: n,
372
+ endMs: l,
352
373
  currentMs: a,
353
- theme: n,
354
- maxTicks: m,
355
- swimLanes: c,
356
- showSwimLanes: h,
374
+ theme: r,
375
+ maxTicks: c,
376
+ swimLanes: m,
377
+ showSwimLanes: d,
357
378
  reorderState: p,
358
- timezone: M
359
- } = l;
360
- let { scrollTop: f } = l;
361
- const u = (s - r) / 1e3;
379
+ timezone: M,
380
+ use12h: h,
381
+ months: y,
382
+ rangeSelection: S
383
+ } = s;
384
+ let { scrollTop: f } = s;
385
+ const u = (l - n) / 1e3;
362
386
  if (u <= 0) return f;
363
- e.fillStyle = n.backgroundColor, e.fillRect(0, 0, t, o);
364
- const D = h && c.length > 0, d = D ? Math.max(0, o - z) : 0;
365
- let w = 0;
366
- if (D)
367
- for (const i of c) w += (i.height ?? $) + W;
368
- const E = Math.max(0, w - d);
369
- if (f > E && (f = E), f < 0 && (f = 0), D && d > 0) {
370
- e.save(), e.beginPath(), e.rect(0, 0, t, d), e.clip();
387
+ e.fillStyle = r.backgroundColor, e.fillRect(0, 0, t, o);
388
+ const w = d && m.length > 0, k = w ? Math.max(0, o - X) : 0;
389
+ let U = 0;
390
+ if (w)
391
+ for (const i of m) U += (i.height ?? P) + W;
392
+ const G = Math.max(0, U - k);
393
+ if (f > G && (f = G), f < 0 && (f = 0), w && k > 0) {
394
+ e.save(), e.beginPath(), e.rect(0, 0, t, k), e.clip();
371
395
  let i = -f;
372
- const y = (b) => (b - r) / (s - r) * t;
373
- for (const b of c) {
374
- const T = b.height ?? $, C = i + T;
375
- if (C > 0 && i < d) {
376
- const g = b.style, O = (g == null ? void 0 : g.backgroundColor) ?? _.backgroundColor;
377
- O && O !== "transparent" && (e.fillStyle = O, e.fillRect(0, i, t, T)), e.strokeStyle = n.tickColor + "44", e.lineWidth = 0.5, e.beginPath(), e.moveTo(0, C), e.lineTo(t, C), e.stroke();
378
- for (const I of b.items) {
379
- const k = ue(b, I, n);
380
- if (I.interval) {
381
- const K = H.JulianDate.toDate(I.interval.start).getTime(), A = H.JulianDate.toDate(I.interval.stop).getTime(), J = y(K), N = y(A), V = Math.max(0, J), q = Math.min(t, N) - V;
382
- if (q > 0) {
383
- e.globalAlpha = k.opacity, e.fillStyle = k.color;
396
+ const b = (D) => (D - n) / (l - n) * t;
397
+ for (const D of m) {
398
+ const T = D.height ?? P, C = i + T;
399
+ if (C > 0 && i < k) {
400
+ const g = D.style, B = (g == null ? void 0 : g.backgroundColor) ?? J.backgroundColor;
401
+ B && B !== "transparent" && (e.fillStyle = B, e.fillRect(0, i, t, T)), e.strokeStyle = r.tickColor + "44", e.lineWidth = 0.5, e.beginPath(), e.moveTo(0, C), e.lineTo(t, C), e.stroke();
402
+ for (const $ of D.items) {
403
+ const H = ue(D, $, r);
404
+ if ($.interval) {
405
+ const V = A.JulianDate.toDate($.interval.start).getTime(), Y = A.JulianDate.toDate($.interval.stop).getTime(), N = b(V), _ = b(Y), q = Math.max(0, N), Q = Math.min(t, _) - q;
406
+ if (Q > 0) {
407
+ e.globalAlpha = H.opacity, e.fillStyle = H.color;
384
408
  const se = 3, le = i + se, ae = T - se * 2;
385
- e.fillRect(V, le, q, ae), k.borderWidth > 0 && (e.strokeStyle = k.borderColor, e.lineWidth = k.borderWidth, e.strokeRect(V, le, q, ae)), e.globalAlpha = 1;
409
+ e.fillRect(q, le, Q, ae), H.borderWidth > 0 && (e.strokeStyle = H.borderColor, e.lineWidth = H.borderWidth, e.strokeRect(q, le, Q, ae)), e.globalAlpha = 1;
386
410
  }
387
411
  }
388
- if (I.instant) {
389
- const K = H.JulianDate.toDate(I.instant).getTime(), A = y(K);
390
- if (A >= -k.markerSize && A <= t + k.markerSize) {
391
- const J = i + T / 2, N = k.markerSize;
392
- e.globalAlpha = k.opacity, e.fillStyle = k.color, k.markerShape === "diamond" ? (e.beginPath(), e.moveTo(A, J - N / 2), e.lineTo(A + N / 2, J), e.lineTo(A, J + N / 2), e.lineTo(A - N / 2, J), e.closePath(), e.fill()) : k.markerShape === "circle" ? (e.beginPath(), e.arc(A, J, N / 2, 0, Math.PI * 2), e.fill()) : (e.strokeStyle = k.color, e.lineWidth = 2, e.beginPath(), e.moveTo(A, i + 2), e.lineTo(A, i + T - 2), e.stroke()), e.globalAlpha = 1;
412
+ if ($.instant) {
413
+ const V = A.JulianDate.toDate($.instant).getTime(), Y = b(V);
414
+ if (Y >= -H.markerSize && Y <= t + H.markerSize) {
415
+ const N = i + T / 2, _ = H.markerSize;
416
+ e.globalAlpha = H.opacity, e.fillStyle = H.color, H.markerShape === "diamond" ? (e.beginPath(), e.moveTo(Y, N - _ / 2), e.lineTo(Y + _ / 2, N), e.lineTo(Y, N + _ / 2), e.lineTo(Y - _ / 2, N), e.closePath(), e.fill()) : H.markerShape === "circle" ? (e.beginPath(), e.arc(Y, N, _ / 2, 0, Math.PI * 2), e.fill()) : (e.strokeStyle = H.color, e.lineWidth = 2, e.beginPath(), e.moveTo(Y, i + 2), e.lineTo(Y, i + T - 2), e.stroke()), e.globalAlpha = 1;
393
417
  }
394
418
  }
395
419
  }
396
- e.font = `${Math.min(11, T - 4)}px system-ui, sans-serif`, e.textAlign = "left", e.textBaseline = "middle", e.fillStyle = (g == null ? void 0 : g.labelColor) ?? _.labelColor, e.fillText(b.label, be, i + T / 2);
420
+ e.font = `${Math.min(11, T - 4)}px system-ui, sans-serif`, e.textAlign = "left", e.textBaseline = "middle", e.fillStyle = (g == null ? void 0 : g.labelColor) ?? J.labelColor, e.fillText(D.label, ke, i + T / 2);
397
421
  }
398
- if (i += T + W, i >= d) break;
422
+ if (i += T + W, i >= k) break;
399
423
  }
400
424
  if (p && p.dragging) {
401
- const b = p.currentY - p.dragStartY;
425
+ const D = p.currentY - p.dragStartY;
402
426
  let T = -f;
403
- for (let g = 0; g < c.length && g < p.insertIndex; g++)
404
- T += (c[g].height ?? $) + W;
405
- e.strokeStyle = n.indicatorColor, e.lineWidth = 2, e.beginPath(), e.moveTo(0, T), e.lineTo(t, T), e.stroke();
406
- const C = c.find((g) => g.id === p.dragLaneId);
427
+ for (let g = 0; g < m.length && g < p.insertIndex; g++)
428
+ T += (m[g].height ?? P) + W;
429
+ e.strokeStyle = r.indicatorColor, e.lineWidth = 2, e.beginPath(), e.moveTo(0, T), e.lineTo(t, T), e.stroke();
430
+ const C = m.find((g) => g.id === p.dragLaneId);
407
431
  if (C) {
408
- const g = C.height ?? $;
409
- let O = -f;
410
- for (const I of c) {
411
- if (I.id === p.dragLaneId) break;
412
- O += (I.height ?? $) + W;
432
+ const g = C.height ?? P;
433
+ let B = -f;
434
+ for (const $ of m) {
435
+ if ($.id === p.dragLaneId) break;
436
+ B += ($.height ?? P) + W;
413
437
  }
414
- e.globalAlpha = 0.4, e.fillStyle = n.indicatorColor, e.fillRect(0, O + b, t, g), e.globalAlpha = 1;
438
+ e.globalAlpha = 0.4, e.fillStyle = r.indicatorColor, e.fillRect(0, B + D, t, g), e.globalAlpha = 1;
415
439
  }
416
440
  }
417
- if (w > d) {
418
- const b = t - Q - 2, T = d / w, C = Math.max(20, d * T), g = f / E * (d - C);
419
- e.fillStyle = n.tickColor + "22", e.fillRect(b, 0, Q, d), e.fillStyle = n.tickColor + "88", e.fillRect(b, g, Q, C);
441
+ if (U > k) {
442
+ const D = t - x - 2, T = k / U, C = Math.max(20, k * T), g = f / G * (k - C);
443
+ e.fillStyle = r.tickColor + "22", e.fillRect(D, 0, x, k), e.fillStyle = r.tickColor + "88", e.fillRect(D, g, x, C);
420
444
  }
421
445
  e.restore();
422
446
  }
423
- e.font = `${n.fontSize}px monospace`;
424
- const U = me(r + u * 500, u, M), G = e.measureText(U).width + 24, he = Math.max(G / t * u, u / 1e3);
425
- let P = S[S.length - 1], v = S.length - 1;
426
- for (let i = 0; i < S.length; i++)
427
- if (S[i] > he) {
428
- P = S[i], v = i;
447
+ e.font = `${r.fontSize}px monospace`;
448
+ const pe = ce(n + u * 500, u, M, h, y), Me = e.measureText(pe).width + 24, de = Math.max(Me / t * u, u / 1e3);
449
+ let I = L[L.length - 1], v = L.length - 1;
450
+ for (let i = 0; i < L.length; i++)
451
+ if (L[i] > de) {
452
+ I = L[i], v = i;
429
453
  break;
430
454
  }
431
- if (m != null && m > 0)
432
- for (; v < S.length - 1 && u / P > m; )
433
- v++, P = S[v];
455
+ if (c != null && c > 0)
456
+ for (; v < L.length - 1 && u / I > c; )
457
+ v++, I = L[v];
434
458
  let R = 0;
435
459
  for (let i = v - 1; i >= 0; i--)
436
- if (P % S[i] < 1e-4) {
437
- t * (S[i] / u) >= 3 && (R = S[i]);
460
+ if (I % L[i] < 1e-4) {
461
+ t * (L[i] / u) >= 3 && (R = L[i]);
438
462
  break;
439
463
  }
440
- let B = 0;
464
+ let z = 0;
441
465
  if (R > 0) {
442
- for (let i = 0; i < S.length && S[i] < R; i++)
443
- if (R % S[i] < 1e-4 && t * (S[i] / u) >= 3) {
444
- B = S[i];
466
+ for (let i = 0; i < L.length && L[i] < R; i++)
467
+ if (R % L[i] < 1e-4 && t * (L[i] / u) >= 3) {
468
+ z = L[i];
445
469
  break;
446
470
  }
447
471
  }
448
- const ne = De(r, u, M), j = (r - ne) / 1e3, X = j + u, Z = (i) => t * ((i - j) / u);
449
- if (B > 0) {
450
- e.strokeStyle = n.tickColor, e.lineWidth = 1;
451
- for (let i = Math.floor(j / B) * B; i <= X; i = ee(i, B)) {
452
- const y = Z(i);
453
- e.beginPath(), e.moveTo(y, o - n.minorTickHeight), e.lineTo(y, o), e.stroke();
472
+ const ne = Ae(n, u, M), j = (n - ne) / 1e3, Z = j + u, K = (i) => t * ((i - j) / u);
473
+ if (z > 0) {
474
+ e.strokeStyle = r.tickColor, e.lineWidth = 1;
475
+ for (let i = Math.floor(j / z) * z; i <= Z; i = ee(i, z)) {
476
+ const b = K(i);
477
+ e.beginPath(), e.moveTo(b, o - r.minorTickHeight), e.lineTo(b, o), e.stroke();
454
478
  }
455
479
  }
456
480
  if (R > 0) {
457
- e.strokeStyle = n.tickColor, e.lineWidth = 1;
458
- for (let i = Math.floor(j / R) * R; i <= X; i = ee(i, R)) {
459
- const y = Z(i);
460
- e.beginPath(), e.moveTo(y, o - n.minorTickHeight), e.lineTo(y, o), e.stroke();
481
+ e.strokeStyle = r.tickColor, e.lineWidth = 1;
482
+ for (let i = Math.floor(j / R) * R; i <= Z; i = ee(i, R)) {
483
+ const b = K(i);
484
+ e.beginPath(), e.moveTo(b, o - r.minorTickHeight), e.lineTo(b, o), e.stroke();
461
485
  }
462
486
  }
463
487
  e.textAlign = "center", e.textBaseline = "bottom";
464
488
  let re = -1 / 0;
465
- for (let i = Math.floor(j / P) * P; i <= X + P; i = ee(i, P)) {
466
- const y = Z(i), b = ne + i * 1e3;
467
- e.strokeStyle = n.majorTickColor, e.lineWidth = 1, e.beginPath(), e.moveTo(y, o - n.majorTickHeight), e.lineTo(y, o), e.stroke();
468
- const T = me(b, u, M), C = e.measureText(T).width, g = y - C / 2;
469
- g > re && (e.fillStyle = n.labelColor, e.fillText(T, y, o - n.majorTickHeight - 4), re = g + C + 5);
489
+ for (let i = Math.floor(j / I) * I; i <= Z + I; i = ee(i, I)) {
490
+ const b = K(i), D = ne + i * 1e3;
491
+ e.strokeStyle = r.majorTickColor, e.lineWidth = 1, e.beginPath(), e.moveTo(b, o - r.majorTickHeight), e.lineTo(b, o), e.stroke();
492
+ const T = ce(D, u, M, h, y), C = e.measureText(T).width, g = b - C / 2;
493
+ g > re && (e.fillStyle = r.labelColor, e.fillText(T, b, o - r.majorTickHeight - 4), re = g + C + 5);
494
+ }
495
+ if (S) {
496
+ const i = (S.startMs - n) / (l - n) * t, b = (S.endMs - n) / (l - n) * t, D = Math.min(i, b), T = Math.abs(b - i);
497
+ e.globalAlpha = 0.2, e.fillStyle = r.indicatorColor, e.fillRect(D, 0, T, o), e.globalAlpha = 1;
470
498
  }
471
- const ie = (a - r) / (s - r) * t;
472
- return e.strokeStyle = n.indicatorColor, e.lineWidth = n.indicatorLineWidth, e.beginPath(), e.moveTo(ie, 0), e.lineTo(ie, o), e.stroke(), f;
499
+ const ie = (a - n) / (l - n) * t;
500
+ return e.strokeStyle = r.indicatorColor, e.lineWidth = r.indicatorLineWidth, e.beginPath(), e.moveTo(ie, 0), e.lineTo(ie, o), e.stroke(), f;
473
501
  }
474
502
  export {
475
- He as DEFAULT_LABELS,
476
- $ as DEFAULT_LANE_HEIGHT,
503
+ Ye as DEFAULT_LABELS,
504
+ P as DEFAULT_LANE_HEIGHT,
477
505
  fe as DateTimeFormats,
478
- be as LABEL_PAD_LEFT,
506
+ ke as LABEL_PAD_LEFT,
479
507
  W as LANE_GAP,
480
- ye as MAX_SPAN_MS,
481
- Se as MIN_SPAN_MS,
482
- x as MONTHS,
483
- Q as SCROLLBAR_WIDTH,
484
- Fe as SWIM_LANE_SCROLL_SPEED,
485
- z as TICK_AREA_HEIGHT,
486
- S as TIC_SCALES,
487
- ce as TickInterval,
488
- we as Timezones,
489
- De as calcEpochMs,
490
- Le as clampSpan,
491
- _ as defaultSwimLaneStyle,
492
- Ce as defaultTheme,
493
- ve as drawTimeline,
494
- ge as formatDateTime,
508
+ Le as MAX_SPAN_MS,
509
+ De as MIN_SPAN_MS,
510
+ He as MONTHS,
511
+ x as SCROLLBAR_WIDTH,
512
+ We as SWIM_LANE_SCROLL_SPEED,
513
+ X as TICK_AREA_HEIGHT,
514
+ L as TIC_SCALES,
515
+ me as TickInterval,
516
+ Ie as Timezones,
517
+ Ae as calcEpochMs,
518
+ he as clampSpan,
519
+ J as defaultSwimLaneStyle,
520
+ we as defaultTheme,
521
+ Xe as drawTimeline,
522
+ ye as formatDateTime,
495
523
  Pe as formatTime,
496
- Ye as fromMilliseconds,
497
- _e as generateTicks,
524
+ $e as fromMilliseconds,
525
+ Ne as generateTicks,
498
526
  oe as getDateParts,
499
- pe as getDurationMs,
500
- Ee as getTimezoneAbbr,
501
- Oe as hitTestLaneLabel,
502
- We as hitTestSwimLane,
503
- Ue as isInSwimLaneRegion,
504
- me as makeLabel,
527
+ ge as getDurationMs,
528
+ Re as getTimezoneAbbr,
529
+ ze as hitTestLaneLabel,
530
+ ve as hitTestSwimLane,
531
+ je as isInSwimLaneRegion,
532
+ ce as makeLabel,
505
533
  ee as nextTic,
506
- Re as positionToTime,
534
+ Fe as positionToTime,
507
535
  ue as resolveItemStyle,
508
- ke as resolveLabel,
509
- $e as snapToTick,
510
- Ie as splitForDisplay,
511
- Te as timeToPosition,
536
+ Ce as resolveLabel,
537
+ _e as snapToTick,
538
+ Je as splitForDisplay,
539
+ be as timeToPosition,
512
540
  te as toDate,
513
- Ae as toJulianDate,
541
+ Ee as toJulianDate,
514
542
  F as toMilliseconds,
515
- Ne as totalSwimLaneHeight,
516
- Y as twoD,
517
- Je as zoomRange
543
+ Be as totalSwimLaneHeight,
544
+ E as twoD,
545
+ Ue as zoomAroundMs,
546
+ Oe as zoomRange
518
547
  };
@@ -1 +1 @@
1
- (function(i,U){typeof exports=="object"&&typeof module<"u"?U(exports,require("cesium")):typeof define=="function"&&define.amd?define(["exports","cesium"],U):(i=typeof globalThis<"u"?globalThis:i||self,U(i.CesiumTimelineCore={},i.Cesium))})(this,(function(i,U){"use strict";function Le(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const o in e)if(o!=="default"){const l=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,l.get?l:{enumerable:!0,get:()=>e[o]})}}return t.default=e,Object.freeze(t)}const L=Le(U);function Ae(e,t){return typeof e=="function"?e(t):e}const He={dateTimeClickTooltip:"Click to jump to a date/time",liveLabel:"LIVE",liveActiveLabel:"● LIVE",liveTooltip:"Jump to live (now)",liveActiveTooltip:"Currently live",resetSpeedTooltip:"Reset to 1× speed",jumpToStartTooltip:"Jump to start",noStartTimeTooltip:"No start time set",jumpToEndTooltip:"Jump to end",noEndTimeTooltip:"No end time set",rewindTooltip:"Rewind",rewindActiveTooltip:e=>`Reverse ${e}× — click to speed up, press play to stop`,playTooltip:"Play",playFromRewindTooltip:"Play (reset to 1×)",pauseTooltip:"Pause",fastForwardTooltip:"Fast forward",fastForwardActiveTooltip:e=>`${e}× speed — click to increase, click again at max to reset`,collapseSwimLanesTooltip:"Collapse swim lanes",expandSwimLanesTooltip:"Expand swim lanes"},ke={backgroundColor:"#1a1a1a",tickColor:"#666666",majorTickColor:"#999999",labelColor:"#cccccc",indicatorColor:"#d69826",indicatorLineWidth:5,majorTickHeight:10,minorTickHeight:5,fontSize:12,controlBarBackground:"#242424",controlBarBorder:"#333333",buttonColor:"#666666",buttonHoverColor:"#888888",buttonActiveColor:"#d69826",swimLaneItemBorderColor:"#666666",swimLaneItemBorderWidth:0};var x=(e=>(e[e.FIFTEEN_MIN=15]="FIFTEEN_MIN",e[e.THIRTY_MIN=30]="THIRTY_MIN",e[e.HOURLY=60]="HOURLY",e[e.CUSTOM=-1]="CUSTOM",e))(x||{});const w={color:"#4da6ff",borderColor:"#2980b9",borderWidth:1,opacity:.8,markerShape:"diamond",markerSize:10,labelColor:"#cccccc",backgroundColor:"transparent"},Y=24;function Ce(e){return e instanceof L.JulianDate?L.JulianDate.clone(e):L.JulianDate.fromDate(e)}function K(e){return e instanceof L.JulianDate?L.JulianDate.toDate(e):e}function I(e){return K(e).getTime()}function Ee(e){return L.JulianDate.fromDate(new Date(e))}function me(e,t){return I(t)-I(e)}const _e=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],we=["January","February","March","April","May","June","July","August","September","October","November","December"],ee={DEFAULT:"MMM DD YYYY HH:mm:ss",TWELVE_HR:"MMM DD YYYY hh:mm:ss A",ISO:"YYYY-MM-DD HH:mm:ss",US:"MM/DD/YYYY HH:mm",EU:"DD/MM/YYYY HH:mm",TIME_ONLY:"HH:mm:ss",TIME_12:"hh:mm:ss A"},Ye={LOCAL:"local",UTC:"UTC"};function Z(e,t){if(!t||t==="local"){const M=e.getFullYear(),u=e.getMonth(),h=e.getDate(),A=e.getHours(),H=A%12||12,g=e.getMinutes(),P=e.getSeconds(),R=e.getMilliseconds();return{yr:M,mo:u,day:h,hr24:A,hr12:H,min:g,sec:P,ms:R,ampm:A<12?"AM":"PM"}}const o=new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}),l={};for(const M of o.formatToParts(e))M.type!=="literal"&&(l[M.type]=M.value);const r=parseInt(l.year),s=parseInt(l.month)-1,m=parseInt(l.day);let n=parseInt(l.hour);n===24&&(n=0);const c=n%12||12,f=parseInt(l.minute),T=parseInt(l.second),d=e.getMilliseconds();return{yr:r,mo:s,day:m,hr24:n,hr12:c,min:f,sec:T,ms:d,ampm:n<12?"AM":"PM"}}function Ie(e,t){var r;if(!t||t==="local")return null;const o=K(e);return((r=new Intl.DateTimeFormat("en-US",{timeZone:t,timeZoneName:"short"}).formatToParts(o).find(s=>s.type==="timeZoneName"))==null?void 0:r.value)??null}function ce(e,t=ee.DEFAULT,o){const l=K(e),{yr:r,mo:s,day:m,hr24:n,hr12:c,min:f,sec:T,ms:d,ampm:M}=Z(l,o),u=H=>String(H).padStart(2,"0"),h=H=>String(H).padStart(3,"0"),A={YYYY:String(r),YY:String(r).slice(-2),MMMM:we[s],MMM:_e[s],MM:u(s+1),M:String(s+1),DD:u(m),D:String(m),HH:u(n),H:String(n),hh:u(c),h:String(c),mm:u(f),ss:u(T),SSS:h(d),A:M,a:M.toLowerCase()};return t.replace(/YYYY|YY|MMMM|MMM|MM|M|DD|D|HH|H|hh|h|mm|ss|SSS|A|a/g,H=>A[H]??H)}function Pe(e=ee.DEFAULT){const t=["YYYY","YY","MMMM","MMM","MM","M","DD","D"],o=["HH","H","hh","h","mm","ss","SSS","A","a"],l=m=>m.replace(/\s{2,}/g," ").trim().replace(/^[\s\W]+|[\s\W]+$/g,"").trim();let r=e;for(const m of t)r=r.replace(m,"");let s=e;for(const m of o)s=s.replace(m,"");return{timeFormat:l(r),dateFormat:l(s)}}function Re(e,t=!1){return ce(e,t?"HH:mm:ss":"HH:mm")}function fe(e,t,o,l){const r=I(e),s=I(t),m=I(o);if(m===s)return 0;const n=(r-s)/(m-s);return Math.max(0,Math.min(1,n))*l}function Ne(e,t,o,l){const r=Math.max(0,Math.min(1,e/l)),s=I(t),m=I(o),n=s+r*(m-s);return L.JulianDate.fromDate(new Date(n))}function Fe(e,t,o,l){const r=[],s=me(e,t),m=I(e);let n;typeof o=="number"&&o in x||typeof o=="number"?n=o*60*1e3:n=3600*1e3;const c=n*4;let f=m,T=0;for(;f<=m+s;){const d=T*n%c===0,M=fe(new Date(f),e,t,l);let u;if(d){const h=new Date(f),A=h.getHours().toString().padStart(2,"0"),H=h.getMinutes().toString().padStart(2,"0");u=`${A}:${H}`}r.push({position:M,isMajor:d,label:u}),f+=n,T++}return r}function Oe(e,t,o=10){let l=t[0],r=Math.abs(l.position-e);for(const s of t){const m=Math.abs(s.position-e);m<r&&(r=m,l=s)}return r<=o?l.position:e}const ue=1e3,he=31536e9,p=[.001,.002,.005,.01,.02,.05,.1,.25,.5,1,2,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,21600,43200,86400,172800,345600,604800,1296e3,2592e3,5184e3,7776e3,15552e3,31536e3,63072e3,126144e3,15768e4,31536e4,63072e4,126144e4,15768e5,31536e5,63072e5,126144e5,15768e6,31536e6],B=36,F=1,Te=6,V=6,$e=.3,q=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function E(e){return e<10?`0${e}`:`${e}`}function te(e,t,o){const l=new Date(e),{yr:r,mo:s,day:m,hr24:n,min:c,sec:f,ms:T}=Z(l,o);if(t>31536e4)return`${r}`;if(t>31536e3)return`${q[s]} ${r}`;if(t>604800)return`${q[s]} ${m}`;if(t>86400)return`${q[s]} ${m} ${E(n)}:${E(c)}`;if(t>3600)return`${E(n)}:${E(c)}`;if(t>60)return`${E(n)}:${E(c)}:${E(f)}`;const d=T>0?`.${String(T).padStart(3,"0")}`:"";return`${E(n)}:${E(c)}:${E(f)}${d}`}function de(e,t,o){const l=new Date(e);if(!o||o==="local"){const c=l.getFullYear(),f=l.getMonth(),T=l.getDate();return t>31536e4?new Date(Math.floor(c/100)*100,0).getTime():t>31536e3?new Date(Math.floor(c/10)*10,0).getTime():t>86400?new Date(c,0).getTime():new Date(c,f,T).getTime()}const{yr:r,hr24:s,min:m,sec:n}=Z(l,o);return t>31536e4?Date.UTC(Math.floor(r/100)*100,0,1):t>31536e3?Date.UTC(Math.floor(r/10)*10,0,1):t>86400?Date.UTC(r,0,1):e-(s*3600+m*60+n)*1e3}function Q(e,t){return Math.ceil(e/t+.5)*t}function oe(e,t,o){var l,r,s,m,n,c,f,T,d,M,u,h;return{color:((l=t.style)==null?void 0:l.color)??((r=e.style)==null?void 0:r.color)??w.color,borderColor:((s=t.style)==null?void 0:s.borderColor)??((m=e.style)==null?void 0:m.borderColor)??(o==null?void 0:o.swimLaneItemBorderColor)??w.borderColor,borderWidth:((n=t.style)==null?void 0:n.borderWidth)??((c=e.style)==null?void 0:c.borderWidth)??(o==null?void 0:o.swimLaneItemBorderWidth)??w.borderWidth,opacity:((f=t.style)==null?void 0:f.opacity)??((T=e.style)==null?void 0:T.opacity)??w.opacity,markerShape:((d=t.style)==null?void 0:d.markerShape)??((M=e.style)==null?void 0:M.markerShape)??w.markerShape,markerSize:((u=t.style)==null?void 0:u.markerSize)??((h=e.style)==null?void 0:h.markerSize)??w.markerSize}}function Me(e){return Math.max(ue,Math.min(he,e))}function Je(e,t,o){const l=t-e,r=(e+t)/2,s=Me(l*o);return{startMs:r-s/2,endMs:r+s/2}}function We(e){let t=0;for(const o of e)t+=(o.height??Y)+F;return t}function ve(e,t,o,l,r){const{swimLanes:s,showSwimLanes:m,scrollTop:n,startMs:c,endMs:f,theme:T}=r;if(!m||s.length===0)return null;const d=Math.max(0,l-B);if(t<0||t>=d)return null;let M=-n;for(const u of s){const h=u.height??Y,A=M,H=M+h;if(M+=h+F,!(t<A||t>=H)){for(const g of u.items){if(g.interval){const P=L.JulianDate.toDate(g.interval.start).getTime(),R=L.JulianDate.toDate(g.interval.stop).getTime(),j=(P-c)/(f-c)*o,ne=(R-c)/(f-c)*o;if(e>=Math.max(0,j)&&e<=Math.min(o,ne))return{lane:u,item:g}}if(g.instant){const R=(L.JulianDate.toDate(g.instant).getTime()-c)/(f-c)*o,j=oe(u,g,T);if(Math.abs(e-R)<=j.markerSize/2+2)return{lane:u,item:g}}}return null}}return null}function Ue(e,t,o,l){const{swimLanes:r,showSwimLanes:s,scrollTop:m}=l;if(!s||r.length===0||e>80)return null;const n=Math.max(0,o-B);if(t<0||t>=n)return null;let c=-m;for(const f of r){const T=f.height??Y;if(t>=c&&t<c+T)return f;c+=T+F}return null}function Be(e,t,o){if(!o.showSwimLanes||o.swimLanes.length===0)return!1;const l=Math.max(0,t-B);return e>=0&&e<l}function je(e,t,o,l){const{startMs:r,endMs:s,currentMs:m,theme:n,maxTicks:c,swimLanes:f,showSwimLanes:T,reorderState:d,timezone:M}=l;let{scrollTop:u}=l;const h=(s-r)/1e3;if(h<=0)return u;e.fillStyle=n.backgroundColor,e.fillRect(0,0,t,o);const A=T&&f.length>0,g=A?Math.max(0,o-B):0;let P=0;if(A)for(const a of f)P+=(a.height??Y)+F;const R=Math.max(0,P-g);if(u>R&&(u=R),u<0&&(u=0),A&&g>0){e.save(),e.beginPath(),e.rect(0,0,t,g),e.clip();let a=-u;const y=D=>(D-r)/(s-r)*t;for(const D of f){const b=D.height??Y,C=a+b;if(C>0&&a<g){const S=D.style,v=(S==null?void 0:S.backgroundColor)??w.backgroundColor;v&&v!=="transparent"&&(e.fillStyle=v,e.fillRect(0,a,t,b)),e.strokeStyle=n.tickColor+"44",e.lineWidth=.5,e.beginPath(),e.moveTo(0,C),e.lineTo(t,C),e.stroke();for(const N of D.items){const k=oe(D,N,n);if(N.interval){const ae=L.JulianDate.toDate(N.interval.start).getTime(),_=L.JulianDate.toDate(N.interval.stop).getTime(),J=y(ae),W=y(_),le=Math.max(0,J),se=Math.min(t,W)-le;if(se>0){e.globalAlpha=k.opacity,e.fillStyle=k.color;const be=3,ye=a+be,De=b-be*2;e.fillRect(le,ye,se,De),k.borderWidth>0&&(e.strokeStyle=k.borderColor,e.lineWidth=k.borderWidth,e.strokeRect(le,ye,se,De)),e.globalAlpha=1}}if(N.instant){const ae=L.JulianDate.toDate(N.instant).getTime(),_=y(ae);if(_>=-k.markerSize&&_<=t+k.markerSize){const J=a+b/2,W=k.markerSize;e.globalAlpha=k.opacity,e.fillStyle=k.color,k.markerShape==="diamond"?(e.beginPath(),e.moveTo(_,J-W/2),e.lineTo(_+W/2,J),e.lineTo(_,J+W/2),e.lineTo(_-W/2,J),e.closePath(),e.fill()):k.markerShape==="circle"?(e.beginPath(),e.arc(_,J,W/2,0,Math.PI*2),e.fill()):(e.strokeStyle=k.color,e.lineWidth=2,e.beginPath(),e.moveTo(_,a+2),e.lineTo(_,a+b-2),e.stroke()),e.globalAlpha=1}}}e.font=`${Math.min(11,b-4)}px system-ui, sans-serif`,e.textAlign="left",e.textBaseline="middle",e.fillStyle=(S==null?void 0:S.labelColor)??w.labelColor,e.fillText(D.label,Te,a+b/2)}if(a+=b+F,a>=g)break}if(d&&d.dragging){const D=d.currentY-d.dragStartY;let b=-u;for(let S=0;S<f.length&&S<d.insertIndex;S++)b+=(f[S].height??Y)+F;e.strokeStyle=n.indicatorColor,e.lineWidth=2,e.beginPath(),e.moveTo(0,b),e.lineTo(t,b),e.stroke();const C=f.find(S=>S.id===d.dragLaneId);if(C){const S=C.height??Y;let v=-u;for(const N of f){if(N.id===d.dragLaneId)break;v+=(N.height??Y)+F}e.globalAlpha=.4,e.fillStyle=n.indicatorColor,e.fillRect(0,v+D,t,S),e.globalAlpha=1}}if(P>g){const D=t-V-2,b=g/P,C=Math.max(20,g*b),S=u/R*(g-C);e.fillStyle=n.tickColor+"22",e.fillRect(D,0,V,g),e.fillStyle=n.tickColor+"88",e.fillRect(D,S,V,C)}e.restore()}e.font=`${n.fontSize}px monospace`;const j=te(r+h*500,h,M),ne=e.measureText(j).width+24,ze=Math.max(ne/t*h,h/1e3);let O=p[p.length-1],z=p.length-1;for(let a=0;a<p.length;a++)if(p[a]>ze){O=p[a],z=a;break}if(c!=null&&c>0)for(;z<p.length-1&&h/O>c;)z++,O=p[z];let $=0;for(let a=z-1;a>=0;a--)if(O%p[a]<1e-4){t*(p[a]/h)>=3&&($=p[a]);break}let G=0;if($>0){for(let a=0;a<p.length&&p[a]<$;a++)if($%p[a]<1e-4&&t*(p[a]/h)>=3){G=p[a];break}}const ge=de(r,h,M),X=(r-ge)/1e3,ie=X+h,re=a=>t*((a-X)/h);if(G>0){e.strokeStyle=n.tickColor,e.lineWidth=1;for(let a=Math.floor(X/G)*G;a<=ie;a=Q(a,G)){const y=re(a);e.beginPath(),e.moveTo(y,o-n.minorTickHeight),e.lineTo(y,o),e.stroke()}}if($>0){e.strokeStyle=n.tickColor,e.lineWidth=1;for(let a=Math.floor(X/$)*$;a<=ie;a=Q(a,$)){const y=re(a);e.beginPath(),e.moveTo(y,o-n.minorTickHeight),e.lineTo(y,o),e.stroke()}}e.textAlign="center",e.textBaseline="bottom";let Se=-1/0;for(let a=Math.floor(X/O)*O;a<=ie+O;a=Q(a,O)){const y=re(a),D=ge+a*1e3;e.strokeStyle=n.majorTickColor,e.lineWidth=1,e.beginPath(),e.moveTo(y,o-n.majorTickHeight),e.lineTo(y,o),e.stroke();const b=te(D,h,M),C=e.measureText(b).width,S=y-C/2;S>Se&&(e.fillStyle=n.labelColor,e.fillText(b,y,o-n.majorTickHeight-4),Se=S+C+5)}const pe=(m-r)/(s-r)*t;return e.strokeStyle=n.indicatorColor,e.lineWidth=n.indicatorLineWidth,e.beginPath(),e.moveTo(pe,0),e.lineTo(pe,o),e.stroke(),u}i.DEFAULT_LABELS=He,i.DEFAULT_LANE_HEIGHT=Y,i.DateTimeFormats=ee,i.LABEL_PAD_LEFT=Te,i.LANE_GAP=F,i.MAX_SPAN_MS=he,i.MIN_SPAN_MS=ue,i.MONTHS=q,i.SCROLLBAR_WIDTH=V,i.SWIM_LANE_SCROLL_SPEED=$e,i.TICK_AREA_HEIGHT=B,i.TIC_SCALES=p,i.TickInterval=x,i.Timezones=Ye,i.calcEpochMs=de,i.clampSpan=Me,i.defaultSwimLaneStyle=w,i.defaultTheme=ke,i.drawTimeline=je,i.formatDateTime=ce,i.formatTime=Re,i.fromMilliseconds=Ee,i.generateTicks=Fe,i.getDateParts=Z,i.getDurationMs=me,i.getTimezoneAbbr=Ie,i.hitTestLaneLabel=Ue,i.hitTestSwimLane=ve,i.isInSwimLaneRegion=Be,i.makeLabel=te,i.nextTic=Q,i.positionToTime=Ne,i.resolveItemStyle=oe,i.resolveLabel=Ae,i.snapToTick=Oe,i.splitForDisplay=Pe,i.timeToPosition=fe,i.toDate=K,i.toJulianDate=Ce,i.toMilliseconds=I,i.totalSwimLaneHeight=We,i.twoD=E,i.zoomRange=Je,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(l,j){typeof exports=="object"&&typeof module<"u"?j(exports,require("cesium")):typeof define=="function"&&define.amd?define(["exports","cesium"],j):(l=typeof globalThis<"u"?globalThis:l||self,j(l.CesiumTimelineCore={},l.Cesium))})(this,(function(l,j){"use strict";function Ae(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const o in e)if(o!=="default"){const i=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,i.get?i:{enumerable:!0,get:()=>e[o]})}}return t.default=e,Object.freeze(t)}const k=Ae(j);function He(e,t){return typeof e=="function"?e(t):e}const ke={dateTimeClickTooltip:"Click to jump to a date/time",liveLabel:"LIVE",liveActiveLabel:"● LIVE",liveTooltip:"Jump to live (now)",liveActiveTooltip:"Currently live",resetSpeedTooltip:"Reset to 1× speed",jumpToStartTooltip:"Jump to start",noStartTimeTooltip:"No start time set",jumpToEndTooltip:"Jump to end",noEndTimeTooltip:"No end time set",rewindTooltip:"Rewind",rewindActiveTooltip:e=>`Reverse ${e}× — click to speed up, press play to stop`,playTooltip:"Play",playFromRewindTooltip:"Play (reset to 1×)",pauseTooltip:"Pause",fastForwardTooltip:"Fast forward",fastForwardActiveTooltip:e=>`${e}× speed — click to increase, click again at max to reset`,collapseSwimLanesTooltip:"Collapse swim lanes",expandSwimLanesTooltip:"Expand swim lanes",months:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},Ce={backgroundColor:"#1a1a1a",tickColor:"#666666",majorTickColor:"#999999",labelColor:"#cccccc",indicatorColor:"#d69826",indicatorLineWidth:5,majorTickHeight:10,minorTickHeight:5,fontSize:12,controlBarBackground:"#242424",controlBarBorder:"#333333",buttonColor:"#666666",buttonHoverColor:"#888888",buttonActiveColor:"#d69826",swimLaneItemBorderColor:"#666666",swimLaneItemBorderWidth:0};var x=(e=>(e[e.FIFTEEN_MIN=15]="FIFTEEN_MIN",e[e.THIRTY_MIN=30]="THIRTY_MIN",e[e.HOURLY=60]="HOURLY",e[e.CUSTOM=-1]="CUSTOM",e))(x||{});const I={color:"#4da6ff",borderColor:"#2980b9",borderWidth:1,opacity:.8,markerShape:"diamond",markerSize:10,labelColor:"#cccccc",backgroundColor:"transparent"},P=24;function Ee(e){return e instanceof k.JulianDate?k.JulianDate.clone(e):k.JulianDate.fromDate(e)}function Z(e){return e instanceof k.JulianDate?k.JulianDate.toDate(e):e}function N(e){return Z(e).getTime()}function _e(e){return k.JulianDate.fromDate(new Date(e))}function me(e,t){return N(t)-N(e)}const we=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Ye=["January","February","March","April","May","June","July","August","September","October","November","December"],ee={DEFAULT:"MMM DD YYYY HH:mm:ss",TWELVE_HR:"MMM DD YYYY hh:mm:ss A",ISO:"YYYY-MM-DD HH:mm:ss",US:"MM/DD/YYYY HH:mm",EU:"DD/MM/YYYY HH:mm",TIME_ONLY:"HH:mm:ss",TIME_12:"hh:mm:ss A"},Ie={LOCAL:"local",UTC:"UTC"};function V(e,t){if(!t||t==="local"){const d=e.getFullYear(),M=e.getMonth(),D=e.getDate(),b=e.getHours(),u=b%12||12,h=e.getMinutes(),Y=e.getSeconds(),U=e.getMilliseconds();return{yr:d,mo:M,day:D,hr24:b,hr12:u,min:h,sec:Y,ms:U,ampm:b<12?"AM":"PM"}}const o=new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}),i={};for(const d of o.formatToParts(e))d.type!=="literal"&&(i[d.type]=d.value);const n=parseInt(i.year),s=parseInt(i.month)-1,c=parseInt(i.day);let r=parseInt(i.hour);r===24&&(r=0);const m=r%12||12,f=parseInt(i.minute),g=parseInt(i.second),T=e.getMilliseconds();return{yr:n,mo:s,day:c,hr24:r,hr12:m,min:f,sec:g,ms:T,ampm:r<12?"AM":"PM"}}function Pe(e,t){var n;if(!t||t==="local")return null;const o=Z(e);return((n=new Intl.DateTimeFormat("en-US",{timeZone:t,timeZoneName:"short"}).formatToParts(o).find(s=>s.type==="timeZoneName"))==null?void 0:n.value)??null}function fe(e,t=ee.DEFAULT,o){const i=Z(e),{yr:n,mo:s,day:c,hr24:r,hr12:m,min:f,sec:g,ms:T,ampm:d}=V(i,o),M=u=>String(u).padStart(2,"0"),D=u=>String(u).padStart(3,"0"),b={YYYY:String(n),YY:String(n).slice(-2),MMMM:Ye[s],MMM:we[s],MM:M(s+1),M:String(s+1),DD:M(c),D:String(c),HH:M(r),H:String(r),hh:M(m),h:String(m),mm:M(f),ss:M(g),SSS:D(T),A:d,a:d.toLowerCase()};return t.replace(/YYYY|YY|MMMM|MMM|MM|M|DD|D|HH|H|hh|h|mm|ss|SSS|A|a/g,u=>b[u]??u)}function Ne(e=ee.DEFAULT){const t=["YYYY","YY","MMMM","MMM","MM","M","DD","D"],o=["HH","H","hh","h","mm","ss","SSS","A","a"],i=c=>c.replace(/\s{2,}/g," ").trim().replace(/^[\s\W]+|[\s\W]+$/g,"").trim();let n=e;for(const c of t)n=n.replace(c,"");let s=e;for(const c of o)s=s.replace(c,"");return{timeFormat:i(n),dateFormat:i(s)}}function Re(e,t=!1){return fe(e,t?"HH:mm:ss":"HH:mm")}function ue(e,t,o,i){const n=N(e),s=N(t),c=N(o);if(c===s)return 0;const r=(n-s)/(c-s);return Math.max(0,Math.min(1,r))*i}function Fe(e,t,o,i){const n=Math.max(0,Math.min(1,e/i)),s=N(t),c=N(o),r=s+n*(c-s);return k.JulianDate.fromDate(new Date(r))}function $e(e,t,o,i){const n=[],s=me(e,t),c=N(e);let r;typeof o=="number"&&o in x||typeof o=="number"?r=o*60*1e3:r=3600*1e3;const m=r*4;let f=c,g=0;for(;f<=c+s;){const T=g*r%m===0,d=ue(new Date(f),e,t,i);let M;if(T){const D=new Date(f),b=D.getHours().toString().padStart(2,"0"),u=D.getMinutes().toString().padStart(2,"0");M=`${b}:${u}`}n.push({position:d,isMajor:T,label:M}),f+=r,g++}return n}function Oe(e,t,o=10){let i=t[0],n=Math.abs(i.position-e);for(const s of t){const c=Math.abs(s.position-e);c<n&&(n=c,i=s)}return n<=o?i.position:e}const he=1e3,Me=31536e9,y=[.001,.002,.005,.01,.02,.05,.1,.25,.5,1,2,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,21600,43200,86400,172800,345600,604800,1296e3,2592e3,5184e3,7776e3,15552e3,31536e3,63072e3,126144e3,15768e4,31536e4,63072e4,126144e4,15768e5,31536e5,63072e5,126144e5,15768e6,31536e6],z=36,F=1,Te=6,q=6,Je=.3,de=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function _(e){return e<10?`0${e}`:`${e}`}function te(e,t,o,i,n){const s=new Date(e),{yr:c,mo:r,day:m,hr24:f,hr12:g,min:T,sec:d,ms:M,ampm:D}=V(s,o),b=i?g:f,u=i?` ${D}`:"",h=n??de;if(t>31536e4)return`${c}`;if(t>31536e3)return`${h[r]} ${c}`;if(t>604800)return`${h[r]} ${m}`;if(t>86400)return`${h[r]} ${m} ${_(b)}:${_(T)}${u}`;if(t>3600)return`${_(b)}:${_(T)}${u}`;if(t>60)return`${_(b)}:${_(T)}:${_(d)}${u}`;const Y=M>0?`.${String(M).padStart(3,"0")}`:"";return`${_(b)}:${_(T)}:${_(d)}${Y}${u}`}function ge(e,t,o){const i=new Date(e);if(!o||o==="local"){const m=i.getFullYear(),f=i.getMonth(),g=i.getDate();return t>31536e4?new Date(Math.floor(m/100)*100,0).getTime():t>31536e3?new Date(Math.floor(m/10)*10,0).getTime():t>86400?new Date(m,0).getTime():new Date(m,f,g).getTime()}const{yr:n,hr24:s,min:c,sec:r}=V(i,o);return t>31536e4?Date.UTC(Math.floor(n/100)*100,0,1):t>31536e3?Date.UTC(Math.floor(n/10)*10,0,1):t>86400?Date.UTC(n,0,1):e-(s*3600+c*60+r)*1e3}function Q(e,t){return Math.ceil(e/t+.5)*t}function oe(e,t,o){var i,n,s,c,r,m,f,g,T,d,M,D;return{color:((i=t.style)==null?void 0:i.color)??((n=e.style)==null?void 0:n.color)??I.color,borderColor:((s=t.style)==null?void 0:s.borderColor)??((c=e.style)==null?void 0:c.borderColor)??(o==null?void 0:o.swimLaneItemBorderColor)??I.borderColor,borderWidth:((r=t.style)==null?void 0:r.borderWidth)??((m=e.style)==null?void 0:m.borderWidth)??(o==null?void 0:o.swimLaneItemBorderWidth)??I.borderWidth,opacity:((f=t.style)==null?void 0:f.opacity)??((g=e.style)==null?void 0:g.opacity)??I.opacity,markerShape:((T=t.style)==null?void 0:T.markerShape)??((d=e.style)==null?void 0:d.markerShape)??I.markerShape,markerSize:((M=t.style)==null?void 0:M.markerSize)??((D=e.style)==null?void 0:D.markerSize)??I.markerSize}}function ne(e){return Math.max(he,Math.min(Me,e))}function We(e,t,o){const i=t-e,n=(e+t)/2,s=ne(i*o);return{startMs:n-s/2,endMs:n+s/2}}function Ue(e,t,o,i){const n=t-e,s=ne(n*o),c=n>0?(i-e)/n:.5;return{startMs:i-c*s,endMs:i+(1-c)*s}}function ve(e){let t=0;for(const o of e)t+=(o.height??P)+F;return t}function Be(e,t,o,i,n){const{swimLanes:s,showSwimLanes:c,scrollTop:r,startMs:m,endMs:f,theme:g}=n;if(!c||s.length===0)return null;const T=Math.max(0,i-z);if(t<0||t>=T)return null;let d=-r;for(const M of s){const D=M.height??P,b=d,u=d+D;if(d+=D+F,!(t<b||t>=u)){for(const h of M.items){if(h.interval){const Y=k.JulianDate.toDate(h.interval.start).getTime(),U=k.JulianDate.toDate(h.interval.stop).getTime(),H=(Y-m)/(f-m)*o,v=(U-m)/(f-m)*o;if(e>=Math.max(0,H)&&e<=Math.min(o,v))return{lane:M,item:h}}if(h.instant){const U=(k.JulianDate.toDate(h.instant).getTime()-m)/(f-m)*o,H=oe(M,h,g);if(Math.abs(e-U)<=H.markerSize/2+2)return{lane:M,item:h}}}return null}}return null}function je(e,t,o,i){const{swimLanes:n,showSwimLanes:s,scrollTop:c}=i;if(!s||n.length===0||e>80)return null;const r=Math.max(0,o-z);if(t<0||t>=r)return null;let m=-c;for(const f of n){const g=f.height??P;if(t>=m&&t<m+g)return f;m+=g+F}return null}function ze(e,t,o){if(!o.showSwimLanes||o.swimLanes.length===0)return!1;const i=Math.max(0,t-z);return e>=0&&e<i}function Ge(e,t,o,i){const{startMs:n,endMs:s,currentMs:c,theme:r,maxTicks:m,swimLanes:f,showSwimLanes:g,reorderState:T,timezone:d,use12h:M,months:D,rangeSelection:b}=i;let{scrollTop:u}=i;const h=(s-n)/1e3;if(h<=0)return u;e.fillStyle=r.backgroundColor,e.fillRect(0,0,t,o);const Y=g&&f.length>0,H=Y?Math.max(0,o-z):0;let v=0;if(Y)for(const a of f)v+=(a.height??P)+F;const ie=Math.max(0,v-H);if(u>ie&&(u=ie),u<0&&(u=0),Y&&H>0){e.save(),e.beginPath(),e.rect(0,0,t,H),e.clip();let a=-u;const L=A=>(A-n)/(s-n)*t;for(const A of f){const p=A.height??P,E=a+p;if(E>0&&a<H){const S=A.style,B=(S==null?void 0:S.backgroundColor)??I.backgroundColor;B&&B!=="transparent"&&(e.fillStyle=B,e.fillRect(0,a,t,p)),e.strokeStyle=r.tickColor+"44",e.lineWidth=.5,e.beginPath(),e.moveTo(0,E),e.lineTo(t,E),e.stroke();for(const R of A.items){const C=oe(A,R,r);if(R.interval){const le=k.JulianDate.toDate(R.interval.start).getTime(),w=k.JulianDate.toDate(R.interval.stop).getTime(),J=L(le),W=L(w),se=Math.max(0,J),ce=Math.min(t,W)-se;if(ce>0){e.globalAlpha=C.opacity,e.fillStyle=C.color;const ye=3,De=a+ye,Le=p-ye*2;e.fillRect(se,De,ce,Le),C.borderWidth>0&&(e.strokeStyle=C.borderColor,e.lineWidth=C.borderWidth,e.strokeRect(se,De,ce,Le)),e.globalAlpha=1}}if(R.instant){const le=k.JulianDate.toDate(R.instant).getTime(),w=L(le);if(w>=-C.markerSize&&w<=t+C.markerSize){const J=a+p/2,W=C.markerSize;e.globalAlpha=C.opacity,e.fillStyle=C.color,C.markerShape==="diamond"?(e.beginPath(),e.moveTo(w,J-W/2),e.lineTo(w+W/2,J),e.lineTo(w,J+W/2),e.lineTo(w-W/2,J),e.closePath(),e.fill()):C.markerShape==="circle"?(e.beginPath(),e.arc(w,J,W/2,0,Math.PI*2),e.fill()):(e.strokeStyle=C.color,e.lineWidth=2,e.beginPath(),e.moveTo(w,a+2),e.lineTo(w,a+p-2),e.stroke()),e.globalAlpha=1}}}e.font=`${Math.min(11,p-4)}px system-ui, sans-serif`,e.textAlign="left",e.textBaseline="middle",e.fillStyle=(S==null?void 0:S.labelColor)??I.labelColor,e.fillText(A.label,Te,a+p/2)}if(a+=p+F,a>=H)break}if(T&&T.dragging){const A=T.currentY-T.dragStartY;let p=-u;for(let S=0;S<f.length&&S<T.insertIndex;S++)p+=(f[S].height??P)+F;e.strokeStyle=r.indicatorColor,e.lineWidth=2,e.beginPath(),e.moveTo(0,p),e.lineTo(t,p),e.stroke();const E=f.find(S=>S.id===T.dragLaneId);if(E){const S=E.height??P;let B=-u;for(const R of f){if(R.id===T.dragLaneId)break;B+=(R.height??P)+F}e.globalAlpha=.4,e.fillStyle=r.indicatorColor,e.fillRect(0,B+A,t,S),e.globalAlpha=1}}if(v>H){const A=t-q-2,p=H/v,E=Math.max(20,H*p),S=u/ie*(H-E);e.fillStyle=r.tickColor+"22",e.fillRect(A,0,q,H),e.fillStyle=r.tickColor+"88",e.fillRect(A,S,q,E)}e.restore()}e.font=`${r.fontSize}px monospace`;const Xe=te(n+h*500,h,d,M,D),Ke=e.measureText(Xe).width+24,Ze=Math.max(Ke/t*h,h/1e3);let $=y[y.length-1],G=y.length-1;for(let a=0;a<y.length;a++)if(y[a]>Ze){$=y[a],G=a;break}if(m!=null&&m>0)for(;G<y.length-1&&h/$>m;)G++,$=y[G];let O=0;for(let a=G-1;a>=0;a--)if($%y[a]<1e-4){t*(y[a]/h)>=3&&(O=y[a]);break}let X=0;if(O>0){for(let a=0;a<y.length&&y[a]<O;a++)if(O%y[a]<1e-4&&t*(y[a]/h)>=3){X=y[a];break}}const Se=ge(n,h,d),K=(n-Se)/1e3,re=K+h,ae=a=>t*((a-K)/h);if(X>0){e.strokeStyle=r.tickColor,e.lineWidth=1;for(let a=Math.floor(K/X)*X;a<=re;a=Q(a,X)){const L=ae(a);e.beginPath(),e.moveTo(L,o-r.minorTickHeight),e.lineTo(L,o),e.stroke()}}if(O>0){e.strokeStyle=r.tickColor,e.lineWidth=1;for(let a=Math.floor(K/O)*O;a<=re;a=Q(a,O)){const L=ae(a);e.beginPath(),e.moveTo(L,o-r.minorTickHeight),e.lineTo(L,o),e.stroke()}}e.textAlign="center",e.textBaseline="bottom";let pe=-1/0;for(let a=Math.floor(K/$)*$;a<=re+$;a=Q(a,$)){const L=ae(a),A=Se+a*1e3;e.strokeStyle=r.majorTickColor,e.lineWidth=1,e.beginPath(),e.moveTo(L,o-r.majorTickHeight),e.lineTo(L,o),e.stroke();const p=te(A,h,d,M,D),E=e.measureText(p).width,S=L-E/2;S>pe&&(e.fillStyle=r.labelColor,e.fillText(p,L,o-r.majorTickHeight-4),pe=S+E+5)}if(b){const a=(b.startMs-n)/(s-n)*t,L=(b.endMs-n)/(s-n)*t,A=Math.min(a,L),p=Math.abs(L-a);e.globalAlpha=.2,e.fillStyle=r.indicatorColor,e.fillRect(A,0,p,o),e.globalAlpha=1}const be=(c-n)/(s-n)*t;return e.strokeStyle=r.indicatorColor,e.lineWidth=r.indicatorLineWidth,e.beginPath(),e.moveTo(be,0),e.lineTo(be,o),e.stroke(),u}l.DEFAULT_LABELS=ke,l.DEFAULT_LANE_HEIGHT=P,l.DateTimeFormats=ee,l.LABEL_PAD_LEFT=Te,l.LANE_GAP=F,l.MAX_SPAN_MS=Me,l.MIN_SPAN_MS=he,l.MONTHS=de,l.SCROLLBAR_WIDTH=q,l.SWIM_LANE_SCROLL_SPEED=Je,l.TICK_AREA_HEIGHT=z,l.TIC_SCALES=y,l.TickInterval=x,l.Timezones=Ie,l.calcEpochMs=ge,l.clampSpan=ne,l.defaultSwimLaneStyle=I,l.defaultTheme=Ce,l.drawTimeline=Ge,l.formatDateTime=fe,l.formatTime=Re,l.fromMilliseconds=_e,l.generateTicks=$e,l.getDateParts=V,l.getDurationMs=me,l.getTimezoneAbbr=Pe,l.hitTestLaneLabel=je,l.hitTestSwimLane=Be,l.isInSwimLaneRegion=ze,l.makeLabel=te,l.nextTic=Q,l.positionToTime=Fe,l.resolveItemStyle=oe,l.resolveLabel=He,l.snapToTick=Oe,l.splitForDisplay=Ne,l.timeToPosition=ue,l.toDate=Z,l.toJulianDate=Ee,l.toMilliseconds=N,l.totalSwimLaneHeight=ve,l.twoD=_,l.zoomAroundMs=Ue,l.zoomRange=We,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
package/dist/index.d.ts CHANGED
@@ -177,7 +177,7 @@ export declare const LABEL_PAD_LEFT = 6;
177
177
  /** Gap in pixels between swim lane rows. */
178
178
  export declare const LANE_GAP = 1;
179
179
 
180
- export declare function makeLabel(ms: number, durationSec: number, timezone?: string): string;
180
+ export declare function makeLabel(ms: number, durationSec: number, timezone?: string, use12h?: boolean, months?: string[]): string;
181
181
 
182
182
  /** Maximum visible span: ~1 000 years — stays within TIC_SCALES range. */
183
183
  export declare const MAX_SPAN_MS = 31536000000000;
@@ -494,6 +494,32 @@ export declare interface TimelineLabels {
494
494
  collapseSwimLanesTooltip: string;
495
495
  /** Tooltip on the chevron button when swim lanes are currently hidden (click will expand). */
496
496
  expandSwimLanesTooltip: string;
497
+ /**
498
+ * Abbreviated month names used for timeline tick labels (Jan–Dec zoom levels).
499
+ * Provide all 12 entries in calendar order (January first) to translate the
500
+ * month labels shown on the canvas.
501
+ *
502
+ * @example
503
+ * ```ts
504
+ * // French
505
+ * months: ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun',
506
+ * 'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc']
507
+ * ```
508
+ */
509
+ months: [
510
+ string,
511
+ string,
512
+ string,
513
+ string,
514
+ string,
515
+ string,
516
+ string,
517
+ string,
518
+ string,
519
+ string,
520
+ string,
521
+ string
522
+ ];
497
523
  }
498
524
 
499
525
  /** Mutable state the engine reads during a draw call. */
@@ -509,6 +535,18 @@ export declare interface TimelineRenderState {
509
535
  reorderState: ReorderState | null;
510
536
  /** @see TimelineBaseProps.timezone */
511
537
  timezone?: string;
538
+ /** When true, tick labels use 12-hour (hh:mm AM/PM) format instead of 24-hour. */
539
+ use12h?: boolean;
540
+ /** Abbreviated month names for tick labels. Falls back to English when omitted. */
541
+ months?: string[];
542
+ /**
543
+ * Active range selection (set while the user is dragging to select a range).
544
+ * When non-null, a highlight is rendered over the selected time span in the tick area.
545
+ */
546
+ rangeSelection?: {
547
+ startMs: number;
548
+ endMs: number;
549
+ } | null;
512
550
  }
513
551
 
514
552
  export declare interface TimelineTheme {
@@ -559,6 +597,17 @@ export declare function totalSwimLaneHeight(lanes: SwimLane[]): number;
559
597
 
560
598
  export declare function twoD(n: number): string;
561
599
 
600
+ /**
601
+ * Compute a new visible range after zooming by `amount` around a specific
602
+ * pivot time. The pivot stays at the same fractional position on-screen,
603
+ * which is the expected behaviour for pinch-to-zoom (pivot = midpoint between
604
+ * the two fingers) and mouse-wheel zoom anchored to the cursor.
605
+ */
606
+ export declare function zoomAroundMs(startMs: number, endMs: number, amount: number, pivotMs: number): {
607
+ startMs: number;
608
+ endMs: number;
609
+ };
610
+
562
611
  /** Compute a new visible range after zooming by `amount` around the center. */
563
612
  export declare function zoomRange(startMs: number, endMs: number, amount: number): {
564
613
  startMs: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kteneyck/cesium-timeline-core",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Framework-agnostic core logic for the Cesium timeline component",
5
5
  "license": "MIT",
6
6
  "author": "kteneyck",
@@ -41,7 +41,7 @@
41
41
  ],
42
42
  "scripts": {
43
43
  "build": "vite build",
44
- "test": "vitest"
44
+ "test": "vitest run"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "cesium": "^1.100.0"