@idm-plugin/vessel 3.7.3 → 3.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +181 -180
- package/dist/index.umd.cjs +1 -1
- package/dist/speed/src/index.d.ts +1 -0
- package/package.json +3 -8
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var ht = Object.defineProperty;
|
|
2
2
|
var mt = (x, e, t) => e in x ? ht(x, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : x[e] = t;
|
|
3
|
-
var
|
|
3
|
+
var K = (x, e, t) => (mt(x, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
4
|
import z from "got";
|
|
5
5
|
import ut from "@log4js-node/log4js-api";
|
|
6
6
|
import w from "moment";
|
|
@@ -57,25 +57,25 @@ class nt {
|
|
|
57
57
|
class Tt extends nt {
|
|
58
58
|
constructor(t, a) {
|
|
59
59
|
super();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
K(this, "clientId");
|
|
61
|
+
K(this, "clientSecret");
|
|
62
|
+
K(this, "token");
|
|
63
63
|
this.clientId = t, this.clientSecret = a;
|
|
64
64
|
}
|
|
65
65
|
async authToken(t = {}) {
|
|
66
|
-
const a = "https://svc.data.myvessel.cn/ada/oauth/token",
|
|
66
|
+
const a = "https://svc.data.myvessel.cn/ada/oauth/token", n = {
|
|
67
67
|
searchParams: {
|
|
68
68
|
client_id: this.clientId,
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
},
|
|
73
|
-
g == null || g.info("[%s] fetch access token from: %s - %j", t.requestId, a,
|
|
74
|
-
accessToken:
|
|
75
|
-
tokenType:
|
|
76
|
-
expiresIn:
|
|
77
|
-
scope:
|
|
78
|
-
jti:
|
|
72
|
+
}, o = await z.post(a, n).json();
|
|
73
|
+
g == null || g.info("[%s] fetch access token from: %s - %j", t.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: w().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
@@ -91,7 +91,7 @@ class Tt extends nt {
|
|
|
91
91
|
async suggest(t, a = {}) {
|
|
92
92
|
var s, r;
|
|
93
93
|
await this.checkToken(a);
|
|
94
|
-
const
|
|
94
|
+
const n = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy", o = {
|
|
95
95
|
headers: {
|
|
96
96
|
Authorization: `${(s = this.token) == null ? void 0 : s.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
97
97
|
},
|
|
@@ -100,8 +100,8 @@ class Tt extends nt {
|
|
|
100
100
|
recordNum: a.ps || 10
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
g == null || g.info("[%s] fetch suggest vessels from: %s - %j", a.requestId,
|
|
104
|
-
const i = await z.post(
|
|
103
|
+
g == null || g.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, n, o);
|
|
104
|
+
const i = await z.post(n, o).json();
|
|
105
105
|
return i.status !== 200 ? (g == null || g.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), []) : (i.data || []).map((u) => ({
|
|
106
106
|
mmsi: u.mmsi,
|
|
107
107
|
name: u.nameEn,
|
|
@@ -122,14 +122,14 @@ class Tt extends nt {
|
|
|
122
122
|
async search(t, a = {}) {
|
|
123
123
|
var l, u;
|
|
124
124
|
await this.checkToken(a);
|
|
125
|
-
const
|
|
125
|
+
const n = /^\d{7}$/.test(t.toString()), o = n ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", i = n ? { imo: t } : { mmsi: t }, s = {
|
|
126
126
|
headers: {
|
|
127
127
|
Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(u = this.token) == null ? void 0 : u.accessToken}`
|
|
128
128
|
},
|
|
129
129
|
searchParams: i
|
|
130
130
|
};
|
|
131
|
-
g == null || g.info("[%s] fetch vessel from: %s - %j", a.requestId,
|
|
132
|
-
const r = await z.get(
|
|
131
|
+
g == null || g.info("[%s] fetch vessel from: %s - %j", a.requestId, o, s);
|
|
132
|
+
const r = await z.get(o, s).json();
|
|
133
133
|
if (r.status !== 200)
|
|
134
134
|
return g == null || g.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
|
|
135
135
|
{
|
|
@@ -164,7 +164,7 @@ class Tt extends nt {
|
|
|
164
164
|
async archives(t, a = {}) {
|
|
165
165
|
var s, r;
|
|
166
166
|
await this.checkToken(a);
|
|
167
|
-
const
|
|
167
|
+
const n = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch", o = {
|
|
168
168
|
headers: {
|
|
169
169
|
Authorization: `${(s = this.token) == null ? void 0 : s.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
170
170
|
},
|
|
@@ -172,21 +172,21 @@ class Tt extends nt {
|
|
|
172
172
|
mmsiList: typeof t == "number" ? [t] : t
|
|
173
173
|
}
|
|
174
174
|
};
|
|
175
|
-
g == null || g.info("[%s] fetch vessel archive from: %s - %j", a.requestId,
|
|
176
|
-
const i = await z.post(
|
|
175
|
+
g == null || g.info("[%s] fetch vessel archive from: %s - %j", a.requestId, n, o);
|
|
176
|
+
const i = await z.post(n, o).json();
|
|
177
177
|
return i.status !== 200 ? (g == null || g.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), {}) : i.data;
|
|
178
178
|
}
|
|
179
179
|
async realTimePosition(t, a = {}) {
|
|
180
180
|
var r, l;
|
|
181
181
|
await this.checkToken(a);
|
|
182
|
-
const
|
|
182
|
+
const n = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", o = {
|
|
183
183
|
headers: {
|
|
184
184
|
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(l = this.token) == null ? void 0 : l.accessToken}`
|
|
185
185
|
},
|
|
186
186
|
searchParams: { mmsi: t }
|
|
187
187
|
};
|
|
188
|
-
g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
189
|
-
const i = await z.get(
|
|
188
|
+
g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o);
|
|
189
|
+
const i = await z.get(n, o).json();
|
|
190
190
|
if (i.code)
|
|
191
191
|
return g == null || g.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), i;
|
|
192
192
|
const s = i.data;
|
|
@@ -236,7 +236,7 @@ class Tt extends nt {
|
|
|
236
236
|
* @param excludeSeas 排除水域, [sea.code]
|
|
237
237
|
* @param options { requiretId: '请求ID', useAIModel: '启用AI算法', withECA: '是否计算低硫区航行距离', withSpecial: '是否计算穿越的特战区列表和海盗区列表', draught: '最大吃水' }
|
|
238
238
|
*/
|
|
239
|
-
async calculateRoute(t, a,
|
|
239
|
+
async calculateRoute(t, a, n, o, i, s = {}) {
|
|
240
240
|
var k, b, F;
|
|
241
241
|
const r = w();
|
|
242
242
|
await this.checkToken(s);
|
|
@@ -252,7 +252,7 @@ class Tt extends nt {
|
|
|
252
252
|
}), a.code && (u.endPortCode = a.code), a.lng !== void 0 && a.lat !== void 0 && (u.endPoint = {
|
|
253
253
|
lon: a.lng,
|
|
254
254
|
lat: a.lat
|
|
255
|
-
}),
|
|
255
|
+
}), n != null && n.length && (u.crossMonthList = n), o != null && o.length && (u.excludeNodes = o), i != null && i.length && (u.excludeSeaAreas = i);
|
|
256
256
|
const c = {
|
|
257
257
|
headers: {
|
|
258
258
|
Authorization: `${(k = this.token) == null ? void 0 : k.tokenType} ${(b = this.token) == null ? void 0 : b.accessToken}`
|
|
@@ -334,14 +334,14 @@ class Tt extends nt {
|
|
|
334
334
|
return I.memo = `time cost: ${S}s`, g.info("[%s] calculate route cost: %d seconds", s.requestId, S), I;
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
-
async trajectory(t, a,
|
|
337
|
+
async trajectory(t, a, n, o, i = !0, s = {}) {
|
|
338
338
|
await this.checkToken(s);
|
|
339
|
-
const r = await this.realTimePosition(t, s), l = w(a), u = w(
|
|
339
|
+
const r = await this.realTimePosition(t, s), l = w(a), u = w(n), c = [];
|
|
340
340
|
for (; u.diff(l, "day", !0) > 30; )
|
|
341
|
-
await this.trajectoryIn30Day(t, l, l.clone().add(30, "day"), r,
|
|
342
|
-
return await this.trajectoryIn30Day(t, l, u, r,
|
|
341
|
+
await this.trajectoryIn30Day(t, l, l.clone().add(30, "day"), r, o, c, s), l.add(30, "day");
|
|
342
|
+
return await this.trajectoryIn30Day(t, l, u, r, o, c, s), c;
|
|
343
343
|
}
|
|
344
|
-
async trajectoryIn30Day(t, a,
|
|
344
|
+
async trajectoryIn30Day(t, a, n, o, i, s, r = {}) {
|
|
345
345
|
var b, F, I, p, v;
|
|
346
346
|
const l = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", u = {
|
|
347
347
|
headers: {
|
|
@@ -350,7 +350,7 @@ class Tt extends nt {
|
|
|
350
350
|
json: {
|
|
351
351
|
mmsi: t,
|
|
352
352
|
startTime: a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
|
|
353
|
-
endTime:
|
|
353
|
+
endTime: n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
354
354
|
}
|
|
355
355
|
};
|
|
356
356
|
g == null || g.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, u);
|
|
@@ -364,7 +364,7 @@ class Tt extends nt {
|
|
|
364
364
|
!isNaN(m[N]) && Number(m[N]) !== 1 / 0 && (m[N] = Number(m[N]));
|
|
365
365
|
const d = w(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), f = m.status, { labelCn: y, labelEn: S } = this.parseStatus(f), M = {
|
|
366
366
|
mmsi: m.mmsi,
|
|
367
|
-
imo:
|
|
367
|
+
imo: o == null ? void 0 : o.imo,
|
|
368
368
|
lat: m.lat,
|
|
369
369
|
lng: m.lon,
|
|
370
370
|
sog: m.sog,
|
|
@@ -388,20 +388,20 @@ class Tt extends nt {
|
|
|
388
388
|
class jt extends nt {
|
|
389
389
|
constructor(t) {
|
|
390
390
|
super();
|
|
391
|
-
|
|
391
|
+
K(this, "token");
|
|
392
392
|
this.token = t;
|
|
393
393
|
}
|
|
394
394
|
async realTimePosition(t, a = {}) {
|
|
395
|
-
const
|
|
395
|
+
const n = "https://api.hifleet.com/position/position/get/token", o = {
|
|
396
396
|
searchParams: {
|
|
397
397
|
mmsi: t,
|
|
398
398
|
usertoken: this.token
|
|
399
399
|
}
|
|
400
|
-
}, i = await z.post(
|
|
401
|
-
g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
400
|
+
}, i = await z.post(n, o).json();
|
|
401
|
+
g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o);
|
|
402
402
|
const s = i == null ? void 0 : i.list;
|
|
403
403
|
if (!s)
|
|
404
|
-
return g == null || g.warn("[%s] fetch realtime position failed: %j", a.requestId,
|
|
404
|
+
return g == null || g.warn("[%s] fetch realtime position failed: %j", a.requestId, n, i), i;
|
|
405
405
|
for (const k in s)
|
|
406
406
|
!isNaN(s[k]) && Number(s[k]) !== 1 / 0 && (s[k] = Number(s[k]));
|
|
407
407
|
s.status = s.sp > 3 ? 0 : 1;
|
|
@@ -436,8 +436,8 @@ class jt extends nt {
|
|
|
436
436
|
};
|
|
437
437
|
}
|
|
438
438
|
async search(t, a = {}) {
|
|
439
|
-
let
|
|
440
|
-
const
|
|
439
|
+
let n = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
440
|
+
const o = {
|
|
441
441
|
searchParams: {
|
|
442
442
|
keyword: t
|
|
443
443
|
},
|
|
@@ -447,8 +447,8 @@ class jt extends nt {
|
|
|
447
447
|
Host: "www.hifleet.com"
|
|
448
448
|
}
|
|
449
449
|
};
|
|
450
|
-
let i = await z.post(
|
|
451
|
-
g == null || g.info("[%s] fetch vessel props from: %s - %j", a.requestId,
|
|
450
|
+
let i = await z.post(n, o).json();
|
|
451
|
+
g == null || g.info("[%s] fetch vessel props from: %s - %j", a.requestId, n, o), i instanceof Array && (i = i[0]);
|
|
452
452
|
for (const r in i)
|
|
453
453
|
!isNaN(i[r]) && Number(i[r]) !== 1 / 0 && (i[r] = Number(i[r]));
|
|
454
454
|
const s = {
|
|
@@ -461,10 +461,10 @@ class jt extends nt {
|
|
|
461
461
|
draught: i.dr,
|
|
462
462
|
type: i.t
|
|
463
463
|
};
|
|
464
|
-
return
|
|
464
|
+
return n = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", i = await z.post(n, o).json(), g == null || g.info("[%s] search vessel dead weight from: %s - %j", a.requestId, n, o), i instanceof Array && (i = i[0]), i && (s.deadweight = Number(i.dwt)), s;
|
|
465
465
|
}
|
|
466
466
|
async suggest(t, a = {}) {
|
|
467
|
-
const
|
|
467
|
+
const n = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", o = {
|
|
468
468
|
searchParams: {
|
|
469
469
|
q: t
|
|
470
470
|
},
|
|
@@ -473,8 +473,8 @@ class jt extends nt {
|
|
|
473
473
|
Origin: "https://www.hifleet.com",
|
|
474
474
|
Host: "www.hifleet.com"
|
|
475
475
|
}
|
|
476
|
-
}, i = await z.post(
|
|
477
|
-
g == null || g.info("[%s] suggest vessel props from: %s - %j", a.requestId,
|
|
476
|
+
}, i = await z.post(n, o).json();
|
|
477
|
+
g == null || g.info("[%s] suggest vessel props from: %s - %j", a.requestId, n, o);
|
|
478
478
|
const s = [];
|
|
479
479
|
for (const r of i)
|
|
480
480
|
s.push({
|
|
@@ -486,11 +486,11 @@ class jt extends nt {
|
|
|
486
486
|
});
|
|
487
487
|
return s.sort((r, l) => l.score - r.score), s;
|
|
488
488
|
}
|
|
489
|
-
async trajectory(t, a,
|
|
489
|
+
async trajectory(t, a, n, o, i = !0, s = {}) {
|
|
490
490
|
var m, d, f;
|
|
491
491
|
const r = await this.realTimePosition(t, s);
|
|
492
492
|
let l = w(a);
|
|
493
|
-
const u = w(
|
|
493
|
+
const u = w(n), c = w();
|
|
494
494
|
if (i) {
|
|
495
495
|
let y = u.diff(l, "d", !0);
|
|
496
496
|
y < 0 ? l = u.clone().subtract(40, "d") : y < 30 ? l.subtract(10, "d") : y < 60 ? l.subtract(5, "d") : l = u.clone().subtract(80, "d"), y = c.diff(u, "d", !0), u.add(y > 10 ? 240 : y * 24, "h");
|
|
@@ -531,7 +531,7 @@ class jt extends nt {
|
|
|
531
531
|
labelEn: M,
|
|
532
532
|
method: "trajectory",
|
|
533
533
|
vendor: "hifleet"
|
|
534
|
-
}, D = Math.floor(S.diff(v, "minute", !0) / (
|
|
534
|
+
}, D = Math.floor(S.diff(v, "minute", !0) / (o || 1));
|
|
535
535
|
D !== p && (p = D, I.push(N));
|
|
536
536
|
}
|
|
537
537
|
return I;
|
|
@@ -540,18 +540,18 @@ class jt extends nt {
|
|
|
540
540
|
class xt extends nt {
|
|
541
541
|
constructor(t) {
|
|
542
542
|
super();
|
|
543
|
-
|
|
543
|
+
K(this, "token");
|
|
544
544
|
this.token = t;
|
|
545
545
|
}
|
|
546
546
|
async realTimePosition(t, a = {}) {
|
|
547
|
-
const
|
|
547
|
+
const n = {
|
|
548
548
|
searchParams: {
|
|
549
549
|
id: t,
|
|
550
550
|
k: this.token,
|
|
551
551
|
enc: 1
|
|
552
552
|
}
|
|
553
|
-
},
|
|
554
|
-
if (g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
553
|
+
}, o = "https://api.shipxy.com/apicall/GetSingleShip", i = await z.get(o, n).json();
|
|
554
|
+
if (g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n), (i == null ? void 0 : i.status) !== 0)
|
|
555
555
|
return i;
|
|
556
556
|
const s = i.data[0];
|
|
557
557
|
for (const h in s)
|
|
@@ -580,9 +580,9 @@ class xt extends nt {
|
|
|
580
580
|
vendor: "shipxy"
|
|
581
581
|
};
|
|
582
582
|
}
|
|
583
|
-
async trajectory(t, a,
|
|
583
|
+
async trajectory(t, a, n, o, i = !0, s = {}) {
|
|
584
584
|
var v;
|
|
585
|
-
const r = await this.realTimePosition(t, s), l = w(a), u = w(
|
|
585
|
+
const r = await this.realTimePosition(t, s), l = w(a), u = w(n), c = "https://api.shipxy.com/apicall/GetShipTrack", h = {
|
|
586
586
|
searchParams: {
|
|
587
587
|
id: t,
|
|
588
588
|
k: this.token,
|
|
@@ -608,7 +608,7 @@ class xt extends nt {
|
|
|
608
608
|
utc: d.utc().format(),
|
|
609
609
|
method: "trajectory",
|
|
610
610
|
vendor: "shipxy"
|
|
611
|
-
}, y = Math.floor(d.diff(I, "minute", !0) / (
|
|
611
|
+
}, y = Math.floor(d.diff(I, "minute", !0) / (o || 1));
|
|
612
612
|
y !== p && (p = y, F.push(f));
|
|
613
613
|
}
|
|
614
614
|
return F;
|
|
@@ -617,30 +617,30 @@ class xt extends nt {
|
|
|
617
617
|
class Nt extends nt {
|
|
618
618
|
constructor(t) {
|
|
619
619
|
super();
|
|
620
|
-
|
|
620
|
+
K(this, "token");
|
|
621
621
|
this.token = t;
|
|
622
622
|
}
|
|
623
623
|
async getShipId(t, a = {}) {
|
|
624
|
-
const
|
|
624
|
+
const n = {
|
|
625
625
|
headers: {
|
|
626
626
|
appKey: this.token
|
|
627
627
|
},
|
|
628
628
|
json: {
|
|
629
629
|
mmsiList: t
|
|
630
630
|
}
|
|
631
|
-
},
|
|
632
|
-
return g == null || g.info("[%s] fetch ship id from: %s - %j", a.requestId,
|
|
631
|
+
}, o = "https://api3.myships.com/sp/ships/getShipIdByMMSI", i = await z.post(o, n).json();
|
|
632
|
+
return g == null || g.info("[%s] fetch ship id from: %s - %j", a.requestId, o, n), i.code !== "0" ? i : i.data[0].shipId;
|
|
633
633
|
}
|
|
634
634
|
async getShipInfo(t, a = {}) {
|
|
635
|
-
const
|
|
635
|
+
const n = {
|
|
636
636
|
headers: {
|
|
637
637
|
appKey: this.token
|
|
638
638
|
},
|
|
639
639
|
json: {
|
|
640
640
|
shipId: t
|
|
641
641
|
}
|
|
642
|
-
},
|
|
643
|
-
if (g == null || g.info("[%s] fetch ship info from: %s - %j", a.requestId,
|
|
642
|
+
}, o = "https://api3.myships.com/sp/ships/aissta", i = await z.post(o, n).json();
|
|
643
|
+
if (g == null || g.info("[%s] fetch ship info from: %s - %j", a.requestId, o, n), i.code !== "0")
|
|
644
644
|
return i;
|
|
645
645
|
const s = i.data;
|
|
646
646
|
let r = s.imo;
|
|
@@ -655,12 +655,12 @@ class Nt extends nt {
|
|
|
655
655
|
};
|
|
656
656
|
}
|
|
657
657
|
async realTimePosition(t, a = {}) {
|
|
658
|
-
const
|
|
658
|
+
const n = await this.getShipId(t, a), o = await this.getShipInfo(n, a), i = {
|
|
659
659
|
headers: {
|
|
660
660
|
appKey: this.token
|
|
661
661
|
},
|
|
662
662
|
json: {
|
|
663
|
-
shipId:
|
|
663
|
+
shipId: n
|
|
664
664
|
}
|
|
665
665
|
}, s = "https://api3.myships.com/sp/ships/position/latest", r = await z.post(s, i).json();
|
|
666
666
|
g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, i);
|
|
@@ -669,7 +669,7 @@ class Nt extends nt {
|
|
|
669
669
|
!isNaN(l[b]) && Number(l[b]) !== 1 / 0 && (l[b] = Number(l[b]));
|
|
670
670
|
const { labelCn: u, labelEn: c } = await this.parseStatus(l.aisNavStatus), h = w.unix(l.posTime);
|
|
671
671
|
return {
|
|
672
|
-
...
|
|
672
|
+
...o,
|
|
673
673
|
mmsi: t,
|
|
674
674
|
lat: Math.round(l.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
675
675
|
lng: Math.round(l.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
@@ -686,13 +686,13 @@ class Nt extends nt {
|
|
|
686
686
|
vendor: "myship"
|
|
687
687
|
};
|
|
688
688
|
}
|
|
689
|
-
async trajectory(t, a,
|
|
690
|
-
const r = w(a), l = w(
|
|
689
|
+
async trajectory(t, a, n, o, i = !0, s = {}) {
|
|
690
|
+
const r = w(a), l = w(n), u = await this.getShipId(t), c = await this.getShipInfo(u), h = [];
|
|
691
691
|
for (; l.diff(r, "day", !0) > 30; )
|
|
692
|
-
await this.trajectoryIn30Day(u, r.unix(), r.add(30, "day").unix(), c, t,
|
|
693
|
-
return await this.trajectoryIn30Day(u, r.unix(), l.unix(), c, t,
|
|
692
|
+
await this.trajectoryIn30Day(u, r.unix(), r.add(30, "day").unix(), c, t, o, h);
|
|
693
|
+
return await this.trajectoryIn30Day(u, r.unix(), l.unix(), c, t, o, h), h;
|
|
694
694
|
}
|
|
695
|
-
async trajectoryIn30Day(t, a,
|
|
695
|
+
async trajectoryIn30Day(t, a, n, o, i, s, r, l = {}) {
|
|
696
696
|
var I;
|
|
697
697
|
const u = {
|
|
698
698
|
headers: {
|
|
@@ -701,7 +701,7 @@ class Nt extends nt {
|
|
|
701
701
|
json: {
|
|
702
702
|
shipId: t,
|
|
703
703
|
startTime: a,
|
|
704
|
-
endTime:
|
|
704
|
+
endTime: n
|
|
705
705
|
}
|
|
706
706
|
}, c = "https://api3.myships.com/sp/ships/position/history", h = await z.post(c, u).json();
|
|
707
707
|
if (g == null || g.info("[%s] fetch trajectory from: %s - %j", l.requestId, c, u), h.code !== "0")
|
|
@@ -713,7 +713,7 @@ class Nt extends nt {
|
|
|
713
713
|
let F = -1;
|
|
714
714
|
for (const p of k) {
|
|
715
715
|
const v = w.unix(p.posTime), m = {
|
|
716
|
-
imo:
|
|
716
|
+
imo: o == null ? void 0 : o.imo,
|
|
717
717
|
mmsi: i,
|
|
718
718
|
lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
719
719
|
lng: Math.round(p.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
@@ -731,9 +731,9 @@ class Nt extends nt {
|
|
|
731
731
|
return r;
|
|
732
732
|
}
|
|
733
733
|
}
|
|
734
|
-
let
|
|
734
|
+
let _;
|
|
735
735
|
try {
|
|
736
|
-
|
|
736
|
+
_ = ut.getLogger("vessel");
|
|
737
737
|
} catch {
|
|
738
738
|
} finally {
|
|
739
739
|
}
|
|
@@ -749,15 +749,15 @@ class Mt {
|
|
|
749
749
|
*/
|
|
750
750
|
parsePrinciple(e, t = {}) {
|
|
751
751
|
var s, r, l;
|
|
752
|
-
|
|
753
|
-
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"),
|
|
754
|
-
if (!
|
|
752
|
+
_ == null || _.debug("[%s] parse rule: %s", t.requestId, e);
|
|
753
|
+
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), n = e.match(a) ? (s = e.match(a)) == null ? void 0 : s[0] : void 0, o = n == null ? void 0 : n.split(";");
|
|
754
|
+
if (!o)
|
|
755
755
|
return;
|
|
756
756
|
const i = {};
|
|
757
|
-
for (let u = 0; u < (
|
|
758
|
-
const c = (l = (r =
|
|
757
|
+
for (let u = 0; u < (o == null ? void 0 : o.length); u++) {
|
|
758
|
+
const c = (l = (r = o[u].match(a)) == null ? void 0 : r[0]) == null ? void 0 : l.split("],");
|
|
759
759
|
if (u === 0 && !c)
|
|
760
|
-
i.scope =
|
|
760
|
+
i.scope = o[0];
|
|
761
761
|
else if (c)
|
|
762
762
|
for (let h = 0, k = c.length; h < k; h++) {
|
|
763
763
|
const b = this.parseRule(c[h]);
|
|
@@ -774,16 +774,16 @@ class Mt {
|
|
|
774
774
|
*/
|
|
775
775
|
parseRule(e, t = {}) {
|
|
776
776
|
var i;
|
|
777
|
-
|
|
778
|
-
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"),
|
|
779
|
-
if (
|
|
780
|
-
let s =
|
|
777
|
+
_ == null || _.debug("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
|
|
778
|
+
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), n = (i = e == null ? void 0 : e.match(a)) == null ? void 0 : i[0], o = n == null ? void 0 : n.split(",");
|
|
779
|
+
if (o) {
|
|
780
|
+
let s = o[3] === "Number.MAX_VALUE" ? 100 : Number(o[3]);
|
|
781
781
|
return s = isNaN(s) ? 1 : s, {
|
|
782
|
-
operator:
|
|
783
|
-
number: Number.isNaN(Number(
|
|
784
|
-
level:
|
|
782
|
+
operator: o[0],
|
|
783
|
+
number: Number.isNaN(Number(o[1])) ? o[1] : Number(o[1]),
|
|
784
|
+
level: o[2],
|
|
785
785
|
time: s,
|
|
786
|
-
key:
|
|
786
|
+
key: o[4]
|
|
787
787
|
};
|
|
788
788
|
}
|
|
789
789
|
}
|
|
@@ -795,13 +795,13 @@ class Mt {
|
|
|
795
795
|
*/
|
|
796
796
|
checkWeather(e, t, a = {}) {
|
|
797
797
|
var b, F, I, p, v, m, d, f, y, S, M, j, N, D, L;
|
|
798
|
-
let
|
|
798
|
+
let n = 0, o = 0, i = 0, s = 0;
|
|
799
799
|
const r = Math.round(((F = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : F.number) * 1.6 * 100) / 100, l = (p = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : p.number, u = (m = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : m.number, c = Math.round((((f = (d = t == null ? void 0 : t.SEVERE) == null ? void 0 : d.wind) == null ? void 0 : f.number) + 2) * 100) / 100, h = (S = (y = t == null ? void 0 : t.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : S.number, k = (j = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
|
|
800
800
|
for (let W = 0; W < (e == null ? void 0 : e.length); W++) {
|
|
801
801
|
const C = e[W], Y = (D = (N = C == null ? void 0 : C.meteo) == null ? void 0 : N.wave) == null ? void 0 : D.sig, A = (L = C == null ? void 0 : C.meteo) == null ? void 0 : L.wind, V = W ? w(C.eta).diff(w(e[W - 1].eta), "hour", !0) : 0;
|
|
802
|
-
s = V > s ? V : s,
|
|
802
|
+
s = V > s ? V : s, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...Y, dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u }), (Y == null ? void 0 : Y.height) >= r ? C.isDangerous = !0 : (Y == null ? void 0 : Y.height) >= l ? C.isSevere = !0 : (Y == null ? void 0 : Y.height) >= u && (C.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...A, dgThd4Wd: c, svThd4Wd: h, hvThd4Wd: k }), (A == null ? void 0 : A.scale) >= c ? (C.isDangerous = !0, delete C.isSevere, delete C.isHeavy) : (A == null ? void 0 : A.scale) > h ? (C.isDangerous || (C.isSevere = !0), delete C.isHeavy) : (A == null ? void 0 : A.scale) === k && !C.isDangerous && !C.isSevere && (C.isHeavy = !0), n += C.isDangerous ? V : 0, o += C.isSevere ? V : 0, i += C.isHeavy ? V : 0;
|
|
803
803
|
}
|
|
804
|
-
return
|
|
804
|
+
return n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, i = Math.round(i * 100) / 100, s = Math.round(s), { sample: e, dangerous: n, severe: o, heavy: i, step: s < 3 ? 3 : s, wind: { dgThd4Wd: c, svThd4Wd: h, hvThd4Wd: k }, sig: { dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u } };
|
|
805
805
|
}
|
|
806
806
|
}
|
|
807
807
|
const Dt = new Mt();
|
|
@@ -826,10 +826,10 @@ class H {
|
|
|
826
826
|
* @param draught 吃水 m
|
|
827
827
|
* @return [0.55, 0.85]
|
|
828
828
|
*/
|
|
829
|
-
static blockCoefficient(e, t, a,
|
|
830
|
-
let
|
|
831
|
-
|
|
832
|
-
const i = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = i.map((r) => Math.abs(r -
|
|
829
|
+
static blockCoefficient(e, t, a, n) {
|
|
830
|
+
let o = Math.round(e / (t * a * n) * 100) / 100;
|
|
831
|
+
o = o < 0.55 ? 0.55 : o > 0.85 ? 0.85 : o;
|
|
832
|
+
const i = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = i.map((r) => Math.abs(r - o));
|
|
833
833
|
return i[s.indexOf(Math.min(...s))];
|
|
834
834
|
}
|
|
835
835
|
/**
|
|
@@ -844,8 +844,8 @@ class H {
|
|
|
844
844
|
* @return [0.05, 0.30]
|
|
845
845
|
*/
|
|
846
846
|
static froudeNumber(e, t, a = 9.8) {
|
|
847
|
-
let
|
|
848
|
-
return
|
|
847
|
+
let n = Math.round(Math.sqrt(e * e / (a * t)) * 100) / 100;
|
|
848
|
+
return n = n < 0.05 ? 0.05 : n > 0.3 ? 0.3 : n, n;
|
|
849
849
|
}
|
|
850
850
|
/**
|
|
851
851
|
* 失速修正系數
|
|
@@ -855,7 +855,7 @@ class H {
|
|
|
855
855
|
* @private
|
|
856
856
|
*/
|
|
857
857
|
static amendFactor(e, t, a) {
|
|
858
|
-
const
|
|
858
|
+
const n = {
|
|
859
859
|
0.55: [1.7, -1.4, -7.4],
|
|
860
860
|
0.6: [2.2, -2.5, -9.7],
|
|
861
861
|
0.65: [2.6, -3.7, -11.6],
|
|
@@ -873,7 +873,7 @@ class H {
|
|
|
873
873
|
0.8: [3, -16.3, -21.6],
|
|
874
874
|
0.85: [3.4, -20.9, 31.8]
|
|
875
875
|
}[e];
|
|
876
|
-
return a === "Laden" && (i =
|
|
876
|
+
return a === "Laden" && (i = n[e]), i[0] + i[1] * t + i[2] * Math.pow(t, 2);
|
|
877
877
|
}
|
|
878
878
|
/**
|
|
879
879
|
* 失速方向因子
|
|
@@ -902,20 +902,21 @@ class H {
|
|
|
902
902
|
* @param kts
|
|
903
903
|
* @private
|
|
904
904
|
*/
|
|
905
|
-
static vesselTagFactor(e, t, a,
|
|
906
|
-
let
|
|
907
|
-
return a === "container" ?
|
|
905
|
+
static vesselTagFactor(e, t, a, n) {
|
|
906
|
+
let o;
|
|
907
|
+
return a === "container" ? o = 0.7 * n / 2 + Math.pow(n, 3) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? o = 0.7 * n / 2 + Math.pow(n, 3) / (2.7 * Math.pow(e, 2 / 3)) : o = 0.5 * n / 2 + Math.pow(n, 3) / (2.7 * Math.pow(e, 2 / 3)), o;
|
|
908
908
|
}
|
|
909
909
|
/**
|
|
910
910
|
* 浪高影响因子
|
|
911
911
|
* @param ht 浪高,单位m
|
|
912
912
|
* @param beta 夹角
|
|
913
|
+
* @param _draught 吃水
|
|
913
914
|
* @private
|
|
914
915
|
*/
|
|
915
|
-
static waveHeightFactor(e, t) {
|
|
916
|
+
static waveHeightFactor(e, t, a = 10) {
|
|
916
917
|
e = e < 3 ? e * 0.7 : e, e = e < 0 ? 0.2 : e, e = e > 6 ? e - 0.9 * (e - 6) : e, e = e > 9 ? 9 : e;
|
|
917
|
-
let
|
|
918
|
-
return t > 30 && t <= 60 ?
|
|
918
|
+
let n;
|
|
919
|
+
return t > 30 && t <= 60 ? n = -0.6 : t > 60 && t <= 90 ? n = -0.4 : t > 90 && t <= 120 ? n = e < 4 ? 0.4 : -0.15 : t > 120 && t <= 150 ? n = e < 4 ? 0.6 : -0.12 : t > 150 && t <= 180 ? n = e < 4 ? 0.7 : -0.1 : n = -0.7, Math.round(n * (0.144 * Math.pow(e, 2) + 0.378 * e) * 1e4) / 1e4;
|
|
919
920
|
}
|
|
920
921
|
/**
|
|
921
922
|
* 组装船舶运行参数
|
|
@@ -925,21 +926,21 @@ class H {
|
|
|
925
926
|
* @param bearing 方位角
|
|
926
927
|
* @private
|
|
927
928
|
*/
|
|
928
|
-
static assembleProperties(e, t, a,
|
|
929
|
+
static assembleProperties(e, t, a, n) {
|
|
929
930
|
var h;
|
|
930
|
-
const
|
|
931
|
+
const o = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, i = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, r = e.deadweight ?? 67035.7773, l = ((h = e == null ? void 0 : e.type) == null ? void 0 : h.toLowerCase()) || "common";
|
|
931
932
|
return {
|
|
932
933
|
tag: l.indexOf("container") > -1 ? "container" : l.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
933
|
-
lbp:
|
|
934
|
+
lbp: o,
|
|
934
935
|
loadCondition: t,
|
|
935
936
|
draught: i,
|
|
936
937
|
breadthMoulded: s,
|
|
937
938
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
938
939
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
939
|
-
displacement: Math.round((r / 1.025 + i * s *
|
|
940
|
+
displacement: Math.round((r / 1.025 + i * s * o * 0.7) * 1e4) / 1e4,
|
|
940
941
|
// 换算为m/s
|
|
941
942
|
speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
942
|
-
bearing:
|
|
943
|
+
bearing: n || 90
|
|
943
944
|
};
|
|
944
945
|
}
|
|
945
946
|
/**
|
|
@@ -953,24 +954,24 @@ class H {
|
|
|
953
954
|
* @param useRouteParam true 启用设置速度
|
|
954
955
|
* @param options
|
|
955
956
|
*/
|
|
956
|
-
static async speedLoseAt(e, t, a,
|
|
957
|
+
static async speedLoseAt(e, t, a, n = "", o = 2, i = !0, s = !1, r = {}) {
|
|
957
958
|
let l;
|
|
958
959
|
if (t.velocity && s && (e.speed = J.roundPrecision(t.velocity * 1852 / 3600, 6)), i) {
|
|
959
960
|
let u;
|
|
960
961
|
try {
|
|
961
|
-
|
|
962
|
-
const { weatherModels: I, marineModels: p } = await dt.autoPickMeteoModel(
|
|
962
|
+
n = (n == null ? void 0 : n.toUpperCase()) === "CMEMS" ? "ECMWF" : n, n = (n == null ? void 0 : n.toUpperCase()) === "METEO2" ? "best_match" : n;
|
|
963
|
+
const { weatherModels: I, marineModels: p } = await dt.autoPickMeteoModel(n), v = a.utc().format(), m = await gt.spotForecast(t.lat, t.lng, v, !1, !1, !0, {
|
|
963
964
|
...r,
|
|
964
965
|
pastDays: 1,
|
|
965
966
|
forecastDays: 2,
|
|
966
967
|
weatherModels: I,
|
|
967
968
|
marineModels: p
|
|
968
|
-
}), [
|
|
969
|
-
u = dt.toLegacy(
|
|
969
|
+
}), [d] = dt.pickHourly(m, a);
|
|
970
|
+
u = dt.toLegacy(d);
|
|
970
971
|
} catch (I) {
|
|
971
|
-
E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source:
|
|
972
|
+
E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: n }, I);
|
|
972
973
|
}
|
|
973
|
-
let c = H.currentFactor(e.bearing, u == null ? void 0 : u.current,
|
|
974
|
+
let c = H.currentFactor(e.bearing, u == null ? void 0 : u.current, o), h = H.weatherFactor(e, u, c);
|
|
974
975
|
const k = e.speed * 1.943844;
|
|
975
976
|
k + c + h <= 0 && (E.warn(
|
|
976
977
|
"[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",
|
|
@@ -1017,49 +1018,49 @@ class H {
|
|
|
1017
1018
|
* @param options
|
|
1018
1019
|
* @private
|
|
1019
1020
|
*/
|
|
1020
|
-
static async speedLoseInHoursStep(e, t, a,
|
|
1021
|
+
static async speedLoseInHoursStep(e, t, a, n, o, i, s = "", r = !0, l = !1, u = {}) {
|
|
1021
1022
|
t.utc();
|
|
1022
1023
|
const c = t.clone().add(14, "days"), h = [], k = [], b = [];
|
|
1023
1024
|
let F = 0, I = 0, p, v;
|
|
1024
1025
|
for (let m = 0; m < i.length - 1; m++) {
|
|
1025
1026
|
let d = i[m];
|
|
1026
|
-
d.distanceFromStart = Math.round((
|
|
1027
|
+
d.distanceFromStart = Math.round((o + I) * 1e3) / 1e3;
|
|
1027
1028
|
const f = i[m + 1];
|
|
1028
1029
|
if (e.bearing = R.calculateBearing(d, f, !f.gcToPrevious), d.bearing = e.bearing, d.suspend && l) {
|
|
1029
1030
|
d.eta = d.eta || t.utc().format(), d.elapsed = d.elapsed ?? 0;
|
|
1030
1031
|
const M = d.suspend - d.elapsed;
|
|
1031
|
-
if (
|
|
1032
|
-
|
|
1032
|
+
if (n - F > M)
|
|
1033
|
+
n = n - F - M, t.add(M, "hour"), d.elapsed = d.suspend;
|
|
1033
1034
|
else {
|
|
1034
|
-
const j =
|
|
1035
|
-
d.elapsed += j, t.add(j, "hour"),
|
|
1035
|
+
const j = n - F;
|
|
1036
|
+
d.elapsed += j, t.add(j, "hour"), n = 0;
|
|
1036
1037
|
}
|
|
1037
|
-
if (E == null || E.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${
|
|
1038
|
+
if (E == null || E.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${n} hours need to go...`, u.requestId, d), n === 0)
|
|
1038
1039
|
return d.distanceFromPrevious = I, { etd: t, from: v || d, to: d, next: i.filter((j) => j), wps: h, days: k, all: b };
|
|
1039
1040
|
} else
|
|
1040
1041
|
d.suspend = 0;
|
|
1041
1042
|
r = t.isAfter(c) ? !1 : r, d = await H.speedLoseAt(e, d, t, s, 0, r, l, u), b.push(d), v = v || d, d.important && h.push(d), t.isSameOrAfter(a) && (k.push(d), a.add(24, "hour"));
|
|
1042
1043
|
const y = R.calculateDistance(d, f, !f.gcToPrevious);
|
|
1043
1044
|
let S = Math.round(y / v.speed * 1e5) / 1e5;
|
|
1044
|
-
if (F + S <
|
|
1045
|
+
if (F + S < n) {
|
|
1045
1046
|
if (F += S, t.add(S, "hour"), delete i[m], E == null || E.debug(
|
|
1046
1047
|
`[%s] go to %j from %j with ${y}nm, and cost ${S} hours`,
|
|
1047
1048
|
u.requestId,
|
|
1048
1049
|
{ lat: f.lat, lng: f.lng },
|
|
1049
1050
|
{ lat: v.lat, lng: v.lng, etd: v.etd }
|
|
1050
1051
|
), I += y, i.filter((M) => M).length <= 1) {
|
|
1051
|
-
p = f, p.eta = t.utc().format(), p.distanceFromPrevious = y, p.distanceFromStart = Math.round((
|
|
1052
|
+
p = f, p.eta = t.utc().format(), p.distanceFromPrevious = y, p.distanceFromStart = Math.round((o + I) * 1e4) / 1e4, h.push(p), b.push(p), delete i[m + 1];
|
|
1052
1053
|
break;
|
|
1053
1054
|
}
|
|
1054
1055
|
} else {
|
|
1055
|
-
S =
|
|
1056
|
+
S = n - F, t.add(S, "hour");
|
|
1056
1057
|
const M = J.roundPrecision(v.speed * S, 5);
|
|
1057
1058
|
p = R.calculateCoordinate(d, e.bearing, M, "nauticalmiles", !f.gcToPrevious), p.eta = t.utc().format(), i[m] = p, E == null || E.debug(
|
|
1058
1059
|
`[%s] go to %j from %j with ${M}nm, and cost ${S} hours`,
|
|
1059
1060
|
u.requestId,
|
|
1060
1061
|
{ lat: p.lat, lng: p.lng },
|
|
1061
1062
|
{ lat: d.lat, lng: d.lng, etd: d.etd }
|
|
1062
|
-
), I += M, p.distanceFromPrevious = Math.round(I * 1e4) / 1e4, p.distanceFromStart = Math.round((
|
|
1063
|
+
), I += M, p.distanceFromPrevious = Math.round(I * 1e4) / 1e4, p.distanceFromStart = Math.round((o + I) * 1e4) / 1e4;
|
|
1063
1064
|
break;
|
|
1064
1065
|
}
|
|
1065
1066
|
}
|
|
@@ -1072,11 +1073,11 @@ class H {
|
|
|
1072
1073
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
1073
1074
|
*/
|
|
1074
1075
|
static currentFactor(e, t, a = 0) {
|
|
1075
|
-
const
|
|
1076
|
-
if (Math.abs(
|
|
1076
|
+
const n = R.includedAngle(e, (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
1077
|
+
if (Math.abs(n) === Math.PI / 2)
|
|
1077
1078
|
return 0;
|
|
1078
|
-
let
|
|
1079
|
-
return a & 2 ?
|
|
1079
|
+
let o = ((t == null ? void 0 : t.kts) || 0) * Math.cos(n);
|
|
1080
|
+
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;
|
|
1080
1081
|
}
|
|
1081
1082
|
/**
|
|
1082
1083
|
* 风浪影响因子
|
|
@@ -1087,13 +1088,13 @@ class H {
|
|
|
1087
1088
|
static weatherFactor(e, t, a = 0) {
|
|
1088
1089
|
var k, b, F, I, p, v, m;
|
|
1089
1090
|
E == null || E.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
1090
|
-
const
|
|
1091
|
+
const n = H.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), o = J.roundPrecision(a * 1852 / 3600, 6), i = H.froudeNumber(e.speed - o, e.lbp), s = H.amendFactor(n, i, e.loadCondition);
|
|
1091
1092
|
let r = R.includedAngle(e.bearing, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.degree);
|
|
1092
1093
|
const l = H.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), u = H.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (F = t == null ? void 0 : t.wind) == null ? void 0 : F.kts);
|
|
1093
|
-
let c = l * s * u / 100 * (e.speed -
|
|
1094
|
+
let c = l * s * u / 100 * (e.speed - o);
|
|
1094
1095
|
c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), E == null || E.debug("wind wx factor = %d", c), r = R.includedAngle(e.bearing, (p = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : p.degree);
|
|
1095
|
-
const h = H.waveHeightFactor(((m = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : m.height) ?? 1, r);
|
|
1096
|
-
return E == null || E.debug("wave wx factor = %d", h), c = Math.abs(c) > Math.abs(h) ? c : 0.
|
|
1096
|
+
const h = H.waveHeightFactor(((m = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : m.height) ?? 1, r, e.draught);
|
|
1097
|
+
return E == null || E.debug("wave wx factor = %d", h), c = Math.abs(c) > Math.abs(h) ? c : 0.8 * c + 0.8 * h, E == null || E.debug("weather factor = %d", c), c = Math.abs(c) > 3 ? 3 * (Math.abs(c) / c) + Math.abs(c) / c * (Math.abs(c) - 2) * 0.1 : c, Math.round((c || 0) * 100) / 100;
|
|
1097
1098
|
}
|
|
1098
1099
|
/**
|
|
1099
1100
|
* 以12小时级别去掉重复的days
|
|
@@ -1101,7 +1102,7 @@ class H {
|
|
|
1101
1102
|
* @param interval 12 hours
|
|
1102
1103
|
*/
|
|
1103
1104
|
static async reduceDays(e, t = 12 * 60 * 60) {
|
|
1104
|
-
return e = e == null ? void 0 : e.reduce((a,
|
|
1105
|
+
return e = e == null ? void 0 : e.reduce((a, n) => (n.positionTime || (n.positionTime = w.utc(n.etd || n.eta).unix()), a.some((o) => Math.floor(o.positionTime / t) === Math.floor(n.positionTime / t)) || a.push(n), a), []), e;
|
|
1105
1106
|
}
|
|
1106
1107
|
/**
|
|
1107
1108
|
* 以分钟级别去掉重复的wps
|
|
@@ -1109,7 +1110,7 @@ class H {
|
|
|
1109
1110
|
* @param interval 1 minute
|
|
1110
1111
|
*/
|
|
1111
1112
|
static async reduceWPS(e, t = 60) {
|
|
1112
|
-
return e = e == null ? void 0 : e.reduce((a,
|
|
1113
|
+
return e = e == null ? void 0 : e.reduce((a, n) => (a.some((o) => Math.floor(w(o.etd).unix() / t) === Math.floor(w(n.etd).unix() / t)) || a.push(n), a), []), e;
|
|
1113
1114
|
}
|
|
1114
1115
|
/**
|
|
1115
1116
|
* 全程失速分析(走完航程)
|
|
@@ -1124,22 +1125,22 @@ class H {
|
|
|
1124
1125
|
* @param useRouteParam
|
|
1125
1126
|
* @param options
|
|
1126
1127
|
*/
|
|
1127
|
-
static async analyseInstant(e, t, a,
|
|
1128
|
-
var
|
|
1128
|
+
static async analyseInstant(e, t, a, n, o, i = "", s = 0, r = !0, l = !1, u = {}) {
|
|
1129
|
+
var U, G, X, Q, Z, $;
|
|
1129
1130
|
const c = w().valueOf();
|
|
1130
1131
|
e.lng = J.convertToStdLng(e.lng);
|
|
1131
|
-
const { route: h, waypoints: k } =
|
|
1132
|
-
if (((
|
|
1132
|
+
const { route: h, waypoints: k } = o.points, b = R.calculateSubRoute(e, h);
|
|
1133
|
+
if (((U = b[0]) == null ? void 0 : U.length) <= 1)
|
|
1133
1134
|
return;
|
|
1134
1135
|
const { v0: F, label: I } = e.sog ? {
|
|
1135
1136
|
v0: e.sog,
|
|
1136
1137
|
label: e.label || "Other"
|
|
1137
1138
|
/* Instruct */
|
|
1138
1139
|
} : {
|
|
1139
|
-
v0:
|
|
1140
|
+
v0: n.speed,
|
|
1140
1141
|
label: "CP"
|
|
1141
1142
|
/* Cp */
|
|
1142
|
-
}, p = H.assembleProperties(a,
|
|
1143
|
+
}, p = H.assembleProperties(a, n.loadCondition, F, 0), v = k.length ? R.calculateSubWaypoints(e, k) : [];
|
|
1143
1144
|
v.forEach((P) => P.important = !0);
|
|
1144
1145
|
const m = {
|
|
1145
1146
|
from: { ...e },
|
|
@@ -1153,7 +1154,7 @@ class H {
|
|
|
1153
1154
|
wps: [],
|
|
1154
1155
|
all: []
|
|
1155
1156
|
};
|
|
1156
|
-
s || (R.calculateRouteDistance(b) /
|
|
1157
|
+
s || (R.calculateRouteDistance(b) / n.speed <= 72 ? s = 3 : s = 6);
|
|
1157
1158
|
let f = R.simplifyRouteToCoordinates(b, v, 0), y = 0, S = 0, M = 0, j = 0;
|
|
1158
1159
|
t = w(t).utc();
|
|
1159
1160
|
const N = t.clone();
|
|
@@ -1194,7 +1195,7 @@ class H {
|
|
|
1194
1195
|
}), d.wps = await H.reduceWPS(d.wps), d.days = await H.reduceDays(d.days), d.all = (Z = d.all) == null ? void 0 : Z.reduce((P, B) => (B.positionTime = w.utc(B.etd || B.eta).unix(), P.some((T) => Math.round(T.positionTime / 60) === Math.round(B.positionTime / 60)) || P.push(B), P), []), m.sample = d;
|
|
1195
1196
|
const W = d.hours.at(0), C = d.hours.at(-1);
|
|
1196
1197
|
m.distance = Math.round(C.distanceFromStart * 1e3) / 1e3, m.etd = w(W.eta).utc().format(), m.eta = w(C.eta).utc().format(), m.wxFactor = Math.round(S / j * 1e3) / 1e3, m.cFactor = Math.round(M / j * 1e3) / 1e3, m.avgSpeed = Math.round(C.distanceFromStart / j * 1e3) / 1e3, m.totalHrs = Math.round(j * 1e3) / 1e3, m.suspend = Math.round(L * 1e3) / 1e3;
|
|
1197
|
-
const Y = J.roundPrecision(
|
|
1198
|
+
const Y = J.roundPrecision(n.dgo / 24 * L, 3), { distanceInECA: A, hoursInECA: V, totalDgoConsInECA: ot, eca: tt } = await this.calculateECA(m, n, u), et = J.roundPrecision(n.fo / 24 * (j - V), 3), it = J.roundPrecision(n.dgo / 24 * j + Y, 3);
|
|
1198
1199
|
m.extend = {
|
|
1199
1200
|
eca: tt,
|
|
1200
1201
|
distanceInECA: A,
|
|
@@ -1220,7 +1221,7 @@ class H {
|
|
|
1220
1221
|
* @param useRouteParam
|
|
1221
1222
|
* @param options
|
|
1222
1223
|
*/
|
|
1223
|
-
static async analyseInstantWithThreshed(e, t, a,
|
|
1224
|
+
static async analyseInstantWithThreshed(e, t, a, n, o, i, s, r = "", l = 3, u = !0, c = !1, h = {}) {
|
|
1224
1225
|
var X, Q, Z, $, P, B;
|
|
1225
1226
|
const k = w().valueOf();
|
|
1226
1227
|
e.lng = J.convertToStdLng(e.lng);
|
|
@@ -1229,10 +1230,10 @@ class H {
|
|
|
1229
1230
|
label: e.label || "Other"
|
|
1230
1231
|
/* Instruct */
|
|
1231
1232
|
} : {
|
|
1232
|
-
v0:
|
|
1233
|
+
v0: o.speed,
|
|
1233
1234
|
label: "CP"
|
|
1234
1235
|
/* Cp */
|
|
1235
|
-
}, I = H.assembleProperties(
|
|
1236
|
+
}, I = H.assembleProperties(n, o.loadCondition, b, 0), p = R.calculateSubRoute(e, i);
|
|
1236
1237
|
if (((X = p[0]) == null ? void 0 : X.length) <= 1)
|
|
1237
1238
|
return;
|
|
1238
1239
|
const v = s.length ? R.calculateSubWaypoints(e, s) : [];
|
|
@@ -1283,7 +1284,7 @@ class H {
|
|
|
1283
1284
|
waypoints: Y,
|
|
1284
1285
|
v0: b,
|
|
1285
1286
|
label: F
|
|
1286
|
-
}, V = J.roundPrecision(
|
|
1287
|
+
}, V = J.roundPrecision(o.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: tt, totalDgoConsInECA: et, eca: it } = await this.calculateECA(A, o, h), rt = J.roundPrecision(o.fo / 24 * (S - tt), 3), st = J.roundPrecision(o.dgo / 24 * S + V, 3);
|
|
1287
1288
|
A.extend = {
|
|
1288
1289
|
eca: it,
|
|
1289
1290
|
distanceInECA: ot,
|
|
@@ -1291,8 +1292,8 @@ class H {
|
|
|
1291
1292
|
totalDgoConsInECA: et,
|
|
1292
1293
|
totalDgoConsInSuspend: V
|
|
1293
1294
|
}, A.totalDgoCons = st, A.totalFoCons = rt < 0 ? 0 : rt;
|
|
1294
|
-
const
|
|
1295
|
-
return E == null || E.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId,
|
|
1295
|
+
const U = w().valueOf() - k, G = ((B = M == null ? void 0 : M.hours) == null ? void 0 : B.length) || 1;
|
|
1296
|
+
return E == null || E.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, U, G, Math.round(U / G * 1e3) / 1e3), A;
|
|
1296
1297
|
}
|
|
1297
1298
|
/**
|
|
1298
1299
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1309,11 +1310,11 @@ class H {
|
|
|
1309
1310
|
* @param lane 基础航线(重要转向点)
|
|
1310
1311
|
* @param options
|
|
1311
1312
|
*/
|
|
1312
|
-
static async analyseCost(e, t, a,
|
|
1313
|
+
static async analyseCost(e, t, a, n, o = {}) {
|
|
1313
1314
|
var p, v;
|
|
1314
1315
|
const i = w().valueOf(), s = [];
|
|
1315
1316
|
e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
|
|
1316
|
-
const r = R.calculateRouteDistance(
|
|
1317
|
+
const r = R.calculateRouteDistance(n.route);
|
|
1317
1318
|
let l = 0;
|
|
1318
1319
|
a.forEach((m) => {
|
|
1319
1320
|
const d = Math.ceil(r / m.speed / 24);
|
|
@@ -1322,7 +1323,7 @@ class H {
|
|
|
1322
1323
|
const u = w.utc(e.etd).add(l ?? 14, "day");
|
|
1323
1324
|
let c = 1;
|
|
1324
1325
|
for (const m of a) {
|
|
1325
|
-
const d = JSON.parse(JSON.stringify(
|
|
1326
|
+
const d = JSON.parse(JSON.stringify(n.route)), f = JSON.parse(JSON.stringify(n.waypoints)), y = await H.analyseInstantWithThreshed(
|
|
1326
1327
|
{ lat: e.lat, lng: e.lng },
|
|
1327
1328
|
e.etd,
|
|
1328
1329
|
u,
|
|
@@ -1334,9 +1335,9 @@ class H {
|
|
|
1334
1335
|
e.speedStep,
|
|
1335
1336
|
e.useMeteo,
|
|
1336
1337
|
e.useRouteParam,
|
|
1337
|
-
|
|
1338
|
+
o
|
|
1338
1339
|
);
|
|
1339
|
-
y && (await H.calculateCost(y, m, e,
|
|
1340
|
+
y && (await H.calculateCost(y, m, e, o), s.push(y), E == null || E.info("[%s][L%d-%d] analyse from %s to %s cost: %j", o.requestId, 1, c, e.etd, u.format(), {
|
|
1340
1341
|
cost: y.cost.total,
|
|
1341
1342
|
hire: y.cost.hire,
|
|
1342
1343
|
bunker: y.cost.bunker,
|
|
@@ -1353,7 +1354,7 @@ class H {
|
|
|
1353
1354
|
M = M > 7 ? 7 : M < e.alterStep ? e.alterStep : M;
|
|
1354
1355
|
let j = 2, N = { combined: !1, speeds: [k], cost: (v = k.cost) == null ? void 0 : v.total }, D;
|
|
1355
1356
|
for (; M >= e.alterStep; ) {
|
|
1356
|
-
const L = await H.combinedAnalyse(e, t, u, [m, d],
|
|
1357
|
+
const L = await H.combinedAnalyse(e, t, u, [m, d], n, M, { ...o, level: j });
|
|
1357
1358
|
if (N.cost > L.cost ? D ? (D == null ? void 0 : D.cost) > L.cost && (D = L) : (D = N, N = L) : (!D || (D == null ? void 0 : D.cost) > L.cost) && (D = L), M <= e.alterStep)
|
|
1358
1359
|
break;
|
|
1359
1360
|
M = Math.ceil(M / 2), j += 1;
|
|
@@ -1361,7 +1362,7 @@ class H {
|
|
|
1361
1362
|
b.push(N), D && b.push(D);
|
|
1362
1363
|
}
|
|
1363
1364
|
const I = w().valueOf() - i;
|
|
1364
|
-
return E == null || E.info("[%s] analyse elapsed: %d ms",
|
|
1365
|
+
return E == null || E.info("[%s] analyse elapsed: %d ms", o == null ? void 0 : o.requestId, I), b.sort((m, d) => m.cost - d.cost);
|
|
1365
1366
|
}
|
|
1366
1367
|
/**
|
|
1367
1368
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1373,9 +1374,9 @@ class H {
|
|
|
1373
1374
|
* @param step 步长,7,4,2,1
|
|
1374
1375
|
* @param options
|
|
1375
1376
|
*/
|
|
1376
|
-
static async combinedAnalyse(e, t, a,
|
|
1377
|
+
static async combinedAnalyse(e, t, a, n, o, i, s = {}) {
|
|
1377
1378
|
s.counter = 1, E == null || E.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, i);
|
|
1378
|
-
const r = await H.alternateAnalyse(e, t, a,
|
|
1379
|
+
const r = await H.alternateAnalyse(e, t, a, n, 0, o, i, s), l = r.reduce((d, f) => d + f.cost.total, 0), u = r.reduce((d, f) => d + f.cost.hire, 0), c = r.reduce((d, f) => d + f.cost.bunker, 0), h = r.reduce((d, f) => d + f.distance, 0), k = r.reduce((d, f) => d + f.totalHrs, 0);
|
|
1379
1380
|
E == null || E.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
|
|
1380
1381
|
cost: l,
|
|
1381
1382
|
hire: u,
|
|
@@ -1383,7 +1384,7 @@ class H {
|
|
|
1383
1384
|
distance: h,
|
|
1384
1385
|
hours: k
|
|
1385
1386
|
});
|
|
1386
|
-
const b = await H.alternateAnalyse(e, t, a,
|
|
1387
|
+
const b = await H.alternateAnalyse(e, t, a, n, 1, o, i, s), F = b.reduce((d, f) => d + f.cost.total, 0), I = b.reduce((d, f) => d + f.cost.hire, 0), p = b.reduce((d, f) => d + f.cost.bunker, 0), v = b.reduce((d, f) => d + f.distance, 0), m = b.reduce((d, f) => d + f.totalHrs, 0);
|
|
1387
1388
|
return E == null || E.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
|
|
1388
1389
|
cost: F,
|
|
1389
1390
|
hire: I,
|
|
@@ -1403,12 +1404,12 @@ class H {
|
|
|
1403
1404
|
* @param step 步长,7,4,2,1
|
|
1404
1405
|
* @param options
|
|
1405
1406
|
*/
|
|
1406
|
-
static async alternateAnalyse(e, t, a,
|
|
1407
|
+
static async alternateAnalyse(e, t, a, n, o, i, s, r = {}) {
|
|
1407
1408
|
var h, k;
|
|
1408
1409
|
let l = w.utc(e.etd);
|
|
1409
1410
|
const u = { lat: e.lat, lng: e.lng }, c = [];
|
|
1410
1411
|
for (; l.isBefore(a); ) {
|
|
1411
|
-
const b = l.clone().utc().add(s, "day"), F = JSON.parse(JSON.stringify(i.route)), I = JSON.parse(JSON.stringify(i.waypoints)), p = o
|
|
1412
|
+
const b = l.clone().utc().add(s, "day"), F = JSON.parse(JSON.stringify(i.route)), I = JSON.parse(JSON.stringify(i.waypoints)), p = n[o], v = await H.analyseInstantWithThreshed(
|
|
1412
1413
|
u,
|
|
1413
1414
|
l.utc().format(),
|
|
1414
1415
|
b,
|
|
@@ -1440,7 +1441,7 @@ class H {
|
|
|
1440
1441
|
)), r.counter = r.counter + 1;
|
|
1441
1442
|
const m = (k = (h = v == null ? void 0 : v.sample) == null ? void 0 : h.hours) == null ? void 0 : k.at(-1);
|
|
1442
1443
|
if (m)
|
|
1443
|
-
u.lat = m.lat, u.lng = m.lng, l = w(m.eta), c.push(v),
|
|
1444
|
+
u.lat = m.lat, u.lng = m.lng, l = w(m.eta), c.push(v), o = o ? 0 : 1;
|
|
1444
1445
|
else
|
|
1445
1446
|
break;
|
|
1446
1447
|
}
|
|
@@ -1453,10 +1454,10 @@ class H {
|
|
|
1453
1454
|
* @param props
|
|
1454
1455
|
* @param options
|
|
1455
1456
|
*/
|
|
1456
|
-
static async calculateCost(e, t, a,
|
|
1457
|
-
var
|
|
1457
|
+
static async calculateCost(e, t, a, n = {}) {
|
|
1458
|
+
var o;
|
|
1458
1459
|
if (e) {
|
|
1459
|
-
const i = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, s = Math.round((a.dailyHire || 0) * (e.suspend || 0) / 24 * 1e3) / 1e3, r = Math.round(e.totalHrs / 24 * (a.dailyHire || 0) * (1 - i) * 1e3) / 1e3 + s, l = Math.round(e.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, u = Math.round((e.totalDgoCons + (((
|
|
1460
|
+
const i = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, s = Math.round((a.dailyHire || 0) * (e.suspend || 0) / 24 * 1e3) / 1e3, r = Math.round(e.totalHrs / 24 * (a.dailyHire || 0) * (1 - i) * 1e3) / 1e3 + s, l = Math.round(e.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, u = Math.round((e.totalDgoCons + (((o = e.extend) == null ? void 0 : o.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
|
|
1460
1461
|
e.cost = {
|
|
1461
1462
|
total: Math.round((r + l + u) * 1e3) / 1e3,
|
|
1462
1463
|
hire: Math.round(r * 1e3) / 1e3,
|
|
@@ -1473,21 +1474,21 @@ class H {
|
|
|
1473
1474
|
*/
|
|
1474
1475
|
static async calculateECA(e, t, a = {}) {
|
|
1475
1476
|
var r, l, u, c;
|
|
1476
|
-
const
|
|
1477
|
-
let
|
|
1477
|
+
const n = await R.intersectInECA((e == null ? void 0 : e.route) || []);
|
|
1478
|
+
let o = 0, i = 0, s = 0;
|
|
1478
1479
|
(l = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || l.forEach((h) => {
|
|
1479
1480
|
h.positionTime = w.utc(h.etd || h.eta).unix();
|
|
1480
1481
|
});
|
|
1481
|
-
for (const h of
|
|
1482
|
-
|
|
1482
|
+
for (const h of n) {
|
|
1483
|
+
o += h.distance;
|
|
1483
1484
|
const k = await R.deadReckoningTime((u = h.waypoints) == null ? void 0 : u.at(0), e.sample.all || e.sample.wps), b = await R.deadReckoningTime((c = h.waypoints) == null ? void 0 : c.at(-1), e.sample.all || e.sample.wps);
|
|
1484
1485
|
h.in = k, h.out = b, h.totalHrs = J.roundPrecision((b.positionTime - k.positionTime) / 3600, 3), h.totalDgoCons = J.roundPrecision(t.fo / 24 * h.totalHrs, 3), i += h.totalHrs, s += h.totalDgoCons;
|
|
1485
1486
|
}
|
|
1486
|
-
return
|
|
1487
|
-
distanceInECA:
|
|
1487
|
+
return o = J.roundPrecision(o, 3), i = J.roundPrecision(i, 3), s = J.roundPrecision(s, 3), {
|
|
1488
|
+
distanceInECA: o,
|
|
1488
1489
|
hoursInECA: i,
|
|
1489
1490
|
totalDgoConsInECA: s,
|
|
1490
|
-
eca:
|
|
1491
|
+
eca: n
|
|
1491
1492
|
};
|
|
1492
1493
|
}
|
|
1493
1494
|
/**
|
|
@@ -1502,7 +1503,7 @@ class H {
|
|
|
1502
1503
|
wps: [],
|
|
1503
1504
|
days: [],
|
|
1504
1505
|
all: []
|
|
1505
|
-
},
|
|
1506
|
+
}, n = e.reduce((f, y) => f + y.distance, 0), o = e.reduce((f, y) => {
|
|
1506
1507
|
var S;
|
|
1507
1508
|
return f + (((S = y.extend) == null ? void 0 : S.distanceInECA) || 0);
|
|
1508
1509
|
}, 0), i = e.reduce((f, y) => f + y.totalHrs, 0), s = e.reduce((f, y) => {
|
|
@@ -1558,9 +1559,9 @@ class H {
|
|
|
1558
1559
|
to: e.at(-1).to,
|
|
1559
1560
|
v0: e.at(0).v0,
|
|
1560
1561
|
label: "Combined",
|
|
1561
|
-
distance: Math.round(
|
|
1562
|
+
distance: Math.round(n * 1e3) / 1e3,
|
|
1562
1563
|
totalHrs: Math.round(i * 1e3) / 1e3,
|
|
1563
|
-
avgSpeed: Math.round(
|
|
1564
|
+
avgSpeed: Math.round(n / i * 1e3) / 1e3,
|
|
1564
1565
|
wxFactor: Math.round(l * 1e3) / 1e3,
|
|
1565
1566
|
cFactor: Math.round(u * 1e3) / 1e3,
|
|
1566
1567
|
totalFoCons: Math.round(c * 1e3) / 1e3,
|
|
@@ -1573,7 +1574,7 @@ class H {
|
|
|
1573
1574
|
extend: {
|
|
1574
1575
|
cps: I,
|
|
1575
1576
|
eca: p,
|
|
1576
|
-
distanceInECA: Math.round(
|
|
1577
|
+
distanceInECA: Math.round(o * 1e3) / 1e3,
|
|
1577
1578
|
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1578
1579
|
totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
|
|
1579
1580
|
speeds: e
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(q,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],x):(q=typeof globalThis<"u"?globalThis:q||self,x(q["idm-plugin-vessel"]={},q.got,q["@log4js-node/log4js-api"],q.moment,q["@idm-plugin/geo2"],q["@idm-plugin/meteo2"],q["@idm-plugin/meteo"]))})(this,function(q,x,U,w,E,pt,it){"use strict";var St=Object.defineProperty;var Ct=(q,x,U)=>x in q?St(q,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):q[x]=U;var _=(q,x,U)=>(Ct(q,typeof x!="symbol"?x+"":x,U),U);let M;try{M=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class Mt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:w().utc().format()})}async checkToken(t={}){var a;return(!this.token||w().diff(w(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const c=r.data;if(c)return{mmsi:c.mmsi,imo:Number.isNaN(c.imo)?null:Number(c.imo),callSign:c.callsign,name:c.nameEn,nameCn:c.nameCn,type:c.vesselTypeNameEn,flagName:c.flagCtry,clasz:c.classSociety,dateOfBuild:c.buildYearMonth,deadweight:c.dwt,grossTonnage:c.grt,netTonnage:c.net,teu:c.teu,length:c.length,breadth:c.width,height:c.height,draught:c.draught,speed:c.speed,passengerCapacity:c.passengercapacity,vendor:"myvessel",raw:c}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=w(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.dest,positionTime:u.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,F;const r=w();await this.checkToken(s);const l="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",u={maxDraught:s.draught||10,useAIModel:s.useAIModel??!0,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const c={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,c);const h=await x.post(l,c).json();if(h.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:h.message,status:h.status,code:h.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:v,seas:g,tracks:f,specialRegions:d,ecaLength:m}=h.data;k.nodes=v==null?void 0:v.map(p=>({code:p.nodeCode,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.lat*1e6)/1e6,lng:Math.round(p.lon*1e6)/1e6},start:{lat:Math.round(p.startLat*1e6)/1e6,lng:Math.round(p.startLon*1e6)/1e6},end:{lat:Math.round(p.endLat*1e6)/1e6,lng:Math.round(p.endLat*1e6)/1e6},isKey:p.isKeyNode,isHub:p.isHubNode})),k.seas=g==null?void 0:g.map(p=>({code:p.mrgidSea,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.centerLat*1e6)/1e6,lng:Math.round(p.centerLon*1e6)/1e6},min:{lat:Math.round(p.minLat*1e6)/1e6,lng:Math.round(p.minLon*1e6)/1e6},max:{lat:Math.round(p.maxLat*1e6)/1e6,lng:Math.round(p.maxLon*1e6)/1e6},level:p.mapLevel})),d==null||d.map(p=>{p.regionLength&&k.regions.push({type:p.regionType,distance:p.regionLength,rows:p.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=f==null?void 0:f.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(F=k.waypoints)!=null&&F.length&&(k.waypoints=E.LaneHelper.simplifyCoordinates(k.waypoints),k.route=E.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=E.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=m);const C=w().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=w(a),u=w(o),c=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,c,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,c,s),c}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,F,k,v,g;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(F=this.token)==null?void 0:F.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const c=await x.post(l,u).json();if(c.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:c.message,status:c.status,code:c.code}),c;let h=-1;const I=w(`${(v=(k=c.data)==null?void 0:k[0])==null?void 0:v.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=c.data)==null||g.forEach(f=>{for(const H in f)!isNaN(f[H])&&Number(f[H])!==1/0&&(f[H]=Number(f[H]));const d=w(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),m=f.status,{labelCn:y,labelEn:C}=this.parseStatus(m),p={mmsi:f.mmsi,imo:n==null?void 0:n.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:m,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta)?w(`${f.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:f.dest,positionTime:d.unix(),labelCn:y,labelEn:C,method:"trajectory",vendor:"myVessel",utc:d.utc().format()},L=Math.floor(d.diff(I,"minute",!0)/(i||1));L!==h&&(h=L,s.push(p))}),s}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:u}=this.parseStatus(r),c=w(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:c.unix(),utc:c.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let i=await x.post(o,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},i=await x.post(o,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var f,d,m;const r=await this.realTimePosition(t,s);let l=w(a);const u=w(o),c=w();if(i){let y=u.diff(l,"d",!0);y<0?l=u.clone().subtract(40,"d"):y<30?l.subtract(10,"d"):y<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),y=c.diff(u,"d",!0),u.add(y>10?240:y*24,"h")}const h={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,h).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,h);let F;b&&(F=((d=(f=b.ships)==null?void 0:f.offors)==null?void 0:d.ship)||[],F.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let v=-1;const g=w(`${(m=F==null?void 0:F[0])==null?void 0:m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of F){for(const W in y)!isNaN(y[W])&&Number(y[W])!==1/0&&(y[W]=Number(y[W]));const C=w(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(y.status),H={mmsi:y.m,name:y.n,imo:r==null?void 0:r.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:C.unix(),utc:C.utc().format(),status:y.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(g,"minute",!0)/(n||1));N!==v&&(v=N,k.push(H))}return k}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=w.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var g;const r=await this.realTimePosition(t,s),l=w(a),u=w(o),c="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(c,h).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,c,h),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,F=[],k=w.unix((g=b[0])==null?void 0:g.utc);let v=-1;for(const f of b){const d=w.unix(f.utc),m={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:d.unix(),utc:d.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(d.diff(k,"minute",!0)/(n||1));y!==v&&(v=y,F.push(m))}return F}}class vt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:c}=await this.parseStatus(l.aisNavStatus),h=w.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:h.utc().format(),status:l.aisNavStatus,labelEn:c,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=w(a),l=w(o),u=await this.getShipId(t),c=await this.getShipInfo(u),h=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),c,t,n,h);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),c,t,n,h),h}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},c="https://api3.myships.com/sp/ships/position/history",h=await x.post(c,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,c,u),h.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,h),h;const I=h.data;for(const v in I)!isNaN(I[v])&&Number(I[v])!==1/0&&(I[v]=Number(I[v]));const b=w.unix((k=I[0])==null?void 0:k.posTime);let F=-1;for(const v of I){const g=w.unix(v.posTime),f={imo:n==null?void 0:n.imo,mmsi:i,lat:Math.round(v.lat/1e4/60*1e5)/1e5,lng:Math.round(v.lon/1e4/60*1e5)/1e5,sog:Math.round(v.sog/10*100)/100,cog:Math.round(v.cog/10*100)/100,hdg:Math.round(v.heading*100)/100,rot:Math.round(v.rot*100)/100,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"myship"},d=Math.floor(g.diff(b,"minute",!0)/(s||1));d!==F&&(F=d,r.push(f))}return r}}let K;try{K=U.getLogger("vessel")}catch{}finally{}var lt=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(lt||{});class ht{parsePrinciple(e,t={}){var s,r,l;K==null||K.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const c=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!c)i.scope=n[0];else if(c)for(let h=0,I=c.length;h<I;h++){const b=this.parseRule(c[h]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;K==null||K.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,F,k,v,g,f,d,m,y,C,p,L,H,N,W;let o=0,n=0,i=0,s=0;const r=Math.round(((F=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:F.number)*1.6*100)/100,l=(v=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:v.number,u=(f=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:f.number,c=Math.round((((m=(d=t==null?void 0:t.SEVERE)==null?void 0:d.wind)==null?void 0:m.number)+2)*100)/100,h=(C=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let B=0;B<(e==null?void 0:e.length);B++){const S=e[B],R=(N=(H=S==null?void 0:S.meteo)==null?void 0:H.wave)==null?void 0:N.sig,D=(W=S==null?void 0:S.meteo)==null?void 0:W.wind,z=B?w(S.eta).diff(w(e[B-1].eta),"hour",!0):0;s=z>s?z:s,K==null||K.debug("[%s] check sig.wave: %j",a.requestId,{...R,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(R==null?void 0:R.height)>=r?S.isDangerous=!0:(R==null?void 0:R.height)>=l?S.isSevere=!0:(R==null?void 0:R.height)>=u&&(S.isHeavy=!0),K==null||K.debug("[%s] check wind: %j",a.requestId,{...D,dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I}),(D==null?void 0:D.scale)>=c?(S.isDangerous=!0,delete S.isSevere,delete S.isHeavy):(D==null?void 0:D.scale)>h?(S.isDangerous||(S.isSevere=!0),delete S.isHeavy):(D==null?void 0:D.scale)===I&&!S.isDangerous&&!S.isSevere&&(S.isHeavy=!0),o+=S.isDangerous?z:0,n+=S.isSevere?z:0,i+=S.isHeavy?z:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const wt=new ht;let T;try{T=U.getLogger("vessel")}catch{}finally{}const It=new pt.MeteoHelper2("",!0);var ft=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ft||{}),mt=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(mt||{}),yt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(yt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.15:t>120&&t<=150?a=e<3?.6:-.12:t>150&&t<=180?a=e<3?.7:-.1:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:k,marineModels:v}=await it.Meteo2Assist.autoPickMeteoModel(o),g=await It.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:2,weatherModels:k,marineModels:v}),[f]=it.Meteo2Assist.pickHourly(g,a);u=it.Meteo2Assist.toLegacy(f)}catch(k){T.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},k)}let c=O.currentFactor(e.bearing,u==null?void 0:u.current,n),h=O.weatherFactor(e,u,c);const I=e.speed*1.943844;I+c+h<=0&&(T.warn("[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",r.requestId,I,h+c,h,c),c=Math.round(c*.6*1e3)/1e3,h=Math.round(h*.6*1e3)/1e3);const b=h<=(r.minV0Factor||-1)?Math.max(r.maxV0Factor||-3,-1*h*(h/1.2)):0;h+=b;let F=Math.round((I+c+h)*100)/100;F=F<=0?1:F,l={meteo:{...u},wxFactor:h,v0Factor:b,cFactor:c,speed:t.velocity&&s?t.velocity:F,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,v0Factor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const c=t.clone().add(14,"days"),h=[],I=[],b=[];let F=0,k=0,v,g;for(let f=0;f<i.length-1;f++){let d=i[f];d.distanceFromStart=Math.round((n+k)*1e3)/1e3;const m=i[f+1];if(e.bearing=E.LaneHelper.calculateBearing(d,m,!m.gcToPrevious),d.bearing=e.bearing,d.suspend&&l){d.eta=d.eta||t.utc().format(),d.elapsed=d.elapsed??0;const p=d.suspend-d.elapsed;if(o-F>p)o=o-F-p,t.add(p,"hour"),d.elapsed=d.suspend;else{const L=o-F;d.elapsed+=L,t.add(L,"hour"),o=0}if(T==null||T.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`,u.requestId,d),o===0)return d.distanceFromPrevious=k,{etd:t,from:g||d,to:d,next:i.filter(L=>L),wps:h,days:I,all:b}}else d.suspend=0;r=t.isAfter(c)?!1:r,d=await O.speedLoseAt(e,d,t,s,0,r,l,u),b.push(d),g=g||d,d.important&&h.push(d),t.isSameOrAfter(a)&&(I.push(d),a.add(24,"hour"));const y=E.LaneHelper.calculateDistance(d,m,!m.gcToPrevious);let C=Math.round(y/g.speed*1e5)/1e5;if(F+C<o){if(F+=C,t.add(C,"hour"),delete i[f],T==null||T.debug(`[%s] go to %j from %j with ${y}nm, and cost ${C} hours`,u.requestId,{lat:m.lat,lng:m.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),k+=y,i.filter(p=>p).length<=1){v=m,v.eta=t.utc().format(),v.distanceFromPrevious=y,v.distanceFromStart=Math.round((n+k)*1e4)/1e4,h.push(v),b.push(v),delete i[f+1];break}}else{C=o-F,t.add(C,"hour");const p=E.LngLatHelper.roundPrecision(g.speed*C,5);v=E.LaneHelper.calculateCoordinate(d,e.bearing,p,"nauticalmiles",!m.gcToPrevious),v.eta=t.utc().format(),i[f]=v,T==null||T.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.requestId,{lat:v.lat,lng:v.lng},{lat:d.lat,lng:d.lng,etd:d.etd}),k+=p,v.distanceFromPrevious=Math.round(k*1e4)/1e4,v.distanceFromStart=Math.round((n+k)*1e4)/1e4;break}}return{etd:t,from:g,to:v,next:i.filter(f=>f),wps:h,days:I,all:b}}static currentFactor(e,t,a=0){const o=E.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t,a=0){var I,b,F,k,v,g,f;T==null||T.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=E.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=E.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(F=t==null?void 0:t.wind)==null?void 0:F.kts);let c=l*s*u/100*(e.speed-n);c=Math.round(c*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),T==null||T.debug("wind wx factor = %d",c),r=E.LaneHelper.includedAngle(e.bearing,(v=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:v.degree);const h=O.waveHeightFactor(((f=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:f.height)??1,r);return T==null||T.debug("wave wx factor = %d",h),c=Math.abs(c)>Math.abs(h)?c:.6*c+.8*h,T==null||T.debug("weather factor = %d",c),c=Math.abs(c)>3?3*(Math.abs(c)/c)+Math.abs(c)/c*(Math.abs(c)-2)*.1:c,Math.round((c||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=w.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(w(n.etd).unix()/t)===Math.floor(w(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const c=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:I}=n.points,b=E.LaneHelper.calculateSubRoute(e,h);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:F,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},v=O.assembleProperties(a,o.loadCondition,F,0),g=I.length?E.LaneHelper.calculateSubWaypoints(e,I):[];g.forEach(P=>P.important=!0);const f={from:{...e},route:b,waypoints:g,v0:F,label:k},d={hours:[],days:[],wps:[],all:[]};s||(E.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let m=E.LaneHelper.simplifyRouteToCoordinates(b,g,0),y=0,C=0,p=0,L=0;t=w(t).utc();const H=t.clone();for(;m.length>0;){const P=s-t.hour()%s,J=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(v,t,H,J,y,m,i,r,l,u);if(d.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(d.hours.push(j.from),d.wps.push(...j.wps),d.days.push(...j.days)),m=j==null?void 0:j.next,!m.length){const V=await O.speedLoseAt(v,j.to,w(j.to.eta),i,0,r,l,u);V.bearing=v.bearing,d.hours.push(V),d.all.push(V)}y+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=d.hours;for(let P=0;P<N.length-1;P++){const J=w(N[P+1].eta).diff(N[P].etd,"hour",!0)||1;C+=(N[P].wxFactor||0)*J,p+=(N[P].cFactor||0)*J,L+=J}const W=N.reduce((P,J)=>P+(J.suspend||0),0);($=d.wps)==null||$.forEach((P,J)=>{P.positionTime=w.utc(P.etd||P.eta).unix();const j=d.wps[J-1];if(j){const V=P.distanceFromStart-j.distanceFromStart,Y=w(P.eta||P.etd).diff(w(j.etd||j.eta),"h",!0);P.avgSpd=Math.round(V/Y*100)/100;const ot=E.LaneHelper.calculateBearing(j,P);P.avgBearing=ot,j.bearing=ot}}),d.wps=await O.reduceWPS(d.wps),d.days=await O.reduceDays(d.days),d.all=(tt=d.all)==null?void 0:tt.reduce((P,J)=>(J.positionTime=w.utc(J.etd||J.eta).unix(),P.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||P.push(J),P),[]),f.sample=d;const B=d.hours.at(0),S=d.hours.at(-1);f.distance=Math.round(S.distanceFromStart*1e3)/1e3,f.etd=w(B.eta).utc().format(),f.eta=w(S.eta).utc().format(),f.wxFactor=Math.round(C/L*1e3)/1e3,f.cFactor=Math.round(p/L*1e3)/1e3,f.avgSpeed=Math.round(S.distanceFromStart/L*1e3)/1e3,f.totalHrs=Math.round(L*1e3)/1e3,f.suspend=Math.round(W*1e3)/1e3;const R=E.LngLatHelper.roundPrecision(o.dgo/24*W,3),{distanceInECA:D,hoursInECA:z,totalDgoConsInECA:rt,eca:st}=await this.calculateECA(f,o,u),at=E.LngLatHelper.roundPrecision(o.fo/24*(L-z),3),ct=E.LngLatHelper.roundPrecision(o.dgo/24*L+R,3);f.extend={eca:st,distanceInECA:D,hoursInECA:z,totalDgoConsInECA:rt,totalDgoConsInSuspend:R},f.totalFoCons=at<0?0:at,f.totalDgoCons=ct;const nt=w().valueOf()-c,ut=((et=d==null?void 0:d.hours)==null?void 0:et.length)||1;return T==null||T.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,ut,Math.round(nt/ut*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,c=!1,h={}){var Z,$,tt,et,P,J;const I=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:F}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},k=O.assembleProperties(o,n.loadCondition,b,0),v=E.LaneHelper.calculateSubRoute(e,i);if(((Z=v[0])==null?void 0:Z.length)<=1)return;const g=s.length?E.LaneHelper.calculateSubWaypoints(e,s):[];g.forEach(j=>j.important=!0);let f=E.LaneHelper.simplifyRouteToCoordinates(v,g,0),d=0,m=0,y=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=w(t).utc();const L=t.clone();for(;f.length>0;){const j=l-t.hour()%l;let V=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;V=t.clone().add(V,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:V;const Y=await O.speedLoseInHoursStep(k,t,L,V,d,f,r,u,c,h);if(p.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(p.hours.push(Y.from),Y!=null&&Y.wps&&p.wps.push(...Y.wps),p.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||p.hours.push(Y==null?void 0:Y.to),d+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!V)break}p.wps=await O.reduceWPS(p.wps),p.days=await O.reduceDays(p.days),p.all=(et=p.all)==null?void 0:et.reduce((j,V)=>(V.positionTime=w.utc(V.etd||V.eta).unix(),j.some(Y=>Math.round(w(Y.etd).unix()/60)===Math.round(w(V.etd).unix()/60))||j.push(V),j),[]),(P=p.wps)==null||P.forEach((j,V)=>{const Y=p.wps[V-1];if(Y){const ot=j.distanceFromStart-Y.distanceFromStart,kt=w(j.eta||j.etd).diff(w(Y.etd||Y.eta),"h",!0);Y.bearing=E.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(ot/kt*100)/100}});const H=p.hours;for(let j=0;j<H.length-1;j++){const V=w(H[j+1].eta).diff(H[j].etd,"hour",!0);m+=H[j].wxFactor*V,y+=H[j].cFactor*V,C+=V}const N=H.reduce((j,V)=>j+(V.suspend||0),0),W=p.hours.at(0),B=p.hours.at(-1),S=await E.LaneHelper.calculateRangeRoute(W,B,v),R=await E.LaneHelper.calculateRangeWaypoints(W,B,v,g),D={sample:p,distance:Math.round(((B==null?void 0:B.distanceFromStart)||0)*1e4)/1e4,etd:w(W.eta).utc().format(),eta:w(B==null?void 0:B.eta).utc().format(),wxFactor:Math.round(m/C*1e3)/1e3,cFactor:Math.round(y/C*1e3)/1e3,avgSpeed:Math.round(((B==null?void 0:B.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:W,to:B,route:S,waypoints:R,v0:b,label:F},z=E.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:rt,hoursInECA:st,totalDgoConsInECA:at,eca:ct}=await this.calculateECA(D,n,h),dt=E.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=E.LngLatHelper.roundPrecision(n.dgo/24*C+z,3);D.extend={eca:ct,distanceInECA:rt,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:z},D.totalDgoCons=nt,D.totalFoCons=dt<0?0:dt;const X=w().valueOf()-I,Q=((J=p==null?void 0:p.hours)==null?void 0:J.length)||1;return T==null||T.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,X,Q,Math.round(X/Q*1e3)/1e3),D}static async analyseCost(e,t,a,o,n={}){var v,g;const i=w().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=E.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(f=>{const d=Math.ceil(r/f.speed/24);l=l<d?d:l}),l=l*1.3;const u=w.utc(e.etd).add(l??14,"day");let c=1;for(const f of a){const d=JSON.parse(JSON.stringify(o.route)),m=JSON.parse(JSON.stringify(o.waypoints)),y=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,f,d,m,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);y&&(await O.calculateCost(y,f,e,n),s.push(y),T==null||T.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,c,e.etd,u.format(),{cost:y.cost.total,hire:y.cost.hire,bunker:y.cost.bunker,distance:y.distance,hours:y.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),c++}s.sort((f,d)=>f.cost.total-d.cost.total);const h=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[h],cost:(v=h.cost)==null?void 0:v.total}),I){const f=h.cost.cp,d=I.cost.cp,m=w(h.eta),y=w(h.etd),C=m.diff(y,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,H={combined:!1,speeds:[I],cost:(g=I.cost)==null?void 0:g.total},N;for(;p>=e.alterStep;){const W=await O.combinedAnalyse(e,t,u,[f,d],o,p,{...n,level:L});if(H.cost>W.cost?N?(N==null?void 0:N.cost)>W.cost&&(N=W):(N=H,H=W):(!N||(N==null?void 0:N.cost)>W.cost)&&(N=W),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(H),N&&b.push(N)}const k=w().valueOf()-i;return T==null||T.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),b.sort((f,d)=>f.cost-d.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,T==null||T.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((d,m)=>d+m.cost.total,0),u=r.reduce((d,m)=>d+m.cost.hire,0),c=r.reduce((d,m)=>d+m.cost.bunker,0),h=r.reduce((d,m)=>d+m.distance,0),I=r.reduce((d,m)=>d+m.totalHrs,0);T==null||T.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:c,distance:h,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),F=b.reduce((d,m)=>d+m.cost.total,0),k=b.reduce((d,m)=>d+m.cost.hire,0),v=b.reduce((d,m)=>d+m.cost.bunker,0),g=b.reduce((d,m)=>d+m.distance,0),f=b.reduce((d,m)=>d+m.totalHrs,0);return T==null||T.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:F,hire:k,bunker:v,distance:g,hours:f}),l<F?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(F*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var h,I;let l=w.utc(e.etd);const u={lat:e.lat,lng:e.lng},c=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),F=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),v=o[n],g=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,v,F,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);g&&(await O.calculateCost(g,v,e,r),T==null||T.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:g.cost.total,hire:g.cost.hire,bunker:g.cost.bunker,distance:g.distance,hours:g.totalHrs,cp:`${v.speed}/${v.fo}/${v.dgo}`})),r.counter=r.counter+1;const f=(I=(h=g==null?void 0:g.sample)==null?void 0:h.hours)==null?void 0:I.at(-1);if(f)u.lat=f.lat,u.lng=f.lng,l=w(f.eta),c.push(g),n=n?0:1;else break}return c}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,c;const o=await E.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(h=>{h.positionTime=w.utc(h.etd||h.eta).unix()});for(const h of o){n+=h.distance;const I=await E.LaneHelper.deadReckoningTime((u=h.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await E.LaneHelper.deadReckoningTime((c=h.waypoints)==null?void 0:c.at(-1),e.sample.all||e.sample.wps);h.in=I,h.out=b,h.totalHrs=E.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),h.totalDgoCons=E.LngLatHelper.roundPrecision(t.fo/24*h.totalHrs,3),i+=h.totalHrs,s+=h.totalDgoCons}return n=E.LngLatHelper.roundPrecision(n,3),i=E.LngLatHelper.roundPrecision(i,3),s=E.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var f,d;const a={hours:[],wps:[],days:[],all:[]},o=e.reduce((m,y)=>m+y.distance,0),n=e.reduce((m,y)=>{var C;return m+(((C=y.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((m,y)=>m+y.totalHrs,0),s=e.reduce((m,y)=>{var C;return m+(((C=y.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((m,y)=>{var C;return m+(((C=y.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((m,y)=>m+y.wxFactor*y.totalHrs/i,0),u=e.reduce((m,y)=>m+y.cFactor*y.totalHrs/i,0),c=e.reduce((m,y)=>m+y.totalFoCons,0),h=e.reduce((m,y)=>m+y.totalDgoCons,0),I=e.reduce((m,y)=>m+y.cost.total,0),b=e.reduce((m,y)=>m+y.cost.hire,0),F=e.reduce((m,y)=>m+y.cost.bunker,0),k=[],v=[];let g;for(const m of e){v.push(...((f=m.extend)==null?void 0:f.eca)||[]);const y=m.sample.hours,C=m.sample.all,p=m.sample.wps,L=m.sample.days,H=y.at(0);g&&(H.distanceFromPrevious=g.distanceFromPrevious,H.distanceFromStart=g.distanceFromStart,y.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),C.at(0).distanceFromPrevious=g.distanceFromPrevious,C.at(0).distanceFromStart=g.distanceFromStart,C.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),p.at(0).distanceFromPrevious=g.distanceFromPrevious,p.at(0).distanceFromStart=g.distanceFromStart,p.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),L.at(0).distanceFromPrevious=g.distanceFromPrevious,L.at(0).distanceFromStart=g.distanceFromStart,L.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)})),H.cp=m.cost.cp;const N=[m.etd,m.eta],W=k.findIndex(S=>S.id===H.cp.id);W===-1?(H.cp.segment=[N],k.push(H.cp)):k[W].segment.push(N),y.forEach(S=>{var D;((D=a.hours)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.hours.push(S)}),C.forEach(S=>{var D;((D=a.all)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.all.push(S)}),p.forEach(S=>{var D;((D=a.wps)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.wps.push(S)}),L.forEach(S=>{var D;((D=a==null?void 0:a.days)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.days.push(S)});const B=(d=a.wps)==null?void 0:d.findIndex(S=>S.eta===H.eta);B===-1?a.wps.push(H):a.wps[B]=H,g=y.at(-1)}return a.wps.sort((m,y)=>w(m.etd).unix()-w(y.etd).unix()),a.wps.forEach((m,y)=>{const C=a.wps[y-1];if(C){const p=m.distanceFromStart-(C.distanceFromStart||0),L=w(m.eta||m.etd).diff(w(C.etd||C.eta),"hour",!0),H=Math.round(p/L*100)/100;m.avgSpd=H;const N=E.LaneHelper.calculateBearing(C,m);C.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(F*1e3)/1e3},extend:{cps:k,eca:v,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}q.AISImpl=G,q.AlertHelper=ht,q.AlertLevel=lt,q.HifleetImpl=bt,q.LoadCondition=mt,q.MyShipImpl=vt,q.MyVesselImpl=Mt,q.ShipxyImpl=gt,q.SpeedHelper=O,q.SpeedLabel=yt,q.VesselTag=ft,q.alertHelper=wt,Object.defineProperty(q,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(q,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],x):(q=typeof globalThis<"u"?globalThis:q||self,x(q["idm-plugin-vessel"]={},q.got,q["@log4js-node/log4js-api"],q.moment,q["@idm-plugin/geo2"],q["@idm-plugin/meteo2"],q["@idm-plugin/meteo"]))})(this,function(q,x,K,w,E,pt,it){"use strict";var St=Object.defineProperty;var Ct=(q,x,K)=>x in q?St(q,x,{enumerable:!0,configurable:!0,writable:!0,value:K}):q[x]=K;var U=(q,x,K)=>(Ct(q,typeof x!="symbol"?x+"":x,K),K);let M;try{M=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class Mt extends G{constructor(t,a){super();U(this,"clientId");U(this,"clientSecret");U(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",n={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await x.post(a,n).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.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:w().utc().format()})}async checkToken(t={}){var a;return(!this.token||w().diff(w(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var s,r;await this.checkToken(a);const n="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",o={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,n,o);const i=await x.post(n,o).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const n=/^\d{7}$/.test(t.toString()),o=n?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=n?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,o,s);const r=await x.get(o,s).json();if(r.status!==200)return M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const c=r.data;if(c)return{mmsi:c.mmsi,imo:Number.isNaN(c.imo)?null:Number(c.imo),callSign:c.callsign,name:c.nameEn,nameCn:c.nameCn,type:c.vesselTypeNameEn,flagName:c.flagCtry,clasz:c.classSociety,dateOfBuild:c.buildYearMonth,deadweight:c.dwt,grossTonnage:c.grt,netTonnage:c.net,teu:c.teu,length:c.length,breadth:c.width,height:c.height,draught:c.draught,speed:c.speed,passengerCapacity:c.passengercapacity,vendor:"myvessel",raw:c}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const n="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",o={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,n,o);const i=await x.post(n,o).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o);const i=await x.get(n,o).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=w(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.dest,positionTime:u.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:u.utc().format()}}else return{}}async calculateRoute(t,a,n,o,i,s={}){var I,b,F;const r=w();await this.checkToken(s);const l="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",u={maxDraught:s.draught||10,useAIModel:s.useAIModel??!0,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),n!=null&&n.length&&(u.crossMonthList=n),o!=null&&o.length&&(u.excludeNodes=o),i!=null&&i.length&&(u.excludeSeaAreas=i);const c={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,c);const h=await x.post(l,c).json();if(h.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:h.message,status:h.status,code:h.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:v,seas:g,tracks:f,specialRegions:d,ecaLength:m}=h.data;k.nodes=v==null?void 0:v.map(p=>({code:p.nodeCode,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.lat*1e6)/1e6,lng:Math.round(p.lon*1e6)/1e6},start:{lat:Math.round(p.startLat*1e6)/1e6,lng:Math.round(p.startLon*1e6)/1e6},end:{lat:Math.round(p.endLat*1e6)/1e6,lng:Math.round(p.endLat*1e6)/1e6},isKey:p.isKeyNode,isHub:p.isHubNode})),k.seas=g==null?void 0:g.map(p=>({code:p.mrgidSea,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.centerLat*1e6)/1e6,lng:Math.round(p.centerLon*1e6)/1e6},min:{lat:Math.round(p.minLat*1e6)/1e6,lng:Math.round(p.minLon*1e6)/1e6},max:{lat:Math.round(p.maxLat*1e6)/1e6,lng:Math.round(p.maxLon*1e6)/1e6},level:p.mapLevel})),d==null||d.map(p=>{p.regionLength&&k.regions.push({type:p.regionType,distance:p.regionLength,rows:p.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=f==null?void 0:f.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(F=k.waypoints)!=null&&F.length&&(k.waypoints=E.LaneHelper.simplifyCoordinates(k.waypoints),k.route=E.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=E.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=m);const C=w().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,n,o,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=w(a),u=w(n),c=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,o,c,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,o,c,s),c}async trajectoryIn30Day(t,a,n,o,i,s,r={}){var b,F,k,v,g;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(F=this.token)==null?void 0:F.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const c=await x.post(l,u).json();if(c.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:c.message,status:c.status,code:c.code}),c;let h=-1;const I=w(`${(v=(k=c.data)==null?void 0:k[0])==null?void 0:v.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=c.data)==null||g.forEach(f=>{for(const H in f)!isNaN(f[H])&&Number(f[H])!==1/0&&(f[H]=Number(f[H]));const d=w(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),m=f.status,{labelCn:y,labelEn:C}=this.parseStatus(m),p={mmsi:f.mmsi,imo:o==null?void 0:o.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:m,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta)?w(`${f.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:f.dest,positionTime:d.unix(),labelCn:y,labelEn:C,method:"trajectory",vendor:"myVessel",utc:d.utc().format()},L=Math.floor(d.diff(I,"minute",!0)/(i||1));L!==h&&(h=L,s.push(p))}),s}}class bt extends G{constructor(t){super();U(this,"token");this.token=t}async realTimePosition(t,a={}){const n="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(n,o).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,n,i),i;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:u}=this.parseStatus(r),c=w(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:c.unix(),utc:c.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let n="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let i=await x.post(n,o).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,n,o),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return n="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(n,o).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,n,o),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const n="https://www.hifleet.com/hifleetapi/getShipSuggest.do",o={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},i=await x.post(n,o).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,n,o);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,n,o,i=!0,s={}){var f,d,m;const r=await this.realTimePosition(t,s);let l=w(a);const u=w(n),c=w();if(i){let y=u.diff(l,"d",!0);y<0?l=u.clone().subtract(40,"d"):y<30?l.subtract(10,"d"):y<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),y=c.diff(u,"d",!0),u.add(y>10?240:y*24,"h")}const h={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,h).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,h);let F;b&&(F=((d=(f=b.ships)==null?void 0:f.offors)==null?void 0:d.ship)||[],F.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let v=-1;const g=w(`${(m=F==null?void 0:F[0])==null?void 0:m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of F){for(const W in y)!isNaN(y[W])&&Number(y[W])!==1/0&&(y[W]=Number(y[W]));const C=w(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(y.status),H={mmsi:y.m,name:y.n,imo:r==null?void 0:r.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:C.unix(),utc:C.utc().format(),status:y.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(g,"minute",!0)/(o||1));N!==v&&(v=N,k.push(H))}return k}}class gt extends G{constructor(t){super();U(this,"token");this.token=t}async realTimePosition(t,a={}){const n={searchParams:{id:t,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(o,n).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=w.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,n,o,i=!0,s={}){var g;const r=await this.realTimePosition(t,s),l=w(a),u=w(n),c="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(c,h).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,c,h),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,F=[],k=w.unix((g=b[0])==null?void 0:g.utc);let v=-1;for(const f of b){const d=w.unix(f.utc),m={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:d.unix(),utc:d.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(d.diff(k,"minute",!0)/(o||1));y!==v&&(v=y,F.push(m))}return F}}class vt extends G{constructor(t){super();U(this,"token");this.token=t}async getShipId(t,a={}){const n={headers:{appKey:this.token},json:{mmsiList:t}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(o,n).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,o,n),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const n={headers:{appKey:this.token},json:{shipId:t}},o="https://api3.myships.com/sp/ships/aissta",i=await x.post(o,n).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,o,n),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const n=await this.getShipId(t,a),o=await this.getShipInfo(n,a),i={headers:{appKey:this.token},json:{shipId:n}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:c}=await this.parseStatus(l.aisNavStatus),h=w.unix(l.posTime);return{...o,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:h.utc().format(),status:l.aisNavStatus,labelEn:c,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,n,o,i=!0,s={}){const r=w(a),l=w(n),u=await this.getShipId(t),c=await this.getShipInfo(u),h=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),c,t,o,h);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),c,t,o,h),h}async trajectoryIn30Day(t,a,n,o,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:n}},c="https://api3.myships.com/sp/ships/position/history",h=await x.post(c,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,c,u),h.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,h),h;const I=h.data;for(const v in I)!isNaN(I[v])&&Number(I[v])!==1/0&&(I[v]=Number(I[v]));const b=w.unix((k=I[0])==null?void 0:k.posTime);let F=-1;for(const v of I){const g=w.unix(v.posTime),f={imo:o==null?void 0:o.imo,mmsi:i,lat:Math.round(v.lat/1e4/60*1e5)/1e5,lng:Math.round(v.lon/1e4/60*1e5)/1e5,sog:Math.round(v.sog/10*100)/100,cog:Math.round(v.cog/10*100)/100,hdg:Math.round(v.heading*100)/100,rot:Math.round(v.rot*100)/100,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"myship"},d=Math.floor(g.diff(b,"minute",!0)/(s||1));d!==F&&(F=d,r.push(f))}return r}}let _;try{_=K.getLogger("vessel")}catch{}finally{}var lt=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(lt||{});class ht{parsePrinciple(e,t={}){var s,r,l;_==null||_.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),n=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,o=n==null?void 0:n.split(";");if(!o)return;const i={};for(let u=0;u<(o==null?void 0:o.length);u++){const c=(l=(r=o[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!c)i.scope=o[0];else if(c)for(let h=0,I=c.length;h<I;h++){const b=this.parseRule(c[h]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;_==null||_.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),n=(i=e==null?void 0:e.match(a))==null?void 0:i[0],o=n==null?void 0:n.split(",");if(o){let s=o[3]==="Number.MAX_VALUE"?100:Number(o[3]);return s=isNaN(s)?1:s,{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:s,key:o[4]}}}checkWeather(e,t,a={}){var b,F,k,v,g,f,d,m,y,C,p,L,H,N,W;let n=0,o=0,i=0,s=0;const r=Math.round(((F=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:F.number)*1.6*100)/100,l=(v=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:v.number,u=(f=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:f.number,c=Math.round((((m=(d=t==null?void 0:t.SEVERE)==null?void 0:d.wind)==null?void 0:m.number)+2)*100)/100,h=(C=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let B=0;B<(e==null?void 0:e.length);B++){const S=e[B],R=(N=(H=S==null?void 0:S.meteo)==null?void 0:H.wave)==null?void 0:N.sig,D=(W=S==null?void 0:S.meteo)==null?void 0:W.wind,z=B?w(S.eta).diff(w(e[B-1].eta),"hour",!0):0;s=z>s?z:s,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...R,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(R==null?void 0:R.height)>=r?S.isDangerous=!0:(R==null?void 0:R.height)>=l?S.isSevere=!0:(R==null?void 0:R.height)>=u&&(S.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...D,dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I}),(D==null?void 0:D.scale)>=c?(S.isDangerous=!0,delete S.isSevere,delete S.isHeavy):(D==null?void 0:D.scale)>h?(S.isDangerous||(S.isSevere=!0),delete S.isHeavy):(D==null?void 0:D.scale)===I&&!S.isDangerous&&!S.isSevere&&(S.isHeavy=!0),n+=S.isDangerous?z:0,o+=S.isSevere?z:0,i+=S.isHeavy?z:0}return n=Math.round(n*100)/100,o=Math.round(o*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:n,severe:o,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const wt=new ht;let T;try{T=K.getLogger("vessel")}catch{}finally{}const It=new pt.MeteoHelper2("",!0);var ft=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ft||{}),mt=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(mt||{}),yt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(yt||{});class O{static blockCoefficient(e,t,a,n){let o=Math.round(e/(t*a*n)*100)/100;o=o<.55?.55:o>.85?.85:o;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-o));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let n=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return n=n<.05?.05:n>.3?.3:n,n}static amendFactor(e,t,a){const n={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=n[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,n){let o;return a==="container"?o=.7*n/2+Math.pow(n,3)/(22*Math.pow(e,2/3)):t==="Ballast"?o=.7*n/2+Math.pow(n,3)/(2.7*Math.pow(e,2/3)):o=.5*n/2+Math.pow(n,3)/(2.7*Math.pow(e,2/3)),o}static waveHeightFactor(e,t,a=10){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let n;return t>30&&t<=60?n=-.6:t>60&&t<=90?n=-.4:t>90&&t<=120?n=e<4?.4:-.15:t>120&&t<=150?n=e<4?.6:-.12:t>150&&t<=180?n=e<4?.7:-.1:n=-.7,Math.round(n*(.144*Math.pow(e,2)+.378*e)*1e4)/1e4}static assembleProperties(e,t,a,n){var h;const o=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:o,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*o*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:n||90}}static async speedLoseAt(e,t,a,n="",o=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{n=(n==null?void 0:n.toUpperCase())==="CMEMS"?"ECMWF":n,n=(n==null?void 0:n.toUpperCase())==="METEO2"?"best_match":n;const{weatherModels:k,marineModels:v}=await it.Meteo2Assist.autoPickMeteoModel(n),g=a.utc().format(),f=await It.spotForecast(t.lat,t.lng,g,!1,!1,!0,{...r,pastDays:1,forecastDays:2,weatherModels:k,marineModels:v}),[d]=it.Meteo2Assist.pickHourly(f,a);u=it.Meteo2Assist.toLegacy(d)}catch(k){T.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:n},k)}let c=O.currentFactor(e.bearing,u==null?void 0:u.current,o),h=O.weatherFactor(e,u,c);const I=e.speed*1.943844;I+c+h<=0&&(T.warn("[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",r.requestId,I,h+c,h,c),c=Math.round(c*.6*1e3)/1e3,h=Math.round(h*.6*1e3)/1e3);const b=h<=(r.minV0Factor||-1)?Math.max(r.maxV0Factor||-3,-1*h*(h/1.2)):0;h+=b;let F=Math.round((I+c+h)*100)/100;F=F<=0?1:F,l={meteo:{...u},wxFactor:h,v0Factor:b,cFactor:c,speed:t.velocity&&s?t.velocity:F,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,v0Factor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,n,o,i,s="",r=!0,l=!1,u={}){t.utc();const c=t.clone().add(14,"days"),h=[],I=[],b=[];let F=0,k=0,v,g;for(let f=0;f<i.length-1;f++){let d=i[f];d.distanceFromStart=Math.round((o+k)*1e3)/1e3;const m=i[f+1];if(e.bearing=E.LaneHelper.calculateBearing(d,m,!m.gcToPrevious),d.bearing=e.bearing,d.suspend&&l){d.eta=d.eta||t.utc().format(),d.elapsed=d.elapsed??0;const p=d.suspend-d.elapsed;if(n-F>p)n=n-F-p,t.add(p,"hour"),d.elapsed=d.suspend;else{const L=n-F;d.elapsed+=L,t.add(L,"hour"),n=0}if(T==null||T.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${n} hours need to go...`,u.requestId,d),n===0)return d.distanceFromPrevious=k,{etd:t,from:g||d,to:d,next:i.filter(L=>L),wps:h,days:I,all:b}}else d.suspend=0;r=t.isAfter(c)?!1:r,d=await O.speedLoseAt(e,d,t,s,0,r,l,u),b.push(d),g=g||d,d.important&&h.push(d),t.isSameOrAfter(a)&&(I.push(d),a.add(24,"hour"));const y=E.LaneHelper.calculateDistance(d,m,!m.gcToPrevious);let C=Math.round(y/g.speed*1e5)/1e5;if(F+C<n){if(F+=C,t.add(C,"hour"),delete i[f],T==null||T.debug(`[%s] go to %j from %j with ${y}nm, and cost ${C} hours`,u.requestId,{lat:m.lat,lng:m.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),k+=y,i.filter(p=>p).length<=1){v=m,v.eta=t.utc().format(),v.distanceFromPrevious=y,v.distanceFromStart=Math.round((o+k)*1e4)/1e4,h.push(v),b.push(v),delete i[f+1];break}}else{C=n-F,t.add(C,"hour");const p=E.LngLatHelper.roundPrecision(g.speed*C,5);v=E.LaneHelper.calculateCoordinate(d,e.bearing,p,"nauticalmiles",!m.gcToPrevious),v.eta=t.utc().format(),i[f]=v,T==null||T.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.requestId,{lat:v.lat,lng:v.lng},{lat:d.lat,lng:d.lng,etd:d.etd}),k+=p,v.distanceFromPrevious=Math.round(k*1e4)/1e4,v.distanceFromStart=Math.round((o+k)*1e4)/1e4;break}}return{etd:t,from:g,to:v,next:i.filter(f=>f),wps:h,days:I,all:b}}static currentFactor(e,t,a=0){const n=E.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(n)===Math.PI/2)return 0;let o=((t==null?void 0:t.kts)||0)*Math.cos(n);return 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(e,t,a=0){var I,b,F,k,v,g,f;T==null||T.debug("calculate weather factor via: %j",{...e,...t});const n=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),o=E.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-o,e.lbp),s=O.amendFactor(n,i,e.loadCondition);let r=E.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(F=t==null?void 0:t.wind)==null?void 0:F.kts);let c=l*s*u/100*(e.speed-o);c=Math.round(c*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),T==null||T.debug("wind wx factor = %d",c),r=E.LaneHelper.includedAngle(e.bearing,(v=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:v.degree);const h=O.waveHeightFactor(((f=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:f.height)??1,r,e.draught);return T==null||T.debug("wave wx factor = %d",h),c=Math.abs(c)>Math.abs(h)?c:.8*c+.8*h,T==null||T.debug("weather factor = %d",c),c=Math.abs(c)>3?3*(Math.abs(c)/c)+Math.abs(c)/c*(Math.abs(c)-2)*.1:c,Math.round((c||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,n)=>(n.positionTime||(n.positionTime=w.utc(n.etd||n.eta).unix()),a.some(o=>Math.floor(o.positionTime/t)===Math.floor(n.positionTime/t))||a.push(n),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,n)=>(a.some(o=>Math.floor(w(o.etd).unix()/t)===Math.floor(w(n.etd).unix()/t))||a.push(n),a),[]),e}static async analyseInstant(e,t,a,n,o,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const c=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:I}=o.points,b=E.LaneHelper.calculateSubRoute(e,h);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:F,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},v=O.assembleProperties(a,n.loadCondition,F,0),g=I.length?E.LaneHelper.calculateSubWaypoints(e,I):[];g.forEach(P=>P.important=!0);const f={from:{...e},route:b,waypoints:g,v0:F,label:k},d={hours:[],days:[],wps:[],all:[]};s||(E.LaneHelper.calculateRouteDistance(b)/n.speed<=72?s=3:s=6);let m=E.LaneHelper.simplifyRouteToCoordinates(b,g,0),y=0,C=0,p=0,L=0;t=w(t).utc();const H=t.clone();for(;m.length>0;){const P=s-t.hour()%s,J=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(v,t,H,J,y,m,i,r,l,u);if(d.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(d.hours.push(j.from),d.wps.push(...j.wps),d.days.push(...j.days)),m=j==null?void 0:j.next,!m.length){const V=await O.speedLoseAt(v,j.to,w(j.to.eta),i,0,r,l,u);V.bearing=v.bearing,d.hours.push(V),d.all.push(V)}y+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=d.hours;for(let P=0;P<N.length-1;P++){const J=w(N[P+1].eta).diff(N[P].etd,"hour",!0)||1;C+=(N[P].wxFactor||0)*J,p+=(N[P].cFactor||0)*J,L+=J}const W=N.reduce((P,J)=>P+(J.suspend||0),0);($=d.wps)==null||$.forEach((P,J)=>{P.positionTime=w.utc(P.etd||P.eta).unix();const j=d.wps[J-1];if(j){const V=P.distanceFromStart-j.distanceFromStart,Y=w(P.eta||P.etd).diff(w(j.etd||j.eta),"h",!0);P.avgSpd=Math.round(V/Y*100)/100;const ot=E.LaneHelper.calculateBearing(j,P);P.avgBearing=ot,j.bearing=ot}}),d.wps=await O.reduceWPS(d.wps),d.days=await O.reduceDays(d.days),d.all=(tt=d.all)==null?void 0:tt.reduce((P,J)=>(J.positionTime=w.utc(J.etd||J.eta).unix(),P.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||P.push(J),P),[]),f.sample=d;const B=d.hours.at(0),S=d.hours.at(-1);f.distance=Math.round(S.distanceFromStart*1e3)/1e3,f.etd=w(B.eta).utc().format(),f.eta=w(S.eta).utc().format(),f.wxFactor=Math.round(C/L*1e3)/1e3,f.cFactor=Math.round(p/L*1e3)/1e3,f.avgSpeed=Math.round(S.distanceFromStart/L*1e3)/1e3,f.totalHrs=Math.round(L*1e3)/1e3,f.suspend=Math.round(W*1e3)/1e3;const R=E.LngLatHelper.roundPrecision(n.dgo/24*W,3),{distanceInECA:D,hoursInECA:z,totalDgoConsInECA:rt,eca:st}=await this.calculateECA(f,n,u),at=E.LngLatHelper.roundPrecision(n.fo/24*(L-z),3),ct=E.LngLatHelper.roundPrecision(n.dgo/24*L+R,3);f.extend={eca:st,distanceInECA:D,hoursInECA:z,totalDgoConsInECA:rt,totalDgoConsInSuspend:R},f.totalFoCons=at<0?0:at,f.totalDgoCons=ct;const nt=w().valueOf()-c,ut=((et=d==null?void 0:d.hours)==null?void 0:et.length)||1;return T==null||T.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,ut,Math.round(nt/ut*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,a,n,o,i,s,r="",l=3,u=!0,c=!1,h={}){var Z,$,tt,et,P,J;const I=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:F}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},k=O.assembleProperties(n,o.loadCondition,b,0),v=E.LaneHelper.calculateSubRoute(e,i);if(((Z=v[0])==null?void 0:Z.length)<=1)return;const g=s.length?E.LaneHelper.calculateSubWaypoints(e,s):[];g.forEach(j=>j.important=!0);let f=E.LaneHelper.simplifyRouteToCoordinates(v,g,0),d=0,m=0,y=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=w(t).utc();const L=t.clone();for(;f.length>0;){const j=l-t.hour()%l;let V=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;V=t.clone().add(V,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:V;const Y=await O.speedLoseInHoursStep(k,t,L,V,d,f,r,u,c,h);if(p.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(p.hours.push(Y.from),Y!=null&&Y.wps&&p.wps.push(...Y.wps),p.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||p.hours.push(Y==null?void 0:Y.to),d+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!V)break}p.wps=await O.reduceWPS(p.wps),p.days=await O.reduceDays(p.days),p.all=(et=p.all)==null?void 0:et.reduce((j,V)=>(V.positionTime=w.utc(V.etd||V.eta).unix(),j.some(Y=>Math.round(w(Y.etd).unix()/60)===Math.round(w(V.etd).unix()/60))||j.push(V),j),[]),(P=p.wps)==null||P.forEach((j,V)=>{const Y=p.wps[V-1];if(Y){const ot=j.distanceFromStart-Y.distanceFromStart,kt=w(j.eta||j.etd).diff(w(Y.etd||Y.eta),"h",!0);Y.bearing=E.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(ot/kt*100)/100}});const H=p.hours;for(let j=0;j<H.length-1;j++){const V=w(H[j+1].eta).diff(H[j].etd,"hour",!0);m+=H[j].wxFactor*V,y+=H[j].cFactor*V,C+=V}const N=H.reduce((j,V)=>j+(V.suspend||0),0),W=p.hours.at(0),B=p.hours.at(-1),S=await E.LaneHelper.calculateRangeRoute(W,B,v),R=await E.LaneHelper.calculateRangeWaypoints(W,B,v,g),D={sample:p,distance:Math.round(((B==null?void 0:B.distanceFromStart)||0)*1e4)/1e4,etd:w(W.eta).utc().format(),eta:w(B==null?void 0:B.eta).utc().format(),wxFactor:Math.round(m/C*1e3)/1e3,cFactor:Math.round(y/C*1e3)/1e3,avgSpeed:Math.round(((B==null?void 0:B.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:W,to:B,route:S,waypoints:R,v0:b,label:F},z=E.LngLatHelper.roundPrecision(o.dgo/24*N,3),{distanceInECA:rt,hoursInECA:st,totalDgoConsInECA:at,eca:ct}=await this.calculateECA(D,o,h),dt=E.LngLatHelper.roundPrecision(o.fo/24*(C-st),3),nt=E.LngLatHelper.roundPrecision(o.dgo/24*C+z,3);D.extend={eca:ct,distanceInECA:rt,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:z},D.totalDgoCons=nt,D.totalFoCons=dt<0?0:dt;const X=w().valueOf()-I,Q=((J=p==null?void 0:p.hours)==null?void 0:J.length)||1;return T==null||T.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,X,Q,Math.round(X/Q*1e3)/1e3),D}static async analyseCost(e,t,a,n,o={}){var v,g;const i=w().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=E.LaneHelper.calculateRouteDistance(n.route);let l=0;a.forEach(f=>{const d=Math.ceil(r/f.speed/24);l=l<d?d:l}),l=l*1.3;const u=w.utc(e.etd).add(l??14,"day");let c=1;for(const f of a){const d=JSON.parse(JSON.stringify(n.route)),m=JSON.parse(JSON.stringify(n.waypoints)),y=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,f,d,m,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,o);y&&(await O.calculateCost(y,f,e,o),s.push(y),T==null||T.info("[%s][L%d-%d] analyse from %s to %s cost: %j",o.requestId,1,c,e.etd,u.format(),{cost:y.cost.total,hire:y.cost.hire,bunker:y.cost.bunker,distance:y.distance,hours:y.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),c++}s.sort((f,d)=>f.cost.total-d.cost.total);const h=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[h],cost:(v=h.cost)==null?void 0:v.total}),I){const f=h.cost.cp,d=I.cost.cp,m=w(h.eta),y=w(h.etd),C=m.diff(y,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,H={combined:!1,speeds:[I],cost:(g=I.cost)==null?void 0:g.total},N;for(;p>=e.alterStep;){const W=await O.combinedAnalyse(e,t,u,[f,d],n,p,{...o,level:L});if(H.cost>W.cost?N?(N==null?void 0:N.cost)>W.cost&&(N=W):(N=H,H=W):(!N||(N==null?void 0:N.cost)>W.cost)&&(N=W),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(H),N&&b.push(N)}const k=w().valueOf()-i;return T==null||T.info("[%s] analyse elapsed: %d ms",o==null?void 0:o.requestId,k),b.sort((f,d)=>f.cost-d.cost)}static async combinedAnalyse(e,t,a,n,o,i,s={}){s.counter=1,T==null||T.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,n,0,o,i,s),l=r.reduce((d,m)=>d+m.cost.total,0),u=r.reduce((d,m)=>d+m.cost.hire,0),c=r.reduce((d,m)=>d+m.cost.bunker,0),h=r.reduce((d,m)=>d+m.distance,0),I=r.reduce((d,m)=>d+m.totalHrs,0);T==null||T.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:c,distance:h,hours:I});const b=await O.alternateAnalyse(e,t,a,n,1,o,i,s),F=b.reduce((d,m)=>d+m.cost.total,0),k=b.reduce((d,m)=>d+m.cost.hire,0),v=b.reduce((d,m)=>d+m.cost.bunker,0),g=b.reduce((d,m)=>d+m.distance,0),f=b.reduce((d,m)=>d+m.totalHrs,0);return T==null||T.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:F,hire:k,bunker:v,distance:g,hours:f}),l<F?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(F*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,n,o,i,s,r={}){var h,I;let l=w.utc(e.etd);const u={lat:e.lat,lng:e.lng},c=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),F=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),v=n[o],g=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,v,F,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);g&&(await O.calculateCost(g,v,e,r),T==null||T.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:g.cost.total,hire:g.cost.hire,bunker:g.cost.bunker,distance:g.distance,hours:g.totalHrs,cp:`${v.speed}/${v.fo}/${v.dgo}`})),r.counter=r.counter+1;const f=(I=(h=g==null?void 0:g.sample)==null?void 0:h.hours)==null?void 0:I.at(-1);if(f)u.lat=f.lat,u.lng=f.lng,l=w(f.eta),c.push(g),o=o?0:1;else break}return c}static async calculateCost(e,t,a,n={}){var o;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((o=e.extend)==null?void 0:o.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,c;const n=await E.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let o=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(h=>{h.positionTime=w.utc(h.etd||h.eta).unix()});for(const h of n){o+=h.distance;const I=await E.LaneHelper.deadReckoningTime((u=h.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await E.LaneHelper.deadReckoningTime((c=h.waypoints)==null?void 0:c.at(-1),e.sample.all||e.sample.wps);h.in=I,h.out=b,h.totalHrs=E.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),h.totalDgoCons=E.LngLatHelper.roundPrecision(t.fo/24*h.totalHrs,3),i+=h.totalHrs,s+=h.totalDgoCons}return o=E.LngLatHelper.roundPrecision(o,3),i=E.LngLatHelper.roundPrecision(i,3),s=E.LngLatHelper.roundPrecision(s,3),{distanceInECA:o,hoursInECA:i,totalDgoConsInECA:s,eca:n}}static async mergeSpeeds(e,t={}){var f,d;const a={hours:[],wps:[],days:[],all:[]},n=e.reduce((m,y)=>m+y.distance,0),o=e.reduce((m,y)=>{var C;return m+(((C=y.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((m,y)=>m+y.totalHrs,0),s=e.reduce((m,y)=>{var C;return m+(((C=y.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((m,y)=>{var C;return m+(((C=y.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((m,y)=>m+y.wxFactor*y.totalHrs/i,0),u=e.reduce((m,y)=>m+y.cFactor*y.totalHrs/i,0),c=e.reduce((m,y)=>m+y.totalFoCons,0),h=e.reduce((m,y)=>m+y.totalDgoCons,0),I=e.reduce((m,y)=>m+y.cost.total,0),b=e.reduce((m,y)=>m+y.cost.hire,0),F=e.reduce((m,y)=>m+y.cost.bunker,0),k=[],v=[];let g;for(const m of e){v.push(...((f=m.extend)==null?void 0:f.eca)||[]);const y=m.sample.hours,C=m.sample.all,p=m.sample.wps,L=m.sample.days,H=y.at(0);g&&(H.distanceFromPrevious=g.distanceFromPrevious,H.distanceFromStart=g.distanceFromStart,y.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),C.at(0).distanceFromPrevious=g.distanceFromPrevious,C.at(0).distanceFromStart=g.distanceFromStart,C.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),p.at(0).distanceFromPrevious=g.distanceFromPrevious,p.at(0).distanceFromStart=g.distanceFromStart,p.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)}),L.at(0).distanceFromPrevious=g.distanceFromPrevious,L.at(0).distanceFromStart=g.distanceFromStart,L.forEach((S,R)=>{R&&(S.distanceFromStart=S.distanceFromStart+g.distanceFromStart)})),H.cp=m.cost.cp;const N=[m.etd,m.eta],W=k.findIndex(S=>S.id===H.cp.id);W===-1?(H.cp.segment=[N],k.push(H.cp)):k[W].segment.push(N),y.forEach(S=>{var D;((D=a.hours)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.hours.push(S)}),C.forEach(S=>{var D;((D=a.all)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.all.push(S)}),p.forEach(S=>{var D;((D=a.wps)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.wps.push(S)}),L.forEach(S=>{var D;((D=a==null?void 0:a.days)==null?void 0:D.findIndex(z=>z.eta===S.eta))===-1&&a.days.push(S)});const B=(d=a.wps)==null?void 0:d.findIndex(S=>S.eta===H.eta);B===-1?a.wps.push(H):a.wps[B]=H,g=y.at(-1)}return a.wps.sort((m,y)=>w(m.etd).unix()-w(y.etd).unix()),a.wps.forEach((m,y)=>{const C=a.wps[y-1];if(C){const p=m.distanceFromStart-(C.distanceFromStart||0),L=w(m.eta||m.etd).diff(w(C.etd||C.eta),"hour",!0),H=Math.round(p/L*100)/100;m.avgSpd=H;const N=E.LaneHelper.calculateBearing(C,m);C.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(n*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(n/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(F*1e3)/1e3},extend:{cps:k,eca:v,distanceInECA:Math.round(o*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}q.AISImpl=G,q.AlertHelper=ht,q.AlertLevel=lt,q.HifleetImpl=bt,q.LoadCondition=mt,q.MyShipImpl=vt,q.MyVesselImpl=Mt,q.ShipxyImpl=gt,q.SpeedHelper=O,q.SpeedLabel=yt,q.VesselTag=ft,q.alertHelper=wt,Object.defineProperty(q,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idm-plugin/vessel",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "3.7.
|
|
4
|
+
"version": "3.7.4",
|
|
5
5
|
"description": "idm plugin for vessel",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"keywords": [
|
|
@@ -31,15 +31,10 @@
|
|
|
31
31
|
"got": "11",
|
|
32
32
|
"moment": "^2.30.1"
|
|
33
33
|
},
|
|
34
|
-
"peerDependencies": {
|
|
35
|
-
"@idm-plugin/geo2": "^1.5.9",
|
|
36
|
-
"@idm-plugin/meteo": "^0.5.4",
|
|
37
|
-
"@idm-plugin/tag": "^0.2.3"
|
|
38
|
-
},
|
|
39
34
|
"devDependencies": {
|
|
40
35
|
"@idm-plugin/geo2": "^1.6.8",
|
|
41
|
-
"@idm-plugin/meteo": "^0.
|
|
42
|
-
"@idm-plugin/meteo2": "^0.9.
|
|
36
|
+
"@idm-plugin/meteo": "^0.6.0",
|
|
37
|
+
"@idm-plugin/meteo2": "^0.9.7",
|
|
43
38
|
"@idm-plugin/tag": "^0.3.0",
|
|
44
39
|
"@turf/turf": "^6.5.0",
|
|
45
40
|
"@types/jest": "^25.2.2",
|