@idm-plugin/vessel 3.6.2 → 3.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +118 -116
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,18 +2,18 @@ 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
4
|
import z from "got";
|
|
5
|
-
import
|
|
5
|
+
import ut from "@log4js-node/log4js-api";
|
|
6
6
|
import w from "moment";
|
|
7
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
|
|
9
|
+
import { Meteo2Assist as dt } from "@idm-plugin/meteo";
|
|
10
10
|
let g;
|
|
11
11
|
try {
|
|
12
|
-
g =
|
|
12
|
+
g = ut.getLogger("vessel");
|
|
13
13
|
} catch {
|
|
14
14
|
} finally {
|
|
15
15
|
}
|
|
16
|
-
class
|
|
16
|
+
class nt {
|
|
17
17
|
/**
|
|
18
18
|
* 解析AIS状态码
|
|
19
19
|
* @param status
|
|
@@ -54,7 +54,7 @@ class at {
|
|
|
54
54
|
return { labelCn: t, labelEn: a };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class Tt extends
|
|
57
|
+
class Tt extends nt {
|
|
58
58
|
constructor(t, a) {
|
|
59
59
|
super();
|
|
60
60
|
U(this, "clientId");
|
|
@@ -273,8 +273,8 @@ class Tt extends at {
|
|
|
273
273
|
route: [],
|
|
274
274
|
distance: 0,
|
|
275
275
|
memo: ""
|
|
276
|
-
}, { nodes:
|
|
277
|
-
I.nodes =
|
|
276
|
+
}, { nodes: p, seas: v, tracks: f, specialRegions: d, ecaLength: m } = h.data;
|
|
277
|
+
I.nodes = p == null ? void 0 : p.map((M) => ({
|
|
278
278
|
code: M.nodeCode,
|
|
279
279
|
nameEn: M.nameEn,
|
|
280
280
|
nameCn: M.nameCn,
|
|
@@ -297,7 +297,7 @@ class Tt extends at {
|
|
|
297
297
|
isKey: M.isKeyNode,
|
|
298
298
|
// 重要枢纽节点
|
|
299
299
|
isHub: M.isHubNode
|
|
300
|
-
})), I.seas =
|
|
300
|
+
})), I.seas = v == null ? void 0 : v.map((M) => ({
|
|
301
301
|
code: M.mrgidSea,
|
|
302
302
|
nameEn: M.nameEn,
|
|
303
303
|
nameCn: M.nameCn,
|
|
@@ -342,7 +342,7 @@ class Tt 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, F, I,
|
|
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
348
|
Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(F = this.token) == null ? void 0 : F.accessToken}`
|
|
@@ -358,8 +358,8 @@ class Tt extends at {
|
|
|
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
|
-
const k = w(`${(
|
|
362
|
-
return (
|
|
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
|
+
return (v = c.data) == null || v.forEach((f) => {
|
|
363
363
|
for (const N in f)
|
|
364
364
|
!isNaN(f[N]) && Number(f[N]) !== 1 / 0 && (f[N] = Number(f[N]));
|
|
365
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 = {
|
|
@@ -385,7 +385,7 @@ class Tt extends at {
|
|
|
385
385
|
}), s;
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
|
-
class jt extends
|
|
388
|
+
class jt extends nt {
|
|
389
389
|
constructor(t) {
|
|
390
390
|
super();
|
|
391
391
|
U(this, "token");
|
|
@@ -507,8 +507,8 @@ class jt extends at {
|
|
|
507
507
|
let F;
|
|
508
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
|
-
let
|
|
511
|
-
const
|
|
510
|
+
let p = -1;
|
|
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
512
|
for (const y of F) {
|
|
513
513
|
for (const L in y)
|
|
514
514
|
!isNaN(y[L]) && Number(y[L]) !== 1 / 0 && (y[L] = Number(y[L]));
|
|
@@ -531,13 +531,13 @@ class jt extends at {
|
|
|
531
531
|
labelEn: M,
|
|
532
532
|
method: "trajectory",
|
|
533
533
|
vendor: "hifleet"
|
|
534
|
-
}, D = Math.floor(S.diff(
|
|
535
|
-
D !==
|
|
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 xt extends
|
|
540
|
+
class xt extends nt {
|
|
541
541
|
constructor(t) {
|
|
542
542
|
super();
|
|
543
543
|
U(this, "token");
|
|
@@ -581,7 +581,7 @@ class xt extends at {
|
|
|
581
581
|
};
|
|
582
582
|
}
|
|
583
583
|
async trajectory(t, a, o, n, i = !0, s = {}) {
|
|
584
|
-
var
|
|
584
|
+
var v;
|
|
585
585
|
const r = await this.realTimePosition(t, s), l = w(a), u = w(o), c = "https://api.shipxy.com/apicall/GetShipTrack", h = {
|
|
586
586
|
searchParams: {
|
|
587
587
|
id: t,
|
|
@@ -594,8 +594,8 @@ class xt extends at {
|
|
|
594
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, F = [], I = w.unix((
|
|
598
|
-
let
|
|
597
|
+
const b = k == null ? void 0 : k.points, F = [], I = w.unix((v = b[0]) == null ? void 0 : v.utc);
|
|
598
|
+
let p = -1;
|
|
599
599
|
for (const f of b) {
|
|
600
600
|
const d = w.unix(f.utc), m = {
|
|
601
601
|
imo: r == null ? void 0 : r.imo,
|
|
@@ -609,12 +609,12 @@ class xt extends at {
|
|
|
609
609
|
method: "trajectory",
|
|
610
610
|
vendor: "shipxy"
|
|
611
611
|
}, y = Math.floor(d.diff(I, "minute", !0) / (n || 1));
|
|
612
|
-
y !==
|
|
612
|
+
y !== p && (p = y, F.push(m));
|
|
613
613
|
}
|
|
614
614
|
return F;
|
|
615
615
|
}
|
|
616
616
|
}
|
|
617
|
-
class Nt extends
|
|
617
|
+
class Nt extends nt {
|
|
618
618
|
constructor(t) {
|
|
619
619
|
super();
|
|
620
620
|
U(this, "token");
|
|
@@ -707,25 +707,25 @@ class Nt extends at {
|
|
|
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
|
-
for (const
|
|
711
|
-
!isNaN(k[
|
|
710
|
+
for (const p in k)
|
|
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
713
|
let F = -1;
|
|
714
|
-
for (const
|
|
715
|
-
const
|
|
714
|
+
for (const p of k) {
|
|
715
|
+
const v = w.unix(p.posTime), f = {
|
|
716
716
|
imo: n == null ? void 0 : n.imo,
|
|
717
717
|
mmsi: i,
|
|
718
|
-
lat: Math.round(
|
|
719
|
-
lng: Math.round(
|
|
720
|
-
sog: Math.round(
|
|
721
|
-
cog: Math.round(
|
|
722
|
-
hdg: Math.round(
|
|
723
|
-
rot: Math.round(
|
|
724
|
-
positionTime:
|
|
725
|
-
utc:
|
|
718
|
+
lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
719
|
+
lng: Math.round(p.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
720
|
+
sog: Math.round(p.sog / 10 * 100) / 100,
|
|
721
|
+
cog: Math.round(p.cog / 10 * 100) / 100,
|
|
722
|
+
hdg: Math.round(p.heading * 100) / 100,
|
|
723
|
+
rot: Math.round(p.rot * 100) / 100,
|
|
724
|
+
positionTime: v.unix(),
|
|
725
|
+
utc: v.utc().format(),
|
|
726
726
|
method: "trajectory",
|
|
727
727
|
vendor: "myship"
|
|
728
|
-
}, d = Math.floor(
|
|
728
|
+
}, d = Math.floor(v.diff(b, "minute", !0) / (s || 1));
|
|
729
729
|
d !== F && (F = d, r.push(f));
|
|
730
730
|
}
|
|
731
731
|
return r;
|
|
@@ -733,7 +733,7 @@ class Nt extends at {
|
|
|
733
733
|
}
|
|
734
734
|
let K;
|
|
735
735
|
try {
|
|
736
|
-
K =
|
|
736
|
+
K = ut.getLogger("vessel");
|
|
737
737
|
} catch {
|
|
738
738
|
} finally {
|
|
739
739
|
}
|
|
@@ -794,9 +794,9 @@ class Mt {
|
|
|
794
794
|
* @param options
|
|
795
795
|
*/
|
|
796
796
|
checkWeather(e, t, a = {}) {
|
|
797
|
-
var b, F, I,
|
|
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(((F = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : F.number) * 1.6 * 100) / 100, l = (
|
|
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
800
|
for (let W = 0; W < (e == null ? void 0 : e.length); W++) {
|
|
801
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
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;
|
|
@@ -807,12 +807,12 @@ class Mt {
|
|
|
807
807
|
const Dt = new Mt();
|
|
808
808
|
let E;
|
|
809
809
|
try {
|
|
810
|
-
E =
|
|
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 || {}),
|
|
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
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
|
|
@@ -959,14 +959,14 @@ class H {
|
|
|
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: F, marineModels: I } = await
|
|
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
|
-
forecastDays:
|
|
965
|
+
forecastDays: 2,
|
|
966
966
|
weatherModels: F,
|
|
967
967
|
marineModels: I
|
|
968
|
-
}), [
|
|
969
|
-
u =
|
|
968
|
+
}), [v] = dt.pickHourly(p, a);
|
|
969
|
+
u = dt.toLegacy(v);
|
|
970
970
|
} catch (F) {
|
|
971
971
|
E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, F);
|
|
972
972
|
}
|
|
@@ -1016,7 +1016,7 @@ class H {
|
|
|
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 F = 0, I = 0,
|
|
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;
|
|
@@ -1031,35 +1031,35 @@ class H {
|
|
|
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
|
-
return d.distanceFromPrevious = I, { etd: t, from:
|
|
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 H.speedLoseAt(e, d, t, s, 0, r, l, u), b.push(d),
|
|
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
1038
|
const y = R.calculateDistance(d, m, !m.gcToPrevious);
|
|
1039
|
-
let S = Math.round(y /
|
|
1039
|
+
let S = Math.round(y / v.speed * 1e5) / 1e5;
|
|
1040
1040
|
if (F + S < o) {
|
|
1041
1041
|
if (F += S, t.add(S, "hour"), delete i[f], E == null || E.debug(
|
|
1042
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
|
-
{ lat:
|
|
1045
|
+
{ lat: v.lat, lng: v.lng, etd: v.etd }
|
|
1046
1046
|
), I += y, i.filter((M) => M).length <= 1) {
|
|
1047
|
-
|
|
1047
|
+
p = m, p.eta = t.utc().format(), p.distanceFromPrevious = y, p.distanceFromStart = Math.round((n + I) * 1e4) / 1e4, h.push(p), b.push(p), delete i[f + 1];
|
|
1048
1048
|
break;
|
|
1049
1049
|
}
|
|
1050
1050
|
} else {
|
|
1051
1051
|
S = o - F, t.add(S, "hour");
|
|
1052
|
-
const M = J.roundPrecision(
|
|
1053
|
-
|
|
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
1054
|
`[%s] go to %j from %j with ${M}nm, and cost ${S} hours`,
|
|
1055
1055
|
u.requestId,
|
|
1056
|
-
{ lat:
|
|
1056
|
+
{ lat: p.lat, lng: p.lng },
|
|
1057
1057
|
{ lat: d.lat, lng: d.lng, etd: d.etd }
|
|
1058
|
-
), I += M,
|
|
1058
|
+
), I += M, p.distanceFromPrevious = Math.round(I * 1e4) / 1e4, p.distanceFromStart = Math.round((n + I) * 1e4) / 1e4;
|
|
1059
1059
|
break;
|
|
1060
1060
|
}
|
|
1061
1061
|
}
|
|
1062
|
-
return { etd: t, from:
|
|
1062
|
+
return { etd: t, from: v, to: p, next: i.filter((f) => f), wps: h, days: k, all: b };
|
|
1063
1063
|
}
|
|
1064
1064
|
/**
|
|
1065
1065
|
* 洋流影响因子
|
|
@@ -1081,14 +1081,14 @@ class H {
|
|
|
1081
1081
|
* @param cFactor 洋流因子
|
|
1082
1082
|
*/
|
|
1083
1083
|
static weatherFactor(e, t, a = 0) {
|
|
1084
|
-
var k, b, F, I,
|
|
1084
|
+
var k, b, F, I, p, v, f;
|
|
1085
1085
|
E == null || E.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
1086
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
1087
|
let r = R.includedAngle(e.bearing, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.degree);
|
|
1088
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 = R.includedAngle(e.bearing, (
|
|
1091
|
-
const h = H.waveHeightFactor(((f = (
|
|
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
|
/**
|
|
@@ -1135,12 +1135,12 @@ class H {
|
|
|
1135
1135
|
v0: o.speed,
|
|
1136
1136
|
label: "CP"
|
|
1137
1137
|
/* Cp */
|
|
1138
|
-
},
|
|
1139
|
-
|
|
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
|
-
waypoints:
|
|
1143
|
+
waypoints: v,
|
|
1144
1144
|
v0: F,
|
|
1145
1145
|
label: I
|
|
1146
1146
|
}, d = {
|
|
@@ -1150,12 +1150,12 @@ class H {
|
|
|
1150
1150
|
all: []
|
|
1151
1151
|
};
|
|
1152
1152
|
s || (R.calculateRouteDistance(b) / o.speed <= 72 ? s = 3 : s = 6);
|
|
1153
|
-
let m = R.simplifyRouteToCoordinates(b,
|
|
1153
|
+
let m = R.simplifyRouteToCoordinates(b, v, 0), y = 0, S = 0, M = 0, j = 0;
|
|
1154
1154
|
t = w(t).utc();
|
|
1155
1155
|
const N = t.clone();
|
|
1156
1156
|
for (; m.length > 0; ) {
|
|
1157
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
1160
|
N,
|
|
1161
1161
|
B,
|
|
@@ -1167,8 +1167,8 @@ class H {
|
|
|
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 O = await H.speedLoseAt(
|
|
1171
|
-
O.bearing =
|
|
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
|
}
|
|
@@ -1183,21 +1183,23 @@ class H {
|
|
|
1183
1183
|
const T = d.wps[B - 1];
|
|
1184
1184
|
if (T) {
|
|
1185
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
|
|
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
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;
|
|
1189
1191
|
const W = d.hours.at(0), C = d.hours.at(-1);
|
|
1190
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;
|
|
1191
|
-
const Y = J.roundPrecision(o.dgo / 24 * L, 3), { distanceInECA: A, hoursInECA: V, totalDgoConsInECA:
|
|
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
1196
|
distanceInECA: A,
|
|
1195
1197
|
hoursInECA: V,
|
|
1196
|
-
totalDgoConsInECA:
|
|
1198
|
+
totalDgoConsInECA: ot,
|
|
1197
1199
|
totalDgoConsInSuspend: Y
|
|
1198
|
-
}, f.totalFoCons = et < 0 ? 0 : et, f.totalDgoCons =
|
|
1199
|
-
const st = w().valueOf() - c,
|
|
1200
|
-
return E == null || E.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", u == null ? void 0 : u.requestId, st,
|
|
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 小时)
|
|
@@ -1226,12 +1228,12 @@ class H {
|
|
|
1226
1228
|
v0: n.speed,
|
|
1227
1229
|
label: "CP"
|
|
1228
1230
|
/* Cp */
|
|
1229
|
-
}, I = H.assembleProperties(o, n.loadCondition, b, 0),
|
|
1230
|
-
if (((X =
|
|
1231
|
+
}, I = H.assembleProperties(o, n.loadCondition, b, 0), p = R.calculateSubRoute(e, i);
|
|
1232
|
+
if (((X = p[0]) == null ? void 0 : X.length) <= 1)
|
|
1231
1233
|
return;
|
|
1232
|
-
const
|
|
1233
|
-
|
|
1234
|
-
let f = R.simplifyRouteToCoordinates(
|
|
1234
|
+
const v = s.length ? R.calculateSubWaypoints(e, s) : [];
|
|
1235
|
+
v.forEach((T) => T.important = !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: [],
|
|
@@ -1251,8 +1253,8 @@ class H {
|
|
|
1251
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) => {
|
|
1252
1254
|
const q = M.wps[O - 1];
|
|
1253
1255
|
if (q) {
|
|
1254
|
-
const
|
|
1255
|
-
q.bearing = R.calculateBearing(q, T), T.avgSpd = Math.round(
|
|
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
1260
|
const N = M.hours;
|
|
@@ -1260,7 +1262,7 @@ class H {
|
|
|
1260
1262
|
const O = w(N[T + 1].eta).diff(N[T].etd, "hour", !0);
|
|
1261
1263
|
m += N[T].wxFactor * O, y += N[T].cFactor * O, S += O;
|
|
1262
1264
|
}
|
|
1263
|
-
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,
|
|
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
1267
|
distance: Math.round(((W == null ? void 0 : W.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1266
1268
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
@@ -1277,14 +1279,14 @@ class H {
|
|
|
1277
1279
|
waypoints: Y,
|
|
1278
1280
|
v0: b,
|
|
1279
1281
|
label: F
|
|
1280
|
-
}, V = J.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA:
|
|
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);
|
|
1281
1283
|
A.extend = {
|
|
1282
|
-
eca:
|
|
1283
|
-
distanceInECA:
|
|
1284
|
+
eca: it,
|
|
1285
|
+
distanceInECA: ot,
|
|
1284
1286
|
hoursInECA: tt,
|
|
1285
1287
|
totalDgoConsInECA: et,
|
|
1286
1288
|
totalDgoConsInSuspend: V
|
|
1287
|
-
}, A.totalDgoCons = st, A.totalFoCons =
|
|
1289
|
+
}, A.totalDgoCons = st, A.totalFoCons = rt < 0 ? 0 : rt;
|
|
1288
1290
|
const _ = w().valueOf() - k, G = ((B = M == null ? void 0 : M.hours) == null ? void 0 : B.length) || 1;
|
|
1289
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
|
}
|
|
@@ -1304,7 +1306,7 @@ class H {
|
|
|
1304
1306
|
* @param options
|
|
1305
1307
|
*/
|
|
1306
1308
|
static async analyseCost(e, t, a, o, n = {}) {
|
|
1307
|
-
var
|
|
1309
|
+
var p, v;
|
|
1308
1310
|
const i = w().valueOf(), s = [];
|
|
1309
1311
|
e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
|
|
1310
1312
|
const r = R.calculateRouteDistance(o.route);
|
|
@@ -1341,11 +1343,11 @@ class H {
|
|
|
1341
1343
|
}
|
|
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
|
-
if (b.push({ combined: !1, speeds: [h], cost: (
|
|
1346
|
+
if (b.push({ combined: !1, speeds: [h], cost: (p = h.cost) == null ? void 0 : p.total }), k) {
|
|
1345
1347
|
const f = h.cost.cp, d = k.cost.cp, m = w(h.eta), y = w(h.etd), S = m.diff(y, "days", !0);
|
|
1346
1348
|
let M = Math.ceil(S / 2);
|
|
1347
1349
|
M = M > 7 ? 7 : M < e.alterStep ? e.alterStep : M;
|
|
1348
|
-
let j = 2, N = { combined: !1, speeds: [k], cost: (
|
|
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
1352
|
const L = await H.combinedAnalyse(e, t, u, [f, d], o, M, { ...n, level: j });
|
|
1351
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)
|
|
@@ -1377,12 +1379,12 @@ class H {
|
|
|
1377
1379
|
distance: h,
|
|
1378
1380
|
hours: k
|
|
1379
1381
|
});
|
|
1380
|
-
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),
|
|
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
1384
|
cost: F,
|
|
1383
1385
|
hire: I,
|
|
1384
|
-
bunker:
|
|
1385
|
-
distance:
|
|
1386
|
+
bunker: p,
|
|
1387
|
+
distance: v,
|
|
1386
1388
|
hours: f
|
|
1387
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
|
}
|
|
@@ -1402,12 +1404,12 @@ class H {
|
|
|
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"), F = JSON.parse(JSON.stringify(i.route)), I = JSON.parse(JSON.stringify(i.waypoints)),
|
|
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
1413
|
F,
|
|
1412
1414
|
I,
|
|
1413
1415
|
e.meteoVendor,
|
|
@@ -1416,7 +1418,7 @@ class H {
|
|
|
1416
1418
|
e.useRouteParam,
|
|
1417
1419
|
r
|
|
1418
1420
|
);
|
|
1419
|
-
|
|
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,
|
|
@@ -1424,17 +1426,17 @@ class H {
|
|
|
1424
1426
|
l.utc().format(),
|
|
1425
1427
|
b.utc().format(),
|
|
1426
1428
|
{
|
|
1427
|
-
cost:
|
|
1428
|
-
hire:
|
|
1429
|
-
bunker:
|
|
1430
|
-
distance:
|
|
1431
|
-
hours:
|
|
1432
|
-
cp: `${
|
|
1429
|
+
cost: v.cost.total,
|
|
1430
|
+
hire: v.cost.hire,
|
|
1431
|
+
bunker: v.cost.bunker,
|
|
1432
|
+
distance: v.distance,
|
|
1433
|
+
hours: v.totalHrs,
|
|
1434
|
+
cp: `${p.speed}/${p.fo}/${p.dgo}`
|
|
1433
1435
|
}
|
|
1434
1436
|
)), r.counter = r.counter + 1;
|
|
1435
|
-
const f = (k = (h =
|
|
1437
|
+
const f = (k = (h = v == null ? void 0 : v.sample) == null ? void 0 : h.hours) == null ? void 0 : k.at(-1);
|
|
1436
1438
|
if (f)
|
|
1437
|
-
u.lat = f.lat, u.lng = f.lng, l = w(f.eta), c.push(
|
|
1439
|
+
u.lat = f.lat, u.lng = f.lng, l = w(f.eta), c.push(v), n = n ? 0 : 1;
|
|
1438
1440
|
else
|
|
1439
1441
|
break;
|
|
1440
1442
|
}
|
|
@@ -1505,19 +1507,19 @@ class H {
|
|
|
1505
1507
|
}, 0), r = e.reduce((m, y) => {
|
|
1506
1508
|
var S;
|
|
1507
1509
|
return m + (((S = y.extend) == null ? void 0 : S.totalDgoConsInECA) || 0);
|
|
1508
|
-
}, 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 = [],
|
|
1509
|
-
let
|
|
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 = [];
|
|
1511
|
+
let v;
|
|
1510
1512
|
for (const m of e) {
|
|
1511
|
-
|
|
1513
|
+
p.push(...((f = m.extend) == null ? void 0 : f.eca) || []);
|
|
1512
1514
|
const y = m.sample.hours, S = m.sample.all, M = m.sample.wps, j = m.sample.days, N = y.at(0);
|
|
1513
|
-
|
|
1514
|
-
Y && (C.distanceFromStart = C.distanceFromStart +
|
|
1515
|
-
}), S.at(0).distanceFromPrevious =
|
|
1516
|
-
Y && (C.distanceFromStart = C.distanceFromStart +
|
|
1517
|
-
}), M.at(0).distanceFromPrevious =
|
|
1518
|
-
Y && (C.distanceFromStart = C.distanceFromStart +
|
|
1519
|
-
}), j.at(0).distanceFromPrevious =
|
|
1520
|
-
Y && (C.distanceFromStart = C.distanceFromStart +
|
|
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);
|
|
1521
1523
|
})), N.cp = m.cost.cp;
|
|
1522
1524
|
const D = [m.etd, m.eta], L = I.findIndex((C) => C.id === N.cp.id);
|
|
1523
1525
|
L === -1 ? (N.cp.segment = [D], I.push(N.cp)) : I[L].segment.push(D), y.forEach((C) => {
|
|
@@ -1534,7 +1536,7 @@ class H {
|
|
|
1534
1536
|
((A = a == null ? void 0 : a.days) == null ? void 0 : A.findIndex((V) => V.eta === C.eta)) === -1 && a.days.push(C);
|
|
1535
1537
|
});
|
|
1536
1538
|
const W = (d = a.wps) == null ? void 0 : d.findIndex((C) => C.eta === N.eta);
|
|
1537
|
-
W === -1 ? a.wps.push(N) : a.wps[W] = N,
|
|
1539
|
+
W === -1 ? a.wps.push(N) : a.wps[W] = N, v = y.at(-1);
|
|
1538
1540
|
}
|
|
1539
1541
|
return a.wps.sort((m, y) => w(m.etd).unix() - w(y.etd).unix()), a.wps.forEach((m, y) => {
|
|
1540
1542
|
const S = a.wps[y - 1];
|
|
@@ -1566,7 +1568,7 @@ class H {
|
|
|
1566
1568
|
},
|
|
1567
1569
|
extend: {
|
|
1568
1570
|
cps: I,
|
|
1569
|
-
eca:
|
|
1571
|
+
eca: p,
|
|
1570
1572
|
distanceInECA: Math.round(n * 1e3) / 1e3,
|
|
1571
1573
|
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1572
1574
|
totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
|
|
@@ -1576,16 +1578,16 @@ class H {
|
|
|
1576
1578
|
}
|
|
1577
1579
|
}
|
|
1578
1580
|
export {
|
|
1579
|
-
|
|
1581
|
+
nt as AISImpl,
|
|
1580
1582
|
Mt as AlertHelper,
|
|
1581
1583
|
yt as AlertLevel,
|
|
1582
1584
|
jt as HifleetImpl,
|
|
1583
|
-
|
|
1585
|
+
vt as LoadCondition,
|
|
1584
1586
|
Nt as MyShipImpl,
|
|
1585
1587
|
Tt as MyVesselImpl,
|
|
1586
1588
|
xt as ShipxyImpl,
|
|
1587
1589
|
H as SpeedHelper,
|
|
1588
|
-
|
|
1590
|
+
pt as SpeedLabel,
|
|
1589
1591
|
bt as VesselTag,
|
|
1590
1592
|
Dt as alertHelper
|
|
1591
1593
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(P,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):(P=typeof globalThis<"u"?globalThis:P||self,x(P["idm-plugin-vessel"]={},P.got,P["@log4js-node/log4js-api"],P.moment,P["@idm-plugin/geo2"],P["@idm-plugin/meteo2"],P["@idm-plugin/meteo"]))})(this,function(P,x,U,w,E,yt,ot){"use strict";var St=Object.defineProperty;var Ct=(P,x,U)=>x in P?St(P,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):P[x]=U;var _=(P,x,U)=>(Ct(P,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,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 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 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 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 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 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 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 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;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 vt=new lt;let F;try{F=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=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 ot.Meteo2Assist.autoPickMeteoModel(o),v=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:T,marineModels:k}),[g]=ot.Meteo2Assist.pickHourly(v,a);u=ot.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(q=>q.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 q=s-t.hour()%s,J=Math.ceil(t.clone().add(q,"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 q=0;q<N.length-1;q++){const J=w(N[q+1].eta).diff(N[q].etd,"hour",!0)||1;C+=(N[q].wxFactor||0)*J,p+=(N[q].cFactor||0)*J,L+=J}const W=N.reduce((q,J)=>q+(J.suspend||0),0);($=d.wps)==null||$.forEach((q,J)=>{q.positionTime=w.utc(q.etd||q.eta).unix();const j=d.wps[J-1];if(j){const V=q.distanceFromStart-j.distanceFromStart,Y=w(q.eta||q.etd).diff(w(j.etd||j.eta),"h",!0);q.avgSpd=Math.round(V/Y*100)/100,j.bearing=E.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,J)=>(J.positionTime=w.utc(J.etd||J.eta).unix(),q.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||q.push(J),q),[]),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:it,eca:st}=await this.calculateECA(m,o,u),at=E.LngLatHelper.roundPrecision(o.fo/24*(L-z),3),rt=E.LngLatHelper.roundPrecision(o.dgo/24*L+R,3);m.extend={eca:st,distanceInECA:D,hoursInECA:z,totalDgoConsInECA:it,totalDgoConsInSuspend:R},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 F==null||F.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,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),[]),(q=p.wps)==null||q.forEach((j,V)=>{const Y=p.wps[V-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=E.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/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:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(D,n,h),ct=E.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=E.LngLatHelper.roundPrecision(n.dgo/24*C+z,3);D.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:z},D.totalDgoCons=nt,D.totalFoCons=ct<0?0:ct;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}}}}P.AISImpl=G,P.AlertHelper=lt,P.AlertLevel=ut,P.HifleetImpl=Mt,P.LoadCondition=ft,P.MyShipImpl=gt,P.MyVesselImpl=pt,P.ShipxyImpl=bt,P.SpeedHelper=O,P.SpeedLabel=mt,P.VesselTag=ht,P.alertHelper=vt,Object.defineProperty(P,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:2,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"})});
|