@idm-plugin/vessel 3.6.1 → 3.6.3

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
1
  var ht = Object.defineProperty;
2
2
  var mt = (x, e, t) => e in x ? ht(x, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : x[e] = t;
3
3
  var U = (x, e, t) => (mt(x, typeof e != "symbol" ? e + "" : e, t), t);
4
- import B from "got";
5
- import dt from "@log4js-node/log4js-api";
4
+ import z from "got";
5
+ import ut from "@log4js-node/log4js-api";
6
6
  import w from "moment";
7
- import { LaneHelper as O, LngLatHelper as z } from "@idm-plugin/geo2";
7
+ import { LaneHelper as R, LngLatHelper as J } from "@idm-plugin/geo2";
8
8
  import { MeteoHelper2 as ft } from "@idm-plugin/meteo2";
9
- import { Meteo2Assist as ct } from "@idm-plugin/meteo";
9
+ import { Meteo2Assist as dt } from "@idm-plugin/meteo";
10
10
  let g;
11
11
  try {
12
- g = dt.getLogger("vessel");
12
+ g = 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 jt extends at {
57
+ class Tt extends nt {
58
58
  constructor(t, a) {
59
59
  super();
60
60
  U(this, "clientId");
@@ -69,7 +69,7 @@ class jt extends at {
69
69
  client_secret: this.clientSecret,
70
70
  grant_type: "client_credentials"
71
71
  }
72
- }, n = await B.post(a, o).json();
72
+ }, n = await z.post(a, o).json();
73
73
  g == null || g.info("[%s] fetch access token from: %s - %j", t.requestId, a, n), n.error || (this.token = {
74
74
  accessToken: n.access_token,
75
75
  tokenType: n.token_type,
@@ -101,7 +101,7 @@ class jt extends at {
101
101
  }
102
102
  };
103
103
  g == null || g.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, o, n);
104
- const i = await B.post(o, n).json();
104
+ const i = await z.post(o, n).json();
105
105
  return i.status !== 200 ? (g == null || g.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), []) : (i.data || []).map((u) => ({
106
106
  mmsi: u.mmsi,
107
107
  name: u.nameEn,
@@ -129,7 +129,7 @@ class jt extends at {
129
129
  searchParams: i
130
130
  };
131
131
  g == null || g.info("[%s] fetch vessel from: %s - %j", a.requestId, n, s);
132
- const r = await B.get(n, s).json();
132
+ const r = await z.get(n, s).json();
133
133
  if (r.status !== 200)
134
134
  return g == null || g.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
135
135
  {
@@ -173,7 +173,7 @@ class jt extends at {
173
173
  }
174
174
  };
175
175
  g == null || g.info("[%s] fetch vessel archive from: %s - %j", a.requestId, o, n);
176
- const i = await B.post(o, n).json();
176
+ const i = await z.post(o, n).json();
177
177
  return i.status !== 200 ? (g == null || g.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), {}) : i.data;
178
178
  }
179
179
  async realTimePosition(t, a = {}) {
@@ -186,7 +186,7 @@ class jt extends at {
186
186
  searchParams: { mmsi: t }
187
187
  };
188
188
  g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
189
- const i = await B.get(o, n).json();
189
+ const i = await z.get(o, n).json();
190
190
  if (i.code)
191
191
  return g == null || g.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), i;
192
192
  const s = i.data;
@@ -237,7 +237,7 @@ class jt extends at {
237
237
  * @param options { requiretId: '请求ID', useAIModel: '启用AI算法', withECA: '是否计算低硫区航行距离', withSpecial: '是否计算穿越的特战区列表和海盗区列表', draught: '最大吃水' }
238
238
  */
239
239
  async calculateRoute(t, a, o, n, i, s = {}) {
240
- var k, b, S;
240
+ var k, b, F;
241
241
  const r = w();
242
242
  await this.checkToken(s);
243
243
  const l = "https://market.myvessel.cn/sdc/v1/mkt/routes/plan", u = {
@@ -260,7 +260,7 @@ class jt extends at {
260
260
  json: u
261
261
  };
262
262
  g == null || g.info("[%s] fetch route from: %s - %j", s.requestId, l, c);
263
- const h = await B.post(l, c).json();
263
+ const h = await z.post(l, c).json();
264
264
  if (h.status !== 200)
265
265
  return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message: h.message, status: h.status, code: h.code }), {};
266
266
  {
@@ -329,9 +329,9 @@ class jt extends at {
329
329
  }), I.waypoints = f == null ? void 0 : f.map((M) => ({
330
330
  lat: Math.round(M.lat * 1e5) / 1e5,
331
331
  lng: Math.round(M.lon * 1e5) / 1e5
332
- })), (S = I.waypoints) != null && S.length && (I.waypoints = O.simplifyCoordinates(I.waypoints), I.route = O.divideAccordingToLng(I.waypoints), I.distance = O.calculateRouteDistance(I.route), I.distanceInECA = m);
333
- const C = w().diff(r, "second");
334
- return I.memo = `time cost: ${C}s`, g.info("[%s] calculate route cost: %d seconds", s.requestId, C), I;
332
+ })), (F = I.waypoints) != null && F.length && (I.waypoints = R.simplifyCoordinates(I.waypoints), I.route = R.divideAccordingToLng(I.waypoints), I.distance = R.calculateRouteDistance(I.route), I.distanceInECA = m);
333
+ const S = w().diff(r, "second");
334
+ return I.memo = `time cost: ${S}s`, g.info("[%s] calculate route cost: %d seconds", s.requestId, S), I;
335
335
  }
336
336
  }
337
337
  async trajectory(t, a, o, n, i = !0, s = {}) {
@@ -342,10 +342,10 @@ class jt extends at {
342
342
  return await this.trajectoryIn30Day(t, l, u, r, n, c, s), c;
343
343
  }
344
344
  async trajectoryIn30Day(t, a, o, n, i, s, r = {}) {
345
- var b, S, I, p, v;
345
+ var b, F, I, p, v;
346
346
  const l = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", u = {
347
347
  headers: {
348
- Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(S = this.token) == null ? void 0 : S.accessToken}`
348
+ Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(F = this.token) == null ? void 0 : F.accessToken}`
349
349
  },
350
350
  json: {
351
351
  mmsi: t,
@@ -354,15 +354,15 @@ class jt extends at {
354
354
  }
355
355
  };
356
356
  g == null || g.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, u);
357
- const c = await B.post(l, u).json();
357
+ const c = await z.post(l, u).json();
358
358
  if (c.code)
359
359
  return g == null || g.warn("[%s] fetch trajectory failed: %j", r.requestId, l, { message: c.message, status: c.status, code: c.code }), c;
360
360
  let h = -1;
