@idm-plugin/vessel 2.2.4 → 2.2.5
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 +218 -216
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var ht = Object.defineProperty;
|
|
2
|
-
var lt = (
|
|
3
|
-
var K = (
|
|
2
|
+
var lt = (x, t, e) => t in x ? ht(x, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : x[t] = e;
|
|
3
|
+
var K = (x, t, e) => (lt(x, typeof t != "symbol" ? t + "" : t, e), e);
|
|
4
4
|
import B from "got";
|
|
5
5
|
import ct from "@log4js-node/log4js-api";
|
|
6
6
|
import g from "moment";
|
|
@@ -54,7 +54,7 @@ class st {
|
|
|
54
54
|
return { labelCn: e, labelEn: a };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class Et extends st {
|
|
58
58
|
constructor(e, a) {
|
|
59
59
|
super();
|
|
60
60
|
K(this, "clientId");
|
|
@@ -69,30 +69,30 @@ class xt extends st {
|
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
},
|
|
73
|
-
v == null || v.info("[%s] fetch access token from: %s - %j", e.requestId, a,
|
|
74
|
-
accessToken:
|
|
75
|
-
tokenType:
|
|
76
|
-
expiresIn:
|
|
77
|
-
scope:
|
|
78
|
-
jti:
|
|
72
|
+
}, o = await B.post(a, i).json();
|
|
73
|
+
v == null || v.info("[%s] fetch access token from: %s - %j", e.requestId, a, o), o.error || (this.token = {
|
|
74
|
+
accessToken: o.access_token,
|
|
75
|
+
tokenType: o.token_type,
|
|
76
|
+
expiresIn: o.expires_in,
|
|
77
|
+
scope: o.scope,
|
|
78
|
+
jti: o.jti,
|
|
79
79
|
issuedAt: g().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async realTimePosition(e, a = {}) {
|
|
83
83
|
var d, r, m;
|
|
84
84
|
(!this.token || g().diff(g(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(a);
|
|
85
|
-
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",
|
|
85
|
+
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", o = {
|
|
86
86
|
headers: {
|
|
87
87
|
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(m = this.token) == null ? void 0 : m.accessToken}`
|
|
88
88
|
},
|
|
89
89
|
searchParams: { mmsi: e }
|
|
90
90
|
};
|
|
91
|
-
v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, i,
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
94
|
-
return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i, { message:
|
|
95
|
-
const s =
|
|
91
|
+
v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, o);
|
|
92
|
+
const n = await B.get(i, o).json();
|
|
93
|
+
if (n.code)
|
|
94
|
+
return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i, { message: n.message, status: n.status, code: n.code }), n;
|
|
95
|
+
const s = n.data;
|
|
96
96
|
for (const M in s)
|
|
97
97
|
!isNaN(s[M]) && Number(s[M]) !== 1 / 0 && (s[M] = Number(s[M]));
|
|
98
98
|
if (s) {
|
|
@@ -131,14 +131,14 @@ class xt extends st {
|
|
|
131
131
|
} else
|
|
132
132
|
return {};
|
|
133
133
|
}
|
|
134
|
-
async trajectory(e, a, i,
|
|
134
|
+
async trajectory(e, a, i, o, n = !0, s = {}) {
|
|
135
135
|
(!this.token || g().diff(g(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(s);
|
|
136
136
|
const d = await this.realTimePosition(e, s), r = g(a), m = g(i), M = [];
|
|
137
137
|
for (; m.diff(r, "day", !0) > 30; )
|
|
138
|
-
await this.trajectoryIn30Day(e, r, r.clone().add(30, "day"), d,
|
|
139
|
-
return await this.trajectoryIn30Day(e, r, m, d,
|
|
138
|
+
await this.trajectoryIn30Day(e, r, r.clone().add(30, "day"), d, o, M, s), r.add(30, "day");
|
|
139
|
+
return await this.trajectoryIn30Day(e, r, m, d, o, M, s), M;
|
|
140
140
|
}
|
|
141
|
-
async trajectoryIn30Day(e, a, i,
|
|
141
|
+
async trajectoryIn30Day(e, a, i, o, n, s, d = {}) {
|
|
142
142
|
var f, C, S, p, w;
|
|
143
143
|
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", m = {
|
|
144
144
|
headers: {
|
|
@@ -161,7 +161,7 @@ class xt extends st {
|
|
|
161
161
|
!isNaN(c[Y]) && Number(c[Y]) !== 1 / 0 && (c[Y] = Number(c[Y]));
|
|
162
162
|
const y = g(`${c.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), h = c.status, { labelCn: u, labelEn: I } = this.parseStatus(h), k = {
|
|
163
163
|
mmsi: c.mmsi,
|
|
164
|
-
imo:
|
|
164
|
+
imo: o == null ? void 0 : o.imo,
|
|
165
165
|
lat: c.lat,
|
|
166
166
|
lng: c.lon,
|
|
167
167
|
sog: c.sog,
|
|
@@ -177,28 +177,28 @@ class xt extends st {
|
|
|
177
177
|
method: "trajectory",
|
|
178
178
|
vendor: "myVessel",
|
|
179
179
|
utc: y.utc().format()
|
|
180
|
-
}, D = Math.floor(y.diff(b, "minute", !0) / (
|
|
180
|
+
}, D = Math.floor(y.diff(b, "minute", !0) / (n || 1));
|
|
181
181
|
D !== l && (l = D, s.push(k));
|
|
182
182
|
}), s;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
class
|
|
185
|
+
class xt extends st {
|
|
186
186
|
constructor(e) {
|
|
187
187
|
super();
|
|
188
188
|
K(this, "token");
|
|
189
189
|
this.token = e;
|
|
190
190
|
}
|
|
191
191
|
async realTimePosition(e, a = {}) {
|
|
192
|
-
const i = "https://api.hifleet.com/position/position/get/token",
|
|
192
|
+
const i = "https://api.hifleet.com/position/position/get/token", o = {
|
|
193
193
|
searchParams: {
|
|
194
194
|
mmsi: e,
|
|
195
195
|
usertoken: this.token
|
|
196
196
|
}
|
|
197
|
-
},
|
|
198
|
-
v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, i,
|
|
199
|
-
const s =
|
|
197
|
+
}, n = await B.post(i, o).json();
|
|
198
|
+
v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, o);
|
|
199
|
+
const s = n == null ? void 0 : n.list;
|
|
200
200
|
if (!s)
|
|
201
|
-
return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i,
|
|
201
|
+
return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i, n), n;
|
|
202
202
|
for (const b in s)
|
|
203
203
|
!isNaN(s[b]) && Number(s[b]) !== 1 / 0 && (s[b] = Number(s[b]));
|
|
204
204
|
s.status = s.sp > 3 ? 0 : 1;
|
|
@@ -234,7 +234,7 @@ class Et extends st {
|
|
|
234
234
|
}
|
|
235
235
|
async search(e, a = {}) {
|
|
236
236
|
let i = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
237
|
-
const
|
|
237
|
+
const o = {
|
|
238
238
|
searchParams: {
|
|
239
239
|
keyword: e
|
|
240
240
|
},
|
|
@@ -244,24 +244,24 @@ class Et extends st {
|
|
|
244
244
|
Host: "www.hifleet.com"
|
|
245
245
|
}
|
|
246
246
|
};
|
|
247
|
-
let
|
|
248
|
-
v == null || v.info("[%s] fetch vessel props from: %s - %j", a.requestId, i,
|
|
249
|
-
for (const d in
|
|
250
|
-
!isNaN(
|
|
247
|
+
let n = await B.post(i, o).json();
|
|
248
|
+
v == null || v.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, o), n instanceof Array && (n = n[0]);
|
|
249
|
+
for (const d in n)
|
|
250
|
+
!isNaN(n[d]) && Number(n[d]) !== 1 / 0 && (n[d] = Number(n[d]));
|
|
251
251
|
const s = {
|
|
252
|
-
mmsi:
|
|
253
|
-
name:
|
|
254
|
-
imo:
|
|
255
|
-
callSign:
|
|
256
|
-
length:
|
|
257
|
-
breadth:
|
|
258
|
-
draught:
|
|
259
|
-
type:
|
|
252
|
+
mmsi: n.m,
|
|
253
|
+
name: n.n,
|
|
254
|
+
imo: n.i,
|
|
255
|
+
callSign: n.c,
|
|
256
|
+
length: n.l,
|
|
257
|
+
breadth: n.b,
|
|
258
|
+
draught: n.dr,
|
|
259
|
+
type: n.t
|
|
260
260
|
};
|
|
261
|
-
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do",
|
|
261
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", n = await B.post(i, o).json(), v == null || v.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, o), n instanceof Array && (n = n[0]), n && (s.deadweight = Number(n.dwt)), s;
|
|
262
262
|
}
|
|
263
263
|
async suggest(e, a = {}) {
|
|
264
|
-
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do",
|
|
264
|
+
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", o = {
|
|
265
265
|
searchParams: {
|
|
266
266
|
q: e
|
|
267
267
|
},
|
|
@@ -270,10 +270,10 @@ class Et extends st {
|
|
|
270
270
|
Origin: "https://www.hifleet.com",
|
|
271
271
|
Host: "www.hifleet.com"
|
|
272
272
|
}
|
|
273
|
-
},
|
|
274
|
-
v == null || v.info("[%s] suggest vessel props from: %s - %j", a.requestId, i,
|
|
273
|
+
}, n = await B.post(i, o).json();
|
|
274
|
+
v == null || v.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, o);
|
|
275
275
|
const s = [];
|
|
276
|
-
for (const d of
|
|
276
|
+
for (const d of n)
|
|
277
277
|
s.push({
|
|
278
278
|
mmsi: !d.mmsi || isNaN(d.mmsi) ? null : Number(d.mmsi),
|
|
279
279
|
name: d.name,
|
|
@@ -283,12 +283,12 @@ class Et extends st {
|
|
|
283
283
|
});
|
|
284
284
|
return s.sort((d, r) => r.score - d.score), s;
|
|
285
285
|
}
|
|
286
|
-
async trajectory(e, a, i,
|
|
286
|
+
async trajectory(e, a, i, o, n = !0, s = {}) {
|
|
287
287
|
var c, y, h;
|
|
288
288
|
const d = await this.realTimePosition(e, s);
|
|
289
289
|
let r = g(a);
|
|
290
290
|
const m = g(i), M = g();
|
|
291
|
-
if (
|
|
291
|
+
if (n) {
|
|
292
292
|
let u = m.diff(r, "d", !0);
|
|
293
293
|
u < 0 ? r = m.clone().subtract(40, "d") : u < 30 ? r.subtract(10, "d") : u < 60 ? r.subtract(5, "d") : r = m.clone().subtract(80, "d"), u = M.diff(m, "d", !0), m.add(u > 10 ? 240 : u * 24, "h");
|
|
294
294
|
}
|
|
@@ -307,8 +307,8 @@ class Et extends st {
|
|
|
307
307
|
let p = -1;
|
|
308
308
|
const w = g(`${(h = C == null ? void 0 : C[0]) == null ? void 0 : h.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
309
309
|
for (const u of C) {
|
|
310
|
-
for (const
|
|
311
|
-
!isNaN(u[
|
|
310
|
+
for (const A in u)
|
|
311
|
+
!isNaN(u[A]) && Number(u[A]) !== 1 / 0 && (u[A] = Number(u[A]));
|
|
312
312
|
const I = g(`${u.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
313
313
|
u.status = u.sp > 4 ? 0 : 1;
|
|
314
314
|
const { labelEn: k, labelCn: D } = this.parseStatus(u.status), Y = {
|
|
@@ -328,7 +328,7 @@ class Et extends st {
|
|
|
328
328
|
labelEn: k,
|
|
329
329
|
method: "trajectory",
|
|
330
330
|
vendor: "hifleet"
|
|
331
|
-
}, j = Math.floor(I.diff(w, "minute", !0) / (
|
|
331
|
+
}, j = Math.floor(I.diff(w, "minute", !0) / (o || 1));
|
|
332
332
|
j !== p && (p = j, S.push(Y));
|
|
333
333
|
}
|
|
334
334
|
return S;
|
|
@@ -347,10 +347,10 @@ class jt extends st {
|
|
|
347
347
|
k: this.token,
|
|
348
348
|
enc: 1
|
|
349
349
|
}
|
|
350
|
-
},
|
|
351
|
-
if (v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
352
|
-
return
|
|
353
|
-
const s =
|
|
350
|
+
}, o = "https://api.shipxy.com/apicall/GetSingleShip", n = await B.get(o, i).json();
|
|
351
|
+
if (v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, i), (n == null ? void 0 : n.status) !== 0)
|
|
352
|
+
return n;
|
|
353
|
+
const s = n.data[0];
|
|
354
354
|
for (const l in s)
|
|
355
355
|
!isNaN(s[l]) && Number(s[l]) !== 1 / 0 && (s[l] = Number(s[l]));
|
|
356
356
|
const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), m = g.unix(s.lasttime);
|
|
@@ -377,7 +377,7 @@ class jt extends st {
|
|
|
377
377
|
vendor: "shipxy"
|
|
378
378
|
};
|
|
379
379
|
}
|
|
380
|
-
async trajectory(e, a, i,
|
|
380
|
+
async trajectory(e, a, i, o, n = !0, s = {}) {
|
|
381
381
|
var w;
|
|
382
382
|
const d = await this.realTimePosition(e, s), r = g(a), m = g(i), M = "https://api.shipxy.com/apicall/GetShipTrack", l = {
|
|
383
383
|
searchParams: {
|
|
@@ -405,7 +405,7 @@ class jt extends st {
|
|
|
405
405
|
utc: y.utc().format(),
|
|
406
406
|
method: "trajectory",
|
|
407
407
|
vendor: "shipxy"
|
|
408
|
-
}, u = Math.floor(y.diff(S, "minute", !0) / (
|
|
408
|
+
}, u = Math.floor(y.diff(S, "minute", !0) / (o || 1));
|
|
409
409
|
u !== p && (p = u, C.push(h));
|
|
410
410
|
}
|
|
411
411
|
return C;
|
|
@@ -425,8 +425,8 @@ class Nt extends st {
|
|
|
425
425
|
json: {
|
|
426
426
|
mmsiList: e
|
|
427
427
|
}
|
|
428
|
-
},
|
|
429
|
-
return v == null || v.info("[%s] fetch ship id from: %s - %j", a.requestId,
|
|
428
|
+
}, o = "https://api3.myships.com/sp/ships/getShipIdByMMSI", n = await B.post(o, i).json();
|
|
429
|
+
return v == null || v.info("[%s] fetch ship id from: %s - %j", a.requestId, o, i), n.code !== "0" ? n : n.data[0].shipId;
|
|
430
430
|
}
|
|
431
431
|
async getShipInfo(e, a = {}) {
|
|
432
432
|
const i = {
|
|
@@ -436,10 +436,10 @@ class Nt extends st {
|
|
|
436
436
|
json: {
|
|
437
437
|
shipId: e
|
|
438
438
|
}
|
|
439
|
-
},
|
|
440
|
-
if (v == null || v.info("[%s] fetch ship info from: %s - %j", a.requestId,
|
|
441
|
-
return
|
|
442
|
-
const s =
|
|
439
|
+
}, o = "https://api3.myships.com/sp/ships/aissta", n = await B.post(o, i).json();
|
|
440
|
+
if (v == null || v.info("[%s] fetch ship info from: %s - %j", a.requestId, o, i), n.code !== "0")
|
|
441
|
+
return n;
|
|
442
|
+
const s = n.data;
|
|
443
443
|
let d = s.imo;
|
|
444
444
|
return e === "407170" && (d = "9198379", v == null || v.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, e, s.imo, d)), {
|
|
445
445
|
mmsi: s.mmsi,
|
|
@@ -452,21 +452,21 @@ class Nt extends st {
|
|
|
452
452
|
};
|
|
453
453
|
}
|
|
454
454
|
async realTimePosition(e, a = {}) {
|
|
455
|
-
const i = await this.getShipId(e, a),
|
|
455
|
+
const i = await this.getShipId(e, a), o = await this.getShipInfo(i, a), n = {
|
|
456
456
|
headers: {
|
|
457
457
|
appKey: this.token
|
|
458
458
|
},
|
|
459
459
|
json: {
|
|
460
460
|
shipId: i
|
|
461
461
|
}
|
|
462
|
-
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s,
|
|
463
|
-
v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, s,
|
|
462
|
+
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s, n).json();
|
|
463
|
+
v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, n);
|
|
464
464
|
const r = d.data[0];
|
|
465
465
|
for (const f in r)
|
|
466
466
|
!isNaN(r[f]) && Number(r[f]) !== 1 / 0 && (r[f] = Number(r[f]));
|
|
467
467
|
const { labelCn: m, labelEn: M } = await this.parseStatus(r.aisNavStatus), l = g.unix(r.posTime);
|
|
468
468
|
return {
|
|
469
|
-
...
|
|
469
|
+
...o,
|
|
470
470
|
mmsi: e,
|
|
471
471
|
lat: Math.round(r.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
472
472
|
lng: Math.round(r.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
@@ -483,13 +483,13 @@ class Nt extends st {
|
|
|
483
483
|
vendor: "myship"
|
|
484
484
|
};
|
|
485
485
|
}
|
|
486
|
-
async trajectory(e, a, i,
|
|
486
|
+
async trajectory(e, a, i, o, n = !0, s = {}) {
|
|
487
487
|
const d = g(a), r = g(i), m = await this.getShipId(e), M = await this.getShipInfo(m), l = [];
|
|
488
488
|
for (; r.diff(d, "day", !0) > 30; )
|
|
489
|
-
await this.trajectoryIn30Day(m, d.unix(), d.add(30, "day").unix(), M, e,
|
|
490
|
-
return await this.trajectoryIn30Day(m, d.unix(), r.unix(), M, e,
|
|
489
|
+
await this.trajectoryIn30Day(m, d.unix(), d.add(30, "day").unix(), M, e, o, l);
|
|
490
|
+
return await this.trajectoryIn30Day(m, d.unix(), r.unix(), M, e, o, l), l;
|
|
491
491
|
}
|
|
492
|
-
async trajectoryIn30Day(e, a, i,
|
|
492
|
+
async trajectoryIn30Day(e, a, i, o, n, s, d, r = {}) {
|
|
493
493
|
var S;
|
|
494
494
|
const m = {
|
|
495
495
|
headers: {
|
|
@@ -510,8 +510,8 @@ class Nt extends st {
|
|
|
510
510
|
let C = -1;
|
|
511
511
|
for (const p of b) {
|
|
512
512
|
const w = g.unix(p.posTime), c = {
|
|
513
|
-
imo:
|
|
514
|
-
mmsi:
|
|
513
|
+
imo: o == null ? void 0 : o.imo,
|
|
514
|
+
mmsi: n,
|
|
515
515
|
lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
516
516
|
lng: Math.round(p.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
517
517
|
sog: Math.round(p.sog / 10 * 100) / 100,
|
|
@@ -534,7 +534,7 @@ try {
|
|
|
534
534
|
} catch {
|
|
535
535
|
} finally {
|
|
536
536
|
}
|
|
537
|
-
var mt = /* @__PURE__ */ ((
|
|
537
|
+
var mt = /* @__PURE__ */ ((x) => (x.NOTICE = "NOTICE", x.WARN = "WARN", x.HEAVY = "HEAVY", x.SEVERE = "SEVERE", x.ERROR = "ERROR", x.FATAL = "FATAL", x))(mt || {});
|
|
538
538
|
class yt {
|
|
539
539
|
/**
|
|
540
540
|
* 解析告警规则, 多规则场景
|
|
@@ -546,22 +546,22 @@ class yt {
|
|
|
546
546
|
*/
|
|
547
547
|
parsePrinciple(t, e = {}) {
|
|
548
548
|
var s, d, r;
|
|
549
|
-
_ == null || _.
|
|
550
|
-
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = t.match(a) ? (s = t.match(a)) == null ? void 0 : s[0] : void 0,
|
|
551
|
-
if (!
|
|
549
|
+
_ == null || _.debug("[%s] parse rule: %s", e.requestId, t);
|
|
550
|
+
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = t.match(a) ? (s = t.match(a)) == null ? void 0 : s[0] : void 0, o = i == null ? void 0 : i.split(";");
|
|
551
|
+
if (!o)
|
|
552
552
|
return;
|
|
553
|
-
const
|
|
554
|
-
for (let m = 0; m < (
|
|
555
|
-
const M = (r = (d =
|
|
553
|
+
const n = {};
|
|
554
|
+
for (let m = 0; m < (o == null ? void 0 : o.length); m++) {
|
|
555
|
+
const M = (r = (d = o[m].match(a)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
|
|
556
556
|
if (m === 0 && !M)
|
|
557
|
-
|
|
557
|
+
n.scope = o[0];
|
|
558
558
|
else if (M)
|
|
559
559
|
for (let l = 0, b = M.length; l < b; l++) {
|
|
560
560
|
const f = this.parseRule(M[l]);
|
|
561
|
-
f && (
|
|
561
|
+
f && (n[f.level] ? f.key ? n[f.level][f == null ? void 0 : f.key] = f : n[f.level] = f : f.key ? n[f.level] = { [f == null ? void 0 : f.key]: f } : n[f.level] = f);
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
|
-
return
|
|
564
|
+
return n;
|
|
565
565
|
}
|
|
566
566
|
/**
|
|
567
567
|
* 解析单一告警规则
|
|
@@ -570,17 +570,19 @@ class yt {
|
|
|
570
570
|
* @param options
|
|
571
571
|
*/
|
|
572
572
|
parseRule(t, e = {}) {
|
|
573
|
-
var
|
|
573
|
+
var n;
|
|
574
574
|
_ == null || _.debug("[%s] parse rule: %s", e.requestId, t), t = t.startsWith("[") ? t : `[${t}`, t = t.endsWith("]") ? t : `${t}]`;
|
|
575
|
-
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (
|
|
576
|
-
if (
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
575
|
+
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (n = t == null ? void 0 : t.match(a)) == null ? void 0 : n[0], o = i == null ? void 0 : i.split(",");
|
|
576
|
+
if (o) {
|
|
577
|
+
let s = o[3] === "Number.MAX_VALUE" ? 100 : Number(o[3]);
|
|
578
|
+
return s = isNaN(s) ? 1 : s, {
|
|
579
|
+
operator: o[0],
|
|
580
|
+
number: Number.isNaN(Number(o[1])) ? o[1] : Number(o[1]),
|
|
581
|
+
level: o[2],
|
|
582
|
+
time: s,
|
|
583
|
+
key: o[4]
|
|
583
584
|
};
|
|
585
|
+
}
|
|
584
586
|
}
|
|
585
587
|
/**
|
|
586
588
|
* 检查航路点天气
|
|
@@ -589,14 +591,14 @@ class yt {
|
|
|
589
591
|
* @param options
|
|
590
592
|
*/
|
|
591
593
|
checkWeather(t, e, a = {}) {
|
|
592
|
-
var f, C, S, p, w, c, y, h, u, I, k, D, Y, j,
|
|
593
|
-
let i = 0,
|
|
594
|
+
var f, C, S, p, w, c, y, h, u, I, k, D, Y, j, A;
|
|
595
|
+
let i = 0, o = 0, n = 0, s = 0;
|
|
594
596
|
const d = Math.round(((C = (f = e == null ? void 0 : e.SEVERE) == null ? void 0 : f.sigWave) == null ? void 0 : C.number) * 1.6 * 100) / 100, r = (p = (S = e == null ? void 0 : e.SEVERE) == null ? void 0 : S.sigWave) == null ? void 0 : p.number, m = (c = (w = e == null ? void 0 : e.HEAVY) == null ? void 0 : w.sigWave) == null ? void 0 : c.number, M = Math.round((((h = (y = e == null ? void 0 : e.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : h.number) + 2) * 100) / 100, l = (I = (u = e == null ? void 0 : e.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : I.number, b = (D = (k = e == null ? void 0 : e.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : D.number;
|
|
595
597
|
for (let T = 0; T < (t == null ? void 0 : t.length); T++) {
|
|
596
|
-
const N = t[T],
|
|
597
|
-
s = U > s ? U : s, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...
|
|
598
|
+
const N = t[T], P = (j = (Y = N == null ? void 0 : N.meteo) == null ? void 0 : Y.wave) == null ? void 0 : j.sig, R = (A = N == null ? void 0 : N.meteo) == null ? void 0 : A.wind, U = T ? g(N.eta).diff(g(t[T - 1].eta), "hour", !0) : 0;
|
|
599
|
+
s = U > s ? U : s, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...P, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: m }), (P == null ? void 0 : P.height) >= d ? N.isDangerous = !0 : (P == null ? void 0 : P.height) >= r ? N.isSevere = !0 : (P == null ? void 0 : P.height) >= m && (N.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: b }), (R == null ? void 0 : R.scale) >= M ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > l ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === b && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? U : 0, o += N.isSevere ? U : 0, n += N.isHeavy ? U : 0;
|
|
598
600
|
}
|
|
599
|
-
return i = Math.round(i * 100) / 100,
|
|
601
|
+
return i = Math.round(i * 100) / 100, o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, s = Math.round(s), { sample: t, dangerous: i, severe: o, heavy: n, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: b }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: m } };
|
|
600
602
|
}
|
|
601
603
|
}
|
|
602
604
|
const Tt = new yt();
|
|
@@ -607,7 +609,7 @@ try {
|
|
|
607
609
|
} finally {
|
|
608
610
|
}
|
|
609
611
|
const Mt = new ft("", !0);
|
|
610
|
-
var bt = /* @__PURE__ */ ((
|
|
612
|
+
var bt = /* @__PURE__ */ ((x) => (x.common = "common", x.container = "container", x.tugs = "tugs", x))(bt || {}), gt = /* @__PURE__ */ ((x) => (x.Ballast = "Ballast", x.Laden = "Laden", x))(gt || {}), wt = /* @__PURE__ */ ((x) => (x.Cp = "CP", x.Perf = "Basis", x.Instruct = "Other", x))(wt || {});
|
|
611
613
|
class O {
|
|
612
614
|
/**
|
|
613
615
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
@@ -622,10 +624,10 @@ class O {
|
|
|
622
624
|
* @return [0.55, 0.85]
|
|
623
625
|
*/
|
|
624
626
|
static blockCoefficient(t, e, a, i) {
|
|
625
|
-
let
|
|
626
|
-
|
|
627
|
-
const
|
|
628
|
-
return
|
|
627
|
+
let o = Math.round(t / (e * a * i) * 100) / 100;
|
|
628
|
+
o = o < 0.55 ? 0.55 : o > 0.85 ? 0.85 : o;
|
|
629
|
+
const n = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = n.map((d) => Math.abs(d - o));
|
|
630
|
+
return n[s.indexOf(Math.min(...s))];
|
|
629
631
|
}
|
|
630
632
|
/**
|
|
631
633
|
* @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
|
|
@@ -659,7 +661,7 @@ class O {
|
|
|
659
661
|
0.8: [2.6, -13.1, -15.1],
|
|
660
662
|
0.85: [3.1, -18.7, 28]
|
|
661
663
|
};
|
|
662
|
-
let
|
|
664
|
+
let n = {
|
|
663
665
|
0.55: [1.7, -1.4, -7.4],
|
|
664
666
|
0.6: [2.2, -2.5, -9.7],
|
|
665
667
|
0.65: [2.6, -3.7, -11.6],
|
|
@@ -668,7 +670,7 @@ class O {
|
|
|
668
670
|
0.8: [3, -16.3, -21.6],
|
|
669
671
|
0.85: [3.4, -20.9, 31.8]
|
|
670
672
|
}[t];
|
|
671
|
-
return a === "Laden" && (
|
|
673
|
+
return a === "Laden" && (n = i[t]), n[0] + n[1] * e + n[2] * Math.pow(e, 2);
|
|
672
674
|
}
|
|
673
675
|
/**
|
|
674
676
|
* 失速方向因子
|
|
@@ -698,8 +700,8 @@ class O {
|
|
|
698
700
|
*/
|
|
699
701
|
static vesselTagFactor(t, e, a, i = 0) {
|
|
700
702
|
i = i > 6 ? i - 0.9 * (i - 6) : i;
|
|
701
|
-
let
|
|
702
|
-
return a === "container" ?
|
|
703
|
+
let o;
|
|
704
|
+
return a === "container" ? o = 0.7 * i + Math.pow(i, 6.5) / (22 * Math.pow(t, 2 / 3)) : e === "Ballast" ? o = 0.7 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(t, 2 / 3)) : o = 0.5 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(t, 2 / 3)), o;
|
|
703
705
|
}
|
|
704
706
|
/**
|
|
705
707
|
* 浪高影响因子
|
|
@@ -721,16 +723,16 @@ class O {
|
|
|
721
723
|
*/
|
|
722
724
|
static assembleProperties(t, e, a, i) {
|
|
723
725
|
var l;
|
|
724
|
-
const
|
|
726
|
+
const o = t.lbp ?? t.length ?? t.lengthOverall ?? 198.9642, n = t.draught ?? 8, s = t.breadthMoulded ?? t.breadth ?? t.breadthExtreme ?? 32.4572, d = t.deadweight ?? 67035.7773, r = ((l = t == null ? void 0 : t.type) == null ? void 0 : l.toLowerCase()) || "common";
|
|
725
727
|
return {
|
|
726
728
|
tag: r.indexOf("container") > -1 ? "container" : r.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
727
|
-
lbp:
|
|
729
|
+
lbp: o,
|
|
728
730
|
loadCondition: e,
|
|
729
|
-
draught:
|
|
731
|
+
draught: n,
|
|
730
732
|
breadthMoulded: s,
|
|
731
733
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
732
734
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
733
|
-
displacement: Math.round((d / 1.025 +
|
|
735
|
+
displacement: Math.round((d / 1.025 + n * s * o * 0.7) * 1e4) / 1e4,
|
|
734
736
|
// 换算为m/s
|
|
735
737
|
speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
736
738
|
bearing: i || 90
|
|
@@ -746,9 +748,9 @@ class O {
|
|
|
746
748
|
* @param useMeteo true 启用气象分析
|
|
747
749
|
* @param useRouteParam true 启用设置速度
|
|
748
750
|
*/
|
|
749
|
-
static async speedLoseAt(t, e, a, i = "",
|
|
751
|
+
static async speedLoseAt(t, e, a, i = "", o = 2, n = !0, s = !1, d = {}) {
|
|
750
752
|
let r;
|
|
751
|
-
if (e.velocity && s && (t.speed = J.roundPrecision(e.velocity * 1852 / 3600, 6)),
|
|
753
|
+
if (e.velocity && s && (t.speed = J.roundPrecision(e.velocity * 1852 / 3600, 6)), n) {
|
|
752
754
|
let m;
|
|
753
755
|
try {
|
|
754
756
|
i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
|
|
@@ -763,7 +765,7 @@ class O {
|
|
|
763
765
|
} catch (f) {
|
|
764
766
|
F.warn("[%s] meteo2 spot(%j) forecast failed: %s", d.requestId, { ...e, eta: a.utc().format(), source: i }, f);
|
|
765
767
|
}
|
|
766
|
-
const M = O.weatherFactor(t, m), l = O.currentFactor(t.bearing, m == null ? void 0 : m.current,
|
|
768
|
+
const M = O.weatherFactor(t, m), l = O.currentFactor(t.bearing, m == null ? void 0 : m.current, o), b = Math.round((t.speed * 1.943844 + M + l) * 100) / 100;
|
|
767
769
|
r = {
|
|
768
770
|
meteo: { ...m },
|
|
769
771
|
wxFactor: M,
|
|
@@ -795,14 +797,14 @@ class O {
|
|
|
795
797
|
* @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
|
|
796
798
|
* @private
|
|
797
799
|
*/
|
|
798
|
-
static async speedLoseInHoursStep(t, e, a, i,
|
|
800
|
+
static async speedLoseInHoursStep(t, e, a, i, o, n, s = "", d = !0, r = !1, m = {}) {
|
|
799
801
|
e.utc();
|
|
800
802
|
const M = e.clone().add(14, "days"), l = [], b = [];
|
|
801
803
|
let f = 0, C = 0, S, p;
|
|
802
|
-
for (let w = 0; w <
|
|
803
|
-
let c =
|
|
804
|
-
c.distanceFromStart = Math.round((
|
|
805
|
-
const y =
|
|
804
|
+
for (let w = 0; w < n.length - 1; w++) {
|
|
805
|
+
let c = n[w];
|
|
806
|
+
c.distanceFromStart = Math.round((o + C) * 1e3) / 1e3;
|
|
807
|
+
const y = n[w + 1];
|
|
806
808
|
if (t.bearing = W.calculateBearing(c, y, !y.gcToPrevious), c.bearing = t.bearing, c.suspend && r) {
|
|
807
809
|
c.eta = c.eta || e.utc().format(), c.elapsed = c.elapsed ?? 0;
|
|
808
810
|
const I = c.suspend - c.elapsed;
|
|
@@ -813,35 +815,35 @@ class O {
|
|
|
813
815
|
c.elapsed += k, e.add(k, "hour"), i = 0;
|
|
814
816
|
}
|
|
815
817
|
if (F == null || F.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`, m.requestId, c), i === 0)
|
|
816
|
-
return c.distanceFromPrevious = C, { etd: e, from: p || c, to: c, next:
|
|
818
|
+
return c.distanceFromPrevious = C, { etd: e, from: p || c, to: c, next: n.filter((k) => k), wps: l, days: b };
|
|
817
819
|
} else
|
|
818
820
|
c.suspend = 0;
|
|
819
821
|
d = e.isAfter(M) ? !1 : d, c = await O.speedLoseAt(t, c, e, s, 0, d, r, m), p = p || c, c.important && l.push(c), e.isSameOrAfter(a) && (b.push(c), a.add(24, "hour"));
|
|
820
822
|
const h = W.calculateDistance(c, y, !y.gcToPrevious);
|
|
821
823
|
let u = Math.round(h / p.speed * 1e5) / 1e5;
|
|
822
824
|
if (f + u < i) {
|
|
823
|
-
if (f += u, e.add(u, "hour"), delete
|
|
825
|
+
if (f += u, e.add(u, "hour"), delete n[w], F == null || F.debug(
|
|
824
826
|
`[%s] go to %j from %j with ${h}nm, and cost ${u} hours`,
|
|
825
827
|
m.requestId,
|
|
826
828
|
{ lat: y.lat, lng: y.lng },
|
|
827
829
|
{ lat: p.lat, lng: p.lng, etd: p.etd }
|
|
828
|
-
), C += h,
|
|
829
|
-
S = y, S.eta = e.utc().format(), S.distanceFromPrevious = h, S.distanceFromStart = Math.round((
|
|
830
|
+
), C += h, n.filter((I) => I).length <= 1) {
|
|
831
|
+
S = y, S.eta = e.utc().format(), S.distanceFromPrevious = h, S.distanceFromStart = Math.round((o + C) * 1e4) / 1e4, l.push(S), delete n[w + 1];
|
|
830
832
|
break;
|
|
831
833
|
}
|
|
832
834
|
} else {
|
|
833
835
|
u = i - f, e.add(u, "hour");
|
|
834
836
|
const I = J.roundPrecision(p.speed * u, 5);
|
|
835
|
-
S = W.calculateCoordinate(c, t.bearing, I, "nauticalmiles", !y.gcToPrevious), S.eta = e.utc().format(),
|
|
837
|
+
S = W.calculateCoordinate(c, t.bearing, I, "nauticalmiles", !y.gcToPrevious), S.eta = e.utc().format(), n[w] = S, F == null || F.debug(
|
|
836
838
|
`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,
|
|
837
839
|
m.requestId,
|
|
838
840
|
{ lat: S.lat, lng: S.lng },
|
|
839
841
|
{ lat: c.lat, lng: c.lng, etd: c.etd }
|
|
840
|
-
), C += I, S.distanceFromPrevious = Math.round(C * 1e4) / 1e4, S.distanceFromStart = Math.round((
|
|
842
|
+
), C += I, S.distanceFromPrevious = Math.round(C * 1e4) / 1e4, S.distanceFromStart = Math.round((o + C) * 1e4) / 1e4;
|
|
841
843
|
break;
|
|
842
844
|
}
|
|
843
845
|
}
|
|
844
|
-
return { etd: e, from: p, to: S, next:
|
|
846
|
+
return { etd: e, from: p, to: S, next: n.filter((w) => w), wps: l, days: b };
|
|
845
847
|
}
|
|
846
848
|
/**
|
|
847
849
|
* 洋流影响因子
|
|
@@ -853,8 +855,8 @@ class O {
|
|
|
853
855
|
const i = (t - (e == null ? void 0 : e.degree) || 0) / 180 * Math.PI;
|
|
854
856
|
if (Math.abs(i) === Math.PI / 2)
|
|
855
857
|
return 0;
|
|
856
|
-
let
|
|
857
|
-
return a & 2 ?
|
|
858
|
+
let o = ((e == null ? void 0 : e.kts) || 0) * Math.cos(i);
|
|
859
|
+
return a & 2 ? o = Math.ceil(o * 100) / 100 : a & 1 ? o = Math.floor(o * 100) / 100 : o = Math.round(o * 100) / 100, Math.abs(o) > 5 ? 0 : o;
|
|
858
860
|
}
|
|
859
861
|
/**
|
|
860
862
|
* 风浪影响因子
|
|
@@ -864,13 +866,13 @@ class O {
|
|
|
864
866
|
static weatherFactor(t, e) {
|
|
865
867
|
var M, l, b, f, C, S, p;
|
|
866
868
|
F == null || F.debug("calculate weather factor via: %j", { ...t, ...e });
|
|
867
|
-
const a = O.blockCoefficient(t.displacement, t.lbp, t.breadthMoulded, t.draught), i = O.froudeNumber(t.speed, t.lbp),
|
|
868
|
-
let
|
|
869
|
-
|
|
870
|
-
const s = O.directionFactor(
|
|
871
|
-
let r = s *
|
|
872
|
-
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, t.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), F == null || F.debug("wind wx factor = %d", r),
|
|
873
|
-
const m = O.waveHeightFactor(((p = (S = e == null ? void 0 : e.wave) == null ? void 0 : S.sig) == null ? void 0 : p.height) ?? 1,
|
|
869
|
+
const a = O.blockCoefficient(t.displacement, t.lbp, t.breadthMoulded, t.draught), i = O.froudeNumber(t.speed, t.lbp), o = O.amendFactor(a, i, t.loadCondition);
|
|
870
|
+
let n = Math.abs(t.bearing % 360 - (((M = e == null ? void 0 : e.wind) == null ? void 0 : M.degree) % 360 || 0));
|
|
871
|
+
n = n > 180 ? 360 - n : n;
|
|
872
|
+
const s = O.directionFactor(n, (l = e == null ? void 0 : e.wind) == null ? void 0 : l.scale), d = O.vesselTagFactor(t.displacement, t.loadCondition, t.tag, (b = e == null ? void 0 : e.wind) == null ? void 0 : b.scale);
|
|
873
|
+
let r = s * o * d / 100 * t.speed;
|
|
874
|
+
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, t.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), F == null || F.debug("wind wx factor = %d", r), n = Math.abs(t.bearing % 360 - (((C = (f = e == null ? void 0 : e.wave) == null ? void 0 : f.sig) == null ? void 0 : C.degree) % 360 || 0));
|
|
875
|
+
const m = O.waveHeightFactor(((p = (S = e == null ? void 0 : e.wave) == null ? void 0 : S.sig) == null ? void 0 : p.height) ?? 1, n);
|
|
874
876
|
return F == null || F.debug("wave wx factor = %d", m), r = Math.abs(r) > Math.abs(m) ? r : r * 0.3 + m * 0.7, F == null || F.debug("weather factor = %d", r), r = Math.abs(r) > 3 ? 3 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 2) * 0.1 : r, Math.round((r || 0) * 100) / 100;
|
|
875
877
|
}
|
|
876
878
|
/**
|
|
@@ -885,11 +887,11 @@ class O {
|
|
|
885
887
|
* @param useMeteo true 启用气象分析
|
|
886
888
|
* @param useRouteParam
|
|
887
889
|
*/
|
|
888
|
-
static async analyseInstant(t, e, a, i,
|
|
889
|
-
var z, G,
|
|
890
|
+
static async analyseInstant(t, e, a, i, o, n = "", s = 0, d = !0, r = !1, m = {}) {
|
|
891
|
+
var z, G, X, Q, Z, $;
|
|
890
892
|
const M = g().valueOf();
|
|
891
893
|
t.lng = J.convertToStdLng(t.lng);
|
|
892
|
-
const { route: l, waypoints: b } =
|
|
894
|
+
const { route: l, waypoints: b } = o.points, f = W.calculateSubRoute(t, l);
|
|
893
895
|
if (((z = f[0]) == null ? void 0 : z.length) <= 1)
|
|
894
896
|
return;
|
|
895
897
|
const { v0: C, label: S } = t.sog ? {
|
|
@@ -918,42 +920,42 @@ class O {
|
|
|
918
920
|
e = g(e).utc();
|
|
919
921
|
const Y = e.clone();
|
|
920
922
|
for (; h.length > 0; ) {
|
|
921
|
-
const q = s - e.hour() % s, V = Math.ceil(e.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4,
|
|
923
|
+
const q = s - e.hour() % s, V = Math.ceil(e.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4, E = await O.speedLoseInHoursStep(
|
|
922
924
|
p,
|
|
923
925
|
e,
|
|
924
926
|
Y,
|
|
925
927
|
V,
|
|
926
928
|
u,
|
|
927
929
|
h,
|
|
928
|
-
|
|
930
|
+
n,
|
|
929
931
|
d,
|
|
930
932
|
r,
|
|
931
933
|
m
|
|
932
934
|
);
|
|
933
|
-
(G =
|
|
935
|
+
(G = E.from) != null && G.speed && (y.hours.push(E.from), y.wps.push(...E.wps), y.days.push(...E.days)), h = E == null ? void 0 : E.next, h.length || y.hours.push(E == null ? void 0 : E.to), u += Math.round((((X = E == null ? void 0 : E.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
934
936
|
}
|
|
935
937
|
const j = y.hours;
|
|
936
938
|
for (let q = 0; q < j.length - 1; q++) {
|
|
937
939
|
const V = g(j[q + 1].eta).diff(j[q].etd, "hour", !0) || 1;
|
|
938
940
|
I += (j[q].wxFactor || 0) * V, k += (j[q].cFactor || 0) * V, D += V;
|
|
939
941
|
}
|
|
940
|
-
(
|
|
942
|
+
(Q = y.wps) == null || Q.forEach((q, V) => {
|
|
941
943
|
q.positionTime = g.utc(q.etd || q.eta).unix();
|
|
942
|
-
const
|
|
943
|
-
if (
|
|
944
|
-
const L = q.distanceFromStart -
|
|
944
|
+
const E = y.wps[V - 1];
|
|
945
|
+
if (E) {
|
|
946
|
+
const L = q.distanceFromStart - E.distanceFromStart, H = g(q.eta || q.etd).diff(g(E.etd || E.eta), "h", !0);
|
|
945
947
|
q.avgSpd = Math.round(L / H * 100) / 100;
|
|
946
|
-
const it = W.calculateBearing(
|
|
947
|
-
|
|
948
|
+
const it = W.calculateBearing(E, q);
|
|
949
|
+
E.bearing = it;
|
|
948
950
|
}
|
|
949
|
-
}), y.wps = (Z = y.wps) == null ? void 0 : Z.reduce((q, V) => (q.some((
|
|
950
|
-
const
|
|
951
|
-
c.distance = Math.round(T.distanceFromStart * 1e3) / 1e3, c.etd = g(
|
|
952
|
-
const { distanceInECA: N, hoursInECA:
|
|
951
|
+
}), y.wps = (Z = y.wps) == null ? void 0 : Z.reduce((q, V) => (q.some((E) => Math.round(E.positionTime / 60) === Math.round(V.positionTime / 60)) || q.push(V), q), []), c.sample = y;
|
|
952
|
+
const A = y.hours.at(0), T = y.hours.at(-1);
|
|
953
|
+
c.distance = Math.round(T.distanceFromStart * 1e3) / 1e3, c.etd = g(A.eta).utc().format(), c.eta = g(T.eta).utc().format(), c.wxFactor = Math.round(I / D * 1e3) / 1e3, c.cFactor = Math.round(k / D * 1e3) / 1e3, c.avgSpeed = Math.round(T.distanceFromStart / D * 1e3) / 1e3, c.totalHrs = Math.round(D * 1e3) / 1e3;
|
|
954
|
+
const { distanceInECA: N, hoursInECA: P, totalDgoConsInECA: R, eca: U } = await this.calculateECA(c, i, m), tt = J.roundPrecision(i.fo / 24 * (D - P), 3), at = J.roundPrecision(i.dgo / 24 * D, 3);
|
|
953
955
|
c.extend = {
|
|
954
956
|
eca: U,
|
|
955
957
|
distanceInECA: N,
|
|
956
|
-
hoursInECA:
|
|
958
|
+
hoursInECA: P,
|
|
957
959
|
totalDgoConsInECA: R
|
|
958
960
|
}, c.totalFoCons = tt < 0 ? 0 : tt, c.totalDgoCons = at;
|
|
959
961
|
const et = g().valueOf() - M, nt = (($ = y == null ? void 0 : y.hours) == null ? void 0 : $.length) || 1;
|
|
@@ -972,8 +974,8 @@ class O {
|
|
|
972
974
|
* @param useMeteo true 启用气象分析
|
|
973
975
|
* @param useRouteParam
|
|
974
976
|
*/
|
|
975
|
-
static async analyseInstantWithThreshed(t, e, a, i,
|
|
976
|
-
var
|
|
977
|
+
static async analyseInstantWithThreshed(t, e, a, i, o, n, s, d = "", r = 3, m = !0, M = !1, l = {}) {
|
|
978
|
+
var X, Q, Z, $, q, V;
|
|
977
979
|
const b = g().valueOf();
|
|
978
980
|
t.lng = J.convertToStdLng(t.lng);
|
|
979
981
|
const { v0: f, label: C } = t.sog ? {
|
|
@@ -981,14 +983,14 @@ class O {
|
|
|
981
983
|
label: t.label || "Other"
|
|
982
984
|
/* Instruct */
|
|
983
985
|
} : {
|
|
984
|
-
v0:
|
|
986
|
+
v0: o.speed,
|
|
985
987
|
label: "CP"
|
|
986
988
|
/* Cp */
|
|
987
|
-
}, S = O.assembleProperties(i,
|
|
988
|
-
if (((
|
|
989
|
+
}, S = O.assembleProperties(i, o.loadCondition, f, 0), p = W.calculateSubRoute(t, n);
|
|
990
|
+
if (((X = p[0]) == null ? void 0 : X.length) <= 1)
|
|
989
991
|
return;
|
|
990
992
|
const w = s.length ? W.calculateSubWaypoints(t, s) : [];
|
|
991
|
-
w.forEach((
|
|
993
|
+
w.forEach((E) => E.important = !0);
|
|
992
994
|
let c = W.simplifyRouteToCoordinates(p, w, 0), y = 0, h = 0, u = 0, I = 0;
|
|
993
995
|
const k = {
|
|
994
996
|
hours: [],
|
|
@@ -998,52 +1000,52 @@ class O {
|
|
|
998
1000
|
e = g(e).utc();
|
|
999
1001
|
const D = e.clone();
|
|
1000
1002
|
for (; c.length > 0; ) {
|
|
1001
|
-
const
|
|
1002
|
-
let L = Math.ceil(e.clone().add(
|
|
1003
|
+
const E = r - e.hour() % r;
|
|
1004
|
+
let L = Math.ceil(e.clone().add(E, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4;
|
|
1003
1005
|
L = e.clone().add(L, "h").isSameOrAfter(a) ? a.diff(e, "h", !0) * 1e4 / 1e4 : L;
|
|
1004
1006
|
const H = await O.speedLoseInHoursStep(S, e, D, L, y, c, d, m, M, l);
|
|
1005
|
-
if ((
|
|
1007
|
+
if ((Q = H.from) != null && Q.speed && (k.hours.push(H.from), H != null && H.wps && k.wps.push(...H.wps), k.days.push(...H.days)), c = H == null ? void 0 : H.next, c.length || k.hours.push(H == null ? void 0 : H.to), y += Math.round((((Z = H == null ? void 0 : H.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
|
|
1006
1008
|
break;
|
|
1007
1009
|
}
|
|
1008
|
-
k.wps = ($ = k.wps) == null ? void 0 : $.reduce((
|
|
1010
|
+
k.wps = ($ = k.wps) == null ? void 0 : $.reduce((E, L) => (E.some((H) => Math.round(g(H.etd).unix() / 60) === Math.round(g(L.etd).unix() / 60)) || E.push(L), E), []), (q = k.wps) == null || q.forEach((E, L) => {
|
|
1009
1011
|
const H = k.wps[L - 1];
|
|
1010
1012
|
if (H) {
|
|
1011
|
-
const it =
|
|
1012
|
-
|
|
1013
|
-
const ut = W.calculateBearing(H,
|
|
1013
|
+
const it = E.distanceFromStart - H.distanceFromStart, dt = g(E.eta || E.etd).diff(g(H.etd || H.eta), "h", !0);
|
|
1014
|
+
E.avgSpd = Math.round(it / dt * 100) / 100;
|
|
1015
|
+
const ut = W.calculateBearing(H, E);
|
|
1014
1016
|
H.bearing = ut;
|
|
1015
1017
|
}
|
|
1016
1018
|
});
|
|
1017
1019
|
const Y = k.hours;
|
|
1018
|
-
for (let
|
|
1019
|
-
const L = g(Y[
|
|
1020
|
-
h += Y[
|
|
1020
|
+
for (let E = 0; E < Y.length - 1; E++) {
|
|
1021
|
+
const L = g(Y[E + 1].eta).diff(Y[E].etd, "hour", !0);
|
|
1022
|
+
h += Y[E].wxFactor * L, u += Y[E].cFactor * L, I += L;
|
|
1021
1023
|
}
|
|
1022
|
-
const j = k.hours.at(0),
|
|
1024
|
+
const j = k.hours.at(0), A = k.hours.at(-1), T = await W.calculateRangeRoute(j, A, p), N = await W.calculateRangeWaypoints(j, A, p, w), P = {
|
|
1023
1025
|
sample: k,
|
|
1024
|
-
distance: Math.round(((
|
|
1026
|
+
distance: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1025
1027
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1026
1028
|
etd: g(j.eta).utc().format(),
|
|
1027
|
-
eta: g(
|
|
1029
|
+
eta: g(A == null ? void 0 : A.eta).utc().format(),
|
|
1028
1030
|
wxFactor: Math.round(h / I * 1e3) / 1e3,
|
|
1029
1031
|
cFactor: Math.round(u / I * 1e3) / 1e3,
|
|
1030
|
-
avgSpeed: Math.round(((
|
|
1032
|
+
avgSpeed: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) / I * 1e3) / 1e3,
|
|
1031
1033
|
totalHrs: Math.round(I * 1e3) / 1e3,
|
|
1032
1034
|
from: j,
|
|
1033
|
-
to:
|
|
1035
|
+
to: A,
|
|
1034
1036
|
route: T,
|
|
1035
1037
|
waypoints: N,
|
|
1036
1038
|
v0: f,
|
|
1037
1039
|
label: C
|
|
1038
|
-
}, { distanceInECA: R, hoursInECA: U, totalDgoConsInECA: tt, eca: at } = await this.calculateECA(
|
|
1039
|
-
|
|
1040
|
+
}, { distanceInECA: R, hoursInECA: U, totalDgoConsInECA: tt, eca: at } = await this.calculateECA(P, o, l), ot = J.roundPrecision(o.fo / 24 * (I - U), 3), et = J.roundPrecision(o.dgo / 24 * I, 3);
|
|
1041
|
+
P.extend = {
|
|
1040
1042
|
eca: at,
|
|
1041
1043
|
distanceInECA: R,
|
|
1042
1044
|
hoursInECA: U,
|
|
1043
1045
|
totalDgoConsInECA: tt
|
|
1044
|
-
},
|
|
1046
|
+
}, P.totalDgoCons = et, P.totalFoCons = ot < 0 ? 0 : ot;
|
|
1045
1047
|
const z = g().valueOf() - b, G = ((V = k == null ? void 0 : k.hours) == null ? void 0 : V.length) || 1;
|
|
1046
|
-
return F == null || F.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, z, G, Math.round(z / G * 1e3) / 1e3),
|
|
1048
|
+
return F == null || F.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, z, G, Math.round(z / G * 1e3) / 1e3), P;
|
|
1047
1049
|
}
|
|
1048
1050
|
/**
|
|
1049
1051
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1060,9 +1062,9 @@ class O {
|
|
|
1060
1062
|
* @param lane 基础航线(重要转向点)
|
|
1061
1063
|
* @param options
|
|
1062
1064
|
*/
|
|
1063
|
-
static async analyseCost(t, e, a, i,
|
|
1065
|
+
static async analyseCost(t, e, a, i, o = {}) {
|
|
1064
1066
|
var p, w;
|
|
1065
|
-
const
|
|
1067
|
+
const n = g().valueOf(), s = [];
|
|
1066
1068
|
t.speedStep = t.speedStep || 3, t.alterStep = t.alterStep ?? 1;
|
|
1067
1069
|
const d = W.calculateRouteDistance(i.route);
|
|
1068
1070
|
let r = 0;
|
|
@@ -1085,9 +1087,9 @@ class O {
|
|
|
1085
1087
|
t.speedStep,
|
|
1086
1088
|
t.useMeteo,
|
|
1087
1089
|
t.useRouteParam,
|
|
1088
|
-
|
|
1090
|
+
o
|
|
1089
1091
|
);
|
|
1090
|
-
u && (await O.calculateCost(u, c, t,
|
|
1092
|
+
u && (await O.calculateCost(u, c, t, o), s.push(u), F == null || F.info("[%s][L%d-%d] analyse from %s to %s cost: %j", o.requestId, 1, M, t.etd, m.format(), {
|
|
1091
1093
|
cost: u.cost.total,
|
|
1092
1094
|
hire: u.cost.hire,
|
|
1093
1095
|
bunker: u.cost.bunker,
|
|
@@ -1104,15 +1106,15 @@ class O {
|
|
|
1104
1106
|
k = k > 7 ? 7 : k < t.alterStep ? t.alterStep : k;
|
|
1105
1107
|
let D = 2, Y = { combined: !1, speeds: [b], cost: (w = b.cost) == null ? void 0 : w.total }, j;
|
|
1106
1108
|
for (; k >= t.alterStep; ) {
|
|
1107
|
-
const
|
|
1108
|
-
if (Y.cost >
|
|
1109
|
+
const A = await O.combinedAnalyse(t, e, m, [c, y], i, k, { ...o, level: D });
|
|
1110
|
+
if (Y.cost > A.cost ? j ? (j == null ? void 0 : j.cost) > A.cost && (j = A) : (j = Y, Y = A) : (!j || (j == null ? void 0 : j.cost) > A.cost) && (j = A), k <= t.alterStep)
|
|
1109
1111
|
break;
|
|
1110
1112
|
k = Math.ceil(k / 2), D += 1;
|
|
1111
1113
|
}
|
|
1112
1114
|
f.push(Y), j && f.push(j);
|
|
1113
1115
|
}
|
|
1114
|
-
const S = g().valueOf() -
|
|
1115
|
-
return F == null || F.info("[%s] analyse elapsed: %d ms",
|
|
1116
|
+
const S = g().valueOf() - n;
|
|
1117
|
+
return F == null || F.info("[%s] analyse elapsed: %d ms", o == null ? void 0 : o.requestId, S), f.sort((c, y) => c.cost - y.cost);
|
|
1116
1118
|
}
|
|
1117
1119
|
/**
|
|
1118
1120
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1124,9 +1126,9 @@ class O {
|
|
|
1124
1126
|
* @param step 步长,7,4,2,1
|
|
1125
1127
|
* @param options
|
|
1126
1128
|
*/
|
|
1127
|
-
static async combinedAnalyse(t, e, a, i,
|
|
1128
|
-
s.counter = 1, F == null || F.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level,
|
|
1129
|
-
const d = await O.alternateAnalyse(t, e, a, i, 0,
|
|
1129
|
+
static async combinedAnalyse(t, e, a, i, o, n, s = {}) {
|
|
1130
|
+
s.counter = 1, F == null || F.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, n);
|
|
1131
|
+
const d = await O.alternateAnalyse(t, e, a, i, 0, o, n, s), r = d.reduce((y, h) => y + h.cost.total, 0), m = d.reduce((y, h) => y + h.cost.hire, 0), M = d.reduce((y, h) => y + h.cost.bunker, 0), l = d.reduce((y, h) => y + h.distance, 0), b = d.reduce((y, h) => y + h.totalHrs, 0);
|
|
1130
1132
|
F == null || F.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
|
|
1131
1133
|
cost: r,
|
|
1132
1134
|
hire: m,
|
|
@@ -1134,14 +1136,14 @@ class O {
|
|
|
1134
1136
|
distance: l,
|
|
1135
1137
|
hours: b
|
|
1136
1138
|
});
|
|
1137
|
-
const f = await O.alternateAnalyse(t, e, a, i, 1,
|
|
1139
|
+
const f = await O.alternateAnalyse(t, e, a, i, 1, o, n, s), C = f.reduce((y, h) => y + h.cost.total, 0), S = f.reduce((y, h) => y + h.cost.hire, 0), p = f.reduce((y, h) => y + h.cost.bunker, 0), w = f.reduce((y, h) => y + h.distance, 0), c = f.reduce((y, h) => y + h.totalHrs, 0);
|
|
1138
1140
|
return F == null || F.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
|
|
1139
1141
|
cost: C,
|
|
1140
1142
|
hire: S,
|
|
1141
1143
|
bunker: p,
|
|
1142
1144
|
distance: w,
|
|
1143
1145
|
hours: c
|
|
1144
|
-
}), r < C ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step:
|
|
1146
|
+
}), r < C ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step: n } : { combined: !0, cost: Math.round(C * 1e3) / 1e3, speeds: f, step: n };
|
|
1145
1147
|
}
|
|
1146
1148
|
/**
|
|
1147
1149
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1154,12 +1156,12 @@ class O {
|
|
|
1154
1156
|
* @param step 步长,7,4,2,1
|
|
1155
1157
|
* @param options
|
|
1156
1158
|
*/
|
|
1157
|
-
static async alternateAnalyse(t, e, a, i,
|
|
1159
|
+
static async alternateAnalyse(t, e, a, i, o, n, s, d = {}) {
|
|
1158
1160
|
var l, b;
|
|
1159
1161
|
let r = g.utc(t.etd);
|
|
1160
1162
|
const m = { lat: t.lat, lng: t.lng }, M = [];
|
|
1161
1163
|
for (; r.isBefore(a); ) {
|
|
1162
|
-
const f = r.clone().utc().add(s, "day"), C = JSON.parse(JSON.stringify(
|
|
1164
|
+
const f = r.clone().utc().add(s, "day"), C = JSON.parse(JSON.stringify(n.route)), S = JSON.parse(JSON.stringify(n.waypoints)), p = i[o], w = await O.analyseInstantWithThreshed(
|
|
1163
1165
|
m,
|
|
1164
1166
|
r.utc().format(),
|
|
1165
1167
|
f,
|
|
@@ -1191,7 +1193,7 @@ class O {
|
|
|
1191
1193
|
)), d.counter = d.counter + 1;
|
|
1192
1194
|
const c = (b = (l = w == null ? void 0 : w.sample) == null ? void 0 : l.hours) == null ? void 0 : b.at(-1);
|
|
1193
1195
|
if (c)
|
|
1194
|
-
m.lat = c.lat, m.lng = c.lng, r = g(c.eta), M.push(w),
|
|
1196
|
+
m.lat = c.lat, m.lng = c.lng, r = g(c.eta), M.push(w), o = o ? 0 : 1;
|
|
1195
1197
|
else
|
|
1196
1198
|
break;
|
|
1197
1199
|
}
|
|
@@ -1205,9 +1207,9 @@ class O {
|
|
|
1205
1207
|
* @param options
|
|
1206
1208
|
*/
|
|
1207
1209
|
static async calculateCost(t, e, a, i = {}) {
|
|
1208
|
-
var
|
|
1210
|
+
var o;
|
|
1209
1211
|
if (t) {
|
|
1210
|
-
const
|
|
1212
|
+
const n = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, s = Math.round(t.totalHrs / 24 * (a.dailyHire || 0) * (1 - n) * 1e3) / 1e3, d = Math.round(t.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, r = Math.round((t.totalDgoCons + (((o = t.extend) == null ? void 0 : o.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
|
|
1211
1213
|
t.cost = {
|
|
1212
1214
|
total: Math.round((s + d + r) * 1e3) / 1e3,
|
|
1213
1215
|
hire: s,
|
|
@@ -1224,18 +1226,18 @@ class O {
|
|
|
1224
1226
|
static async calculateECA(t, e, a = {}) {
|
|
1225
1227
|
var d, r, m, M;
|
|
1226
1228
|
const i = await W.intersectInECA((t == null ? void 0 : t.route) || []);
|
|
1227
|
-
let
|
|
1229
|
+
let o = 0, n = 0, s = 0;
|
|
1228
1230
|
(r = (d = t == null ? void 0 : t.sample) == null ? void 0 : d.wps) == null || r.forEach((l) => {
|
|
1229
1231
|
l.positionTime = g.utc(l.etd || l.eta).unix();
|
|
1230
1232
|
});
|
|
1231
1233
|
for (const l of i) {
|
|
1232
|
-
|
|
1234
|
+
o += l.distance;
|
|
1233
1235
|
const b = await W.deadReckoningTime((m = l.waypoints) == null ? void 0 : m.at(0), t.sample.wps), f = await W.deadReckoningTime((M = l.waypoints) == null ? void 0 : M.at(-1), t.sample.wps);
|
|
1234
|
-
l.in = b, l.out = f, l.totalHrs = J.roundPrecision((f.positionTime - b.positionTime) / 3600, 3), l.totalDgoCons = J.roundPrecision(e.fo / 24 * l.totalHrs, 3),
|
|
1236
|
+
l.in = b, l.out = f, l.totalHrs = J.roundPrecision((f.positionTime - b.positionTime) / 3600, 3), l.totalDgoCons = J.roundPrecision(e.fo / 24 * l.totalHrs, 3), n += l.totalHrs, s += l.totalDgoCons;
|
|
1235
1237
|
}
|
|
1236
|
-
return
|
|
1237
|
-
distanceInECA:
|
|
1238
|
-
hoursInECA:
|
|
1238
|
+
return o = J.roundPrecision(o, 3), n = J.roundPrecision(n, 3), s = J.roundPrecision(s, 3), {
|
|
1239
|
+
distanceInECA: o,
|
|
1240
|
+
hoursInECA: n,
|
|
1239
1241
|
totalDgoConsInECA: s,
|
|
1240
1242
|
eca: i
|
|
1241
1243
|
};
|
|
@@ -1251,16 +1253,16 @@ class O {
|
|
|
1251
1253
|
hours: [],
|
|
1252
1254
|
wps: [],
|
|
1253
1255
|
days: []
|
|
1254
|
-
}, i = t.reduce((h, u) => h + u.distance, 0),
|
|
1256
|
+
}, i = t.reduce((h, u) => h + u.distance, 0), o = t.reduce((h, u) => {
|
|
1255
1257
|
var I;
|
|
1256
1258
|
return h + (((I = u.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1257
|
-
}, 0),
|
|
1259
|
+
}, 0), n = t.reduce((h, u) => h + u.totalHrs, 0), s = t.reduce((h, u) => {
|
|
1258
1260
|
var I;
|
|
1259
1261
|
return h + (((I = u.extend) == null ? void 0 : I.hoursInECA) || 0);
|
|
1260
1262
|
}, 0), d = t.reduce((h, u) => {
|
|
1261
1263
|
var I;
|
|
1262
1264
|
return h + (((I = u.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1263
|
-
}, 0), r = t.reduce((h, u) => h + u.wxFactor * u.totalHrs /
|
|
1265
|
+
}, 0), r = t.reduce((h, u) => h + u.wxFactor * u.totalHrs / n, 0), m = t.reduce((h, u) => h + u.cFactor * u.totalHrs / n, 0), M = t.reduce((h, u) => h + u.totalFoCons, 0), l = t.reduce((h, u) => h + u.totalDgoCons, 0), b = t.reduce((h, u) => h + u.cost.total, 0), f = t.reduce((h, u) => h + u.cost.hire, 0), C = t.reduce((h, u) => h + u.cost.bunker, 0), S = [], p = [];
|
|
1264
1266
|
let w;
|
|
1265
1267
|
for (const h of t) {
|
|
1266
1268
|
p.push(...((c = h.extend) == null ? void 0 : c.eca) || []);
|
|
@@ -1274,17 +1276,17 @@ class O {
|
|
|
1274
1276
|
})), D.cp = h.cost.cp;
|
|
1275
1277
|
const Y = [h.etd, h.eta], j = S.findIndex((T) => T.id === D.cp.id);
|
|
1276
1278
|
j === -1 ? (D.cp.segment = [Y], S.push(D.cp)) : S[j].segment.push(Y), u.forEach((T) => {
|
|
1277
|
-
var
|
|
1278
|
-
((
|
|
1279
|
+
var P;
|
|
1280
|
+
((P = a.hours) == null ? void 0 : P.findIndex((R) => R.eta === T.eta)) === -1 && a.hours.push(T);
|
|
1279
1281
|
}), I.forEach((T) => {
|
|
1280
|
-
var
|
|
1281
|
-
((
|
|
1282
|
+
var P;
|
|
1283
|
+
((P = a.wps) == null ? void 0 : P.findIndex((R) => R.eta === T.eta)) === -1 && a.wps.push(T);
|
|
1282
1284
|
}), k.forEach((T) => {
|
|
1283
|
-
var
|
|
1284
|
-
((
|
|
1285
|
+
var P;
|
|
1286
|
+
((P = a == null ? void 0 : a.days) == null ? void 0 : P.findIndex((R) => R.eta === T.eta)) === -1 && a.days.push(T);
|
|
1285
1287
|
});
|
|
1286
|
-
const
|
|
1287
|
-
|
|
1288
|
+
const A = (y = a.wps) == null ? void 0 : y.findIndex((T) => T.eta === D.eta);
|
|
1289
|
+
A === -1 ? a.wps.push(D) : a.wps[A] = D, w = u.at(-1);
|
|
1288
1290
|
}
|
|
1289
1291
|
return a.wps.sort((h, u) => {
|
|
1290
1292
|
g(h.etd).unix() - g(u.etd).unix();
|
|
@@ -1305,8 +1307,8 @@ class O {
|
|
|
1305
1307
|
v0: t.at(0).v0,
|
|
1306
1308
|
label: "Combined",
|
|
1307
1309
|
distance: Math.round(i * 1e3) / 1e3,
|
|
1308
|
-
totalHrs: Math.round(
|
|
1309
|
-
avgSpeed: Math.round(i /
|
|
1310
|
+
totalHrs: Math.round(n * 1e3) / 1e3,
|
|
1311
|
+
avgSpeed: Math.round(i / n * 1e3) / 1e3,
|
|
1310
1312
|
wxFactor: Math.round(r * 1e3) / 1e3,
|
|
1311
1313
|
cFactor: Math.round(m * 1e3) / 1e3,
|
|
1312
1314
|
totalFoCons: Math.round(M * 1e3) / 1e3,
|
|
@@ -1319,7 +1321,7 @@ class O {
|
|
|
1319
1321
|
extend: {
|
|
1320
1322
|
cps: S,
|
|
1321
1323
|
eca: p,
|
|
1322
|
-
distanceInECA: Math.round(
|
|
1324
|
+
distanceInECA: Math.round(o * 1e3) / 1e3,
|
|
1323
1325
|
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1324
1326
|
totalDgoConsInECA: Math.round(d * 1e3) / 1e3,
|
|
1325
1327
|
speeds: t
|
|
@@ -1331,10 +1333,10 @@ export {
|
|
|
1331
1333
|
st as AISImpl,
|
|
1332
1334
|
yt as AlertHelper,
|
|
1333
1335
|
mt as AlertLevel,
|
|
1334
|
-
|
|
1336
|
+
xt as HifleetImpl,
|
|
1335
1337
|
gt as LoadCondition,
|
|
1336
1338
|
Nt as MyShipImpl,
|
|
1337
|
-
|
|
1339
|
+
Et as MyVesselImpl,
|
|
1338
1340
|
jt as ShipxyImpl,
|
|
1339
1341
|
O as SpeedHelper,
|
|
1340
1342
|
wt as SpeedLabel,
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(A,R){typeof exports=="object"&&typeof module<"u"?R(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"],R):(A=typeof globalThis<"u"?globalThis:A||self,R(A["idm-plugin-vessel"]={},A.got,A["@log4js-node/log4js-api"],A.moment,A["@idm-plugin/geo2"],A["@idm-plugin/meteo2"],A["@idm-plugin/meteo"]))})(this,function(A,R,K,p,T,mt,nt){"use strict";var St=Object.defineProperty;var kt=(A,R,K)=>R in A?St(A,R,{enumerable:!0,configurable:!0,writable:!0,value:K}):A[R]=K;var z=(A,R,K)=>(kt(A,typeof R!="symbol"?R+"":R,K),K);let g;try{g=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(t){let e,a;switch(t){case 0:e="在航(主机推动)",a="Underway Using Engine";break;case 1:e="锚泊",a="Anchored";break;case 2:e="失控",a="Not operated";break;case 3:e="操纵受限",a="Limited airworthiness";break;case 4:e="吃水受限",a="Limited by ship's draft";break;case 5:e="靠泊",a="Mooring";break;case 6:e="搁浅",a="Stranded";break;case 7:e="捕捞作业",a="Engaged in fishing";break;case 8:e="靠帆船提供动力",a="Sailing";break;default:e="未定义",a="Undefined"}return{labelCn:e,labelEn:a}}}class yt extends G{constructor(e,a){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=e,this.clientSecret=a}async authToken(e={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await R.post(a,i).json();g==null||g.info("[%s] fetch access token from: %s - %j",e.requestId,a,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:p().utc().format()})}async realTimePosition(e,a={}){var d,r,m;(!this.token||p().diff(p(this.token.issuedAt),"seconds")>((d=this.token)==null?void 0:d.expiresIn)-300)&&await this.authToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(m=this.token)==null?void 0:m.accessToken}`},searchParams:{mmsi:e}};g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,o);const n=await R.get(i,o).json();if(n.code)return g==null||g.warn("[%s] fetch realtime position failed: %j",a.requestId,i,{message:n.message,status:n.status,code:n.code}),n;const s=n.data;for(const M in s)!isNaN(s[M])&&Number(s[M])!==1/0&&(s[M]=Number(s[M]));if(s){const M=p(`${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)?p.utc(s.eta).format():void 0,destination:s.dest,positionTime:M.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:M.utc().format()}}else return{}}async trajectory(e,a,i,o,n=!0,s={}){(!this.token||p().diff(p(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(e,s),r=p(a),m=p(i),M=[];for(;m.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(e,r,r.clone().add(30,"day"),d,o,M,s),r.add(30,"day");return await this.trajectoryIn30Day(e,r,m,d,o,M,s),M}async trajectoryIn30Day(e,a,i,o,n,s,d={}){var f,C,k,w,v;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",m={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(C=this.token)==null?void 0:C.accessToken}`},json:{mmsi:e,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};g==null||g.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,m);const M=await R.post(r,m).json();if(M.code)return g==null||g.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:M.message,status:M.status,code:M.code}),M;let h=-1;const b=p(`${(w=(k=M.data)==null?void 0:k[0])==null?void 0:w.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=M.data)==null||v.forEach(c=>{for(const P in c)!isNaN(c[P])&&Number(c[P])!==1/0&&(c[P]=Number(c[P]));const y=p(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),l=c.status,{labelCn:u,labelEn:I}=this.parseStatus(l),F={mmsi:c.mmsi,imo:o==null?void 0:o.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:l,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?p(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:y.unix(),labelCn:u,labelEn:I,method:"trajectory",vendor:"myVessel",utc:y.utc().format()},N=Math.floor(y.diff(b,"minute",!0)/(n||1));N!==h&&(h=N,s.push(F))}),s}}class Mt extends G{constructor(e){super();z(this,"token");this.token=e}async realTimePosition(e,a={}){const i="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:e,usertoken:this.token}},n=await R.post(i,o).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,o);const s=n==null?void 0:n.list;if(!s)return g==null||g.warn("[%s] fetch realtime position failed: %j",a.requestId,i,n),n;for(const b in s)!isNaN(s[b])&&Number(s[b])!==1/0&&(s[b]=Number(s[b]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:m}=this.parseStatus(d),M=p(`${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)?p.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:M.unix(),utc:M.utc().format(),status:d,labelCn:r,labelEn:m,method:"position",vendor:"hifleet"}}async search(e,a={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:e},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let n=await R.post(i,o).json();g==null||g.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,o),n instanceof Array&&(n=n[0]);for(const d in n)!isNaN(n[d])&&Number(n[d])!==1/0&&(n[d]=Number(n[d]));const s={mmsi:n.m,name:n.n,imo:n.i,callSign:n.c,length:n.l,breadth:n.b,draught:n.dr,type:n.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",n=await R.post(i,o).json(),g==null||g.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,o),n instanceof Array&&(n=n[0]),n&&(s.deadweight=Number(n.dwt)),s}async suggest(e,a={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",o={searchParams:{q:e},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},n=await R.post(i,o).json();g==null||g.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,o);const s=[];for(const d of n)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(e,a,i,o,n=!0,s={}){var c,y,l;const d=await this.realTimePosition(e,s);let r=p(a);const m=p(i),M=p();if(n){let u=m.diff(r,"d",!0);u<0?r=m.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=m.clone().subtract(80,"d"),u=M.diff(m,"d",!0),m.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:m.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:e,usertoken:this.token}},b="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await R.get(b,h).json();g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,b,h);let C;f&&(C=((y=(c=f.ships)==null?void 0:c.offors)==null?void 0:y.ship)||[],C.length||g==null||g.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const k=[];let w=-1;const v=p(`${(l=C==null?void 0:C[0])==null?void 0:l.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of C){for(const L in u)!isNaN(u[L])&&Number(u[L])!==1/0&&(u[L]=Number(u[L]));const I=p(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:F,labelCn:N}=this.parseStatus(u.status),P={mmsi:u.m,name:u.n,imo:d==null?void 0:d.imo,lat:u.la,lng:u.lo,draught:u.draught,sog:u.sp,cog:u.co,hdg:u.hdg,positionTime:I.unix(),utc:I.utc().format(),status:u.status,labelCn:N,labelEn:F,method:"trajectory",vendor:"hifleet"},E=Math.floor(I.diff(v,"minute",!0)/(o||1));E!==w&&(w=E,k.push(P))}return k}}class pt extends G{constructor(e){super();z(this,"token");this.token=e}async realTimePosition(e,a={}){const i={searchParams:{id:e,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",n=await R.get(o,i).json();if(g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,i),(n==null?void 0:n.status)!==0)return n;const s=n.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),m=p.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:m.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(e,a,i,o,n=!0,s={}){var v;const d=await this.realTimePosition(e,s),r=p(a),m=p(i),M="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:e,k:this.token,enc:1,cut:0,btm:r.unix(),etm:m.unix()}},b=await R.get(M,h).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,M,h),(b==null?void 0:b.status)!==0)return b;const f=b==null?void 0:b.points,C=[],k=p.unix((v=f[0])==null?void 0:v.utc);let w=-1;for(const c of f){const y=p.unix(c.utc),l={imo:d==null?void 0:d.imo,mmsi:e,sog:Math.round(c.sog*3600/1e3/1852*100)/100,cog:Math.round(c.cog/100*100)/100,lat:Math.round(c.lat/1e6*1e5)/1e5,lng:Math.round(c.lon/1e6*1e5)/1e5,positionTime:y.unix(),utc:y.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(y.diff(k,"minute",!0)/(o||1));u!==w&&(w=u,C.push(l))}return C}}class bt extends G{constructor(e){super();z(this,"token");this.token=e}async getShipId(e,a={}){const i={headers:{appKey:this.token},json:{mmsiList:e}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",n=await R.post(o,i).json();return g==null||g.info("[%s] fetch ship id from: %s - %j",a.requestId,o,i),n.code!=="0"?n:n.data[0].shipId}async getShipInfo(e,a={}){const i={headers:{appKey:this.token},json:{shipId:e}},o="https://api3.myships.com/sp/ships/aissta",n=await R.post(o,i).json();if(g==null||g.info("[%s] fetch ship info from: %s - %j",a.requestId,o,i),n.code!=="0")return n;const s=n.data;let d=s.imo;return e==="407170"&&(d="9198379",g==null||g.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,e,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(e,a={}){const i=await this.getShipId(e,a),o=await this.getShipInfo(i,a),n={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await R.post(s,n).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,n);const r=d.data[0];for(const f in r)!isNaN(r[f])&&Number(r[f])!==1/0&&(r[f]=Number(r[f]));const{labelCn:m,labelEn:M}=await this.parseStatus(r.aisNavStatus),h=p.unix(r.posTime);return{...o,mmsi:e,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:h.utc().format(),status:r.aisNavStatus,labelEn:M,labelCn:m,method:"position",vendor:"myship"}}async trajectory(e,a,i,o,n=!0,s={}){const d=p(a),r=p(i),m=await this.getShipId(e),M=await this.getShipInfo(m),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(m,d.unix(),d.add(30,"day").unix(),M,e,o,h);return await this.trajectoryIn30Day(m,d.unix(),r.unix(),M,e,o,h),h}async trajectoryIn30Day(e,a,i,o,n,s,d,r={}){var k;const m={headers:{appKey:this.token},json:{shipId:e,startTime:a,endTime:i}},M="https://api3.myships.com/sp/ships/position/history",h=await R.post(M,m).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",r.requestId,M,m),h.code!=="0")return g==null||g.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const b=h.data;for(const w in b)!isNaN(b[w])&&Number(b[w])!==1/0&&(b[w]=Number(b[w]));const f=p.unix((k=b[0])==null?void 0:k.posTime);let C=-1;for(const w of b){const v=p.unix(w.posTime),c={imo:o==null?void 0:o.imo,mmsi:n,lat:Math.round(w.lat/1e4/60*1e5)/1e5,lng:Math.round(w.lon/1e4/60*1e5)/1e5,sog:Math.round(w.sog/10*100)/100,cog:Math.round(w.cog/10*100)/100,hdg:Math.round(w.heading*100)/100,rot:Math.round(w.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},y=Math.floor(v.diff(f,"minute",!0)/(s||1));y!==C&&(C=y,d.push(c))}return d}}let _;try{_=K.getLogger("vessel")}catch{}finally{}var dt=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(dt||{});class ut{parsePrinciple(t,e={}){var s,d,r;_==null||_.info("[%s] parse rule: %s",e.requestId,t);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=t.match(a)?(s=t.match(a))==null?void 0:s[0]:void 0,o=i==null?void 0:i.split(";");if(!o)return;const n={};for(let m=0;m<(o==null?void 0:o.length);m++){const M=(r=(d=o[m].match(a))==null?void 0:d[0])==null?void 0:r.split("],");if(m===0&&!M)n.scope=o[0];else if(M)for(let h=0,b=M.length;h<b;h++){const f=this.parseRule(M[h]);f&&(n[f.level]?f.key?n[f.level][f==null?void 0:f.key]=f:n[f.level]=f:f.key?n[f.level]={[f==null?void 0:f.key]:f}:n[f.level]=f)}}return n}parseRule(t,e={}){var n;_==null||_.debug("[%s] parse rule: %s",e.requestId,t),t=t.startsWith("[")?t:`[${t}`,t=t.endsWith("]")?t:`${t}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(n=t==null?void 0:t.match(a))==null?void 0:n[0],o=i==null?void 0:i.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(t,e,a={}){var f,C,k,w,v,c,y,l,u,I,F,N,P,E,L;let i=0,o=0,n=0,s=0;const d=Math.round(((C=(f=e==null?void 0:e.SEVERE)==null?void 0:f.sigWave)==null?void 0:C.number)*1.6*100)/100,r=(w=(k=e==null?void 0:e.SEVERE)==null?void 0:k.sigWave)==null?void 0:w.number,m=(c=(v=e==null?void 0:e.HEAVY)==null?void 0:v.sigWave)==null?void 0:c.number,M=Math.round((((l=(y=e==null?void 0:e.SEVERE)==null?void 0:y.wind)==null?void 0:l.number)+2)*100)/100,h=(I=(u=e==null?void 0:e.SEVERE)==null?void 0:u.wind)==null?void 0:I.number,b=(N=(F=e==null?void 0:e.HEAVY)==null?void 0:F.wind)==null?void 0:N.number;for(let x=0;x<(t==null?void 0:t.length);x++){const H=t[x],q=(E=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:E.sig,V=(L=H==null?void 0:H.meteo)==null?void 0:L.wind,U=x?p(H.eta).diff(p(t[x-1].eta),"hour",!0):0;s=U>s?U:s,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...q,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}),(q==null?void 0:q.height)>=d?H.isDangerous=!0:(q==null?void 0:q.height)>=r?H.isSevere=!0:(q==null?void 0:q.height)>=m&&(H.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:b}),(V==null?void 0:V.scale)>=M?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(V==null?void 0:V.scale)>h?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(V==null?void 0:V.scale)===b&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),i+=H.isDangerous?U:0,o+=H.isSevere?U:0,n+=H.isHeavy?U:0}return i=Math.round(i*100)/100,o=Math.round(o*100)/100,n=Math.round(n*100)/100,s=Math.round(s),{sample:t,dangerous:i,severe:o,heavy:n,step:s<3?3:s,wind:{dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:b},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}}}}const gt=new ut;let S;try{S=K.getLogger("vessel")}catch{}finally{}const vt=new mt.MeteoHelper2("",!0);var lt=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(lt||{}),ht=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(ht||{}),ft=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ft||{});class W{static blockCoefficient(t,e,a,i){let o=Math.round(t/(e*a*i)*100)/100;o=o<.55?.55:o>.85?.85:o;const n=[.55,.6,.65,.7,.75,.8,.85],s=n.map(d=>Math.abs(d-o));return n[s.indexOf(Math.min(...s))]}static froudeNumber(t,e,a=9.8){let i=Math.round(Math.sqrt(t*t/(a*e))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(t,e,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let 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.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[t];return a==="Laden"&&(n=i[t]),n[0]+n[1]*e+n[2]*Math.pow(e,2)}static directionFactor(t,e=0){let a;return t>30&&t<=60?a=(1.7-.03*Math.pow(e-4,2))/2:t>60&&t<=150?a=(.9-.06*Math.pow(e-6,2))/2:t>150&&t<=180?a=(.4-.03*Math.pow(e-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(t,e,a,i=0){i=i>6?i-.9*(i-6):i;let o;return a==="container"?o=.7*i+Math.pow(i,6.5)/(22*Math.pow(t,2/3)):e==="Ballast"?o=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(t,2/3)):o=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(t,2/3)),o}static waveHeightFactor(t,e){t=t<3?t*.7:t,t=t<0?.2:t,t=t>6?t-.9*(t-6):t,t=t>9?9:t;let a;return e>30&&e<=60?a=-.6:e>60&&e<=90?a=-.4:e>90&&e<=120?a=t<3?.4:-.3:e>120&&e<=150?a=t<3?.6:-.5:e>150&&e<=180?a=t<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(t,2)+.278*t)*1e4)/1e4}static assembleProperties(t,e,a,i){var h;const o=t.lbp??t.length??t.lengthOverall??198.9642,n=t.draught??8,s=t.breadthMoulded??t.breadth??t.breadthExtreme??32.4572,d=t.deadweight??67035.7773,r=((h=t==null?void 0:t.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:o,loadCondition:e,draught:n,breadthMoulded:s,displacement:Math.round((d/1.025+n*s*o*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(t,e,a,i="",o=2,n=!0,s=!1,d={}){let r;if(e.velocity&&s&&(t.speed=T.LngLatHelper.roundPrecision(e.velocity*1852/3600,6)),n){let m;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:f,marineModels:C}=await nt.Meteo2Assist.autoPickMeteoModel(i),k=await vt.spotForecast(e.lat,e.lng,a.utc().format(),!1,!1,!0,{...d,pastDays:1,forecastDays:1,weatherModels:f,marineModels:C}),[w]=nt.Meteo2Assist.pickHourly(k,a);m=nt.Meteo2Assist.toLegacy(w)}catch(f){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...e,eta:a.utc().format(),source:i},f)}const M=W.weatherFactor(t,m),h=W.currentFactor(t.bearing,m==null?void 0:m.current,o),b=Math.round((t.speed*1.943844+M+h)*100)/100;r={meteo:{...m},wxFactor:M,cFactor:h,speed:e.velocity&&s?e.velocity:b<0?1:b,eta:a.utc().format(),etd:a.utc().format()}}else r={wxFactor:0,cFactor:0,speed:e.velocity&&s?e.velocity:Math.round((t.speed*1.943844+0+0)*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete e.meteo,delete e.wxFactor,delete e.cFactor,delete e.speed,delete e.etd,{...r,...e}}static async speedLoseInHoursStep(t,e,a,i,o,n,s="",d=!0,r=!1,m={}){e.utc();const M=e.clone().add(14,"days"),h=[],b=[];let f=0,C=0,k,w;for(let v=0;v<n.length-1;v++){let c=n[v];c.distanceFromStart=Math.round((o+C)*1e3)/1e3;const y=n[v+1];if(t.bearing=T.LaneHelper.calculateBearing(c,y,!y.gcToPrevious),c.bearing=t.bearing,c.suspend&&r){c.eta=c.eta||e.utc().format(),c.elapsed=c.elapsed??0;const I=c.suspend-c.elapsed;if(i-f>I)i=i-f-I,e.add(I,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,e.add(F,"hour"),i=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,m.requestId,c),i===0)return c.distanceFromPrevious=C,{etd:e,from:w||c,to:c,next:n.filter(F=>F),wps:h,days:b}}else c.suspend=0;d=e.isAfter(M)?!1:d,c=await W.speedLoseAt(t,c,e,s,0,d,r,m),w=w||c,c.important&&h.push(c),e.isSameOrAfter(a)&&(b.push(c),a.add(24,"hour"));const l=T.LaneHelper.calculateDistance(c,y,!y.gcToPrevious);let u=Math.round(l/w.speed*1e5)/1e5;if(f+u<i){if(f+=u,e.add(u,"hour"),delete n[v],S==null||S.debug(`[%s] go to %j from %j with ${l}nm, and cost ${u} hours`,m.requestId,{lat:y.lat,lng:y.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),C+=l,n.filter(I=>I).length<=1){k=y,k.eta=e.utc().format(),k.distanceFromPrevious=l,k.distanceFromStart=Math.round((o+C)*1e4)/1e4,h.push(k),delete n[v+1];break}}else{u=i-f,e.add(u,"hour");const I=T.LngLatHelper.roundPrecision(w.speed*u,5);k=T.LaneHelper.calculateCoordinate(c,t.bearing,I,"nauticalmiles",!y.gcToPrevious),k.eta=e.utc().format(),n[v]=k,S==null||S.debug(`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,m.requestId,{lat:k.lat,lng:k.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),C+=I,k.distanceFromPrevious=Math.round(C*1e4)/1e4,k.distanceFromStart=Math.round((o+C)*1e4)/1e4;break}}return{etd:e,from:w,to:k,next:n.filter(v=>v),wps:h,days:b}}static currentFactor(t,e,a=0){const i=(t-(e==null?void 0:e.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let o=((e==null?void 0:e.kts)||0)*Math.cos(i);return a&2?o=Math.ceil(o*100)/100:a&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(t,e){var M,h,b,f,C,k,w;S==null||S.debug("calculate weather factor via: %j",{...t,...e});const a=W.blockCoefficient(t.displacement,t.lbp,t.breadthMoulded,t.draught),i=W.froudeNumber(t.speed,t.lbp),o=W.amendFactor(a,i,t.loadCondition);let n=Math.abs(t.bearing%360-(((M=e==null?void 0:e.wind)==null?void 0:M.degree)%360||0));n=n>180?360-n:n;const s=W.directionFactor(n,(h=e==null?void 0:e.wind)==null?void 0:h.scale),d=W.vesselTagFactor(t.displacement,t.loadCondition,t.tag,(b=e==null?void 0:e.wind)==null?void 0:b.scale);let r=s*o*d/100*t.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,t.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),S==null||S.debug("wind wx factor = %d",r),n=Math.abs(t.bearing%360-(((C=(f=e==null?void 0:e.wave)==null?void 0:f.sig)==null?void 0:C.degree)%360||0));const m=W.waveHeightFactor(((w=(k=e==null?void 0:e.wave)==null?void 0:k.sig)==null?void 0:w.height)??1,n);return S==null||S.debug("wave wx factor = %d",m),r=Math.abs(r)>Math.abs(m)?r:r*.3+m*.7,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>3?3*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-2)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(t,e,a,i,o,n="",s=0,d=!0,r=!1,m={}){var Q,X,Z,$,tt,et;const M=p().valueOf();t.lng=T.LngLatHelper.convertToStdLng(t.lng);const{route:h,waypoints:b}=o.points,f=T.LaneHelper.calculateSubRoute(t,h);if(((Q=f[0])==null?void 0:Q.length)<=1)return;const{v0:C,label:k}=t.sog?{v0:t.sog,label:t.label||"Other"}:{v0:i.speed,label:"CP"},w=W.assembleProperties(a,i.loadCondition,C,0),v=b.length?T.LaneHelper.calculateSubWaypoints(t,b):[];v.forEach(Y=>Y.important=!0);const c={from:{...t},route:f,waypoints:v,v0:C,label:k},y={hours:[],days:[],wps:[]};s||(T.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let l=T.LaneHelper.simplifyRouteToCoordinates(f,v,0),u=0,I=0,F=0,N=0;e=p(e).utc();const P=e.clone();for(;l.length>0;){const Y=s-e.hour()%s,J=Math.ceil(e.clone().add(Y,"h").set({minute:0,second:0,millisecond:0}).diff(e,"h",!0)*1e4)/1e4,j=await W.speedLoseInHoursStep(w,e,P,J,u,l,n,d,r,m);(X=j.from)!=null&&X.speed&&(y.hours.push(j.from),y.wps.push(...j.wps),y.days.push(...j.days)),l=j==null?void 0:j.next,l.length||y.hours.push(j==null?void 0:j.to),u+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const E=y.hours;for(let Y=0;Y<E.length-1;Y++){const J=p(E[Y+1].eta).diff(E[Y].etd,"hour",!0)||1;I+=(E[Y].wxFactor||0)*J,F+=(E[Y].cFactor||0)*J,N+=J}($=y.wps)==null||$.forEach((Y,J)=>{Y.positionTime=p.utc(Y.etd||Y.eta).unix();const j=y.wps[J-1];if(j){const B=Y.distanceFromStart-j.distanceFromStart,O=p(Y.eta||Y.etd).diff(p(j.etd||j.eta),"h",!0);Y.avgSpd=Math.round(B/O*100)/100;const ct=T.LaneHelper.calculateBearing(j,Y);j.bearing=ct}}),y.wps=(tt=y.wps)==null?void 0:tt.reduce((Y,J)=>(Y.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||Y.push(J),Y),[]),c.sample=y;const L=y.hours.at(0),x=y.hours.at(-1);c.distance=Math.round(x.distanceFromStart*1e3)/1e3,c.etd=p(L.eta).utc().format(),c.eta=p(x.eta).utc().format(),c.wxFactor=Math.round(I/N*1e3)/1e3,c.cFactor=Math.round(F/N*1e3)/1e3,c.avgSpeed=Math.round(x.distanceFromStart/N*1e3)/1e3,c.totalHrs=Math.round(N*1e3)/1e3;const{distanceInECA:H,hoursInECA:q,totalDgoConsInECA:V,eca:U}=await this.calculateECA(c,i,m),st=T.LngLatHelper.roundPrecision(i.fo/24*(N-q),3),ot=T.LngLatHelper.roundPrecision(i.dgo/24*N,3);c.extend={eca:U,distanceInECA:H,hoursInECA:q,totalDgoConsInECA:V},c.totalFoCons=st<0?0:st,c.totalDgoCons=ot;const at=p().valueOf()-M,rt=((et=y==null?void 0:y.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",m==null?void 0:m.requestId,at,rt,Math.round(at/rt*1e3)/1e3),c}static async analyseInstantWithThreshed(t,e,a,i,o,n,s,d="",r=3,m=!0,M=!1,h={}){var Z,$,tt,et,Y,J;const b=p().valueOf();t.lng=T.LngLatHelper.convertToStdLng(t.lng);const{v0:f,label:C}=t.sog?{v0:t.sog,label:t.label||"Other"}:{v0:o.speed,label:"CP"},k=W.assembleProperties(i,o.loadCondition,f,0),w=T.LaneHelper.calculateSubRoute(t,n);if(((Z=w[0])==null?void 0:Z.length)<=1)return;const v=s.length?T.LaneHelper.calculateSubWaypoints(t,s):[];v.forEach(j=>j.important=!0);let c=T.LaneHelper.simplifyRouteToCoordinates(w,v,0),y=0,l=0,u=0,I=0;const F={hours:[],wps:[],days:[]};e=p(e).utc();const N=e.clone();for(;c.length>0;){const j=r-e.hour()%r;let B=Math.ceil(e.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(e,"h",!0)*1e4)/1e4;B=e.clone().add(B,"h").isSameOrAfter(a)?a.diff(e,"h",!0)*1e4/1e4:B;const O=await W.speedLoseInHoursStep(k,e,N,B,y,c,d,m,M,h);if(($=O.from)!=null&&$.speed&&(F.hours.push(O.from),O!=null&&O.wps&&F.wps.push(...O.wps),F.days.push(...O.days)),c=O==null?void 0:O.next,c.length||F.hours.push(O==null?void 0:O.to),y+=Math.round((((tt=O==null?void 0:O.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!B)break}F.wps=(et=F.wps)==null?void 0:et.reduce((j,B)=>(j.some(O=>Math.round(p(O.etd).unix()/60)===Math.round(p(B.etd).unix()/60))||j.push(B),j),[]),(Y=F.wps)==null||Y.forEach((j,B)=>{const O=F.wps[B-1];if(O){const ct=j.distanceFromStart-O.distanceFromStart,wt=p(j.eta||j.etd).diff(p(O.etd||O.eta),"h",!0);j.avgSpd=Math.round(ct/wt*100)/100;const It=T.LaneHelper.calculateBearing(O,j);O.bearing=It}});const P=F.hours;for(let j=0;j<P.length-1;j++){const B=p(P[j+1].eta).diff(P[j].etd,"hour",!0);l+=P[j].wxFactor*B,u+=P[j].cFactor*B,I+=B}const E=F.hours.at(0),L=F.hours.at(-1),x=await T.LaneHelper.calculateRangeRoute(E,L,w),H=await T.LaneHelper.calculateRangeWaypoints(E,L,w,v),q={sample:F,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:p(E.eta).utc().format(),eta:p(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(l/I*1e3)/1e3,cFactor:Math.round(u/I*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/I*1e3)/1e3,totalHrs:Math.round(I*1e3)/1e3,from:E,to:L,route:x,waypoints:H,v0:f,label:C},{distanceInECA:V,hoursInECA:U,totalDgoConsInECA:st,eca:ot}=await this.calculateECA(q,o,h),it=T.LngLatHelper.roundPrecision(o.fo/24*(I-U),3),at=T.LngLatHelper.roundPrecision(o.dgo/24*I,3);q.extend={eca:ot,distanceInECA:V,hoursInECA:U,totalDgoConsInECA:st},q.totalDgoCons=at,q.totalFoCons=it<0?0:it;const Q=p().valueOf()-b,X=((J=F==null?void 0:F.hours)==null?void 0:J.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,Q,X,Math.round(Q/X*1e3)/1e3),q}static async analyseCost(t,e,a,i,o={}){var w,v;const n=p().valueOf(),s=[];t.speedStep=t.speedStep||3,t.alterStep=t.alterStep??1;const d=T.LaneHelper.calculateRouteDistance(i.route);let r=0;a.forEach(c=>{const y=Math.ceil(d/c.speed/24);r=r<y?y:r}),r=r*1.3;const m=p.utc(t.etd).add(r??14,"day");let M=1;for(const c of a){const y=JSON.parse(JSON.stringify(i.route)),l=JSON.parse(JSON.stringify(i.waypoints)),u=await W.analyseInstantWithThreshed({lat:t.lat,lng:t.lng},t.etd,m,e,c,y,l,t.meteoVendor,t.speedStep,t.useMeteo,t.useRouteParam,o);u&&(await W.calculateCost(u,c,t,o),s.push(u),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",o.requestId,1,M,t.etd,m.format(),{cost:u.cost.total,hire:u.cost.hire,bunker:u.cost.bunker,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),M++}s.sort((c,y)=>c.cost.total-y.cost.total);const h=s.at(0),b=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(w=h.cost)==null?void 0:w.total}),b){const c=h.cost.cp,y=b.cost.cp,l=p(h.eta),u=p(h.etd),I=l.diff(u,"days",!0);let F=Math.ceil(I/2);F=F>7?7:F<t.alterStep?t.alterStep:F;let N=2,P={combined:!1,speeds:[b],cost:(v=b.cost)==null?void 0:v.total},E;for(;F>=t.alterStep;){const L=await W.combinedAnalyse(t,e,m,[c,y],i,F,{...o,level:N});if(P.cost>L.cost?E?(E==null?void 0:E.cost)>L.cost&&(E=L):(E=P,P=L):(!E||(E==null?void 0:E.cost)>L.cost)&&(E=L),F<=t.alterStep)break;F=Math.ceil(F/2),N+=1}f.push(P),E&&f.push(E)}const k=p().valueOf()-n;return S==null||S.info("[%s] analyse elapsed: %d ms",o==null?void 0:o.requestId,k),f.sort((c,y)=>c.cost-y.cost)}static async combinedAnalyse(t,e,a,i,o,n,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,n);const d=await W.alternateAnalyse(t,e,a,i,0,o,n,s),r=d.reduce((y,l)=>y+l.cost.total,0),m=d.reduce((y,l)=>y+l.cost.hire,0),M=d.reduce((y,l)=>y+l.cost.bunker,0),h=d.reduce((y,l)=>y+l.distance,0),b=d.reduce((y,l)=>y+l.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:r,hire:m,bunker:M,distance:h,hours:b});const f=await W.alternateAnalyse(t,e,a,i,1,o,n,s),C=f.reduce((y,l)=>y+l.cost.total,0),k=f.reduce((y,l)=>y+l.cost.hire,0),w=f.reduce((y,l)=>y+l.cost.bunker,0),v=f.reduce((y,l)=>y+l.distance,0),c=f.reduce((y,l)=>y+l.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:C,hire:k,bunker:w,distance:v,hours:c}),r<C?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:n}:{combined:!0,cost:Math.round(C*1e3)/1e3,speeds:f,step:n}}static async alternateAnalyse(t,e,a,i,o,n,s,d={}){var h,b;let r=p.utc(t.etd);const m={lat:t.lat,lng:t.lng},M=[];for(;r.isBefore(a);){const f=r.clone().utc().add(s,"day"),C=JSON.parse(JSON.stringify(n.route)),k=JSON.parse(JSON.stringify(n.waypoints)),w=i[o],v=await W.analyseInstantWithThreshed(m,r.utc().format(),f,e,w,C,k,t.meteoVendor,t.speedStep,t.useMeteo,t.useRouteParam,d);v&&(await W.calculateCost(v,w,t,d),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",d.requestId,d.level,d.counter,r.utc().format(),f.utc().format(),{cost:v.cost.total,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${w.speed}/${w.fo}/${w.dgo}`})),d.counter=d.counter+1;const c=(b=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:b.at(-1);if(c)m.lat=c.lat,m.lng=c.lng,r=p(c.eta),M.push(v),o=o?0:1;else break}return M}static async calculateCost(t,e,a,i={}){var o;if(t){const n=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round(t.totalHrs/24*(a.dailyHire||0)*(1-n)*1e3)/1e3,d=Math.round(t.totalFoCons*(a.priceFO||0)*1e3)/1e3,r=Math.round((t.totalDgoCons+(((o=t.extend)==null?void 0:o.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;t.cost={total:Math.round((s+d+r)*1e3)/1e3,hire:s,bunker:Math.round((d+r)*1e3)/1e3,cp:e}}return t}static async calculateECA(t,e,a={}){var d,r,m,M;const i=await T.LaneHelper.intersectInECA((t==null?void 0:t.route)||[]);let o=0,n=0,s=0;(r=(d=t==null?void 0:t.sample)==null?void 0:d.wps)==null||r.forEach(h=>{h.positionTime=p.utc(h.etd||h.eta).unix()});for(const h of i){o+=h.distance;const b=await T.LaneHelper.deadReckoningTime((m=h.waypoints)==null?void 0:m.at(0),t.sample.wps),f=await T.LaneHelper.deadReckoningTime((M=h.waypoints)==null?void 0:M.at(-1),t.sample.wps);h.in=b,h.out=f,h.totalHrs=T.LngLatHelper.roundPrecision((f.positionTime-b.positionTime)/3600,3),h.totalDgoCons=T.LngLatHelper.roundPrecision(e.fo/24*h.totalHrs,3),n+=h.totalHrs,s+=h.totalDgoCons}return o=T.LngLatHelper.roundPrecision(o,3),n=T.LngLatHelper.roundPrecision(n,3),s=T.LngLatHelper.roundPrecision(s,3),{distanceInECA:o,hoursInECA:n,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(t,e={}){var c,y;const a={hours:[],wps:[],days:[]},i=t.reduce((l,u)=>l+u.distance,0),o=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.distanceInECA)||0)},0),n=t.reduce((l,u)=>l+u.totalHrs,0),s=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.hoursInECA)||0)},0),d=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.totalDgoConsInECA)||0)},0),r=t.reduce((l,u)=>l+u.wxFactor*u.totalHrs/n,0),m=t.reduce((l,u)=>l+u.cFactor*u.totalHrs/n,0),M=t.reduce((l,u)=>l+u.totalFoCons,0),h=t.reduce((l,u)=>l+u.totalDgoCons,0),b=t.reduce((l,u)=>l+u.cost.total,0),f=t.reduce((l,u)=>l+u.cost.hire,0),C=t.reduce((l,u)=>l+u.cost.bunker,0),k=[],w=[];let v;for(const l of t){w.push(...((c=l.extend)==null?void 0:c.eca)||[]);const u=l.sample.hours,I=l.sample.wps,F=l.sample.days,N=u.at(0);v&&(N.distanceFromPrevious=v.distanceFromPrevious,N.distanceFromStart=v.distanceFromStart,u.forEach((x,H)=>{H&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)}),I.at(0).distanceFromPrevious=v.distanceFromPrevious,I.at(0).distanceFromStart=v.distanceFromStart,I.forEach((x,H)=>{H&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)}),F.at(0).distanceFromPrevious=v.distanceFromPrevious,F.at(0).distanceFromStart=v.distanceFromStart,F.forEach((x,H)=>{H&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)})),N.cp=l.cost.cp;const P=[l.etd,l.eta],E=k.findIndex(x=>x.id===N.cp.id);E===-1?(N.cp.segment=[P],k.push(N.cp)):k[E].segment.push(P),u.forEach(x=>{var q;((q=a.hours)==null?void 0:q.findIndex(V=>V.eta===x.eta))===-1&&a.hours.push(x)}),I.forEach(x=>{var q;((q=a.wps)==null?void 0:q.findIndex(V=>V.eta===x.eta))===-1&&a.wps.push(x)}),F.forEach(x=>{var q;((q=a==null?void 0:a.days)==null?void 0:q.findIndex(V=>V.eta===x.eta))===-1&&a.days.push(x)});const L=(y=a.wps)==null?void 0:y.findIndex(x=>x.eta===N.eta);L===-1?a.wps.push(N):a.wps[L]=N,v=u.at(-1)}return a.wps.sort((l,u)=>{p(l.etd).unix()-p(u.etd).unix()}),a.wps.forEach((l,u)=>{const I=a.wps[u-1];if(I){const F=l.distanceFromStart-(I.distanceFromStart||0),N=p(l.eta||l.etd).diff(p(I.etd||I.eta),"hour",!0),P=Math.round(F/N*100)/100;l.avgSpd=P;const E=T.LaneHelper.calculateBearing(I,l);I.bearing=E}}),{sample:a,etd:t.at(0).etd,eta:t.at(-1).eta,from:t.at(0).from,to:t.at(-1).to,v0:t.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(n*1e3)/1e3,avgSpeed:Math.round(i/n*1e3)/1e3,wxFactor:Math.round(r*1e3)/1e3,cFactor:Math.round(m*1e3)/1e3,totalFoCons:Math.round(M*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(b*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(C*1e3)/1e3},extend:{cps:k,eca:w,distanceInECA:Math.round(o*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:t}}}}A.AISImpl=G,A.AlertHelper=ut,A.AlertLevel=dt,A.HifleetImpl=Mt,A.LoadCondition=ht,A.MyShipImpl=bt,A.MyVesselImpl=yt,A.ShipxyImpl=pt,A.SpeedHelper=W,A.SpeedLabel=ft,A.VesselTag=lt,A.alertHelper=gt,Object.defineProperty(A,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(A,R){typeof exports=="object"&&typeof module<"u"?R(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"],R):(A=typeof globalThis<"u"?globalThis:A||self,R(A["idm-plugin-vessel"]={},A.got,A["@log4js-node/log4js-api"],A.moment,A["@idm-plugin/geo2"],A["@idm-plugin/meteo2"],A["@idm-plugin/meteo"]))})(this,function(A,R,K,p,x,mt,nt){"use strict";var St=Object.defineProperty;var kt=(A,R,K)=>R in A?St(A,R,{enumerable:!0,configurable:!0,writable:!0,value:K}):A[R]=K;var z=(A,R,K)=>(kt(A,typeof R!="symbol"?R+"":R,K),K);let g;try{g=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(t){let e,a;switch(t){case 0:e="在航(主机推动)",a="Underway Using Engine";break;case 1:e="锚泊",a="Anchored";break;case 2:e="失控",a="Not operated";break;case 3:e="操纵受限",a="Limited airworthiness";break;case 4:e="吃水受限",a="Limited by ship's draft";break;case 5:e="靠泊",a="Mooring";break;case 6:e="搁浅",a="Stranded";break;case 7:e="捕捞作业",a="Engaged in fishing";break;case 8:e="靠帆船提供动力",a="Sailing";break;default:e="未定义",a="Undefined"}return{labelCn:e,labelEn:a}}}class yt extends G{constructor(e,a){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=e,this.clientSecret=a}async authToken(e={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await R.post(a,i).json();g==null||g.info("[%s] fetch access token from: %s - %j",e.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:p().utc().format()})}async realTimePosition(e,a={}){var d,r,m;(!this.token||p().diff(p(this.token.issuedAt),"seconds")>((d=this.token)==null?void 0:d.expiresIn)-300)&&await this.authToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(m=this.token)==null?void 0:m.accessToken}`},searchParams:{mmsi:e}};g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await R.get(i,n).json();if(o.code)return g==null||g.warn("[%s] fetch realtime position failed: %j",a.requestId,i,{message:o.message,status:o.status,code:o.code}),o;const s=o.data;for(const M in s)!isNaN(s[M])&&Number(s[M])!==1/0&&(s[M]=Number(s[M]));if(s){const M=p(`${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)?p.utc(s.eta).format():void 0,destination:s.dest,positionTime:M.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:M.utc().format()}}else return{}}async trajectory(e,a,i,n,o=!0,s={}){(!this.token||p().diff(p(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(e,s),r=p(a),m=p(i),M=[];for(;m.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(e,r,r.clone().add(30,"day"),d,n,M,s),r.add(30,"day");return await this.trajectoryIn30Day(e,r,m,d,n,M,s),M}async trajectoryIn30Day(e,a,i,n,o,s,d={}){var f,C,k,w,v;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",m={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(C=this.token)==null?void 0:C.accessToken}`},json:{mmsi:e,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};g==null||g.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,m);const M=await R.post(r,m).json();if(M.code)return g==null||g.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:M.message,status:M.status,code:M.code}),M;let h=-1;const b=p(`${(w=(k=M.data)==null?void 0:k[0])==null?void 0:w.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=M.data)==null||v.forEach(c=>{for(const P in c)!isNaN(c[P])&&Number(c[P])!==1/0&&(c[P]=Number(c[P]));const y=p(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),l=c.status,{labelCn:u,labelEn:I}=this.parseStatus(l),F={mmsi:c.mmsi,imo:n==null?void 0:n.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:l,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?p(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:y.unix(),labelCn:u,labelEn:I,method:"trajectory",vendor:"myVessel",utc:y.utc().format()},T=Math.floor(y.diff(b,"minute",!0)/(o||1));T!==h&&(h=T,s.push(F))}),s}}class Mt extends G{constructor(e){super();z(this,"token");this.token=e}async realTimePosition(e,a={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:e,usertoken:this.token}},o=await R.post(i,n).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const s=o==null?void 0:o.list;if(!s)return g==null||g.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const b in s)!isNaN(s[b])&&Number(s[b])!==1/0&&(s[b]=Number(s[b]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:m}=this.parseStatus(d),M=p(`${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)?p.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:M.unix(),utc:M.utc().format(),status:d,labelCn:r,labelEn:m,method:"position",vendor:"hifleet"}}async search(e,a={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:e},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let o=await R.post(i,n).json();g==null||g.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]);for(const d in o)!isNaN(o[d])&&Number(o[d])!==1/0&&(o[d]=Number(o[d]));const s={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await R.post(i,n).json(),g==null||g.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(s.deadweight=Number(o.dwt)),s}async suggest(e,a={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:e},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},o=await R.post(i,n).json();g==null||g.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const s=[];for(const d of o)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(e,a,i,n,o=!0,s={}){var c,y,l;const d=await this.realTimePosition(e,s);let r=p(a);const m=p(i),M=p();if(o){let u=m.diff(r,"d",!0);u<0?r=m.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=m.clone().subtract(80,"d"),u=M.diff(m,"d",!0),m.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:m.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:e,usertoken:this.token}},b="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await R.get(b,h).json();g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,b,h);let C;f&&(C=((y=(c=f.ships)==null?void 0:c.offors)==null?void 0:y.ship)||[],C.length||g==null||g.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const k=[];let w=-1;const v=p(`${(l=C==null?void 0:C[0])==null?void 0:l.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of C){for(const L in u)!isNaN(u[L])&&Number(u[L])!==1/0&&(u[L]=Number(u[L]));const I=p(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:F,labelCn:T}=this.parseStatus(u.status),P={mmsi:u.m,name:u.n,imo:d==null?void 0:d.imo,lat:u.la,lng:u.lo,draught:u.draught,sog:u.sp,cog:u.co,hdg:u.hdg,positionTime:I.unix(),utc:I.utc().format(),status:u.status,labelCn:T,labelEn:F,method:"trajectory",vendor:"hifleet"},E=Math.floor(I.diff(v,"minute",!0)/(n||1));E!==w&&(w=E,k.push(P))}return k}}class pt extends G{constructor(e){super();z(this,"token");this.token=e}async realTimePosition(e,a={}){const i={searchParams:{id:e,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",o=await R.get(n,i).json();if(g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const s=o.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),m=p.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:m.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(e,a,i,n,o=!0,s={}){var v;const d=await this.realTimePosition(e,s),r=p(a),m=p(i),M="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:e,k:this.token,enc:1,cut:0,btm:r.unix(),etm:m.unix()}},b=await R.get(M,h).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,M,h),(b==null?void 0:b.status)!==0)return b;const f=b==null?void 0:b.points,C=[],k=p.unix((v=f[0])==null?void 0:v.utc);let w=-1;for(const c of f){const y=p.unix(c.utc),l={imo:d==null?void 0:d.imo,mmsi:e,sog:Math.round(c.sog*3600/1e3/1852*100)/100,cog:Math.round(c.cog/100*100)/100,lat:Math.round(c.lat/1e6*1e5)/1e5,lng:Math.round(c.lon/1e6*1e5)/1e5,positionTime:y.unix(),utc:y.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(y.diff(k,"minute",!0)/(n||1));u!==w&&(w=u,C.push(l))}return C}}class bt extends G{constructor(e){super();z(this,"token");this.token=e}async getShipId(e,a={}){const i={headers:{appKey:this.token},json:{mmsiList:e}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",o=await R.post(n,i).json();return g==null||g.info("[%s] fetch ship id from: %s - %j",a.requestId,n,i),o.code!=="0"?o:o.data[0].shipId}async getShipInfo(e,a={}){const i={headers:{appKey:this.token},json:{shipId:e}},n="https://api3.myships.com/sp/ships/aissta",o=await R.post(n,i).json();if(g==null||g.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const s=o.data;let d=s.imo;return e==="407170"&&(d="9198379",g==null||g.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,e,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(e,a={}){const i=await this.getShipId(e,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await R.post(s,o).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,o);const r=d.data[0];for(const f in r)!isNaN(r[f])&&Number(r[f])!==1/0&&(r[f]=Number(r[f]));const{labelCn:m,labelEn:M}=await this.parseStatus(r.aisNavStatus),h=p.unix(r.posTime);return{...n,mmsi:e,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:h.utc().format(),status:r.aisNavStatus,labelEn:M,labelCn:m,method:"position",vendor:"myship"}}async trajectory(e,a,i,n,o=!0,s={}){const d=p(a),r=p(i),m=await this.getShipId(e),M=await this.getShipInfo(m),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(m,d.unix(),d.add(30,"day").unix(),M,e,n,h);return await this.trajectoryIn30Day(m,d.unix(),r.unix(),M,e,n,h),h}async trajectoryIn30Day(e,a,i,n,o,s,d,r={}){var k;const m={headers:{appKey:this.token},json:{shipId:e,startTime:a,endTime:i}},M="https://api3.myships.com/sp/ships/position/history",h=await R.post(M,m).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",r.requestId,M,m),h.code!=="0")return g==null||g.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const b=h.data;for(const w in b)!isNaN(b[w])&&Number(b[w])!==1/0&&(b[w]=Number(b[w]));const f=p.unix((k=b[0])==null?void 0:k.posTime);let C=-1;for(const w of b){const v=p.unix(w.posTime),c={imo:n==null?void 0:n.imo,mmsi:o,lat:Math.round(w.lat/1e4/60*1e5)/1e5,lng:Math.round(w.lon/1e4/60*1e5)/1e5,sog:Math.round(w.sog/10*100)/100,cog:Math.round(w.cog/10*100)/100,hdg:Math.round(w.heading*100)/100,rot:Math.round(w.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},y=Math.floor(v.diff(f,"minute",!0)/(s||1));y!==C&&(C=y,d.push(c))}return d}}let _;try{_=K.getLogger("vessel")}catch{}finally{}var dt=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(dt||{});class ut{parsePrinciple(t,e={}){var s,d,r;_==null||_.debug("[%s] parse rule: %s",e.requestId,t);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=t.match(a)?(s=t.match(a))==null?void 0:s[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let m=0;m<(n==null?void 0:n.length);m++){const M=(r=(d=n[m].match(a))==null?void 0:d[0])==null?void 0:r.split("],");if(m===0&&!M)o.scope=n[0];else if(M)for(let h=0,b=M.length;h<b;h++){const f=this.parseRule(M[h]);f&&(o[f.level]?f.key?o[f.level][f==null?void 0:f.key]=f:o[f.level]=f:f.key?o[f.level]={[f==null?void 0:f.key]:f}:o[f.level]=f)}}return o}parseRule(t,e={}){var o;_==null||_.debug("[%s] parse rule: %s",e.requestId,t),t=t.startsWith("[")?t:`[${t}`,t=t.endsWith("]")?t:`${t}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=t==null?void 0:t.match(a))==null?void 0:o[0],n=i==null?void 0:i.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(t,e,a={}){var f,C,k,w,v,c,y,l,u,I,F,T,P,E,L;let i=0,n=0,o=0,s=0;const d=Math.round(((C=(f=e==null?void 0:e.SEVERE)==null?void 0:f.sigWave)==null?void 0:C.number)*1.6*100)/100,r=(w=(k=e==null?void 0:e.SEVERE)==null?void 0:k.sigWave)==null?void 0:w.number,m=(c=(v=e==null?void 0:e.HEAVY)==null?void 0:v.sigWave)==null?void 0:c.number,M=Math.round((((l=(y=e==null?void 0:e.SEVERE)==null?void 0:y.wind)==null?void 0:l.number)+2)*100)/100,h=(I=(u=e==null?void 0:e.SEVERE)==null?void 0:u.wind)==null?void 0:I.number,b=(T=(F=e==null?void 0:e.HEAVY)==null?void 0:F.wind)==null?void 0:T.number;for(let N=0;N<(t==null?void 0:t.length);N++){const H=t[N],q=(E=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:E.sig,V=(L=H==null?void 0:H.meteo)==null?void 0:L.wind,U=N?p(H.eta).diff(p(t[N-1].eta),"hour",!0):0;s=U>s?U:s,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...q,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}),(q==null?void 0:q.height)>=d?H.isDangerous=!0:(q==null?void 0:q.height)>=r?H.isSevere=!0:(q==null?void 0:q.height)>=m&&(H.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:b}),(V==null?void 0:V.scale)>=M?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(V==null?void 0:V.scale)>h?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(V==null?void 0:V.scale)===b&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),i+=H.isDangerous?U:0,n+=H.isSevere?U:0,o+=H.isHeavy?U:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,s=Math.round(s),{sample:t,dangerous:i,severe:n,heavy:o,step:s<3?3:s,wind:{dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:b},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}}}}const gt=new ut;let S;try{S=K.getLogger("vessel")}catch{}finally{}const vt=new mt.MeteoHelper2("",!0);var lt=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(lt||{}),ht=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(ht||{}),ft=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ft||{});class W{static blockCoefficient(t,e,a,i){let n=Math.round(t/(e*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],s=o.map(d=>Math.abs(d-n));return o[s.indexOf(Math.min(...s))]}static froudeNumber(t,e,a=9.8){let i=Math.round(Math.sqrt(t*t/(a*e))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(t,e,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[t];return a==="Laden"&&(o=i[t]),o[0]+o[1]*e+o[2]*Math.pow(e,2)}static directionFactor(t,e=0){let a;return t>30&&t<=60?a=(1.7-.03*Math.pow(e-4,2))/2:t>60&&t<=150?a=(.9-.06*Math.pow(e-6,2))/2:t>150&&t<=180?a=(.4-.03*Math.pow(e-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(t,e,a,i=0){i=i>6?i-.9*(i-6):i;let n;return a==="container"?n=.7*i+Math.pow(i,6.5)/(22*Math.pow(t,2/3)):e==="Ballast"?n=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(t,2/3)):n=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(t,2/3)),n}static waveHeightFactor(t,e){t=t<3?t*.7:t,t=t<0?.2:t,t=t>6?t-.9*(t-6):t,t=t>9?9:t;let a;return e>30&&e<=60?a=-.6:e>60&&e<=90?a=-.4:e>90&&e<=120?a=t<3?.4:-.3:e>120&&e<=150?a=t<3?.6:-.5:e>150&&e<=180?a=t<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(t,2)+.278*t)*1e4)/1e4}static assembleProperties(t,e,a,i){var h;const n=t.lbp??t.length??t.lengthOverall??198.9642,o=t.draught??8,s=t.breadthMoulded??t.breadth??t.breadthExtreme??32.4572,d=t.deadweight??67035.7773,r=((h=t==null?void 0:t.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:e,draught:o,breadthMoulded:s,displacement:Math.round((d/1.025+o*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(t,e,a,i="",n=2,o=!0,s=!1,d={}){let r;if(e.velocity&&s&&(t.speed=x.LngLatHelper.roundPrecision(e.velocity*1852/3600,6)),o){let m;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:f,marineModels:C}=await nt.Meteo2Assist.autoPickMeteoModel(i),k=await vt.spotForecast(e.lat,e.lng,a.utc().format(),!1,!1,!0,{...d,pastDays:1,forecastDays:1,weatherModels:f,marineModels:C}),[w]=nt.Meteo2Assist.pickHourly(k,a);m=nt.Meteo2Assist.toLegacy(w)}catch(f){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...e,eta:a.utc().format(),source:i},f)}const M=W.weatherFactor(t,m),h=W.currentFactor(t.bearing,m==null?void 0:m.current,n),b=Math.round((t.speed*1.943844+M+h)*100)/100;r={meteo:{...m},wxFactor:M,cFactor:h,speed:e.velocity&&s?e.velocity:b<0?1:b,eta:a.utc().format(),etd:a.utc().format()}}else r={wxFactor:0,cFactor:0,speed:e.velocity&&s?e.velocity:Math.round((t.speed*1.943844+0+0)*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete e.meteo,delete e.wxFactor,delete e.cFactor,delete e.speed,delete e.etd,{...r,...e}}static async speedLoseInHoursStep(t,e,a,i,n,o,s="",d=!0,r=!1,m={}){e.utc();const M=e.clone().add(14,"days"),h=[],b=[];let f=0,C=0,k,w;for(let v=0;v<o.length-1;v++){let c=o[v];c.distanceFromStart=Math.round((n+C)*1e3)/1e3;const y=o[v+1];if(t.bearing=x.LaneHelper.calculateBearing(c,y,!y.gcToPrevious),c.bearing=t.bearing,c.suspend&&r){c.eta=c.eta||e.utc().format(),c.elapsed=c.elapsed??0;const I=c.suspend-c.elapsed;if(i-f>I)i=i-f-I,e.add(I,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,e.add(F,"hour"),i=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,m.requestId,c),i===0)return c.distanceFromPrevious=C,{etd:e,from:w||c,to:c,next:o.filter(F=>F),wps:h,days:b}}else c.suspend=0;d=e.isAfter(M)?!1:d,c=await W.speedLoseAt(t,c,e,s,0,d,r,m),w=w||c,c.important&&h.push(c),e.isSameOrAfter(a)&&(b.push(c),a.add(24,"hour"));const l=x.LaneHelper.calculateDistance(c,y,!y.gcToPrevious);let u=Math.round(l/w.speed*1e5)/1e5;if(f+u<i){if(f+=u,e.add(u,"hour"),delete o[v],S==null||S.debug(`[%s] go to %j from %j with ${l}nm, and cost ${u} hours`,m.requestId,{lat:y.lat,lng:y.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),C+=l,o.filter(I=>I).length<=1){k=y,k.eta=e.utc().format(),k.distanceFromPrevious=l,k.distanceFromStart=Math.round((n+C)*1e4)/1e4,h.push(k),delete o[v+1];break}}else{u=i-f,e.add(u,"hour");const I=x.LngLatHelper.roundPrecision(w.speed*u,5);k=x.LaneHelper.calculateCoordinate(c,t.bearing,I,"nauticalmiles",!y.gcToPrevious),k.eta=e.utc().format(),o[v]=k,S==null||S.debug(`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,m.requestId,{lat:k.lat,lng:k.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),C+=I,k.distanceFromPrevious=Math.round(C*1e4)/1e4,k.distanceFromStart=Math.round((n+C)*1e4)/1e4;break}}return{etd:e,from:w,to:k,next:o.filter(v=>v),wps:h,days:b}}static currentFactor(t,e,a=0){const i=(t-(e==null?void 0:e.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((e==null?void 0:e.kts)||0)*Math.cos(i);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(t,e){var M,h,b,f,C,k,w;S==null||S.debug("calculate weather factor via: %j",{...t,...e});const a=W.blockCoefficient(t.displacement,t.lbp,t.breadthMoulded,t.draught),i=W.froudeNumber(t.speed,t.lbp),n=W.amendFactor(a,i,t.loadCondition);let o=Math.abs(t.bearing%360-(((M=e==null?void 0:e.wind)==null?void 0:M.degree)%360||0));o=o>180?360-o:o;const s=W.directionFactor(o,(h=e==null?void 0:e.wind)==null?void 0:h.scale),d=W.vesselTagFactor(t.displacement,t.loadCondition,t.tag,(b=e==null?void 0:e.wind)==null?void 0:b.scale);let r=s*n*d/100*t.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,t.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),S==null||S.debug("wind wx factor = %d",r),o=Math.abs(t.bearing%360-(((C=(f=e==null?void 0:e.wave)==null?void 0:f.sig)==null?void 0:C.degree)%360||0));const m=W.waveHeightFactor(((w=(k=e==null?void 0:e.wave)==null?void 0:k.sig)==null?void 0:w.height)??1,o);return S==null||S.debug("wave wx factor = %d",m),r=Math.abs(r)>Math.abs(m)?r:r*.3+m*.7,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>3?3*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-2)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(t,e,a,i,n,o="",s=0,d=!0,r=!1,m={}){var X,Q,Z,$,tt,et;const M=p().valueOf();t.lng=x.LngLatHelper.convertToStdLng(t.lng);const{route:h,waypoints:b}=n.points,f=x.LaneHelper.calculateSubRoute(t,h);if(((X=f[0])==null?void 0:X.length)<=1)return;const{v0:C,label:k}=t.sog?{v0:t.sog,label:t.label||"Other"}:{v0:i.speed,label:"CP"},w=W.assembleProperties(a,i.loadCondition,C,0),v=b.length?x.LaneHelper.calculateSubWaypoints(t,b):[];v.forEach(Y=>Y.important=!0);const c={from:{...t},route:f,waypoints:v,v0:C,label:k},y={hours:[],days:[],wps:[]};s||(x.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let l=x.LaneHelper.simplifyRouteToCoordinates(f,v,0),u=0,I=0,F=0,T=0;e=p(e).utc();const P=e.clone();for(;l.length>0;){const Y=s-e.hour()%s,J=Math.ceil(e.clone().add(Y,"h").set({minute:0,second:0,millisecond:0}).diff(e,"h",!0)*1e4)/1e4,j=await W.speedLoseInHoursStep(w,e,P,J,u,l,o,d,r,m);(Q=j.from)!=null&&Q.speed&&(y.hours.push(j.from),y.wps.push(...j.wps),y.days.push(...j.days)),l=j==null?void 0:j.next,l.length||y.hours.push(j==null?void 0:j.to),u+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const E=y.hours;for(let Y=0;Y<E.length-1;Y++){const J=p(E[Y+1].eta).diff(E[Y].etd,"hour",!0)||1;I+=(E[Y].wxFactor||0)*J,F+=(E[Y].cFactor||0)*J,T+=J}($=y.wps)==null||$.forEach((Y,J)=>{Y.positionTime=p.utc(Y.etd||Y.eta).unix();const j=y.wps[J-1];if(j){const B=Y.distanceFromStart-j.distanceFromStart,O=p(Y.eta||Y.etd).diff(p(j.etd||j.eta),"h",!0);Y.avgSpd=Math.round(B/O*100)/100;const ct=x.LaneHelper.calculateBearing(j,Y);j.bearing=ct}}),y.wps=(tt=y.wps)==null?void 0:tt.reduce((Y,J)=>(Y.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||Y.push(J),Y),[]),c.sample=y;const L=y.hours.at(0),N=y.hours.at(-1);c.distance=Math.round(N.distanceFromStart*1e3)/1e3,c.etd=p(L.eta).utc().format(),c.eta=p(N.eta).utc().format(),c.wxFactor=Math.round(I/T*1e3)/1e3,c.cFactor=Math.round(F/T*1e3)/1e3,c.avgSpeed=Math.round(N.distanceFromStart/T*1e3)/1e3,c.totalHrs=Math.round(T*1e3)/1e3;const{distanceInECA:H,hoursInECA:q,totalDgoConsInECA:V,eca:U}=await this.calculateECA(c,i,m),st=x.LngLatHelper.roundPrecision(i.fo/24*(T-q),3),ot=x.LngLatHelper.roundPrecision(i.dgo/24*T,3);c.extend={eca:U,distanceInECA:H,hoursInECA:q,totalDgoConsInECA:V},c.totalFoCons=st<0?0:st,c.totalDgoCons=ot;const at=p().valueOf()-M,rt=((et=y==null?void 0:y.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",m==null?void 0:m.requestId,at,rt,Math.round(at/rt*1e3)/1e3),c}static async analyseInstantWithThreshed(t,e,a,i,n,o,s,d="",r=3,m=!0,M=!1,h={}){var Z,$,tt,et,Y,J;const b=p().valueOf();t.lng=x.LngLatHelper.convertToStdLng(t.lng);const{v0:f,label:C}=t.sog?{v0:t.sog,label:t.label||"Other"}:{v0:n.speed,label:"CP"},k=W.assembleProperties(i,n.loadCondition,f,0),w=x.LaneHelper.calculateSubRoute(t,o);if(((Z=w[0])==null?void 0:Z.length)<=1)return;const v=s.length?x.LaneHelper.calculateSubWaypoints(t,s):[];v.forEach(j=>j.important=!0);let c=x.LaneHelper.simplifyRouteToCoordinates(w,v,0),y=0,l=0,u=0,I=0;const F={hours:[],wps:[],days:[]};e=p(e).utc();const T=e.clone();for(;c.length>0;){const j=r-e.hour()%r;let B=Math.ceil(e.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(e,"h",!0)*1e4)/1e4;B=e.clone().add(B,"h").isSameOrAfter(a)?a.diff(e,"h",!0)*1e4/1e4:B;const O=await W.speedLoseInHoursStep(k,e,T,B,y,c,d,m,M,h);if(($=O.from)!=null&&$.speed&&(F.hours.push(O.from),O!=null&&O.wps&&F.wps.push(...O.wps),F.days.push(...O.days)),c=O==null?void 0:O.next,c.length||F.hours.push(O==null?void 0:O.to),y+=Math.round((((tt=O==null?void 0:O.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!B)break}F.wps=(et=F.wps)==null?void 0:et.reduce((j,B)=>(j.some(O=>Math.round(p(O.etd).unix()/60)===Math.round(p(B.etd).unix()/60))||j.push(B),j),[]),(Y=F.wps)==null||Y.forEach((j,B)=>{const O=F.wps[B-1];if(O){const ct=j.distanceFromStart-O.distanceFromStart,wt=p(j.eta||j.etd).diff(p(O.etd||O.eta),"h",!0);j.avgSpd=Math.round(ct/wt*100)/100;const It=x.LaneHelper.calculateBearing(O,j);O.bearing=It}});const P=F.hours;for(let j=0;j<P.length-1;j++){const B=p(P[j+1].eta).diff(P[j].etd,"hour",!0);l+=P[j].wxFactor*B,u+=P[j].cFactor*B,I+=B}const E=F.hours.at(0),L=F.hours.at(-1),N=await x.LaneHelper.calculateRangeRoute(E,L,w),H=await x.LaneHelper.calculateRangeWaypoints(E,L,w,v),q={sample:F,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:p(E.eta).utc().format(),eta:p(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(l/I*1e3)/1e3,cFactor:Math.round(u/I*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/I*1e3)/1e3,totalHrs:Math.round(I*1e3)/1e3,from:E,to:L,route:N,waypoints:H,v0:f,label:C},{distanceInECA:V,hoursInECA:U,totalDgoConsInECA:st,eca:ot}=await this.calculateECA(q,n,h),it=x.LngLatHelper.roundPrecision(n.fo/24*(I-U),3),at=x.LngLatHelper.roundPrecision(n.dgo/24*I,3);q.extend={eca:ot,distanceInECA:V,hoursInECA:U,totalDgoConsInECA:st},q.totalDgoCons=at,q.totalFoCons=it<0?0:it;const X=p().valueOf()-b,Q=((J=F==null?void 0:F.hours)==null?void 0:J.length)||1;return S==null||S.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),q}static async analyseCost(t,e,a,i,n={}){var w,v;const o=p().valueOf(),s=[];t.speedStep=t.speedStep||3,t.alterStep=t.alterStep??1;const d=x.LaneHelper.calculateRouteDistance(i.route);let r=0;a.forEach(c=>{const y=Math.ceil(d/c.speed/24);r=r<y?y:r}),r=r*1.3;const m=p.utc(t.etd).add(r??14,"day");let M=1;for(const c of a){const y=JSON.parse(JSON.stringify(i.route)),l=JSON.parse(JSON.stringify(i.waypoints)),u=await W.analyseInstantWithThreshed({lat:t.lat,lng:t.lng},t.etd,m,e,c,y,l,t.meteoVendor,t.speedStep,t.useMeteo,t.useRouteParam,n);u&&(await W.calculateCost(u,c,t,n),s.push(u),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,M,t.etd,m.format(),{cost:u.cost.total,hire:u.cost.hire,bunker:u.cost.bunker,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),M++}s.sort((c,y)=>c.cost.total-y.cost.total);const h=s.at(0),b=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(w=h.cost)==null?void 0:w.total}),b){const c=h.cost.cp,y=b.cost.cp,l=p(h.eta),u=p(h.etd),I=l.diff(u,"days",!0);let F=Math.ceil(I/2);F=F>7?7:F<t.alterStep?t.alterStep:F;let T=2,P={combined:!1,speeds:[b],cost:(v=b.cost)==null?void 0:v.total},E;for(;F>=t.alterStep;){const L=await W.combinedAnalyse(t,e,m,[c,y],i,F,{...n,level:T});if(P.cost>L.cost?E?(E==null?void 0:E.cost)>L.cost&&(E=L):(E=P,P=L):(!E||(E==null?void 0:E.cost)>L.cost)&&(E=L),F<=t.alterStep)break;F=Math.ceil(F/2),T+=1}f.push(P),E&&f.push(E)}const k=p().valueOf()-o;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),f.sort((c,y)=>c.cost-y.cost)}static async combinedAnalyse(t,e,a,i,n,o,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,o);const d=await W.alternateAnalyse(t,e,a,i,0,n,o,s),r=d.reduce((y,l)=>y+l.cost.total,0),m=d.reduce((y,l)=>y+l.cost.hire,0),M=d.reduce((y,l)=>y+l.cost.bunker,0),h=d.reduce((y,l)=>y+l.distance,0),b=d.reduce((y,l)=>y+l.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:r,hire:m,bunker:M,distance:h,hours:b});const f=await W.alternateAnalyse(t,e,a,i,1,n,o,s),C=f.reduce((y,l)=>y+l.cost.total,0),k=f.reduce((y,l)=>y+l.cost.hire,0),w=f.reduce((y,l)=>y+l.cost.bunker,0),v=f.reduce((y,l)=>y+l.distance,0),c=f.reduce((y,l)=>y+l.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:C,hire:k,bunker:w,distance:v,hours:c}),r<C?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:o}:{combined:!0,cost:Math.round(C*1e3)/1e3,speeds:f,step:o}}static async alternateAnalyse(t,e,a,i,n,o,s,d={}){var h,b;let r=p.utc(t.etd);const m={lat:t.lat,lng:t.lng},M=[];for(;r.isBefore(a);){const f=r.clone().utc().add(s,"day"),C=JSON.parse(JSON.stringify(o.route)),k=JSON.parse(JSON.stringify(o.waypoints)),w=i[n],v=await W.analyseInstantWithThreshed(m,r.utc().format(),f,e,w,C,k,t.meteoVendor,t.speedStep,t.useMeteo,t.useRouteParam,d);v&&(await W.calculateCost(v,w,t,d),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",d.requestId,d.level,d.counter,r.utc().format(),f.utc().format(),{cost:v.cost.total,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${w.speed}/${w.fo}/${w.dgo}`})),d.counter=d.counter+1;const c=(b=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:b.at(-1);if(c)m.lat=c.lat,m.lng=c.lng,r=p(c.eta),M.push(v),n=n?0:1;else break}return M}static async calculateCost(t,e,a,i={}){var n;if(t){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round(t.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3,d=Math.round(t.totalFoCons*(a.priceFO||0)*1e3)/1e3,r=Math.round((t.totalDgoCons+(((n=t.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;t.cost={total:Math.round((s+d+r)*1e3)/1e3,hire:s,bunker:Math.round((d+r)*1e3)/1e3,cp:e}}return t}static async calculateECA(t,e,a={}){var d,r,m,M;const i=await x.LaneHelper.intersectInECA((t==null?void 0:t.route)||[]);let n=0,o=0,s=0;(r=(d=t==null?void 0:t.sample)==null?void 0:d.wps)==null||r.forEach(h=>{h.positionTime=p.utc(h.etd||h.eta).unix()});for(const h of i){n+=h.distance;const b=await x.LaneHelper.deadReckoningTime((m=h.waypoints)==null?void 0:m.at(0),t.sample.wps),f=await x.LaneHelper.deadReckoningTime((M=h.waypoints)==null?void 0:M.at(-1),t.sample.wps);h.in=b,h.out=f,h.totalHrs=x.LngLatHelper.roundPrecision((f.positionTime-b.positionTime)/3600,3),h.totalDgoCons=x.LngLatHelper.roundPrecision(e.fo/24*h.totalHrs,3),o+=h.totalHrs,s+=h.totalDgoCons}return n=x.LngLatHelper.roundPrecision(n,3),o=x.LngLatHelper.roundPrecision(o,3),s=x.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(t,e={}){var c,y;const a={hours:[],wps:[],days:[]},i=t.reduce((l,u)=>l+u.distance,0),n=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.distanceInECA)||0)},0),o=t.reduce((l,u)=>l+u.totalHrs,0),s=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.hoursInECA)||0)},0),d=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.totalDgoConsInECA)||0)},0),r=t.reduce((l,u)=>l+u.wxFactor*u.totalHrs/o,0),m=t.reduce((l,u)=>l+u.cFactor*u.totalHrs/o,0),M=t.reduce((l,u)=>l+u.totalFoCons,0),h=t.reduce((l,u)=>l+u.totalDgoCons,0),b=t.reduce((l,u)=>l+u.cost.total,0),f=t.reduce((l,u)=>l+u.cost.hire,0),C=t.reduce((l,u)=>l+u.cost.bunker,0),k=[],w=[];let v;for(const l of t){w.push(...((c=l.extend)==null?void 0:c.eca)||[]);const u=l.sample.hours,I=l.sample.wps,F=l.sample.days,T=u.at(0);v&&(T.distanceFromPrevious=v.distanceFromPrevious,T.distanceFromStart=v.distanceFromStart,u.forEach((N,H)=>{H&&(N.distanceFromStart=N.distanceFromStart+v.distanceFromStart)}),I.at(0).distanceFromPrevious=v.distanceFromPrevious,I.at(0).distanceFromStart=v.distanceFromStart,I.forEach((N,H)=>{H&&(N.distanceFromStart=N.distanceFromStart+v.distanceFromStart)}),F.at(0).distanceFromPrevious=v.distanceFromPrevious,F.at(0).distanceFromStart=v.distanceFromStart,F.forEach((N,H)=>{H&&(N.distanceFromStart=N.distanceFromStart+v.distanceFromStart)})),T.cp=l.cost.cp;const P=[l.etd,l.eta],E=k.findIndex(N=>N.id===T.cp.id);E===-1?(T.cp.segment=[P],k.push(T.cp)):k[E].segment.push(P),u.forEach(N=>{var q;((q=a.hours)==null?void 0:q.findIndex(V=>V.eta===N.eta))===-1&&a.hours.push(N)}),I.forEach(N=>{var q;((q=a.wps)==null?void 0:q.findIndex(V=>V.eta===N.eta))===-1&&a.wps.push(N)}),F.forEach(N=>{var q;((q=a==null?void 0:a.days)==null?void 0:q.findIndex(V=>V.eta===N.eta))===-1&&a.days.push(N)});const L=(y=a.wps)==null?void 0:y.findIndex(N=>N.eta===T.eta);L===-1?a.wps.push(T):a.wps[L]=T,v=u.at(-1)}return a.wps.sort((l,u)=>{p(l.etd).unix()-p(u.etd).unix()}),a.wps.forEach((l,u)=>{const I=a.wps[u-1];if(I){const F=l.distanceFromStart-(I.distanceFromStart||0),T=p(l.eta||l.etd).diff(p(I.etd||I.eta),"hour",!0),P=Math.round(F/T*100)/100;l.avgSpd=P;const E=x.LaneHelper.calculateBearing(I,l);I.bearing=E}}),{sample:a,etd:t.at(0).etd,eta:t.at(-1).eta,from:t.at(0).from,to:t.at(-1).to,v0:t.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(r*1e3)/1e3,cFactor:Math.round(m*1e3)/1e3,totalFoCons:Math.round(M*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(b*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(C*1e3)/1e3},extend:{cps:k,eca:w,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:t}}}}A.AISImpl=G,A.AlertHelper=ut,A.AlertLevel=dt,A.HifleetImpl=Mt,A.LoadCondition=ht,A.MyShipImpl=bt,A.MyVesselImpl=yt,A.ShipxyImpl=pt,A.SpeedHelper=W,A.SpeedLabel=ft,A.VesselTag=lt,A.alertHelper=gt,Object.defineProperty(A,Symbol.toStringTag,{value:"Module"})});
|