@idm-plugin/vessel 1.3.7 → 1.3.9
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 +117 -115
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var st = (I, s, t) => s in I ? et(I, s, { enumerable: !0, configurable: !0, writ
|
|
|
3
3
|
var Z = (I, s, t) => (st(I, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
4
|
import R from "got";
|
|
5
5
|
import z from "@log4js-node/log4js-api";
|
|
6
|
-
import
|
|
6
|
+
import v from "moment";
|
|
7
7
|
import { LngLatHelper as B, LaneHelper as V } from "@idm-plugin/geo";
|
|
8
8
|
import { MeteoHelper as at } from "@idm-plugin/meteo";
|
|
9
9
|
let u;
|
|
@@ -75,12 +75,12 @@ class pt extends K {
|
|
|
75
75
|
expiresIn: n.expires_in,
|
|
76
76
|
scope: n.scope,
|
|
77
77
|
jti: n.jti,
|
|
78
|
-
issuedAt:
|
|
78
|
+
issuedAt: v().utc().format()
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
async realTimePosition(t, i = {}) {
|
|
82
82
|
var d, l, p;
|
|
83
|
-
(!this.token ||
|
|
83
|
+
(!this.token || v().diff(v(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(i);
|
|
84
84
|
const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
|
|
85
85
|
headers: {
|
|
86
86
|
Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(p = this.token) == null ? void 0 : p.accessToken}`
|
|
@@ -94,7 +94,7 @@ class pt extends K {
|
|
|
94
94
|
const e = a.data;
|
|
95
95
|
for (const f in e)
|
|
96
96
|
!isNaN(e[f]) && Number(e[f]) !== 1 / 0 && (e[f] = Number(e[f]));
|
|
97
|
-
const c =
|
|
97
|
+
const c = v(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
98
98
|
return {
|
|
99
99
|
mmsi: e.mmsi,
|
|
100
100
|
name: e.vesselName,
|
|
@@ -121,17 +121,17 @@ class pt extends K {
|
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
124
|
-
(!this.token ||
|
|
125
|
-
const c = await this.realTimePosition(t, e), r =
|
|
124
|
+
(!this.token || v().diff(v(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
|
|
125
|
+
const c = await this.realTimePosition(t, e), r = v(i), d = v(o), l = [];
|
|
126
126
|
for (; d.diff(r, "day", !0) > 30; )
|
|
127
127
|
await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), c, n, l, e), r.add(30, "day");
|
|
128
128
|
return await this.trajectoryIn30Day(t, r, d, c, n, l, e), l;
|
|
129
129
|
}
|
|
130
130
|
async trajectoryIn30Day(t, i, o, n, a, e, c = {}) {
|
|
131
|
-
var m,
|
|
131
|
+
var m, Y, j, b, M;
|
|
132
132
|
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", d = {
|
|
133
133
|
headers: {
|
|
134
|
-
Authorization: `${(m = this.token) == null ? void 0 : m.tokenType} ${(
|
|
134
|
+
Authorization: `${(m = this.token) == null ? void 0 : m.tokenType} ${(Y = this.token) == null ? void 0 : Y.accessToken}`
|
|
135
135
|
},
|
|
136
136
|
json: {
|
|
137
137
|
mmsi: t,
|
|
@@ -144,11 +144,11 @@ class pt extends K {
|
|
|
144
144
|
if (l.code)
|
|
145
145
|
return u == null || u.warn("[%s] fetch trajectory failed: %j", c.requestId, r, { message: l.message, status: l.status, code: l.code }), l;
|
|
146
146
|
let p = -1;
|
|
147
|
-
const f =
|
|
147
|
+
const f = v(`${(b = (j = l.data) == null ? void 0 : j[0]) == null ? void 0 : b.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
148
148
|
return (M = l.data) == null || M.forEach((h) => {
|
|
149
149
|
for (const T in h)
|
|
150
150
|
!isNaN(h[T]) && Number(h[T]) !== 1 / 0 && (h[T] = Number(h[T]));
|
|
151
|
-
const k =
|
|
151
|
+
const k = v(`${h.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), w = h.eta ? v(`${h.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, y = h.status, { labelCn: g, labelEn: N } = this.parseStatus(y), F = {
|
|
152
152
|
mmsi: h.mmsi,
|
|
153
153
|
imo: n == null ? void 0 : n.imo,
|
|
154
154
|
lat: h.lat,
|
|
@@ -158,7 +158,7 @@ class pt extends K {
|
|
|
158
158
|
hdg: h.hdg,
|
|
159
159
|
draught: h.draught,
|
|
160
160
|
status: y,
|
|
161
|
-
eta:
|
|
161
|
+
eta: w == null ? void 0 : w.unix(),
|
|
162
162
|
destination: h.dest,
|
|
163
163
|
positionTime: k.unix(),
|
|
164
164
|
labelCn: g,
|
|
@@ -191,7 +191,7 @@ class Mt extends K {
|
|
|
191
191
|
for (const f in e)
|
|
192
192
|
!isNaN(e[f]) && Number(e[f]) !== 1 / 0 && (e[f] = Number(e[f]));
|
|
193
193
|
e.status = e.sp > 3 ? 0 : 1;
|
|
194
|
-
const c = e.status, { labelCn: r, labelEn: d } = this.parseStatus(c), l =
|
|
194
|
+
const c = e.status, { labelCn: r, labelEn: d } = this.parseStatus(c), l = v(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
195
195
|
return {
|
|
196
196
|
mmsi: e.m,
|
|
197
197
|
name: e.n,
|
|
@@ -206,7 +206,7 @@ class Mt extends K {
|
|
|
206
206
|
cog: e.co,
|
|
207
207
|
hdg: e.h,
|
|
208
208
|
rot: isNaN(e.rot) ? 0 : e.rot,
|
|
209
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ?
|
|
209
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? v(`${e.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
|
|
210
210
|
destination: e.destination,
|
|
211
211
|
positionTime: l.unix(),
|
|
212
212
|
utc: l.utc().format(),
|
|
@@ -245,10 +245,10 @@ class Mt extends K {
|
|
|
245
245
|
return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await R.post(o, n).json(), u == null || u.info("[%s] fetch vessel dead weight from: %s - %j", i.requestId, o, n), a instanceof Array && (a = a[0]), a && (e.deadweight = Number(a.dwt)), e;
|
|
246
246
|
}
|
|
247
247
|
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
248
|
-
var h, k,
|
|
248
|
+
var h, k, w;
|
|
249
249
|
const c = await this.realTimePosition(t, e);
|
|
250
|
-
let r =
|
|
251
|
-
const d =
|
|
250
|
+
let r = v(i);
|
|
251
|
+
const d = v(o), l = v();
|
|
252
252
|
if (a) {
|
|
253
253
|
let y = d.diff(r, "d", !0);
|
|
254
254
|
y < 0 ? r = d.clone().subtract(40, "d") : y < 30 ? r.subtract(10, "d") : y < 60 ? r.subtract(5, "d") : r = d.clone().subtract(80, "d"), y = l.diff(d, "d", !0), d.add(y > 10 ? 240 : y * 24, "h");
|
|
@@ -262,15 +262,15 @@ class Mt extends K {
|
|
|
262
262
|
}
|
|
263
263
|
}, f = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", m = await R.get(f, p).json();
|
|
264
264
|
u == null || u.info("[%s] fetch trajectory from: %s - %j", e.requestId, f, p);
|
|
265
|
-
let
|
|
266
|
-
m && (
|
|
267
|
-
const
|
|
268
|
-
let
|
|
269
|
-
const M =
|
|
270
|
-
for (const y of
|
|
265
|
+
let Y;
|
|
266
|
+
m && (Y = ((k = (h = m.ships) == null ? void 0 : h.offors) == null ? void 0 : k.ship) || [], Y.length || u == null || u.warn("[%s] fetch trajectory failed: %j", e.requestId, m));
|
|
267
|
+
const j = [];
|
|
268
|
+
let b = -1;
|
|
269
|
+
const M = v(`${(w = Y == null ? void 0 : Y[0]) == null ? void 0 : w.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
270
|
+
for (const y of Y) {
|
|
271
271
|
for (const L in y)
|
|
272
272
|
!isNaN(y[L]) && Number(y[L]) !== 1 / 0 && (y[L] = Number(y[L]));
|
|
273
|
-
const g =
|
|
273
|
+
const g = v(`${y.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
274
274
|
y.status = y.sp > 4 ? 0 : 1;
|
|
275
275
|
const { labelEn: N, labelCn: F } = this.parseStatus(y.status), W = {
|
|
276
276
|
mmsi: y.m,
|
|
@@ -290,9 +290,9 @@ class Mt extends K {
|
|
|
290
290
|
method: "trajectory",
|
|
291
291
|
vendor: "hifleet"
|
|
292
292
|
}, T = Math.floor(g.diff(M, "minute", !0) / (n || 1));
|
|
293
|
-
T !==
|
|
293
|
+
T !== b && (b = T, j.push(W));
|
|
294
294
|
}
|
|
295
|
-
return
|
|
295
|
+
return j;
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
class yt extends K {
|
|
@@ -314,7 +314,7 @@ class yt extends K {
|
|
|
314
314
|
const e = a.data[0];
|
|
315
315
|
for (const p in e)
|
|
316
316
|
!isNaN(e[p]) && Number(e[p]) !== 1 / 0 && (e[p] = Number(e[p]));
|
|
317
|
-
const { labelCn: c, labelEn: r } = await this.parseStatus(e.navistat), d =
|
|
317
|
+
const { labelCn: c, labelEn: r } = await this.parseStatus(e.navistat), d = v.unix(e.lasttime);
|
|
318
318
|
return {
|
|
319
319
|
mmsi: e.ShipID,
|
|
320
320
|
name: e.name,
|
|
@@ -340,7 +340,7 @@ class yt extends K {
|
|
|
340
340
|
}
|
|
341
341
|
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
342
342
|
var M;
|
|
343
|
-
const c = await this.realTimePosition(t, e), r =
|
|
343
|
+
const c = await this.realTimePosition(t, e), r = v(i), d = v(o), l = "https://api.shipxy.com/apicall/GetShipTrack", p = {
|
|
344
344
|
searchParams: {
|
|
345
345
|
id: t,
|
|
346
346
|
k: this.token,
|
|
@@ -352,10 +352,10 @@ class yt extends K {
|
|
|
352
352
|
}, f = await R.get(l, p).json();
|
|
353
353
|
if (u == null || u.info("[%s] fetch trajectory from: %s - %j", e.requestId, l, p), (f == null ? void 0 : f.status) !== 0)
|
|
354
354
|
return f;
|
|
355
|
-
const m = f == null ? void 0 : f.points,
|
|
356
|
-
let
|
|
355
|
+
const m = f == null ? void 0 : f.points, Y = [], j = v.unix((M = m[0]) == null ? void 0 : M.utc);
|
|
356
|
+
let b = -1;
|
|
357
357
|
for (const h of m) {
|
|
358
|
-
const k =
|
|
358
|
+
const k = v.unix(h.utc), w = {
|
|
359
359
|
imo: c == null ? void 0 : c.imo,
|
|
360
360
|
mmsi: t,
|
|
361
361
|
sog: Math.round(h.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
@@ -366,10 +366,10 @@ class yt extends K {
|
|
|
366
366
|
utc: k.utc().format(),
|
|
367
367
|
method: "trajectory",
|
|
368
368
|
vendor: "shipxy"
|
|
369
|
-
}, y = Math.floor(k.diff(
|
|
370
|
-
y !==
|
|
369
|
+
}, y = Math.floor(k.diff(j, "minute", !0) / (n || 1));
|
|
370
|
+
y !== b && (b = y, Y.push(w));
|
|
371
371
|
}
|
|
372
|
-
return
|
|
372
|
+
return Y;
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
375
|
class gt extends K {
|
|
@@ -425,7 +425,7 @@ class gt extends K {
|
|
|
425
425
|
const r = c.data[0];
|
|
426
426
|
for (const m in r)
|
|
427
427
|
!isNaN(r[m]) && Number(r[m]) !== 1 / 0 && (r[m] = Number(r[m]));
|
|
428
|
-
const { labelCn: d, labelEn: l } = await this.parseStatus(r.aisNavStatus), p =
|
|
428
|
+
const { labelCn: d, labelEn: l } = await this.parseStatus(r.aisNavStatus), p = v.unix(r.posTime);
|
|
429
429
|
return {
|
|
430
430
|
...n,
|
|
431
431
|
mmsi: t,
|
|
@@ -445,13 +445,13 @@ class gt extends K {
|
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
447
|
async trajectory(t, i, o, n, a = !0, e = {}) {
|
|
448
|
-
const c =
|
|
448
|
+
const c = v(i), r = v(o), d = await this.getShipId(t), l = await this.getShipInfo(d), p = [];
|
|
449
449
|
for (; r.diff(c, "day", !0) > 30; )
|
|
450
450
|
await this.trajectoryIn30Day(d, c.unix(), c.add(30, "day").unix(), l, t, n, p);
|
|
451
451
|
return await this.trajectoryIn30Day(d, c.unix(), r.unix(), l, t, n, p), p;
|
|
452
452
|
}
|
|
453
453
|
async trajectoryIn30Day(t, i, o, n, a, e, c, r = {}) {
|
|
454
|
-
var
|
|
454
|
+
var j;
|
|
455
455
|
const d = {
|
|
456
456
|
headers: {
|
|
457
457
|
appKey: this.token
|
|
@@ -465,26 +465,26 @@ class gt extends K {
|
|
|
465
465
|
if (u == null || u.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, d), p.code !== "0")
|
|
466
466
|
return u == null || u.warn("[%s] invoke myship trajectory failed: %j", r.requestId, p), p;
|
|
467
467
|
const f = p.data;
|
|
468
|
-
for (const
|
|
469
|
-
!isNaN(f[
|
|
470
|
-
const m =
|
|
471
|
-
let
|
|
472
|
-
for (const
|
|
473
|
-
const M =
|
|
468
|
+
for (const b in f)
|
|
469
|
+
!isNaN(f[b]) && Number(f[b]) !== 1 / 0 && (f[b] = Number(f[b]));
|
|
470
|
+
const m = v.unix((j = f[0]) == null ? void 0 : j.posTime);
|
|
471
|
+
let Y = -1;
|
|
472
|
+
for (const b of f) {
|
|
473
|
+
const M = v.unix(b.posTime), h = {
|
|
474
474
|
imo: n == null ? void 0 : n.imo,
|
|
475
475
|
mmsi: a,
|
|
476
|
-
lat: Math.round(
|
|
477
|
-
lng: Math.round(
|
|
478
|
-
sog: Math.round(
|
|
479
|
-
cog: Math.round(
|
|
480
|
-
hdg: Math.round(
|
|
481
|
-
rot: Math.round(
|
|
476
|
+
lat: Math.round(b.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
477
|
+
lng: Math.round(b.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
478
|
+
sog: Math.round(b.sog / 10 * 100) / 100,
|
|
479
|
+
cog: Math.round(b.cog / 10 * 100) / 100,
|
|
480
|
+
hdg: Math.round(b.heading * 100) / 100,
|
|
481
|
+
rot: Math.round(b.rot * 100) / 100,
|
|
482
482
|
positionTime: M.unix(),
|
|
483
483
|
utc: M.utc().format(),
|
|
484
484
|
method: "trajectory",
|
|
485
485
|
vendor: "myship"
|
|
486
486
|
}, k = Math.floor(M.diff(m, "minute", !0) / (e || 1));
|
|
487
|
-
k !==
|
|
487
|
+
k !== Y && (Y = k, c.push(h));
|
|
488
488
|
}
|
|
489
489
|
return c;
|
|
490
490
|
}
|
|
@@ -550,20 +550,20 @@ class nt {
|
|
|
550
550
|
* @param options
|
|
551
551
|
*/
|
|
552
552
|
checkWeather(s, t, i = {}) {
|
|
553
|
-
var m,
|
|
553
|
+
var m, Y, j, b, M, h, k, w, y, g, N, F, W, T, L;
|
|
554
554
|
let o = 0, n = 0, a = 0, e = 0;
|
|
555
|
-
const c = Math.round(((
|
|
555
|
+
const c = Math.round(((Y = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.sigWave) == null ? void 0 : Y.number) * 1.6 * 100) / 100, r = (b = (j = t == null ? void 0 : t.SEVERE) == null ? void 0 : j.sigWave) == null ? void 0 : b.number, d = (h = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.sigWave) == null ? void 0 : h.number, l = Math.round((((w = (k = t == null ? void 0 : t.SEVERE) == null ? void 0 : k.wind) == null ? void 0 : w.number) + 2) * 100) / 100, p = (g = (y = t == null ? void 0 : t.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : g.number, f = (F = (N = t == null ? void 0 : t.HEAVY) == null ? void 0 : N.wind) == null ? void 0 : F.number;
|
|
556
556
|
for (let A = 0; A < (s == null ? void 0 : s.length); A++) {
|
|
557
|
-
const S = s[A], P = (T = (W = S == null ? void 0 : S.meteo) == null ? void 0 : W.wave) == null ? void 0 : T.sig,
|
|
558
|
-
e = E > e ? E : e, O == null || O.info("[%s] check sig.wave: %j", i.requestId, { ...P, dgThd4Wv: c, svThd4Wv: r, hvThd4Wv: d }), (P == null ? void 0 : P.height) >= c ? S.isDangerous = !0 : (P == null ? void 0 : P.height) >= r ? S.isSevere = !0 : (P == null ? void 0 : P.height) >= d && (S.isHeavy = !0), O == null || O.info("[%s] check wind: %j", i.requestId, { ...
|
|
557
|
+
const S = s[A], P = (T = (W = S == null ? void 0 : S.meteo) == null ? void 0 : W.wave) == null ? void 0 : T.sig, x = (L = S == null ? void 0 : S.meteo) == null ? void 0 : L.wind, E = A ? v(S.eta).diff(v(s[A - 1].eta), "hour", !0) : 0;
|
|
558
|
+
e = E > e ? E : e, O == null || O.info("[%s] check sig.wave: %j", i.requestId, { ...P, dgThd4Wv: c, svThd4Wv: r, hvThd4Wv: d }), (P == null ? void 0 : P.height) >= c ? S.isDangerous = !0 : (P == null ? void 0 : P.height) >= r ? S.isSevere = !0 : (P == null ? void 0 : P.height) >= d && (S.isHeavy = !0), O == null || O.info("[%s] check wind: %j", i.requestId, { ...x, dgThd4Wd: l, svThd4Wd: p, hvThd4Wd: f }), (x == null ? void 0 : x.scale) >= l ? (S.isDangerous = !0, delete S.isSevere, delete S.isHeavy) : (x == null ? void 0 : x.scale) > p ? (S.isDangerous || (S.isSevere = !0), delete S.isHeavy) : (x == null ? void 0 : x.scale) === f && !S.isDangerous && !S.isSevere && (S.isHeavy = !0), o += S.isDangerous ? E : 0, n += S.isSevere ? E : 0, a += S.isHeavy ? E : 0;
|
|
559
559
|
}
|
|
560
560
|
return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, a = Math.round(a * 100) / 100, e = Math.round(e), { sample: s, dangerous: o, severe: n, heavy: a, step: e < 3 ? 3 : e, wind: { dgThd4Wd: l, svThd4Wd: p, hvThd4Wd: f }, sig: { dgThd4Wv: c, svThd4Wv: r, hvThd4Wv: d } };
|
|
561
561
|
}
|
|
562
562
|
}
|
|
563
563
|
const bt = new nt();
|
|
564
|
-
let
|
|
564
|
+
let D;
|
|
565
565
|
try {
|
|
566
|
-
|
|
566
|
+
D = z.getLogger("vessel");
|
|
567
567
|
} catch {
|
|
568
568
|
} finally {
|
|
569
569
|
}
|
|
@@ -666,8 +666,10 @@ class C {
|
|
|
666
666
|
* @param ht 浪高,单位m
|
|
667
667
|
* @private
|
|
668
668
|
*/
|
|
669
|
-
static waveHeightFactor(s) {
|
|
670
|
-
|
|
669
|
+
static waveHeightFactor(s, t) {
|
|
670
|
+
s = s < 1.25 ? 1.25 : s, s = s > 6 ? s - 0.9 * (s - 6) : s, s = s > 9 ? 9 : s;
|
|
671
|
+
let i;
|
|
672
|
+
return t > 30 && t <= 60 ? i = -0.6 : t > 60 && t <= 90 ? i = -0.4 : t > 90 && t <= 120 ? i = s < 3 ? 0.4 : -0.3 : t > 120 && t <= 150 ? i = s < 3 ? 0.6 : -0.5 : t > 150 && t <= 180 ? i = s < 3 ? 0.7 : -0.6 : i = -0.7, Math.round(i * (0.144 * Math.pow(s, 2) + 0.178 * s) * 1e4) / 1e4;
|
|
671
673
|
}
|
|
672
674
|
/**
|
|
673
675
|
* 组装船舶运行参数
|
|
@@ -742,11 +744,11 @@ class C {
|
|
|
742
744
|
static async speedLoseInHoursStep(s, t, i, o, n, a, e = "", c = !0, r = !1, d = {}) {
|
|
743
745
|
t.utc();
|
|
744
746
|
const l = [], p = [];
|
|
745
|
-
let f = 0, m = 0,
|
|
746
|
-
for (let
|
|
747
|
-
let M = a[
|
|
747
|
+
let f = 0, m = 0, Y, j;
|
|
748
|
+
for (let b = 0; b < a.length - 1; b++) {
|
|
749
|
+
let M = a[b];
|
|
748
750
|
M.distanceFromStart = n + m;
|
|
749
|
-
const h = a[
|
|
751
|
+
const h = a[b + 1];
|
|
750
752
|
if (s.bearing = V.calculateBearing(M, h, !h.gcToPrevious), M.bearing = s.bearing, M.suspend && r) {
|
|
751
753
|
M.eta = M.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), M.elapsed = M.elapsed ?? 0;
|
|
752
754
|
const y = M.suspend - M.elapsed;
|
|
@@ -756,35 +758,35 @@ class C {
|
|
|
756
758
|
const g = o - f;
|
|
757
759
|
M.elapsed += g, t.add(g, "hour"), o = 0;
|
|
758
760
|
}
|
|
759
|
-
if (
|
|
760
|
-
return M.distanceFromPrevious = m, { etd: t, from:
|
|
761
|
+
if (D == null || D.info(`[%s] suspend ${M.elapsed} hours at %j, and remain ${o} hours need to go...`, d.requestId, M), o === 0)
|
|
762
|
+
return M.distanceFromPrevious = m, { etd: t, from: j || M, to: M, next: a.filter((g) => g), wps: l, days: p };
|
|
761
763
|
}
|
|
762
|
-
M = await C.speedLoseAt(s, M, t, e, 0, c, r, d),
|
|
764
|
+
M = await C.speedLoseAt(s, M, t, e, 0, c, r, d), j = j || M, M.important && l.push(M), t.isSameOrAfter(i) && (p.push(M), i.add(24, "hour"));
|
|
763
765
|
const k = V.calculateDistance(M, h, !h.gcToPrevious);
|
|
764
|
-
let
|
|
765
|
-
if (f +
|
|
766
|
-
if (f +=
|
|
767
|
-
`[%s] go to %j from %j with ${k}nm, and cost ${
|
|
766
|
+
let w = Math.ceil(k / j.speed * 1e4) / 1e4;
|
|
767
|
+
if (f + w < o) {
|
|
768
|
+
if (f += w, t.add(w, "hour"), delete a[b], D == null || D.info(
|
|
769
|
+
`[%s] go to %j from %j with ${k}nm, and cost ${w} hours`,
|
|
768
770
|
d.requestId,
|
|
769
771
|
{ lat: h.lat, lng: h.lng },
|
|
770
|
-
{ lat:
|
|
772
|
+
{ lat: j.lat, lng: j.lng, etd: j.etd }
|
|
771
773
|
), m += k, a.filter((y) => y).length <= 1) {
|
|
772
|
-
|
|
774
|
+
Y = h, Y.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), Y.distanceFromPrevious = k, Y.distanceFromStart = n + m, l.push(Y), delete a[b + 1];
|
|
773
775
|
break;
|
|
774
776
|
}
|
|
775
777
|
} else {
|
|
776
|
-
|
|
777
|
-
const y = B.roundPrecision(
|
|
778
|
-
|
|
779
|
-
`[%s] go to %j from %j with ${y}nm, and cost ${
|
|
778
|
+
w = o - f, t.add(w, "hour");
|
|
779
|
+
const y = B.roundPrecision(j.speed * w, 4);
|
|
780
|
+
Y = V.calculateCoordinate(M, s.bearing, y, "nauticalmiles", !h.gcToPrevious), Y.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[b] = Y, D == null || D.info(
|
|
781
|
+
`[%s] go to %j from %j with ${y}nm, and cost ${w} hours`,
|
|
780
782
|
d.requestId,
|
|
781
|
-
{ lat:
|
|
783
|
+
{ lat: Y.lat, lng: Y.lng },
|
|
782
784
|
{ lat: M.lat, lng: M.lng, etd: M.etd }
|
|
783
|
-
), m += y,
|
|
785
|
+
), m += y, Y.distanceFromPrevious = m, Y.distanceFromStart = n + m;
|
|
784
786
|
break;
|
|
785
787
|
}
|
|
786
788
|
}
|
|
787
|
-
return { etd: t, from:
|
|
789
|
+
return { etd: t, from: j, to: Y, next: a.filter((b) => b), wps: l, days: p };
|
|
788
790
|
}
|
|
789
791
|
/**
|
|
790
792
|
* 洋流影响因子
|
|
@@ -805,16 +807,16 @@ class C {
|
|
|
805
807
|
* @param wwc 气象要素
|
|
806
808
|
*/
|
|
807
809
|
static weatherFactor(s, t) {
|
|
808
|
-
var l, p, f, m,
|
|
809
|
-
|
|
810
|
+
var l, p, f, m, Y, j, b;
|
|
811
|
+
D == null || D.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
810
812
|
const i = C.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), o = C.froudeNumber(s.speed, s.lbp), n = C.amendFactor(i, o, s.loadCondition);
|
|
811
813
|
let a = Math.abs(s.bearing % 360 - (((l = t == null ? void 0 : t.wind) == null ? void 0 : l.degree) % 360 || 0));
|
|
812
814
|
a = a > 180 ? 360 - a : a;
|
|
813
815
|
const e = C.directionFactor(a, (p = t == null ? void 0 : t.wind) == null ? void 0 : p.scale), c = C.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (f = t == null ? void 0 : t.wind) == null ? void 0 : f.scale);
|
|
814
816
|
let r = e * n * c / 100 * s.speed;
|
|
815
|
-
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1));
|
|
816
|
-
const d = C.waveHeightFactor(((
|
|
817
|
-
return r = r + d,
|
|
817
|
+
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), D == null || D.debug("wind wx factor = %d", r), a = Math.abs(s.bearing % 360 - (((Y = (m = t == null ? void 0 : t.wave) == null ? void 0 : m.sig) == null ? void 0 : Y.degree) % 360 || 0));
|
|
818
|
+
const d = C.waveHeightFactor(((b = (j = t == null ? void 0 : t.wave) == null ? void 0 : j.sig) == null ? void 0 : b.height) ?? 1, a);
|
|
819
|
+
return D == null || D.debug("wave wx factor = %d", d), r = r + d, D == null || D.debug("weather factor = %d", r), r = Math.abs(r) > 5 ? 5 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 5) * 0.4 : r, Math.round(r * 100) / 100;
|
|
818
820
|
}
|
|
819
821
|
/**
|
|
820
822
|
* 全程失速分析(走完航程)
|
|
@@ -830,12 +832,12 @@ class C {
|
|
|
830
832
|
*/
|
|
831
833
|
static async analyseInstant(s, t, i, o, n, a = "", e = 0, c = !0, r = !1, d = {}) {
|
|
832
834
|
var E, G, U, J, Q;
|
|
833
|
-
const l =
|
|
835
|
+
const l = v().valueOf();
|
|
834
836
|
s.lng = B.convertToStdLng(s.lng);
|
|
835
837
|
const { route: p, waypoints: f } = n.points, m = V.calculateSubRoute(s, p);
|
|
836
838
|
if (((E = m[0]) == null ? void 0 : E.length) <= 1)
|
|
837
839
|
return;
|
|
838
|
-
const { v0:
|
|
840
|
+
const { v0: Y, label: j } = s.sog ? {
|
|
839
841
|
v0: s.sog,
|
|
840
842
|
label: "Other"
|
|
841
843
|
/* Instruct */
|
|
@@ -843,46 +845,46 @@ class C {
|
|
|
843
845
|
v0: o.speed,
|
|
844
846
|
label: "CP"
|
|
845
847
|
/* Cp */
|
|
846
|
-
},
|
|
848
|
+
}, b = C.assembleProperties(i, o.loadCondition, Y, 0), M = f.length ? V.calculateSubWaypoints(s, f) : [];
|
|
847
849
|
M.forEach((H) => H.important = !0);
|
|
848
850
|
const h = {
|
|
849
851
|
from: { ...s },
|
|
850
852
|
route: m,
|
|
851
853
|
waypoints: M,
|
|
852
|
-
v0:
|
|
853
|
-
label:
|
|
854
|
+
v0: Y,
|
|
855
|
+
label: j
|
|
854
856
|
}, k = {
|
|
855
857
|
hours: [],
|
|
856
858
|
days: [],
|
|
857
859
|
wps: []
|
|
858
860
|
};
|
|
859
861
|
e || (V.calculateRouteDistance(m) / o.speed <= 72 ? e = 3 : e = 6);
|
|
860
|
-
let
|
|
861
|
-
t =
|
|
862
|
+
let w = V.simplifyRouteToCoordinates(m, M, 0), y = 0, g = 0, N = 0, F = 0;
|
|
863
|
+
t = v(t).utc();
|
|
862
864
|
const W = t.clone();
|
|
863
|
-
for (;
|
|
865
|
+
for (; w.length > 0; ) {
|
|
864
866
|
const H = e - t.hour() % e, _ = Math.ceil(t.clone().add(H, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, q = await C.speedLoseInHoursStep(
|
|
865
|
-
|
|
867
|
+
b,
|
|
866
868
|
t,
|
|
867
869
|
W,
|
|
868
870
|
_,
|
|
869
871
|
y,
|
|
870
|
-
|
|
872
|
+
w,
|
|
871
873
|
a,
|
|
872
874
|
c,
|
|
873
875
|
r,
|
|
874
876
|
d
|
|
875
877
|
);
|
|
876
|
-
(G = q.from) != null && G.speed && (k.hours.push(q.from), k.wps.push(...q.wps), k.days.push(...q.days)),
|
|
878
|
+
(G = q.from) != null && G.speed && (k.hours.push(q.from), k.wps.push(...q.wps), k.days.push(...q.days)), w = q == null ? void 0 : q.next, w.length || k.hours.push(q == null ? void 0 : q.to), y += ((U = q == null ? void 0 : q.to) == null ? void 0 : U.distanceFromPrevious) ?? 0;
|
|
877
879
|
}
|
|
878
880
|
const T = k.hours;
|
|
879
881
|
for (let H = 0; H < T.length - 1; H++) {
|
|
880
|
-
const _ =
|
|
882
|
+
const _ = v(T[H + 1].eta).diff(T[H].etd, "hour", !0) || 1;
|
|
881
883
|
g += (T[H].wxFactor || 0) * _, N += (T[H].cFactor || 0) * _, F += _;
|
|
882
884
|
}
|
|
883
885
|
(J = k.wps) == null || J.forEach((H, _) => {
|
|
884
886
|
if (_) {
|
|
885
|
-
const q = k.wps[_ - 1], tt = H.distanceFromStart - q.distanceFromStart, X =
|
|
887
|
+
const q = k.wps[_ - 1], tt = H.distanceFromStart - q.distanceFromStart, X = v(H.eta).diff(v(q.etd), "h", !0);
|
|
886
888
|
if (X < 1)
|
|
887
889
|
H.avgSpd = q.speed;
|
|
888
890
|
else {
|
|
@@ -893,9 +895,9 @@ class C {
|
|
|
893
895
|
}
|
|
894
896
|
}), h.sample = k;
|
|
895
897
|
const L = k.hours.at(0), A = k.hours.at(-1);
|
|
896
|
-
h.distance = Math.round(A.distanceFromStart * 1e4) / 1e4, h.etd =
|
|
897
|
-
const P =
|
|
898
|
-
return
|
|
898
|
+
h.distance = Math.round(A.distanceFromStart * 1e4) / 1e4, h.etd = v(L.eta).utc().format(), h.eta = v(A.eta).utc().format(), h.wxFactor = Math.round(g / F * 1e4) / 1e4, h.cFactor = Math.round(N / F * 1e4) / 1e4, h.avgSpeed = Math.round(A.distanceFromStart / F * 1e4) / 1e4, h.totalHrs = Math.round(F * 1e4) / 1e4, h.totalFoCons = Math.round((o == null ? void 0 : o.fo) / 24 * h.totalHrs * 1e3) / 1e3, h.totalDgoCons = Math.round((o == null ? void 0 : o.dgo) / 24 * h.totalHrs * 1e3) / 1e3;
|
|
899
|
+
const P = v().valueOf() - l, x = ((Q = k == null ? void 0 : k.hours) == null ? void 0 : Q.length) || 1;
|
|
900
|
+
return D == null || D.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", d == null ? void 0 : d.requestId, P, x, Math.round(P / x * 1e3) / 1e3), h;
|
|
899
901
|
}
|
|
900
902
|
/**
|
|
901
903
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -921,23 +923,23 @@ class C {
|
|
|
921
923
|
v0: n.speed,
|
|
922
924
|
label: "CP"
|
|
923
925
|
/* Cp */
|
|
924
|
-
},
|
|
925
|
-
if (((A =
|
|
926
|
+
}, Y = C.assembleProperties(o, n.loadCondition, f, 0), j = V.calculateSubRoute(s, a);
|
|
927
|
+
if (((A = j[0]) == null ? void 0 : A.length) <= 1)
|
|
926
928
|
return;
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
let M = V.simplifyRouteToCoordinates(
|
|
929
|
+
const b = e.length ? V.calculateSubWaypoints(s, e) : [];
|
|
930
|
+
b.forEach((x) => x.important = !0);
|
|
931
|
+
let M = V.simplifyRouteToCoordinates(j, b, 0), h = 0, k = 0, w = 0, y = 0, g;
|
|
930
932
|
const N = {
|
|
931
933
|
hours: [],
|
|
932
934
|
wps: [],
|
|
933
935
|
days: []
|
|
934
936
|
};
|
|
935
|
-
for (t =
|
|
936
|
-
const
|
|
937
|
-
let E = Math.ceil(t.clone().add(
|
|
937
|
+
for (t = v(t).utc(); M.length > 0; ) {
|
|
938
|
+
const x = r - t.hour() % r;
|
|
939
|
+
let E = Math.ceil(t.clone().add(x, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
938
940
|
if (E = t.clone().add(E, "h").isAfter(i) ? i.diff(t, "h", !0) * 1e4 / 1e4 : E, E)
|
|
939
941
|
g = await C.speedLoseInHoursStep(
|
|
940
|
-
|
|
942
|
+
Y,
|
|
941
943
|
t,
|
|
942
944
|
i.clone(),
|
|
943
945
|
E,
|
|
@@ -954,25 +956,25 @@ class C {
|
|
|
954
956
|
}
|
|
955
957
|
}
|
|
956
958
|
const F = N.hours;
|
|
957
|
-
for (let
|
|
958
|
-
const E =
|
|
959
|
-
k += F[
|
|
959
|
+
for (let x = 0; x < F.length - 1; x++) {
|
|
960
|
+
const E = v(F[x + 1].eta).diff(F[x].etd, "hour", !0);
|
|
961
|
+
k += F[x].wxFactor * E, w += F[x].cFactor * E, y += E;
|
|
960
962
|
}
|
|
961
963
|
const W = N.hours.at(0), T = N.hours.at(-1);
|
|
962
964
|
return {
|
|
963
965
|
sample: N,
|
|
964
966
|
distance: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
965
967
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
966
|
-
etd:
|
|
967
|
-
eta:
|
|
968
|
+
etd: v(W.eta).utc().format(),
|
|
969
|
+
eta: v(T == null ? void 0 : T.eta).utc().format(),
|
|
968
970
|
wxFactor: Math.round(k / y * 1e4) / 1e4,
|
|
969
|
-
cFactor: Math.round(
|
|
971
|
+
cFactor: Math.round(w / y * 1e4) / 1e4,
|
|
970
972
|
avgSpeed: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) / y * 1e4) / 1e4,
|
|
971
973
|
totalHrs: Math.round(y * 1e4) / 1e4,
|
|
972
974
|
from: s,
|
|
973
975
|
to: T,
|
|
974
|
-
route:
|
|
975
|
-
waypoints:
|
|
976
|
+
route: j,
|
|
977
|
+
waypoints: b,
|
|
976
978
|
v0: f,
|
|
977
979
|
label: m
|
|
978
980
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(w,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo","@idm-plugin/meteo"],D):(w=typeof globalThis<"u"?globalThis:w||self,D(w["idm-plugin-rabbitmq"]={},w.got,w["@log4js-node/log4js-api"],w.moment,w["@idm-plugin/geo"],w["@idm-plugin/meteo"]))})(this,function(w,D,Z,g,O,ot){"use strict";var lt=Object.defineProperty;var ft=(w,D,Z)=>D in w?lt(w,D,{enumerable:!0,configurable:!0,writable:!0,value:Z}):w[D]=Z;var K=(w,D,Z)=>(ft(w,typeof D!="symbol"?D+"":D,Z),Z);let u;try{u=Z.getLogger("vessel")}catch{}finally{}class z{parseStatus(s){let t,i;switch(s){case 0:t="在航(主机推动)",i="The engine is in use";break;case 1:t="锚泊",i="Anchored";break;case 2:t="失控",i="Not operated";break;case 3:t="操纵受限",i="Limited airworthiness";break;case 4:t="吃水受限",i="Limited by ship's draft";break;case 5:t="靠泊",i="Mooring";break;case 6:t="搁浅",i="Stranded";break;case 7:t="捕捞作业",i="Engaged in fishing";break;case 8:t="靠帆船提供动力",i="Sailing";break;default:t="未定义",i="Undefined"}return{labelCn:t,labelEn:i}}}class it extends z{constructor(t,i){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",n={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await D.post(i,n).json();u==null||u.info("[%s] fetch access token from: %s - %j",t.requestId,i,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:g().utc().format()})}async realTimePosition(t,i={}){var d,l,p;(!this.token||g().diff(g(this.token.issuedAt),"seconds")>((d=this.token)==null?void 0:d.expiresIn)-300)&&await this.authToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(p=this.token)==null?void 0:p.accessToken}`},searchParams:{mmsi:t}};u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const a=await D.get(n,o).json();if(a.code)return u==null||u.warn("[%s] fetch realtime position failed: %j",i.requestId,n,{message:a.message,status:a.status,code:a.code}),a;const e=a.data;for(const f in e)!isNaN(e[f])&&Number(e[f])!==1/0&&(e[f]=Number(e[f]));const c=g(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName,imo:e.imo,callSign:e.callsign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:e.eta,destination:e.dest,positionTime:c.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,method:"position",vendor:"myVessel",utc:c.utc().format()}}async trajectory(t,i,n,o,a=!0,e={}){(!this.token||g().diff(g(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const c=await this.realTimePosition(t,e),r=g(i),d=g(n),l=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),c,o,l,e),r.add(30,"day");return await this.trajectoryIn30Day(t,r,d,c,o,l,e),l}async trajectoryIn30Day(t,i,n,o,a,e,c={}){var m,v,k,Y,M;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",d={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(v=this.token)==null?void 0:v.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};u==null||u.info("[%s] fetch trajectory from: %s - %j",c.requestId,r,d);const l=await D.post(r,d).json();if(l.code)return u==null||u.warn("[%s] fetch trajectory failed: %j",c.requestId,r,{message:l.message,status:l.status,code:l.code}),l;let p=-1;const f=g(`${(Y=(k=l.data)==null?void 0:k[0])==null?void 0:Y.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(M=l.data)==null||M.forEach(h=>{for(const S in h)!isNaN(h[S])&&Number(h[S])!==1/0&&(h[S]=Number(h[S]));const I=g(`${h.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),H=h.eta?g(`${h.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,y=h.status,{labelCn:b,labelEn:F}=this.parseStatus(y),E={mmsi:h.mmsi,imo:o==null?void 0:o.imo,lat:h.lat,lng:h.lon,sog:h.sog,cog:h.cog,hdg:h.hdg,draught:h.draught,status:y,eta:H==null?void 0:H.unix(),destination:h.dest,positionTime:I.unix(),labelCn:b,labelEn:F,method:"trajectory",vendor:"myVessel",utc:I.utc().format()},V=Math.floor(I.diff(f,"minute",!0)/(a||1));V!==p&&(p=V,e.push(E))}),e}}class rt extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:t,usertoken:this.token}},a=await D.post(n,o).json();u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const e=a==null?void 0:a.list;if(!e)return u==null||u.warn("[%s] fetch realtime position failed: %j",i.requestId,n,a),a;for(const f in e)!isNaN(e[f])&&Number(e[f])!==1/0&&(e[f]=Number(e[f]));e.status=e.sp>3?0:1;const c=e.status,{labelCn:r,labelEn:d}=this.parseStatus(c),l=g(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?g(`${e.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:e.destination,positionTime:l.unix(),utc:l.utc().format(),status:c,labelCn:r,labelEn:d,method:"position",vendor:"hifleet"}}async search(t,i={}){let n="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await D.post(n,o).json();u==null||u.info("[%s] fetch vessel props from: %s - %j",i.requestId,n,o),a instanceof Array&&(a=a[0]);for(const c in a)!isNaN(a[c])&&Number(a[c])!==1/0&&(a[c]=Number(a[c]));const e={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr};return n="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await D.post(n,o).json(),u==null||u.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,n,o),a instanceof Array&&(a=a[0]),a&&(e.deadweight=Number(a.dwt)),e}async trajectory(t,i,n,o,a=!0,e={}){var h,I,H;const c=await this.realTimePosition(t,e);let r=g(i);const d=g(n),l=g();if(a){let y=d.diff(r,"d",!0);y<0?r=d.clone().subtract(40,"d"):y<30?r.subtract(10,"d"):y<60?r.subtract(5,"d"):r=d.clone().subtract(80,"d"),y=l.diff(d,"d",!0),d.add(y>10?240:y*24,"h")}const p={searchParams:{endtime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},f="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",m=await D.get(f,p).json();u==null||u.info("[%s] fetch trajectory from: %s - %j",e.requestId,f,p);let v;m&&(v=((I=(h=m.ships)==null?void 0:h.offors)==null?void 0:I.ship)||[],v.length||u==null||u.warn("[%s] fetch trajectory failed: %j",e.requestId,m));const k=[];let Y=-1;const M=g(`${(H=v==null?void 0:v[0])==null?void 0:H.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of v){for(const _ in y)!isNaN(y[_])&&Number(y[_])!==1/0&&(y[_]=Number(y[_]));const b=g(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:F,labelCn:E}=this.parseStatus(y.status),V={mmsi:y.m,name:y.n,imo:c==null?void 0:c.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:b.unix(),utc:b.utc().format(),status:y.status,labelCn:E,labelEn:F,method:"trajectory",vendor:"hifleet"},S=Math.floor(b.diff(M,"minute",!0)/(o||1));S!==Y&&(Y=S,k.push(V))}return k}}class ct extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n={searchParams:{id:t,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",a=await D.get(o,n).json();if(u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n),(a==null?void 0:a.status)!==0)return a;const e=a.data[0];for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const{labelCn:c,labelEn:r}=await this.parseStatus(e.navistat),d=g.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:d.utc().format(),status:e.navistat,labelEn:r,labelCn:c,method:"position",vendor:"shipxy"}}async trajectory(t,i,n,o,a=!0,e={}){var M;const c=await this.realTimePosition(t,e),r=g(i),d=g(n),l="https://api.shipxy.com/apicall/GetShipTrack",p={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:d.unix()}},f=await D.get(l,p).json();if(u==null||u.info("[%s] fetch trajectory from: %s - %j",e.requestId,l,p),(f==null?void 0:f.status)!==0)return f;const m=f==null?void 0:f.points,v=[],k=g.unix((M=m[0])==null?void 0:M.utc);let Y=-1;for(const h of m){const I=g.unix(h.utc),H={imo:c==null?void 0:c.imo,mmsi:t,sog:Math.round(h.sog*3600/1e3/1852*100)/100,cog:Math.round(h.cog/100*100)/100,lat:Math.round(h.lat/1e6*1e5)/1e5,lng:Math.round(h.lon/1e6*1e5)/1e5,positionTime:I.unix(),utc:I.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(I.diff(k,"minute",!0)/(o||1));y!==Y&&(Y=y,v.push(H))}return v}}class dt extends z{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,i={}){const n={headers:{appKey:this.token},json:{mmsiList:t}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await D.post(o,n).json();return u==null||u.info("[%s] fetch ship id from: %s - %j",i.requestId,o,n),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,i={}){const n={headers:{appKey:this.token},json:{shipId:t}},o="https://api3.myships.com/sp/ships/aissta",a=await D.post(o,n).json();if(u==null||u.info("[%s] fetch ship info from: %s - %j",i.requestId,o,n),a.code!=="0")return a;const e=a.data;let c=e.imo;return t==="407170"&&(c="9198379",u==null||u.warn("[%s] ship(%s) imo error: %s, should be %s",i.requestId,t,e.imo,c)),{mmsi:e.mmsi,name:e.shipnameEn,imo:c,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,i={}){const n=await this.getShipId(t,i),o=await this.getShipInfo(n,i),a={headers:{appKey:this.token},json:{shipId:n}},e="https://api3.myships.com/sp/ships/position/latest",c=await D.post(e,a).json();u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,a);const r=c.data[0];for(const m in r)!isNaN(r[m])&&Number(r[m])!==1/0&&(r[m]=Number(r[m]));const{labelCn:d,labelEn:l}=await this.parseStatus(r.aisNavStatus),p=g.unix(r.posTime);return{...o,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:p.utc().format(),status:r.aisNavStatus,labelEn:l,labelCn:d,method:"position",vendor:"myship"}}async trajectory(t,i,n,o,a=!0,e={}){const c=g(i),r=g(n),d=await this.getShipId(t),l=await this.getShipInfo(d),p=[];for(;r.diff(c,"day",!0)>30;)await this.trajectoryIn30Day(d,c.unix(),c.add(30,"day").unix(),l,t,o,p);return await this.trajectoryIn30Day(d,c.unix(),r.unix(),l,t,o,p),p}async trajectoryIn30Day(t,i,n,o,a,e,c,r={}){var k;const d={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:n}},l="https://api3.myships.com/sp/ships/position/history",p=await D.post(l,d).json();if(u==null||u.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,d),p.code!=="0")return u==null||u.warn("[%s] invoke myship trajectory failed: %j",r.requestId,p),p;const f=p.data;for(const Y in f)!isNaN(f[Y])&&Number(f[Y])!==1/0&&(f[Y]=Number(f[Y]));const m=g.unix((k=f[0])==null?void 0:k.posTime);let v=-1;for(const Y of f){const M=g.unix(Y.posTime),h={imo:o==null?void 0:o.imo,mmsi:a,lat:Math.round(Y.lat/1e4/60*1e5)/1e5,lng:Math.round(Y.lon/1e4/60*1e5)/1e5,sog:Math.round(Y.sog/10*100)/100,cog:Math.round(Y.cog/10*100)/100,hdg:Math.round(Y.heading*100)/100,rot:Math.round(Y.rot*100)/100,positionTime:M.unix(),utc:M.utc().format(),method:"trajectory",vendor:"myship"},I=Math.floor(M.diff(m,"minute",!0)/(e||1));I!==v&&(v=I,c.push(h))}return c}}let R;try{R=Z.getLogger("vessel")}catch{}finally{}var G=(j=>(j.NOTICE="NOTICE",j.WARN="WARN",j.HEAVY="HEAVY",j.SEVERE="SEVERE",j.ERROR="ERROR",j.FATAL="FATAL",j))(G||{});class U{parsePrinciple(s,t={}){var e,c,r;R==null||R.info("[%s] parse rule: %s",t.requestId,s);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),n=s.match(i)?(e=s.match(i))==null?void 0:e[0]:void 0,o=n==null?void 0:n.split(";");if(!o)return;const a={};for(let d=0;d<(o==null?void 0:o.length);d++){const l=(r=(c=o[d].match(i))==null?void 0:c[0])==null?void 0:r.split("],");if(d===0&&!l)a.scope=o[0];else if(l)for(let p=0,f=l.length;p<f;p++){const m=this.parseRule(l[p]);m&&(a[m.level]?m.key?a[m.level][m==null?void 0:m.key]=m:a[m.level]=m:m.key?a[m.level]={[m==null?void 0:m.key]:m}:a[m.level]=m)}}return a}parseRule(s,t={}){var a;R==null||R.info("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),n=(a=s==null?void 0:s.match(i))==null?void 0:a[0],o=n==null?void 0:n.split(",");if(o)return{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:Number(o[3]),key:o[4]}}checkWeather(s,t,i={}){var m,v,k,Y,M,h,I,H,y,b,F,E,V,S,_;let n=0,o=0,a=0,e=0;const c=Math.round(((v=(m=t==null?void 0:t.SEVERE)==null?void 0:m.sigWave)==null?void 0:v.number)*1.6*100)/100,r=(Y=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:Y.number,d=(h=(M=t==null?void 0:t.HEAVY)==null?void 0:M.sigWave)==null?void 0:h.number,l=Math.round((((H=(I=t==null?void 0:t.SEVERE)==null?void 0:I.wind)==null?void 0:H.number)+2)*100)/100,p=(b=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:b.number,f=(E=(F=t==null?void 0:t.HEAVY)==null?void 0:F.wind)==null?void 0:E.number;for(let W=0;W<(s==null?void 0:s.length);W++){const T=s[W],C=(S=(V=T==null?void 0:T.meteo)==null?void 0:V.wave)==null?void 0:S.sig,N=(_=T==null?void 0:T.meteo)==null?void 0:_.wind,P=W?g(T.eta).diff(g(s[W-1].eta),"hour",!0):0;e=P>e?P:e,R==null||R.info("[%s] check sig.wave: %j",i.requestId,{...C,dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:d}),(C==null?void 0:C.height)>=c?T.isDangerous=!0:(C==null?void 0:C.height)>=r?T.isSevere=!0:(C==null?void 0:C.height)>=d&&(T.isHeavy=!0),R==null||R.info("[%s] check wind: %j",i.requestId,{...N,dgThd4Wd:l,svThd4Wd:p,hvThd4Wd:f}),(N==null?void 0:N.scale)>=l?(T.isDangerous=!0,delete T.isSevere,delete T.isHeavy):(N==null?void 0:N.scale)>p?(T.isDangerous||(T.isSevere=!0),delete T.isHeavy):(N==null?void 0:N.scale)===f&&!T.isDangerous&&!T.isSevere&&(T.isHeavy=!0),n+=T.isDangerous?P:0,o+=T.isSevere?P:0,a+=T.isHeavy?P:0}return n=Math.round(n*100)/100,o=Math.round(o*100)/100,a=Math.round(a*100)/100,e=Math.round(e),{sample:s,dangerous:n,severe:o,heavy:a,step:e<3?3:e,wind:{dgThd4Wd:l,svThd4Wd:p,hvThd4Wd:f},sig:{dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:d}}}}const ut=new U;let x;try{x=Z.getLogger("vessel")}catch{}finally{}var J=(j=>(j.common="common",j.container="container",j.tugs="tugs",j))(J||{}),Q=(j=>(j.Ballast="Ballast",j.Laden="Laden",j))(Q||{}),X=(j=>(j.Cp="CP",j.Perf="Basis",j.Instruct="Other",j))(X||{});class A{static blockCoefficient(s,t,i,n){let o=Math.round(s/(t*i*n)*100)/100;o=o<.55?.55:o>.85?.85:o;const a=[.55,.6,.65,.7,.75,.8,.85],e=a.map(c=>Math.abs(c-o));return a[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,i=9.8){let n=Math.round(Math.sqrt(s*s/(i*t))*100)/100;return n=n<.05?.05:n>.3?.3:n,n}static amendFactor(s,t,i){const n={.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 a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return i==="Laden"&&(a=n[s]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(s,t=0){let i;return s>30&&s<=60?i=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?i=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?i=(.4-.03*Math.pow(t-8,2))/2:i=1,Math.round(i*1e5)/1e5}static vesselTagFactor(s,t,i,n=0){n=n>6?n-.9*(n-6):n;let o;return i==="container"?o=.7*n+Math.pow(n,6.5)/(22*Math.pow(s,2/3)):t==="Ballast"?o=.7*n+Math.pow(n,6.5)/(2.7*Math.pow(s,2/3)):o=.5*n+Math.pow(n,6.5)/(2.7*Math.pow(s,2/3)),o}static waveHeightFactor(s){return s=s<1.25?1.25:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s,Math.round((-.144*Math.pow(s,2)+.178*s)*1e4)/1e4}static assembleProperties(s,t,i,n){var p;const o=s.lbp??s.length??s.lengthOverall??198.9642,a=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,c=s.deadweight??67035.7773,r=((p=s==null?void 0:s.type)==null?void 0:p.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:o,loadCondition:t,draught:a,breadthMoulded:e,displacement:Math.round((c/1.025+a*e*o*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:n||90}}static async speedLoseAt(s,t,i,n="",o=2,a=!0,e=!1,c={}){let r;if(t.velocity&&e&&(s.speed=O.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){const d=await ot.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",n,c),l=A.weatherFactor(s,d),p=A.currentFactor(s.bearing,d==null?void 0:d.current,o),f=Math.round((s.speed*1.943844+l+p)*100)/100;r={meteo:{...d},wxFactor:l,cFactor:p,speed:t.velocity&&e?t.velocity:f<0?1:f,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round((s.speed*1.943844+0+0)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(s,t,i,n,o,a,e="",c=!0,r=!1,d={}){t.utc();const l=[],p=[];let f=0,m=0,v,k;for(let Y=0;Y<a.length-1;Y++){let M=a[Y];M.distanceFromStart=o+m;const h=a[Y+1];if(s.bearing=O.LaneHelper.calculateBearing(M,h,!h.gcToPrevious),M.bearing=s.bearing,M.suspend&&r){M.eta=M.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),M.elapsed=M.elapsed??0;const y=M.suspend-M.elapsed;if(n-f>y)n=n-f-y,t.add(y,"hour"),M.elapsed=M.suspend;else{const b=n-f;M.elapsed+=b,t.add(b,"hour"),n=0}if(x==null||x.info(`[%s] suspend ${M.elapsed} hours at %j, and remain ${n} hours need to go...`,d.requestId,M),n===0)return M.distanceFromPrevious=m,{etd:t,from:k||M,to:M,next:a.filter(b=>b),wps:l,days:p}}M=await A.speedLoseAt(s,M,t,e,0,c,r,d),k=k||M,M.important&&l.push(M),t.isSameOrAfter(i)&&(p.push(M),i.add(24,"hour"));const I=O.LaneHelper.calculateDistance(M,h,!h.gcToPrevious);let H=Math.ceil(I/k.speed*1e4)/1e4;if(f+H<n){if(f+=H,t.add(H,"hour"),delete a[Y],x==null||x.info(`[%s] go to %j from %j with ${I}nm, and cost ${H} hours`,d.requestId,{lat:h.lat,lng:h.lng},{lat:k.lat,lng:k.lng,etd:k.etd}),m+=I,a.filter(y=>y).length<=1){v=h,v.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),v.distanceFromPrevious=I,v.distanceFromStart=o+m,l.push(v),delete a[Y+1];break}}else{H=n-f,t.add(H,"hour");const y=O.LngLatHelper.roundPrecision(k.speed*H,4);v=O.LaneHelper.calculateCoordinate(M,s.bearing,y,"nauticalmiles",!h.gcToPrevious),v.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),a[Y]=v,x==null||x.info(`[%s] go to %j from %j with ${y}nm, and cost ${H} hours`,d.requestId,{lat:v.lat,lng:v.lng},{lat:M.lat,lng:M.lng,etd:M.etd}),m+=y,v.distanceFromPrevious=m,v.distanceFromStart=o+m;break}}return{etd:t,from:k,to:v,next:a.filter(Y=>Y),wps:l,days:p}}static currentFactor(s,t,i=0){const n=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(n)===Math.PI/2)return 0;let o=((t==null?void 0:t.kts)||0)*Math.cos(n);return i&2?o=Math.ceil(o*100)/100:i&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(s,t){var l,p,f,m,v;x==null||x.debug("calculate weather factor via: %j",{...s,...t});const i=A.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=A.froudeNumber(s.speed,s.lbp),o=A.amendFactor(i,n,s.loadCondition);let a=Math.abs(s.bearing%360-(((l=t==null?void 0:t.wind)==null?void 0:l.degree)%360||0));a=a>180?360-a:a;const e=A.directionFactor(a,(p=t==null?void 0:t.wind)==null?void 0:p.scale),c=A.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(f=t==null?void 0:t.wind)==null?void 0:f.scale);let r=e*o*c/100*s.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1));const d=A.waveHeightFactor(((v=(m=t==null?void 0:t.wave)==null?void 0:m.sig)==null?void 0:v.height)??1);return r=r+d,x==null||x.debug("weather factor = %s",r),r=Math.abs(r)>5?5*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-5)*.4:r,Math.round(r*100)/100}static async analyseInstant(s,t,i,n,o,a="",e=0,c=!0,r=!1,d={}){var P,$,tt,et,st;const l=g().valueOf();s.lng=O.LngLatHelper.convertToStdLng(s.lng);const{route:p,waypoints:f}=o.points,m=O.LaneHelper.calculateSubRoute(s,p);if(((P=m[0])==null?void 0:P.length)<=1)return;const{v0:v,label:k}=s.sog?{v0:s.sog,label:"Other"}:{v0:n.speed,label:"CP"},Y=A.assembleProperties(i,n.loadCondition,v,0),M=f.length?O.LaneHelper.calculateSubWaypoints(s,f):[];M.forEach(q=>q.important=!0);const h={from:{...s},route:m,waypoints:M,v0:v,label:k},I={hours:[],days:[],wps:[]};e||(O.LaneHelper.calculateRouteDistance(m)/n.speed<=72?e=3:e=6);let H=O.LaneHelper.simplifyRouteToCoordinates(m,M,0),y=0,b=0,F=0,E=0;t=g(t).utc();const V=t.clone();for(;H.length>0;){const q=e-t.hour()%e,B=Math.ceil(t.clone().add(q,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,L=await A.speedLoseInHoursStep(Y,t,V,B,y,H,a,c,r,d);($=L.from)!=null&&$.speed&&(I.hours.push(L.from),I.wps.push(...L.wps),I.days.push(...L.days)),H=L==null?void 0:L.next,H.length||I.hours.push(L==null?void 0:L.to),y+=((tt=L==null?void 0:L.to)==null?void 0:tt.distanceFromPrevious)??0}const S=I.hours;for(let q=0;q<S.length-1;q++){const B=g(S[q+1].eta).diff(S[q].etd,"hour",!0)||1;b+=(S[q].wxFactor||0)*B,F+=(S[q].cFactor||0)*B,E+=B}(et=I.wps)==null||et.forEach((q,B)=>{if(B){const L=I.wps[B-1],ht=q.distanceFromStart-L.distanceFromStart,at=g(q.eta).diff(g(L.etd),"h",!0);if(at<1)q.avgSpd=L.speed;else{q.avgSpd=Math.round(ht/at*100)/100;const nt=Math.round((L.speed+q.speed)/2*100)/100;q.avgSpd=q.avgSpd>nt?nt:q.avgSpd}}}),h.sample=I;const _=I.hours.at(0),W=I.hours.at(-1);h.distance=Math.round(W.distanceFromStart*1e4)/1e4,h.etd=g(_.eta).utc().format(),h.eta=g(W.eta).utc().format(),h.wxFactor=Math.round(b/E*1e4)/1e4,h.cFactor=Math.round(F/E*1e4)/1e4,h.avgSpeed=Math.round(W.distanceFromStart/E*1e4)/1e4,h.totalHrs=Math.round(E*1e4)/1e4,h.totalFoCons=Math.round((n==null?void 0:n.fo)/24*h.totalHrs*1e3)/1e3,h.totalDgoCons=Math.round((n==null?void 0:n.dgo)/24*h.totalHrs*1e3)/1e3;const C=g().valueOf()-l,N=((st=I==null?void 0:I.hours)==null?void 0:st.length)||1;return x==null||x.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",d==null?void 0:d.requestId,C,N,Math.round(C/N*1e3)/1e3),h}static async analyseInstantWithThreshed(s,t,i,n,o,a,e,c="",r=3,d=!0,l=!1,p={}){var W,T,C;s.lng=O.LngLatHelper.convertToStdLng(s.lng);const{v0:f,label:m}=s.sog?{v0:s.sog,label:"Other"}:{v0:o.speed,label:"CP"},v=A.assembleProperties(n,o.loadCondition,f,0),k=O.LaneHelper.calculateSubRoute(s,a);if(((W=k[0])==null?void 0:W.length)<=1)return;const Y=e.length?O.LaneHelper.calculateSubWaypoints(s,e):[];Y.forEach(N=>N.important=!0);let M=O.LaneHelper.simplifyRouteToCoordinates(k,Y,0),h=0,I=0,H=0,y=0,b;const F={hours:[],wps:[],days:[]};for(t=g(t).utc();M.length>0;){const N=r-t.hour()%r;let P=Math.ceil(t.clone().add(N,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(P=t.clone().add(P,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:P,P)b=await A.speedLoseInHoursStep(v,t,i.clone(),P,h,M,c,d,l,p),(T=b.from)!=null&&T.speed&&(F.hours.push(b.from),b!=null&&b.wps&&F.wps.push(...b.wps),F.days.push(...b.days)),M=b==null?void 0:b.next,M.length||(F.hours.push(b==null?void 0:b.to),b!=null&&b.wps&&F.wps.push(...b.wps),F.days.push(b==null?void 0:b.to)),h+=((C=b==null?void 0:b.to)==null?void 0:C.distanceFromPrevious)??0;else{b&&(F.hours.push(b.to),b!=null&&b.wps&&F.wps.push(...b.wps),F.days.push(b.to));break}}const E=F.hours;for(let N=0;N<E.length-1;N++){const P=g(E[N+1].eta).diff(E[N].etd,"hour",!0);I+=E[N].wxFactor*P,H+=E[N].cFactor*P,y+=P}const V=F.hours.at(0),S=F.hours.at(-1);return{sample:F,distance:Math.round(((S==null?void 0:S.distanceFromStart)||0)*1e4)/1e4,etd:g(V.eta).utc().format(),eta:g(S==null?void 0:S.eta).utc().format(),wxFactor:Math.round(I/y*1e4)/1e4,cFactor:Math.round(H/y*1e4)/1e4,avgSpeed:Math.round(((S==null?void 0:S.distanceFromStart)||0)/y*1e4)/1e4,totalHrs:Math.round(y*1e4)/1e4,from:s,to:S,route:k,waypoints:Y,v0:f,label:m}}}w.AISImpl=z,w.AlertHelper=U,w.AlertLevel=G,w.HifleetImpl=rt,w.LoadCondition=Q,w.MyShipImpl=dt,w.MyVesselImpl=it,w.ShipxyImpl=ct,w.SpeedHelper=A,w.SpeedLabel=X,w.VesselTag=J,w.alertHelper=ut,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(H,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo","@idm-plugin/meteo"],D):(H=typeof globalThis<"u"?globalThis:H||self,D(H["idm-plugin-rabbitmq"]={},H.got,H["@log4js-node/log4js-api"],H.moment,H["@idm-plugin/geo"],H["@idm-plugin/meteo"]))})(this,function(H,D,Z,g,O,ot){"use strict";var lt=Object.defineProperty;var ft=(H,D,Z)=>D in H?lt(H,D,{enumerable:!0,configurable:!0,writable:!0,value:Z}):H[D]=Z;var K=(H,D,Z)=>(ft(H,typeof D!="symbol"?D+"":D,Z),Z);let u;try{u=Z.getLogger("vessel")}catch{}finally{}class z{parseStatus(s){let t,i;switch(s){case 0:t="在航(主机推动)",i="The engine is in use";break;case 1:t="锚泊",i="Anchored";break;case 2:t="失控",i="Not operated";break;case 3:t="操纵受限",i="Limited airworthiness";break;case 4:t="吃水受限",i="Limited by ship's draft";break;case 5:t="靠泊",i="Mooring";break;case 6:t="搁浅",i="Stranded";break;case 7:t="捕捞作业",i="Engaged in fishing";break;case 8:t="靠帆船提供动力",i="Sailing";break;default:t="未定义",i="Undefined"}return{labelCn:t,labelEn:i}}}class it extends z{constructor(t,i){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",n={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await D.post(i,n).json();u==null||u.info("[%s] fetch access token from: %s - %j",t.requestId,i,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:g().utc().format()})}async realTimePosition(t,i={}){var d,l,p;(!this.token||g().diff(g(this.token.issuedAt),"seconds")>((d=this.token)==null?void 0:d.expiresIn)-300)&&await this.authToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(p=this.token)==null?void 0:p.accessToken}`},searchParams:{mmsi:t}};u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const a=await D.get(n,o).json();if(a.code)return u==null||u.warn("[%s] fetch realtime position failed: %j",i.requestId,n,{message:a.message,status:a.status,code:a.code}),a;const e=a.data;for(const f in e)!isNaN(e[f])&&Number(e[f])!==1/0&&(e[f]=Number(e[f]));const c=g(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName,imo:e.imo,callSign:e.callsign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:e.eta,destination:e.dest,positionTime:c.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,method:"position",vendor:"myVessel",utc:c.utc().format()}}async trajectory(t,i,n,o,a=!0,e={}){(!this.token||g().diff(g(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const c=await this.realTimePosition(t,e),r=g(i),d=g(n),l=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),c,o,l,e),r.add(30,"day");return await this.trajectoryIn30Day(t,r,d,c,o,l,e),l}async trajectoryIn30Day(t,i,n,o,a,e,c={}){var m,Y,j,v,M;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",d={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(Y=this.token)==null?void 0:Y.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};u==null||u.info("[%s] fetch trajectory from: %s - %j",c.requestId,r,d);const l=await D.post(r,d).json();if(l.code)return u==null||u.warn("[%s] fetch trajectory failed: %j",c.requestId,r,{message:l.message,status:l.status,code:l.code}),l;let p=-1;const f=g(`${(v=(j=l.data)==null?void 0:j[0])==null?void 0:v.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(M=l.data)==null||M.forEach(h=>{for(const S in h)!isNaN(h[S])&&Number(h[S])!==1/0&&(h[S]=Number(h[S]));const I=g(`${h.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),w=h.eta?g(`${h.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,y=h.status,{labelCn:b,labelEn:x}=this.parseStatus(y),E={mmsi:h.mmsi,imo:o==null?void 0:o.imo,lat:h.lat,lng:h.lon,sog:h.sog,cog:h.cog,hdg:h.hdg,draught:h.draught,status:y,eta:w==null?void 0:w.unix(),destination:h.dest,positionTime:I.unix(),labelCn:b,labelEn:x,method:"trajectory",vendor:"myVessel",utc:I.utc().format()},V=Math.floor(I.diff(f,"minute",!0)/(a||1));V!==p&&(p=V,e.push(E))}),e}}class rt extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:t,usertoken:this.token}},a=await D.post(n,o).json();u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const e=a==null?void 0:a.list;if(!e)return u==null||u.warn("[%s] fetch realtime position failed: %j",i.requestId,n,a),a;for(const f in e)!isNaN(e[f])&&Number(e[f])!==1/0&&(e[f]=Number(e[f]));e.status=e.sp>3?0:1;const c=e.status,{labelCn:r,labelEn:d}=this.parseStatus(c),l=g(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?g(`${e.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:e.destination,positionTime:l.unix(),utc:l.utc().format(),status:c,labelCn:r,labelEn:d,method:"position",vendor:"hifleet"}}async search(t,i={}){let n="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await D.post(n,o).json();u==null||u.info("[%s] fetch vessel props from: %s - %j",i.requestId,n,o),a instanceof Array&&(a=a[0]);for(const c in a)!isNaN(a[c])&&Number(a[c])!==1/0&&(a[c]=Number(a[c]));const e={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr};return n="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await D.post(n,o).json(),u==null||u.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,n,o),a instanceof Array&&(a=a[0]),a&&(e.deadweight=Number(a.dwt)),e}async trajectory(t,i,n,o,a=!0,e={}){var h,I,w;const c=await this.realTimePosition(t,e);let r=g(i);const d=g(n),l=g();if(a){let y=d.diff(r,"d",!0);y<0?r=d.clone().subtract(40,"d"):y<30?r.subtract(10,"d"):y<60?r.subtract(5,"d"):r=d.clone().subtract(80,"d"),y=l.diff(d,"d",!0),d.add(y>10?240:y*24,"h")}const p={searchParams:{endtime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},f="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",m=await D.get(f,p).json();u==null||u.info("[%s] fetch trajectory from: %s - %j",e.requestId,f,p);let Y;m&&(Y=((I=(h=m.ships)==null?void 0:h.offors)==null?void 0:I.ship)||[],Y.length||u==null||u.warn("[%s] fetch trajectory failed: %j",e.requestId,m));const j=[];let v=-1;const M=g(`${(w=Y==null?void 0:Y[0])==null?void 0:w.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of Y){for(const _ in y)!isNaN(y[_])&&Number(y[_])!==1/0&&(y[_]=Number(y[_]));const b=g(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:x,labelCn:E}=this.parseStatus(y.status),V={mmsi:y.m,name:y.n,imo:c==null?void 0:c.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:b.unix(),utc:b.utc().format(),status:y.status,labelCn:E,labelEn:x,method:"trajectory",vendor:"hifleet"},S=Math.floor(b.diff(M,"minute",!0)/(o||1));S!==v&&(v=S,j.push(V))}return j}}class ct extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n={searchParams:{id:t,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",a=await D.get(o,n).json();if(u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n),(a==null?void 0:a.status)!==0)return a;const e=a.data[0];for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const{labelCn:c,labelEn:r}=await this.parseStatus(e.navistat),d=g.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:d.utc().format(),status:e.navistat,labelEn:r,labelCn:c,method:"position",vendor:"shipxy"}}async trajectory(t,i,n,o,a=!0,e={}){var M;const c=await this.realTimePosition(t,e),r=g(i),d=g(n),l="https://api.shipxy.com/apicall/GetShipTrack",p={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:d.unix()}},f=await D.get(l,p).json();if(u==null||u.info("[%s] fetch trajectory from: %s - %j",e.requestId,l,p),(f==null?void 0:f.status)!==0)return f;const m=f==null?void 0:f.points,Y=[],j=g.unix((M=m[0])==null?void 0:M.utc);let v=-1;for(const h of m){const I=g.unix(h.utc),w={imo:c==null?void 0:c.imo,mmsi:t,sog:Math.round(h.sog*3600/1e3/1852*100)/100,cog:Math.round(h.cog/100*100)/100,lat:Math.round(h.lat/1e6*1e5)/1e5,lng:Math.round(h.lon/1e6*1e5)/1e5,positionTime:I.unix(),utc:I.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(I.diff(j,"minute",!0)/(o||1));y!==v&&(v=y,Y.push(w))}return Y}}class dt extends z{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,i={}){const n={headers:{appKey:this.token},json:{mmsiList:t}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await D.post(o,n).json();return u==null||u.info("[%s] fetch ship id from: %s - %j",i.requestId,o,n),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,i={}){const n={headers:{appKey:this.token},json:{shipId:t}},o="https://api3.myships.com/sp/ships/aissta",a=await D.post(o,n).json();if(u==null||u.info("[%s] fetch ship info from: %s - %j",i.requestId,o,n),a.code!=="0")return a;const e=a.data;let c=e.imo;return t==="407170"&&(c="9198379",u==null||u.warn("[%s] ship(%s) imo error: %s, should be %s",i.requestId,t,e.imo,c)),{mmsi:e.mmsi,name:e.shipnameEn,imo:c,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,i={}){const n=await this.getShipId(t,i),o=await this.getShipInfo(n,i),a={headers:{appKey:this.token},json:{shipId:n}},e="https://api3.myships.com/sp/ships/position/latest",c=await D.post(e,a).json();u==null||u.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,a);const r=c.data[0];for(const m in r)!isNaN(r[m])&&Number(r[m])!==1/0&&(r[m]=Number(r[m]));const{labelCn:d,labelEn:l}=await this.parseStatus(r.aisNavStatus),p=g.unix(r.posTime);return{...o,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:p.utc().format(),status:r.aisNavStatus,labelEn:l,labelCn:d,method:"position",vendor:"myship"}}async trajectory(t,i,n,o,a=!0,e={}){const c=g(i),r=g(n),d=await this.getShipId(t),l=await this.getShipInfo(d),p=[];for(;r.diff(c,"day",!0)>30;)await this.trajectoryIn30Day(d,c.unix(),c.add(30,"day").unix(),l,t,o,p);return await this.trajectoryIn30Day(d,c.unix(),r.unix(),l,t,o,p),p}async trajectoryIn30Day(t,i,n,o,a,e,c,r={}){var j;const d={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:n}},l="https://api3.myships.com/sp/ships/position/history",p=await D.post(l,d).json();if(u==null||u.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,d),p.code!=="0")return u==null||u.warn("[%s] invoke myship trajectory failed: %j",r.requestId,p),p;const f=p.data;for(const v in f)!isNaN(f[v])&&Number(f[v])!==1/0&&(f[v]=Number(f[v]));const m=g.unix((j=f[0])==null?void 0:j.posTime);let Y=-1;for(const v of f){const M=g.unix(v.posTime),h={imo:o==null?void 0:o.imo,mmsi:a,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:M.unix(),utc:M.utc().format(),method:"trajectory",vendor:"myship"},I=Math.floor(M.diff(m,"minute",!0)/(e||1));I!==Y&&(Y=I,c.push(h))}return c}}let R;try{R=Z.getLogger("vessel")}catch{}finally{}var G=(k=>(k.NOTICE="NOTICE",k.WARN="WARN",k.HEAVY="HEAVY",k.SEVERE="SEVERE",k.ERROR="ERROR",k.FATAL="FATAL",k))(G||{});class U{parsePrinciple(s,t={}){var e,c,r;R==null||R.info("[%s] parse rule: %s",t.requestId,s);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),n=s.match(i)?(e=s.match(i))==null?void 0:e[0]:void 0,o=n==null?void 0:n.split(";");if(!o)return;const a={};for(let d=0;d<(o==null?void 0:o.length);d++){const l=(r=(c=o[d].match(i))==null?void 0:c[0])==null?void 0:r.split("],");if(d===0&&!l)a.scope=o[0];else if(l)for(let p=0,f=l.length;p<f;p++){const m=this.parseRule(l[p]);m&&(a[m.level]?m.key?a[m.level][m==null?void 0:m.key]=m:a[m.level]=m:m.key?a[m.level]={[m==null?void 0:m.key]:m}:a[m.level]=m)}}return a}parseRule(s,t={}){var a;R==null||R.info("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),n=(a=s==null?void 0:s.match(i))==null?void 0:a[0],o=n==null?void 0:n.split(",");if(o)return{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:Number(o[3]),key:o[4]}}checkWeather(s,t,i={}){var m,Y,j,v,M,h,I,w,y,b,x,E,V,S,_;let n=0,o=0,a=0,e=0;const c=Math.round(((Y=(m=t==null?void 0:t.SEVERE)==null?void 0:m.sigWave)==null?void 0:Y.number)*1.6*100)/100,r=(v=(j=t==null?void 0:t.SEVERE)==null?void 0:j.sigWave)==null?void 0:v.number,d=(h=(M=t==null?void 0:t.HEAVY)==null?void 0:M.sigWave)==null?void 0:h.number,l=Math.round((((w=(I=t==null?void 0:t.SEVERE)==null?void 0:I.wind)==null?void 0:w.number)+2)*100)/100,p=(b=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:b.number,f=(E=(x=t==null?void 0:t.HEAVY)==null?void 0:x.wind)==null?void 0:E.number;for(let W=0;W<(s==null?void 0:s.length);W++){const T=s[W],C=(S=(V=T==null?void 0:T.meteo)==null?void 0:V.wave)==null?void 0:S.sig,F=(_=T==null?void 0:T.meteo)==null?void 0:_.wind,P=W?g(T.eta).diff(g(s[W-1].eta),"hour",!0):0;e=P>e?P:e,R==null||R.info("[%s] check sig.wave: %j",i.requestId,{...C,dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:d}),(C==null?void 0:C.height)>=c?T.isDangerous=!0:(C==null?void 0:C.height)>=r?T.isSevere=!0:(C==null?void 0:C.height)>=d&&(T.isHeavy=!0),R==null||R.info("[%s] check wind: %j",i.requestId,{...F,dgThd4Wd:l,svThd4Wd:p,hvThd4Wd:f}),(F==null?void 0:F.scale)>=l?(T.isDangerous=!0,delete T.isSevere,delete T.isHeavy):(F==null?void 0:F.scale)>p?(T.isDangerous||(T.isSevere=!0),delete T.isHeavy):(F==null?void 0:F.scale)===f&&!T.isDangerous&&!T.isSevere&&(T.isHeavy=!0),n+=T.isDangerous?P:0,o+=T.isSevere?P:0,a+=T.isHeavy?P:0}return n=Math.round(n*100)/100,o=Math.round(o*100)/100,a=Math.round(a*100)/100,e=Math.round(e),{sample:s,dangerous:n,severe:o,heavy:a,step:e<3?3:e,wind:{dgThd4Wd:l,svThd4Wd:p,hvThd4Wd:f},sig:{dgThd4Wv:c,svThd4Wv:r,hvThd4Wv:d}}}}const ut=new U;let N;try{N=Z.getLogger("vessel")}catch{}finally{}var J=(k=>(k.common="common",k.container="container",k.tugs="tugs",k))(J||{}),Q=(k=>(k.Ballast="Ballast",k.Laden="Laden",k))(Q||{}),X=(k=>(k.Cp="CP",k.Perf="Basis",k.Instruct="Other",k))(X||{});class A{static blockCoefficient(s,t,i,n){let o=Math.round(s/(t*i*n)*100)/100;o=o<.55?.55:o>.85?.85:o;const a=[.55,.6,.65,.7,.75,.8,.85],e=a.map(c=>Math.abs(c-o));return a[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,i=9.8){let n=Math.round(Math.sqrt(s*s/(i*t))*100)/100;return n=n<.05?.05:n>.3?.3:n,n}static amendFactor(s,t,i){const n={.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 a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return i==="Laden"&&(a=n[s]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(s,t=0){let i;return s>30&&s<=60?i=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?i=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?i=(.4-.03*Math.pow(t-8,2))/2:i=1,Math.round(i*1e5)/1e5}static vesselTagFactor(s,t,i,n=0){n=n>6?n-.9*(n-6):n;let o;return i==="container"?o=.7*n+Math.pow(n,6.5)/(22*Math.pow(s,2/3)):t==="Ballast"?o=.7*n+Math.pow(n,6.5)/(2.7*Math.pow(s,2/3)):o=.5*n+Math.pow(n,6.5)/(2.7*Math.pow(s,2/3)),o}static waveHeightFactor(s,t){s=s<1.25?1.25:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let i;return t>30&&t<=60?i=-.6:t>60&&t<=90?i=-.4:t>90&&t<=120?i=s<3?.4:-.3:t>120&&t<=150?i=s<3?.6:-.5:t>150&&t<=180?i=s<3?.7:-.6:i=-.7,Math.round(i*(.144*Math.pow(s,2)+.178*s)*1e4)/1e4}static assembleProperties(s,t,i,n){var p;const o=s.lbp??s.length??s.lengthOverall??198.9642,a=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,c=s.deadweight??67035.7773,r=((p=s==null?void 0:s.type)==null?void 0:p.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:o,loadCondition:t,draught:a,breadthMoulded:e,displacement:Math.round((c/1.025+a*e*o*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:n||90}}static async speedLoseAt(s,t,i,n="",o=2,a=!0,e=!1,c={}){let r;if(t.velocity&&e&&(s.speed=O.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){const d=await ot.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",n,c),l=A.weatherFactor(s,d),p=A.currentFactor(s.bearing,d==null?void 0:d.current,o),f=Math.round((s.speed*1.943844+l+p)*100)/100;r={meteo:{...d},wxFactor:l,cFactor:p,speed:t.velocity&&e?t.velocity:f<0?1:f,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round((s.speed*1.943844+0+0)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(s,t,i,n,o,a,e="",c=!0,r=!1,d={}){t.utc();const l=[],p=[];let f=0,m=0,Y,j;for(let v=0;v<a.length-1;v++){let M=a[v];M.distanceFromStart=o+m;const h=a[v+1];if(s.bearing=O.LaneHelper.calculateBearing(M,h,!h.gcToPrevious),M.bearing=s.bearing,M.suspend&&r){M.eta=M.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),M.elapsed=M.elapsed??0;const y=M.suspend-M.elapsed;if(n-f>y)n=n-f-y,t.add(y,"hour"),M.elapsed=M.suspend;else{const b=n-f;M.elapsed+=b,t.add(b,"hour"),n=0}if(N==null||N.info(`[%s] suspend ${M.elapsed} hours at %j, and remain ${n} hours need to go...`,d.requestId,M),n===0)return M.distanceFromPrevious=m,{etd:t,from:j||M,to:M,next:a.filter(b=>b),wps:l,days:p}}M=await A.speedLoseAt(s,M,t,e,0,c,r,d),j=j||M,M.important&&l.push(M),t.isSameOrAfter(i)&&(p.push(M),i.add(24,"hour"));const I=O.LaneHelper.calculateDistance(M,h,!h.gcToPrevious);let w=Math.ceil(I/j.speed*1e4)/1e4;if(f+w<n){if(f+=w,t.add(w,"hour"),delete a[v],N==null||N.info(`[%s] go to %j from %j with ${I}nm, and cost ${w} hours`,d.requestId,{lat:h.lat,lng:h.lng},{lat:j.lat,lng:j.lng,etd:j.etd}),m+=I,a.filter(y=>y).length<=1){Y=h,Y.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),Y.distanceFromPrevious=I,Y.distanceFromStart=o+m,l.push(Y),delete a[v+1];break}}else{w=n-f,t.add(w,"hour");const y=O.LngLatHelper.roundPrecision(j.speed*w,4);Y=O.LaneHelper.calculateCoordinate(M,s.bearing,y,"nauticalmiles",!h.gcToPrevious),Y.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),a[v]=Y,N==null||N.info(`[%s] go to %j from %j with ${y}nm, and cost ${w} hours`,d.requestId,{lat:Y.lat,lng:Y.lng},{lat:M.lat,lng:M.lng,etd:M.etd}),m+=y,Y.distanceFromPrevious=m,Y.distanceFromStart=o+m;break}}return{etd:t,from:j,to:Y,next:a.filter(v=>v),wps:l,days:p}}static currentFactor(s,t,i=0){const n=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(n)===Math.PI/2)return 0;let o=((t==null?void 0:t.kts)||0)*Math.cos(n);return i&2?o=Math.ceil(o*100)/100:i&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(s,t){var l,p,f,m,Y,j,v;N==null||N.debug("calculate weather factor via: %j",{...s,...t});const i=A.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=A.froudeNumber(s.speed,s.lbp),o=A.amendFactor(i,n,s.loadCondition);let a=Math.abs(s.bearing%360-(((l=t==null?void 0:t.wind)==null?void 0:l.degree)%360||0));a=a>180?360-a:a;const e=A.directionFactor(a,(p=t==null?void 0:t.wind)==null?void 0:p.scale),c=A.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(f=t==null?void 0:t.wind)==null?void 0:f.scale);let r=e*o*c/100*s.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),N==null||N.debug("wind wx factor = %d",r),a=Math.abs(s.bearing%360-(((Y=(m=t==null?void 0:t.wave)==null?void 0:m.sig)==null?void 0:Y.degree)%360||0));const d=A.waveHeightFactor(((v=(j=t==null?void 0:t.wave)==null?void 0:j.sig)==null?void 0:v.height)??1,a);return N==null||N.debug("wave wx factor = %d",d),r=r+d,N==null||N.debug("weather factor = %d",r),r=Math.abs(r)>5?5*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-5)*.4:r,Math.round(r*100)/100}static async analyseInstant(s,t,i,n,o,a="",e=0,c=!0,r=!1,d={}){var P,$,tt,et,st;const l=g().valueOf();s.lng=O.LngLatHelper.convertToStdLng(s.lng);const{route:p,waypoints:f}=o.points,m=O.LaneHelper.calculateSubRoute(s,p);if(((P=m[0])==null?void 0:P.length)<=1)return;const{v0:Y,label:j}=s.sog?{v0:s.sog,label:"Other"}:{v0:n.speed,label:"CP"},v=A.assembleProperties(i,n.loadCondition,Y,0),M=f.length?O.LaneHelper.calculateSubWaypoints(s,f):[];M.forEach(q=>q.important=!0);const h={from:{...s},route:m,waypoints:M,v0:Y,label:j},I={hours:[],days:[],wps:[]};e||(O.LaneHelper.calculateRouteDistance(m)/n.speed<=72?e=3:e=6);let w=O.LaneHelper.simplifyRouteToCoordinates(m,M,0),y=0,b=0,x=0,E=0;t=g(t).utc();const V=t.clone();for(;w.length>0;){const q=e-t.hour()%e,B=Math.ceil(t.clone().add(q,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,L=await A.speedLoseInHoursStep(v,t,V,B,y,w,a,c,r,d);($=L.from)!=null&&$.speed&&(I.hours.push(L.from),I.wps.push(...L.wps),I.days.push(...L.days)),w=L==null?void 0:L.next,w.length||I.hours.push(L==null?void 0:L.to),y+=((tt=L==null?void 0:L.to)==null?void 0:tt.distanceFromPrevious)??0}const S=I.hours;for(let q=0;q<S.length-1;q++){const B=g(S[q+1].eta).diff(S[q].etd,"hour",!0)||1;b+=(S[q].wxFactor||0)*B,x+=(S[q].cFactor||0)*B,E+=B}(et=I.wps)==null||et.forEach((q,B)=>{if(B){const L=I.wps[B-1],ht=q.distanceFromStart-L.distanceFromStart,at=g(q.eta).diff(g(L.etd),"h",!0);if(at<1)q.avgSpd=L.speed;else{q.avgSpd=Math.round(ht/at*100)/100;const nt=Math.round((L.speed+q.speed)/2*100)/100;q.avgSpd=q.avgSpd>nt?nt:q.avgSpd}}}),h.sample=I;const _=I.hours.at(0),W=I.hours.at(-1);h.distance=Math.round(W.distanceFromStart*1e4)/1e4,h.etd=g(_.eta).utc().format(),h.eta=g(W.eta).utc().format(),h.wxFactor=Math.round(b/E*1e4)/1e4,h.cFactor=Math.round(x/E*1e4)/1e4,h.avgSpeed=Math.round(W.distanceFromStart/E*1e4)/1e4,h.totalHrs=Math.round(E*1e4)/1e4,h.totalFoCons=Math.round((n==null?void 0:n.fo)/24*h.totalHrs*1e3)/1e3,h.totalDgoCons=Math.round((n==null?void 0:n.dgo)/24*h.totalHrs*1e3)/1e3;const C=g().valueOf()-l,F=((st=I==null?void 0:I.hours)==null?void 0:st.length)||1;return N==null||N.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",d==null?void 0:d.requestId,C,F,Math.round(C/F*1e3)/1e3),h}static async analyseInstantWithThreshed(s,t,i,n,o,a,e,c="",r=3,d=!0,l=!1,p={}){var W,T,C;s.lng=O.LngLatHelper.convertToStdLng(s.lng);const{v0:f,label:m}=s.sog?{v0:s.sog,label:"Other"}:{v0:o.speed,label:"CP"},Y=A.assembleProperties(n,o.loadCondition,f,0),j=O.LaneHelper.calculateSubRoute(s,a);if(((W=j[0])==null?void 0:W.length)<=1)return;const v=e.length?O.LaneHelper.calculateSubWaypoints(s,e):[];v.forEach(F=>F.important=!0);let M=O.LaneHelper.simplifyRouteToCoordinates(j,v,0),h=0,I=0,w=0,y=0,b;const x={hours:[],wps:[],days:[]};for(t=g(t).utc();M.length>0;){const F=r-t.hour()%r;let P=Math.ceil(t.clone().add(F,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(P=t.clone().add(P,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:P,P)b=await A.speedLoseInHoursStep(Y,t,i.clone(),P,h,M,c,d,l,p),(T=b.from)!=null&&T.speed&&(x.hours.push(b.from),b!=null&&b.wps&&x.wps.push(...b.wps),x.days.push(...b.days)),M=b==null?void 0:b.next,M.length||(x.hours.push(b==null?void 0:b.to),b!=null&&b.wps&&x.wps.push(...b.wps),x.days.push(b==null?void 0:b.to)),h+=((C=b==null?void 0:b.to)==null?void 0:C.distanceFromPrevious)??0;else{b&&(x.hours.push(b.to),b!=null&&b.wps&&x.wps.push(...b.wps),x.days.push(b.to));break}}const E=x.hours;for(let F=0;F<E.length-1;F++){const P=g(E[F+1].eta).diff(E[F].etd,"hour",!0);I+=E[F].wxFactor*P,w+=E[F].cFactor*P,y+=P}const V=x.hours.at(0),S=x.hours.at(-1);return{sample:x,distance:Math.round(((S==null?void 0:S.distanceFromStart)||0)*1e4)/1e4,etd:g(V.eta).utc().format(),eta:g(S==null?void 0:S.eta).utc().format(),wxFactor:Math.round(I/y*1e4)/1e4,cFactor:Math.round(w/y*1e4)/1e4,avgSpeed:Math.round(((S==null?void 0:S.distanceFromStart)||0)/y*1e4)/1e4,totalHrs:Math.round(y*1e4)/1e4,from:s,to:S,route:j,waypoints:v,v0:f,label:m}}}H.AISImpl=z,H.AlertHelper=U,H.AlertLevel=G,H.HifleetImpl=rt,H.LoadCondition=Q,H.MyShipImpl=dt,H.MyVesselImpl=it,H.ShipxyImpl=ct,H.SpeedHelper=A,H.SpeedLabel=X,H.VesselTag=J,H.alertHelper=ut,Object.defineProperty(H,Symbol.toStringTag,{value:"Module"})});
|