361
361
  const k = w(`${(p = (I = c.data) == null ? void 0 : I[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
362
362
  return (v = c.data) == null || v.forEach((f) => {
363
- for (const P in f)
364
- !isNaN(f[P]) && Number(f[P]) !== 1 / 0 && (f[P] = Number(f[P]));
365
- const d = w(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), m = f.status, { labelCn: y, labelEn: C } = this.parseStatus(m), M = {
363
+ for (const N in f)
364
+ !isNaN(f[N]) && Number(f[N]) !== 1 / 0 && (f[N] = Number(f[N]));
365
+ const d = w(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), m = f.status, { labelCn: y, labelEn: S } = this.parseStatus(m), M = {
366
366
  mmsi: f.mmsi,
367
367
  imo: n == null ? void 0 : n.imo,
368
368
  lat: f.lat,
@@ -376,7 +376,7 @@ class jt extends at {
376
376
  destination: f.dest,
377
377
  positionTime: d.unix(),
378
378
  labelCn: y,
379
- labelEn: C,
379
+ labelEn: S,
380
380
  method: "trajectory",
381
381
  vendor: "myVessel",
382
382
  utc: d.utc().format()
@@ -385,7 +385,7 @@ class jt extends at {
385
385
  }), s;
386
386
  }
387
387
  }
388
- class Ft extends at {
388
+ class jt extends nt {
389
389
  constructor(t) {
390
390
  super();
391
391
  U(this, "token");
@@ -397,7 +397,7 @@ class Ft extends at {
397
397
  mmsi: t,
398
398
  usertoken: this.token
399
399
  }
400
- }, i = await B.post(o, n).json();
400
+ }, i = await z.post(o, n).json();
401
401
  g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
402
402
  const s = i == null ? void 0 : i.list;
403
403
  if (!s)
@@ -447,7 +447,7 @@ class Ft extends at {
447
447
  Host: "www.hifleet.com"
448
448
  }
449
449
  };
450
- let i = await B.post(o, n).json();
450
+ let i = await z.post(o, n).json();
451
451
  g == null || g.info("[%s] fetch vessel props from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]);
452
452
  for (const r in i)
453
453
  !isNaN(i[r]) && Number(i[r]) !== 1 / 0 && (i[r] = Number(i[r]));
@@ -461,7 +461,7 @@ class Ft extends at {
461
461
  draught: i.dr,
462
462
  type: i.t
463
463
  };
464
- return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", i = await B.post(o, n).json(), g == null || g.info("[%s] search vessel dead weight from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]), i && (s.deadweight = Number(i.dwt)), s;
464
+ return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", i = await z.post(o, n).json(), g == null || g.info("[%s] search vessel dead weight from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]), i && (s.deadweight = Number(i.dwt)), s;
465
465
  }
466
466
  async suggest(t, a = {}) {
467
467
  const o = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
@@ -473,7 +473,7 @@ class Ft extends at {
473
473
  Origin: "https://www.hifleet.com",
474
474
  Host: "www.hifleet.com"
475
475
  }
476
- }, i = await B.post(o, n).json();
476
+ }, i = await z.post(o, n).json();
477
477
  g == null || g.info("[%s] suggest vessel props from: %s - %j", a.requestId, o, n);
478
478
  const s = [];
479
479
  for (const r of i)
@@ -502,19 +502,19 @@ class Ft extends at {
502
502
  mmsi: t,
503
503
  usertoken: this.token
504
504
  }
505
- }, k = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await B.get(k, h).json();
505
+ }, k = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await z.get(k, h).json();
506
506
  g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, k, h);
507
- let S;
508
- b && (S = ((d = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : d.ship) || [], S.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
507
+ let F;
508
+ b && (F = ((d = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : d.ship) || [], F.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
509
509
  const I = [];
510
510
  let p = -1;
511
- const v = w(`${(m = S == null ? void 0 : S[0]) == null ? void 0 : m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
512
- for (const y of S) {
513
- for (const H in y)
514
- !isNaN(y[H]) && Number(y[H]) !== 1 / 0 && (y[H] = Number(y[H]));
515
- const C = w(`${y.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
511
+ const v = w(`${(m = F == null ? void 0 : F[0]) == null ? void 0 : m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
512
+ for (const y of F) {
513
+ for (const L in y)
514
+ !isNaN(y[L]) && Number(y[L]) !== 1 / 0 && (y[L] = Number(y[L]));
515
+ const S = w(`${y.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
516
516
  y.status = y.sp > 4 ? 0 : 1;
517
- const { labelEn: M, labelCn: j } = this.parseStatus(y.status), P = {
517
+ const { labelEn: M, labelCn: j } = this.parseStatus(y.status), N = {
518
518
  mmsi: y.m,
519
519
  name: y.n,
520
520
  imo: r == null ? void 0 : r.imo,
@@ -524,20 +524,20 @@ class Ft extends at {
524
524
  sog: y.sp,
525
525
  cog: y.co,
526
526
  hdg: y.hdg,
527
- positionTime: C.unix(),
528
- utc: C.utc().format(),
527
+ positionTime: S.unix(),
528
+ utc: S.utc().format(),
529
529
  status: y.status,
530
530
  labelCn: j,
531
531
  labelEn: M,
532
532
  method: "trajectory",
533
533
  vendor: "hifleet"
534
- }, D = Math.floor(C.diff(v, "minute", !0) / (n || 1));
535
- D !== p && (p = D, I.push(P));
534
+ }, D = Math.floor(S.diff(v, "minute", !0) / (n || 1));
535
+ D !== p && (p = D, I.push(N));
536
536
  }
537
537
  return I;
538
538
  }
539
539
  }
540
- class Nt extends at {
540
+ class xt extends nt {
541
541
  constructor(t) {
542
542
  super();
543
543
  U(this, "token");
@@ -550,7 +550,7 @@ class Nt extends at {
550
550
  k: this.token,
551
551
  enc: 1
552
552
  }
553
- }, n = "https://api.shipxy.com/apicall/GetSingleShip", i = await B.get(n, o).json();
553
+ }, n = "https://api.shipxy.com/apicall/GetSingleShip", i = await z.get(n, o).json();
554
554
  if (g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o), (i == null ? void 0 : i.status) !== 0)
555
555
  return i;
556
556
  const s = i.data[0];
@@ -591,10 +591,10 @@ class Nt extends at {
591
591
  btm: l.unix(),
592
592
  etm: u.unix()
593
593
  }
594
- }, k = await B.get(c, h).json();
594
+ }, k = await z.get(c, h).json();
595
595
  if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, c, h), (k == null ? void 0 : k.status) !== 0)
596
596
  return k;
597
- const b = k == null ? void 0 : k.points, S = [], I = w.unix((v = b[0]) == null ? void 0 : v.utc);
597
+ const b = k == null ? void 0 : k.points, F = [], I = w.unix((v = b[0]) == null ? void 0 : v.utc);
598
598
  let p = -1;
599
599
  for (const f of b) {
600
600
  const d = w.unix(f.utc), m = {
@@ -609,12 +609,12 @@ class Nt extends at {
609
609
  method: "trajectory",
610
610
  vendor: "shipxy"
611
611
  }, y = Math.floor(d.diff(I, "minute", !0) / (n || 1));
612
- y !== p && (p = y, S.push(m));
612
+ y !== p && (p = y, F.push(m));
613
613
  }
614
- return S;
614
+ return F;
615
615
  }
616
616
  }
617
- class xt extends at {
617
+ class Nt extends nt {
618
618
  constructor(t) {
619
619
  super();
620
620
  U(this, "token");
@@ -628,7 +628,7 @@ class xt extends at {
628
628
  json: {
629
629
  mmsiList: t
630
630
  }
631
- }, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", i = await B.post(n, o).json();
631
+ }, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", i = await z.post(n, o).json();
632
632
  return g == null || g.info("[%s] fetch ship id from: %s - %j", a.requestId, n, o), i.code !== "0" ? i : i.data[0].shipId;
633
633
  }
634
634
  async getShipInfo(t, a = {}) {
@@ -639,7 +639,7 @@ class xt extends at {
639
639
  json: {
640
640
  shipId: t
641
641
  }
642
- }, n = "https://api3.myships.com/sp/ships/aissta", i = await B.post(n, o).json();
642
+ }, n = "https://api3.myships.com/sp/ships/aissta", i = await z.post(n, o).json();
643
643
  if (g == null || g.info("[%s] fetch ship info from: %s - %j", a.requestId, n, o), i.code !== "0")
644
644
  return i;
645
645
  const s = i.data;
@@ -662,7 +662,7 @@ class xt extends at {
662
662
  json: {
663
663
  shipId: o
664
664
  }
665
- }, s = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(s, i).json();
665
+ }, s = "https://api3.myships.com/sp/ships/position/latest", r = await z.post(s, i).json();
666
666
  g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, i);
667
667
  const l = r.data[0];
668
668
  for (const b in l)
@@ -703,14 +703,14 @@ class xt extends at {
703
703
  startTime: a,
704
704
  endTime: o
705
705
  }
706
- }, c = "https://api3.myships.com/sp/ships/position/history", h = await B.post(c, u).json();
706
+ }, c = "https://api3.myships.com/sp/ships/position/history", h = await z.post(c, u).json();
707
707
  if (g == null || g.info("[%s] fetch trajectory from: %s - %j", l.requestId, c, u), h.code !== "0")
708
708
  return g == null || g.warn("[%s] invoke myship trajectory failed: %j", l.requestId, h), h;
709
709
  const k = h.data;
710
710
  for (const p in k)
711
711
  !isNaN(k[p]) && Number(k[p]) !== 1 / 0 && (k[p] = Number(k[p]));
712
712
  const b = w.unix((I = k[0]) == null ? void 0 : I.posTime);
713
- let S = -1;
713
+ let F = -1;
714
714
  for (const p of k) {
715
715
  const v = w.unix(p.posTime), f = {
716
716
  imo: n == null ? void 0 : n.imo,
@@ -726,14 +726,14 @@ class xt extends at {
726
726
  method: "trajectory",
727
727
  vendor: "myship"
728
728
  }, d = Math.floor(v.diff(b, "minute", !0) / (s || 1));
729
- d !== S && (S = d, r.push(f));
729
+ d !== F && (F = d, r.push(f));
730
730
  }
731
731
  return r;
732
732
  }
733
733
  }
734
- let J;
734
+ let K;
735
735
  try {
736
- J = dt.getLogger("vessel");
736
+ K = ut.getLogger("vessel");
737
737
  } catch {
738
738
  } finally {
739
739
  }
@@ -749,7 +749,7 @@ class Mt {
749
749
  */
750
750
  parsePrinciple(e, t = {}) {
751
751
  var s, r, l;
752
- J == null || J.debug("[%s] parse rule: %s", t.requestId, e);
752
+ K == null || K.debug("[%s] parse rule: %s", t.requestId, e);
753
753
  const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), o = e.match(a) ? (s = e.match(a)) == null ? void 0 : s[0] : void 0, n = o == null ? void 0 : o.split(";");
754
754
  if (!n)
755
755
  return;
@@ -774,7 +774,7 @@ class Mt {
774
774
  */
775
775
  parseRule(e, t = {}) {
776
776
  var i;
777
- J == null || J.debug("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
777
+ K == null || K.debug("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
778
778
  const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), o = (i = e == null ? void 0 : e.match(a)) == null ? void 0 : i[0], n = o == null ? void 0 : o.split(",");
779
779
  if (n) {
780
780
  let s = n[3] === "Number.MAX_VALUE" ? 100 : Number(n[3]);
@@ -794,12 +794,12 @@ class Mt {
794
794
  * @param options
795
795
  */
796
796
  checkWeather(e, t, a = {}) {
797
- var b, S, I, p, v, f, d, m, y, C, M, j, P, D, H;
797
+ var b, F, I, p, v, f, d, m, y, S, M, j, N, D, L;
798
798
  let o = 0, n = 0, i = 0, s = 0;
799
- const r = Math.round(((S = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : S.number) * 1.6 * 100) / 100, l = (p = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : p.number, u = (f = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : f.number, c = Math.round((((m = (d = t == null ? void 0 : t.SEVERE) == null ? void 0 : d.wind) == null ? void 0 : m.number) + 2) * 100) / 100, h = (C = (y = t == null ? void 0 : t.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : C.number, k = (j = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
800
- for (let F = 0; F < (e == null ? void 0 : e.length); F++) {
801
- const N = e[F], R = (D = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wave) == null ? void 0 : D.sig, W = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wind, K = F ? w(N.eta).diff(w(e[F - 1].eta), "hour", !0) : 0;
802
- s = K > s ? K : s, J == null || J.debug("[%s] check sig.wave: %j", a.requestId, { ...R, dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u }), (R == null ? void 0 : R.height) >= r ? N.isDangerous = !0 : (R == null ? void 0 : R.height) >= l ? N.isSevere = !0 : (R == null ? void 0 : R.height) >= u && (N.isHeavy = !0), J == null || J.debug("[%s] check wind: %j", a.requestId, { ...W, dgThd4Wd: c, svThd4Wd: h, hvThd4Wd: k }), (W == null ? void 0 : W.scale) >= c ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (W == null ? void 0 : W.scale) > h ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (W == null ? void 0 : W.scale) === k && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), o += N.isDangerous ? K : 0, n += N.isSevere ? K : 0, i += N.isHeavy ? K : 0;
799
+ const r = Math.round(((F = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : F.number) * 1.6 * 100) / 100, l = (p = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : p.number, u = (f = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : f.number, c = Math.round((((m = (d = t == null ? void 0 : t.SEVERE) == null ? void 0 : d.wind) == null ? void 0 : m.number) + 2) * 100) / 100, h = (S = (y = t == null ? void 0 : t.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : S.number, k = (j = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
800
+ for (let W = 0; W < (e == null ? void 0 : e.length); W++) {
801
+ const C = e[W], Y = (D = (N = C == null ? void 0 : C.meteo) == null ? void 0 : N.wave) == null ? void 0 : D.sig, A = (L = C == null ? void 0 : C.meteo) == null ? void 0 : L.wind, V = W ? w(C.eta).diff(w(e[W - 1].eta), "hour", !0) : 0;
802
+ s = V > s ? V : s, K == null || K.debug("[%s] check sig.wave: %j", a.requestId, { ...Y, dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u }), (Y == null ? void 0 : Y.height) >= r ? C.isDangerous = !0 : (Y == null ? void 0 : Y.height) >= l ? C.isSevere = !0 : (Y == null ? void 0 : Y.height) >= u && (C.isHeavy = !0), K == null || K.debug("[%s] check wind: %j", a.requestId, { ...A, dgThd4Wd: c, svThd4Wd: h, hvThd4Wd: k }), (A == null ? void 0 : A.scale) >= c ? (C.isDangerous = !0, delete C.isSevere, delete C.isHeavy) : (A == null ? void 0 : A.scale) > h ? (C.isDangerous || (C.isSevere = !0), delete C.isHeavy) : (A == null ? void 0 : A.scale) === k && !C.isDangerous && !C.isSevere && (C.isHeavy = !0), o += C.isDangerous ? V : 0, n += C.isSevere ? V : 0, i += C.isHeavy ? V : 0;
803
803
  }
804
804
  return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, i = Math.round(i * 100) / 100, s = Math.round(s), { sample: e, dangerous: o, severe: n, heavy: i, step: s < 3 ? 3 : s, wind: { dgThd4Wd: c, svThd4Wd: h, hvThd4Wd: k }, sig: { dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u } };
805
805
  }
@@ -807,13 +807,13 @@ class Mt {
807
807
  const Dt = new Mt();
808
808
  let E;
809
809
  try {
810
- E = dt.getLogger("vessel");
810
+ E = ut.getLogger("vessel");
811
811
  } catch {
812
812
  } finally {
813
813
  }
814
814
  const gt = new ft("", !0);
815
- var bt = /* @__PURE__ */ ((x) => (x.common = "common", x.container = "container", x.tugs = "tugs", x))(bt || {}), pt = /* @__PURE__ */ ((x) => (x.Ballast = "Ballast", x.Laden = "Laden", x))(pt || {}), vt = /* @__PURE__ */ ((x) => (x.Cp = "CP", x.Perf = "Basis", x.Instruct = "Other", x))(vt || {});
816
- class Y {
815
+ var bt = /* @__PURE__ */ ((x) => (x.common = "common", x.container = "container", x.tugs = "tugs", x))(bt || {}), vt = /* @__PURE__ */ ((x) => (x.Ballast = "Ballast", x.Laden = "Laden", x))(vt || {}), pt = /* @__PURE__ */ ((x) => (x.Cp = "CP", x.Perf = "Basis", x.Instruct = "Other", x))(pt || {});
816
+ class H {
817
817
  /**
818
818
  * @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
819
819
  * 方形系数(block coefficient)
@@ -955,22 +955,22 @@ class Y {
955
955
  */
956
956
  static async speedLoseAt(e, t, a, o = "", n = 2, i = !0, s = !1, r = {}) {
957
957
  let l;
958
- if (t.velocity && s && (e.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), i) {
958
+ if (t.velocity && s && (e.speed = J.roundPrecision(t.velocity * 1852 / 3600, 6)), i) {
959
959
  let u;
960
960
  try {
961
961
  o = (o == null ? void 0 : o.toUpperCase()) === "CMEMS" ? "ECMWF" : o, o = (o == null ? void 0 : o.toUpperCase()) === "METEO2" ? "best_match" : o;
962
- const { weatherModels: S, marineModels: I } = await ct.autoPickMeteoModel(o), p = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
962
+ const { weatherModels: F, marineModels: I } = await dt.autoPickMeteoModel(o), p = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
963
963
  ...r,
964
964
  pastDays: 1,
965
965
  forecastDays: 1,
966
- weatherModels: S,
966
+ weatherModels: F,
967
967
  marineModels: I
968
- }), [v] = ct.pickHourly(p, a);
969
- u = ct.toLegacy(v);
970
- } catch (S) {
971
- E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, S);
968
+ }), [v] = dt.pickHourly(p, a);
969
+ u = dt.toLegacy(v);
970
+ } catch (F) {
971
+ E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, F);
972
972
  }
973
- let c = Y.currentFactor(e.bearing, u == null ? void 0 : u.current, n), h = Y.weatherFactor(e, u, c);
973
+ let c = H.currentFactor(e.bearing, u == null ? void 0 : u.current, n), h = H.weatherFactor(e, u, c);
974
974
  const k = e.speed * 1.943844;
975
975
  k + c + h <= 0 && (E.warn(
976
976
  "[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",
@@ -1016,30 +1016,30 @@ class Y {
1016
1016
  static async speedLoseInHoursStep(e, t, a, o, n, i, s = "", r = !0, l = !1, u = {}) {
1017
1017
  t.utc();
1018
1018
  const c = t.clone().add(14, "days"), h = [], k = [], b = [];
1019
- let S = 0, I = 0, p, v;
1019
+ let F = 0, I = 0, p, v;
1020
1020
  for (let f = 0; f < i.length - 1; f++) {
1021
1021
  let d = i[f];
1022
1022
  d.distanceFromStart = Math.round((n + I) * 1e3) / 1e3;
1023
1023
  const m = i[f + 1];
1024
- if (e.bearing = O.calculateBearing(d, m, !m.gcToPrevious), d.bearing = e.bearing, d.suspend && l) {
1024
+ if (e.bearing = R.calculateBearing(d, m, !m.gcToPrevious), d.bearing = e.bearing, d.suspend && l) {
1025
1025
  d.eta = d.eta || t.utc().format(), d.elapsed = d.elapsed ?? 0;
1026
1026
  const M = d.suspend - d.elapsed;
1027
- if (o - S > M)
1028
- o = o - S - M, t.add(M, "hour"), d.elapsed = d.suspend;
1027
+ if (o - F > M)
1028
+ o = o - F - M, t.add(M, "hour"), d.elapsed = d.suspend;
1029
1029
  else {
1030
- const j = o - S;
1030
+ const j = o - F;
1031
1031
  d.elapsed += j, t.add(j, "hour"), o = 0;
1032
1032
  }
1033
1033
  if (E == null || E.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`, u.requestId, d), o === 0)
1034
1034
  return d.distanceFromPrevious = I, { etd: t, from: v || d, to: d, next: i.filter((j) => j), wps: h, days: k, all: b };
1035
1035
  } else
1036
1036
  d.suspend = 0;
1037
- r = t.isAfter(c) ? !1 : r, d = await Y.speedLoseAt(e, d, t, s, 0, r, l, u), b.push(d), v = v || d, d.important && h.push(d), t.isSameOrAfter(a) && (k.push(d), a.add(24, "hour"));
1038
- const y = O.calculateDistance(d, m, !m.gcToPrevious);
1039
- let C = Math.round(y / v.speed * 1e5) / 1e5;
1040
- if (S + C < o) {
1041
- if (S += C, t.add(C, "hour"), delete i[f], E == null || E.debug(
1042
- `[%s] go to %j from %j with ${y}nm, and cost ${C} hours`,
1037
+ r = t.isAfter(c) ? !1 : r, d = await H.speedLoseAt(e, d, t, s, 0, r, l, u), b.push(d), v = v || d, d.important && h.push(d), t.isSameOrAfter(a) && (k.push(d), a.add(24, "hour"));
1038
+ const y = R.calculateDistance(d, m, !m.gcToPrevious);
1039
+ let S = Math.round(y / v.speed * 1e5) / 1e5;
1040
+ if (F + S < o) {
1041
+ if (F += S, t.add(S, "hour"), delete i[f], E == null || E.debug(
1042
+ `[%s] go to %j from %j with ${y}nm, and cost ${S} hours`,
1043
1043
  u.requestId,
1044
1044
  { lat: m.lat, lng: m.lng },
1045
1045
  { lat: v.lat, lng: v.lng, etd: v.etd }
@@ -1048,10 +1048,10 @@ class Y {
1048
1048
  break;
1049
1049
  }
1050
1050
  } else {
1051
- C = o - S, t.add(C, "hour");
1052
- const M = z.roundPrecision(v.speed * C, 5);
1053
- p = O.calculateCoordinate(d, e.bearing, M, "nauticalmiles", !m.gcToPrevious), p.eta = t.utc().format(), i[f] = p, E == null || E.debug(
1054
- `[%s] go to %j from %j with ${M}nm, and cost ${C} hours`,
1051
+ S = o - F, t.add(S, "hour");
1052
+ const M = J.roundPrecision(v.speed * S, 5);
1053
+ p = R.calculateCoordinate(d, e.bearing, M, "nauticalmiles", !m.gcToPrevious), p.eta = t.utc().format(), i[f] = p, E == null || E.debug(
1054
+ `[%s] go to %j from %j with ${M}nm, and cost ${S} hours`,
1055
1055
  u.requestId,
1056
1056
  { lat: p.lat, lng: p.lng },
1057
1057
  { lat: d.lat, lng: d.lng, etd: d.etd }
@@ -1068,7 +1068,7 @@ class Y {
1068
1068
  * @param role 1: 船东, 2: 租家, 0: 未知
1069
1069
  */
1070
1070
  static currentFactor(e, t, a = 0) {
1071
- const o = O.includedAngle(e, (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
1071
+ const o = R.includedAngle(e, (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
1072
1072
  if (Math.abs(o) === Math.PI / 2)
1073
1073
  return 0;
1074
1074
  let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(o);
@@ -1081,14 +1081,14 @@ class Y {
1081
1081
  * @param cFactor 洋流因子
1082
1082
  */
1083
1083
  static weatherFactor(e, t, a = 0) {
1084
- var k, b, S, I, p, v, f;
1084
+ var k, b, F, I, p, v, f;
1085
1085
  E == null || E.debug("calculate weather factor via: %j", { ...e, ...t });
1086
- const o = Y.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), n = z.roundPrecision(a * 1852 / 3600, 6), i = Y.froudeNumber(e.speed - n, e.lbp), s = Y.amendFactor(o, i, e.loadCondition);
1087
- let r = O.includedAngle(e.bearing, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.degree);
1088
- const l = Y.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), u = Y.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (S = t == null ? void 0 : t.wind) == null ? void 0 : S.kts);
1086
+ const o = H.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), n = J.roundPrecision(a * 1852 / 3600, 6), i = H.froudeNumber(e.speed - n, e.lbp), s = H.amendFactor(o, i, e.loadCondition);
1087
+ let r = R.includedAngle(e.bearing, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.degree);
1088
+ const l = H.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), u = H.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (F = t == null ? void 0 : t.wind) == null ? void 0 : F.kts);
1089
1089
  let c = l * s * u / 100 * (e.speed - n);
1090
- c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), E == null || E.debug("wind wx factor = %d", c), r = O.includedAngle(e.bearing, (p = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : p.degree);
1091
- const h = Y.waveHeightFactor(((f = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : f.height) ?? 1, r);
1090
+ c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), E == null || E.debug("wind wx factor = %d", c), r = R.includedAngle(e.bearing, (p = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : p.degree);
1091
+ const h = H.waveHeightFactor(((f = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : f.height) ?? 1, r);
1092
1092
  return E == null || E.debug("wave wx factor = %d", h), c = Math.abs(c) > Math.abs(h) ? c : c * 0.3 + h * 0.7, E == null || E.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;
1093
1093
  }
1094
1094
  /**
@@ -1123,11 +1123,11 @@ class Y {
1123
1123
  static async analyseInstant(e, t, a, o, n, i = "", s = 0, r = !0, l = !1, u = {}) {
1124
1124
  var _, G, X, Q, Z, $;
1125
1125
  const c = w().valueOf();
1126
- e.lng = z.convertToStdLng(e.lng);
1127
- const { route: h, waypoints: k } = n.points, b = O.calculateSubRoute(e, h);
1126
+ e.lng = J.convertToStdLng(e.lng);
1127
+ const { route: h, waypoints: k } = n.points, b = R.calculateSubRoute(e, h);
1128
1128
  if (((_ = b[0]) == null ? void 0 : _.length) <= 1)
1129
1129
  return;
1130
- const { v0: S, label: I } = e.sog ? {
1130
+ const { v0: F, label: I } = e.sog ? {
1131
1131
  v0: e.sog,
1132
1132
  label: e.label || "Other"
1133
1133
  /* Instruct */
@@ -1135,13 +1135,13 @@ class Y {
1135
1135
  v0: o.speed,
1136
1136
  label: "CP"
1137
1137
  /* Cp */
1138
- }, p = Y.assembleProperties(a, o.loadCondition, S, 0), v = k.length ? O.calculateSubWaypoints(e, k) : [];
1139
- v.forEach((A) => A.important = !0);
1138
+ }, p = H.assembleProperties(a, o.loadCondition, F, 0), v = k.length ? R.calculateSubWaypoints(e, k) : [];
1139
+ v.forEach((P) => P.important = !0);
1140
1140
  const f = {
1141
1141
  from: { ...e },
1142
1142
  route: b,
1143
1143
  waypoints: v,
1144
- v0: S,
1144
+ v0: F,
1145
1145
  label: I
1146
1146
  }, d = {
1147
1147
  hours: [],
@@ -1149,16 +1149,16 @@ class Y {
1149
1149
  wps: [],
1150
1150
  all: []
1151
1151
  };
1152
- s || (O.calculateRouteDistance(b) / o.speed <= 72 ? s = 3 : s = 6);
1153
- let m = O.simplifyRouteToCoordinates(b, v, 0), y = 0, C = 0, M = 0, j = 0;
1152
+ s || (R.calculateRouteDistance(b) / o.speed <= 72 ? s = 3 : s = 6);
1153
+ let m = R.simplifyRouteToCoordinates(b, v, 0), y = 0, S = 0, M = 0, j = 0;
1154
1154
  t = w(t).utc();
1155
- const P = t.clone();
1155
+ const N = t.clone();
1156
1156
  for (; m.length > 0; ) {
1157
- const A = s - t.hour() % s, V = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, T = await Y.speedLoseInHoursStep(
1157
+ const P = s - t.hour() % s, B = Math.ceil(t.clone().add(P, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, T = await H.speedLoseInHoursStep(
1158
1158
  p,
1159
1159
  t,
1160
- P,
1161
- V,
1160
+ N,
1161
+ B,
1162
1162
  y,
1163
1163
  m,
1164
1164
  i,
@@ -1167,37 +1167,39 @@ class Y {
1167
1167
  u
1168
1168
  );
1169
1169
  if (d.all.push(...T.all), (G = T.from) != null && G.speed && (d.hours.push(T.from), d.wps.push(...T.wps), d.days.push(...T.days)), m = T == null ? void 0 : T.next, !m.length) {
1170
- const L = await Y.speedLoseAt(p, T.to, w(T.to.eta), i, 0, r, l, u);
1171
- L.bearing = p.bearing, d.hours.push(L), d.all.push(L);
1170
+ const O = await H.speedLoseAt(p, T.to, w(T.to.eta), i, 0, r, l, u);
1171
+ O.bearing = p.bearing, d.hours.push(O), d.all.push(O);
1172
1172
  }
1173
1173
  y += Math.round((((X = T == null ? void 0 : T.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1174
1174
  }
1175
1175
  const D = d.hours;
1176
- for (let A = 0; A < D.length - 1; A++) {
1177
- const V = w(D[A + 1].eta).diff(D[A].etd, "hour", !0) || 1;
1178
- C += (D[A].wxFactor || 0) * V, M += (D[A].cFactor || 0) * V, j += V;
1176
+ for (let P = 0; P < D.length - 1; P++) {
1177
+ const B = w(D[P + 1].eta).diff(D[P].etd, "hour", !0) || 1;
1178
+ S += (D[P].wxFactor || 0) * B, M += (D[P].cFactor || 0) * B, j += B;
1179
1179
  }
1180
- const H = D.reduce((A, V) => A + (V.suspend || 0), 0);
1181
- (Q = d.wps) == null || Q.forEach((A, V) => {
1182
- A.positionTime = w.utc(A.etd || A.eta).unix();
1183
- const T = d.wps[V - 1];
1180
+ const L = D.reduce((P, B) => P + (B.suspend || 0), 0);
1181
+ (Q = d.wps) == null || Q.forEach((P, B) => {
1182
+ P.positionTime = w.utc(P.etd || P.eta).unix();
1183
+ const T = d.wps[B - 1];
1184
1184
  if (T) {
1185
- const L = A.distanceFromStart - T.distanceFromStart, q = w(A.eta || A.etd).diff(w(T.etd || T.eta), "h", !0);
1186
- A.avgSpd = Math.round(L / q * 100) / 100, T.bearing = O.calculateBearing(T, A);
1185
+ const O = P.distanceFromStart - T.distanceFromStart, q = w(P.eta || P.etd).diff(w(T.etd || T.eta), "h", !0);
1186
+ P.avgSpd = Math.round(O / q * 100) / 100;
1187
+ const at = R.calculateBearing(T, P);
1188
+ P.avgBearing = at, T.bearing = at;
1187
1189
  }
1188
- }), d.wps = await Y.reduceWPS(d.wps), d.days = await Y.reduceDays(d.days), d.all = (Z = d.all) == null ? void 0 : Z.reduce((A, V) => (V.positionTime = w.utc(V.etd || V.eta).unix(), A.some((T) => Math.round(T.positionTime / 60) === Math.round(V.positionTime / 60)) || A.push(V), A), []), f.sample = d;
1189
- const F = d.hours.at(0), N = d.hours.at(-1);
1190
- f.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, f.etd = w(F.eta).utc().format(), f.eta = w(N.eta).utc().format(), f.wxFactor = Math.round(C / j * 1e3) / 1e3, f.cFactor = Math.round(M / j * 1e3) / 1e3, f.avgSpeed = Math.round(N.distanceFromStart / j * 1e3) / 1e3, f.totalHrs = Math.round(j * 1e3) / 1e3, f.suspend = Math.round(H * 1e3) / 1e3;
1191
- const R = z.roundPrecision(o.dgo / 24 * H, 3), { distanceInECA: W, hoursInECA: K, totalDgoConsInECA: nt, eca: tt } = await this.calculateECA(f, o, u), et = z.roundPrecision(o.fo / 24 * (j - K), 3), ot = z.roundPrecision(o.dgo / 24 * j + R, 3);
1190
+ }), d.wps = await H.reduceWPS(d.wps), d.days = await H.reduceDays(d.days), d.all = (Z = d.all) == null ? void 0 : Z.reduce((P, B) => (B.positionTime = w.utc(B.etd || B.eta).unix(), P.some((T) => Math.round(T.positionTime / 60) === Math.round(B.positionTime / 60)) || P.push(B), P), []), f.sample = d;
1191
+ const W = d.hours.at(0), C = d.hours.at(-1);
1192
+ f.distance = Math.round(C.distanceFromStart * 1e3) / 1e3, f.etd = w(W.eta).utc().format(), f.eta = w(C.eta).utc().format(), f.wxFactor = Math.round(S / j * 1e3) / 1e3, f.cFactor = Math.round(M / j * 1e3) / 1e3, f.avgSpeed = Math.round(C.distanceFromStart / j * 1e3) / 1e3, f.totalHrs = Math.round(j * 1e3) / 1e3, f.suspend = Math.round(L * 1e3) / 1e3;
1193
+ const Y = J.roundPrecision(o.dgo / 24 * L, 3), { distanceInECA: A, hoursInECA: V, totalDgoConsInECA: ot, eca: tt } = await this.calculateECA(f, o, u), et = J.roundPrecision(o.fo / 24 * (j - V), 3), it = J.roundPrecision(o.dgo / 24 * j + Y, 3);
1192
1194
  f.extend = {
1193
1195
  eca: tt,
1194
- distanceInECA: W,
1195
- hoursInECA: K,
1196
- totalDgoConsInECA: nt,
1197
- totalDgoConsInSuspend: R
1198
- }, f.totalFoCons = et < 0 ? 0 : et, f.totalDgoCons = ot;
1199
- const st = w().valueOf() - c, rt = (($ = d == null ? void 0 : d.hours) == null ? void 0 : $.length) || 1;
1200
- return E == null || E.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", u == null ? void 0 : u.requestId, st, rt, Math.round(st / rt * 1e3) / 1e3), f;
1196
+ distanceInECA: A,
1197
+ hoursInECA: V,
1198
+ totalDgoConsInECA: ot,
1199
+ totalDgoConsInSuspend: Y
1200
+ }, f.totalFoCons = et < 0 ? 0 : et, f.totalDgoCons = it;
1201
+ const st = w().valueOf() - c, ct = (($ = d == null ? void 0 : d.hours) == null ? void 0 : $.length) || 1;
1202
+ return E == null || E.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", u == null ? void 0 : u.requestId, st, ct, Math.round(st / ct * 1e3) / 1e3), f;
1201
1203
  }
1202
1204
  /**
1203
1205
  * 分段失速分析(最多走hours 小时)
@@ -1215,10 +1217,10 @@ class Y {
1215
1217
  * @param options
1216
1218
  */
1217
1219
  static async analyseInstantWithThreshed(e, t, a, o, n, i, s, r = "", l = 3, u = !0, c = !1, h = {}) {
1218
- var X, Q, Z, $, A, V;
1220
+ var X, Q, Z, $, P, B;
1219
1221
  const k = w().valueOf();
1220
- e.lng = z.convertToStdLng(e.lng);
1221
- const { v0: b, label: S } = e.sog ? {
1222
+ e.lng = J.convertToStdLng(e.lng);
1223
+ const { v0: b, label: F } = e.sog ? {
1222
1224
  v0: e.sog,
1223
1225
  label: e.label || "Other"
1224
1226
  /* Instruct */
@@ -1226,12 +1228,12 @@ class Y {
1226
1228
  v0: n.speed,
1227
1229
  label: "CP"
1228
1230
  /* Cp */
1229
- }, I = Y.assembleProperties(o, n.loadCondition, b, 0), p = O.calculateSubRoute(e, i);
1231
+ }, I = H.assembleProperties(o, n.loadCondition, b, 0), p = R.calculateSubRoute(e, i);
1230
1232
  if (((X = p[0]) == null ? void 0 : X.length) <= 1)
1231
1233
  return;
1232
- const v = s.length ? O.calculateSubWaypoints(e, s) : [];
1234
+ const v = s.length ? R.calculateSubWaypoints(e, s) : [];
1233
1235
  v.forEach((T) => T.important = !0);
1234
- let f = O.simplifyRouteToCoordinates(p, v, 0), d = 0, m = 0, y = 0, C = 0;
1236
+ let f = R.simplifyRouteToCoordinates(p, v, 0), d = 0, m = 0, y = 0, S = 0;
1235
1237
  const M = {
1236
1238
  hours: [],
1237
1239
  wps: [],
@@ -1242,51 +1244,51 @@ class Y {
1242
1244
  const j = t.clone();
1243
1245
  for (; f.length > 0; ) {
1244
1246
  const T = l - t.hour() % l;
1245
- let L = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1246
- L = t.clone().add(L, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : L;
1247
- const q = await Y.speedLoseInHoursStep(I, t, j, L, d, f, r, u, c, h);
1248
- if (M.all.push(...q.all), (Q = q.from) != null && Q.speed && (M.hours.push(q.from), q != null && q.wps && M.wps.push(...q.wps), M.days.push(...q.days)), f = q == null ? void 0 : q.next, f.length || M.hours.push(q == null ? void 0 : q.to), d += Math.round((((Z = q == null ? void 0 : q.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
1247
+ let O = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1248
+ O = t.clone().add(O, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : O;
1249
+ const q = await H.speedLoseInHoursStep(I, t, j, O, d, f, r, u, c, h);
1250
+ if (M.all.push(...q.all), (Q = q.from) != null && Q.speed && (M.hours.push(q.from), q != null && q.wps && M.wps.push(...q.wps), M.days.push(...q.days)), f = q == null ? void 0 : q.next, f.length || M.hours.push(q == null ? void 0 : q.to), d += Math.round((((Z = q == null ? void 0 : q.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !O)
1249
1251
  break;
1250
1252
  }
1251
- M.wps = await Y.reduceWPS(M.wps), M.days = await Y.reduceDays(M.days), M.all = ($ = M.all) == null ? void 0 : $.reduce((T, L) => (L.positionTime = w.utc(L.etd || L.eta).unix(), T.some((q) => Math.round(w(q.etd).unix() / 60) === Math.round(w(L.etd).unix() / 60)) || T.push(L), T), []), (A = M.wps) == null || A.forEach((T, L) => {
1252
- const q = M.wps[L - 1];
1253
+ M.wps = await H.reduceWPS(M.wps), M.days = await H.reduceDays(M.days), M.all = ($ = M.all) == null ? void 0 : $.reduce((T, O) => (O.positionTime = w.utc(O.etd || O.eta).unix(), T.some((q) => Math.round(w(q.etd).unix() / 60) === Math.round(w(O.etd).unix() / 60)) || T.push(O), T), []), (P = M.wps) == null || P.forEach((T, O) => {
1254
+ const q = M.wps[O - 1];
1253
1255
  if (q) {
1254
- const ut = T.distanceFromStart - q.distanceFromStart, lt = w(T.eta || T.etd).diff(w(q.etd || q.eta), "h", !0);
1255
- q.bearing = O.calculateBearing(q, T), T.avgSpd = Math.round(ut / lt * 100) / 100;
1256
+ const at = T.distanceFromStart - q.distanceFromStart, lt = w(T.eta || T.etd).diff(w(q.etd || q.eta), "h", !0);
1257
+ q.bearing = R.calculateBearing(q, T), T.avgSpd = Math.round(at / lt * 100) / 100;
1256
1258
  }
1257
1259
  });
1258
- const P = M.hours;
1259
- for (let T = 0; T < P.length - 1; T++) {
1260
- const L = w(P[T + 1].eta).diff(P[T].etd, "hour", !0);
1261
- m += P[T].wxFactor * L, y += P[T].cFactor * L, C += L;
1260
+ const N = M.hours;
1261
+ for (let T = 0; T < N.length - 1; T++) {
1262
+ const O = w(N[T + 1].eta).diff(N[T].etd, "hour", !0);
1263
+ m += N[T].wxFactor * O, y += N[T].cFactor * O, S += O;
1262
1264
  }
1263
- const D = P.reduce((T, L) => T + (L.suspend || 0), 0), H = M.hours.at(0), F = M.hours.at(-1), N = await O.calculateRangeRoute(H, F, p), R = await O.calculateRangeWaypoints(H, F, p, v), W = {
1265
+ const D = N.reduce((T, O) => T + (O.suspend || 0), 0), L = M.hours.at(0), W = M.hours.at(-1), C = await R.calculateRangeRoute(L, W, p), Y = await R.calculateRangeWaypoints(L, W, p, v), A = {
1264
1266
  sample: M,
1265
- distance: Math.round(((F == null ? void 0 : F.distanceFromStart) || 0) * 1e4) / 1e4,
1267
+ distance: Math.round(((W == null ? void 0 : W.distanceFromStart) || 0) * 1e4) / 1e4,
1266
1268
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
1267
- etd: w(H.eta).utc().format(),
1268
- eta: w(F == null ? void 0 : F.eta).utc().format(),
1269
- wxFactor: Math.round(m / C * 1e3) / 1e3,
1270
- cFactor: Math.round(y / C * 1e3) / 1e3,
1271
- avgSpeed: Math.round(((F == null ? void 0 : F.distanceFromStart) || 0) / C * 1e3) / 1e3,
1272
- totalHrs: Math.round(C * 1e3) / 1e3,
1269
+ etd: w(L.eta).utc().format(),
1270
+ eta: w(W == null ? void 0 : W.eta).utc().format(),
1271
+ wxFactor: Math.round(m / S * 1e3) / 1e3,
1272
+ cFactor: Math.round(y / S * 1e3) / 1e3,
1273
+ avgSpeed: Math.round(((W == null ? void 0 : W.distanceFromStart) || 0) / S * 1e3) / 1e3,
1274
+ totalHrs: Math.round(S * 1e3) / 1e3,
1273
1275
  suspend: Math.round(D * 1e3) / 1e3,
1274
- from: H,
1275
- to: F,
1276
- route: N,
1277
- waypoints: R,
1276
+ from: L,
1277
+ to: W,
1278
+ route: C,
1279
+ waypoints: Y,
1278
1280
  v0: b,
1279
- label: S
1280
- }, K = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: nt, hoursInECA: tt, totalDgoConsInECA: et, eca: ot } = await this.calculateECA(W, n, h), it = z.roundPrecision(n.fo / 24 * (C - tt), 3), st = z.roundPrecision(n.dgo / 24 * C + K, 3);
1281
- W.extend = {
1282
- eca: ot,
1283
- distanceInECA: nt,
1281
+ label: F
1282
+ }, V = J.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: tt, totalDgoConsInECA: et, eca: it } = await this.calculateECA(A, n, h), rt = J.roundPrecision(n.fo / 24 * (S - tt), 3), st = J.roundPrecision(n.dgo / 24 * S + V, 3);
1283
+ A.extend = {
1284
+ eca: it,
1285
+ distanceInECA: ot,
1284
1286
  hoursInECA: tt,
1285
1287
  totalDgoConsInECA: et,
1286
- totalDgoConsInSuspend: K
1287
- }, W.totalDgoCons = st, W.totalFoCons = it < 0 ? 0 : it;
1288
- const _ = w().valueOf() - k, G = ((V = M == null ? void 0 : M.hours) == null ? void 0 : V.length) || 1;
1289
- return E == null || E.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, _, G, Math.round(_ / G * 1e3) / 1e3), W;
1288
+ totalDgoConsInSuspend: V
1289
+ }, A.totalDgoCons = st, A.totalFoCons = rt < 0 ? 0 : rt;
1290
+ const _ = w().valueOf() - k, G = ((B = M == null ? void 0 : M.hours) == null ? void 0 : B.length) || 1;
1291
+ return E == null || E.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, _, G, Math.round(_ / G * 1e3) / 1e3), A;
1290
1292
  }
1291
1293
  /**
1292
1294
  * 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
@@ -1307,7 +1309,7 @@ class Y {
1307
1309
  var p, v;
1308
1310
  const i = w().valueOf(), s = [];
1309
1311
  e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
1310
- const r = O.calculateRouteDistance(o.route);
1312
+ const r = R.calculateRouteDistance(o.route);
1311
1313
  let l = 0;
1312
1314
  a.forEach((f) => {
1313
1315
  const d = Math.ceil(r / f.speed / 24);
@@ -1316,7 +1318,7 @@ class Y {
1316
1318
  const u = w.utc(e.etd).add(l ?? 14, "day");
1317
1319
  let c = 1;
1318
1320
  for (const f of a) {
1319
- const d = JSON.parse(JSON.stringify(o.route)), m = JSON.parse(JSON.stringify(o.waypoints)), y = await Y.analyseInstantWithThreshed(
1321
+ const d = JSON.parse(JSON.stringify(o.route)), m = JSON.parse(JSON.stringify(o.waypoints)), y = await H.analyseInstantWithThreshed(
1320
1322
  { lat: e.lat, lng: e.lng },
1321
1323
  e.etd,
1322
1324
  u,
@@ -1330,7 +1332,7 @@ class Y {
1330
1332
  e.useRouteParam,
1331
1333
  n
1332
1334
  );
1333
- y && (await Y.calculateCost(y, f, e, n), s.push(y), E == null || E.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, c, e.etd, u.format(), {
1335
+ y && (await H.calculateCost(y, f, e, n), s.push(y), E == null || E.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, c, e.etd, u.format(), {
1334
1336
  cost: y.cost.total,
1335
1337
  hire: y.cost.hire,
1336
1338
  bunker: y.cost.bunker,
@@ -1342,17 +1344,17 @@ class Y {
1342
1344
  s.sort((f, d) => f.cost.total - d.cost.total);
1343
1345
  const h = s.at(0), k = s.at(1), b = [];
1344
1346
  if (b.push({ combined: !1, speeds: [h], cost: (p = h.cost) == null ? void 0 : p.total }), k) {
1345
- const f = h.cost.cp, d = k.cost.cp, m = w(h.eta), y = w(h.etd), C = m.diff(y, "days", !0);
1346
- let M = Math.ceil(C / 2);
1347
+ const f = h.cost.cp, d = k.cost.cp, m = w(h.eta), y = w(h.etd), S = m.diff(y, "days", !0);
1348
+ let M = Math.ceil(S / 2);
1347
1349
  M = M > 7 ? 7 : M < e.alterStep ? e.alterStep : M;
1348
- let j = 2, P = { combined: !1, speeds: [k], cost: (v = k.cost) == null ? void 0 : v.total }, D;
1350
+ let j = 2, N = { combined: !1, speeds: [k], cost: (v = k.cost) == null ? void 0 : v.total }, D;
1349
1351
  for (; M >= e.alterStep; ) {
1350
- const H = await Y.combinedAnalyse(e, t, u, [f, d], o, M, { ...n, level: j });
1351
- if (P.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = P, P = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), M <= e.alterStep)
1352
+ const L = await H.combinedAnalyse(e, t, u, [f, d], o, M, { ...n, level: j });
1353
+ if (N.cost > L.cost ? D ? (D == null ? void 0 : D.cost) > L.cost && (D = L) : (D = N, N = L) : (!D || (D == null ? void 0 : D.cost) > L.cost) && (D = L), M <= e.alterStep)
1352
1354
  break;
1353
1355
  M = Math.ceil(M / 2), j += 1;
1354
1356
  }
1355
- b.push(P), D && b.push(D);
1357
+ b.push(N), D && b.push(D);
1356
1358
  }
1357
1359
  const I = w().valueOf() - i;
1358
1360
  return E == null || E.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, I), b.sort((f, d) => f.cost - d.cost);
@@ -1369,7 +1371,7 @@ class Y {
1369
1371
  */
1370
1372
  static async combinedAnalyse(e, t, a, o, n, i, s = {}) {
1371
1373
  s.counter = 1, E == null || E.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, i);
1372
- const r = await Y.alternateAnalyse(e, t, a, o, 0, n, i, s), l = r.reduce((d, m) => d + m.cost.total, 0), u = r.reduce((d, m) => d + m.cost.hire, 0), c = r.reduce((d, m) => d + m.cost.bunker, 0), h = r.reduce((d, m) => d + m.distance, 0), k = r.reduce((d, m) => d + m.totalHrs, 0);
1374
+ const r = await H.alternateAnalyse(e, t, a, o, 0, n, i, s), l = r.reduce((d, m) => d + m.cost.total, 0), u = r.reduce((d, m) => d + m.cost.hire, 0), c = r.reduce((d, m) => d + m.cost.bunker, 0), h = r.reduce((d, m) => d + m.distance, 0), k = r.reduce((d, m) => d + m.totalHrs, 0);
1373
1375
  E == null || E.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1374
1376
  cost: l,
1375
1377
  hire: u,
@@ -1377,14 +1379,14 @@ class Y {
1377
1379
  distance: h,
1378
1380
  hours: k
1379
1381
  });
1380
- const b = await Y.alternateAnalyse(e, t, a, o, 1, n, i, s), S = b.reduce((d, m) => d + m.cost.total, 0), I = b.reduce((d, m) => d + m.cost.hire, 0), p = b.reduce((d, m) => d + m.cost.bunker, 0), v = b.reduce((d, m) => d + m.distance, 0), f = b.reduce((d, m) => d + m.totalHrs, 0);
1382
+ const b = await H.alternateAnalyse(e, t, a, o, 1, n, i, s), F = b.reduce((d, m) => d + m.cost.total, 0), I = b.reduce((d, m) => d + m.cost.hire, 0), p = b.reduce((d, m) => d + m.cost.bunker, 0), v = b.reduce((d, m) => d + m.distance, 0), f = b.reduce((d, m) => d + m.totalHrs, 0);
1381
1383
  return E == null || E.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
1382
- cost: S,
1384
+ cost: F,
1383
1385
  hire: I,
1384
1386
  bunker: p,
1385
1387
  distance: v,
1386
1388
  hours: f
1387
- }), l < S ? { combined: !0, cost: Math.round(l * 1e3) / 1e3, speeds: r, step: i } : { combined: !0, cost: Math.round(S * 1e3) / 1e3, speeds: b, step: i };
1389
+ }), l < F ? { combined: !0, cost: Math.round(l * 1e3) / 1e3, speeds: r, step: i } : { combined: !0, cost: Math.round(F * 1e3) / 1e3, speeds: b, step: i };
1388
1390
  }
1389
1391
  /**
1390
1392
  * 基于cp索引,交替计算指定步长下的成本
@@ -1402,13 +1404,13 @@ class Y {
1402
1404
  let l = w.utc(e.etd);
1403
1405
  const u = { lat: e.lat, lng: e.lng }, c = [];
1404
1406
  for (; l.isBefore(a); ) {
1405
- const b = l.clone().utc().add(s, "day"), S = JSON.parse(JSON.stringify(i.route)), I = JSON.parse(JSON.stringify(i.waypoints)), p = o[n], v = await Y.analyseInstantWithThreshed(
1407
+ const b = l.clone().utc().add(s, "day"), F = JSON.parse(JSON.stringify(i.route)), I = JSON.parse(JSON.stringify(i.waypoints)), p = o[n], v = await H.analyseInstantWithThreshed(
1406
1408
  u,
1407
1409
  l.utc().format(),
1408
1410
  b,
1409
1411
  t,
1410
1412
  p,
1411
- S,
1413
+ F,
1412
1414
  I,
1413
1415
  e.meteoVendor,
1414
1416
  e.speedStep,
@@ -1416,7 +1418,7 @@ class Y {
1416
1418
  e.useRouteParam,
1417
1419
  r
1418
1420
  );
1419
- v && (await Y.calculateCost(v, p, e, r), E == null || E.info(
1421
+ v && (await H.calculateCost(v, p, e, r), E == null || E.info(
1420
1422
  "[%s][L%d-%d] analyse from %s to %s cost: %j",
1421
1423
  r.requestId,
1422
1424
  r.level,
@@ -1467,17 +1469,17 @@ class Y {
1467
1469
  */
1468
1470
  static async calculateECA(e, t, a = {}) {
1469
1471
  var r, l, u, c;
1470
- const o = await O.intersectInECA((e == null ? void 0 : e.route) || []);
1472
+ const o = await R.intersectInECA((e == null ? void 0 : e.route) || []);
1471
1473
  let n = 0, i = 0, s = 0;
1472
1474
  (l = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || l.forEach((h) => {
1473
1475
  h.positionTime = w.utc(h.etd || h.eta).unix();
1474
1476
  });
1475
1477
  for (const h of o) {
1476
1478
  n += h.distance;
1477
- const k = await O.deadReckoningTime((u = h.waypoints) == null ? void 0 : u.at(0), e.sample.all || e.sample.wps), b = await O.deadReckoningTime((c = h.waypoints) == null ? void 0 : c.at(-1), e.sample.all || e.sample.wps);
1478
- h.in = k, h.out = b, h.totalHrs = z.roundPrecision((b.positionTime - k.positionTime) / 3600, 3), h.totalDgoCons = z.roundPrecision(t.fo / 24 * h.totalHrs, 3), i += h.totalHrs, s += h.totalDgoCons;
1479
+ const k = await R.deadReckoningTime((u = h.waypoints) == null ? void 0 : u.at(0), e.sample.all || e.sample.wps), b = await R.deadReckoningTime((c = h.waypoints) == null ? void 0 : c.at(-1), e.sample.all || e.sample.wps);
1480
+ h.in = k, h.out = b, h.totalHrs = J.roundPrecision((b.positionTime - k.positionTime) / 3600, 3), h.totalDgoCons = J.roundPrecision(t.fo / 24 * h.totalHrs, 3), i += h.totalHrs, s += h.totalDgoCons;
1479
1481
  }
1480
- return n = z.roundPrecision(n, 3), i = z.roundPrecision(i, 3), s = z.roundPrecision(s, 3), {
1482
+ return n = J.roundPrecision(n, 3), i = J.roundPrecision(i, 3), s = J.roundPrecision(s, 3), {
1481
1483
  distanceInECA: n,
1482
1484
  hoursInECA: i,
1483
1485
  totalDgoConsInECA: s,
@@ -1494,49 +1496,55 @@ class Y {
1494
1496
  const a = {
1495
1497
  hours: [],
1496
1498
  wps: [],
1497
- days: []
1499
+ days: [],
1500
+ all: []
1498
1501
  }, o = e.reduce((m, y) => m + y.distance, 0), n = e.reduce((m, y) => {
1499
- var C;
1500
- return m + (((C = y.extend) == null ? void 0 : C.distanceInECA) || 0);
1502
+ var S;
1503
+ return m + (((S = y.extend) == null ? void 0 : S.distanceInECA) || 0);
1501
1504
  }, 0), i = e.reduce((m, y) => m + y.totalHrs, 0), s = e.reduce((m, y) => {
1502
- var C;
1503
- return m + (((C = y.extend) == null ? void 0 : C.hoursInECA) || 0);
1505
+ var S;
1506
+ return m + (((S = y.extend) == null ? void 0 : S.hoursInECA) || 0);
1504
1507
  }, 0), r = e.reduce((m, y) => {
1505
- var C;
1506
- return m + (((C = y.extend) == null ? void 0 : C.totalDgoConsInECA) || 0);
1507
- }, 0), l = e.reduce((m, y) => m + y.wxFactor * y.totalHrs / i, 0), u = e.reduce((m, y) => m + y.cFactor * y.totalHrs / i, 0), c = e.reduce((m, y) => m + y.totalFoCons, 0), h = e.reduce((m, y) => m + y.totalDgoCons, 0), k = e.reduce((m, y) => m + y.cost.total, 0), b = e.reduce((m, y) => m + y.cost.hire, 0), S = e.reduce((m, y) => m + y.cost.bunker, 0), I = [], p = [];
1508
+ var S;
1509
+ return m + (((S = y.extend) == null ? void 0 : S.totalDgoConsInECA) || 0);
1510
+ }, 0), l = e.reduce((m, y) => m + y.wxFactor * y.totalHrs / i, 0), u = e.reduce((m, y) => m + y.cFactor * y.totalHrs / i, 0), c = e.reduce((m, y) => m + y.totalFoCons, 0), h = e.reduce((m, y) => m + y.totalDgoCons, 0), k = e.reduce((m, y) => m + y.cost.total, 0), b = e.reduce((m, y) => m + y.cost.hire, 0), F = e.reduce((m, y) => m + y.cost.bunker, 0), I = [], p = [];
1508
1511
  let v;
1509
1512
  for (const m of e) {
1510
1513
  p.push(...((f = m.extend) == null ? void 0 : f.eca) || []);
1511
- const y = m.sample.hours, C = m.sample.wps, M = m.sample.days, j = y.at(0);
1512
- v && (j.distanceFromPrevious = v.distanceFromPrevious, j.distanceFromStart = v.distanceFromStart, y.forEach((F, N) => {
1513
- N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1514
- }), C.at(0).distanceFromPrevious = v.distanceFromPrevious, C.at(0).distanceFromStart = v.distanceFromStart, C.forEach((F, N) => {
1515
- N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1516
- }), M.at(0).distanceFromPrevious = v.distanceFromPrevious, M.at(0).distanceFromStart = v.distanceFromStart, M.forEach((F, N) => {
1517
- N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1518
- })), j.cp = m.cost.cp;
1519
- const P = [m.etd, m.eta], D = I.findIndex((F) => F.id === j.cp.id);
1520
- D === -1 ? (j.cp.segment = [P], I.push(j.cp)) : I[D].segment.push(P), y.forEach((F) => {
1521
- var R;
1522
- ((R = a.hours) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.hours.push(F);
1523
- }), C.forEach((F) => {
1524
- var R;
1525
- ((R = a.wps) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.wps.push(F);
1526
- }), M.forEach((F) => {
1527
- var R;
1528
- ((R = a == null ? void 0 : a.days) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.days.push(F);
1514
+ const y = m.sample.hours, S = m.sample.all, M = m.sample.wps, j = m.sample.days, N = y.at(0);
1515
+ v && (N.distanceFromPrevious = v.distanceFromPrevious, N.distanceFromStart = v.distanceFromStart, y.forEach((C, Y) => {
1516
+ Y && (C.distanceFromStart = C.distanceFromStart + v.distanceFromStart);
1517
+ }), S.at(0).distanceFromPrevious = v.distanceFromPrevious, S.at(0).distanceFromStart = v.distanceFromStart, S.forEach((C, Y) => {
1518
+ Y && (C.distanceFromStart = C.distanceFromStart + v.distanceFromStart);
1519
+ }), M.at(0).distanceFromPrevious = v.distanceFromPrevious, M.at(0).distanceFromStart = v.distanceFromStart, M.forEach((C, Y) => {
1520
+ Y && (C.distanceFromStart = C.distanceFromStart + v.distanceFromStart);
1521
+ }), j.at(0).distanceFromPrevious = v.distanceFromPrevious, j.at(0).distanceFromStart = v.distanceFromStart, j.forEach((C, Y) => {
1522
+ Y && (C.distanceFromStart = C.distanceFromStart + v.distanceFromStart);
1523
+ })), N.cp = m.cost.cp;
1524
+ const D = [m.etd, m.eta], L = I.findIndex((C) => C.id === N.cp.id);
1525
+ L === -1 ? (N.cp.segment = [D], I.push(N.cp)) : I[L].segment.push(D), y.forEach((C) => {
1526
+ var A;
1527
+ ((A = a.hours) == null ? void 0 : A.findIndex((V) => V.eta === C.eta)) === -1 && a.hours.push(C);
1528
+ }), S.forEach((C) => {
1529
+ var A;
1530
+ ((A = a.all) == null ? void 0 : A.findIndex((V) => V.eta === C.eta)) === -1 && a.all.push(C);
1531
+ }), M.forEach((C) => {
1532
+ var A;
1533
+ ((A = a.wps) == null ? void 0 : A.findIndex((V) => V.eta === C.eta)) === -1 && a.wps.push(C);
1534
+ }), j.forEach((C) => {
1535
+ var A;
1536
+ ((A = a == null ? void 0 : a.days) == null ? void 0 : A.findIndex((V) => V.eta === C.eta)) === -1 && a.days.push(C);
1529
1537
  });
1530
- const H = (d = a.wps) == null ? void 0 : d.findIndex((F) => F.eta === j.eta);
1531
- H === -1 ? a.wps.push(j) : a.wps[H] = j, v = y.at(-1);
1538
+ const W = (d = a.wps) == null ? void 0 : d.findIndex((C) => C.eta === N.eta);
1539
+ W === -1 ? a.wps.push(N) : a.wps[W] = N, v = y.at(-1);
1532
1540
  }
1533
1541
  return a.wps.sort((m, y) => w(m.etd).unix() - w(y.etd).unix()), a.wps.forEach((m, y) => {
1534
- const C = a.wps[y - 1];
1535
- if (C) {
1536
- const M = m.distanceFromStart - (C.distanceFromStart || 0), j = w(m.eta || m.etd).diff(w(C.etd || C.eta), "hour", !0), P = Math.round(M / j * 100) / 100;
1537
- m.avgSpd = P;
1538
- const D = O.calculateBearing(C, m);
1539
- C.bearing = D;
1542
+ const S = a.wps[y - 1];
1543
+ if (S) {
1544
+ const M = m.distanceFromStart - (S.distanceFromStart || 0), j = w(m.eta || m.etd).diff(w(S.etd || S.eta), "hour", !0), N = Math.round(M / j * 100) / 100;
1545
+ m.avgSpd = N;
1546
+ const D = R.calculateBearing(S, m);
1547
+ S.bearing = D;
1540
1548
  }
1541
1549
  }), {
1542
1550
  sample: a,
@@ -1556,7 +1564,7 @@ class Y {
1556
1564
  cost: {
1557
1565
  total: Math.round(k * 1e3) / 1e3,
1558
1566
  hire: Math.round(b * 1e3) / 1e3,
1559
- bunker: Math.round(S * 1e3) / 1e3
1567
+ bunker: Math.round(F * 1e3) / 1e3
1560
1568
  },
1561
1569
  extend: {
1562
1570
  cps: I,
@@ -1570,16 +1578,16 @@ class Y {
1570
1578
  }
1571
1579
  }
1572
1580
  export {
1573
- at as AISImpl,
1581
+ nt as AISImpl,
1574
1582
  Mt as AlertHelper,
1575
1583
  yt as AlertLevel,
1576
- Ft as HifleetImpl,
1577
- pt as LoadCondition,
1578
- xt as MyShipImpl,
1579
- jt as MyVesselImpl,
1580
- Nt as ShipxyImpl,
1581
- Y as SpeedHelper,
1582
- vt as SpeedLabel,
1584
+ jt as HifleetImpl,
1585
+ vt as LoadCondition,
1586
+ Nt as MyShipImpl,
1587
+ Tt as MyVesselImpl,
1588
+ xt as ShipxyImpl,
1589
+ H as SpeedHelper,
1590
+ pt as SpeedLabel,
1583
1591
  bt as VesselTag,
1584
1592
  Dt as alertHelper
1585
1593
  };
@@ -1 +1 @@
1
- (function(D,x){typeof exports=="object"&&typeof module<"u"?x(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"],x):(D=typeof globalThis<"u"?globalThis:D||self,x(D["idm-plugin-vessel"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,x,U,w,F,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(D,x,U)=>x in D?Ct(D,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):D[x]=U;var _=(D,x,U)=>(St(D,typeof x!="symbol"?x+"":x,U),U);let M;try{M=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){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 pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();M==null||M.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:w().utc().format()})}async checkToken(t={}){var a;return(!this.token||w().diff(w(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 s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return M==null||M.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 s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=w(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.dest,positionTime:u.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,S;const r=w();await this.checkToken(s);const l="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",u={maxDraught:s.draught||10,useAIModel:s.useAIModel??!0,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const c={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,c);const h=await x.post(l,c).json();if(h.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:h.message,status:h.status,code:h.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:v,tracks:m,specialRegions:d,ecaLength:f}=h.data;k.nodes=g==null?void 0:g.map(p=>({code:p.nodeCode,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.lat*1e6)/1e6,lng:Math.round(p.lon*1e6)/1e6},start:{lat:Math.round(p.startLat*1e6)/1e6,lng:Math.round(p.startLon*1e6)/1e6},end:{lat:Math.round(p.endLat*1e6)/1e6,lng:Math.round(p.endLat*1e6)/1e6},isKey:p.isKeyNode,isHub:p.isHubNode})),k.seas=v==null?void 0:v.map(p=>({code:p.mrgidSea,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.centerLat*1e6)/1e6,lng:Math.round(p.centerLon*1e6)/1e6},min:{lat:Math.round(p.minLat*1e6)/1e6,lng:Math.round(p.minLon*1e6)/1e6},max:{lat:Math.round(p.maxLat*1e6)/1e6,lng:Math.round(p.maxLon*1e6)/1e6},level:p.mapLevel})),d==null||d.map(p=>{p.regionLength&&k.regions.push({type:p.regionType,distance:p.regionLength,rows:p.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=m==null?void 0:m.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(S=k.waypoints)!=null&&S.length&&(k.waypoints=F.LaneHelper.simplifyCoordinates(k.waypoints),k.route=F.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=F.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=f);const C=w().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=w(a),u=w(o),c=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,c,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,c,s),c}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,S,k,g,v;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(S=this.token)==null?void 0:S.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const c=await x.post(l,u).json();if(c.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:c.message,status:c.status,code:c.code}),c;let h=-1;const I=w(`${(g=(k=c.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=c.data)==null||v.forEach(m=>{for(const P in m)!isNaN(m[P])&&Number(m[P])!==1/0&&(m[P]=Number(m[P]));const d=w(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),f=m.status,{labelCn:y,labelEn:C}=this.parseStatus(f),p={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:f,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta)?w(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:m.dest,positionTime:d.unix(),labelCn:y,labelEn:C,method:"trajectory",vendor:"myVessel",utc:d.utc().format()},L=Math.floor(d.diff(I,"minute",!0)/(i||1));L!==h&&(h=L,s.push(p))}),s}}class Mt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:u}=this.parseStatus(r),c=w(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:c.unix(),utc:c.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="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 i=await x.post(o,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="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"}},i=await x.post(o,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.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 s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var m,d,f;const r=await this.realTimePosition(t,s);let l=w(a);const u=w(o),c=w();if(i){let y=u.diff(l,"d",!0);y<0?l=u.clone().subtract(40,"d"):y<30?l.subtract(10,"d"):y<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),y=c.diff(u,"d",!0),u.add(y>10?240:y*24,"h")}const h={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,h).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,h);let S;b&&(S=((d=(m=b.ships)==null?void 0:m.offors)==null?void 0:d.ship)||[],S.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let g=-1;const v=w(`${(f=S==null?void 0:S[0])==null?void 0:f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of S){for(const R in y)!isNaN(y[R])&&Number(y[R])!==1/0&&(y[R]=Number(y[R]));const C=w(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(y.status),P={mmsi:y.m,name:y.n,imo:r==null?void 0:r.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:C.unix(),utc:C.utc().format(),status:y.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(v,"minute",!0)/(n||1));N!==g&&(g=N,k.push(P))}return k}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=w.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var v;const r=await this.realTimePosition(t,s),l=w(a),u=w(o),c="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(c,h).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,c,h),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,S=[],k=w.unix((v=b[0])==null?void 0:v.utc);let g=-1;for(const m of b){const d=w.unix(m.utc),f={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:d.unix(),utc:d.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(d.diff(k,"minute",!0)/(n||1));y!==g&&(g=y,S.push(f))}return S}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:c}=await this.parseStatus(l.aisNavStatus),h=w.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:h.utc().format(),status:l.aisNavStatus,labelEn:c,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=w(a),l=w(o),u=await this.getShipId(t),c=await this.getShipInfo(u),h=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),c,t,n,h);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),c,t,n,h),h}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},c="https://api3.myships.com/sp/ships/position/history",h=await x.post(c,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,c,u),h.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,h),h;const I=h.data;for(const g in I)!isNaN(I[g])&&Number(I[g])!==1/0&&(I[g]=Number(I[g]));const b=w.unix((k=I[0])==null?void 0:k.posTime);let S=-1;for(const g of I){const v=w.unix(g.posTime),m={imo:n==null?void 0:n.imo,mmsi:i,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},d=Math.floor(v.diff(b,"minute",!0)/(s||1));d!==S&&(S=d,r.push(m))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const c=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!c)i.scope=n[0];else if(c)for(let h=0,I=c.length;h<I;h++){const b=this.parseRule(c[h]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,S,k,g,v,m,d,f,y,C,p,L,P,N,R;let o=0,n=0,i=0,s=0;const r=Math.round(((S=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:S.number)*1.6*100)/100,l=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,u=(m=(v=t==null?void 0:t.HEAVY)==null?void 0:v.sigWave)==null?void 0:m.number,c=Math.round((((f=(d=t==null?void 0:t.SEVERE)==null?void 0:d.wind)==null?void 0:f.number)+2)*100)/100,h=(C=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let E=0;E<(e==null?void 0:e.length);E++){const H=e[E],V=(N=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=E?w(H.eta).diff(w(e[E-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=u&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I}),(B==null?void 0:B.scale)>=c?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>h?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===I&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),o+=H.isDangerous?K:0,n+=H.isSevere?K:0,i+=H.isHeavy?K:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const vt=new lt;let T;try{T=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ht||{}),ft=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(ft||{}),mt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(mt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const 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.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let 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.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=F.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:S,marineModels:k}=await ot.Meteo2Assist.autoPickMeteoModel(o),g=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:S,marineModels:k}),[v]=ot.Meteo2Assist.pickHourly(g,a);u=ot.Meteo2Assist.toLegacy(v)}catch(S){T.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},S)}let c=O.currentFactor(e.bearing,u==null?void 0:u.current,n),h=O.weatherFactor(e,u,c);const I=e.speed*1.943844;I+c+h<=0&&(T.warn("[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",r.requestId,I,h+c,h,c),c=Math.round(c*.6*1e3)/1e3,h=Math.round(h*.6*1e3)/1e3);let b=Math.round((I+c+h)*100)/100;b=b<=0?1:b,l={meteo:{...u},wxFactor:h,cFactor:c,speed:t.velocity&&s?t.velocity:b,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.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,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const c=t.clone().add(14,"days"),h=[],I=[],b=[];let S=0,k=0,g,v;for(let m=0;m<i.length-1;m++){let d=i[m];d.distanceFromStart=Math.round((n+k)*1e3)/1e3;const f=i[m+1];if(e.bearing=F.LaneHelper.calculateBearing(d,f,!f.gcToPrevious),d.bearing=e.bearing,d.suspend&&l){d.eta=d.eta||t.utc().format(),d.elapsed=d.elapsed??0;const p=d.suspend-d.elapsed;if(o-S>p)o=o-S-p,t.add(p,"hour"),d.elapsed=d.suspend;else{const L=o-S;d.elapsed+=L,t.add(L,"hour"),o=0}if(T==null||T.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`,u.requestId,d),o===0)return d.distanceFromPrevious=k,{etd:t,from:v||d,to:d,next:i.filter(L=>L),wps:h,days:I,all:b}}else d.suspend=0;r=t.isAfter(c)?!1:r,d=await O.speedLoseAt(e,d,t,s,0,r,l,u),b.push(d),v=v||d,d.important&&h.push(d),t.isSameOrAfter(a)&&(I.push(d),a.add(24,"hour"));const y=F.LaneHelper.calculateDistance(d,f,!f.gcToPrevious);let C=Math.round(y/v.speed*1e5)/1e5;if(S+C<o){if(S+=C,t.add(C,"hour"),delete i[m],T==null||T.debug(`[%s] go to %j from %j with ${y}nm, and cost ${C} hours`,u.requestId,{lat:f.lat,lng:f.lng},{lat:v.lat,lng:v.lng,etd:v.etd}),k+=y,i.filter(p=>p).length<=1){g=f,g.eta=t.utc().format(),g.distanceFromPrevious=y,g.distanceFromStart=Math.round((n+k)*1e4)/1e4,h.push(g),b.push(g),delete i[m+1];break}}else{C=o-S,t.add(C,"hour");const p=F.LngLatHelper.roundPrecision(v.speed*C,5);g=F.LaneHelper.calculateCoordinate(d,e.bearing,p,"nauticalmiles",!f.gcToPrevious),g.eta=t.utc().format(),i[m]=g,T==null||T.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.requestId,{lat:g.lat,lng:g.lng},{lat:d.lat,lng:d.lng,etd:d.etd}),k+=p,g.distanceFromPrevious=Math.round(k*1e4)/1e4,g.distanceFromStart=Math.round((n+k)*1e4)/1e4;break}}return{etd:t,from:v,to:g,next:i.filter(m=>m),wps:h,days:I,all:b}}static currentFactor(e,t,a=0){const o=F.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);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(e,t,a=0){var I,b,S,k,g,v,m;T==null||T.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=F.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=F.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(S=t==null?void 0:t.wind)==null?void 0:S.kts);let c=l*s*u/100*(e.speed-n);c=Math.round(c*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),T==null||T.debug("wind wx factor = %d",c),r=F.LaneHelper.includedAngle(e.bearing,(g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.degree);const h=O.waveHeightFactor(((m=(v=t==null?void 0:t.wave)==null?void 0:v.sig)==null?void 0:m.height)??1,r);return T==null||T.debug("wave wx factor = %d",h),c=Math.abs(c)>Math.abs(h)?c:c*.3+h*.7,T==null||T.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 reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=w.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(w(n.etd).unix()/t)===Math.floor(w(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const c=w().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:I}=n.points,b=F.LaneHelper.calculateSubRoute(e,h);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:S,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},g=O.assembleProperties(a,o.loadCondition,S,0),v=I.length?F.LaneHelper.calculateSubWaypoints(e,I):[];v.forEach(q=>q.important=!0);const m={from:{...e},route:b,waypoints:v,v0:S,label:k},d={hours:[],days:[],wps:[],all:[]};s||(F.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let f=F.LaneHelper.simplifyRouteToCoordinates(b,v,0),y=0,C=0,p=0,L=0;t=w(t).utc();const P=t.clone();for(;f.length>0;){const q=s-t.hour()%s,z=Math.ceil(t.clone().add(q,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,P,z,y,f,i,r,l,u);if(d.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(d.hours.push(j.from),d.wps.push(...j.wps),d.days.push(...j.days)),f=j==null?void 0:j.next,!f.length){const W=await O.speedLoseAt(g,j.to,w(j.to.eta),i,0,r,l,u);W.bearing=g.bearing,d.hours.push(W),d.all.push(W)}y+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=d.hours;for(let q=0;q<N.length-1;q++){const z=w(N[q+1].eta).diff(N[q].etd,"hour",!0)||1;C+=(N[q].wxFactor||0)*z,p+=(N[q].cFactor||0)*z,L+=z}const R=N.reduce((q,z)=>q+(z.suspend||0),0);($=d.wps)==null||$.forEach((q,z)=>{q.positionTime=w.utc(q.etd||q.eta).unix();const j=d.wps[z-1];if(j){const W=q.distanceFromStart-j.distanceFromStart,Y=w(q.eta||q.etd).diff(w(j.etd||j.eta),"h",!0);q.avgSpd=Math.round(W/Y*100)/100,j.bearing=F.LaneHelper.calculateBearing(j,q)}}),d.wps=await O.reduceWPS(d.wps),d.days=await O.reduceDays(d.days),d.all=(tt=d.all)==null?void 0:tt.reduce((q,z)=>(z.positionTime=w.utc(z.etd||z.eta).unix(),q.some(j=>Math.round(j.positionTime/60)===Math.round(z.positionTime/60))||q.push(z),q),[]),m.sample=d;const E=d.hours.at(0),H=d.hours.at(-1);m.distance=Math.round(H.distanceFromStart*1e3)/1e3,m.etd=w(E.eta).utc().format(),m.eta=w(H.eta).utc().format(),m.wxFactor=Math.round(C/L*1e3)/1e3,m.cFactor=Math.round(p/L*1e3)/1e3,m.avgSpeed=Math.round(H.distanceFromStart/L*1e3)/1e3,m.totalHrs=Math.round(L*1e3)/1e3,m.suspend=Math.round(R*1e3)/1e3;const V=F.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(m,o,u),at=F.LngLatHelper.roundPrecision(o.fo/24*(L-K),3),rt=F.LngLatHelper.roundPrecision(o.dgo/24*L+V,3);m.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},m.totalFoCons=at<0?0:at,m.totalDgoCons=rt;const nt=w().valueOf()-c,dt=((et=d==null?void 0:d.hours)==null?void 0:et.length)||1;return T==null||T.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),m}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,c=!1,h={}){var Z,$,tt,et,q,z;const I=w().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:S}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},k=O.assembleProperties(o,n.loadCondition,b,0),g=F.LaneHelper.calculateSubRoute(e,i);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const v=s.length?F.LaneHelper.calculateSubWaypoints(e,s):[];v.forEach(j=>j.important=!0);let m=F.LaneHelper.simplifyRouteToCoordinates(g,v,0),d=0,f=0,y=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=w(t).utc();const L=t.clone();for(;m.length>0;){const j=l-t.hour()%l;let W=Math.ceil(t.clone().add(j,"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 Y=await O.speedLoseInHoursStep(k,t,L,W,d,m,r,u,c,h);if(p.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(p.hours.push(Y.from),Y!=null&&Y.wps&&p.wps.push(...Y.wps),p.days.push(...Y.days)),m=Y==null?void 0:Y.next,m.length||p.hours.push(Y==null?void 0:Y.to),d+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!W)break}p.wps=await O.reduceWPS(p.wps),p.days=await O.reduceDays(p.days),p.all=(et=p.all)==null?void 0:et.reduce((j,W)=>(W.positionTime=w.utc(W.etd||W.eta).unix(),j.some(Y=>Math.round(w(Y.etd).unix()/60)===Math.round(w(W.etd).unix()/60))||j.push(W),j),[]),(q=p.wps)==null||q.forEach((j,W)=>{const Y=p.wps[W-1];if(Y){const It=j.distanceFromStart-Y.distanceFromStart,kt=w(j.eta||j.etd).diff(w(Y.etd||Y.eta),"h",!0);Y.bearing=F.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/kt*100)/100}});const P=p.hours;for(let j=0;j<P.length-1;j++){const W=w(P[j+1].eta).diff(P[j].etd,"hour",!0);f+=P[j].wxFactor*W,y+=P[j].cFactor*W,C+=W}const N=P.reduce((j,W)=>j+(W.suspend||0),0),R=p.hours.at(0),E=p.hours.at(-1),H=await F.LaneHelper.calculateRangeRoute(R,E,g),V=await F.LaneHelper.calculateRangeWaypoints(R,E,g,v),B={sample:p,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:w(R.eta).utc().format(),eta:w(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(f/C*1e3)/1e3,cFactor:Math.round(y/C*1e3)/1e3,avgSpeed:Math.round(((E==null?void 0:E.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:E,route:H,waypoints:V,v0:b,label:S},K=F.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,h),ct=F.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=F.LngLatHelper.roundPrecision(n.dgo/24*C+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=w().valueOf()-I,Q=((z=p==null?void 0:p.hours)==null?void 0:z.length)||1;return T==null||T.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,o,n={}){var g,v;const i=w().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=F.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(m=>{const d=Math.ceil(r/m.speed/24);l=l<d?d:l}),l=l*1.3;const u=w.utc(e.etd).add(l??14,"day");let c=1;for(const m of a){const d=JSON.parse(JSON.stringify(o.route)),f=JSON.parse(JSON.stringify(o.waypoints)),y=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,m,d,f,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);y&&(await O.calculateCost(y,m,e,n),s.push(y),T==null||T.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,c,e.etd,u.format(),{cost:y.cost.total,hire:y.cost.hire,bunker:y.cost.bunker,distance:y.distance,hours:y.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),c++}s.sort((m,d)=>m.cost.total-d.cost.total);const h=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[h],cost:(g=h.cost)==null?void 0:g.total}),I){const m=h.cost.cp,d=I.cost.cp,f=w(h.eta),y=w(h.etd),C=f.diff(y,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,P={combined:!1,speeds:[I],cost:(v=I.cost)==null?void 0:v.total},N;for(;p>=e.alterStep;){const R=await O.combinedAnalyse(e,t,u,[m,d],o,p,{...n,level:L});if(P.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=P,P=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(P),N&&b.push(N)}const k=w().valueOf()-i;return T==null||T.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),b.sort((m,d)=>m.cost-d.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,T==null||T.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((d,f)=>d+f.cost.total,0),u=r.reduce((d,f)=>d+f.cost.hire,0),c=r.reduce((d,f)=>d+f.cost.bunker,0),h=r.reduce((d,f)=>d+f.distance,0),I=r.reduce((d,f)=>d+f.totalHrs,0);T==null||T.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:c,distance:h,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),S=b.reduce((d,f)=>d+f.cost.total,0),k=b.reduce((d,f)=>d+f.cost.hire,0),g=b.reduce((d,f)=>d+f.cost.bunker,0),v=b.reduce((d,f)=>d+f.distance,0),m=b.reduce((d,f)=>d+f.totalHrs,0);return T==null||T.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:S,hire:k,bunker:g,distance:v,hours:m}),l<S?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(S*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var h,I;let l=w.utc(e.etd);const u={lat:e.lat,lng:e.lng},c=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),S=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),g=o[n],v=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,g,S,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);v&&(await O.calculateCost(v,g,e,r),T==null||T.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:v.cost.total,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const m=(I=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:I.at(-1);if(m)u.lat=m.lat,u.lng=m.lng,l=w(m.eta),c.push(v),n=n?0:1;else break}return c}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,c;const o=await F.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(h=>{h.positionTime=w.utc(h.etd||h.eta).unix()});for(const h of o){n+=h.distance;const I=await F.LaneHelper.deadReckoningTime((u=h.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await F.LaneHelper.deadReckoningTime((c=h.waypoints)==null?void 0:c.at(-1),e.sample.all||e.sample.wps);h.in=I,h.out=b,h.totalHrs=F.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),h.totalDgoCons=F.LngLatHelper.roundPrecision(t.fo/24*h.totalHrs,3),i+=h.totalHrs,s+=h.totalDgoCons}return n=F.LngLatHelper.roundPrecision(n,3),i=F.LngLatHelper.roundPrecision(i,3),s=F.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var m,d;const a={hours:[],wps:[],days:[]},o=e.reduce((f,y)=>f+y.distance,0),n=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((f,y)=>f+y.totalHrs,0),s=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((f,y)=>f+y.wxFactor*y.totalHrs/i,0),u=e.reduce((f,y)=>f+y.cFactor*y.totalHrs/i,0),c=e.reduce((f,y)=>f+y.totalFoCons,0),h=e.reduce((f,y)=>f+y.totalDgoCons,0),I=e.reduce((f,y)=>f+y.cost.total,0),b=e.reduce((f,y)=>f+y.cost.hire,0),S=e.reduce((f,y)=>f+y.cost.bunker,0),k=[],g=[];let v;for(const f of e){g.push(...((m=f.extend)==null?void 0:m.eca)||[]);const y=f.sample.hours,C=f.sample.wps,p=f.sample.days,L=y.at(0);v&&(L.distanceFromPrevious=v.distanceFromPrevious,L.distanceFromStart=v.distanceFromStart,y.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)}),C.at(0).distanceFromPrevious=v.distanceFromPrevious,C.at(0).distanceFromStart=v.distanceFromStart,C.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)}),p.at(0).distanceFromPrevious=v.distanceFromPrevious,p.at(0).distanceFromStart=v.distanceFromStart,p.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)})),L.cp=f.cost.cp;const P=[f.etd,f.eta],N=k.findIndex(E=>E.id===L.cp.id);N===-1?(L.cp.segment=[P],k.push(L.cp)):k[N].segment.push(P),y.forEach(E=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.hours.push(E)}),C.forEach(E=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.wps.push(E)}),p.forEach(E=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.days.push(E)});const R=(d=a.wps)==null?void 0:d.findIndex(E=>E.eta===L.eta);R===-1?a.wps.push(L):a.wps[R]=L,v=y.at(-1)}return a.wps.sort((f,y)=>w(f.etd).unix()-w(y.etd).unix()),a.wps.forEach((f,y)=>{const C=a.wps[y-1];if(C){const p=f.distanceFromStart-(C.distanceFromStart||0),L=w(f.eta||f.etd).diff(w(C.etd||C.eta),"hour",!0),P=Math.round(p/L*100)/100;f.avgSpd=P;const N=F.LaneHelper.calculateBearing(C,f);C.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(S*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}D.AISImpl=G,D.AlertHelper=lt,D.AlertLevel=ut,D.HifleetImpl=Mt,D.LoadCondition=ft,D.MyShipImpl=gt,D.MyVesselImpl=pt,D.ShipxyImpl=bt,D.SpeedHelper=O,D.SpeedLabel=mt,D.VesselTag=ht,D.alertHelper=vt,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
1
+ (function(q,x){typeof exports=="object"&&typeof module<"u"?x(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"],x):(q=typeof globalThis<"u"?globalThis:q||self,x(q["idm-plugin-vessel"]={},q.got,q["@log4js-node/log4js-api"],q.moment,q["@idm-plugin/geo2"],q["@idm-plugin/meteo2"],q["@idm-plugin/meteo"]))})(this,function(q,x,U,w,E,pt,it){"use strict";var St=Object.defineProperty;var Ct=(q,x,U)=>x in q?St(q,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):q[x]=U;var _=(q,x,U)=>(Ct(q,typeof x!="symbol"?x+"":x,U),U);let M;try{M=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){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();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();M==null||M.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:w().utc().format()})}async checkToken(t={}){var a;return(!this.token||w().diff(w(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 s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return M==null||M.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 s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=w(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.dest,positionTime:u.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,T;const r=w();await this.checkToken(s);const l="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",u={maxDraught:s.draught||10,useAIModel:s.useAIModel??!0,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const c={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,c);const h=await x.post(l,c).json();if(h.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:h.message,status:h.status,code:h.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:v,seas:g,tracks:m,specialRegions:d,ecaLength:f}=h.data;k.nodes=v==null?void 0:v.map(p=>({code:p.nodeCode,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.lat*1e6)/1e6,lng:Math.round(p.lon*1e6)/1e6},start:{lat:Math.round(p.startLat*1e6)/1e6,lng:Math.round(p.startLon*1e6)/1e6},end:{lat:Math.round(p.endLat*1e6)/1e6,lng:Math.round(p.endLat*1e6)/1e6},isKey:p.isKeyNode,isHub:p.isHubNode})),k.seas=g==null?void 0:g.map(p=>({code:p.mrgidSea,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.centerLat*1e6)/1e6,lng:Math.round(p.centerLon*1e6)/1e6},min:{lat:Math.round(p.minLat*1e6)/1e6,lng:Math.round(p.minLon*1e6)/1e6},max:{lat:Math.round(p.maxLat*1e6)/1e6,lng:Math.round(p.maxLon*1e6)/1e6},level:p.mapLevel})),d==null||d.map(p=>{p.regionLength&&k.regions.push({type:p.regionType,distance:p.regionLength,rows:p.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=m==null?void 0:m.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(T=k.waypoints)!=null&&T.length&&(k.waypoints=E.LaneHelper.simplifyCoordinates(k.waypoints),k.route=E.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=E.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=f);const C=w().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=w(a),u=w(o),c=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,c,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,c,s),c}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,T,k,v,g;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(T=this.token)==null?void 0:T.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const c=await x.post(l,u).json();if(c.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:c.message,status:c.status,code:c.code}),c;let h=-1;const I=w(`${(v=(k=c.data)==null?void 0:k[0])==null?void 0:v.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=c.data)==null||g.forEach(m=>{for(const H in m)!isNaN(m[H])&&Number(m[H])!==1/0&&(m[H]=Number(m[H]));const d=w(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),f=m.status,{labelCn:y,labelEn:C}=this.parseStatus(f),p={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:f,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta)?w(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:m.dest,positionTime:d.unix(),labelCn:y,labelEn:C,method:"trajectory",vendor:"myVessel",utc:d.utc().format()},L=Math.floor(d.diff(I,"minute",!0)/(i||1));L!==h&&(h=L,s.push(p))}),s}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:u}=this.parseStatus(r),c=w(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:c.unix(),utc:c.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="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 i=await x.post(o,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="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"}},i=await x.post(o,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.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 s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var m,d,f;const r=await this.realTimePosition(t,s);let l=w(a);const u=w(o),c=w();if(i){let y=u.diff(l,"d",!0);y<0?l=u.clone().subtract(40,"d"):y<30?l.subtract(10,"d"):y<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),y=c.diff(u,"d",!0),u.add(y>10?240:y*24,"h")}const h={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,h).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,h);let T;b&&(T=((d=(m=b.ships)==null?void 0:m.offors)==null?void 0:d.ship)||[],T.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let v=-1;const g=w(`${(f=T==null?void 0:T[0])==null?void 0:f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of T){for(const W in y)!isNaN(y[W])&&Number(y[W])!==1/0&&(y[W]=Number(y[W]));const C=w(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(y.status),H={mmsi:y.m,name:y.n,imo:r==null?void 0:r.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:C.unix(),utc:C.utc().format(),status:y.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(g,"minute",!0)/(n||1));N!==v&&(v=N,k.push(H))}return k}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=w.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var g;const r=await this.realTimePosition(t,s),l=w(a),u=w(o),c="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(c,h).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,c,h),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,T=[],k=w.unix((g=b[0])==null?void 0:g.utc);let v=-1;for(const m of b){const d=w.unix(m.utc),f={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:d.unix(),utc:d.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(d.diff(k,"minute",!0)/(n||1));y!==v&&(v=y,T.push(f))}return T}}class vt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:c}=await this.parseStatus(l.aisNavStatus),h=w.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:h.utc().format(),status:l.aisNavStatus,labelEn:c,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=w(a),l=w(o),u=await this.getShipId(t),c=await this.getShipInfo(u),h=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),c,t,n,h);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),c,t,n,h),h}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},c="https://api3.myships.com/sp/ships/position/history",h=await x.post(c,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,c,u),h.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,h),h;const I=h.data;for(const v in I)!isNaN(I[v])&&Number(I[v])!==1/0&&(I[v]=Number(I[v]));const b=w.unix((k=I[0])==null?void 0:k.posTime);let T=-1;for(const v of I){const g=w.unix(v.posTime),m={imo:n==null?void 0:n.imo,mmsi:i,lat:Math.round(v.lat/1e4/60*1e5)/1e5,lng:Math.round(v.lon/1e4/60*1e5)/1e5,sog:Math.round(v.sog/10*100)/100,cog:Math.round(v.cog/10*100)/100,hdg:Math.round(v.heading*100)/100,rot:Math.round(v.rot*100)/100,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"myship"},d=Math.floor(g.diff(b,"minute",!0)/(s||1));d!==T&&(T=d,r.push(m))}return r}}let K;try{K=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(e,t={}){var s,r,l;K==null||K.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const c=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!c)i.scope=n[0];else if(c)for(let h=0,I=c.length;h<I;h++){const b=this.parseRule(c[h]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;K==null||K.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,T,k,v,g,m,d,f,y,C,p,L,H,N,W;let o=0,n=0,i=0,s=0;const r=Math.round(((T=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:T.number)*1.6*100)/100,l=(v=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:v.number,u=(m=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:m.number,c=Math.round((((f=(d=t==null?void 0:t.SEVERE)==null?void 0:d.wind)==null?void 0:f.number)+2)*100)/100,h=(C=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let B=0;B<(e==null?void 0:e.length);B++){const S=e[B],R=(N=(H=S==null?void 0:S.meteo)==null?void 0:H.wave)==null?void 0:N.sig,D=(W=S==null?void 0:S.meteo)==null?void 0:W.wind,z=B?w(S.eta).diff(w(e[B-1].eta),"hour",!0):0;s=z>s?z:s,K==null||K.debug("[%s] check sig.wave: %j",a.requestId,{...R,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(R==null?void 0:R.height)>=r?S.isDangerous=!0:(R==null?void 0:R.height)>=l?S.isSevere=!0:(R==null?void 0:R.height)>=u&&(S.isHeavy=!0),K==null||K.debug("[%s] check wind: %j",a.requestId,{...D,dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I}),(D==null?void 0:D.scale)>=c?(S.isDangerous=!0,delete S.isSevere,delete S.isHeavy):(D==null?void 0:D.scale)>h?(S.isDangerous||(S.isSevere=!0),delete S.isHeavy):(D==null?void 0:D.scale)===I&&!S.isDangerous&&!S.isSevere&&(S.isHeavy=!0),o+=S.isDangerous?z:0,n+=S.isSevere?z:0,i+=S.isHeavy?z:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const wt=new ht;let F;try{F=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 O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const 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.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let 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.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:T,marineModels:k}=await it.Meteo2Assist.autoPickMeteoModel(o),v=await It.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:T,marineModels:k}),[g]=it.Meteo2Assist.pickHourly(v,a);u=it.Meteo2Assist.toLegacy(g)}catch(T){F.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},T)}let c=O.currentFactor(e.bearing,u==null?void 0:u.current,n),h=O.weatherFactor(e,u,c);const I=e.speed*1.943844;I+c+h<=0&&(F.warn("[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",r.requestId,I,h+c,h,c),c=Math.round(c*.6*1e3)/1e3,h=Math.round(h*.6*1e3)/1e3);let b=Math.round((I+c+h)*100)/100;b=b<=0?1:b,l={meteo:{...u},wxFactor:h,cFactor:c,speed:t.velocity&&s?t.velocity:b,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.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,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const c=t.clone().add(14,"days"),h=[],I=[],b=[];let T=0,k=0,v,g;for(let m=0;m<i.length-1;m++){let d=i[m];d.distanceFromStart=Math.round((n+k)*1e3)/1e3;const f=i[m+1];if(e.bearing=E.LaneHelper.calculateBearing(d,f,!f.gcToPrevious),d.bearing=e.bearing,d.suspend&&l){d.eta=d.eta||t.utc().format(),d.elapsed=d.elapsed??0;const p=d.suspend-d.elapsed;if(o-T>p)o=o-T-p,t.add(p,"hour"),d.elapsed=d.suspend;else{const L=o-T;d.elapsed+=L,t.add(L,"hour"),o=0}if(F==null||F.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`,u.requestId,d),o===0)return d.distanceFromPrevious=k,{etd:t,from:g||d,to:d,next:i.filter(L=>L),wps:h,days:I,all:b}}else d.suspend=0;r=t.isAfter(c)?!1:r,d=await O.speedLoseAt(e,d,t,s,0,r,l,u),b.push(d),g=g||d,d.important&&h.push(d),t.isSameOrAfter(a)&&(I.push(d),a.add(24,"hour"));const y=E.LaneHelper.calculateDistance(d,f,!f.gcToPrevious);let C=Math.round(y/g.speed*1e5)/1e5;if(T+C<o){if(T+=C,t.add(C,"hour"),delete i[m],F==null||F.debug(`[%s] go to %j from %j with ${y}nm, and cost ${C} hours`,u.requestId,{lat:f.lat,lng:f.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),k+=y,i.filter(p=>p).length<=1){v=f,v.eta=t.utc().format(),v.distanceFromPrevious=y,v.distanceFromStart=Math.round((n+k)*1e4)/1e4,h.push(v),b.push(v),delete i[m+1];break}}else{C=o-T,t.add(C,"hour");const p=E.LngLatHelper.roundPrecision(g.speed*C,5);v=E.LaneHelper.calculateCoordinate(d,e.bearing,p,"nauticalmiles",!f.gcToPrevious),v.eta=t.utc().format(),i[m]=v,F==null||F.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.requestId,{lat:v.lat,lng:v.lng},{lat:d.lat,lng:d.lng,etd:d.etd}),k+=p,v.distanceFromPrevious=Math.round(k*1e4)/1e4,v.distanceFromStart=Math.round((n+k)*1e4)/1e4;break}}return{etd:t,from:g,to:v,next:i.filter(m=>m),wps:h,days:I,all:b}}static currentFactor(e,t,a=0){const o=E.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);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(e,t,a=0){var I,b,T,k,v,g,m;F==null||F.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=E.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=E.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(T=t==null?void 0:t.wind)==null?void 0:T.kts);let c=l*s*u/100*(e.speed-n);c=Math.round(c*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),F==null||F.debug("wind wx factor = %d",c),r=E.LaneHelper.includedAngle(e.bearing,(v=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:v.degree);const h=O.waveHeightFactor(((m=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:m.height)??1,r);return F==null||F.debug("wave wx factor = %d",h),c=Math.abs(c)>Math.abs(h)?c:c*.3+h*.7,F==null||F.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 reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=w.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(w(n.etd).unix()/t)===Math.floor(w(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const c=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:I}=n.points,b=E.LaneHelper.calculateSubRoute(e,h);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:T,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},v=O.assembleProperties(a,o.loadCondition,T,0),g=I.length?E.LaneHelper.calculateSubWaypoints(e,I):[];g.forEach(P=>P.important=!0);const m={from:{...e},route:b,waypoints:g,v0:T,label:k},d={hours:[],days:[],wps:[],all:[]};s||(E.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let f=E.LaneHelper.simplifyRouteToCoordinates(b,g,0),y=0,C=0,p=0,L=0;t=w(t).utc();const H=t.clone();for(;f.length>0;){const P=s-t.hour()%s,J=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(v,t,H,J,y,f,i,r,l,u);if(d.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(d.hours.push(j.from),d.wps.push(...j.wps),d.days.push(...j.days)),f=j==null?void 0:j.next,!f.length){const V=await O.speedLoseAt(v,j.to,w(j.to.eta),i,0,r,l,u);V.bearing=v.bearing,d.hours.push(V),d.all.push(V)}y+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=d.hours;for(let P=0;P<N.length-1;P++){const J=w(N[P+1].eta).diff(N[P].etd,"hour",!0)||1;C+=(N[P].wxFactor||0)*J,p+=(N[P].cFactor||0)*J,L+=J}const W=N.reduce((P,J)=>P+(J.suspend||0),0);($=d.wps)==null||$.forEach((P,J)=>{P.positionTime=w.utc(P.etd||P.eta).unix();const j=d.wps[J-1];if(j){const V=P.distanceFromStart-j.distanceFromStart,Y=w(P.eta||P.etd).diff(w(j.etd||j.eta),"h",!0);P.avgSpd=Math.round(V/Y*100)/100;const ot=E.LaneHelper.calculateBearing(j,P);P.avgBearing=ot,j.bearing=ot}}),d.wps=await O.reduceWPS(d.wps),d.days=await O.reduceDays(d.days),d.all=(tt=d.all)==null?void 0:tt.reduce((P,J)=>(J.positionTime=w.utc(J.etd||J.eta).unix(),P.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||P.push(J),P),[]),m.sample=d;const B=d.hours.at(0),S=d.hours.at(-1);m.distance=Math.round(S.distanceFromStart*1e3)/1e3,m.etd=w(B.eta).utc().format(),m.eta=w(S.eta).utc().format(),m.wxFactor=Math.round(C/L*1e3)/1e3,m.cFactor=Math.round(p/L*1e3)/1e3,m.avgSpeed=Math.round(S.distanceFromStart/L*1e3)/1e3,m.totalHrs=Math.round(L*1e3)/1e3,m.suspend=Math.round(W*1e3)/1e3;const R=E.LngLatHelper.roundPrecision(o.dgo/24*W,3),{distanceInECA:D,hoursInECA:z,totalDgoConsInECA:rt,eca:st}=await this.calculateECA(m,o,u),at=E.LngLatHelper.roundPrecision(o.fo/24*(L-z),3),ct=E.LngLatHelper.roundPrecision(o.dgo/24*L+R,3);m.extend={eca:st,distanceInECA:D,hoursInECA:z,totalDgoConsInECA:rt,totalDgoConsInSuspend:R},m.totalFoCons=at<0?0:at,m.totalDgoCons=ct;const nt=w().valueOf()-c,ut=((et=d==null?void 0:d.hours)==null?void 0:et.length)||1;return F==null||F.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,ut,Math.round(nt/ut*1e3)/1e3),m}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,c=!1,h={}){var Z,$,tt,et,P,J;const I=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},k=O.assembleProperties(o,n.loadCondition,b,0),v=E.LaneHelper.calculateSubRoute(e,i);if(((Z=v[0])==null?void 0:Z.length)<=1)return;const g=s.length?E.LaneHelper.calculateSubWaypoints(e,s):[];g.forEach(j=>j.important=!0);let m=E.LaneHelper.simplifyRouteToCoordinates(v,g,0),d=0,f=0,y=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=w(t).utc();const L=t.clone();for(;m.length>0;){const j=l-t.hour()%l;let V=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;V=t.clone().add(V,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:V;const Y=await O.speedLoseInHoursStep(k,t,L,V,d,m,r,u,c,h);if(p.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(p.hours.push(Y.from),Y!=null&&Y.wps&&p.wps.push(...Y.wps),p.days.push(...Y.days)),m=Y==null?void 0:Y.next,m.length||p.hours.push(Y==null?void 0:Y.to),d+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!V)break}p.wps=await O.reduceWPS(p.wps),p.days=await O.reduceDays(p.days),p.all=(et=p.all)==null?void 0:et.reduce((j,V)=>(V.positionTime=w.utc(V.etd||V.eta).unix(),j.some(Y=>Math.round(w(Y.etd).unix()/60)===Math.round(w(V.etd).unix()/60))||j.push(V),j),[]),(P=p.wps)==null||P.forEach((j,V)=>{const Y=p.wps[V-1];if(Y){const ot=j.distanceFromStart-Y.distanceFromStart,kt=w(j.eta||j.etd).diff(w(Y.etd||Y.eta),"h",!0);Y.bearing=E.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(ot/kt*100)/100}});const H=p.hours;for(let j=0;j<H.length-1;j++){const V=w(H[j+1].eta).diff(H[j].etd,"hour",!0);f+=H[j].wxFactor*V,y+=H[j].cFactor*V,C+=V}const N=H.reduce((j,V)=>j+(V.suspend||0),0),W=p.hours.at(0),B=p.hours.at(-1),S=await E.LaneHelper.calculateRangeRoute(W,B,v),R=await E.LaneHelper.calculateRangeWaypoints(W,B,v,g),D={sample:p,distance:Math.round(((B==null?void 0:B.distanceFromStart)||0)*1e4)/1e4,etd:w(W.eta).utc().format(),eta:w(B==null?void 0:B.eta).utc().format(),wxFactor:Math.round(f/C*1e3)/1e3,cFactor:Math.round(y/C*1e3)/1e3,avgSpeed:Math.round(((B==null?void 0:B.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:W,to:B,route:S,waypoints:R,v0:b,label:T},z=E.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:rt,hoursInECA:st,totalDgoConsInECA:at,eca:ct}=await this.calculateECA(D,n,h),dt=E.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=E.LngLatHelper.roundPrecision(n.dgo/24*C+z,3);D.extend={eca:ct,distanceInECA:rt,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:z},D.totalDgoCons=nt,D.totalFoCons=dt<0?0:dt;const X=w().valueOf()-I,Q=((J=p==null?void 0:p.hours)==null?void 0:J.length)||1;return F==null||F.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,X,Q,Math.round(X/Q*1e3)/1e3),D}static async analyseCost(e,t,a,o,n={}){var v,g;const i=w().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=E.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(m=>{const d=Math.ceil(r/m.speed/24);l=l<d?d:l}),l=l*1.3;const u=w.utc(e.etd).add(l??14,"day");let c=1;for(const m of a){const d=JSON.parse(JSON.stringify(o.route)),f=JSON.parse(JSON.stringify(o.waypoints)),y=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,m,d,f,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);y&&(await O.calculateCost(y,m,e,n),s.push(y),F==null||F.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,c,e.etd,u.format(),{cost:y.cost.total,hire:y.cost.hire,bunker:y.cost.bunker,distance:y.distance,hours:y.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),c++}s.sort((m,d)=>m.cost.total-d.cost.total);const h=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[h],cost:(v=h.cost)==null?void 0:v.total}),I){const m=h.cost.cp,d=I.cost.cp,f=w(h.eta),y=w(h.etd),C=f.diff(y,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,H={combined:!1,speeds:[I],cost:(g=I.cost)==null?void 0:g.total},N;for(;p>=e.alterStep;){const W=await O.combinedAnalyse(e,t,u,[m,d],o,p,{...n,level:L});if(H.cost>W.cost?N?(N==null?void 0:N.cost)>W.cost&&(N=W):(N=H,H=W):(!N||(N==null?void 0:N.cost)>W.cost)&&(N=W),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(H),N&&b.push(N)}const k=w().valueOf()-i;return F==null||F.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),b.sort((m,d)=>m.cost-d.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,F==null||F.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((d,f)=>d+f.cost.total,0),u=r.reduce((d,f)=>d+f.cost.hire,0),c=r.reduce((d,f)=>d+f.cost.bunker,0),h=r.reduce((d,f)=>d+f.distance,0),I=r.reduce((d,f)=>d+f.totalHrs,0);F==null||F.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:c,distance:h,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),T=b.reduce((d,f)=>d+f.cost.total,0),k=b.reduce((d,f)=>d+f.cost.hire,0),v=b.reduce((d,f)=>d+f.cost.bunker,0),g=b.reduce((d,f)=>d+f.distance,0),m=b.reduce((d,f)=>d+f.totalHrs,0);return F==null||F.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:T,hire:k,bunker:v,distance:g,hours:m}),l<T?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(T*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var h,I;let l=w.utc(e.etd);const u={lat:e.lat,lng:e.lng},c=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),T=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),v=o[n],g=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,v,T,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);g&&(await O.calculateCost(g,v,e,r),F==null||F.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:g.cost.total,hire:g.cost.hire,bunker:g.cost.bunker,distance:g.distance,hours:g.totalHrs,cp:`${v.speed}/${v.fo}/${v.dgo}`})),r.counter=r.counter+1;const m=(I=(h=g==null?void 0:g.sample)==null?void 0:h.hours)==null?void 0:I.at(-1);if(m)u.lat=m.lat,u.lng=m.lng,l=w(m.eta),c.push(g),n=n?0:1;else break}return c}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,c;const o=await E.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(h=>{h.positionTime=w.utc(h.etd||h.eta).unix()});for(const h of o){n+=h.distance;const I=await E.LaneHelper.deadReckoningTime((u=h.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await E.LaneHelper.deadReckoningTime((c=h.waypoints)==null?void 0:c.at(-1),e.sample.all||e.sample.wps);h.in=I,h.out=b,h.totalHrs=E.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),h.totalDgoCons=E.LngLatHelper.roundPrecision(t.fo/24*h.totalHrs,3),i+=h.totalHrs,s+=h.totalDgoCons}return n=E.LngLatHelper.roundPrecision(n,3),i=E.LngLatHelper.roundPrecision(i,3),s=E.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var m,d;const a={hours:[],wps:[],days:[],all:[]},o=e.reduce((f,y)=>f+y.distance,0),n=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((f,y)=>f+y.totalHrs,0),s=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((f,y)=>f+y.wxFactor*y.totalHrs/i,0),u=e.reduce((f,y)=>f+y.cFactor*y.totalHrs/i,0),c=e.reduce((f,y)=>f+y.totalFoCons,0),h=e.reduce((f,y)=>f+y.totalDgoCons,0),I=e.reduce((f,y)=>f+y.cost.total,0),b=e.reduce((f,y)=>f+y.cost.hire,0),T=e.reduce((f,y)=>f+y.cost.bunker,0),k=[],v=[];let g;for(const f of e){v.push(...((m=f.extend)==null?void 0:m.eca)||[]);const y=f.sample.hours,C=f.sample.all,p=f.sample.wps,L=f.sample.days,H=y.at(0);g&&(H.distanceFromPrevious=g.distanceFromPrevious,H.distanceFromStart=g.distanceFromStart,y.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),C.at(0).distanceFromPrevious=g.distanceFromPrevious,C.at(0).distanceFromStart=g.distanceFromStart,C.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),p.at(0).distanceFromPrevious=g.distanceFromPrevious,p.at(0).distanceFromStart=g.distanceFromStart,p.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),L.at(0).distanceFromPrevious=g.distanceFromPrevious,L.at(0).distanceFromStart=g.distanceFromStart,L.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)})),H.cp=f.cost.cp;const N=[f.etd,f.eta],W=k.findIndex(S=>S.id===H.cp.id);W===-1?(H.cp.segment=[N],k.push(H.cp)):k[W].segment.push(N),y.forEach(S=>{var D;((D=a.hours)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.hours.push(S)}),C.forEach(S=>{var D;((D=a.all)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.all.push(S)}),p.forEach(S=>{var D;((D=a.wps)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.wps.push(S)}),L.forEach(S=>{var D;((D=a==null?void 0:a.days)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.days.push(S)});const B=(d=a.wps)==null?void 0:d.findIndex(S=>S.eta===H.eta);B===-1?a.wps.push(H):a.wps[B]=H,g=y.at(-1)}return a.wps.sort((f,y)=>w(f.etd).unix()-w(y.etd).unix()),a.wps.forEach((f,y)=>{const C=a.wps[y-1];if(C){const p=f.distanceFromStart-(C.distanceFromStart||0),L=w(f.eta||f.etd).diff(w(C.etd||C.eta),"hour",!0),H=Math.round(p/L*100)/100;f.avgSpd=H;const N=E.LaneHelper.calculateBearing(C,f);C.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(T*1e3)/1e3},extend:{cps:k,eca:v,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}q.AISImpl=G,q.AlertHelper=ht,q.AlertLevel=lt,q.HifleetImpl=bt,q.LoadCondition=mt,q.MyShipImpl=vt,q.MyVesselImpl=Mt,q.ShipxyImpl=gt,q.SpeedHelper=O,q.SpeedLabel=yt,q.VesselTag=ft,q.alertHelper=wt,Object.defineProperty(q,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.6.1",
4
+ "version": "3.6.3",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [