@idm-plugin/vessel 3.4.2 → 3.4.4

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/index.js CHANGED
@@ -1,19 +1,19 @@
1
- var ht = Object.defineProperty;
2
- var lt = (E, s, t) => s in E ? ht(E, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : E[s] = t;
3
- var U = (E, s, t) => (lt(E, typeof s != "symbol" ? s + "" : s, t), t);
1
+ var mt = Object.defineProperty;
2
+ var ft = (N, s, t) => s in N ? mt(N, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : N[s] = t;
3
+ var U = (N, s, t) => (ft(N, typeof s != "symbol" ? s + "" : s, t), t);
4
4
  import B from "got";
5
- import ct from "@log4js-node/log4js-api";
6
- import v from "moment";
5
+ import ut from "@log4js-node/log4js-api";
6
+ import p from "moment";
7
7
  import { LngLatHelper as z, LaneHelper as V } from "@idm-plugin/geo2";
8
- import { MeteoHelper2 as mt } from "@idm-plugin/meteo2";
9
- import { Meteo2Assist as rt } from "@idm-plugin/meteo";
8
+ import { MeteoHelper2 as yt } from "@idm-plugin/meteo2";
9
+ import { Meteo2Assist as dt } from "@idm-plugin/meteo";
10
10
  let y;
11
11
  try {
12
- y = ct.getLogger("vessel");
12
+ y = ut.getLogger("vessel");
13
13
  } catch {
14
14
  } finally {
15
15
  }
16
- class at {
16
+ class nt {
17
17
  /**
18
18
  * 解析AIS状态码
19
19
  * @param status
@@ -54,7 +54,7 @@ class at {
54
54
  return { labelCn: t, labelEn: a };
55
55
  }
56
56
  }
57
- class Tt extends at {
57
+ class Et extends nt {
58
58
  constructor(t, a) {
59
59
  super();
60
60
  U(this, "clientId");
@@ -76,12 +76,12 @@ class Tt extends at {
76
76
  expiresIn: n.expires_in,
77
77
  scope: n.scope,
78
78
  jti: n.jti,
79
- issuedAt: v().utc().format()
79
+ issuedAt: p().utc().format()
80
80
  });
81
81
  }
82
82
  async checkToken(t = {}) {
83
83
  var a;
84
- return (!this.token || v().diff(v(this.token.issuedAt), "seconds") > (((a = this.token) == null ? void 0 : a.expiresIn) || 0) - 300) && await this.authToken(t), this.token;
84
+ return (!this.token || p().diff(p(this.token.issuedAt), "seconds") > (((a = this.token) == null ? void 0 : a.expiresIn) || 0) - 300) && await this.authToken(t), this.token;
85
85
  }
86
86
  /**
87
87
  * 模糊查询
@@ -193,7 +193,7 @@ class Tt extends at {
193
193
  for (const h in e)
194
194
  !isNaN(e[h]) && Number(e[h]) !== 1 / 0 && (e[h] = Number(e[h]));
195
195
  if (e) {
196
- const h = v(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
196
+ const h = p(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
197
197
  return {
198
198
  mmsi: e.mmsi,
199
199
  name: e.vesselName || e.aisVesselName,
@@ -208,7 +208,7 @@ class Tt extends at {
208
208
  cog: e.cog,
209
209
  hdg: e.hdg,
210
210
  rot: e.rot,
211
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? v.utc(e.eta).format() : void 0,
211
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? p.utc(e.eta).format() : void 0,
212
212
  destination: e.dest,
213
213
  positionTime: h.unix(),
214
214
  status: e.status,
@@ -255,13 +255,13 @@ class Tt extends at {
255
255
  }
256
256
  async trajectory(t, a, i, n, o = !0, e = {}) {
257
257
  await this.checkToken(e);
258
- const r = await this.realTimePosition(t, e), d = v(a), h = v(i), c = [];
258
+ const r = await this.realTimePosition(t, e), d = p(a), h = p(i), c = [];
259
259
  for (; h.diff(d, "day", !0) > 30; )
260
260
  await this.trajectoryIn30Day(t, d, d.clone().add(30, "day"), r, n, c, e), d.add(30, "day");
261
261
  return await this.trajectoryIn30Day(t, d, h, r, n, c, e), c;
262
262
  }
263
263
  async trajectoryIn30Day(t, a, i, n, o, e, r = {}) {
264
- var b, j, T, g, p;
264
+ var b, j, F, g, v;
265
265
  const d = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
266
266
  headers: {
267
267
  Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(j = this.token) == null ? void 0 : j.accessToken}`
@@ -277,11 +277,11 @@ class Tt extends at {
277
277
  if (c.code)
278
278
  return y == null || y.warn("[%s] fetch trajectory failed: %j", r.requestId, d, { message: c.message, status: c.status, code: c.code }), c;
279
279
  let M = -1;
280
- const w = v(`${(g = (T = c.data) == null ? void 0 : T[0]) == null ? void 0 : g.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
281
- return (p = c.data) == null || p.forEach((f) => {
282
- for (const H in f)
283
- !isNaN(f[H]) && Number(f[H]) !== 1 / 0 && (f[H] = Number(f[H]));
284
- const u = v(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), l = f.status, { labelCn: m, labelEn: I } = this.parseStatus(l), k = {
280
+ const w = p(`${(g = (F = c.data) == null ? void 0 : F[0]) == null ? void 0 : g.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
281
+ return (v = c.data) == null || v.forEach((f) => {
282
+ for (const q in f)
283
+ !isNaN(f[q]) && Number(f[q]) !== 1 / 0 && (f[q] = Number(f[q]));
284
+ const u = p(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), l = f.status, { labelCn: m, labelEn: I } = this.parseStatus(l), k = {
285
285
  mmsi: f.mmsi,
286
286
  imo: n == null ? void 0 : n.imo,
287
287
  lat: f.lat,
@@ -291,7 +291,7 @@ class Tt extends at {
291
291
  hdg: f.hdg,
292
292
  draught: f.draught,
293
293
  status: l,
294
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta) ? v(`${f.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
294
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta) ? p(`${f.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
295
295
  destination: f.dest,
296
296
  positionTime: u.unix(),
297
297
  labelCn: m,
@@ -299,12 +299,12 @@ class Tt extends at {
299
299
  method: "trajectory",
300
300
  vendor: "myVessel",
301
301
  utc: u.utc().format()
302
- }, F = Math.floor(u.diff(w, "minute", !0) / (o || 1));
303
- F !== M && (M = F, e.push(k));
302
+ }, E = Math.floor(u.diff(w, "minute", !0) / (o || 1));
303
+ E !== M && (M = E, e.push(k));
304
304
  }), e;
305
305
  }
306
306
  }
307
- class Ft extends at {
307
+ class xt extends nt {
308
308
  constructor(t) {
309
309
  super();
310
310
  U(this, "token");
@@ -324,7 +324,7 @@ class Ft extends at {
324
324
  for (const w in e)
325
325
  !isNaN(e[w]) && Number(e[w]) !== 1 / 0 && (e[w] = Number(e[w]));
326
326
  e.status = e.sp > 3 ? 0 : 1;
327
- const r = e.status, { labelCn: d, labelEn: h } = this.parseStatus(r), c = v(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
327
+ const r = e.status, { labelCn: d, labelEn: h } = this.parseStatus(r), c = p(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
328
328
  return {
329
329
  mmsi: e.m,
330
330
  name: e.n,
@@ -339,7 +339,7 @@ class Ft extends at {
339
339
  cog: e.co,
340
340
  hdg: e.h,
341
341
  rot: isNaN(e.rot) ? 0 : e.rot,
342
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? v.utc(e.eta).format() : void 0,
342
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? p.utc(e.eta).format() : void 0,
343
343
  destination: e.destination,
344
344
  vesselType: e.type,
345
345
  dwt: e.dwt,
@@ -408,8 +408,8 @@ class Ft extends at {
408
408
  async trajectory(t, a, i, n, o = !0, e = {}) {
409
409
  var f, u, l;
410
410
  const r = await this.realTimePosition(t, e);
411
- let d = v(a);
412
- const h = v(i), c = v();
411
+ let d = p(a);
412
+ const h = p(i), c = p();
413
413
  if (o) {
414
414
  let m = h.diff(d, "d", !0);
415
415
  m < 0 ? d = h.clone().subtract(40, "d") : m < 30 ? d.subtract(10, "d") : m < 60 ? d.subtract(5, "d") : d = h.clone().subtract(80, "d"), m = c.diff(h, "d", !0), h.add(m > 10 ? 240 : m * 24, "h");
@@ -425,15 +425,15 @@ class Ft extends at {
425
425
  y == null || y.info("[%s] fetch trajectory from: %s - %j", e.requestId, w, M);
426
426
  let j;
427
427
  b && (j = ((u = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : u.ship) || [], j.length || y == null || y.warn("[%s] fetch trajectory failed: %j", e.requestId, b));
428
- const T = [];
428
+ const F = [];
429
429
  let g = -1;
430
- const p = v(`${(l = j == null ? void 0 : j[0]) == null ? void 0 : l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
430
+ const v = p(`${(l = j == null ? void 0 : j[0]) == null ? void 0 : l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
431
431
  for (const m of j) {
432
- for (const A in m)
433
- !isNaN(m[A]) && Number(m[A]) !== 1 / 0 && (m[A] = Number(m[A]));
434
- const I = v(`${m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
432
+ for (const H in m)
433
+ !isNaN(m[H]) && Number(m[H]) !== 1 / 0 && (m[H] = Number(m[H]));
434
+ const I = p(`${m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
435
435
  m.status = m.sp > 4 ? 0 : 1;
436
- const { labelEn: k, labelCn: F } = this.parseStatus(m.status), H = {
436
+ const { labelEn: k, labelCn: E } = this.parseStatus(m.status), q = {
437
437
  mmsi: m.m,
438
438
  name: m.n,
439
439
  imo: r == null ? void 0 : r.imo,
@@ -446,17 +446,17 @@ class Ft extends at {
446
446
  positionTime: I.unix(),
447
447
  utc: I.utc().format(),
448
448
  status: m.status,
449
- labelCn: F,
449
+ labelCn: E,
450
450
  labelEn: k,
451
451
  method: "trajectory",
452
452
  vendor: "hifleet"
453
- }, x = Math.floor(I.diff(p, "minute", !0) / (n || 1));
454
- x !== g && (g = x, T.push(H));
453
+ }, D = Math.floor(I.diff(v, "minute", !0) / (n || 1));
454
+ D !== g && (g = D, F.push(q));
455
455
  }
456
- return T;
456
+ return F;
457
457
  }
458
458
  }
459
- class Et extends at {
459
+ class Nt extends nt {
460
460
  constructor(t) {
461
461
  super();
462
462
  U(this, "token");
@@ -475,7 +475,7 @@ class Et extends at {
475
475
  const e = o.data[0];
476
476
  for (const M in e)
477
477
  !isNaN(e[M]) && Number(e[M]) !== 1 / 0 && (e[M] = Number(e[M]));
478
- const { labelCn: r, labelEn: d } = await this.parseStatus(e.navistat), h = v.unix(e.lasttime);
478
+ const { labelCn: r, labelEn: d } = await this.parseStatus(e.navistat), h = p.unix(e.lasttime);
479
479
  return {
480
480
  mmsi: e.ShipID,
481
481
  name: e.name,
@@ -500,8 +500,8 @@ class Et extends at {
500
500
  };
501
501
  }
502
502
  async trajectory(t, a, i, n, o = !0, e = {}) {
503
- var p;
504
- const r = await this.realTimePosition(t, e), d = v(a), h = v(i), c = "https://api.shipxy.com/apicall/GetShipTrack", M = {
503
+ var v;
504
+ const r = await this.realTimePosition(t, e), d = p(a), h = p(i), c = "https://api.shipxy.com/apicall/GetShipTrack", M = {
505
505
  searchParams: {
506
506
  id: t,
507
507
  k: this.token,
@@ -513,10 +513,10 @@ class Et extends at {
513
513
  }, w = await B.get(c, M).json();
514
514
  if (y == null || y.info("[%s] fetch trajectory from: %s - %j", e.requestId, c, M), (w == null ? void 0 : w.status) !== 0)
515
515
  return w;
516
- const b = w == null ? void 0 : w.points, j = [], T = v.unix((p = b[0]) == null ? void 0 : p.utc);
516
+ const b = w == null ? void 0 : w.points, j = [], F = p.unix((v = b[0]) == null ? void 0 : v.utc);
517
517
  let g = -1;
518
518
  for (const f of b) {
519
- const u = v.unix(f.utc), l = {
519
+ const u = p.unix(f.utc), l = {
520
520
  imo: r == null ? void 0 : r.imo,
521
521
  mmsi: t,
522
522
  sog: Math.round(f.sog * 3600 / 1e3 / 1852 * 100) / 100,
@@ -527,13 +527,13 @@ class Et extends at {
527
527
  utc: u.utc().format(),
528
528
  method: "trajectory",
529
529
  vendor: "shipxy"
530
- }, m = Math.floor(u.diff(T, "minute", !0) / (n || 1));
530
+ }, m = Math.floor(u.diff(F, "minute", !0) / (n || 1));
531
531
  m !== g && (g = m, j.push(l));
532
532
  }
533
533
  return j;
534
534
  }
535
535
  }
536
- class xt extends at {
536
+ class Dt extends nt {
537
537
  constructor(t) {
538
538
  super();
539
539
  U(this, "token");
@@ -586,7 +586,7 @@ class xt extends at {
586
586
  const d = r.data[0];
587
587
  for (const b in d)
588
588
  !isNaN(d[b]) && Number(d[b]) !== 1 / 0 && (d[b] = Number(d[b]));
589
- const { labelCn: h, labelEn: c } = await this.parseStatus(d.aisNavStatus), M = v.unix(d.posTime);
589
+ const { labelCn: h, labelEn: c } = await this.parseStatus(d.aisNavStatus), M = p.unix(d.posTime);
590
590
  return {
591
591
  ...n,
592
592
  mmsi: t,
@@ -606,13 +606,13 @@ class xt extends at {
606
606
  };
607
607
  }
608
608
  async trajectory(t, a, i, n, o = !0, e = {}) {
609
- const r = v(a), d = v(i), h = await this.getShipId(t), c = await this.getShipInfo(h), M = [];
609
+ const r = p(a), d = p(i), h = await this.getShipId(t), c = await this.getShipInfo(h), M = [];
610
610
  for (; d.diff(r, "day", !0) > 30; )
611
611
  await this.trajectoryIn30Day(h, r.unix(), r.add(30, "day").unix(), c, t, n, M);
612
612
  return await this.trajectoryIn30Day(h, r.unix(), d.unix(), c, t, n, M), M;
613
613
  }
614
614
  async trajectoryIn30Day(t, a, i, n, o, e, r, d = {}) {
615
- var T;
615
+ var F;
616
616
  const h = {
617
617
  headers: {
618
618
  appKey: this.token
@@ -628,10 +628,10 @@ class xt extends at {
628
628
  const w = M.data;
629
629
  for (const g in w)
630
630
  !isNaN(w[g]) && Number(w[g]) !== 1 / 0 && (w[g] = Number(w[g]));
631
- const b = v.unix((T = w[0]) == null ? void 0 : T.posTime);
631
+ const b = p.unix((F = w[0]) == null ? void 0 : F.posTime);
632
632
  let j = -1;
633
633
  for (const g of w) {
634
- const p = v.unix(g.posTime), f = {
634
+ const v = p.unix(g.posTime), f = {
635
635
  imo: n == null ? void 0 : n.imo,
636
636
  mmsi: o,
637
637
  lat: Math.round(g.lat / 1e4 / 60 * 1e5) / 1e5,
@@ -640,11 +640,11 @@ class xt extends at {
640
640
  cog: Math.round(g.cog / 10 * 100) / 100,
641
641
  hdg: Math.round(g.heading * 100) / 100,
642
642
  rot: Math.round(g.rot * 100) / 100,
643
- positionTime: p.unix(),
644
- utc: p.utc().format(),
643
+ positionTime: v.unix(),
644
+ utc: v.utc().format(),
645
645
  method: "trajectory",
646
646
  vendor: "myship"
647
- }, u = Math.floor(p.diff(b, "minute", !0) / (e || 1));
647
+ }, u = Math.floor(v.diff(b, "minute", !0) / (e || 1));
648
648
  u !== j && (j = u, r.push(f));
649
649
  }
650
650
  return r;
@@ -652,12 +652,12 @@ class xt extends at {
652
652
  }
653
653
  let _;
654
654
  try {
655
- _ = ct.getLogger("vessel");
655
+ _ = ut.getLogger("vessel");
656
656
  } catch {
657
657
  } finally {
658
658
  }
659
- var ft = /* @__PURE__ */ ((E) => (E.NOTICE = "NOTICE", E.WARN = "WARN", E.HEAVY = "HEAVY", E.SEVERE = "SEVERE", E.ERROR = "ERROR", E.FATAL = "FATAL", E))(ft || {});
660
- class yt {
659
+ var Mt = /* @__PURE__ */ ((N) => (N.NOTICE = "NOTICE", N.WARN = "WARN", N.HEAVY = "HEAVY", N.SEVERE = "SEVERE", N.ERROR = "ERROR", N.FATAL = "FATAL", N))(Mt || {});
660
+ class bt {
661
661
  /**
662
662
  * 解析告警规则, 多规则场景
663
663
  * @param rule
@@ -713,26 +713,26 @@ class yt {
713
713
  * @param options
714
714
  */
715
715
  checkWeather(s, t, a = {}) {
716
- var b, j, T, g, p, f, u, l, m, I, k, F, H, x, A;
716
+ var b, j, F, g, v, f, u, l, m, I, k, E, q, D, H;
717
717
  let i = 0, n = 0, o = 0, e = 0;
718
- const r = Math.round(((j = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, d = (g = (T = t == null ? void 0 : t.SEVERE) == null ? void 0 : T.sigWave) == null ? void 0 : g.number, h = (f = (p = t == null ? void 0 : t.HEAVY) == null ? void 0 : p.sigWave) == null ? void 0 : f.number, c = Math.round((((l = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : l.number) + 2) * 100) / 100, M = (I = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.wind) == null ? void 0 : I.number, w = (F = (k = t == null ? void 0 : t.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : F.number;
719
- for (let D = 0; D < (s == null ? void 0 : s.length); D++) {
720
- const N = s[D], Y = (x = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wave) == null ? void 0 : x.sig, L = (A = N == null ? void 0 : N.meteo) == null ? void 0 : A.wind, J = D ? v(N.eta).diff(v(s[D - 1].eta), "hour", !0) : 0;
721
- e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...Y, dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h }), (Y == null ? void 0 : Y.height) >= r ? N.isDangerous = !0 : (Y == null ? void 0 : Y.height) >= d ? N.isSevere = !0 : (Y == null ? void 0 : Y.height) >= h && (N.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...L, dgThd4Wd: c, svThd4Wd: M, hvThd4Wd: w }), (L == null ? void 0 : L.scale) >= c ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (L == null ? void 0 : L.scale) > M ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (L == null ? void 0 : L.scale) === w && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? J : 0, n += N.isSevere ? J : 0, o += N.isHeavy ? J : 0;
718
+ const r = Math.round(((j = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, d = (g = (F = t == null ? void 0 : t.SEVERE) == null ? void 0 : F.sigWave) == null ? void 0 : g.number, h = (f = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : f.number, c = Math.round((((l = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : l.number) + 2) * 100) / 100, M = (I = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.wind) == null ? void 0 : I.number, w = (E = (k = t == null ? void 0 : t.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : E.number;
719
+ for (let T = 0; T < (s == null ? void 0 : s.length); T++) {
720
+ const x = s[T], O = (D = (q = x == null ? void 0 : x.meteo) == null ? void 0 : q.wave) == null ? void 0 : D.sig, R = (H = x == null ? void 0 : x.meteo) == null ? void 0 : H.wind, J = T ? p(x.eta).diff(p(s[T - 1].eta), "hour", !0) : 0;
721
+ e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...O, dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h }), (O == null ? void 0 : O.height) >= r ? x.isDangerous = !0 : (O == null ? void 0 : O.height) >= d ? x.isSevere = !0 : (O == null ? void 0 : O.height) >= h && (x.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: c, svThd4Wd: M, hvThd4Wd: w }), (R == null ? void 0 : R.scale) >= c ? (x.isDangerous = !0, delete x.isSevere, delete x.isHeavy) : (R == null ? void 0 : R.scale) > M ? (x.isDangerous || (x.isSevere = !0), delete x.isHeavy) : (R == null ? void 0 : R.scale) === w && !x.isDangerous && !x.isSevere && (x.isHeavy = !0), i += x.isDangerous ? J : 0, n += x.isSevere ? J : 0, o += x.isHeavy ? J : 0;
722
722
  }
723
723
  return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, e = Math.round(e), { sample: s, dangerous: i, severe: n, heavy: o, step: e < 3 ? 3 : e, wind: { dgThd4Wd: c, svThd4Wd: M, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h } };
724
724
  }
725
725
  }
726
- const Nt = new yt();
726
+ const At = new bt();
727
727
  let C;
728
728
  try {
729
- C = ct.getLogger("vessel");
729
+ C = ut.getLogger("vessel");
730
730
  } catch {
731
731
  } finally {
732
732
  }
733
- const Mt = new mt("", !0);
734
- var bt = /* @__PURE__ */ ((E) => (E.common = "common", E.container = "container", E.tugs = "tugs", E))(bt || {}), gt = /* @__PURE__ */ ((E) => (E.Ballast = "Ballast", E.Laden = "Laden", E))(gt || {}), vt = /* @__PURE__ */ ((E) => (E.Cp = "CP", E.Perf = "Basis", E.Instruct = "Other", E))(vt || {});
735
- class R {
733
+ const gt = new yt("", !0);
734
+ var pt = /* @__PURE__ */ ((N) => (N.common = "common", N.container = "container", N.tugs = "tugs", N))(pt || {}), vt = /* @__PURE__ */ ((N) => (N.Ballast = "Ballast", N.Laden = "Laden", N))(vt || {}), wt = /* @__PURE__ */ ((N) => (N.Cp = "CP", N.Perf = "Basis", N.Instruct = "Other", N))(wt || {});
735
+ class W {
736
736
  /**
737
737
  * @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
738
738
  * 方形系数(block coefficient)
@@ -878,18 +878,18 @@ class R {
878
878
  let h;
879
879
  try {
880
880
  i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
881
- const { weatherModels: b, marineModels: j } = await rt.autoPickMeteoModel(i), T = await Mt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
881
+ const { weatherModels: b, marineModels: j } = await dt.autoPickMeteoModel(i), F = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
882
882
  ...r,
883
883
  pastDays: 1,
884
884
  forecastDays: 1,
885
885
  weatherModels: b,
886
886
  marineModels: j
887
- }), [g] = rt.pickHourly(T, a);
888
- h = rt.toLegacy(g);
887
+ }), [g] = dt.pickHourly(F, a);
888
+ h = dt.toLegacy(g);
889
889
  } catch (b) {
890
890
  C.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: i }, b);
891
891
  }
892
- const c = R.currentFactor(s.bearing, h == null ? void 0 : h.current, n), M = R.weatherFactor(s, h, c), w = Math.round((s.speed * 1.943844 + M + c) * 100) / 100;
892
+ const c = W.currentFactor(s.bearing, h == null ? void 0 : h.current, n), M = W.weatherFactor(s, h, c), w = Math.round((s.speed * 1.943844 + M + c) * 100) / 100;
893
893
  d = {
894
894
  meteo: { ...h },
895
895
  wxFactor: M,
@@ -925,10 +925,10 @@ class R {
925
925
  static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", r = !0, d = !1, h = {}) {
926
926
  t.utc();
927
927
  const c = t.clone().add(14, "days"), M = [], w = [], b = [];
928
- let j = 0, T = 0, g, p;
928
+ let j = 0, F = 0, g, v;
929
929
  for (let f = 0; f < o.length - 1; f++) {
930
930
  let u = o[f];
931
- u.distanceFromStart = Math.round((n + T) * 1e3) / 1e3;
931
+ u.distanceFromStart = Math.round((n + F) * 1e3) / 1e3;
932
932
  const l = o[f + 1];
933
933
  if (s.bearing = V.calculateBearing(u, l, !l.gcToPrevious), u.bearing = s.bearing, u.suspend && d) {
934
934
  u.eta = u.eta || t.utc().format(), u.elapsed = u.elapsed ?? 0;
@@ -936,39 +936,39 @@ class R {
936
936
  if (i - j > k)
937
937
  i = i - j - k, t.add(k, "hour"), u.elapsed = u.suspend;
938
938
  else {
939
- const F = i - j;
940
- u.elapsed += F, t.add(F, "hour"), i = 0;
939
+ const E = i - j;
940
+ u.elapsed += E, t.add(E, "hour"), i = 0;
941
941
  }
942
942
  if (C == null || C.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`, h.requestId, u), i === 0)
943
- return u.distanceFromPrevious = T, { etd: t, from: p || u, to: u, next: o.filter((F) => F), wps: M, days: w, all: b };
943
+ return u.distanceFromPrevious = F, { etd: t, from: v || u, to: u, next: o.filter((E) => E), wps: M, days: w, all: b };
944
944
  } else
945
945
  u.suspend = 0;
946
- r = t.isAfter(c) ? !1 : r, u = await R.speedLoseAt(s, u, t, e, 0, r, d, h), b.push(u), p = p || u, u.important && M.push(u), t.isSameOrAfter(a) && (w.push(u), a.add(24, "hour"));
946
+ r = t.isAfter(c) ? !1 : r, u = await W.speedLoseAt(s, u, t, e, 0, r, d, h), b.push(u), v = v || u, u.important && M.push(u), t.isSameOrAfter(a) && (w.push(u), a.add(24, "hour"));
947
947
  const m = V.calculateDistance(u, l, !l.gcToPrevious);
948
- let I = Math.round(m / p.speed * 1e5) / 1e5;
948
+ let I = Math.round(m / v.speed * 1e5) / 1e5;
949
949
  if (j + I < i) {
950
950
  if (j += I, t.add(I, "hour"), delete o[f], C == null || C.debug(
951
951
  `[%s] go to %j from %j with ${m}nm, and cost ${I} hours`,
952
952
  h.requestId,
953
953
  { lat: l.lat, lng: l.lng },
954
- { lat: p.lat, lng: p.lng, etd: p.etd }
955
- ), T += m, o.filter((k) => k).length <= 1) {
956
- g = l, g.eta = t.utc().format(), g.distanceFromPrevious = m, g.distanceFromStart = Math.round((n + T) * 1e4) / 1e4, M.push(g), b.push(g), delete o[f + 1];
954
+ { lat: v.lat, lng: v.lng, etd: v.etd }
955
+ ), F += m, o.filter((k) => k).length <= 1) {
956
+ g = l, g.eta = t.utc().format(), g.distanceFromPrevious = m, g.distanceFromStart = Math.round((n + F) * 1e4) / 1e4, M.push(g), b.push(g), delete o[f + 1];
957
957
  break;
958
958
  }
959
959
  } else {
960
960
  I = i - j, t.add(I, "hour");
961
- const k = z.roundPrecision(p.speed * I, 5);
961
+ const k = z.roundPrecision(v.speed * I, 5);
962
962
  g = V.calculateCoordinate(u, s.bearing, k, "nauticalmiles", !l.gcToPrevious), g.eta = t.utc().format(), o[f] = g, C == null || C.debug(
963
963
  `[%s] go to %j from %j with ${k}nm, and cost ${I} hours`,
964
964
  h.requestId,
965
965
  { lat: g.lat, lng: g.lng },
966
966
  { lat: u.lat, lng: u.lng, etd: u.etd }
967
- ), T += k, g.distanceFromPrevious = Math.round(T * 1e4) / 1e4, g.distanceFromStart = Math.round((n + T) * 1e4) / 1e4;
967
+ ), F += k, g.distanceFromPrevious = Math.round(F * 1e4) / 1e4, g.distanceFromStart = Math.round((n + F) * 1e4) / 1e4;
968
968
  break;
969
969
  }
970
970
  }
971
- return { etd: t, from: p, to: g, next: o.filter((f) => f), wps: M, days: w, all: b };
971
+ return { etd: t, from: v, to: g, next: o.filter((f) => f), wps: M, days: w, all: b };
972
972
  }
973
973
  /**
974
974
  * 洋流影响因子
@@ -990,15 +990,15 @@ class R {
990
990
  * @param cFactor 洋流因子
991
991
  */
992
992
  static weatherFactor(s, t, a = 0) {
993
- var w, b, j, T, g, p, f;
993
+ var w, b, j, F, g, v, f;
994
994
  C == null || C.debug("calculate weather factor via: %j", { ...s, ...t });
995
- const i = R.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = R.froudeNumber(s.speed - n, s.lbp), e = R.amendFactor(i, o, s.loadCondition);
995
+ const i = W.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = W.froudeNumber(s.speed - n, s.lbp), e = W.amendFactor(i, o, s.loadCondition);
996
996
  let r = Math.abs(s.bearing % 360 - (((w = t == null ? void 0 : t.wind) == null ? void 0 : w.degree) % 360 || 0));
997
997
  r = r > 180 ? 360 - r : r;
998
- const d = R.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), h = R.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (j = t == null ? void 0 : t.wind) == null ? void 0 : j.kts);
998
+ const d = W.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), h = W.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (j = t == null ? void 0 : t.wind) == null ? void 0 : j.kts);
999
999
  let c = d * e * h / 100 * (s.speed - n);
1000
- c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), C == null || C.debug("wind wx factor = %d", c), r = Math.abs(s.bearing % 360 - (((g = (T = t == null ? void 0 : t.wave) == null ? void 0 : T.sig) == null ? void 0 : g.degree) % 360 || 0)), r = r > 180 ? 360 - r : r;
1001
- const M = R.waveHeightFactor(((f = (p = t == null ? void 0 : t.wave) == null ? void 0 : p.sig) == null ? void 0 : f.height) ?? 1, r);
1000
+ c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), C == null || C.debug("wind wx factor = %d", c), r = Math.abs(s.bearing % 360 - (((g = (F = t == null ? void 0 : t.wave) == null ? void 0 : F.sig) == null ? void 0 : g.degree) % 360 || 0)), r = r > 180 ? 360 - r : r;
1001
+ const M = W.waveHeightFactor(((f = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : f.height) ?? 1, r);
1002
1002
  return C == null || C.debug("wave wx factor = %d", M), c = Math.abs(c) > Math.abs(M) ? c : c * 0.3 + M * 0.7, C == null || C.debug("weather factor = %d", c), c = Math.abs(c) > 3 ? 3 * (Math.abs(c) / c) + Math.abs(c) / c * (Math.abs(c) - 2) * 0.1 : c, Math.round((c || 0) * 100) / 100;
1003
1003
  }
1004
1004
  /**
@@ -1016,12 +1016,12 @@ class R {
1016
1016
  */
1017
1017
  static async analyseInstant(s, t, a, i, n, o = "", e = 0, r = !0, d = !1, h = {}) {
1018
1018
  var K, G, X, Q, Z, $, tt;
1019
- const c = v().valueOf();
1019
+ const c = p().valueOf();
1020
1020
  s.lng = z.convertToStdLng(s.lng);
1021
1021
  const { route: M, waypoints: w } = n.points, b = V.calculateSubRoute(s, M);
1022
1022
  if (((K = b[0]) == null ? void 0 : K.length) <= 1)
1023
1023
  return;
1024
- const { v0: j, label: T } = s.sog ? {
1024
+ const { v0: j, label: F } = s.sog ? {
1025
1025
  v0: s.sog,
1026
1026
  label: s.label || "Other"
1027
1027
  /* Instruct */
@@ -1029,14 +1029,14 @@ class R {
1029
1029
  v0: i.speed,
1030
1030
  label: "CP"
1031
1031
  /* Cp */
1032
- }, g = R.assembleProperties(a, i.loadCondition, j, 0), p = w.length ? V.calculateSubWaypoints(s, w) : [];
1033
- p.forEach((q) => q.important = !0);
1032
+ }, g = W.assembleProperties(a, i.loadCondition, j, 0), v = w.length ? V.calculateSubWaypoints(s, w) : [];
1033
+ v.forEach((A) => A.important = !0);
1034
1034
  const f = {
1035
1035
  from: { ...s },
1036
1036
  route: b,
1037
- waypoints: p,
1037
+ waypoints: v,
1038
1038
  v0: j,
1039
- label: T
1039
+ label: F
1040
1040
  }, u = {
1041
1041
  hours: [],
1042
1042
  days: [],
@@ -1044,15 +1044,15 @@ class R {
1044
1044
  all: []
1045
1045
  };
1046
1046
  e || (V.calculateRouteDistance(b) / i.speed <= 72 ? e = 3 : e = 6);
1047
- let l = V.simplifyRouteToCoordinates(b, p, 0), m = 0, I = 0, k = 0, F = 0;
1048
- t = v(t).utc();
1049
- const H = t.clone();
1047
+ let l = V.simplifyRouteToCoordinates(b, v, 0), m = 0, I = 0, k = 0, E = 0;
1048
+ t = p(t).utc();
1049
+ const q = t.clone();
1050
1050
  for (; l.length > 0; ) {
1051
- const q = e - t.hour() % e, W = Math.ceil(t.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, S = await R.speedLoseInHoursStep(
1051
+ const A = e - t.hour() % e, L = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, S = await W.speedLoseInHoursStep(
1052
1052
  g,
1053
1053
  t,
1054
- H,
1055
- W,
1054
+ q,
1055
+ L,
1056
1056
  m,
1057
1057
  l,
1058
1058
  o,
@@ -1061,35 +1061,37 @@ class R {
1061
1061
  h
1062
1062
  );
1063
1063
  if (u.all.push(...S.all), (G = S.from) != null && G.speed && (u.hours.push(S.from), u.wps.push(...S.wps), u.days.push(...S.days)), l = S == null ? void 0 : S.next, !l.length) {
1064
- const O = await R.speedLoseAt(g, S.to, v(S.to.eta), o, 0, r, d, h);
1065
- O.bearing = g.bearing, u.hours.push(O), u.all.push(O);
1064
+ const Y = await W.speedLoseAt(g, S.to, p(S.to.eta), o, 0, r, d, h);
1065
+ Y.bearing = g.bearing, u.hours.push(Y), u.all.push(Y);
1066
1066
  }
1067
1067
  m += Math.round((((X = S == null ? void 0 : S.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1068
1068
  }
1069
- const x = u.hours;
1070
- for (let q = 0; q < x.length - 1; q++) {
1071
- const W = v(x[q + 1].eta).diff(x[q].etd, "hour", !0) || 1;
1072
- I += (x[q].wxFactor || 0) * W, k += (x[q].cFactor || 0) * W, F += W;
1069
+ const D = u.hours;
1070
+ for (let A = 0; A < D.length - 1; A++) {
1071
+ const L = p(D[A + 1].eta).diff(D[A].etd, "hour", !0) || 1;
1072
+ I += (D[A].wxFactor || 0) * L, k += (D[A].cFactor || 0) * L, E += L;
1073
1073
  }
1074
- (Q = u.wps) == null || Q.forEach((q, W) => {
1075
- q.positionTime = v.utc(q.etd || q.eta).unix();
1076
- const S = u.wps[W - 1];
1074
+ const H = D.reduce((A, L) => A + (L.suspend || 0), 0);
1075
+ (Q = u.wps) == null || Q.forEach((A, L) => {
1076
+ A.positionTime = p.utc(A.etd || A.eta).unix();
1077
+ const S = u.wps[L - 1];
1077
1078
  if (S) {
1078
- const O = q.distanceFromStart - S.distanceFromStart, P = v(q.eta || q.etd).diff(v(S.etd || S.eta), "h", !0);
1079
- q.avgSpd = Math.round(O / P * 100) / 100, S.bearing = V.calculateBearing(S, q);
1079
+ const Y = A.distanceFromStart - S.distanceFromStart, P = p(A.eta || A.etd).diff(p(S.etd || S.eta), "h", !0);
1080
+ A.avgSpd = Math.round(Y / P * 100) / 100, S.bearing = V.calculateBearing(S, A);
1080
1081
  }
1081
- }), u.wps = (Z = u.wps) == null ? void 0 : Z.reduce((q, W) => (q.some((S) => Math.round(S.positionTime / 60) === Math.round(W.positionTime / 60)) || q.push(W), q), []), u.all = ($ = u.all) == null ? void 0 : $.reduce((q, W) => (W.positionTime = v.utc(W.etd || W.eta).unix(), q.some((S) => Math.round(S.positionTime / 60) === Math.round(W.positionTime / 60)) || q.push(W), q), []), f.sample = u;
1082
- const A = u.hours.at(0), D = u.hours.at(-1);
1083
- f.distance = Math.round(D.distanceFromStart * 1e3) / 1e3, f.etd = v(A.eta).utc().format(), f.eta = v(D.eta).utc().format(), f.wxFactor = Math.round(I / F * 1e3) / 1e3, f.cFactor = Math.round(k / F * 1e3) / 1e3, f.avgSpeed = Math.round(D.distanceFromStart / F * 1e3) / 1e3, f.totalHrs = Math.round(F * 1e3) / 1e3;
1084
- const { distanceInECA: N, hoursInECA: Y, totalDgoConsInECA: L, eca: J } = await this.calculateECA(f, i, h), et = z.roundPrecision(i.fo / 24 * (F - Y), 3), nt = z.roundPrecision(i.dgo / 24 * F, 3);
1082
+ }), u.wps = (Z = u.wps) == null ? void 0 : Z.reduce((A, L) => (A.some((S) => Math.round(S.positionTime / 60) === Math.round(L.positionTime / 60)) || A.push(L), A), []), u.all = ($ = u.all) == null ? void 0 : $.reduce((A, L) => (L.positionTime = p.utc(L.etd || L.eta).unix(), A.some((S) => Math.round(S.positionTime / 60) === Math.round(L.positionTime / 60)) || A.push(L), A), []), f.sample = u;
1083
+ const T = u.hours.at(0), x = u.hours.at(-1);
1084
+ f.distance = Math.round(x.distanceFromStart * 1e3) / 1e3, f.etd = p(T.eta).utc().format(), f.eta = p(x.eta).utc().format(), f.wxFactor = Math.round(I / E * 1e3) / 1e3, f.cFactor = Math.round(k / E * 1e3) / 1e3, f.avgSpeed = Math.round(x.distanceFromStart / E * 1e3) / 1e3, f.totalHrs = Math.round(E * 1e3) / 1e3, f.suspend = Math.round(H * 1e3) / 1e3;
1085
+ const O = z.roundPrecision(i.dgo / 24 * H, 3), { distanceInECA: R, hoursInECA: J, totalDgoConsInECA: ot, eca: et } = await this.calculateECA(f, i, h), st = z.roundPrecision(i.fo / 24 * (E - J), 3), it = z.roundPrecision(i.dgo / 24 * E + O, 3);
1085
1086
  f.extend = {
1086
- eca: J,
1087
- distanceInECA: N,
1088
- hoursInECA: Y,
1089
- totalDgoConsInECA: L
1090
- }, f.totalFoCons = et < 0 ? 0 : et, f.totalDgoCons = nt;
1091
- const st = v().valueOf() - c, it = ((tt = u == null ? void 0 : u.hours) == null ? void 0 : tt.length) || 1;
1092
- return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, st, it, Math.round(st / it * 1e3) / 1e3), f;
1087
+ eca: et,
1088
+ distanceInECA: R,
1089
+ hoursInECA: J,
1090
+ totalDgoConsInECA: ot,
1091
+ totalDgoConsInSuspend: O
1092
+ }, f.totalFoCons = st < 0 ? 0 : st, f.totalDgoCons = it;
1093
+ const at = p().valueOf() - c, ct = ((tt = u == null ? void 0 : u.hours) == null ? void 0 : tt.length) || 1;
1094
+ return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, at, ct, Math.round(at / ct * 1e3) / 1e3), f;
1093
1095
  }
1094
1096
  /**
1095
1097
  * 分段失速分析(最多走hours 小时)
@@ -1107,8 +1109,8 @@ class R {
1107
1109
  * @param options
1108
1110
  */
1109
1111
  static async analyseInstantWithThreshed(s, t, a, i, n, o, e, r = "", d = 3, h = !0, c = !1, M = {}) {
1110
- var X, Q, Z, $, tt, q, W;
1111
- const w = v().valueOf();
1112
+ var X, Q, Z, $, tt, A, L;
1113
+ const w = p().valueOf();
1112
1114
  s.lng = z.convertToStdLng(s.lng);
1113
1115
  const { v0: b, label: j } = s.sog ? {
1114
1116
  v0: s.sog,
@@ -1118,65 +1120,67 @@ class R {
1118
1120
  v0: n.speed,
1119
1121
  label: "CP"
1120
1122
  /* Cp */
1121
- }, T = R.assembleProperties(i, n.loadCondition, b, 0), g = V.calculateSubRoute(s, o);
1123
+ }, F = W.assembleProperties(i, n.loadCondition, b, 0), g = V.calculateSubRoute(s, o);
1122
1124
  if (((X = g[0]) == null ? void 0 : X.length) <= 1)
1123
1125
  return;
1124
- const p = e.length ? V.calculateSubWaypoints(s, e) : [];
1125
- p.forEach((S) => S.important = !0);
1126
- let f = V.simplifyRouteToCoordinates(g, p, 0), u = 0, l = 0, m = 0, I = 0;
1126
+ const v = e.length ? V.calculateSubWaypoints(s, e) : [];
1127
+ v.forEach((S) => S.important = !0);
1128
+ let f = V.simplifyRouteToCoordinates(g, v, 0), u = 0, l = 0, m = 0, I = 0;
1127
1129
  const k = {
1128
1130
  hours: [],
1129
1131
  wps: [],
1130
1132
  days: [],
1131
1133
  all: []
1132
1134
  };
1133
- t = v(t).utc();
1134
- const F = t.clone();
1135
+ t = p(t).utc();
1136
+ const E = t.clone();
1135
1137
  for (; f.length > 0; ) {
1136
1138
  const S = d - t.hour() % d;
1137
- let O = Math.ceil(t.clone().add(S, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1138
- O = t.clone().add(O, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : O;
1139
- const P = await R.speedLoseInHoursStep(T, t, F, O, u, f, r, h, c, M);
1140
- if (k.all.push(...P.all), (Q = P.from) != null && Q.speed && (k.hours.push(P.from), P != null && P.wps && k.wps.push(...P.wps), k.days.push(...P.days)), f = P == null ? void 0 : P.next, f.length || k.hours.push(P == null ? void 0 : P.to), u += Math.round((((Z = P == null ? void 0 : P.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !O)
1139
+ let Y = Math.ceil(t.clone().add(S, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1140
+ Y = t.clone().add(Y, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : Y;
1141
+ const P = await W.speedLoseInHoursStep(F, t, E, Y, u, f, r, h, c, M);
1142
+ if (k.all.push(...P.all), (Q = P.from) != null && Q.speed && (k.hours.push(P.from), P != null && P.wps && k.wps.push(...P.wps), k.days.push(...P.days)), f = P == null ? void 0 : P.next, f.length || k.hours.push(P == null ? void 0 : P.to), u += Math.round((((Z = P == null ? void 0 : P.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !Y)
1141
1143
  break;
1142
1144
  }
1143
- k.wps = ($ = k.wps) == null ? void 0 : $.reduce((S, O) => (S.some((P) => Math.round(v(P.etd).unix() / 60) === Math.round(v(O.etd).unix() / 60)) || S.push(O), S), []), k.all = (tt = k.all) == null ? void 0 : tt.reduce((S, O) => (O.positionTime = v.utc(O.etd || O.eta).unix(), S.some((P) => Math.round(v(P.etd).unix() / 60) === Math.round(v(O.etd).unix() / 60)) || S.push(O), S), []), (q = k.wps) == null || q.forEach((S, O) => {
1144
- const P = k.wps[O - 1];
1145
+ k.wps = ($ = k.wps) == null ? void 0 : $.reduce((S, Y) => (S.some((P) => Math.round(p(P.etd).unix() / 60) === Math.round(p(Y.etd).unix() / 60)) || S.push(Y), S), []), k.all = (tt = k.all) == null ? void 0 : tt.reduce((S, Y) => (Y.positionTime = p.utc(Y.etd || Y.eta).unix(), S.some((P) => Math.round(p(P.etd).unix() / 60) === Math.round(p(Y.etd).unix() / 60)) || S.push(Y), S), []), (A = k.wps) == null || A.forEach((S, Y) => {
1146
+ const P = k.wps[Y - 1];
1145
1147
  if (P) {
1146
- const dt = S.distanceFromStart - P.distanceFromStart, ut = v(S.eta || S.etd).diff(v(P.etd || P.eta), "h", !0);
1147
- S.avgSpd = Math.round(dt / ut * 100) / 100, P.bearing = V.calculateBearing(P, S);
1148
+ const ht = S.distanceFromStart - P.distanceFromStart, lt = p(S.eta || S.etd).diff(p(P.etd || P.eta), "h", !0);
1149
+ S.avgSpd = Math.round(ht / lt * 100) / 100, P.bearing = V.calculateBearing(P, S);
1148
1150
  }
1149
1151
  });
1150
- const H = k.hours;
1151
- for (let S = 0; S < H.length - 1; S++) {
1152
- const O = v(H[S + 1].eta).diff(H[S].etd, "hour", !0);
1153
- l += H[S].wxFactor * O, m += H[S].cFactor * O, I += O;
1152
+ const q = k.hours;
1153
+ for (let S = 0; S < q.length - 1; S++) {
1154
+ const Y = p(q[S + 1].eta).diff(q[S].etd, "hour", !0);
1155
+ l += q[S].wxFactor * Y, m += q[S].cFactor * Y, I += Y;
1154
1156
  }
1155
- const x = k.hours.at(0), A = k.hours.at(-1), D = await V.calculateRangeRoute(x, A, g), N = await V.calculateRangeWaypoints(x, A, g, p), Y = {
1157
+ const D = q.reduce((S, Y) => S + (Y.suspend || 0), 0), H = k.hours.at(0), T = k.hours.at(-1), x = await V.calculateRangeRoute(H, T, g), O = await V.calculateRangeWaypoints(H, T, g, v), R = {
1156
1158
  sample: k,
1157
- distance: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) * 1e4) / 1e4,
1159
+ distance: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) * 1e4) / 1e4,
1158
1160
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
1159
- etd: v(x.eta).utc().format(),
1160
- eta: v(A == null ? void 0 : A.eta).utc().format(),
1161
+ etd: p(H.eta).utc().format(),
1162
+ eta: p(T == null ? void 0 : T.eta).utc().format(),
1161
1163
  wxFactor: Math.round(l / I * 1e3) / 1e3,
1162
1164
  cFactor: Math.round(m / I * 1e3) / 1e3,
1163
- avgSpeed: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) / I * 1e3) / 1e3,
1165
+ avgSpeed: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) / I * 1e3) / 1e3,
1164
1166
  totalHrs: Math.round(I * 1e3) / 1e3,
1165
- from: x,
1166
- to: A,
1167
- route: D,
1168
- waypoints: N,
1167
+ suspend: Math.round(D * 1e3) / 1e3,
1168
+ from: H,
1169
+ to: T,
1170
+ route: x,
1171
+ waypoints: O,
1169
1172
  v0: b,
1170
1173
  label: j
1171
- }, { distanceInECA: L, hoursInECA: J, totalDgoConsInECA: et, eca: nt } = await this.calculateECA(Y, n, M), ot = z.roundPrecision(n.fo / 24 * (I - J), 3), st = z.roundPrecision(n.dgo / 24 * I, 3);
1172
- Y.extend = {
1173
- eca: nt,
1174
- distanceInECA: L,
1175
- hoursInECA: J,
1176
- totalDgoConsInECA: et
1177
- }, Y.totalDgoCons = st, Y.totalFoCons = ot < 0 ? 0 : ot;
1178
- const K = v().valueOf() - w, G = ((W = k == null ? void 0 : k.hours) == null ? void 0 : W.length) || 1;
1179
- return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", M == null ? void 0 : M.requestId, K, G, Math.round(K / G * 1e3) / 1e3), Y;
1174
+ }, J = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: et, totalDgoConsInECA: st, eca: it } = await this.calculateECA(R, n, M), rt = z.roundPrecision(n.fo / 24 * (I - et), 3), at = z.roundPrecision(n.dgo / 24 * I + J, 3);
1175
+ R.extend = {
1176
+ eca: it,
1177
+ distanceInECA: ot,
1178
+ hoursInECA: et,
1179
+ totalDgoConsInECA: st,
1180
+ totalDgoConsInSuspend: J
1181
+ }, R.totalDgoCons = at, R.totalFoCons = rt < 0 ? 0 : rt;
1182
+ const K = p().valueOf() - w, G = ((L = k == null ? void 0 : k.hours) == null ? void 0 : L.length) || 1;
1183
+ return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", M == null ? void 0 : M.requestId, K, G, Math.round(K / G * 1e3) / 1e3), R;
1180
1184
  }
1181
1185
  /**
1182
1186
  * 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
@@ -1194,8 +1198,8 @@ class R {
1194
1198
  * @param options
1195
1199
  */
1196
1200
  static async analyseCost(s, t, a, i, n = {}) {
1197
- var g, p;
1198
- const o = v().valueOf(), e = [];
1201
+ var g, v;
1202
+ const o = p().valueOf(), e = [];
1199
1203
  s.speedStep = s.speedStep || 3, s.alterStep = s.alterStep ?? 1;
1200
1204
  const r = V.calculateRouteDistance(i.route);
1201
1205
  let d = 0;
@@ -1203,10 +1207,10 @@ class R {
1203
1207
  const u = Math.ceil(r / f.speed / 24);
1204
1208
  d = d < u ? u : d;
1205
1209
  }), d = d * 1.3;
1206
- const h = v.utc(s.etd).add(d ?? 14, "day");
1210
+ const h = p.utc(s.etd).add(d ?? 14, "day");
1207
1211
  let c = 1;
1208
1212
  for (const f of a) {
1209
- const u = JSON.parse(JSON.stringify(i.route)), l = JSON.parse(JSON.stringify(i.waypoints)), m = await R.analyseInstantWithThreshed(
1213
+ const u = JSON.parse(JSON.stringify(i.route)), l = JSON.parse(JSON.stringify(i.waypoints)), m = await W.analyseInstantWithThreshed(
1210
1214
  { lat: s.lat, lng: s.lng },
1211
1215
  s.etd,
1212
1216
  h,
@@ -1220,7 +1224,7 @@ class R {
1220
1224
  s.useRouteParam,
1221
1225
  n
1222
1226
  );
1223
- m && (await R.calculateCost(m, f, s, n), e.push(m), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, c, s.etd, h.format(), {
1227
+ m && (await W.calculateCost(m, f, s, n), e.push(m), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, c, s.etd, h.format(), {
1224
1228
  cost: m.cost.total,
1225
1229
  hire: m.cost.hire,
1226
1230
  bunker: m.cost.bunker,
@@ -1232,20 +1236,20 @@ class R {
1232
1236
  e.sort((f, u) => f.cost.total - u.cost.total);
1233
1237
  const M = e.at(0), w = e.at(1), b = [];
1234
1238
  if (b.push({ combined: !1, speeds: [M], cost: (g = M.cost) == null ? void 0 : g.total }), w) {
1235
- const f = M.cost.cp, u = w.cost.cp, l = v(M.eta), m = v(M.etd), I = l.diff(m, "days", !0);
1239
+ const f = M.cost.cp, u = w.cost.cp, l = p(M.eta), m = p(M.etd), I = l.diff(m, "days", !0);
1236
1240
  let k = Math.ceil(I / 2);
1237
1241
  k = k > 7 ? 7 : k < s.alterStep ? s.alterStep : k;
1238
- let F = 2, H = { combined: !1, speeds: [w], cost: (p = w.cost) == null ? void 0 : p.total }, x;
1242
+ let E = 2, q = { combined: !1, speeds: [w], cost: (v = w.cost) == null ? void 0 : v.total }, D;
1239
1243
  for (; k >= s.alterStep; ) {
1240
- const A = await R.combinedAnalyse(s, t, h, [f, u], i, k, { ...n, level: F });
1241
- if (H.cost > A.cost ? x ? (x == null ? void 0 : x.cost) > A.cost && (x = A) : (x = H, H = A) : (!x || (x == null ? void 0 : x.cost) > A.cost) && (x = A), k <= s.alterStep)
1244
+ const H = await W.combinedAnalyse(s, t, h, [f, u], i, k, { ...n, level: E });
1245
+ if (q.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = q, q = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), k <= s.alterStep)
1242
1246
  break;
1243
- k = Math.ceil(k / 2), F += 1;
1247
+ k = Math.ceil(k / 2), E += 1;
1244
1248
  }
1245
- b.push(H), x && b.push(x);
1249
+ b.push(q), D && b.push(D);
1246
1250
  }
1247
- const T = v().valueOf() - o;
1248
- return C == null || C.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, T), b.sort((f, u) => f.cost - u.cost);
1251
+ const F = p().valueOf() - o;
1252
+ return C == null || C.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, F), b.sort((f, u) => f.cost - u.cost);
1249
1253
  }
1250
1254
  /**
1251
1255
  * 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
@@ -1259,7 +1263,7 @@ class R {
1259
1263
  */
1260
1264
  static async combinedAnalyse(s, t, a, i, n, o, e = {}) {
1261
1265
  e.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", e.requestId, e.level, o);
1262
- const r = await R.alternateAnalyse(s, t, a, i, 0, n, o, e), d = r.reduce((u, l) => u + l.cost.total, 0), h = r.reduce((u, l) => u + l.cost.hire, 0), c = r.reduce((u, l) => u + l.cost.bunker, 0), M = r.reduce((u, l) => u + l.distance, 0), w = r.reduce((u, l) => u + l.totalHrs, 0);
1266
+ const r = await W.alternateAnalyse(s, t, a, i, 0, n, o, e), d = r.reduce((u, l) => u + l.cost.total, 0), h = r.reduce((u, l) => u + l.cost.hire, 0), c = r.reduce((u, l) => u + l.cost.bunker, 0), M = r.reduce((u, l) => u + l.distance, 0), w = r.reduce((u, l) => u + l.totalHrs, 0);
1263
1267
  C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j", e.requestId, e.level, {
1264
1268
  cost: d,
1265
1269
  hire: h,
@@ -1267,12 +1271,12 @@ class R {
1267
1271
  distance: M,
1268
1272
  hours: w
1269
1273
  });
1270
- const b = await R.alternateAnalyse(s, t, a, i, 1, n, o, e), j = b.reduce((u, l) => u + l.cost.total, 0), T = b.reduce((u, l) => u + l.cost.hire, 0), g = b.reduce((u, l) => u + l.cost.bunker, 0), p = b.reduce((u, l) => u + l.distance, 0), f = b.reduce((u, l) => u + l.totalHrs, 0);
1274
+ const b = await W.alternateAnalyse(s, t, a, i, 1, n, o, e), j = b.reduce((u, l) => u + l.cost.total, 0), F = b.reduce((u, l) => u + l.cost.hire, 0), g = b.reduce((u, l) => u + l.cost.bunker, 0), v = b.reduce((u, l) => u + l.distance, 0), f = b.reduce((u, l) => u + l.totalHrs, 0);
1271
1275
  return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j", e.requestId, e.level, {
1272
1276
  cost: j,
1273
- hire: T,
1277
+ hire: F,
1274
1278
  bunker: g,
1275
- distance: p,
1279
+ distance: v,
1276
1280
  hours: f
1277
1281
  }), d < j ? { combined: !0, cost: Math.round(d * 1e3) / 1e3, speeds: r, step: o } : { combined: !0, cost: Math.round(j * 1e3) / 1e3, speeds: b, step: o };
1278
1282
  }
@@ -1289,24 +1293,24 @@ class R {
1289
1293
  */
1290
1294
  static async alternateAnalyse(s, t, a, i, n, o, e, r = {}) {
1291
1295
  var M, w;
1292
- let d = v.utc(s.etd);
1296
+ let d = p.utc(s.etd);
1293
1297
  const h = { lat: s.lat, lng: s.lng }, c = [];
1294
1298
  for (; d.isBefore(a); ) {
1295
- const b = d.clone().utc().add(e, "day"), j = JSON.parse(JSON.stringify(o.route)), T = JSON.parse(JSON.stringify(o.waypoints)), g = i[n], p = await R.analyseInstantWithThreshed(
1299
+ const b = d.clone().utc().add(e, "day"), j = JSON.parse(JSON.stringify(o.route)), F = JSON.parse(JSON.stringify(o.waypoints)), g = i[n], v = await W.analyseInstantWithThreshed(
1296
1300
  h,
1297
1301
  d.utc().format(),
1298
1302
  b,
1299
1303
  t,
1300
1304
  g,
1301
1305
  j,
1302
- T,
1306
+ F,
1303
1307
  s.meteoVendor,
1304
1308
  s.speedStep,
1305
1309
  s.useMeteo,
1306
1310
  s.useRouteParam,
1307
1311
  r
1308
1312
  );
1309
- p && (await R.calculateCost(p, g, s, r), C == null || C.info(
1313
+ v && (await W.calculateCost(v, g, s, r), C == null || C.info(
1310
1314
  "[%s][L%d-%d] analyse from %s to %s cost: %j",
1311
1315
  r.requestId,
1312
1316
  r.level,
@@ -1314,17 +1318,17 @@ class R {
1314
1318
  d.utc().format(),
1315
1319
  b.utc().format(),
1316
1320
  {
1317
- cost: p.cost.total,
1318
- hire: p.cost.hire,
1319
- bunker: p.cost.bunker,
1320
- distance: p.distance,
1321
- hours: p.totalHrs,
1321
+ cost: v.cost.total,
1322
+ hire: v.cost.hire,
1323
+ bunker: v.cost.bunker,
1324
+ distance: v.distance,
1325
+ hours: v.totalHrs,
1322
1326
  cp: `${g.speed}/${g.fo}/${g.dgo}`
1323
1327
  }
1324
1328
  )), r.counter = r.counter + 1;
1325
- const f = (w = (M = p == null ? void 0 : p.sample) == null ? void 0 : M.hours) == null ? void 0 : w.at(-1);
1329
+ const f = (w = (M = v == null ? void 0 : v.sample) == null ? void 0 : M.hours) == null ? void 0 : w.at(-1);
1326
1330
  if (f)
1327
- h.lat = f.lat, h.lng = f.lng, d = v(f.eta), c.push(p), n = n ? 0 : 1;
1331
+ h.lat = f.lat, h.lng = f.lng, d = p(f.eta), c.push(v), n = n ? 0 : 1;
1328
1332
  else
1329
1333
  break;
1330
1334
  }
@@ -1340,11 +1344,12 @@ class R {
1340
1344
  static async calculateCost(s, t, a, i = {}) {
1341
1345
  var n;
1342
1346
  if (s) {
1343
- const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3, r = Math.round(s.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, d = Math.round((s.totalDgoCons + (((n = s.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
1347
+ const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round((a.dailyHire || 0) * s.suspend / 24 * 1e3) / 1e3, r = Math.round(e + s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3, d = Math.round(s.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, h = Math.round((s.totalDgoCons + (((n = s.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
1344
1348
  s.cost = {
1345
- total: Math.round((e + r + d) * 1e3) / 1e3,
1346
- hire: e,
1347
- bunker: Math.round((r + d) * 1e3) / 1e3,
1349
+ total: Math.round((r + d + h) * 1e3) / 1e3,
1350
+ hire: r,
1351
+ suspendHire: e,
1352
+ bunker: Math.round((d + h) * 1e3) / 1e3,
1348
1353
  cp: t
1349
1354
  };
1350
1355
  }
@@ -1359,7 +1364,7 @@ class R {
1359
1364
  const i = await V.intersectInECA((s == null ? void 0 : s.route) || []);
1360
1365
  let n = 0, o = 0, e = 0;
1361
1366
  (d = (r = s == null ? void 0 : s.sample) == null ? void 0 : r.wps) == null || d.forEach((M) => {
1362
- M.positionTime = v.utc(M.etd || M.eta).unix();
1367
+ M.positionTime = p.utc(M.etd || M.eta).unix();
1363
1368
  });
1364
1369
  for (const M of i) {
1365
1370
  n += M.distance;
@@ -1393,41 +1398,41 @@ class R {
1393
1398
  }, 0), r = s.reduce((l, m) => {
1394
1399
  var I;
1395
1400
  return l + (((I = m.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
1396
- }, 0), d = s.reduce((l, m) => l + m.wxFactor * m.totalHrs / o, 0), h = s.reduce((l, m) => l + m.cFactor * m.totalHrs / o, 0), c = s.reduce((l, m) => l + m.totalFoCons, 0), M = s.reduce((l, m) => l + m.totalDgoCons, 0), w = s.reduce((l, m) => l + m.cost.total, 0), b = s.reduce((l, m) => l + m.cost.hire, 0), j = s.reduce((l, m) => l + m.cost.bunker, 0), T = [], g = [];
1397
- let p;
1401
+ }, 0), d = s.reduce((l, m) => l + m.wxFactor * m.totalHrs / o, 0), h = s.reduce((l, m) => l + m.cFactor * m.totalHrs / o, 0), c = s.reduce((l, m) => l + m.totalFoCons, 0), M = s.reduce((l, m) => l + m.totalDgoCons, 0), w = s.reduce((l, m) => l + m.cost.total, 0), b = s.reduce((l, m) => l + m.cost.hire, 0), j = s.reduce((l, m) => l + m.cost.bunker, 0), F = [], g = [];
1402
+ let v;
1398
1403
  for (const l of s) {
1399
1404
  g.push(...((f = l.extend) == null ? void 0 : f.eca) || []);
1400
- const m = l.sample.hours, I = l.sample.wps, k = l.sample.days, F = m.at(0);
1401
- p && (F.distanceFromPrevious = p.distanceFromPrevious, F.distanceFromStart = p.distanceFromStart, m.forEach((D, N) => {
1402
- N && (D.distanceFromStart = D.distanceFromStart + p.distanceFromStart);
1403
- }), I.at(0).distanceFromPrevious = p.distanceFromPrevious, I.at(0).distanceFromStart = p.distanceFromStart, I.forEach((D, N) => {
1404
- N && (D.distanceFromStart = D.distanceFromStart + p.distanceFromStart);
1405
- }), k.at(0).distanceFromPrevious = p.distanceFromPrevious, k.at(0).distanceFromStart = p.distanceFromStart, k.forEach((D, N) => {
1406
- N && (D.distanceFromStart = D.distanceFromStart + p.distanceFromStart);
1407
- })), F.cp = l.cost.cp;
1408
- const H = [l.etd, l.eta], x = T.findIndex((D) => D.id === F.cp.id);
1409
- x === -1 ? (F.cp.segment = [H], T.push(F.cp)) : T[x].segment.push(H), m.forEach((D) => {
1410
- var Y;
1411
- ((Y = a.hours) == null ? void 0 : Y.findIndex((L) => L.eta === D.eta)) === -1 && a.hours.push(D);
1412
- }), I.forEach((D) => {
1413
- var Y;
1414
- ((Y = a.wps) == null ? void 0 : Y.findIndex((L) => L.eta === D.eta)) === -1 && a.wps.push(D);
1415
- }), k.forEach((D) => {
1416
- var Y;
1417
- ((Y = a == null ? void 0 : a.days) == null ? void 0 : Y.findIndex((L) => L.eta === D.eta)) === -1 && a.days.push(D);
1405
+ const m = l.sample.hours, I = l.sample.wps, k = l.sample.days, E = m.at(0);
1406
+ v && (E.distanceFromPrevious = v.distanceFromPrevious, E.distanceFromStart = v.distanceFromStart, m.forEach((T, x) => {
1407
+ x && (T.distanceFromStart = T.distanceFromStart + v.distanceFromStart);
1408
+ }), I.at(0).distanceFromPrevious = v.distanceFromPrevious, I.at(0).distanceFromStart = v.distanceFromStart, I.forEach((T, x) => {
1409
+ x && (T.distanceFromStart = T.distanceFromStart + v.distanceFromStart);
1410
+ }), k.at(0).distanceFromPrevious = v.distanceFromPrevious, k.at(0).distanceFromStart = v.distanceFromStart, k.forEach((T, x) => {
1411
+ x && (T.distanceFromStart = T.distanceFromStart + v.distanceFromStart);
1412
+ })), E.cp = l.cost.cp;
1413
+ const q = [l.etd, l.eta], D = F.findIndex((T) => T.id === E.cp.id);
1414
+ D === -1 ? (E.cp.segment = [q], F.push(E.cp)) : F[D].segment.push(q), m.forEach((T) => {
1415
+ var O;
1416
+ ((O = a.hours) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.hours.push(T);
1417
+ }), I.forEach((T) => {
1418
+ var O;
1419
+ ((O = a.wps) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.wps.push(T);
1420
+ }), k.forEach((T) => {
1421
+ var O;
1422
+ ((O = a == null ? void 0 : a.days) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.days.push(T);
1418
1423
  });
1419
- const A = (u = a.wps) == null ? void 0 : u.findIndex((D) => D.eta === F.eta);
1420
- A === -1 ? a.wps.push(F) : a.wps[A] = F, p = m.at(-1);
1424
+ const H = (u = a.wps) == null ? void 0 : u.findIndex((T) => T.eta === E.eta);
1425
+ H === -1 ? a.wps.push(E) : a.wps[H] = E, v = m.at(-1);
1421
1426
  }
1422
1427
  return a.wps.sort((l, m) => {
1423
- v(l.etd).unix() - v(m.etd).unix();
1428
+ p(l.etd).unix() - p(m.etd).unix();
1424
1429
  }), a.wps.forEach((l, m) => {
1425
1430
  const I = a.wps[m - 1];
1426
1431
  if (I) {
1427
- const k = l.distanceFromStart - (I.distanceFromStart || 0), F = v(l.eta || l.etd).diff(v(I.etd || I.eta), "hour", !0), H = Math.round(k / F * 100) / 100;
1428
- l.avgSpd = H;
1429
- const x = V.calculateBearing(I, l);
1430
- I.bearing = x;
1432
+ const k = l.distanceFromStart - (I.distanceFromStart || 0), E = p(l.eta || l.etd).diff(p(I.etd || I.eta), "hour", !0), q = Math.round(k / E * 100) / 100;
1433
+ l.avgSpd = q;
1434
+ const D = V.calculateBearing(I, l);
1435
+ I.bearing = D;
1431
1436
  }
1432
1437
  }), {
1433
1438
  sample: a,
@@ -1450,7 +1455,7 @@ class R {
1450
1455
  bunker: Math.round(j * 1e3) / 1e3
1451
1456
  },
1452
1457
  extend: {
1453
- cps: T,
1458
+ cps: F,
1454
1459
  eca: g,
1455
1460
  distanceInECA: Math.round(n * 1e3) / 1e3,
1456
1461
  hoursInECA: Math.round(e * 1e3) / 1e3,
@@ -1461,16 +1466,16 @@ class R {
1461
1466
  }
1462
1467
  }
1463
1468
  export {
1464
- at as AISImpl,
1465
- yt as AlertHelper,
1466
- ft as AlertLevel,
1467
- Ft as HifleetImpl,
1468
- gt as LoadCondition,
1469
- xt as MyShipImpl,
1470
- Tt as MyVesselImpl,
1471
- Et as ShipxyImpl,
1472
- R as SpeedHelper,
1473
- vt as SpeedLabel,
1474
- bt as VesselTag,
1475
- Nt as alertHelper
1469
+ nt as AISImpl,
1470
+ bt as AlertHelper,
1471
+ Mt as AlertLevel,
1472
+ xt as HifleetImpl,
1473
+ vt as LoadCondition,
1474
+ Dt as MyShipImpl,
1475
+ Et as MyVesselImpl,
1476
+ Nt as ShipxyImpl,
1477
+ W as SpeedHelper,
1478
+ wt as SpeedLabel,
1479
+ pt as VesselTag,
1480
+ At as alertHelper
1476
1481
  };
@@ -1 +1 @@
1
- (function(Y,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],D):(Y=typeof globalThis<"u"?globalThis:Y||self,D(Y["idm-plugin-vessel"]={},Y.got,Y["@log4js-node/log4js-api"],Y.moment,Y["@idm-plugin/geo2"],Y["@idm-plugin/meteo2"],Y["@idm-plugin/meteo"]))})(this,function(Y,D,U,v,H,mt,ot){"use strict";var It=Object.defineProperty;var St=(Y,D,U)=>D in Y?It(Y,D,{enumerable:!0,configurable:!0,writable:!0,value:U}):Y[D]=U;var K=(Y,D,U)=>(St(Y,typeof D!="symbol"?D+"":D,U),U);let y;try{y=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(s){let t,a;switch(s){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class yt extends G{constructor(t,a){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await D.post(a,i).json();y==null||y.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async checkToken(t={}){var a;return(!this.token||v().diff(v(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var e,r;await this.checkToken(a);const i="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};y==null||y.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,i,n);const o=await D.post(i,n).json();return o.status!==200?(y==null||y.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),[]):(o.data||[]).map(l=>({mmsi:l.mmsi,name:l.nameEn,nameCn:l.nameCn,imo:Number.isNaN(l.imo)?null:Number(l.imo),callSign:l.callsign,type:l.vesselTypeNameEn,flagName:l.flagCtry,vendor:"myvessel",raw:l}))}async search(t,a={}){var d,l;await this.checkToken(a);const i=/^\d{7}$/.test(t.toString()),n=i?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",o=i?{imo:t}:{mmsi:t},e={headers:{Authorization:`${(d=this.token)==null?void 0:d.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:o};y==null||y.info("[%s] fetch vessel from: %s - %j",a.requestId,n,e);const r=await D.get(n,e).json();if(r.status!==200)return y==null||y.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const c=r.data;if(c)return{mmsi:c.mmsi,imo:Number.isNaN(c.imo)?null:Number(c.imo),callSign:c.callsign,name:c.nameEn,nameCn:c.nameCn,type:c.vesselTypeNameEn,flagName:c.flagCtry,clasz:c.classSociety,dateOfBuild:c.buildYearMonth,deadweight:c.dwt,grossTonnage:c.grt,netTonnage:c.net,teu:c.teu,length:c.length,breadth:c.width,height:c.height,draught:c.draught,speed:c.speed,passengerCapacity:c.passengercapacity,vendor:"myvessel",raw:c}}return{}}async archives(t,a={}){var e,r;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};y==null||y.info("[%s] fetch vessel archive from: %s - %j",a.requestId,i,n);const o=await D.post(i,n).json();return o.status!==200?(y==null||y.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),{}):o.data}async realTimePosition(t,a={}){var r,d;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},searchParams:{mmsi:t}};y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await D.get(i,n).json();if(o.code)return y==null||y.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),o;const e=o.data;for(const l in e)!isNaN(e[l])&&Number(e[l])!==1/0&&(e[l]=Number(e[l]));if(e){const l=v(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName||e.aisVesselName,imo:e.imo,callSign:e.callsign||e.aisCallSign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.dest,positionTime:l.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,vesselType:e.vesselTypeNameEn,flag:e.flagCtryNameEn,clasz:e.classSociety,build:e.buildYear,dwt:e.dwt,grt:e.grt,net:e.net,method:"position",vendor:"myVessel",utc:l.utc().format()}}else return{}}async calculateRoute(t,a,i={}){var r,d;await this.checkToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},json:{startPoint:{lon:t.lng,lat:t.lat},endPoint:{lon:a.lng,lat:a.lat},maxDraught:i.maxDraught||10,useAIModel:i.useAIModel||!1,withECA:i.withECA||!1}};y==null||y.info("[%s] fetch route from: %s - %j",i.requestId,n,o);const e=await D.post(n,o).json();return e.status!==200?(y==null||y.warn("[%s] fetch route failed: %j",i.requestId,{message:e.message,status:e.status,code:e.code}),{}):e.data}async trajectory(t,a,i,n,o=!0,e={}){await this.checkToken(e);const r=await this.realTimePosition(t,e),d=v(a),l=v(i),c=[];for(;l.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(t,d,d.clone().add(30,"day"),r,n,c,e),d.add(30,"day");return await this.trajectoryIn30Day(t,d,l,r,n,c,e),c}async trajectoryIn30Day(t,a,i,n,o,e,r={}){var M,C,T,b,g;const d="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(C=this.token)==null?void 0:C.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};y==null||y.info("[%s] fetch trajectory from: %s - %j",r.requestId,d,l);const c=await D.post(d,l).json();if(c.code)return y==null||y.warn("[%s] fetch trajectory failed: %j",r.requestId,d,{message:c.message,status:c.status,code:c.code}),c;let p=-1;const w=v(`${(b=(T=c.data)==null?void 0:T[0])==null?void 0:b.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=c.data)==null||g.forEach(m=>{for(const R in m)!isNaN(m[R])&&Number(m[R])!==1/0&&(m[R]=Number(m[R]));const u=v(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),h=m.status,{labelCn:f,labelEn:I}=this.parseStatus(h),k={mmsi:m.mmsi,imo:n==null?void 0:n.imo,lat:m.lat,lng:m.lon,sog:m.sog,cog:m.cog,hdg:m.hdg,draught:m.draught,status:h,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta)?v(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:m.dest,positionTime:u.unix(),labelCn:f,labelEn:I,method:"trajectory",vendor:"myVessel",utc:u.utc().format()},F=Math.floor(u.diff(w,"minute",!0)/(o||1));F!==p&&(p=F,e.push(k))}),e}}class pt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},o=await D.post(i,n).json();y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const e=o==null?void 0:o.list;if(!e)return y==null||y.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const w in e)!isNaN(e[w])&&Number(e[w])!==1/0&&(e[w]=Number(e[w]));e.status=e.sp>3?0:1;const r=e.status,{labelCn:d,labelEn:l}=this.parseStatus(r),c=v(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.destination,vesselType:e.type,dwt:e.dwt,build:e.buildyear,flag:e.fn,positionTime:c.unix(),utc:c.utc().format(),status:r,labelCn:d,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,a={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let o=await D.post(i,n).json();y==null||y.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]);for(const r in o)!isNaN(o[r])&&Number(o[r])!==1/0&&(o[r]=Number(o[r]));const e={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await D.post(i,n).json(),y==null||y.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(e.deadweight=Number(o.dwt)),e}async suggest(t,a={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},o=await D.post(i,n).json();y==null||y.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const e=[];for(const r of o)e.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return e.sort((r,d)=>d.score-r.score),e}async trajectory(t,a,i,n,o=!0,e={}){var m,u,h;const r=await this.realTimePosition(t,e);let d=v(a);const l=v(i),c=v();if(o){let f=l.diff(d,"d",!0);f<0?d=l.clone().subtract(40,"d"):f<30?d.subtract(10,"d"):f<60?d.subtract(5,"d"):d=l.clone().subtract(80,"d"),f=c.diff(l,"d",!0),l.add(f>10?240:f*24,"h")}const p={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},w="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",M=await D.get(w,p).json();y==null||y.info("[%s] fetch trajectory from: %s - %j",e.requestId,w,p);let C;M&&(C=((u=(m=M.ships)==null?void 0:m.offors)==null?void 0:u.ship)||[],C.length||y==null||y.warn("[%s] fetch trajectory failed: %j",e.requestId,M));const T=[];let b=-1;const g=v(`${(h=C==null?void 0:C[0])==null?void 0:h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const f of C){for(const L in f)!isNaN(f[L])&&Number(f[L])!==1/0&&(f[L]=Number(f[L]));const I=v(`${f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");f.status=f.sp>4?0:1;const{labelEn:k,labelCn:F}=this.parseStatus(f.status),R={mmsi:f.m,name:f.n,imo:r==null?void 0:r.imo,lat:f.la,lng:f.lo,draught:f.draught,sog:f.sp,cog:f.co,hdg:f.hdg,positionTime:I.unix(),utc:I.utc().format(),status:f.status,labelCn:F,labelEn:k,method:"trajectory",vendor:"hifleet"},E=Math.floor(I.diff(g,"minute",!0)/(n||1));E!==b&&(b=E,T.push(R))}return T}}class Mt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",o=await D.get(n,i).json();if(y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const e=o.data[0];for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const{labelCn:r,labelEn:d}=await this.parseStatus(e.navistat),l=v.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:l.utc().format(),status:e.navistat,labelEn:d,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,i,n,o=!0,e={}){var g;const r=await this.realTimePosition(t,e),d=v(a),l=v(i),c="https://api.shipxy.com/apicall/GetShipTrack",p={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:d.unix(),etm:l.unix()}},w=await D.get(c,p).json();if(y==null||y.info("[%s] fetch trajectory from: %s - %j",e.requestId,c,p),(w==null?void 0:w.status)!==0)return w;const M=w==null?void 0:w.points,C=[],T=v.unix((g=M[0])==null?void 0:g.utc);let b=-1;for(const m of M){const u=v.unix(m.utc),h={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(m.sog*3600/1e3/1852*100)/100,cog:Math.round(m.cog/100*100)/100,lat:Math.round(m.lat/1e6*1e5)/1e5,lng:Math.round(m.lon/1e6*1e5)/1e5,positionTime:u.unix(),utc:u.utc().format(),method:"trajectory",vendor:"shipxy"},f=Math.floor(u.diff(T,"minute",!0)/(n||1));f!==b&&(b=f,C.push(h))}return C}}class bt extends G{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,a={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",o=await D.post(n,i).json();return y==null||y.info("[%s] fetch ship id from: %s - %j",a.requestId,n,i),o.code!=="0"?o:o.data[0].shipId}async getShipInfo(t,a={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",o=await D.post(n,i).json();if(y==null||y.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const e=o.data;let r=e.imo;return t==="407170"&&(r="9198379",y==null||y.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,e.imo,r)),{mmsi:e.mmsi,name:e.shipnameEn,imo:r,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,a={}){const i=await this.getShipId(t,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},e="https://api3.myships.com/sp/ships/position/latest",r=await D.post(e,o).json();y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,e,o);const d=r.data[0];for(const M in d)!isNaN(d[M])&&Number(d[M])!==1/0&&(d[M]=Number(d[M]));const{labelCn:l,labelEn:c}=await this.parseStatus(d.aisNavStatus),p=v.unix(d.posTime);return{...n,mmsi:t,lat:Math.round(d.lat/1e4/60*1e5)/1e5,lng:Math.round(d.lon/1e4/60*1e5)/1e5,sog:Math.round(d.sog/10*100)/100,cog:Math.round(d.cog/10*100)/100,hdg:Math.round(d.heading*100)/100,rot:Math.round(d.rot*100)/100,positionTime:d.posTime,utc:p.utc().format(),status:d.aisNavStatus,labelEn:c,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,a,i,n,o=!0,e={}){const r=v(a),d=v(i),l=await this.getShipId(t),c=await this.getShipInfo(l),p=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(l,r.unix(),r.add(30,"day").unix(),c,t,n,p);return await this.trajectoryIn30Day(l,r.unix(),d.unix(),c,t,n,p),p}async trajectoryIn30Day(t,a,i,n,o,e,r,d={}){var T;const l={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:i}},c="https://api3.myships.com/sp/ships/position/history",p=await D.post(c,l).json();if(y==null||y.info("[%s] fetch trajectory from: %s - %j",d.requestId,c,l),p.code!=="0")return y==null||y.warn("[%s] invoke myship trajectory failed: %j",d.requestId,p),p;const w=p.data;for(const b in w)!isNaN(w[b])&&Number(w[b])!==1/0&&(w[b]=Number(w[b]));const M=v.unix((T=w[0])==null?void 0:T.posTime);let C=-1;for(const b of w){const g=v.unix(b.posTime),m={imo:n==null?void 0:n.imo,mmsi:o,lat:Math.round(b.lat/1e4/60*1e5)/1e5,lng:Math.round(b.lon/1e4/60*1e5)/1e5,sog:Math.round(b.sog/10*100)/100,cog:Math.round(b.cog/10*100)/100,hdg:Math.round(b.heading*100)/100,rot:Math.round(b.rot*100)/100,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"myship"},u=Math.floor(g.diff(M,"minute",!0)/(e||1));u!==C&&(C=u,r.push(m))}return r}}let _;try{_=U.getLogger("vessel")}catch{}finally{}var dt=(q=>(q.NOTICE="NOTICE",q.WARN="WARN",q.HEAVY="HEAVY",q.SEVERE="SEVERE",q.ERROR="ERROR",q.FATAL="FATAL",q))(dt||{});class ut{parsePrinciple(s,t={}){var e,r,d;_==null||_.debug("[%s] parse rule: %s",t.requestId,s);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=s.match(a)?(e=s.match(a))==null?void 0:e[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let l=0;l<(n==null?void 0:n.length);l++){const c=(d=(r=n[l].match(a))==null?void 0:r[0])==null?void 0:d.split("],");if(l===0&&!c)o.scope=n[0];else if(c)for(let p=0,w=c.length;p<w;p++){const M=this.parseRule(c[p]);M&&(o[M.level]?M.key?o[M.level][M==null?void 0:M.key]=M:o[M.level]=M:M.key?o[M.level]={[M==null?void 0:M.key]:M}:o[M.level]=M)}}return o}parseRule(s,t={}){var o;_==null||_.debug("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=s==null?void 0:s.match(a))==null?void 0:o[0],n=i==null?void 0:i.split(",");if(n){let e=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return e=isNaN(e)?1:e,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:e,key:n[4]}}}checkWeather(s,t,a={}){var M,C,T,b,g,m,u,h,f,I,k,F,R,E,L;let i=0,n=0,o=0,e=0;const r=Math.round(((C=(M=t==null?void 0:t.SEVERE)==null?void 0:M.sigWave)==null?void 0:C.number)*1.6*100)/100,d=(b=(T=t==null?void 0:t.SEVERE)==null?void 0:T.sigWave)==null?void 0:b.number,l=(m=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:m.number,c=Math.round((((h=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:h.number)+2)*100)/100,p=(I=(f=t==null?void 0:t.SEVERE)==null?void 0:f.wind)==null?void 0:I.number,w=(F=(k=t==null?void 0:t.HEAVY)==null?void 0:k.wind)==null?void 0:F.number;for(let x=0;x<(s==null?void 0:s.length);x++){const N=s[x],O=(E=(R=N==null?void 0:N.meteo)==null?void 0:R.wave)==null?void 0:E.sig,B=(L=N==null?void 0:N.meteo)==null?void 0:L.wind,J=x?v(N.eta).diff(v(s[x-1].eta),"hour",!0):0;e=J>e?J:e,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...O,dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}),(O==null?void 0:O.height)>=r?N.isDangerous=!0:(O==null?void 0:O.height)>=d?N.isSevere=!0:(O==null?void 0:O.height)>=l&&(N.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:c,svThd4Wd:p,hvThd4Wd:w}),(B==null?void 0:B.scale)>=c?(N.isDangerous=!0,delete N.isSevere,delete N.isHeavy):(B==null?void 0:B.scale)>p?(N.isDangerous||(N.isSevere=!0),delete N.isHeavy):(B==null?void 0:B.scale)===w&&!N.isDangerous&&!N.isSevere&&(N.isHeavy=!0),i+=N.isDangerous?J:0,n+=N.isSevere?J:0,o+=N.isHeavy?J:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,e=Math.round(e),{sample:s,dangerous:i,severe:n,heavy:o,step:e<3?3:e,wind:{dgThd4Wd:c,svThd4Wd:p,hvThd4Wd:w},sig:{dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}}}}const vt=new ut;let j;try{j=U.getLogger("vessel")}catch{}finally{}const gt=new mt.MeteoHelper2("",!0);var lt=(q=>(q.common="common",q.container="container",q.tugs="tugs",q))(lt||{}),ht=(q=>(q.Ballast="Ballast",q.Laden="Laden",q))(ht||{}),ft=(q=>(q.Cp="CP",q.Perf="Basis",q.Instruct="Other",q))(ft||{});class V{static blockCoefficient(s,t,a,i){let n=Math.round(s/(t*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],e=o.map(r=>Math.abs(r-n));return o[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,a=9.8){let i=Math.round(Math.sqrt(s*s/(a*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(s,t,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return a==="Laden"&&(o=i[s]),o[0]+o[1]*t+o[2]*Math.pow(t,2)}static directionFactor(s,t=0){let a;return s>30&&s<=60?a=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?a=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(s,t,a,i){let n;return a==="container"?n=.7*i/2+Math.pow(i,3)/(22*Math.pow(s,2/3)):t==="Ballast"?n=.7*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)):n=.5*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)),n}static waveHeightFactor(s,t){s=s<3?s*.7:s,s=s<0?.2:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=s<3?.4:-.3:t>120&&t<=150?a=s<3?.6:-.5:t>150&&t<=180?a=s<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(s,2)+.278*s)*1e4)/1e4}static assembleProperties(s,t,a,i){var p;const n=s.lbp??s.length??s.lengthOverall??198.9642,o=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,r=s.deadweight??67035.7773,d=((p=s==null?void 0:s.type)==null?void 0:p.toLowerCase())||"common";return{tag:d.indexOf("container")>-1?"container":d.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:o,breadthMoulded:e,displacement:Math.round((r/1.025+o*e*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(s,t,a,i="",n=2,o=!0,e=!1,r={}){let d;if(t.velocity&&e&&(s.speed=H.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),o){let l;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:M,marineModels:C}=await ot.Meteo2Assist.autoPickMeteoModel(i),T=await gt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:M,marineModels:C}),[b]=ot.Meteo2Assist.pickHourly(T,a);l=ot.Meteo2Assist.toLegacy(b)}catch(M){j.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:i},M)}const c=V.currentFactor(s.bearing,l==null?void 0:l.current,n),p=V.weatherFactor(s,l,c),w=Math.round((s.speed*1.943844+p+c)*100)/100;d={meteo:{...l},wxFactor:p,cFactor:c,speed:t.velocity&&e?t.velocity:w<0?1:w,eta:a.utc().format(),etd:a.utc().format()}}else d={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round(s.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...d,...t}}static async speedLoseInHoursStep(s,t,a,i,n,o,e="",r=!0,d=!1,l={}){t.utc();const c=t.clone().add(14,"days"),p=[],w=[],M=[];let C=0,T=0,b,g;for(let m=0;m<o.length-1;m++){let u=o[m];u.distanceFromStart=Math.round((n+T)*1e3)/1e3;const h=o[m+1];if(s.bearing=H.LaneHelper.calculateBearing(u,h,!h.gcToPrevious),u.bearing=s.bearing,u.suspend&&d){u.eta=u.eta||t.utc().format(),u.elapsed=u.elapsed??0;const k=u.suspend-u.elapsed;if(i-C>k)i=i-C-k,t.add(k,"hour"),u.elapsed=u.suspend;else{const F=i-C;u.elapsed+=F,t.add(F,"hour"),i=0}if(j==null||j.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,u),i===0)return u.distanceFromPrevious=T,{etd:t,from:g||u,to:u,next:o.filter(F=>F),wps:p,days:w,all:M}}else u.suspend=0;r=t.isAfter(c)?!1:r,u=await V.speedLoseAt(s,u,t,e,0,r,d,l),M.push(u),g=g||u,u.important&&p.push(u),t.isSameOrAfter(a)&&(w.push(u),a.add(24,"hour"));const f=H.LaneHelper.calculateDistance(u,h,!h.gcToPrevious);let I=Math.round(f/g.speed*1e5)/1e5;if(C+I<i){if(C+=I,t.add(I,"hour"),delete o[m],j==null||j.debug(`[%s] go to %j from %j with ${f}nm, and cost ${I} hours`,l.requestId,{lat:h.lat,lng:h.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),T+=f,o.filter(k=>k).length<=1){b=h,b.eta=t.utc().format(),b.distanceFromPrevious=f,b.distanceFromStart=Math.round((n+T)*1e4)/1e4,p.push(b),M.push(b),delete o[m+1];break}}else{I=i-C,t.add(I,"hour");const k=H.LngLatHelper.roundPrecision(g.speed*I,5);b=H.LaneHelper.calculateCoordinate(u,s.bearing,k,"nauticalmiles",!h.gcToPrevious),b.eta=t.utc().format(),o[m]=b,j==null||j.debug(`[%s] go to %j from %j with ${k}nm, and cost ${I} hours`,l.requestId,{lat:b.lat,lng:b.lng},{lat:u.lat,lng:u.lng,etd:u.etd}),T+=k,b.distanceFromPrevious=Math.round(T*1e4)/1e4,b.distanceFromStart=Math.round((n+T)*1e4)/1e4;break}}return{etd:t,from:g,to:b,next:o.filter(m=>m),wps:p,days:w,all:M}}static currentFactor(s,t,a=0){const i=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(s,t,a=0){var w,M,C,T,b,g,m;j==null||j.debug("calculate weather factor via: %j",{...s,...t});const i=V.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=H.LngLatHelper.roundPrecision(a*1852/3600,6),o=V.froudeNumber(s.speed-n,s.lbp),e=V.amendFactor(i,o,s.loadCondition);let r=Math.abs(s.bearing%360-(((w=t==null?void 0:t.wind)==null?void 0:w.degree)%360||0));r=r>180?360-r:r;const d=V.directionFactor(r,(M=t==null?void 0:t.wind)==null?void 0:M.scale),l=V.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(C=t==null?void 0:t.wind)==null?void 0:C.kts);let c=d*e*l/100*(s.speed-n);c=Math.round(c*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),j==null||j.debug("wind wx factor = %d",c),r=Math.abs(s.bearing%360-(((b=(T=t==null?void 0:t.wave)==null?void 0:T.sig)==null?void 0:b.degree)%360||0)),r=r>180?360-r:r;const p=V.waveHeightFactor(((m=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:m.height)??1,r);return j==null||j.debug("wave wx factor = %d",p),c=Math.abs(c)>Math.abs(p)?c:c*.3+p*.7,j==null||j.debug("weather factor = %d",c),c=Math.abs(c)>3?3*(Math.abs(c)/c)+Math.abs(c)/c*(Math.abs(c)-2)*.1:c,Math.round((c||0)*100)/100}static async analyseInstant(s,t,a,i,n,o="",e=0,r=!0,d=!1,l={}){var X,Q,Z,$,tt,et,st;const c=v().valueOf();s.lng=H.LngLatHelper.convertToStdLng(s.lng);const{route:p,waypoints:w}=n.points,M=H.LaneHelper.calculateSubRoute(s,p);if(((X=M[0])==null?void 0:X.length)<=1)return;const{v0:C,label:T}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:i.speed,label:"CP"},b=V.assembleProperties(a,i.loadCondition,C,0),g=w.length?H.LaneHelper.calculateSubWaypoints(s,w):[];g.forEach(A=>A.important=!0);const m={from:{...s},route:M,waypoints:g,v0:C,label:T},u={hours:[],days:[],wps:[],all:[]};e||(H.LaneHelper.calculateRouteDistance(M)/i.speed<=72?e=3:e=6);let h=H.LaneHelper.simplifyRouteToCoordinates(M,g,0),f=0,I=0,k=0,F=0;t=v(t).utc();const R=t.clone();for(;h.length>0;){const A=e-t.hour()%e,z=Math.ceil(t.clone().add(A,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,S=await V.speedLoseInHoursStep(b,t,R,z,f,h,o,r,d,l);if(u.all.push(...S.all),(Q=S.from)!=null&&Q.speed&&(u.hours.push(S.from),u.wps.push(...S.wps),u.days.push(...S.days)),h=S==null?void 0:S.next,!h.length){const W=await V.speedLoseAt(b,S.to,v(S.to.eta),o,0,r,d,l);W.bearing=b.bearing,u.hours.push(W),u.all.push(W)}f+=Math.round((((Z=S==null?void 0:S.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const E=u.hours;for(let A=0;A<E.length-1;A++){const z=v(E[A+1].eta).diff(E[A].etd,"hour",!0)||1;I+=(E[A].wxFactor||0)*z,k+=(E[A].cFactor||0)*z,F+=z}($=u.wps)==null||$.forEach((A,z)=>{A.positionTime=v.utc(A.etd||A.eta).unix();const S=u.wps[z-1];if(S){const W=A.distanceFromStart-S.distanceFromStart,P=v(A.eta||A.etd).diff(v(S.etd||S.eta),"h",!0);A.avgSpd=Math.round(W/P*100)/100,S.bearing=H.LaneHelper.calculateBearing(S,A)}}),u.wps=(tt=u.wps)==null?void 0:tt.reduce((A,z)=>(A.some(S=>Math.round(S.positionTime/60)===Math.round(z.positionTime/60))||A.push(z),A),[]),u.all=(et=u.all)==null?void 0:et.reduce((A,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),A.some(S=>Math.round(S.positionTime/60)===Math.round(z.positionTime/60))||A.push(z),A),[]),m.sample=u;const L=u.hours.at(0),x=u.hours.at(-1);m.distance=Math.round(x.distanceFromStart*1e3)/1e3,m.etd=v(L.eta).utc().format(),m.eta=v(x.eta).utc().format(),m.wxFactor=Math.round(I/F*1e3)/1e3,m.cFactor=Math.round(k/F*1e3)/1e3,m.avgSpeed=Math.round(x.distanceFromStart/F*1e3)/1e3,m.totalHrs=Math.round(F*1e3)/1e3;const{distanceInECA:N,hoursInECA:O,totalDgoConsInECA:B,eca:J}=await this.calculateECA(m,i,l),at=H.LngLatHelper.roundPrecision(i.fo/24*(F-O),3),it=H.LngLatHelper.roundPrecision(i.dgo/24*F,3);m.extend={eca:J,distanceInECA:N,hoursInECA:O,totalDgoConsInECA:B},m.totalFoCons=at<0?0:at,m.totalDgoCons=it;const nt=v().valueOf()-c,ct=((st=u==null?void 0:u.hours)==null?void 0:st.length)||1;return j==null||j.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,nt,ct,Math.round(nt/ct*1e3)/1e3),m}static async analyseInstantWithThreshed(s,t,a,i,n,o,e,r="",d=3,l=!0,c=!1,p={}){var Z,$,tt,et,st,A,z;const w=v().valueOf();s.lng=H.LngLatHelper.convertToStdLng(s.lng);const{v0:M,label:C}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:n.speed,label:"CP"},T=V.assembleProperties(i,n.loadCondition,M,0),b=H.LaneHelper.calculateSubRoute(s,o);if(((Z=b[0])==null?void 0:Z.length)<=1)return;const g=e.length?H.LaneHelper.calculateSubWaypoints(s,e):[];g.forEach(S=>S.important=!0);let m=H.LaneHelper.simplifyRouteToCoordinates(b,g,0),u=0,h=0,f=0,I=0;const k={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const F=t.clone();for(;m.length>0;){const S=d-t.hour()%d;let W=Math.ceil(t.clone().add(S,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const P=await V.speedLoseInHoursStep(T,t,F,W,u,m,r,l,c,p);if(k.all.push(...P.all),($=P.from)!=null&&$.speed&&(k.hours.push(P.from),P!=null&&P.wps&&k.wps.push(...P.wps),k.days.push(...P.days)),m=P==null?void 0:P.next,m.length||k.hours.push(P==null?void 0:P.to),u+=Math.round((((tt=P==null?void 0:P.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!W)break}k.wps=(et=k.wps)==null?void 0:et.reduce((S,W)=>(S.some(P=>Math.round(v(P.etd).unix()/60)===Math.round(v(W.etd).unix()/60))||S.push(W),S),[]),k.all=(st=k.all)==null?void 0:st.reduce((S,W)=>(W.positionTime=v.utc(W.etd||W.eta).unix(),S.some(P=>Math.round(v(P.etd).unix()/60)===Math.round(v(W.etd).unix()/60))||S.push(W),S),[]),(A=k.wps)==null||A.forEach((S,W)=>{const P=k.wps[W-1];if(P){const wt=S.distanceFromStart-P.distanceFromStart,kt=v(S.eta||S.etd).diff(v(P.etd||P.eta),"h",!0);S.avgSpd=Math.round(wt/kt*100)/100,P.bearing=H.LaneHelper.calculateBearing(P,S)}});const R=k.hours;for(let S=0;S<R.length-1;S++){const W=v(R[S+1].eta).diff(R[S].etd,"hour",!0);h+=R[S].wxFactor*W,f+=R[S].cFactor*W,I+=W}const E=k.hours.at(0),L=k.hours.at(-1),x=await H.LaneHelper.calculateRangeRoute(E,L,b),N=await H.LaneHelper.calculateRangeWaypoints(E,L,b,g),O={sample:k,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:v(E.eta).utc().format(),eta:v(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(h/I*1e3)/1e3,cFactor:Math.round(f/I*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/I*1e3)/1e3,totalHrs:Math.round(I*1e3)/1e3,from:E,to:L,route:x,waypoints:N,v0:M,label:C},{distanceInECA:B,hoursInECA:J,totalDgoConsInECA:at,eca:it}=await this.calculateECA(O,n,p),rt=H.LngLatHelper.roundPrecision(n.fo/24*(I-J),3),nt=H.LngLatHelper.roundPrecision(n.dgo/24*I,3);O.extend={eca:it,distanceInECA:B,hoursInECA:J,totalDgoConsInECA:at},O.totalDgoCons=nt,O.totalFoCons=rt<0?0:rt;const X=v().valueOf()-w,Q=((z=k==null?void 0:k.hours)==null?void 0:z.length)||1;return j==null||j.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",p==null?void 0:p.requestId,X,Q,Math.round(X/Q*1e3)/1e3),O}static async analyseCost(s,t,a,i,n={}){var b,g;const o=v().valueOf(),e=[];s.speedStep=s.speedStep||3,s.alterStep=s.alterStep??1;const r=H.LaneHelper.calculateRouteDistance(i.route);let d=0;a.forEach(m=>{const u=Math.ceil(r/m.speed/24);d=d<u?u:d}),d=d*1.3;const l=v.utc(s.etd).add(d??14,"day");let c=1;for(const m of a){const u=JSON.parse(JSON.stringify(i.route)),h=JSON.parse(JSON.stringify(i.waypoints)),f=await V.analyseInstantWithThreshed({lat:s.lat,lng:s.lng},s.etd,l,t,m,u,h,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,n);f&&(await V.calculateCost(f,m,s,n),e.push(f),j==null||j.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,c,s.etd,l.format(),{cost:f.cost.total,hire:f.cost.hire,bunker:f.cost.bunker,distance:f.distance,hours:f.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),c++}e.sort((m,u)=>m.cost.total-u.cost.total);const p=e.at(0),w=e.at(1),M=[];if(M.push({combined:!1,speeds:[p],cost:(b=p.cost)==null?void 0:b.total}),w){const m=p.cost.cp,u=w.cost.cp,h=v(p.eta),f=v(p.etd),I=h.diff(f,"days",!0);let k=Math.ceil(I/2);k=k>7?7:k<s.alterStep?s.alterStep:k;let F=2,R={combined:!1,speeds:[w],cost:(g=w.cost)==null?void 0:g.total},E;for(;k>=s.alterStep;){const L=await V.combinedAnalyse(s,t,l,[m,u],i,k,{...n,level:F});if(R.cost>L.cost?E?(E==null?void 0:E.cost)>L.cost&&(E=L):(E=R,R=L):(!E||(E==null?void 0:E.cost)>L.cost)&&(E=L),k<=s.alterStep)break;k=Math.ceil(k/2),F+=1}M.push(R),E&&M.push(E)}const T=v().valueOf()-o;return j==null||j.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,T),M.sort((m,u)=>m.cost-u.cost)}static async combinedAnalyse(s,t,a,i,n,o,e={}){e.counter=1,j==null||j.info("[%s][L%d] analyse with alternate cp in every %d days",e.requestId,e.level,o);const r=await V.alternateAnalyse(s,t,a,i,0,n,o,e),d=r.reduce((u,h)=>u+h.cost.total,0),l=r.reduce((u,h)=>u+h.cost.hire,0),c=r.reduce((u,h)=>u+h.cost.bunker,0),p=r.reduce((u,h)=>u+h.distance,0),w=r.reduce((u,h)=>u+h.totalHrs,0);j==null||j.info("[%s][L%d] cost with cpa/cpb turn: %j",e.requestId,e.level,{cost:d,hire:l,bunker:c,distance:p,hours:w});const M=await V.alternateAnalyse(s,t,a,i,1,n,o,e),C=M.reduce((u,h)=>u+h.cost.total,0),T=M.reduce((u,h)=>u+h.cost.hire,0),b=M.reduce((u,h)=>u+h.cost.bunker,0),g=M.reduce((u,h)=>u+h.distance,0),m=M.reduce((u,h)=>u+h.totalHrs,0);return j==null||j.info("[%s][L%d] cost with cpb/cpa turn: %j",e.requestId,e.level,{cost:C,hire:T,bunker:b,distance:g,hours:m}),d<C?{combined:!0,cost:Math.round(d*1e3)/1e3,speeds:r,step:o}:{combined:!0,cost:Math.round(C*1e3)/1e3,speeds:M,step:o}}static async alternateAnalyse(s,t,a,i,n,o,e,r={}){var p,w;let d=v.utc(s.etd);const l={lat:s.lat,lng:s.lng},c=[];for(;d.isBefore(a);){const M=d.clone().utc().add(e,"day"),C=JSON.parse(JSON.stringify(o.route)),T=JSON.parse(JSON.stringify(o.waypoints)),b=i[n],g=await V.analyseInstantWithThreshed(l,d.utc().format(),M,t,b,C,T,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,r);g&&(await V.calculateCost(g,b,s,r),j==null||j.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,d.utc().format(),M.utc().format(),{cost:g.cost.total,hire:g.cost.hire,bunker:g.cost.bunker,distance:g.distance,hours:g.totalHrs,cp:`${b.speed}/${b.fo}/${b.dgo}`})),r.counter=r.counter+1;const m=(w=(p=g==null?void 0:g.sample)==null?void 0:p.hours)==null?void 0:w.at(-1);if(m)l.lat=m.lat,l.lng=m.lng,d=v(m.eta),c.push(g),n=n?0:1;else break}return c}static async calculateCost(s,t,a,i={}){var n;if(s){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,e=Math.round(s.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3,r=Math.round(s.totalFoCons*(a.priceFO||0)*1e3)/1e3,d=Math.round((s.totalDgoCons+(((n=s.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;s.cost={total:Math.round((e+r+d)*1e3)/1e3,hire:e,bunker:Math.round((r+d)*1e3)/1e3,cp:t}}return s}static async calculateECA(s,t,a={}){var r,d,l,c;const i=await H.LaneHelper.intersectInECA((s==null?void 0:s.route)||[]);let n=0,o=0,e=0;(d=(r=s==null?void 0:s.sample)==null?void 0:r.wps)==null||d.forEach(p=>{p.positionTime=v.utc(p.etd||p.eta).unix()});for(const p of i){n+=p.distance;const w=await H.LaneHelper.deadReckoningTime((l=p.waypoints)==null?void 0:l.at(0),s.sample.all||s.sample.wps),M=await H.LaneHelper.deadReckoningTime((c=p.waypoints)==null?void 0:c.at(-1),s.sample.all||s.sample.wps);p.in=w,p.out=M,p.totalHrs=H.LngLatHelper.roundPrecision((M.positionTime-w.positionTime)/3600,3),p.totalDgoCons=H.LngLatHelper.roundPrecision(t.fo/24*p.totalHrs,3),o+=p.totalHrs,e+=p.totalDgoCons}return n=H.LngLatHelper.roundPrecision(n,3),o=H.LngLatHelper.roundPrecision(o,3),e=H.LngLatHelper.roundPrecision(e,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:e,eca:i}}static async mergeSpeeds(s,t={}){var m,u;const a={hours:[],wps:[],days:[]},i=s.reduce((h,f)=>h+f.distance,0),n=s.reduce((h,f)=>{var I;return h+(((I=f.extend)==null?void 0:I.distanceInECA)||0)},0),o=s.reduce((h,f)=>h+f.totalHrs,0),e=s.reduce((h,f)=>{var I;return h+(((I=f.extend)==null?void 0:I.hoursInECA)||0)},0),r=s.reduce((h,f)=>{var I;return h+(((I=f.extend)==null?void 0:I.totalDgoConsInECA)||0)},0),d=s.reduce((h,f)=>h+f.wxFactor*f.totalHrs/o,0),l=s.reduce((h,f)=>h+f.cFactor*f.totalHrs/o,0),c=s.reduce((h,f)=>h+f.totalFoCons,0),p=s.reduce((h,f)=>h+f.totalDgoCons,0),w=s.reduce((h,f)=>h+f.cost.total,0),M=s.reduce((h,f)=>h+f.cost.hire,0),C=s.reduce((h,f)=>h+f.cost.bunker,0),T=[],b=[];let g;for(const h of s){b.push(...((m=h.extend)==null?void 0:m.eca)||[]);const f=h.sample.hours,I=h.sample.wps,k=h.sample.days,F=f.at(0);g&&(F.distanceFromPrevious=g.distanceFromPrevious,F.distanceFromStart=g.distanceFromStart,f.forEach((x,N)=>{N&&(x.distanceFromStart=x.distanceFromStart+g.distanceFromStart)}),I.at(0).distanceFromPrevious=g.distanceFromPrevious,I.at(0).distanceFromStart=g.distanceFromStart,I.forEach((x,N)=>{N&&(x.distanceFromStart=x.distanceFromStart+g.distanceFromStart)}),k.at(0).distanceFromPrevious=g.distanceFromPrevious,k.at(0).distanceFromStart=g.distanceFromStart,k.forEach((x,N)=>{N&&(x.distanceFromStart=x.distanceFromStart+g.distanceFromStart)})),F.cp=h.cost.cp;const R=[h.etd,h.eta],E=T.findIndex(x=>x.id===F.cp.id);E===-1?(F.cp.segment=[R],T.push(F.cp)):T[E].segment.push(R),f.forEach(x=>{var O;((O=a.hours)==null?void 0:O.findIndex(B=>B.eta===x.eta))===-1&&a.hours.push(x)}),I.forEach(x=>{var O;((O=a.wps)==null?void 0:O.findIndex(B=>B.eta===x.eta))===-1&&a.wps.push(x)}),k.forEach(x=>{var O;((O=a==null?void 0:a.days)==null?void 0:O.findIndex(B=>B.eta===x.eta))===-1&&a.days.push(x)});const L=(u=a.wps)==null?void 0:u.findIndex(x=>x.eta===F.eta);L===-1?a.wps.push(F):a.wps[L]=F,g=f.at(-1)}return a.wps.sort((h,f)=>{v(h.etd).unix()-v(f.etd).unix()}),a.wps.forEach((h,f)=>{const I=a.wps[f-1];if(I){const k=h.distanceFromStart-(I.distanceFromStart||0),F=v(h.eta||h.etd).diff(v(I.etd||I.eta),"hour",!0),R=Math.round(k/F*100)/100;h.avgSpd=R;const E=H.LaneHelper.calculateBearing(I,h);I.bearing=E}}),{sample:a,etd:s.at(0).etd,eta:s.at(-1).eta,from:s.at(0).from,to:s.at(-1).to,v0:s.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(d*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(p*1e3)/1e3,cost:{total:Math.round(w*1e3)/1e3,hire:Math.round(M*1e3)/1e3,bunker:Math.round(C*1e3)/1e3},extend:{cps:T,eca:b,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(e*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:s}}}}Y.AISImpl=G,Y.AlertHelper=ut,Y.AlertLevel=dt,Y.HifleetImpl=pt,Y.LoadCondition=ht,Y.MyShipImpl=bt,Y.MyVesselImpl=yt,Y.ShipxyImpl=Mt,Y.SpeedHelper=V,Y.SpeedLabel=ft,Y.VesselTag=lt,Y.alertHelper=vt,Object.defineProperty(Y,Symbol.toStringTag,{value:"Module"})});
1
+ (function(P,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],D):(P=typeof globalThis<"u"?globalThis:P||self,D(P["idm-plugin-vessel"]={},P.got,P["@log4js-node/log4js-api"],P.moment,P["@idm-plugin/geo2"],P["@idm-plugin/meteo2"],P["@idm-plugin/meteo"]))})(this,function(P,D,U,v,H,pt,it){"use strict";var Ct=Object.defineProperty;var jt=(P,D,U)=>D in P?Ct(P,D,{enumerable:!0,configurable:!0,writable:!0,value:U}):P[D]=U;var K=(P,D,U)=>(jt(P,typeof D!="symbol"?D+"":D,U),U);let y;try{y=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(s){let t,a;switch(s){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class Mt extends G{constructor(t,a){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await D.post(a,i).json();y==null||y.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async checkToken(t={}){var a;return(!this.token||v().diff(v(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var e,r;await this.checkToken(a);const i="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};y==null||y.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,i,n);const o=await D.post(i,n).json();return o.status!==200?(y==null||y.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),[]):(o.data||[]).map(l=>({mmsi:l.mmsi,name:l.nameEn,nameCn:l.nameCn,imo:Number.isNaN(l.imo)?null:Number(l.imo),callSign:l.callsign,type:l.vesselTypeNameEn,flagName:l.flagCtry,vendor:"myvessel",raw:l}))}async search(t,a={}){var d,l;await this.checkToken(a);const i=/^\d{7}$/.test(t.toString()),n=i?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",o=i?{imo:t}:{mmsi:t},e={headers:{Authorization:`${(d=this.token)==null?void 0:d.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:o};y==null||y.info("[%s] fetch vessel from: %s - %j",a.requestId,n,e);const r=await D.get(n,e).json();if(r.status!==200)return y==null||y.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const c=r.data;if(c)return{mmsi:c.mmsi,imo:Number.isNaN(c.imo)?null:Number(c.imo),callSign:c.callsign,name:c.nameEn,nameCn:c.nameCn,type:c.vesselTypeNameEn,flagName:c.flagCtry,clasz:c.classSociety,dateOfBuild:c.buildYearMonth,deadweight:c.dwt,grossTonnage:c.grt,netTonnage:c.net,teu:c.teu,length:c.length,breadth:c.width,height:c.height,draught:c.draught,speed:c.speed,passengerCapacity:c.passengercapacity,vendor:"myvessel",raw:c}}return{}}async archives(t,a={}){var e,r;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};y==null||y.info("[%s] fetch vessel archive from: %s - %j",a.requestId,i,n);const o=await D.post(i,n).json();return o.status!==200?(y==null||y.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),{}):o.data}async realTimePosition(t,a={}){var r,d;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},searchParams:{mmsi:t}};y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await D.get(i,n).json();if(o.code)return y==null||y.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),o;const e=o.data;for(const l in e)!isNaN(e[l])&&Number(e[l])!==1/0&&(e[l]=Number(e[l]));if(e){const l=v(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName||e.aisVesselName,imo:e.imo,callSign:e.callsign||e.aisCallSign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.dest,positionTime:l.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,vesselType:e.vesselTypeNameEn,flag:e.flagCtryNameEn,clasz:e.classSociety,build:e.buildYear,dwt:e.dwt,grt:e.grt,net:e.net,method:"position",vendor:"myVessel",utc:l.utc().format()}}else return{}}async calculateRoute(t,a,i={}){var r,d;await this.checkToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},json:{startPoint:{lon:t.lng,lat:t.lat},endPoint:{lon:a.lng,lat:a.lat},maxDraught:i.maxDraught||10,useAIModel:i.useAIModel||!1,withECA:i.withECA||!1}};y==null||y.info("[%s] fetch route from: %s - %j",i.requestId,n,o);const e=await D.post(n,o).json();return e.status!==200?(y==null||y.warn("[%s] fetch route failed: %j",i.requestId,{message:e.message,status:e.status,code:e.code}),{}):e.data}async trajectory(t,a,i,n,o=!0,e={}){await this.checkToken(e);const r=await this.realTimePosition(t,e),d=v(a),l=v(i),c=[];for(;l.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(t,d,d.clone().add(30,"day"),r,n,c,e),d.add(30,"day");return await this.trajectoryIn30Day(t,d,l,r,n,c,e),c}async trajectoryIn30Day(t,a,i,n,o,e,r={}){var M,j,F,b,g;const d="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(j=this.token)==null?void 0:j.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};y==null||y.info("[%s] fetch trajectory from: %s - %j",r.requestId,d,l);const c=await D.post(d,l).json();if(c.code)return y==null||y.warn("[%s] fetch trajectory failed: %j",r.requestId,d,{message:c.message,status:c.status,code:c.code}),c;let p=-1;const w=v(`${(b=(F=c.data)==null?void 0:F[0])==null?void 0:b.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=c.data)==null||g.forEach(m=>{for(const Y in m)!isNaN(m[Y])&&Number(m[Y])!==1/0&&(m[Y]=Number(m[Y]));const u=v(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),h=m.status,{labelCn:f,labelEn:k}=this.parseStatus(h),I={mmsi:m.mmsi,imo:n==null?void 0:n.imo,lat:m.lat,lng:m.lon,sog:m.sog,cog:m.cog,hdg:m.hdg,draught:m.draught,status:h,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta)?v(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:m.dest,positionTime:u.unix(),labelCn:f,labelEn:k,method:"trajectory",vendor:"myVessel",utc:u.utc().format()},E=Math.floor(u.diff(w,"minute",!0)/(o||1));E!==p&&(p=E,e.push(I))}),e}}class bt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},o=await D.post(i,n).json();y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const e=o==null?void 0:o.list;if(!e)return y==null||y.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const w in e)!isNaN(e[w])&&Number(e[w])!==1/0&&(e[w]=Number(e[w]));e.status=e.sp>3?0:1;const r=e.status,{labelCn:d,labelEn:l}=this.parseStatus(r),c=v(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.destination,vesselType:e.type,dwt:e.dwt,build:e.buildyear,flag:e.fn,positionTime:c.unix(),utc:c.utc().format(),status:r,labelCn:d,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,a={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let o=await D.post(i,n).json();y==null||y.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]);for(const r in o)!isNaN(o[r])&&Number(o[r])!==1/0&&(o[r]=Number(o[r]));const e={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await D.post(i,n).json(),y==null||y.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(e.deadweight=Number(o.dwt)),e}async suggest(t,a={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},o=await D.post(i,n).json();y==null||y.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const e=[];for(const r of o)e.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return e.sort((r,d)=>d.score-r.score),e}async trajectory(t,a,i,n,o=!0,e={}){var m,u,h;const r=await this.realTimePosition(t,e);let d=v(a);const l=v(i),c=v();if(o){let f=l.diff(d,"d",!0);f<0?d=l.clone().subtract(40,"d"):f<30?d.subtract(10,"d"):f<60?d.subtract(5,"d"):d=l.clone().subtract(80,"d"),f=c.diff(l,"d",!0),l.add(f>10?240:f*24,"h")}const p={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},w="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",M=await D.get(w,p).json();y==null||y.info("[%s] fetch trajectory from: %s - %j",e.requestId,w,p);let j;M&&(j=((u=(m=M.ships)==null?void 0:m.offors)==null?void 0:u.ship)||[],j.length||y==null||y.warn("[%s] fetch trajectory failed: %j",e.requestId,M));const F=[];let b=-1;const g=v(`${(h=j==null?void 0:j[0])==null?void 0:h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const f of j){for(const R in f)!isNaN(f[R])&&Number(f[R])!==1/0&&(f[R]=Number(f[R]));const k=v(`${f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");f.status=f.sp>4?0:1;const{labelEn:I,labelCn:E}=this.parseStatus(f.status),Y={mmsi:f.m,name:f.n,imo:r==null?void 0:r.imo,lat:f.la,lng:f.lo,draught:f.draught,sog:f.sp,cog:f.co,hdg:f.hdg,positionTime:k.unix(),utc:k.utc().format(),status:f.status,labelCn:E,labelEn:I,method:"trajectory",vendor:"hifleet"},x=Math.floor(k.diff(g,"minute",!0)/(n||1));x!==b&&(b=x,F.push(Y))}return F}}class vt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",o=await D.get(n,i).json();if(y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const e=o.data[0];for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const{labelCn:r,labelEn:d}=await this.parseStatus(e.navistat),l=v.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:l.utc().format(),status:e.navistat,labelEn:d,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,i,n,o=!0,e={}){var g;const r=await this.realTimePosition(t,e),d=v(a),l=v(i),c="https://api.shipxy.com/apicall/GetShipTrack",p={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:d.unix(),etm:l.unix()}},w=await D.get(c,p).json();if(y==null||y.info("[%s] fetch trajectory from: %s - %j",e.requestId,c,p),(w==null?void 0:w.status)!==0)return w;const M=w==null?void 0:w.points,j=[],F=v.unix((g=M[0])==null?void 0:g.utc);let b=-1;for(const m of M){const u=v.unix(m.utc),h={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(m.sog*3600/1e3/1852*100)/100,cog:Math.round(m.cog/100*100)/100,lat:Math.round(m.lat/1e6*1e5)/1e5,lng:Math.round(m.lon/1e6*1e5)/1e5,positionTime:u.unix(),utc:u.utc().format(),method:"trajectory",vendor:"shipxy"},f=Math.floor(u.diff(F,"minute",!0)/(n||1));f!==b&&(b=f,j.push(h))}return j}}class gt extends G{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,a={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",o=await D.post(n,i).json();return y==null||y.info("[%s] fetch ship id from: %s - %j",a.requestId,n,i),o.code!=="0"?o:o.data[0].shipId}async getShipInfo(t,a={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",o=await D.post(n,i).json();if(y==null||y.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const e=o.data;let r=e.imo;return t==="407170"&&(r="9198379",y==null||y.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,e.imo,r)),{mmsi:e.mmsi,name:e.shipnameEn,imo:r,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,a={}){const i=await this.getShipId(t,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},e="https://api3.myships.com/sp/ships/position/latest",r=await D.post(e,o).json();y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,e,o);const d=r.data[0];for(const M in d)!isNaN(d[M])&&Number(d[M])!==1/0&&(d[M]=Number(d[M]));const{labelCn:l,labelEn:c}=await this.parseStatus(d.aisNavStatus),p=v.unix(d.posTime);return{...n,mmsi:t,lat:Math.round(d.lat/1e4/60*1e5)/1e5,lng:Math.round(d.lon/1e4/60*1e5)/1e5,sog:Math.round(d.sog/10*100)/100,cog:Math.round(d.cog/10*100)/100,hdg:Math.round(d.heading*100)/100,rot:Math.round(d.rot*100)/100,positionTime:d.posTime,utc:p.utc().format(),status:d.aisNavStatus,labelEn:c,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,a,i,n,o=!0,e={}){const r=v(a),d=v(i),l=await this.getShipId(t),c=await this.getShipInfo(l),p=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(l,r.unix(),r.add(30,"day").unix(),c,t,n,p);return await this.trajectoryIn30Day(l,r.unix(),d.unix(),c,t,n,p),p}async trajectoryIn30Day(t,a,i,n,o,e,r,d={}){var F;const l={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:i}},c="https://api3.myships.com/sp/ships/position/history",p=await D.post(c,l).json();if(y==null||y.info("[%s] fetch trajectory from: %s - %j",d.requestId,c,l),p.code!=="0")return y==null||y.warn("[%s] invoke myship trajectory failed: %j",d.requestId,p),p;const w=p.data;for(const b in w)!isNaN(w[b])&&Number(w[b])!==1/0&&(w[b]=Number(w[b]));const M=v.unix((F=w[0])==null?void 0:F.posTime);let j=-1;for(const b of w){const g=v.unix(b.posTime),m={imo:n==null?void 0:n.imo,mmsi:o,lat:Math.round(b.lat/1e4/60*1e5)/1e5,lng:Math.round(b.lon/1e4/60*1e5)/1e5,sog:Math.round(b.sog/10*100)/100,cog:Math.round(b.cog/10*100)/100,hdg:Math.round(b.heading*100)/100,rot:Math.round(b.rot*100)/100,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"myship"},u=Math.floor(g.diff(M,"minute",!0)/(e||1));u!==j&&(j=u,r.push(m))}return r}}let _;try{_=U.getLogger("vessel")}catch{}finally{}var lt=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(lt||{});class ht{parsePrinciple(s,t={}){var e,r,d;_==null||_.debug("[%s] parse rule: %s",t.requestId,s);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=s.match(a)?(e=s.match(a))==null?void 0:e[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let l=0;l<(n==null?void 0:n.length);l++){const c=(d=(r=n[l].match(a))==null?void 0:r[0])==null?void 0:d.split("],");if(l===0&&!c)o.scope=n[0];else if(c)for(let p=0,w=c.length;p<w;p++){const M=this.parseRule(c[p]);M&&(o[M.level]?M.key?o[M.level][M==null?void 0:M.key]=M:o[M.level]=M:M.key?o[M.level]={[M==null?void 0:M.key]:M}:o[M.level]=M)}}return o}parseRule(s,t={}){var o;_==null||_.debug("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=s==null?void 0:s.match(a))==null?void 0:o[0],n=i==null?void 0:i.split(",");if(n){let e=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return e=isNaN(e)?1:e,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:e,key:n[4]}}}checkWeather(s,t,a={}){var M,j,F,b,g,m,u,h,f,k,I,E,Y,x,R;let i=0,n=0,o=0,e=0;const r=Math.round(((j=(M=t==null?void 0:t.SEVERE)==null?void 0:M.sigWave)==null?void 0:j.number)*1.6*100)/100,d=(b=(F=t==null?void 0:t.SEVERE)==null?void 0:F.sigWave)==null?void 0:b.number,l=(m=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:m.number,c=Math.round((((h=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:h.number)+2)*100)/100,p=(k=(f=t==null?void 0:t.SEVERE)==null?void 0:f.wind)==null?void 0:k.number,w=(E=(I=t==null?void 0:t.HEAVY)==null?void 0:I.wind)==null?void 0:E.number;for(let T=0;T<(s==null?void 0:s.length);T++){const N=s[T],W=(x=(Y=N==null?void 0:N.meteo)==null?void 0:Y.wave)==null?void 0:x.sig,V=(R=N==null?void 0:N.meteo)==null?void 0:R.wind,J=T?v(N.eta).diff(v(s[T-1].eta),"hour",!0):0;e=J>e?J:e,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...W,dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}),(W==null?void 0:W.height)>=r?N.isDangerous=!0:(W==null?void 0:W.height)>=d?N.isSevere=!0:(W==null?void 0:W.height)>=l&&(N.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:c,svThd4Wd:p,hvThd4Wd:w}),(V==null?void 0:V.scale)>=c?(N.isDangerous=!0,delete N.isSevere,delete N.isHeavy):(V==null?void 0:V.scale)>p?(N.isDangerous||(N.isSevere=!0),delete N.isHeavy):(V==null?void 0:V.scale)===w&&!N.isDangerous&&!N.isSevere&&(N.isHeavy=!0),i+=N.isDangerous?J:0,n+=N.isSevere?J:0,o+=N.isHeavy?J:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,e=Math.round(e),{sample:s,dangerous:i,severe:n,heavy:o,step:e<3?3:e,wind:{dgThd4Wd:c,svThd4Wd:p,hvThd4Wd:w},sig:{dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}}}}const wt=new ht;let C;try{C=U.getLogger("vessel")}catch{}finally{}const It=new pt.MeteoHelper2("",!0);var ft=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ft||{}),mt=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(mt||{}),yt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(yt||{});class B{static blockCoefficient(s,t,a,i){let n=Math.round(s/(t*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],e=o.map(r=>Math.abs(r-n));return o[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,a=9.8){let i=Math.round(Math.sqrt(s*s/(a*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(s,t,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return a==="Laden"&&(o=i[s]),o[0]+o[1]*t+o[2]*Math.pow(t,2)}static directionFactor(s,t=0){let a;return s>30&&s<=60?a=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?a=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(s,t,a,i){let n;return a==="container"?n=.7*i/2+Math.pow(i,3)/(22*Math.pow(s,2/3)):t==="Ballast"?n=.7*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)):n=.5*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)),n}static waveHeightFactor(s,t){s=s<3?s*.7:s,s=s<0?.2:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=s<3?.4:-.3:t>120&&t<=150?a=s<3?.6:-.5:t>150&&t<=180?a=s<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(s,2)+.278*s)*1e4)/1e4}static assembleProperties(s,t,a,i){var p;const n=s.lbp??s.length??s.lengthOverall??198.9642,o=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,r=s.deadweight??67035.7773,d=((p=s==null?void 0:s.type)==null?void 0:p.toLowerCase())||"common";return{tag:d.indexOf("container")>-1?"container":d.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:o,breadthMoulded:e,displacement:Math.round((r/1.025+o*e*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(s,t,a,i="",n=2,o=!0,e=!1,r={}){let d;if(t.velocity&&e&&(s.speed=H.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),o){let l;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:M,marineModels:j}=await it.Meteo2Assist.autoPickMeteoModel(i),F=await It.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:M,marineModels:j}),[b]=it.Meteo2Assist.pickHourly(F,a);l=it.Meteo2Assist.toLegacy(b)}catch(M){C.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:i},M)}const c=B.currentFactor(s.bearing,l==null?void 0:l.current,n),p=B.weatherFactor(s,l,c),w=Math.round((s.speed*1.943844+p+c)*100)/100;d={meteo:{...l},wxFactor:p,cFactor:c,speed:t.velocity&&e?t.velocity:w<0?1:w,eta:a.utc().format(),etd:a.utc().format()}}else d={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round(s.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...d,...t}}static async speedLoseInHoursStep(s,t,a,i,n,o,e="",r=!0,d=!1,l={}){t.utc();const c=t.clone().add(14,"days"),p=[],w=[],M=[];let j=0,F=0,b,g;for(let m=0;m<o.length-1;m++){let u=o[m];u.distanceFromStart=Math.round((n+F)*1e3)/1e3;const h=o[m+1];if(s.bearing=H.LaneHelper.calculateBearing(u,h,!h.gcToPrevious),u.bearing=s.bearing,u.suspend&&d){u.eta=u.eta||t.utc().format(),u.elapsed=u.elapsed??0;const I=u.suspend-u.elapsed;if(i-j>I)i=i-j-I,t.add(I,"hour"),u.elapsed=u.suspend;else{const E=i-j;u.elapsed+=E,t.add(E,"hour"),i=0}if(C==null||C.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,u),i===0)return u.distanceFromPrevious=F,{etd:t,from:g||u,to:u,next:o.filter(E=>E),wps:p,days:w,all:M}}else u.suspend=0;r=t.isAfter(c)?!1:r,u=await B.speedLoseAt(s,u,t,e,0,r,d,l),M.push(u),g=g||u,u.important&&p.push(u),t.isSameOrAfter(a)&&(w.push(u),a.add(24,"hour"));const f=H.LaneHelper.calculateDistance(u,h,!h.gcToPrevious);let k=Math.round(f/g.speed*1e5)/1e5;if(j+k<i){if(j+=k,t.add(k,"hour"),delete o[m],C==null||C.debug(`[%s] go to %j from %j with ${f}nm, and cost ${k} hours`,l.requestId,{lat:h.lat,lng:h.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),F+=f,o.filter(I=>I).length<=1){b=h,b.eta=t.utc().format(),b.distanceFromPrevious=f,b.distanceFromStart=Math.round((n+F)*1e4)/1e4,p.push(b),M.push(b),delete o[m+1];break}}else{k=i-j,t.add(k,"hour");const I=H.LngLatHelper.roundPrecision(g.speed*k,5);b=H.LaneHelper.calculateCoordinate(u,s.bearing,I,"nauticalmiles",!h.gcToPrevious),b.eta=t.utc().format(),o[m]=b,C==null||C.debug(`[%s] go to %j from %j with ${I}nm, and cost ${k} hours`,l.requestId,{lat:b.lat,lng:b.lng},{lat:u.lat,lng:u.lng,etd:u.etd}),F+=I,b.distanceFromPrevious=Math.round(F*1e4)/1e4,b.distanceFromStart=Math.round((n+F)*1e4)/1e4;break}}return{etd:t,from:g,to:b,next:o.filter(m=>m),wps:p,days:w,all:M}}static currentFactor(s,t,a=0){const i=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(s,t,a=0){var w,M,j,F,b,g,m;C==null||C.debug("calculate weather factor via: %j",{...s,...t});const i=B.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=H.LngLatHelper.roundPrecision(a*1852/3600,6),o=B.froudeNumber(s.speed-n,s.lbp),e=B.amendFactor(i,o,s.loadCondition);let r=Math.abs(s.bearing%360-(((w=t==null?void 0:t.wind)==null?void 0:w.degree)%360||0));r=r>180?360-r:r;const d=B.directionFactor(r,(M=t==null?void 0:t.wind)==null?void 0:M.scale),l=B.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(j=t==null?void 0:t.wind)==null?void 0:j.kts);let c=d*e*l/100*(s.speed-n);c=Math.round(c*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),C==null||C.debug("wind wx factor = %d",c),r=Math.abs(s.bearing%360-(((b=(F=t==null?void 0:t.wave)==null?void 0:F.sig)==null?void 0:b.degree)%360||0)),r=r>180?360-r:r;const p=B.waveHeightFactor(((m=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:m.height)??1,r);return C==null||C.debug("wave wx factor = %d",p),c=Math.abs(c)>Math.abs(p)?c:c*.3+p*.7,C==null||C.debug("weather factor = %d",c),c=Math.abs(c)>3?3*(Math.abs(c)/c)+Math.abs(c)/c*(Math.abs(c)-2)*.1:c,Math.round((c||0)*100)/100}static async analyseInstant(s,t,a,i,n,o="",e=0,r=!0,d=!1,l={}){var X,Q,Z,$,tt,et,st;const c=v().valueOf();s.lng=H.LngLatHelper.convertToStdLng(s.lng);const{route:p,waypoints:w}=n.points,M=H.LaneHelper.calculateSubRoute(s,p);if(((X=M[0])==null?void 0:X.length)<=1)return;const{v0:j,label:F}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:i.speed,label:"CP"},b=B.assembleProperties(a,i.loadCondition,j,0),g=w.length?H.LaneHelper.calculateSubWaypoints(s,w):[];g.forEach(L=>L.important=!0);const m={from:{...s},route:M,waypoints:g,v0:j,label:F},u={hours:[],days:[],wps:[],all:[]};e||(H.LaneHelper.calculateRouteDistance(M)/i.speed<=72?e=3:e=6);let h=H.LaneHelper.simplifyRouteToCoordinates(M,g,0),f=0,k=0,I=0,E=0;t=v(t).utc();const Y=t.clone();for(;h.length>0;){const L=e-t.hour()%e,z=Math.ceil(t.clone().add(L,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,S=await B.speedLoseInHoursStep(b,t,Y,z,f,h,o,r,d,l);if(u.all.push(...S.all),(Q=S.from)!=null&&Q.speed&&(u.hours.push(S.from),u.wps.push(...S.wps),u.days.push(...S.days)),h=S==null?void 0:S.next,!h.length){const O=await B.speedLoseAt(b,S.to,v(S.to.eta),o,0,r,d,l);O.bearing=b.bearing,u.hours.push(O),u.all.push(O)}f+=Math.round((((Z=S==null?void 0:S.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const x=u.hours;for(let L=0;L<x.length-1;L++){const z=v(x[L+1].eta).diff(x[L].etd,"hour",!0)||1;k+=(x[L].wxFactor||0)*z,I+=(x[L].cFactor||0)*z,E+=z}const R=x.reduce((L,z)=>L+(z.suspend||0),0);($=u.wps)==null||$.forEach((L,z)=>{L.positionTime=v.utc(L.etd||L.eta).unix();const S=u.wps[z-1];if(S){const O=L.distanceFromStart-S.distanceFromStart,q=v(L.eta||L.etd).diff(v(S.etd||S.eta),"h",!0);L.avgSpd=Math.round(O/q*100)/100,S.bearing=H.LaneHelper.calculateBearing(S,L)}}),u.wps=(tt=u.wps)==null?void 0:tt.reduce((L,z)=>(L.some(S=>Math.round(S.positionTime/60)===Math.round(z.positionTime/60))||L.push(z),L),[]),u.all=(et=u.all)==null?void 0:et.reduce((L,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),L.some(S=>Math.round(S.positionTime/60)===Math.round(z.positionTime/60))||L.push(z),L),[]),m.sample=u;const T=u.hours.at(0),N=u.hours.at(-1);m.distance=Math.round(N.distanceFromStart*1e3)/1e3,m.etd=v(T.eta).utc().format(),m.eta=v(N.eta).utc().format(),m.wxFactor=Math.round(k/E*1e3)/1e3,m.cFactor=Math.round(I/E*1e3)/1e3,m.avgSpeed=Math.round(N.distanceFromStart/E*1e3)/1e3,m.totalHrs=Math.round(E*1e3)/1e3,m.suspend=Math.round(R*1e3)/1e3;const W=H.LngLatHelper.roundPrecision(i.dgo/24*R,3),{distanceInECA:V,hoursInECA:J,totalDgoConsInECA:rt,eca:at}=await this.calculateECA(m,i,l),nt=H.LngLatHelper.roundPrecision(i.fo/24*(E-J),3),ct=H.LngLatHelper.roundPrecision(i.dgo/24*E+W,3);m.extend={eca:at,distanceInECA:V,hoursInECA:J,totalDgoConsInECA:rt,totalDgoConsInSuspend:W},m.totalFoCons=nt<0?0:nt,m.totalDgoCons=ct;const ot=v().valueOf()-c,ut=((st=u==null?void 0:u.hours)==null?void 0:st.length)||1;return C==null||C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,ot,ut,Math.round(ot/ut*1e3)/1e3),m}static async analyseInstantWithThreshed(s,t,a,i,n,o,e,r="",d=3,l=!0,c=!1,p={}){var Z,$,tt,et,st,L,z;const w=v().valueOf();s.lng=H.LngLatHelper.convertToStdLng(s.lng);const{v0:M,label:j}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:n.speed,label:"CP"},F=B.assembleProperties(i,n.loadCondition,M,0),b=H.LaneHelper.calculateSubRoute(s,o);if(((Z=b[0])==null?void 0:Z.length)<=1)return;const g=e.length?H.LaneHelper.calculateSubWaypoints(s,e):[];g.forEach(S=>S.important=!0);let m=H.LaneHelper.simplifyRouteToCoordinates(b,g,0),u=0,h=0,f=0,k=0;const I={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const E=t.clone();for(;m.length>0;){const S=d-t.hour()%d;let O=Math.ceil(t.clone().add(S,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;O=t.clone().add(O,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:O;const q=await B.speedLoseInHoursStep(F,t,E,O,u,m,r,l,c,p);if(I.all.push(...q.all),($=q.from)!=null&&$.speed&&(I.hours.push(q.from),q!=null&&q.wps&&I.wps.push(...q.wps),I.days.push(...q.days)),m=q==null?void 0:q.next,m.length||I.hours.push(q==null?void 0:q.to),u+=Math.round((((tt=q==null?void 0:q.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!O)break}I.wps=(et=I.wps)==null?void 0:et.reduce((S,O)=>(S.some(q=>Math.round(v(q.etd).unix()/60)===Math.round(v(O.etd).unix()/60))||S.push(O),S),[]),I.all=(st=I.all)==null?void 0:st.reduce((S,O)=>(O.positionTime=v.utc(O.etd||O.eta).unix(),S.some(q=>Math.round(v(q.etd).unix()/60)===Math.round(v(O.etd).unix()/60))||S.push(O),S),[]),(L=I.wps)==null||L.forEach((S,O)=>{const q=I.wps[O-1];if(q){const kt=S.distanceFromStart-q.distanceFromStart,St=v(S.eta||S.etd).diff(v(q.etd||q.eta),"h",!0);S.avgSpd=Math.round(kt/St*100)/100,q.bearing=H.LaneHelper.calculateBearing(q,S)}});const Y=I.hours;for(let S=0;S<Y.length-1;S++){const O=v(Y[S+1].eta).diff(Y[S].etd,"hour",!0);h+=Y[S].wxFactor*O,f+=Y[S].cFactor*O,k+=O}const x=Y.reduce((S,O)=>S+(O.suspend||0),0),R=I.hours.at(0),T=I.hours.at(-1),N=await H.LaneHelper.calculateRangeRoute(R,T,b),W=await H.LaneHelper.calculateRangeWaypoints(R,T,b,g),V={sample:I,distance:Math.round(((T==null?void 0:T.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(T==null?void 0:T.eta).utc().format(),wxFactor:Math.round(h/k*1e3)/1e3,cFactor:Math.round(f/k*1e3)/1e3,avgSpeed:Math.round(((T==null?void 0:T.distanceFromStart)||0)/k*1e3)/1e3,totalHrs:Math.round(k*1e3)/1e3,suspend:Math.round(x*1e3)/1e3,from:R,to:T,route:N,waypoints:W,v0:M,label:j},J=H.LngLatHelper.roundPrecision(n.dgo/24*x,3),{distanceInECA:rt,hoursInECA:at,totalDgoConsInECA:nt,eca:ct}=await this.calculateECA(V,n,p),dt=H.LngLatHelper.roundPrecision(n.fo/24*(k-at),3),ot=H.LngLatHelper.roundPrecision(n.dgo/24*k+J,3);V.extend={eca:ct,distanceInECA:rt,hoursInECA:at,totalDgoConsInECA:nt,totalDgoConsInSuspend:J},V.totalDgoCons=ot,V.totalFoCons=dt<0?0:dt;const X=v().valueOf()-w,Q=((z=I==null?void 0:I.hours)==null?void 0:z.length)||1;return C==null||C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",p==null?void 0:p.requestId,X,Q,Math.round(X/Q*1e3)/1e3),V}static async analyseCost(s,t,a,i,n={}){var b,g;const o=v().valueOf(),e=[];s.speedStep=s.speedStep||3,s.alterStep=s.alterStep??1;const r=H.LaneHelper.calculateRouteDistance(i.route);let d=0;a.forEach(m=>{const u=Math.ceil(r/m.speed/24);d=d<u?u:d}),d=d*1.3;const l=v.utc(s.etd).add(d??14,"day");let c=1;for(const m of a){const u=JSON.parse(JSON.stringify(i.route)),h=JSON.parse(JSON.stringify(i.waypoints)),f=await B.analyseInstantWithThreshed({lat:s.lat,lng:s.lng},s.etd,l,t,m,u,h,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,n);f&&(await B.calculateCost(f,m,s,n),e.push(f),C==null||C.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,c,s.etd,l.format(),{cost:f.cost.total,hire:f.cost.hire,bunker:f.cost.bunker,distance:f.distance,hours:f.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),c++}e.sort((m,u)=>m.cost.total-u.cost.total);const p=e.at(0),w=e.at(1),M=[];if(M.push({combined:!1,speeds:[p],cost:(b=p.cost)==null?void 0:b.total}),w){const m=p.cost.cp,u=w.cost.cp,h=v(p.eta),f=v(p.etd),k=h.diff(f,"days",!0);let I=Math.ceil(k/2);I=I>7?7:I<s.alterStep?s.alterStep:I;let E=2,Y={combined:!1,speeds:[w],cost:(g=w.cost)==null?void 0:g.total},x;for(;I>=s.alterStep;){const R=await B.combinedAnalyse(s,t,l,[m,u],i,I,{...n,level:E});if(Y.cost>R.cost?x?(x==null?void 0:x.cost)>R.cost&&(x=R):(x=Y,Y=R):(!x||(x==null?void 0:x.cost)>R.cost)&&(x=R),I<=s.alterStep)break;I=Math.ceil(I/2),E+=1}M.push(Y),x&&M.push(x)}const F=v().valueOf()-o;return C==null||C.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,F),M.sort((m,u)=>m.cost-u.cost)}static async combinedAnalyse(s,t,a,i,n,o,e={}){e.counter=1,C==null||C.info("[%s][L%d] analyse with alternate cp in every %d days",e.requestId,e.level,o);const r=await B.alternateAnalyse(s,t,a,i,0,n,o,e),d=r.reduce((u,h)=>u+h.cost.total,0),l=r.reduce((u,h)=>u+h.cost.hire,0),c=r.reduce((u,h)=>u+h.cost.bunker,0),p=r.reduce((u,h)=>u+h.distance,0),w=r.reduce((u,h)=>u+h.totalHrs,0);C==null||C.info("[%s][L%d] cost with cpa/cpb turn: %j",e.requestId,e.level,{cost:d,hire:l,bunker:c,distance:p,hours:w});const M=await B.alternateAnalyse(s,t,a,i,1,n,o,e),j=M.reduce((u,h)=>u+h.cost.total,0),F=M.reduce((u,h)=>u+h.cost.hire,0),b=M.reduce((u,h)=>u+h.cost.bunker,0),g=M.reduce((u,h)=>u+h.distance,0),m=M.reduce((u,h)=>u+h.totalHrs,0);return C==null||C.info("[%s][L%d] cost with cpb/cpa turn: %j",e.requestId,e.level,{cost:j,hire:F,bunker:b,distance:g,hours:m}),d<j?{combined:!0,cost:Math.round(d*1e3)/1e3,speeds:r,step:o}:{combined:!0,cost:Math.round(j*1e3)/1e3,speeds:M,step:o}}static async alternateAnalyse(s,t,a,i,n,o,e,r={}){var p,w;let d=v.utc(s.etd);const l={lat:s.lat,lng:s.lng},c=[];for(;d.isBefore(a);){const M=d.clone().utc().add(e,"day"),j=JSON.parse(JSON.stringify(o.route)),F=JSON.parse(JSON.stringify(o.waypoints)),b=i[n],g=await B.analyseInstantWithThreshed(l,d.utc().format(),M,t,b,j,F,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,r);g&&(await B.calculateCost(g,b,s,r),C==null||C.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,d.utc().format(),M.utc().format(),{cost:g.cost.total,hire:g.cost.hire,bunker:g.cost.bunker,distance:g.distance,hours:g.totalHrs,cp:`${b.speed}/${b.fo}/${b.dgo}`})),r.counter=r.counter+1;const m=(w=(p=g==null?void 0:g.sample)==null?void 0:p.hours)==null?void 0:w.at(-1);if(m)l.lat=m.lat,l.lng=m.lng,d=v(m.eta),c.push(g),n=n?0:1;else break}return c}static async calculateCost(s,t,a,i={}){var n;if(s){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,e=Math.round((a.dailyHire||0)*s.suspend/24*1e3)/1e3,r=Math.round(e+s.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3,d=Math.round(s.totalFoCons*(a.priceFO||0)*1e3)/1e3,l=Math.round((s.totalDgoCons+(((n=s.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;s.cost={total:Math.round((r+d+l)*1e3)/1e3,hire:r,suspendHire:e,bunker:Math.round((d+l)*1e3)/1e3,cp:t}}return s}static async calculateECA(s,t,a={}){var r,d,l,c;const i=await H.LaneHelper.intersectInECA((s==null?void 0:s.route)||[]);let n=0,o=0,e=0;(d=(r=s==null?void 0:s.sample)==null?void 0:r.wps)==null||d.forEach(p=>{p.positionTime=v.utc(p.etd||p.eta).unix()});for(const p of i){n+=p.distance;const w=await H.LaneHelper.deadReckoningTime((l=p.waypoints)==null?void 0:l.at(0),s.sample.all||s.sample.wps),M=await H.LaneHelper.deadReckoningTime((c=p.waypoints)==null?void 0:c.at(-1),s.sample.all||s.sample.wps);p.in=w,p.out=M,p.totalHrs=H.LngLatHelper.roundPrecision((M.positionTime-w.positionTime)/3600,3),p.totalDgoCons=H.LngLatHelper.roundPrecision(t.fo/24*p.totalHrs,3),o+=p.totalHrs,e+=p.totalDgoCons}return n=H.LngLatHelper.roundPrecision(n,3),o=H.LngLatHelper.roundPrecision(o,3),e=H.LngLatHelper.roundPrecision(e,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:e,eca:i}}static async mergeSpeeds(s,t={}){var m,u;const a={hours:[],wps:[],days:[]},i=s.reduce((h,f)=>h+f.distance,0),n=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.distanceInECA)||0)},0),o=s.reduce((h,f)=>h+f.totalHrs,0),e=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.hoursInECA)||0)},0),r=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.totalDgoConsInECA)||0)},0),d=s.reduce((h,f)=>h+f.wxFactor*f.totalHrs/o,0),l=s.reduce((h,f)=>h+f.cFactor*f.totalHrs/o,0),c=s.reduce((h,f)=>h+f.totalFoCons,0),p=s.reduce((h,f)=>h+f.totalDgoCons,0),w=s.reduce((h,f)=>h+f.cost.total,0),M=s.reduce((h,f)=>h+f.cost.hire,0),j=s.reduce((h,f)=>h+f.cost.bunker,0),F=[],b=[];let g;for(const h of s){b.push(...((m=h.extend)==null?void 0:m.eca)||[]);const f=h.sample.hours,k=h.sample.wps,I=h.sample.days,E=f.at(0);g&&(E.distanceFromPrevious=g.distanceFromPrevious,E.distanceFromStart=g.distanceFromStart,f.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)}),k.at(0).distanceFromPrevious=g.distanceFromPrevious,k.at(0).distanceFromStart=g.distanceFromStart,k.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)}),I.at(0).distanceFromPrevious=g.distanceFromPrevious,I.at(0).distanceFromStart=g.distanceFromStart,I.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)})),E.cp=h.cost.cp;const Y=[h.etd,h.eta],x=F.findIndex(T=>T.id===E.cp.id);x===-1?(E.cp.segment=[Y],F.push(E.cp)):F[x].segment.push(Y),f.forEach(T=>{var W;((W=a.hours)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.hours.push(T)}),k.forEach(T=>{var W;((W=a.wps)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.wps.push(T)}),I.forEach(T=>{var W;((W=a==null?void 0:a.days)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.days.push(T)});const R=(u=a.wps)==null?void 0:u.findIndex(T=>T.eta===E.eta);R===-1?a.wps.push(E):a.wps[R]=E,g=f.at(-1)}return a.wps.sort((h,f)=>{v(h.etd).unix()-v(f.etd).unix()}),a.wps.forEach((h,f)=>{const k=a.wps[f-1];if(k){const I=h.distanceFromStart-(k.distanceFromStart||0),E=v(h.eta||h.etd).diff(v(k.etd||k.eta),"hour",!0),Y=Math.round(I/E*100)/100;h.avgSpd=Y;const x=H.LaneHelper.calculateBearing(k,h);k.bearing=x}}),{sample:a,etd:s.at(0).etd,eta:s.at(-1).eta,from:s.at(0).from,to:s.at(-1).to,v0:s.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(d*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(p*1e3)/1e3,cost:{total:Math.round(w*1e3)/1e3,hire:Math.round(M*1e3)/1e3,bunker:Math.round(j*1e3)/1e3},extend:{cps:F,eca:b,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(e*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:s}}}}P.AISImpl=G,P.AlertHelper=ht,P.AlertLevel=lt,P.HifleetImpl=bt,P.LoadCondition=mt,P.MyShipImpl=gt,P.MyVesselImpl=Mt,P.ShipxyImpl=vt,P.SpeedHelper=B,P.SpeedLabel=yt,P.VesselTag=ft,P.alertHelper=wt,Object.defineProperty(P,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "3.4.2",
4
+ "version": "3.4.4",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [