@idm-plugin/vessel 3.4.8 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- var lt = Object.defineProperty;
2
- var mt = (x, e, t) => e in x ? lt(x, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : x[e] = t;
1
+ var ht = Object.defineProperty;
2
+ var mt = (x, e, t) => e in x ? ht(x, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : x[e] = t;
3
3
  var U = (x, e, t) => (mt(x, typeof e != "symbol" ? e + "" : e, t), t);
4
4
  import B from "got";
5
5
  import dt from "@log4js-node/log4js-api";
6
- import v from "moment";
7
- import { LaneHelper as W, LngLatHelper as z } from "@idm-plugin/geo2";
6
+ import w from "moment";
7
+ import { LaneHelper as O, LngLatHelper as z } from "@idm-plugin/geo2";
8
8
  import { MeteoHelper2 as ft } from "@idm-plugin/meteo2";
9
9
  import { Meteo2Assist as ct } from "@idm-plugin/meteo";
10
10
  let M;
@@ -54,7 +54,7 @@ class at {
54
54
  return { labelCn: t, labelEn: a };
55
55
  }
56
56
  }
57
- class Tt extends at {
57
+ class jt extends at {
58
58
  constructor(t, a) {
59
59
  super();
60
60
  U(this, "clientId");
@@ -63,25 +63,25 @@ class Tt extends at {
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", i = {
66
+ const a = "https://svc.data.myvessel.cn/ada/oauth/token", o = {
67
67
  searchParams: {
68
68
  client_id: this.clientId,
69
69
  client_secret: this.clientSecret,
70
70
  grant_type: "client_credentials"
71
71
  }
72
- }, n = await B.post(a, i).json();
72
+ }, n = await B.post(a, o).json();
73
73
  M == null || M.info("[%s] fetch access token from: %s - %j", t.requestId, a, n), n.error || (this.token = {
74
74
  accessToken: n.access_token,
75
75
  tokenType: n.token_type,
76
76
  expiresIn: n.expires_in,
77
77
  scope: n.scope,
78
78
  jti: n.jti,
79
- issuedAt: v().utc().format()
79
+ issuedAt: w().utc().format()
80
80
  });
81
81
  }
82
82
  async checkToken(t = {}) {
83
83
  var a;
84
- return (!this.token || v().diff(v(this.token.issuedAt), "seconds") > (((a = this.token) == null ? void 0 : a.expiresIn) || 0) - 300) && await this.authToken(t), this.token;
84
+ 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;
85
85
  }
86
86
  /**
87
87
  * 模糊查询
@@ -91,7 +91,7 @@ class Tt extends at {
91
91
  async suggest(t, a = {}) {
92
92
  var s, r;
93
93
  await this.checkToken(a);
94
- const i = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy", n = {
94
+ const o = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy", n = {
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,18 +100,18 @@ class Tt extends at {
100
100
  recordNum: a.ps || 10
101
101
  }
102
102
  };
103
- M == null || M.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, i, n);
104
- const o = await B.post(i, n).json();
105
- return o.status !== 200 ? (M == null || M.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), []) : (o.data || []).map((l) => ({
106
- mmsi: l.mmsi,
107
- name: l.nameEn,
108
- nameCn: l.nameCn,
109
- imo: Number.isNaN(l.imo) ? null : Number(l.imo),
110
- callSign: l.callsign,
111
- type: l.vesselTypeNameEn,
112
- flagName: l.flagCtry,
103
+ M == null || M.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, o, n);
104
+ const i = await B.post(o, n).json();
105
+ 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) => ({
106
+ mmsi: u.mmsi,
107
+ name: u.nameEn,
108
+ nameCn: u.nameCn,
109
+ imo: Number.isNaN(u.imo) ? null : Number(u.imo),
110
+ callSign: u.callsign,
111
+ type: u.vesselTypeNameEn,
112
+ flagName: u.flagCtry,
113
113
  vendor: "myvessel",
114
- raw: l
114
+ raw: u
115
115
  }));
116
116
  }
117
117
  /**
@@ -120,13 +120,13 @@ class Tt extends at {
120
120
  * @param options
121
121
  */
122
122
  async search(t, a = {}) {
123
- var h, l;
123
+ var l, u;
124
124
  await this.checkToken(a);
125
- const i = /^\d{7}$/.test(t.toString()), n = i ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", o = i ? { imo: t } : { mmsi: t }, s = {
125
+ 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 = {
126
126
  headers: {
127
- Authorization: `${(h = this.token) == null ? void 0 : h.tokenType} ${(l = this.token) == null ? void 0 : l.accessToken}`
127
+ Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(u = this.token) == null ? void 0 : u.accessToken}`
128
128
  },
129
- searchParams: o
129
+ searchParams: i
130
130
  };
131
131
  M == null || M.info("[%s] fetch vessel from: %s - %j", a.requestId, n, s);
132
132
  const r = await B.get(n, s).json();
@@ -164,7 +164,7 @@ class Tt extends at {
164
164
  async archives(t, a = {}) {
165
165
  var s, r;
166
166
  await this.checkToken(a);
167
- const i = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch", n = {
167
+ const o = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch", n = {
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,28 +172,28 @@ class Tt extends at {
172
172
  mmsiList: typeof t == "number" ? [t] : t
173
173
  }
174
174
  };
175
- M == null || M.info("[%s] fetch vessel archive from: %s - %j", a.requestId, i, n);
176
- const o = await B.post(i, n).json();
177
- return o.status !== 200 ? (M == null || M.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), {}) : o.data;
175
+ M == null || M.info("[%s] fetch vessel archive from: %s - %j", a.requestId, o, n);
176
+ const i = await B.post(o, n).json();
177
+ 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;
178
178
  }
179
179
  async realTimePosition(t, a = {}) {
180
- var r, h;
180
+ var r, l;
181
181
  await this.checkToken(a);
182
- const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
182
+ const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
183
183
  headers: {
184
- Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
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
- M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
189
- const o = await B.get(i, n).json();
190
- if (o.code)
191
- return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), o;
192
- const s = o.data;
193
- for (const l in s)
194
- !isNaN(s[l]) && Number(s[l]) !== 1 / 0 && (s[l] = Number(s[l]));
188
+ M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
189
+ const i = await B.get(o, n).json();
190
+ if (i.code)
191
+ return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), i;
192
+ const s = i.data;
193
+ for (const u in s)
194
+ !isNaN(s[u]) && Number(s[u]) !== 1 / 0 && (s[u] = Number(s[u]));
195
195
  if (s) {
196
- const l = v(`${s.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
196
+ const u = w(`${s.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
197
197
  return {
198
198
  mmsi: s.mmsi,
199
199
  name: s.vesselName || s.aisVesselName,
@@ -208,9 +208,9 @@ class Tt extends at {
208
208
  cog: s.cog,
209
209
  hdg: s.hdg,
210
210
  rot: s.rot,
211
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? v.utc(s.eta).format() : void 0,
211
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? w.utc(s.eta).format() : void 0,
212
212
  destination: s.dest,
213
- positionTime: l.unix(),
213
+ positionTime: u.unix(),
214
214
  status: s.status,
215
215
  labelCn: s.statusNameCn,
216
216
  labelEn: s.statusNameEn,
@@ -223,7 +223,7 @@ class Tt extends at {
223
223
  net: s.net,
224
224
  method: "position",
225
225
  vendor: "myVessel",
226
- utc: l.utc().format()
226
+ utc: u.utc().format()
227
227
  };
228
228
  } else
229
229
  return {};
@@ -236,35 +236,39 @@ class Tt extends at {
236
236
  * @param excludeSeas 排除水域, [sea.code]
237
237
  * @param options { requiretId: '请求ID', useAIModel: '启用AI算法', withECA: '是否计算低硫区航行距离', withSpecial: '是否计算穿越的特战区列表和海盗区列表', draught: '最大吃水' }
238
238
  */
239
- async calculateRoute(t, a, i, n, o, s = {}) {
240
- var y, w, g;
241
- const r = v();
239
+ async calculateRoute(t, a, o, n, i, s = {}) {
240
+ var k, b, S;
241
+ const r = w();
242
242
  await this.checkToken(s);
243
- const h = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", l = {
243
+ const l = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", u = {
244
+ endPoint: {
245
+ lon: a.lng,
246
+ lat: a.lat
247
+ },
248
+ maxDraught: s.draught || 10,
249
+ useAIModel: s.useAIModel || !1,
250
+ withECA: s.withECA || !1,
251
+ withSpecialRegion: s.withSpecial || !1
252
+ };
253
+ t.code && (u.startPortCode = t.code), t.lng !== void 0 && t.lat !== void 0 && (u.startPoint = {
254
+ lon: t.lng,
255
+ lat: t.lat
256
+ }), a.code && (u.endPortCode = a.code), a.lng !== void 0 && a.lat !== void 0 && (u.endPoint = {
257
+ lon: a.lng,
258
+ lat: a.lat
259
+ }), o != null && o.length && (u.crossMonthList = o), n != null && n.length && (u.excludeNodes = n), i != null && i.length && (u.excludeSeaAreas = i);
260
+ const d = {
244
261
  headers: {
245
- Authorization: `${(y = this.token) == null ? void 0 : y.tokenType} ${(w = this.token) == null ? void 0 : w.accessToken}`
262
+ Authorization: `${(k = this.token) == null ? void 0 : k.tokenType} ${(b = this.token) == null ? void 0 : b.accessToken}`
246
263
  },
247
- json: {
248
- startPoint: {
249
- lon: t.lng,
250
- lat: t.lat
251
- },
252
- endPoint: {
253
- lon: a.lng,
254
- lat: a.lat
255
- },
256
- maxDraught: s.draught || 10,
257
- useAIModel: s.useAIModel || !1,
258
- withECA: s.withECA || !1,
259
- withSpecialRegion: s.withSpecial || !1
260
- }
264
+ json: u
261
265
  };
262
- i != null && i.length && (l.json.crossMonthList = i), n != null && n.length && (l.json.excludeNodes = n), o != null && o.length && (l.json.excludeSeaAreas = o), M == null || M.info("[%s] fetch route from: %s - %j", s.requestId, h, l);
263
- const d = await B.post(h, l).json();
264
- if (d.status !== 200)
265
- return M == null || M.warn("[%s] fetch route failed: %j", s.requestId, { message: d.message, status: d.status, code: d.code }), {};
266
+ M == null || M.info("[%s] fetch route from: %s - %j", s.requestId, l, d);
267
+ const y = await B.post(l, d).json();
268
+ if (y.status !== 200)
269
+ return M == null || M.warn("[%s] fetch route failed: %j", s.requestId, { message: y.message, status: y.status, code: y.code }), {};
266
270
  {
267
- const k = {
271
+ const C = {
268
272
  status: "Success",
269
273
  nodes: [],
270
274
  seas: [],
@@ -273,52 +277,52 @@ class Tt extends at {
273
277
  route: [],
274
278
  distance: 0,
275
279
  memo: ""
276
- }, { nodes: j, seas: b, tracks: p, specialRegions: f } = d.data;
277
- k.nodes = j == null ? void 0 : j.map((c) => ({
278
- code: c.nodeCode,
279
- nameEn: c.nameEn,
280
- nameCn: c.nameCn,
280
+ }, { nodes: p, seas: v, tracks: m, specialRegions: c } = y.data;
281
+ C.nodes = p == null ? void 0 : p.map((g) => ({
282
+ code: g.nodeCode,
283
+ nameEn: g.nameEn,
284
+ nameCn: g.nameCn,
281
285
  // 中心
282
286
  center: {
283
- lat: Math.round(c.lat * 1e6) / 1e6,
284
- lng: Math.round(c.lon * 1e6) / 1e6
287
+ lat: Math.round(g.lat * 1e6) / 1e6,
288
+ lng: Math.round(g.lon * 1e6) / 1e6
285
289
  },
286
290
  // 起点
287
291
  start: {
288
- lat: Math.round(c.startLat * 1e6) / 1e6,
289
- lng: Math.round(c.startLon * 1e6) / 1e6
292
+ lat: Math.round(g.startLat * 1e6) / 1e6,
293
+ lng: Math.round(g.startLon * 1e6) / 1e6
290
294
  },
291
295
  // 终点
292
296
  end: {
293
- lat: Math.round(c.endLat * 1e6) / 1e6,
294
- lng: Math.round(c.endLat * 1e6) / 1e6
297
+ lat: Math.round(g.endLat * 1e6) / 1e6,
298
+ lng: Math.round(g.endLat * 1e6) / 1e6
295
299
  },
296
300
  // 是否为不可避开关键节点
297
- isKey: c.isKeyNode,
301
+ isKey: g.isKeyNode,
298
302
  // 重要枢纽节点
299
- isHub: c.isHubNode
300
- })), k.seas = b == null ? void 0 : b.map((c) => ({
301
- code: c.mrgidSea,
302
- nameEn: c.nameEn,
303
- nameCn: c.nameCn,
303
+ isHub: g.isHubNode
304
+ })), C.seas = v == null ? void 0 : v.map((g) => ({
305
+ code: g.mrgidSea,
306
+ nameEn: g.nameEn,
307
+ nameCn: g.nameCn,
304
308
  center: {
305
- lat: Math.round(c.centerLat * 1e6) / 1e6,
306
- lng: Math.round(c.centerLon * 1e6) / 1e6
309
+ lat: Math.round(g.centerLat * 1e6) / 1e6,
310
+ lng: Math.round(g.centerLon * 1e6) / 1e6
307
311
  },
308
312
  min: {
309
- lat: Math.round(c.minLat * 1e6) / 1e6,
310
- lng: Math.round(c.minLon * 1e6) / 1e6
313
+ lat: Math.round(g.minLat * 1e6) / 1e6,
314
+ lng: Math.round(g.minLon * 1e6) / 1e6
311
315
  },
312
316
  max: {
313
- lat: Math.round(c.maxLat * 1e6) / 1e6,
314
- lng: Math.round(c.maxLon * 1e6) / 1e6
317
+ lat: Math.round(g.maxLat * 1e6) / 1e6,
318
+ lng: Math.round(g.maxLon * 1e6) / 1e6
315
319
  },
316
- level: c.mapLevel
317
- })), f == null || f.map((c) => {
318
- c.regionLength && k.regions.push({
319
- type: c.regionType,
320
- distance: c.regionLength,
321
- rows: c.regions.map((I) => ({
320
+ level: g.mapLevel
321
+ })), c == null || c.map((g) => {
322
+ g.regionLength && C.regions.push({
323
+ type: g.regionType,
324
+ distance: g.regionLength,
325
+ rows: g.regions.map((I) => ({
322
326
  code: I.regionCode,
323
327
  nameCn: I.nameCn,
324
328
  nameEn: I.nameEn,
@@ -326,62 +330,62 @@ class Tt extends at {
326
330
  distance: I.length
327
331
  }))
328
332
  });
329
- }), k.waypoints = p == null ? void 0 : p.map((c) => ({
330
- lat: Math.round(c.lat * 1e5) / 1e5,
331
- lng: Math.round(c.lon * 1e5) / 1e5
332
- })), (g = k.waypoints) != null && g.length && (k.waypoints = W.simplifyCoordinates(k.waypoints), k.route = W.divideAccordingToLng(k.waypoints), k.distance = W.calculateRouteDistance(k.route));
333
- const m = v().diff(r, "second");
334
- return k.memo = `time cost: ${m}s`, M.info("[%s] calculate route cost: %d seconds", s.requestId, m), k;
333
+ }), C.waypoints = m == null ? void 0 : m.map((g) => ({
334
+ lat: Math.round(g.lat * 1e5) / 1e5,
335
+ lng: Math.round(g.lon * 1e5) / 1e5
336
+ })), (S = C.waypoints) != null && S.length && (C.waypoints = O.simplifyCoordinates(C.waypoints), C.route = O.divideAccordingToLng(C.waypoints), C.distance = O.calculateRouteDistance(C.route));
337
+ const h = w().diff(r, "second");
338
+ return C.memo = `time cost: ${h}s`, M.info("[%s] calculate route cost: %d seconds", s.requestId, h), C;
335
339
  }
336
340
  }
337
- async trajectory(t, a, i, n, o = !0, s = {}) {
341
+ async trajectory(t, a, o, n, i = !0, s = {}) {
338
342
  await this.checkToken(s);
339
- const r = await this.realTimePosition(t, s), h = v(a), l = v(i), d = [];
340
- for (; l.diff(h, "day", !0) > 30; )
341
- await this.trajectoryIn30Day(t, h, h.clone().add(30, "day"), r, n, d, s), h.add(30, "day");
342
- return await this.trajectoryIn30Day(t, h, l, r, n, d, s), d;
343
+ const r = await this.realTimePosition(t, s), l = w(a), u = w(o), d = [];
344
+ for (; u.diff(l, "day", !0) > 30; )
345
+ await this.trajectoryIn30Day(t, l, l.clone().add(30, "day"), r, n, d, s), l.add(30, "day");
346
+ return await this.trajectoryIn30Day(t, l, u, r, n, d, s), d;
343
347
  }
344
- async trajectoryIn30Day(t, a, i, n, o, s, r = {}) {
345
- var g, k, j, b, p;
346
- const h = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", l = {
348
+ async trajectoryIn30Day(t, a, o, n, i, s, r = {}) {
349
+ var b, S, C, p, v;
350
+ const l = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", u = {
347
351
  headers: {
348
- Authorization: `${(g = this.token) == null ? void 0 : g.tokenType} ${(k = this.token) == null ? void 0 : k.accessToken}`
352
+ Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(S = this.token) == null ? void 0 : S.accessToken}`
349
353
  },
350
354
  json: {
351
355
  mmsi: t,
352
356
  startTime: a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
353
- endTime: i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
357
+ endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
354
358
  }
355
359
  };
356
- M == null || M.info("[%s] fetch trajectory from: %s - %j", r.requestId, h, l);
357
- const d = await B.post(h, l).json();
360
+ M == null || M.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, u);
361
+ const d = await B.post(l, u).json();
358
362
  if (d.code)
359
- return M == null || M.warn("[%s] fetch trajectory failed: %j", r.requestId, h, { message: d.message, status: d.status, code: d.code }), d;
363
+ return M == null || M.warn("[%s] fetch trajectory failed: %j", r.requestId, l, { message: d.message, status: d.status, code: d.code }), d;
360
364
  let y = -1;
361
- const w = v(`${(b = (j = d.data) == null ? void 0 : j[0]) == null ? void 0 : b.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
362
- return (p = d.data) == null || p.forEach((f) => {
363
- for (const P in f)
364
- !isNaN(f[P]) && Number(f[P]) !== 1 / 0 && (f[P] = Number(f[P]));
365
- const u = v(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), m = f.status, { labelCn: c, labelEn: I } = this.parseStatus(m), C = {
366
- mmsi: f.mmsi,
365
+ const k = w(`${(p = (C = d.data) == null ? void 0 : C[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
366
+ return (v = d.data) == null || v.forEach((m) => {
367
+ for (const P in m)
368
+ !isNaN(m[P]) && Number(m[P]) !== 1 / 0 && (m[P] = Number(m[P]));
369
+ const c = w(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), f = m.status, { labelCn: h, labelEn: g } = this.parseStatus(f), I = {
370
+ mmsi: m.mmsi,
367
371
  imo: n == null ? void 0 : n.imo,
368
- lat: f.lat,
369
- lng: f.lon,
370
- sog: f.sog,
371
- cog: f.cog,
372
- hdg: f.hdg,
373
- draught: f.draught,
374
- status: m,
375
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta) ? v(`${f.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
376
- destination: f.dest,
377
- positionTime: u.unix(),
378
- labelCn: c,
379
- labelEn: I,
372
+ lat: m.lat,
373
+ lng: m.lon,
374
+ sog: m.sog,
375
+ cog: m.cog,
376
+ hdg: m.hdg,
377
+ draught: m.draught,
378
+ status: f,
379
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta) ? w(`${m.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
380
+ destination: m.dest,
381
+ positionTime: c.unix(),
382
+ labelCn: h,
383
+ labelEn: g,
380
384
  method: "trajectory",
381
385
  vendor: "myVessel",
382
- utc: u.utc().format()
383
- }, F = Math.floor(u.diff(w, "minute", !0) / (o || 1));
384
- F !== y && (y = F, s.push(C));
386
+ utc: c.utc().format()
387
+ }, F = Math.floor(c.diff(k, "minute", !0) / (i || 1));
388
+ F !== y && (y = F, s.push(I));
385
389
  }), s;
386
390
  }
387
391
  }
@@ -392,20 +396,20 @@ class Ft extends at {
392
396
  this.token = t;
393
397
  }
394
398
  async realTimePosition(t, a = {}) {
395
- const i = "https://api.hifleet.com/position/position/get/token", n = {
399
+ const o = "https://api.hifleet.com/position/position/get/token", n = {
396
400
  searchParams: {
397
401
  mmsi: t,
398
402
  usertoken: this.token
399
403
  }
400
- }, o = await B.post(i, n).json();
401
- M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
402
- const s = o == null ? void 0 : o.list;
404
+ }, i = await B.post(o, n).json();
405
+ M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
406
+ const s = i == null ? void 0 : i.list;
403
407
  if (!s)
404
- return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, i, o), o;
405
- for (const w in s)
406
- !isNaN(s[w]) && Number(s[w]) !== 1 / 0 && (s[w] = Number(s[w]));
408
+ return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, o, i), i;
409
+ for (const k in s)
410
+ !isNaN(s[k]) && Number(s[k]) !== 1 / 0 && (s[k] = Number(s[k]));
407
411
  s.status = s.sp > 3 ? 0 : 1;
408
- const r = s.status, { labelCn: h, labelEn: l } = this.parseStatus(r), d = v(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
412
+ const r = s.status, { labelCn: l, labelEn: u } = this.parseStatus(r), d = w(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
409
413
  return {
410
414
  mmsi: s.m,
411
415
  name: s.n,
@@ -420,7 +424,7 @@ class Ft extends at {
420
424
  cog: s.co,
421
425
  hdg: s.h,
422
426
  rot: isNaN(s.rot) ? 0 : s.rot,
423
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? v.utc(s.eta).format() : void 0,
427
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? w.utc(s.eta).format() : void 0,
424
428
  destination: s.destination,
425
429
  vesselType: s.type,
426
430
  dwt: s.dwt,
@@ -429,14 +433,14 @@ class Ft extends at {
429
433
  positionTime: d.unix(),
430
434
  utc: d.utc().format(),
431
435
  status: r,
432
- labelCn: h,
433
- labelEn: l,
436
+ labelCn: l,
437
+ labelEn: u,
434
438
  method: "position",
435
439
  vendor: "hifleet"
436
440
  };
437
441
  }
438
442
  async search(t, a = {}) {
439
- let i = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
443
+ let o = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
440
444
  const n = {
441
445
  searchParams: {
442
446
  keyword: t
@@ -447,24 +451,24 @@ class Ft extends at {
447
451
  Host: "www.hifleet.com"
448
452
  }
449
453
  };
450
- let o = await B.post(i, n).json();
451
- M == null || M.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]);
452
- for (const r in o)
453
- !isNaN(o[r]) && Number(o[r]) !== 1 / 0 && (o[r] = Number(o[r]));
454
+ let i = await B.post(o, n).json();
455
+ M == null || M.info("[%s] fetch vessel props from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]);
456
+ for (const r in i)
457
+ !isNaN(i[r]) && Number(i[r]) !== 1 / 0 && (i[r] = Number(i[r]));
454
458
  const s = {
455
- mmsi: o.m,
456
- name: o.n,
457
- imo: o.i,
458
- callSign: o.c,
459
- length: o.l,
460
- breadth: o.b,
461
- draught: o.dr,
462
- type: o.t
459
+ mmsi: i.m,
460
+ name: i.n,
461
+ imo: i.i,
462
+ callSign: i.c,
463
+ length: i.l,
464
+ breadth: i.b,
465
+ draught: i.dr,
466
+ type: i.t
463
467
  };
464
- return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(), M == null || M.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]), o && (s.deadweight = Number(o.dwt)), s;
468
+ return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", i = await B.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;
465
469
  }
466
470
  async suggest(t, a = {}) {
467
- const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
471
+ const o = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
468
472
  searchParams: {
469
473
  q: t
470
474
  },
@@ -473,10 +477,10 @@ class Ft extends at {
473
477
  Origin: "https://www.hifleet.com",
474
478
  Host: "www.hifleet.com"
475
479
  }
476
- }, o = await B.post(i, n).json();
477
- M == null || M.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, n);
480
+ }, i = await B.post(o, n).json();
481
+ M == null || M.info("[%s] suggest vessel props from: %s - %j", a.requestId, o, n);
478
482
  const s = [];
479
- for (const r of o)
483
+ for (const r of i)
480
484
  s.push({
481
485
  mmsi: !r.mmsi || isNaN(r.mmsi) ? null : Number(r.mmsi),
482
486
  name: r.name,
@@ -484,57 +488,57 @@ class Ft extends at {
484
488
  imo: !r.imo || isNaN(r.imo) ? null : Number(r.imo),
485
489
  score: r._score
486
490
  });
487
- return s.sort((r, h) => h.score - r.score), s;
491
+ return s.sort((r, l) => l.score - r.score), s;
488
492
  }
489
- async trajectory(t, a, i, n, o = !0, s = {}) {
490
- var f, u, m;
493
+ async trajectory(t, a, o, n, i = !0, s = {}) {
494
+ var m, c, f;
491
495
  const r = await this.realTimePosition(t, s);
492
- let h = v(a);
493
- const l = v(i), d = v();
494
- if (o) {
495
- let c = l.diff(h, "d", !0);
496
- c < 0 ? h = l.clone().subtract(40, "d") : c < 30 ? h.subtract(10, "d") : c < 60 ? h.subtract(5, "d") : h = l.clone().subtract(80, "d"), c = d.diff(l, "d", !0), l.add(c > 10 ? 240 : c * 24, "h");
496
+ let l = w(a);
497
+ const u = w(o), d = w();
498
+ if (i) {
499
+ let h = u.diff(l, "d", !0);
500
+ h < 0 ? l = u.clone().subtract(40, "d") : h < 30 ? l.subtract(10, "d") : h < 60 ? l.subtract(5, "d") : l = u.clone().subtract(80, "d"), h = d.diff(u, "d", !0), u.add(h > 10 ? 240 : h * 24, "h");
497
501
  }
498
502
  const y = {
499
503
  searchParams: {
500
- endtime: l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
501
- starttime: h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
504
+ endtime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
505
+ starttime: l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
502
506
  mmsi: t,
503
507
  usertoken: this.token
504
508
  }
505
- }, w = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", g = await B.get(w, y).json();
506
- M == null || M.info("[%s] fetch trajectory from: %s - %j", s.requestId, w, y);
507
- let k;
508
- g && (k = ((u = (f = g.ships) == null ? void 0 : f.offors) == null ? void 0 : u.ship) || [], k.length || M == null || M.warn("[%s] fetch trajectory failed: %j", s.requestId, g));
509
- const j = [];
510
- let b = -1;
511
- const p = v(`${(m = k == null ? void 0 : k[0]) == null ? void 0 : m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
512
- for (const c of k) {
513
- for (const H in c)
514
- !isNaN(c[H]) && Number(c[H]) !== 1 / 0 && (c[H] = Number(c[H]));
515
- const I = v(`${c.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
516
- c.status = c.sp > 4 ? 0 : 1;
517
- const { labelEn: C, labelCn: F } = this.parseStatus(c.status), P = {
518
- mmsi: c.m,
519
- name: c.n,
509
+ }, k = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await B.get(k, y).json();
510
+ M == null || M.info("[%s] fetch trajectory from: %s - %j", s.requestId, k, y);
511
+ let S;
512
+ b && (S = ((c = (m = b.ships) == null ? void 0 : m.offors) == null ? void 0 : c.ship) || [], S.length || M == null || M.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
513
+ const C = [];
514
+ let p = -1;
515
+ const v = w(`${(f = S == null ? void 0 : S[0]) == null ? void 0 : f.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
516
+ for (const h of S) {
517
+ for (const H in h)
518
+ !isNaN(h[H]) && Number(h[H]) !== 1 / 0 && (h[H] = Number(h[H]));
519
+ const g = w(`${h.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
520
+ h.status = h.sp > 4 ? 0 : 1;
521
+ const { labelEn: I, labelCn: F } = this.parseStatus(h.status), P = {
522
+ mmsi: h.m,
523
+ name: h.n,
520
524
  imo: r == null ? void 0 : r.imo,
521
- lat: c.la,
522
- lng: c.lo,
523
- draught: c.draught,
524
- sog: c.sp,
525
- cog: c.co,
526
- hdg: c.hdg,
527
- positionTime: I.unix(),
528
- utc: I.utc().format(),
529
- status: c.status,
525
+ lat: h.la,
526
+ lng: h.lo,
527
+ draught: h.draught,
528
+ sog: h.sp,
529
+ cog: h.co,
530
+ hdg: h.hdg,
531
+ positionTime: g.unix(),
532
+ utc: g.utc().format(),
533
+ status: h.status,
530
534
  labelCn: F,
531
- labelEn: C,
535
+ labelEn: I,
532
536
  method: "trajectory",
533
537
  vendor: "hifleet"
534
- }, D = Math.floor(I.diff(p, "minute", !0) / (n || 1));
535
- D !== b && (b = D, j.push(P));
538
+ }, D = Math.floor(g.diff(v, "minute", !0) / (n || 1));
539
+ D !== p && (p = D, C.push(P));
536
540
  }
537
- return j;
541
+ return C;
538
542
  }
539
543
  }
540
544
  class Nt extends at {
@@ -544,19 +548,19 @@ class Nt extends at {
544
548
  this.token = t;
545
549
  }
546
550
  async realTimePosition(t, a = {}) {
547
- const i = {
551
+ const o = {
548
552
  searchParams: {
549
553
  id: t,
550
554
  k: this.token,
551
555
  enc: 1
552
556
  }
553
- }, n = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(n, i).json();
554
- if (M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, i), (o == null ? void 0 : o.status) !== 0)
555
- return o;
556
- const s = o.data[0];
557
+ }, n = "https://api.shipxy.com/apicall/GetSingleShip", i = await B.get(n, o).json();
558
+ if (M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o), (i == null ? void 0 : i.status) !== 0)
559
+ return i;
560
+ const s = i.data[0];
557
561
  for (const y in s)
558
562
  !isNaN(s[y]) && Number(s[y]) !== 1 / 0 && (s[y] = Number(s[y]));
559
- const { labelCn: r, labelEn: h } = await this.parseStatus(s.navistat), l = v.unix(s.lasttime);
563
+ const { labelCn: r, labelEn: l } = await this.parseStatus(s.navistat), u = w.unix(s.lasttime);
560
564
  return {
561
565
  mmsi: s.ShipID,
562
566
  name: s.name,
@@ -572,46 +576,46 @@ class Nt extends at {
572
576
  hdg: Math.round(s.hdg / 100 * 100) / 100,
573
577
  rot: Math.round(s.rot / 100 * 100) / 100,
574
578
  positionTime: s.lasttime,
575
- utc: l.utc().format(),
579
+ utc: u.utc().format(),
576
580
  status: s.navistat,
577
- labelEn: h,
581
+ labelEn: l,
578
582
  labelCn: r,
579
583
  method: "position",
580
584
  vendor: "shipxy"
581
585
  };
582
586
  }
583
- async trajectory(t, a, i, n, o = !0, s = {}) {
584
- var p;
585
- const r = await this.realTimePosition(t, s), h = v(a), l = v(i), d = "https://api.shipxy.com/apicall/GetShipTrack", y = {
587
+ async trajectory(t, a, o, n, i = !0, s = {}) {
588
+ var v;
589
+ const r = await this.realTimePosition(t, s), l = w(a), u = w(o), d = "https://api.shipxy.com/apicall/GetShipTrack", y = {
586
590
  searchParams: {
587
591
  id: t,
588
592
  k: this.token,
589
593
  enc: 1,
590
594
  cut: 0,
591
- btm: h.unix(),
592
- etm: l.unix()
595
+ btm: l.unix(),
596
+ etm: u.unix()
593
597
  }
594
- }, w = await B.get(d, y).json();
595
- if (M == null || M.info("[%s] fetch trajectory from: %s - %j", s.requestId, d, y), (w == null ? void 0 : w.status) !== 0)
596
- return w;
597
- const g = w == null ? void 0 : w.points, k = [], j = v.unix((p = g[0]) == null ? void 0 : p.utc);
598
- let b = -1;
599
- for (const f of g) {
600
- const u = v.unix(f.utc), m = {
598
+ }, k = await B.get(d, y).json();
599
+ if (M == null || M.info("[%s] fetch trajectory from: %s - %j", s.requestId, d, y), (k == null ? void 0 : k.status) !== 0)
600
+ return k;
601
+ const b = k == null ? void 0 : k.points, S = [], C = w.unix((v = b[0]) == null ? void 0 : v.utc);
602
+ let p = -1;
603
+ for (const m of b) {
604
+ const c = w.unix(m.utc), f = {
601
605
  imo: r == null ? void 0 : r.imo,
602
606
  mmsi: t,
603
- sog: Math.round(f.sog * 3600 / 1e3 / 1852 * 100) / 100,
604
- cog: Math.round(f.cog / 100 * 100) / 100,
605
- lat: Math.round(f.lat / 1e6 * 1e5) / 1e5,
606
- lng: Math.round(f.lon / 1e6 * 1e5) / 1e5,
607
- positionTime: u.unix(),
608
- utc: u.utc().format(),
607
+ sog: Math.round(m.sog * 3600 / 1e3 / 1852 * 100) / 100,
608
+ cog: Math.round(m.cog / 100 * 100) / 100,
609
+ lat: Math.round(m.lat / 1e6 * 1e5) / 1e5,
610
+ lng: Math.round(m.lon / 1e6 * 1e5) / 1e5,
611
+ positionTime: c.unix(),
612
+ utc: c.utc().format(),
609
613
  method: "trajectory",
610
614
  vendor: "shipxy"
611
- }, c = Math.floor(u.diff(j, "minute", !0) / (n || 1));
612
- c !== b && (b = c, k.push(m));
615
+ }, h = Math.floor(c.diff(C, "minute", !0) / (n || 1));
616
+ h !== p && (p = h, S.push(f));
613
617
  }
614
- return k;
618
+ return S;
615
619
  }
616
620
  }
617
621
  class xt extends at {
@@ -621,28 +625,28 @@ class xt extends at {
621
625
  this.token = t;
622
626
  }
623
627
  async getShipId(t, a = {}) {
624
- const i = {
628
+ const o = {
625
629
  headers: {
626
630
  appKey: this.token
627
631
  },
628
632
  json: {
629
633
  mmsiList: t
630
634
  }
631
- }, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await B.post(n, i).json();
632
- return M == null || M.info("[%s] fetch ship id from: %s - %j", a.requestId, n, i), o.code !== "0" ? o : o.data[0].shipId;
635
+ }, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", i = await B.post(n, o).json();
636
+ return M == null || M.info("[%s] fetch ship id from: %s - %j", a.requestId, n, o), i.code !== "0" ? i : i.data[0].shipId;
633
637
  }
634
638
  async getShipInfo(t, a = {}) {
635
- const i = {
639
+ const o = {
636
640
  headers: {
637
641
  appKey: this.token
638
642
  },
639
643
  json: {
640
644
  shipId: t
641
645
  }
642
- }, n = "https://api3.myships.com/sp/ships/aissta", o = await B.post(n, i).json();
643
- if (M == null || M.info("[%s] fetch ship info from: %s - %j", a.requestId, n, i), o.code !== "0")
644
- return o;
645
- const s = o.data;
646
+ }, n = "https://api3.myships.com/sp/ships/aissta", i = await B.post(n, o).json();
647
+ if (M == null || M.info("[%s] fetch ship info from: %s - %j", a.requestId, n, o), i.code !== "0")
648
+ return i;
649
+ const s = i.data;
646
650
  let r = s.imo;
647
651
  return t === "407170" && (r = "9198379", M == null || M.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, s.imo, r)), {
648
652
  mmsi: s.mmsi,
@@ -655,78 +659,78 @@ class xt extends at {
655
659
  };
656
660
  }
657
661
  async realTimePosition(t, a = {}) {
658
- const i = await this.getShipId(t, a), n = await this.getShipInfo(i, a), o = {
662
+ const o = await this.getShipId(t, a), n = await this.getShipInfo(o, a), i = {
659
663
  headers: {
660
664
  appKey: this.token
661
665
  },
662
666
  json: {
663
- shipId: i
667
+ shipId: o
664
668
  }
665
- }, s = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(s, o).json();
666
- M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, o);
667
- const h = r.data[0];
668
- for (const g in h)
669
- !isNaN(h[g]) && Number(h[g]) !== 1 / 0 && (h[g] = Number(h[g]));
670
- const { labelCn: l, labelEn: d } = await this.parseStatus(h.aisNavStatus), y = v.unix(h.posTime);
669
+ }, s = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(s, i).json();
670
+ M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, i);
671
+ const l = r.data[0];
672
+ for (const b in l)
673
+ !isNaN(l[b]) && Number(l[b]) !== 1 / 0 && (l[b] = Number(l[b]));
674
+ const { labelCn: u, labelEn: d } = await this.parseStatus(l.aisNavStatus), y = w.unix(l.posTime);
671
675
  return {
672
676
  ...n,
673
677
  mmsi: t,
674
- lat: Math.round(h.lat / 1e4 / 60 * 1e5) / 1e5,
675
- lng: Math.round(h.lon / 1e4 / 60 * 1e5) / 1e5,
676
- sog: Math.round(h.sog / 10 * 100) / 100,
677
- cog: Math.round(h.cog / 10 * 100) / 100,
678
- hdg: Math.round(h.heading * 100) / 100,
679
- rot: Math.round(h.rot * 100) / 100,
680
- positionTime: h.posTime,
678
+ lat: Math.round(l.lat / 1e4 / 60 * 1e5) / 1e5,
679
+ lng: Math.round(l.lon / 1e4 / 60 * 1e5) / 1e5,
680
+ sog: Math.round(l.sog / 10 * 100) / 100,
681
+ cog: Math.round(l.cog / 10 * 100) / 100,
682
+ hdg: Math.round(l.heading * 100) / 100,
683
+ rot: Math.round(l.rot * 100) / 100,
684
+ positionTime: l.posTime,
681
685
  utc: y.utc().format(),
682
- status: h.aisNavStatus,
686
+ status: l.aisNavStatus,
683
687
  labelEn: d,
684
- labelCn: l,
688
+ labelCn: u,
685
689
  method: "position",
686
690
  vendor: "myship"
687
691
  };
688
692
  }
689
- async trajectory(t, a, i, n, o = !0, s = {}) {
690
- const r = v(a), h = v(i), l = await this.getShipId(t), d = await this.getShipInfo(l), y = [];
691
- for (; h.diff(r, "day", !0) > 30; )
692
- await this.trajectoryIn30Day(l, r.unix(), r.add(30, "day").unix(), d, t, n, y);
693
- return await this.trajectoryIn30Day(l, r.unix(), h.unix(), d, t, n, y), y;
693
+ async trajectory(t, a, o, n, i = !0, s = {}) {
694
+ const r = w(a), l = w(o), u = await this.getShipId(t), d = await this.getShipInfo(u), y = [];
695
+ for (; l.diff(r, "day", !0) > 30; )
696
+ await this.trajectoryIn30Day(u, r.unix(), r.add(30, "day").unix(), d, t, n, y);
697
+ return await this.trajectoryIn30Day(u, r.unix(), l.unix(), d, t, n, y), y;
694
698
  }
695
- async trajectoryIn30Day(t, a, i, n, o, s, r, h = {}) {
696
- var j;
697
- const l = {
699
+ async trajectoryIn30Day(t, a, o, n, i, s, r, l = {}) {
700
+ var C;
701
+ const u = {
698
702
  headers: {
699
703
  appKey: this.token
700
704
  },
701
705
  json: {
702
706
  shipId: t,
703
707
  startTime: a,
704
- endTime: i
708
+ endTime: o
705
709
  }
706
- }, d = "https://api3.myships.com/sp/ships/position/history", y = await B.post(d, l).json();
707
- if (M == null || M.info("[%s] fetch trajectory from: %s - %j", h.requestId, d, l), y.code !== "0")
708
- return M == null || M.warn("[%s] invoke myship trajectory failed: %j", h.requestId, y), y;
709
- const w = y.data;
710
- for (const b in w)
711
- !isNaN(w[b]) && Number(w[b]) !== 1 / 0 && (w[b] = Number(w[b]));
712
- const g = v.unix((j = w[0]) == null ? void 0 : j.posTime);
713
- let k = -1;
714
- for (const b of w) {
715
- const p = v.unix(b.posTime), f = {
710
+ }, d = "https://api3.myships.com/sp/ships/position/history", y = await B.post(d, u).json();
711
+ if (M == null || M.info("[%s] fetch trajectory from: %s - %j", l.requestId, d, u), y.code !== "0")
712
+ return M == null || M.warn("[%s] invoke myship trajectory failed: %j", l.requestId, y), y;
713
+ const k = y.data;
714
+ for (const p in k)
715
+ !isNaN(k[p]) && Number(k[p]) !== 1 / 0 && (k[p] = Number(k[p]));
716
+ const b = w.unix((C = k[0]) == null ? void 0 : C.posTime);
717
+ let S = -1;
718
+ for (const p of k) {
719
+ const v = w.unix(p.posTime), m = {
716
720
  imo: n == null ? void 0 : n.imo,
717
- mmsi: o,
718
- lat: Math.round(b.lat / 1e4 / 60 * 1e5) / 1e5,
719
- lng: Math.round(b.lon / 1e4 / 60 * 1e5) / 1e5,
720
- sog: Math.round(b.sog / 10 * 100) / 100,
721
- cog: Math.round(b.cog / 10 * 100) / 100,
722
- hdg: Math.round(b.heading * 100) / 100,
723
- rot: Math.round(b.rot * 100) / 100,
724
- positionTime: p.unix(),
725
- utc: p.utc().format(),
721
+ mmsi: i,
722
+ lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
723
+ lng: Math.round(p.lon / 1e4 / 60 * 1e5) / 1e5,
724
+ sog: Math.round(p.sog / 10 * 100) / 100,
725
+ cog: Math.round(p.cog / 10 * 100) / 100,
726
+ hdg: Math.round(p.heading * 100) / 100,
727
+ rot: Math.round(p.rot * 100) / 100,
728
+ positionTime: v.unix(),
729
+ utc: v.utc().format(),
726
730
  method: "trajectory",
727
731
  vendor: "myship"
728
- }, u = Math.floor(p.diff(g, "minute", !0) / (s || 1));
729
- u !== k && (k = u, r.push(f));
732
+ }, c = Math.floor(v.diff(b, "minute", !0) / (s || 1));
733
+ c !== S && (S = c, r.push(m));
730
734
  }
731
735
  return r;
732
736
  }
@@ -748,23 +752,23 @@ class Mt {
748
752
  * @param options
749
753
  */
750
754
  parsePrinciple(e, t = {}) {
751
- var s, r, h;
755
+ var s, r, l;
752
756
  J == null || J.debug("[%s] parse rule: %s", t.requestId, e);
753
- const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = e.match(a) ? (s = e.match(a)) == null ? void 0 : s[0] : void 0, n = i == null ? void 0 : i.split(";");
757
+ const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), o = e.match(a) ? (s = e.match(a)) == null ? void 0 : s[0] : void 0, n = o == null ? void 0 : o.split(";");
754
758
  if (!n)
755
759
  return;
756
- const o = {};
757
- for (let l = 0; l < (n == null ? void 0 : n.length); l++) {
758
- const d = (h = (r = n[l].match(a)) == null ? void 0 : r[0]) == null ? void 0 : h.split("],");
759
- if (l === 0 && !d)
760
- o.scope = n[0];
760
+ const i = {};
761
+ for (let u = 0; u < (n == null ? void 0 : n.length); u++) {
762
+ const d = (l = (r = n[u].match(a)) == null ? void 0 : r[0]) == null ? void 0 : l.split("],");
763
+ if (u === 0 && !d)
764
+ i.scope = n[0];
761
765
  else if (d)
762
- for (let y = 0, w = d.length; y < w; y++) {
763
- const g = this.parseRule(d[y]);
764
- g && (o[g.level] ? g.key ? o[g.level][g == null ? void 0 : g.key] = g : o[g.level] = g : g.key ? o[g.level] = { [g == null ? void 0 : g.key]: g } : o[g.level] = g);
766
+ for (let y = 0, k = d.length; y < k; y++) {
767
+ const b = this.parseRule(d[y]);
768
+ 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);
765
769
  }
766
770
  }
767
- return o;
771
+ return i;
768
772
  }
769
773
  /**
770
774
  * 解析单一告警规则
@@ -773,9 +777,9 @@ class Mt {
773
777
  * @param options
774
778
  */
775
779
  parseRule(e, t = {}) {
776
- var o;
780
+ var i;
777
781
  J == null || J.debug("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
778
- const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (o = e == null ? void 0 : e.match(a)) == null ? void 0 : o[0], n = i == null ? void 0 : i.split(",");
782
+ const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), o = (i = e == null ? void 0 : e.match(a)) == null ? void 0 : i[0], n = o == null ? void 0 : o.split(",");
779
783
  if (n) {
780
784
  let s = n[3] === "Number.MAX_VALUE" ? 100 : Number(n[3]);
781
785
  return s = isNaN(s) ? 1 : s, {
@@ -794,20 +798,20 @@ class Mt {
794
798
  * @param options
795
799
  */
796
800
  checkWeather(e, t, a = {}) {
797
- var g, k, j, b, p, f, u, m, c, I, C, F, P, D, H;
798
- let i = 0, n = 0, o = 0, s = 0;
799
- const r = Math.round(((k = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.sigWave) == null ? void 0 : k.number) * 1.6 * 100) / 100, h = (b = (j = t == null ? void 0 : t.SEVERE) == null ? void 0 : j.sigWave) == null ? void 0 : b.number, l = (f = (p = t == null ? void 0 : t.HEAVY) == null ? void 0 : p.sigWave) == null ? void 0 : f.number, d = Math.round((((m = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : m.number) + 2) * 100) / 100, y = (I = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : I.number, w = (F = (C = t == null ? void 0 : t.HEAVY) == null ? void 0 : C.wind) == null ? void 0 : F.number;
800
- for (let T = 0; T < (e == null ? void 0 : e.length); T++) {
801
- const N = e[T], O = (D = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wave) == null ? void 0 : D.sig, R = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wind, K = T ? v(N.eta).diff(v(e[T - 1].eta), "hour", !0) : 0;
802
- s = K > s ? K : s, J == null || J.debug("[%s] check sig.wave: %j", a.requestId, { ...O, dgThd4Wv: r, svThd4Wv: h, hvThd4Wv: l }), (O == null ? void 0 : O.height) >= r ? N.isDangerous = !0 : (O == null ? void 0 : O.height) >= h ? N.isSevere = !0 : (O == null ? void 0 : O.height) >= l && (N.isHeavy = !0), J == null || J.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }), (R == null ? void 0 : R.scale) >= d ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > y ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === w && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? K : 0, n += N.isSevere ? K : 0, o += N.isHeavy ? K : 0;
801
+ var b, S, C, p, v, m, c, f, h, g, I, F, P, D, H;
802
+ let o = 0, n = 0, i = 0, s = 0;
803
+ const r = Math.round(((S = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : S.number) * 1.6 * 100) / 100, l = (p = (C = t == null ? void 0 : t.SEVERE) == null ? void 0 : C.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, d = Math.round((((f = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : f.number) + 2) * 100) / 100, y = (g = (h = t == null ? void 0 : t.SEVERE) == null ? void 0 : h.wind) == null ? void 0 : g.number, k = (F = (I = t == null ? void 0 : t.HEAVY) == null ? void 0 : I.wind) == null ? void 0 : F.number;
804
+ for (let j = 0; j < (e == null ? void 0 : e.length); j++) {
805
+ const N = e[j], R = (D = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wave) == null ? void 0 : D.sig, W = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wind, K = j ? w(N.eta).diff(w(e[j - 1].eta), "hour", !0) : 0;
806
+ s = K > s ? K : s, J == null || J.debug("[%s] check sig.wave: %j", a.requestId, { ...R, dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u }), (R == null ? void 0 : R.height) >= r ? N.isDangerous = !0 : (R == null ? void 0 : R.height) >= l ? N.isSevere = !0 : (R == null ? void 0 : R.height) >= u && (N.isHeavy = !0), J == null || J.debug("[%s] check wind: %j", a.requestId, { ...W, dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: k }), (W == null ? void 0 : W.scale) >= d ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (W == null ? void 0 : W.scale) > y ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (W == null ? void 0 : W.scale) === k && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), o += N.isDangerous ? K : 0, n += N.isSevere ? K : 0, i += N.isHeavy ? K : 0;
803
807
  }
804
- return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, s = Math.round(s), { sample: e, dangerous: i, severe: n, heavy: o, step: s < 3 ? 3 : s, wind: { dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv: h, hvThd4Wv: l } };
808
+ 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: d, svThd4Wd: y, hvThd4Wd: k }, sig: { dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u } };
805
809
  }
806
810
  }
807
811
  const Dt = new Mt();
808
- let S;
812
+ let T;
809
813
  try {
810
- S = dt.getLogger("vessel");
814
+ T = dt.getLogger("vessel");
811
815
  } catch {
812
816
  } finally {
813
817
  }
@@ -826,11 +830,11 @@ class Y {
826
830
  * @param draught 吃水 m
827
831
  * @return [0.55, 0.85]
828
832
  */
829
- static blockCoefficient(e, t, a, i) {
830
- let n = Math.round(e / (t * a * i) * 100) / 100;
833
+ static blockCoefficient(e, t, a, o) {
834
+ let n = Math.round(e / (t * a * o) * 100) / 100;
831
835
  n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
832
- const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = o.map((r) => Math.abs(r - n));
833
- return o[s.indexOf(Math.min(...s))];
836
+ const i = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = i.map((r) => Math.abs(r - n));
837
+ return i[s.indexOf(Math.min(...s))];
834
838
  }
835
839
  /**
836
840
  * @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
@@ -844,8 +848,8 @@ class Y {
844
848
  * @return [0.05, 0.30]
845
849
  */
846
850
  static froudeNumber(e, t, a = 9.8) {
847
- let i = Math.round(Math.sqrt(e * e / (a * t)) * 100) / 100;
848
- return i = i < 0.05 ? 0.05 : i > 0.3 ? 0.3 : i, i;
851
+ let o = Math.round(Math.sqrt(e * e / (a * t)) * 100) / 100;
852
+ return o = o < 0.05 ? 0.05 : o > 0.3 ? 0.3 : o, o;
849
853
  }
850
854
  /**
851
855
  * 失速修正系數
@@ -855,7 +859,7 @@ class Y {
855
859
  * @private
856
860
  */
857
861
  static amendFactor(e, t, a) {
858
- const i = {
862
+ const o = {
859
863
  0.55: [1.7, -1.4, -7.4],
860
864
  0.6: [2.2, -2.5, -9.7],
861
865
  0.65: [2.6, -3.7, -11.6],
@@ -864,7 +868,7 @@ class Y {
864
868
  0.8: [2.6, -13.1, -15.1],
865
869
  0.85: [3.1, -18.7, 28]
866
870
  };
867
- let o = {
871
+ let i = {
868
872
  0.55: [1.7, -1.4, -7.4],
869
873
  0.6: [2.2, -2.5, -9.7],
870
874
  0.65: [2.6, -3.7, -11.6],
@@ -873,7 +877,7 @@ class Y {
873
877
  0.8: [3, -16.3, -21.6],
874
878
  0.85: [3.4, -20.9, 31.8]
875
879
  }[e];
876
- return a === "Laden" && (o = i[e]), o[0] + o[1] * t + o[2] * Math.pow(t, 2);
880
+ return a === "Laden" && (i = o[e]), i[0] + i[1] * t + i[2] * Math.pow(t, 2);
877
881
  }
878
882
  /**
879
883
  * 失速方向因子
@@ -902,9 +906,9 @@ class Y {
902
906
  * @param kts
903
907
  * @private
904
908
  */
905
- static vesselTagFactor(e, t, a, i) {
909
+ static vesselTagFactor(e, t, a, o) {
906
910
  let n;
907
- return a === "container" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (2.7 * Math.pow(e, 2 / 3)) : n = 0.5 * i / 2 + Math.pow(i, 3) / (2.7 * Math.pow(e, 2 / 3)), n;
911
+ return a === "container" ? n = 0.7 * o / 2 + Math.pow(o, 3) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? n = 0.7 * o / 2 + Math.pow(o, 3) / (2.7 * Math.pow(e, 2 / 3)) : n = 0.5 * o / 2 + Math.pow(o, 3) / (2.7 * Math.pow(e, 2 / 3)), n;
908
912
  }
909
913
  /**
910
914
  * 浪高影响因子
@@ -925,21 +929,21 @@ class Y {
925
929
  * @param bearing 方位角
926
930
  * @private
927
931
  */
928
- static assembleProperties(e, t, a, i) {
932
+ static assembleProperties(e, t, a, o) {
929
933
  var y;
930
- const n = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, o = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, r = e.deadweight ?? 67035.7773, h = ((y = e == null ? void 0 : e.type) == null ? void 0 : y.toLowerCase()) || "common";
934
+ 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 = ((y = e == null ? void 0 : e.type) == null ? void 0 : y.toLowerCase()) || "common";
931
935
  return {
932
- tag: h.indexOf("container") > -1 ? "container" : h.indexOf("tugs") > -1 ? "tugs" : "common",
936
+ tag: l.indexOf("container") > -1 ? "container" : l.indexOf("tugs") > -1 ? "tugs" : "common",
933
937
  lbp: n,
934
938
  loadCondition: t,
935
- draught: o,
939
+ draught: i,
936
940
  breadthMoulded: s,
937
941
  // 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
938
942
  // 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
939
- displacement: Math.round((r / 1.025 + o * s * n * 0.7) * 1e4) / 1e4,
943
+ displacement: Math.round((r / 1.025 + i * s * n * 0.7) * 1e4) / 1e4,
940
944
  // 换算为m/s
941
945
  speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
942
- bearing: i || 90
946
+ bearing: o || 90
943
947
  };
944
948
  }
945
949
  /**
@@ -953,41 +957,41 @@ class Y {
953
957
  * @param useRouteParam true 启用设置速度
954
958
  * @param options
955
959
  */
956
- static async speedLoseAt(e, t, a, i = "", n = 2, o = !0, s = !1, r = {}) {
957
- let h;
958
- if (t.velocity && s && (e.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
959
- let l;
960
+ static async speedLoseAt(e, t, a, o = "", n = 2, i = !0, s = !1, r = {}) {
961
+ let l;
962
+ if (t.velocity && s && (e.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), i) {
963
+ let u;
960
964
  try {
961
- i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
962
- const { weatherModels: g, marineModels: k } = await ct.autoPickMeteoModel(i), j = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
965
+ o = (o == null ? void 0 : o.toUpperCase()) === "CMEMS" ? "ECMWF" : o, o = (o == null ? void 0 : o.toUpperCase()) === "METEO2" ? "best_match" : o;
966
+ const { weatherModels: b, marineModels: S } = await ct.autoPickMeteoModel(o), C = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
963
967
  ...r,
964
968
  pastDays: 1,
965
969
  forecastDays: 1,
966
- weatherModels: g,
967
- marineModels: k
968
- }), [b] = ct.pickHourly(j, a);
969
- l = ct.toLegacy(b);
970
- } catch (g) {
971
- S.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: i }, g);
970
+ weatherModels: b,
971
+ marineModels: S
972
+ }), [p] = ct.pickHourly(C, a);
973
+ u = ct.toLegacy(p);
974
+ } catch (b) {
975
+ T.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, b);
972
976
  }
973
- const d = Y.currentFactor(e.bearing, l == null ? void 0 : l.current, n), y = Y.weatherFactor(e, l, d), w = Math.round((e.speed * 1.943844 + y + d) * 100) / 100;
974
- h = {
975
- meteo: { ...l },
977
+ const d = Y.currentFactor(e.bearing, u == null ? void 0 : u.current, n), y = Y.weatherFactor(e, u, d), k = Math.round((e.speed * 1.943844 + y + d) * 100) / 100;
978
+ l = {
979
+ meteo: { ...u },
976
980
  wxFactor: y,
977
981
  cFactor: d,
978
- speed: t.velocity && s ? t.velocity : w < 0 ? 1 : w,
982
+ speed: t.velocity && s ? t.velocity : k < 0 ? 1 : k,
979
983
  eta: a.utc().format(),
980
984
  etd: a.utc().format()
981
985
  };
982
986
  } else
983
- h = {
987
+ l = {
984
988
  wxFactor: 0,
985
989
  cFactor: 0,
986
990
  speed: t.velocity && s ? t.velocity : Math.round(e.speed * 1.943844 * 100) / 100,
987
991
  eta: a.utc().format(),
988
992
  etd: a.utc().format()
989
993
  };
990
- return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...h, ...t };
994
+ return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...l, ...t };
991
995
  }
992
996
  /**
993
997
  * 基于步长计算失速样本
@@ -1003,53 +1007,53 @@ class Y {
1003
1007
  * @param options
1004
1008
  * @private
1005
1009
  */
1006
- static async speedLoseInHoursStep(e, t, a, i, n, o, s = "", r = !0, h = !1, l = {}) {
1010
+ static async speedLoseInHoursStep(e, t, a, o, n, i, s = "", r = !0, l = !1, u = {}) {
1007
1011
  t.utc();
1008
- const d = t.clone().add(14, "days"), y = [], w = [], g = [];
1009
- let k = 0, j = 0, b, p;
1010
- for (let f = 0; f < o.length - 1; f++) {
1011
- let u = o[f];
1012
- u.distanceFromStart = Math.round((n + j) * 1e3) / 1e3;
1013
- const m = o[f + 1];
1014
- if (e.bearing = W.calculateBearing(u, m, !m.gcToPrevious), u.bearing = e.bearing, u.suspend && h) {
1015
- u.eta = u.eta || t.utc().format(), u.elapsed = u.elapsed ?? 0;
1016
- const C = u.suspend - u.elapsed;
1017
- if (i - k > C)
1018
- i = i - k - C, t.add(C, "hour"), u.elapsed = u.suspend;
1012
+ const d = t.clone().add(14, "days"), y = [], k = [], b = [];
1013
+ let S = 0, C = 0, p, v;
1014
+ for (let m = 0; m < i.length - 1; m++) {
1015
+ let c = i[m];
1016
+ c.distanceFromStart = Math.round((n + C) * 1e3) / 1e3;
1017
+ const f = i[m + 1];
1018
+ if (e.bearing = O.calculateBearing(c, f, !f.gcToPrevious), c.bearing = e.bearing, c.suspend && l) {
1019
+ c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
1020
+ const I = c.suspend - c.elapsed;
1021
+ if (o - S > I)
1022
+ o = o - S - I, t.add(I, "hour"), c.elapsed = c.suspend;
1019
1023
  else {
1020
- const F = i - k;
1021
- u.elapsed += F, t.add(F, "hour"), i = 0;
1024
+ const F = o - S;
1025
+ c.elapsed += F, t.add(F, "hour"), o = 0;
1022
1026
  }
1023
- if (S == null || S.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`, l.requestId, u), i === 0)
1024
- return u.distanceFromPrevious = j, { etd: t, from: p || u, to: u, next: o.filter((F) => F), wps: y, days: w, all: g };
1027
+ if (T == null || T.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`, u.requestId, c), o === 0)
1028
+ return c.distanceFromPrevious = C, { etd: t, from: v || c, to: c, next: i.filter((F) => F), wps: y, days: k, all: b };
1025
1029
  } else
1026
- u.suspend = 0;
1027
- r = t.isAfter(d) ? !1 : r, u = await Y.speedLoseAt(e, u, t, s, 0, r, h, l), g.push(u), p = p || u, u.important && y.push(u), t.isSameOrAfter(a) && (w.push(u), a.add(24, "hour"));
1028
- const c = W.calculateDistance(u, m, !m.gcToPrevious);
1029
- let I = Math.round(c / p.speed * 1e5) / 1e5;
1030
- if (k + I < i) {
1031
- if (k += I, t.add(I, "hour"), delete o[f], S == null || S.debug(
1032
- `[%s] go to %j from %j with ${c}nm, and cost ${I} hours`,
1033
- l.requestId,
1034
- { lat: m.lat, lng: m.lng },
1035
- { lat: p.lat, lng: p.lng, etd: p.etd }
1036
- ), j += c, o.filter((C) => C).length <= 1) {
1037
- b = m, b.eta = t.utc().format(), b.distanceFromPrevious = c, b.distanceFromStart = Math.round((n + j) * 1e4) / 1e4, y.push(b), g.push(b), delete o[f + 1];
1030
+ c.suspend = 0;
1031
+ r = t.isAfter(d) ? !1 : r, c = await Y.speedLoseAt(e, c, t, s, 0, r, l, u), b.push(c), v = v || c, c.important && y.push(c), t.isSameOrAfter(a) && (k.push(c), a.add(24, "hour"));
1032
+ const h = O.calculateDistance(c, f, !f.gcToPrevious);
1033
+ let g = Math.round(h / v.speed * 1e5) / 1e5;
1034
+ if (S + g < o) {
1035
+ if (S += g, t.add(g, "hour"), delete i[m], T == null || T.debug(
1036
+ `[%s] go to %j from %j with ${h}nm, and cost ${g} hours`,
1037
+ u.requestId,
1038
+ { lat: f.lat, lng: f.lng },
1039
+ { lat: v.lat, lng: v.lng, etd: v.etd }
1040
+ ), C += h, i.filter((I) => I).length <= 1) {
1041
+ p = f, p.eta = t.utc().format(), p.distanceFromPrevious = h, p.distanceFromStart = Math.round((n + C) * 1e4) / 1e4, y.push(p), b.push(p), delete i[m + 1];
1038
1042
  break;
1039
1043
  }
1040
1044
  } else {
1041
- I = i - k, t.add(I, "hour");
1042
- const C = z.roundPrecision(p.speed * I, 5);
1043
- b = W.calculateCoordinate(u, e.bearing, C, "nauticalmiles", !m.gcToPrevious), b.eta = t.utc().format(), o[f] = b, S == null || S.debug(
1044
- `[%s] go to %j from %j with ${C}nm, and cost ${I} hours`,
1045
- l.requestId,
1046
- { lat: b.lat, lng: b.lng },
1047
- { lat: u.lat, lng: u.lng, etd: u.etd }
1048
- ), j += C, b.distanceFromPrevious = Math.round(j * 1e4) / 1e4, b.distanceFromStart = Math.round((n + j) * 1e4) / 1e4;
1045
+ g = o - S, t.add(g, "hour");
1046
+ const I = z.roundPrecision(v.speed * g, 5);
1047
+ p = O.calculateCoordinate(c, e.bearing, I, "nauticalmiles", !f.gcToPrevious), p.eta = t.utc().format(), i[m] = p, T == null || T.debug(
1048
+ `[%s] go to %j from %j with ${I}nm, and cost ${g} hours`,
1049
+ u.requestId,
1050
+ { lat: p.lat, lng: p.lng },
1051
+ { lat: c.lat, lng: c.lng, etd: c.etd }
1052
+ ), C += I, p.distanceFromPrevious = Math.round(C * 1e4) / 1e4, p.distanceFromStart = Math.round((n + C) * 1e4) / 1e4;
1049
1053
  break;
1050
1054
  }
1051
1055
  }
1052
- return { etd: t, from: p, to: b, next: o.filter((f) => f), wps: y, days: w, all: g };
1056
+ return { etd: t, from: v, to: p, next: i.filter((m) => m), wps: y, days: k, all: b };
1053
1057
  }
1054
1058
  /**
1055
1059
  * 洋流影响因子
@@ -1058,10 +1062,10 @@ class Y {
1058
1062
  * @param role 1: 船东, 2: 租家, 0: 未知
1059
1063
  */
1060
1064
  static currentFactor(e, t, a = 0) {
1061
- const i = (e - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
1062
- if (Math.abs(i) === Math.PI / 2)
1065
+ const o = O.includedAngle(e, (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
1066
+ if (Math.abs(o) === Math.PI / 2)
1063
1067
  return 0;
1064
- let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(i);
1068
+ let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(o);
1065
1069
  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;
1066
1070
  }
1067
1071
  /**
@@ -1071,16 +1075,15 @@ class Y {
1071
1075
  * @param cFactor 洋流因子
1072
1076
  */
1073
1077
  static weatherFactor(e, t, a = 0) {
1074
- var w, g, k, j, b, p, f;
1075
- S == null || S.debug("calculate weather factor via: %j", { ...e, ...t });
1076
- const i = Y.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = Y.froudeNumber(e.speed - n, e.lbp), s = Y.amendFactor(i, o, e.loadCondition);
1077
- let r = Math.abs(e.bearing % 360 - (((w = t == null ? void 0 : t.wind) == null ? void 0 : w.degree) % 360 || 0));
1078
- r = r > 180 ? 360 - r : r;
1079
- const h = Y.directionFactor(r, (g = t == null ? void 0 : t.wind) == null ? void 0 : g.scale), l = Y.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.kts);
1080
- let d = h * s * l / 100 * (e.speed - n);
1081
- d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), S == null || S.debug("wind wx factor = %d", d), r = Math.abs(e.bearing % 360 - (((b = (j = t == null ? void 0 : t.wave) == null ? void 0 : j.sig) == null ? void 0 : b.degree) % 360 || 0)), r = r > 180 ? 360 - r : r;
1082
- const y = Y.waveHeightFactor(((f = (p = t == null ? void 0 : t.wave) == null ? void 0 : p.sig) == null ? void 0 : f.height) ?? 1, r);
1083
- return S == null || S.debug("wave wx factor = %d", y), d = Math.abs(d) > Math.abs(y) ? d : d * 0.3 + y * 0.7, S == null || S.debug("weather factor = %d", d), d = Math.abs(d) > 3 ? 3 * (Math.abs(d) / d) + Math.abs(d) / d * (Math.abs(d) - 2) * 0.1 : d, Math.round((d || 0) * 100) / 100;
1078
+ var k, b, S, C, p, v, m;
1079
+ T == null || T.debug("calculate weather factor via: %j", { ...e, ...t });
1080
+ const o = Y.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), n = z.roundPrecision(a * 1852 / 3600, 6), i = Y.froudeNumber(e.speed - n, e.lbp), s = Y.amendFactor(o, i, e.loadCondition);
1081
+ let r = O.includedAngle(e.bearing, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.degree);
1082
+ const l = Y.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), u = Y.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (S = t == null ? void 0 : t.wind) == null ? void 0 : S.kts);
1083
+ let d = l * s * u / 100 * (e.speed - n);
1084
+ d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), T == null || T.debug("wind wx factor = %d", d), r = O.includedAngle(e.bearing, (p = (C = t == null ? void 0 : t.wave) == null ? void 0 : C.sig) == null ? void 0 : p.degree);
1085
+ const y = Y.waveHeightFactor(((m = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : m.height) ?? 1, r);
1086
+ return T == null || T.debug("wave wx factor = %d", y), d = Math.abs(d) > Math.abs(y) ? d : d * 0.3 + y * 0.7, T == null || T.debug("weather factor = %d", d), d = Math.abs(d) > 3 ? 3 * (Math.abs(d) / d) + Math.abs(d) / d * (Math.abs(d) - 2) * 0.1 : d, Math.round((d || 0) * 100) / 100;
1084
1087
  }
1085
1088
  /**
1086
1089
  * 以12小时级别去掉重复的days
@@ -1088,7 +1091,7 @@ class Y {
1088
1091
  * @param interval 12 hours
1089
1092
  */
1090
1093
  static async reduceDays(e, t = 12 * 60 * 60) {
1091
- return e = e == null ? void 0 : e.reduce((a, i) => (a.some((n) => Math.floor(n.positionTime / t) === Math.floor(i.positionTime / t)) || a.push(i), a), []), e;
1094
+ 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;
1092
1095
  }
1093
1096
  /**
1094
1097
  * 以分钟级别去掉重复的wps
@@ -1096,7 +1099,7 @@ class Y {
1096
1099
  * @param interval 1 minute
1097
1100
  */
1098
1101
  static async reduceWPS(e, t = 60) {
1099
- return e = e == null ? void 0 : e.reduce((a, i) => (a.some((n) => Math.floor(v(n.etd).unix() / t) === Math.floor(v(i.etd).unix() / t)) || a.push(i), a), []), e;
1102
+ 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;
1100
1103
  }
1101
1104
  /**
1102
1105
  * 全程失速分析(走完航程)
@@ -1111,84 +1114,84 @@ class Y {
1111
1114
  * @param useRouteParam
1112
1115
  * @param options
1113
1116
  */
1114
- static async analyseInstant(e, t, a, i, n, o = "", s = 0, r = !0, h = !1, l = {}) {
1117
+ static async analyseInstant(e, t, a, o, n, i = "", s = 0, r = !0, l = !1, u = {}) {
1115
1118
  var _, G, X, Q, Z, $;
1116
- const d = v().valueOf();
1119
+ const d = w().valueOf();
1117
1120
  e.lng = z.convertToStdLng(e.lng);
1118
- const { route: y, waypoints: w } = n.points, g = W.calculateSubRoute(e, y);
1119
- if (((_ = g[0]) == null ? void 0 : _.length) <= 1)
1121
+ const { route: y, waypoints: k } = n.points, b = O.calculateSubRoute(e, y);
1122
+ if (((_ = b[0]) == null ? void 0 : _.length) <= 1)
1120
1123
  return;
1121
- const { v0: k, label: j } = e.sog ? {
1124
+ const { v0: S, label: C } = e.sog ? {
1122
1125
  v0: e.sog,
1123
1126
  label: e.label || "Other"
1124
1127
  /* Instruct */
1125
1128
  } : {
1126
- v0: i.speed,
1129
+ v0: o.speed,
1127
1130
  label: "CP"
1128
1131
  /* Cp */
1129
- }, b = Y.assembleProperties(a, i.loadCondition, k, 0), p = w.length ? W.calculateSubWaypoints(e, w) : [];
1130
- p.forEach((A) => A.important = !0);
1131
- const f = {
1132
+ }, p = Y.assembleProperties(a, o.loadCondition, S, 0), v = k.length ? O.calculateSubWaypoints(e, k) : [];
1133
+ v.forEach((A) => A.important = !0);
1134
+ const m = {
1132
1135
  from: { ...e },
1133
- route: g,
1134
- waypoints: p,
1135
- v0: k,
1136
- label: j
1137
- }, u = {
1136
+ route: b,
1137
+ waypoints: v,
1138
+ v0: S,
1139
+ label: C
1140
+ }, c = {
1138
1141
  hours: [],
1139
1142
  days: [],
1140
1143
  wps: [],
1141
1144
  all: []
1142
1145
  };
1143
- s || (W.calculateRouteDistance(g) / i.speed <= 72 ? s = 3 : s = 6);
1144
- let m = W.simplifyRouteToCoordinates(g, p, 0), c = 0, I = 0, C = 0, F = 0;
1145
- t = v(t).utc();
1146
+ s || (O.calculateRouteDistance(b) / o.speed <= 72 ? s = 3 : s = 6);
1147
+ let f = O.simplifyRouteToCoordinates(b, v, 0), h = 0, g = 0, I = 0, F = 0;
1148
+ t = w(t).utc();
1146
1149
  const P = t.clone();
1147
- for (; m.length > 0; ) {
1150
+ for (; f.length > 0; ) {
1148
1151
  const A = s - t.hour() % s, V = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, E = await Y.speedLoseInHoursStep(
1149
- b,
1152
+ p,
1150
1153
  t,
1151
1154
  P,
1152
1155
  V,
1153
- c,
1154
- m,
1155
- o,
1156
- r,
1157
1156
  h,
1158
- l
1157
+ f,
1158
+ i,
1159
+ r,
1160
+ l,
1161
+ u
1159
1162
  );
1160
- if (u.all.push(...E.all), (G = E.from) != null && G.speed && (u.hours.push(E.from), u.wps.push(...E.wps), u.days.push(...E.days)), m = E == null ? void 0 : E.next, !m.length) {
1161
- const L = await Y.speedLoseAt(b, E.to, v(E.to.eta), o, 0, r, h, l);
1162
- L.bearing = b.bearing, u.hours.push(L), u.all.push(L);
1163
+ if (c.all.push(...E.all), (G = E.from) != null && G.speed && (c.hours.push(E.from), c.wps.push(...E.wps), c.days.push(...E.days)), f = E == null ? void 0 : E.next, !f.length) {
1164
+ const L = await Y.speedLoseAt(p, E.to, w(E.to.eta), i, 0, r, l, u);
1165
+ L.bearing = p.bearing, c.hours.push(L), c.all.push(L);
1163
1166
  }
1164
- c += Math.round((((X = E == null ? void 0 : E.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1167
+ h += Math.round((((X = E == null ? void 0 : E.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1165
1168
  }
1166
- const D = u.hours;
1169
+ const D = c.hours;
1167
1170
  for (let A = 0; A < D.length - 1; A++) {
1168
- const V = v(D[A + 1].eta).diff(D[A].etd, "hour", !0) || 1;
1169
- I += (D[A].wxFactor || 0) * V, C += (D[A].cFactor || 0) * V, F += V;
1171
+ const V = w(D[A + 1].eta).diff(D[A].etd, "hour", !0) || 1;
1172
+ g += (D[A].wxFactor || 0) * V, I += (D[A].cFactor || 0) * V, F += V;
1170
1173
  }
1171
1174
  const H = D.reduce((A, V) => A + (V.suspend || 0), 0);
1172
- (Q = u.wps) == null || Q.forEach((A, V) => {
1173
- A.positionTime = v.utc(A.etd || A.eta).unix();
1174
- const E = u.wps[V - 1];
1175
+ (Q = c.wps) == null || Q.forEach((A, V) => {
1176
+ A.positionTime = w.utc(A.etd || A.eta).unix();
1177
+ const E = c.wps[V - 1];
1175
1178
  if (E) {
1176
- const L = A.distanceFromStart - E.distanceFromStart, q = v(A.eta || A.etd).diff(v(E.etd || E.eta), "h", !0);
1177
- A.avgSpd = Math.round(L / q * 100) / 100, E.bearing = W.calculateBearing(E, A);
1179
+ const L = A.distanceFromStart - E.distanceFromStart, q = w(A.eta || A.etd).diff(w(E.etd || E.eta), "h", !0);
1180
+ A.avgSpd = Math.round(L / q * 100) / 100, E.bearing = O.calculateBearing(E, A);
1178
1181
  }
1179
- }), u.wps = await Y.reduceWPS(u.wps), u.days = await Y.reduceDays(u.days), u.all = (Z = u.all) == null ? void 0 : Z.reduce((A, V) => (V.positionTime = v.utc(V.etd || V.eta).unix(), A.some((E) => Math.round(E.positionTime / 60) === Math.round(V.positionTime / 60)) || A.push(V), A), []), f.sample = u;
1180
- const T = u.hours.at(0), N = u.hours.at(-1);
1181
- f.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, f.etd = v(T.eta).utc().format(), f.eta = v(N.eta).utc().format(), f.wxFactor = Math.round(I / F * 1e3) / 1e3, f.cFactor = Math.round(C / F * 1e3) / 1e3, f.avgSpeed = Math.round(N.distanceFromStart / F * 1e3) / 1e3, f.totalHrs = Math.round(F * 1e3) / 1e3, f.suspend = Math.round(H * 1e3) / 1e3;
1182
- const O = z.roundPrecision(i.dgo / 24 * H, 3), { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: nt, eca: tt } = await this.calculateECA(f, i, l), et = z.roundPrecision(i.fo / 24 * (F - K), 3), ot = z.roundPrecision(i.dgo / 24 * F + O, 3);
1183
- f.extend = {
1182
+ }), c.wps = await Y.reduceWPS(c.wps), c.days = await Y.reduceDays(c.days), c.all = (Z = c.all) == null ? void 0 : Z.reduce((A, V) => (V.positionTime = w.utc(V.etd || V.eta).unix(), A.some((E) => Math.round(E.positionTime / 60) === Math.round(V.positionTime / 60)) || A.push(V), A), []), m.sample = c;
1183
+ const j = c.hours.at(0), N = c.hours.at(-1);
1184
+ m.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, m.etd = w(j.eta).utc().format(), m.eta = w(N.eta).utc().format(), m.wxFactor = Math.round(g / F * 1e3) / 1e3, m.cFactor = Math.round(I / F * 1e3) / 1e3, m.avgSpeed = Math.round(N.distanceFromStart / F * 1e3) / 1e3, m.totalHrs = Math.round(F * 1e3) / 1e3, m.suspend = Math.round(H * 1e3) / 1e3;
1185
+ const R = z.roundPrecision(o.dgo / 24 * H, 3), { distanceInECA: W, hoursInECA: K, totalDgoConsInECA: nt, eca: tt } = await this.calculateECA(m, o, u), et = z.roundPrecision(o.fo / 24 * (F - K), 3), ot = z.roundPrecision(o.dgo / 24 * F + R, 3);
1186
+ m.extend = {
1184
1187
  eca: tt,
1185
- distanceInECA: R,
1188
+ distanceInECA: W,
1186
1189
  hoursInECA: K,
1187
1190
  totalDgoConsInECA: nt,
1188
- totalDgoConsInSuspend: O
1189
- }, f.totalFoCons = et < 0 ? 0 : et, f.totalDgoCons = ot;
1190
- const st = v().valueOf() - d, rt = (($ = u == null ? void 0 : u.hours) == null ? void 0 : $.length) || 1;
1191
- return S == null || S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, st, rt, Math.round(st / rt * 1e3) / 1e3), f;
1191
+ totalDgoConsInSuspend: R
1192
+ }, m.totalFoCons = et < 0 ? 0 : et, m.totalDgoCons = ot;
1193
+ const st = w().valueOf() - d, rt = (($ = c == null ? void 0 : c.hours) == null ? void 0 : $.length) || 1;
1194
+ return T == null || T.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", u == null ? void 0 : u.requestId, st, rt, Math.round(st / rt * 1e3) / 1e3), m;
1192
1195
  }
1193
1196
  /**
1194
1197
  * 分段失速分析(最多走hours 小时)
@@ -1205,11 +1208,11 @@ class Y {
1205
1208
  * @param useRouteParam
1206
1209
  * @param options
1207
1210
  */
1208
- static async analyseInstantWithThreshed(e, t, a, i, n, o, s, r = "", h = 3, l = !0, d = !1, y = {}) {
1211
+ static async analyseInstantWithThreshed(e, t, a, o, n, i, s, r = "", l = 3, u = !0, d = !1, y = {}) {
1209
1212
  var X, Q, Z, $, A, V;
1210
- const w = v().valueOf();
1213
+ const k = w().valueOf();
1211
1214
  e.lng = z.convertToStdLng(e.lng);
1212
- const { v0: g, label: k } = e.sog ? {
1215
+ const { v0: b, label: S } = e.sog ? {
1213
1216
  v0: e.sog,
1214
1217
  label: e.label || "Other"
1215
1218
  /* Instruct */
@@ -1217,67 +1220,67 @@ class Y {
1217
1220
  v0: n.speed,
1218
1221
  label: "CP"
1219
1222
  /* Cp */
1220
- }, j = Y.assembleProperties(i, n.loadCondition, g, 0), b = W.calculateSubRoute(e, o);
1221
- if (((X = b[0]) == null ? void 0 : X.length) <= 1)
1223
+ }, C = Y.assembleProperties(o, n.loadCondition, b, 0), p = O.calculateSubRoute(e, i);
1224
+ if (((X = p[0]) == null ? void 0 : X.length) <= 1)
1222
1225
  return;
1223
- const p = s.length ? W.calculateSubWaypoints(e, s) : [];
1224
- p.forEach((E) => E.important = !0);
1225
- let f = W.simplifyRouteToCoordinates(b, p, 0), u = 0, m = 0, c = 0, I = 0;
1226
- const C = {
1226
+ const v = s.length ? O.calculateSubWaypoints(e, s) : [];
1227
+ v.forEach((E) => E.important = !0);
1228
+ let m = O.simplifyRouteToCoordinates(p, v, 0), c = 0, f = 0, h = 0, g = 0;
1229
+ const I = {
1227
1230
  hours: [],
1228
1231
  wps: [],
1229
1232
  days: [],
1230
1233
  all: []
1231
1234
  };
1232
- t = v(t).utc();
1235
+ t = w(t).utc();
1233
1236
  const F = t.clone();
1234
- for (; f.length > 0; ) {
1235
- const E = h - t.hour() % h;
1237
+ for (; m.length > 0; ) {
1238
+ const E = l - t.hour() % l;
1236
1239
  let L = Math.ceil(t.clone().add(E, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1237
1240
  L = t.clone().add(L, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : L;
1238
- const q = await Y.speedLoseInHoursStep(j, t, F, L, u, f, r, l, d, y);
1239
- if (C.all.push(...q.all), (Q = q.from) != null && Q.speed && (C.hours.push(q.from), q != null && q.wps && C.wps.push(...q.wps), C.days.push(...q.days)), f = q == null ? void 0 : q.next, f.length || C.hours.push(q == null ? void 0 : q.to), u += Math.round((((Z = q == null ? void 0 : q.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
1241
+ const q = await Y.speedLoseInHoursStep(C, t, F, L, c, m, r, u, d, y);
1242
+ if (I.all.push(...q.all), (Q = q.from) != null && Q.speed && (I.hours.push(q.from), q != null && q.wps && I.wps.push(...q.wps), I.days.push(...q.days)), m = q == null ? void 0 : q.next, m.length || I.hours.push(q == null ? void 0 : q.to), c += Math.round((((Z = q == null ? void 0 : q.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
1240
1243
  break;
1241
1244
  }
1242
- C.wps = await Y.reduceWPS(C.wps), C.days = await Y.reduceDays(C.days), C.all = ($ = C.all) == null ? void 0 : $.reduce((E, L) => (L.positionTime = v.utc(L.etd || L.eta).unix(), E.some((q) => Math.round(v(q.etd).unix() / 60) === Math.round(v(L.etd).unix() / 60)) || E.push(L), E), []), (A = C.wps) == null || A.forEach((E, L) => {
1243
- const q = C.wps[L - 1];
1245
+ I.wps = await Y.reduceWPS(I.wps), I.days = await Y.reduceDays(I.days), I.all = ($ = I.all) == null ? void 0 : $.reduce((E, L) => (L.positionTime = w.utc(L.etd || L.eta).unix(), E.some((q) => Math.round(w(q.etd).unix() / 60) === Math.round(w(L.etd).unix() / 60)) || E.push(L), E), []), (A = I.wps) == null || A.forEach((E, L) => {
1246
+ const q = I.wps[L - 1];
1244
1247
  if (q) {
1245
- const ut = E.distanceFromStart - q.distanceFromStart, ht = v(E.eta || E.etd).diff(v(q.etd || q.eta), "h", !0);
1246
- q.bearing = W.calculateBearing(q, E), E.avgSpd = Math.round(ut / ht * 100) / 100;
1248
+ const ut = E.distanceFromStart - q.distanceFromStart, lt = w(E.eta || E.etd).diff(w(q.etd || q.eta), "h", !0);
1249
+ q.bearing = O.calculateBearing(q, E), E.avgSpd = Math.round(ut / lt * 100) / 100;
1247
1250
  }
1248
1251
  });
1249
- const P = C.hours;
1252
+ const P = I.hours;
1250
1253
  for (let E = 0; E < P.length - 1; E++) {
1251
- const L = v(P[E + 1].eta).diff(P[E].etd, "hour", !0);
1252
- m += P[E].wxFactor * L, c += P[E].cFactor * L, I += L;
1254
+ const L = w(P[E + 1].eta).diff(P[E].etd, "hour", !0);
1255
+ f += P[E].wxFactor * L, h += P[E].cFactor * L, g += L;
1253
1256
  }
1254
- const D = P.reduce((E, L) => E + (L.suspend || 0), 0), H = C.hours.at(0), T = C.hours.at(-1), N = await W.calculateRangeRoute(H, T, b), O = await W.calculateRangeWaypoints(H, T, b, p), R = {
1255
- sample: C,
1256
- distance: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) * 1e4) / 1e4,
1257
+ const D = P.reduce((E, L) => E + (L.suspend || 0), 0), H = I.hours.at(0), j = I.hours.at(-1), N = await O.calculateRangeRoute(H, j, p), R = await O.calculateRangeWaypoints(H, j, p, v), W = {
1258
+ sample: I,
1259
+ distance: Math.round(((j == null ? void 0 : j.distanceFromStart) || 0) * 1e4) / 1e4,
1257
1260
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
1258
- etd: v(H.eta).utc().format(),
1259
- eta: v(T == null ? void 0 : T.eta).utc().format(),
1260
- wxFactor: Math.round(m / I * 1e3) / 1e3,
1261
- cFactor: Math.round(c / I * 1e3) / 1e3,
1262
- avgSpeed: Math.round(((T == null ? void 0 : T.distanceFromStart) || 0) / I * 1e3) / 1e3,
1263
- totalHrs: Math.round(I * 1e3) / 1e3,
1261
+ etd: w(H.eta).utc().format(),
1262
+ eta: w(j == null ? void 0 : j.eta).utc().format(),
1263
+ wxFactor: Math.round(f / g * 1e3) / 1e3,
1264
+ cFactor: Math.round(h / g * 1e3) / 1e3,
1265
+ avgSpeed: Math.round(((j == null ? void 0 : j.distanceFromStart) || 0) / g * 1e3) / 1e3,
1266
+ totalHrs: Math.round(g * 1e3) / 1e3,
1264
1267
  suspend: Math.round(D * 1e3) / 1e3,
1265
1268
  from: H,
1266
- to: T,
1269
+ to: j,
1267
1270
  route: N,
1268
- waypoints: O,
1269
- v0: g,
1270
- label: k
1271
- }, K = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: nt, hoursInECA: tt, totalDgoConsInECA: et, eca: ot } = await this.calculateECA(R, n, y), it = z.roundPrecision(n.fo / 24 * (I - tt), 3), st = z.roundPrecision(n.dgo / 24 * I + K, 3);
1272
- R.extend = {
1271
+ waypoints: R,
1272
+ v0: b,
1273
+ label: S
1274
+ }, K = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: nt, hoursInECA: tt, totalDgoConsInECA: et, eca: ot } = await this.calculateECA(W, n, y), it = z.roundPrecision(n.fo / 24 * (g - tt), 3), st = z.roundPrecision(n.dgo / 24 * g + K, 3);
1275
+ W.extend = {
1273
1276
  eca: ot,
1274
1277
  distanceInECA: nt,
1275
1278
  hoursInECA: tt,
1276
1279
  totalDgoConsInECA: et,
1277
1280
  totalDgoConsInSuspend: K
1278
- }, R.totalDgoCons = st, R.totalFoCons = it < 0 ? 0 : it;
1279
- const _ = v().valueOf() - w, G = ((V = C == null ? void 0 : C.hours) == null ? void 0 : V.length) || 1;
1280
- return S == null || S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", y == null ? void 0 : y.requestId, _, G, Math.round(_ / G * 1e3) / 1e3), R;
1281
+ }, W.totalDgoCons = st, W.totalFoCons = it < 0 ? 0 : it;
1282
+ const _ = w().valueOf() - k, G = ((V = I == null ? void 0 : I.hours) == null ? void 0 : V.length) || 1;
1283
+ return T == null || T.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", y == null ? void 0 : y.requestId, _, G, Math.round(_ / G * 1e3) / 1e3), W;
1281
1284
  }
1282
1285
  /**
1283
1286
  * 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
@@ -1294,59 +1297,59 @@ class Y {
1294
1297
  * @param lane 基础航线(重要转向点)
1295
1298
  * @param options
1296
1299
  */
1297
- static async analyseCost(e, t, a, i, n = {}) {
1298
- var b, p;
1299
- const o = v().valueOf(), s = [];
1300
+ static async analyseCost(e, t, a, o, n = {}) {
1301
+ var p, v;
1302
+ const i = w().valueOf(), s = [];
1300
1303
  e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
1301
- const r = W.calculateRouteDistance(i.route);
1302
- let h = 0;
1303
- a.forEach((f) => {
1304
- const u = Math.ceil(r / f.speed / 24);
1305
- h = h < u ? u : h;
1306
- }), h = h * 1.3;
1307
- const l = v.utc(e.etd).add(h ?? 14, "day");
1304
+ const r = O.calculateRouteDistance(o.route);
1305
+ let l = 0;
1306
+ a.forEach((m) => {
1307
+ const c = Math.ceil(r / m.speed / 24);
1308
+ l = l < c ? c : l;
1309
+ }), l = l * 1.3;
1310
+ const u = w.utc(e.etd).add(l ?? 14, "day");
1308
1311
  let d = 1;
1309
- for (const f of a) {
1310
- const u = JSON.parse(JSON.stringify(i.route)), m = JSON.parse(JSON.stringify(i.waypoints)), c = await Y.analyseInstantWithThreshed(
1312
+ for (const m of a) {
1313
+ const c = JSON.parse(JSON.stringify(o.route)), f = JSON.parse(JSON.stringify(o.waypoints)), h = await Y.analyseInstantWithThreshed(
1311
1314
  { lat: e.lat, lng: e.lng },
1312
1315
  e.etd,
1313
- l,
1314
- t,
1315
- f,
1316
1316
  u,
1317
+ t,
1317
1318
  m,
1319
+ c,
1320
+ f,
1318
1321
  e.meteoVendor,
1319
1322
  e.speedStep,
1320
1323
  e.useMeteo,
1321
1324
  e.useRouteParam,
1322
1325
  n
1323
1326
  );
1324
- c && (await Y.calculateCost(c, f, e, n), s.push(c), S == null || S.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, d, e.etd, l.format(), {
1325
- cost: c.cost.total,
1326
- hire: c.cost.hire,
1327
- bunker: c.cost.bunker,
1328
- distance: c.distance,
1329
- hours: c.totalHrs,
1330
- cp: `${f.speed}/${f.fo}/${f.dgo}`
1327
+ h && (await Y.calculateCost(h, m, e, n), s.push(h), T == null || T.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, d, e.etd, u.format(), {
1328
+ cost: h.cost.total,
1329
+ hire: h.cost.hire,
1330
+ bunker: h.cost.bunker,
1331
+ distance: h.distance,
1332
+ hours: h.totalHrs,
1333
+ cp: `${m.speed}/${m.fo}/${m.dgo}`
1331
1334
  })), d++;
1332
1335
  }
1333
- s.sort((f, u) => f.cost.total - u.cost.total);
1334
- const y = s.at(0), w = s.at(1), g = [];
1335
- if (g.push({ combined: !1, speeds: [y], cost: (b = y.cost) == null ? void 0 : b.total }), w) {
1336
- const f = y.cost.cp, u = w.cost.cp, m = v(y.eta), c = v(y.etd), I = m.diff(c, "days", !0);
1337
- let C = Math.ceil(I / 2);
1338
- C = C > 7 ? 7 : C < e.alterStep ? e.alterStep : C;
1339
- let F = 2, P = { combined: !1, speeds: [w], cost: (p = w.cost) == null ? void 0 : p.total }, D;
1340
- for (; C >= e.alterStep; ) {
1341
- const H = await Y.combinedAnalyse(e, t, l, [f, u], i, C, { ...n, level: F });
1342
- if (P.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = P, P = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), C <= e.alterStep)
1336
+ s.sort((m, c) => m.cost.total - c.cost.total);
1337
+ const y = s.at(0), k = s.at(1), b = [];
1338
+ if (b.push({ combined: !1, speeds: [y], cost: (p = y.cost) == null ? void 0 : p.total }), k) {
1339
+ const m = y.cost.cp, c = k.cost.cp, f = w(y.eta), h = w(y.etd), g = f.diff(h, "days", !0);
1340
+ let I = Math.ceil(g / 2);
1341
+ I = I > 7 ? 7 : I < e.alterStep ? e.alterStep : I;
1342
+ let F = 2, P = { combined: !1, speeds: [k], cost: (v = k.cost) == null ? void 0 : v.total }, D;
1343
+ for (; I >= e.alterStep; ) {
1344
+ const H = await Y.combinedAnalyse(e, t, u, [m, c], o, I, { ...n, level: F });
1345
+ if (P.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = P, P = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), I <= e.alterStep)
1343
1346
  break;
1344
- C = Math.ceil(C / 2), F += 1;
1347
+ I = Math.ceil(I / 2), F += 1;
1345
1348
  }
1346
- g.push(P), D && g.push(D);
1349
+ b.push(P), D && b.push(D);
1347
1350
  }
1348
- const j = v().valueOf() - o;
1349
- return S == null || S.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, j), g.sort((f, u) => f.cost - u.cost);
1351
+ const C = w().valueOf() - i;
1352
+ return T == null || T.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, C), b.sort((m, c) => m.cost - c.cost);
1350
1353
  }
1351
1354
  /**
1352
1355
  * 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
@@ -1358,24 +1361,24 @@ class Y {
1358
1361
  * @param step 步长,7,4,2,1
1359
1362
  * @param options
1360
1363
  */
1361
- static async combinedAnalyse(e, t, a, i, n, o, s = {}) {
1362
- s.counter = 1, S == null || S.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, o);
1363
- const r = await Y.alternateAnalyse(e, t, a, i, 0, n, o, s), h = r.reduce((u, m) => u + m.cost.total, 0), l = r.reduce((u, m) => u + m.cost.hire, 0), d = r.reduce((u, m) => u + m.cost.bunker, 0), y = r.reduce((u, m) => u + m.distance, 0), w = r.reduce((u, m) => u + m.totalHrs, 0);
1364
- S == null || S.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1365
- cost: h,
1366
- hire: l,
1364
+ static async combinedAnalyse(e, t, a, o, n, i, s = {}) {
1365
+ s.counter = 1, T == null || T.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, i);
1366
+ const r = await Y.alternateAnalyse(e, t, a, o, 0, n, i, s), l = r.reduce((c, f) => c + f.cost.total, 0), u = r.reduce((c, f) => c + f.cost.hire, 0), d = r.reduce((c, f) => c + f.cost.bunker, 0), y = r.reduce((c, f) => c + f.distance, 0), k = r.reduce((c, f) => c + f.totalHrs, 0);
1367
+ T == null || T.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1368
+ cost: l,
1369
+ hire: u,
1367
1370
  bunker: d,
1368
1371
  distance: y,
1369
- hours: w
1372
+ hours: k
1370
1373
  });
1371
- const g = await Y.alternateAnalyse(e, t, a, i, 1, n, o, s), k = g.reduce((u, m) => u + m.cost.total, 0), j = g.reduce((u, m) => u + m.cost.hire, 0), b = g.reduce((u, m) => u + m.cost.bunker, 0), p = g.reduce((u, m) => u + m.distance, 0), f = g.reduce((u, m) => u + m.totalHrs, 0);
1372
- return S == null || S.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
1373
- cost: k,
1374
- hire: j,
1375
- bunker: b,
1376
- distance: p,
1377
- hours: f
1378
- }), h < k ? { combined: !0, cost: Math.round(h * 1e3) / 1e3, speeds: r, step: o } : { combined: !0, cost: Math.round(k * 1e3) / 1e3, speeds: g, step: o };
1374
+ const b = await Y.alternateAnalyse(e, t, a, o, 1, n, i, s), S = b.reduce((c, f) => c + f.cost.total, 0), C = b.reduce((c, f) => c + f.cost.hire, 0), p = b.reduce((c, f) => c + f.cost.bunker, 0), v = b.reduce((c, f) => c + f.distance, 0), m = b.reduce((c, f) => c + f.totalHrs, 0);
1375
+ return T == null || T.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
1376
+ cost: S,
1377
+ hire: C,
1378
+ bunker: p,
1379
+ distance: v,
1380
+ hours: m
1381
+ }), l < S ? { combined: !0, cost: Math.round(l * 1e3) / 1e3, speeds: r, step: i } : { combined: !0, cost: Math.round(S * 1e3) / 1e3, speeds: b, step: i };
1379
1382
  }
1380
1383
  /**
1381
1384
  * 基于cp索引,交替计算指定步长下的成本
@@ -1388,44 +1391,44 @@ class Y {
1388
1391
  * @param step 步长,7,4,2,1
1389
1392
  * @param options
1390
1393
  */
1391
- static async alternateAnalyse(e, t, a, i, n, o, s, r = {}) {
1392
- var y, w;
1393
- let h = v.utc(e.etd);
1394
- const l = { lat: e.lat, lng: e.lng }, d = [];
1395
- for (; h.isBefore(a); ) {
1396
- const g = h.clone().utc().add(s, "day"), k = JSON.parse(JSON.stringify(o.route)), j = JSON.parse(JSON.stringify(o.waypoints)), b = i[n], p = await Y.analyseInstantWithThreshed(
1397
- l,
1398
- h.utc().format(),
1399
- g,
1400
- t,
1394
+ static async alternateAnalyse(e, t, a, o, n, i, s, r = {}) {
1395
+ var y, k;
1396
+ let l = w.utc(e.etd);
1397
+ const u = { lat: e.lat, lng: e.lng }, d = [];
1398
+ for (; l.isBefore(a); ) {
1399
+ const b = l.clone().utc().add(s, "day"), S = JSON.parse(JSON.stringify(i.route)), C = JSON.parse(JSON.stringify(i.waypoints)), p = o[n], v = await Y.analyseInstantWithThreshed(
1400
+ u,
1401
+ l.utc().format(),
1401
1402
  b,
1402
- k,
1403
- j,
1403
+ t,
1404
+ p,
1405
+ S,
1406
+ C,
1404
1407
  e.meteoVendor,
1405
1408
  e.speedStep,
1406
1409
  e.useMeteo,
1407
1410
  e.useRouteParam,
1408
1411
  r
1409
1412
  );
1410
- p && (await Y.calculateCost(p, b, e, r), S == null || S.info(
1413
+ v && (await Y.calculateCost(v, p, e, r), T == null || T.info(
1411
1414
  "[%s][L%d-%d] analyse from %s to %s cost: %j",
1412
1415
  r.requestId,
1413
1416
  r.level,
1414
1417
  r.counter,
1415
- h.utc().format(),
1416
- g.utc().format(),
1418
+ l.utc().format(),
1419
+ b.utc().format(),
1417
1420
  {
1418
- cost: p.cost.total,
1419
- hire: p.cost.hire,
1420
- bunker: p.cost.bunker,
1421
- distance: p.distance,
1422
- hours: p.totalHrs,
1423
- cp: `${b.speed}/${b.fo}/${b.dgo}`
1421
+ cost: v.cost.total,
1422
+ hire: v.cost.hire,
1423
+ bunker: v.cost.bunker,
1424
+ distance: v.distance,
1425
+ hours: v.totalHrs,
1426
+ cp: `${p.speed}/${p.fo}/${p.dgo}`
1424
1427
  }
1425
1428
  )), r.counter = r.counter + 1;
1426
- const f = (w = (y = p == null ? void 0 : p.sample) == null ? void 0 : y.hours) == null ? void 0 : w.at(-1);
1427
- if (f)
1428
- l.lat = f.lat, l.lng = f.lng, h = v(f.eta), d.push(p), n = n ? 0 : 1;
1429
+ const m = (k = (y = v == null ? void 0 : v.sample) == null ? void 0 : y.hours) == null ? void 0 : k.at(-1);
1430
+ if (m)
1431
+ u.lat = m.lat, u.lng = m.lng, l = w(m.eta), d.push(v), n = n ? 0 : 1;
1429
1432
  else
1430
1433
  break;
1431
1434
  }
@@ -1438,15 +1441,15 @@ class Y {
1438
1441
  * @param props
1439
1442
  * @param options
1440
1443
  */
1441
- static async calculateCost(e, t, a, i = {}) {
1444
+ static async calculateCost(e, t, a, o = {}) {
1442
1445
  var n;
1443
1446
  if (e) {
1444
- const o = (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 - o) * 1e3) / 1e3 + s, h = Math.round(e.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, l = Math.round((e.totalDgoCons + (((n = e.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
1447
+ 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;
1445
1448
  e.cost = {
1446
- total: Math.round((r + h + l) * 1e3) / 1e3,
1449
+ total: Math.round((r + l + u) * 1e3) / 1e3,
1447
1450
  hire: Math.round(r * 1e3) / 1e3,
1448
1451
  suspendHire: s,
1449
- bunker: Math.round((h + l) * 1e3) / 1e3,
1452
+ bunker: Math.round((l + u) * 1e3) / 1e3,
1450
1453
  cp: t
1451
1454
  };
1452
1455
  }
@@ -1457,22 +1460,22 @@ class Y {
1457
1460
  *
1458
1461
  */
1459
1462
  static async calculateECA(e, t, a = {}) {
1460
- var r, h, l, d;
1461
- const i = await W.intersectInECA((e == null ? void 0 : e.route) || []);
1462
- let n = 0, o = 0, s = 0;
1463
- (h = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || h.forEach((y) => {
1464
- y.positionTime = v.utc(y.etd || y.eta).unix();
1463
+ var r, l, u, d;
1464
+ const o = await O.intersectInECA((e == null ? void 0 : e.route) || []);
1465
+ let n = 0, i = 0, s = 0;
1466
+ (l = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || l.forEach((y) => {
1467
+ y.positionTime = w.utc(y.etd || y.eta).unix();
1465
1468
  });
1466
- for (const y of i) {
1469
+ for (const y of o) {
1467
1470
  n += y.distance;
1468
- const w = await W.deadReckoningTime((l = y.waypoints) == null ? void 0 : l.at(0), e.sample.all || e.sample.wps), g = await W.deadReckoningTime((d = y.waypoints) == null ? void 0 : d.at(-1), e.sample.all || e.sample.wps);
1469
- y.in = w, y.out = g, y.totalHrs = z.roundPrecision((g.positionTime - w.positionTime) / 3600, 3), y.totalDgoCons = z.roundPrecision(t.fo / 24 * y.totalHrs, 3), o += y.totalHrs, s += y.totalDgoCons;
1471
+ const k = await O.deadReckoningTime((u = y.waypoints) == null ? void 0 : u.at(0), e.sample.all || e.sample.wps), b = await O.deadReckoningTime((d = y.waypoints) == null ? void 0 : d.at(-1), e.sample.all || e.sample.wps);
1472
+ y.in = k, y.out = b, y.totalHrs = z.roundPrecision((b.positionTime - k.positionTime) / 3600, 3), y.totalDgoCons = z.roundPrecision(t.fo / 24 * y.totalHrs, 3), i += y.totalHrs, s += y.totalDgoCons;
1470
1473
  }
1471
- return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3), s = z.roundPrecision(s, 3), {
1474
+ return n = z.roundPrecision(n, 3), i = z.roundPrecision(i, 3), s = z.roundPrecision(s, 3), {
1472
1475
  distanceInECA: n,
1473
- hoursInECA: o,
1476
+ hoursInECA: i,
1474
1477
  totalDgoConsInECA: s,
1475
- eca: i
1478
+ eca: o
1476
1479
  };
1477
1480
  }
1478
1481
  /**
@@ -1481,53 +1484,53 @@ class Y {
1481
1484
  * @param options
1482
1485
  */
1483
1486
  static async mergeSpeeds(e, t = {}) {
1484
- var f, u;
1487
+ var m, c;
1485
1488
  const a = {
1486
1489
  hours: [],
1487
1490
  wps: [],
1488
1491
  days: []
1489
- }, i = e.reduce((m, c) => m + c.distance, 0), n = e.reduce((m, c) => {
1490
- var I;
1491
- return m + (((I = c.extend) == null ? void 0 : I.distanceInECA) || 0);
1492
- }, 0), o = e.reduce((m, c) => m + c.totalHrs, 0), s = e.reduce((m, c) => {
1493
- var I;
1494
- return m + (((I = c.extend) == null ? void 0 : I.hoursInECA) || 0);
1495
- }, 0), r = e.reduce((m, c) => {
1496
- var I;
1497
- return m + (((I = c.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
1498
- }, 0), h = e.reduce((m, c) => m + c.wxFactor * c.totalHrs / o, 0), l = e.reduce((m, c) => m + c.cFactor * c.totalHrs / o, 0), d = e.reduce((m, c) => m + c.totalFoCons, 0), y = e.reduce((m, c) => m + c.totalDgoCons, 0), w = e.reduce((m, c) => m + c.cost.total, 0), g = e.reduce((m, c) => m + c.cost.hire, 0), k = e.reduce((m, c) => m + c.cost.bunker, 0), j = [], b = [];
1499
- let p;
1500
- for (const m of e) {
1501
- b.push(...((f = m.extend) == null ? void 0 : f.eca) || []);
1502
- const c = m.sample.hours, I = m.sample.wps, C = m.sample.days, F = c.at(0);
1503
- p && (F.distanceFromPrevious = p.distanceFromPrevious, F.distanceFromStart = p.distanceFromStart, c.forEach((T, N) => {
1504
- N && (T.distanceFromStart = T.distanceFromStart + p.distanceFromStart);
1505
- }), I.at(0).distanceFromPrevious = p.distanceFromPrevious, I.at(0).distanceFromStart = p.distanceFromStart, I.forEach((T, N) => {
1506
- N && (T.distanceFromStart = T.distanceFromStart + p.distanceFromStart);
1507
- }), C.at(0).distanceFromPrevious = p.distanceFromPrevious, C.at(0).distanceFromStart = p.distanceFromStart, C.forEach((T, N) => {
1508
- N && (T.distanceFromStart = T.distanceFromStart + p.distanceFromStart);
1509
- })), F.cp = m.cost.cp;
1510
- const P = [m.etd, m.eta], D = j.findIndex((T) => T.id === F.cp.id);
1511
- D === -1 ? (F.cp.segment = [P], j.push(F.cp)) : j[D].segment.push(P), c.forEach((T) => {
1512
- var O;
1513
- ((O = a.hours) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.hours.push(T);
1514
- }), I.forEach((T) => {
1515
- var O;
1516
- ((O = a.wps) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.wps.push(T);
1517
- }), C.forEach((T) => {
1518
- var O;
1519
- ((O = a == null ? void 0 : a.days) == null ? void 0 : O.findIndex((R) => R.eta === T.eta)) === -1 && a.days.push(T);
1492
+ }, o = e.reduce((f, h) => f + h.distance, 0), n = e.reduce((f, h) => {
1493
+ var g;
1494
+ return f + (((g = h.extend) == null ? void 0 : g.distanceInECA) || 0);
1495
+ }, 0), i = e.reduce((f, h) => f + h.totalHrs, 0), s = e.reduce((f, h) => {
1496
+ var g;
1497
+ return f + (((g = h.extend) == null ? void 0 : g.hoursInECA) || 0);
1498
+ }, 0), r = e.reduce((f, h) => {
1499
+ var g;
1500
+ return f + (((g = h.extend) == null ? void 0 : g.totalDgoConsInECA) || 0);
1501
+ }, 0), l = e.reduce((f, h) => f + h.wxFactor * h.totalHrs / i, 0), u = e.reduce((f, h) => f + h.cFactor * h.totalHrs / i, 0), d = e.reduce((f, h) => f + h.totalFoCons, 0), y = e.reduce((f, h) => f + h.totalDgoCons, 0), k = e.reduce((f, h) => f + h.cost.total, 0), b = e.reduce((f, h) => f + h.cost.hire, 0), S = e.reduce((f, h) => f + h.cost.bunker, 0), C = [], p = [];
1502
+ let v;
1503
+ for (const f of e) {
1504
+ p.push(...((m = f.extend) == null ? void 0 : m.eca) || []);
1505
+ const h = f.sample.hours, g = f.sample.wps, I = f.sample.days, F = h.at(0);
1506
+ v && (F.distanceFromPrevious = v.distanceFromPrevious, F.distanceFromStart = v.distanceFromStart, h.forEach((j, N) => {
1507
+ N && (j.distanceFromStart = j.distanceFromStart + v.distanceFromStart);
1508
+ }), g.at(0).distanceFromPrevious = v.distanceFromPrevious, g.at(0).distanceFromStart = v.distanceFromStart, g.forEach((j, N) => {
1509
+ N && (j.distanceFromStart = j.distanceFromStart + v.distanceFromStart);
1510
+ }), I.at(0).distanceFromPrevious = v.distanceFromPrevious, I.at(0).distanceFromStart = v.distanceFromStart, I.forEach((j, N) => {
1511
+ N && (j.distanceFromStart = j.distanceFromStart + v.distanceFromStart);
1512
+ })), F.cp = f.cost.cp;
1513
+ const P = [f.etd, f.eta], D = C.findIndex((j) => j.id === F.cp.id);
1514
+ D === -1 ? (F.cp.segment = [P], C.push(F.cp)) : C[D].segment.push(P), h.forEach((j) => {
1515
+ var R;
1516
+ ((R = a.hours) == null ? void 0 : R.findIndex((W) => W.eta === j.eta)) === -1 && a.hours.push(j);
1517
+ }), g.forEach((j) => {
1518
+ var R;
1519
+ ((R = a.wps) == null ? void 0 : R.findIndex((W) => W.eta === j.eta)) === -1 && a.wps.push(j);
1520
+ }), I.forEach((j) => {
1521
+ var R;
1522
+ ((R = a == null ? void 0 : a.days) == null ? void 0 : R.findIndex((W) => W.eta === j.eta)) === -1 && a.days.push(j);
1520
1523
  });
1521
- const H = (u = a.wps) == null ? void 0 : u.findIndex((T) => T.eta === F.eta);
1522
- H === -1 ? a.wps.push(F) : a.wps[H] = F, p = c.at(-1);
1524
+ const H = (c = a.wps) == null ? void 0 : c.findIndex((j) => j.eta === F.eta);
1525
+ H === -1 ? a.wps.push(F) : a.wps[H] = F, v = h.at(-1);
1523
1526
  }
1524
- return a.wps.sort((m, c) => v(m.etd).unix() - v(c.etd).unix()), a.wps.forEach((m, c) => {
1525
- const I = a.wps[c - 1];
1526
- if (I) {
1527
- const C = m.distanceFromStart - (I.distanceFromStart || 0), F = v(m.eta || m.etd).diff(v(I.etd || I.eta), "hour", !0), P = Math.round(C / F * 100) / 100;
1528
- m.avgSpd = P;
1529
- const D = W.calculateBearing(I, m);
1530
- I.bearing = D;
1527
+ return a.wps.sort((f, h) => w(f.etd).unix() - w(h.etd).unix()), a.wps.forEach((f, h) => {
1528
+ const g = a.wps[h - 1];
1529
+ if (g) {
1530
+ const I = f.distanceFromStart - (g.distanceFromStart || 0), F = w(f.eta || f.etd).diff(w(g.etd || g.eta), "hour", !0), P = Math.round(I / F * 100) / 100;
1531
+ f.avgSpd = P;
1532
+ const D = O.calculateBearing(g, f);
1533
+ g.bearing = D;
1531
1534
  }
1532
1535
  }), {
1533
1536
  sample: a,
@@ -1537,21 +1540,21 @@ class Y {
1537
1540
  to: e.at(-1).to,
1538
1541
  v0: e.at(0).v0,
1539
1542
  label: "Combined",
1540
- distance: Math.round(i * 1e3) / 1e3,
1541
- totalHrs: Math.round(o * 1e3) / 1e3,
1542
- avgSpeed: Math.round(i / o * 1e3) / 1e3,
1543
- wxFactor: Math.round(h * 1e3) / 1e3,
1544
- cFactor: Math.round(l * 1e3) / 1e3,
1543
+ distance: Math.round(o * 1e3) / 1e3,
1544
+ totalHrs: Math.round(i * 1e3) / 1e3,
1545
+ avgSpeed: Math.round(o / i * 1e3) / 1e3,
1546
+ wxFactor: Math.round(l * 1e3) / 1e3,
1547
+ cFactor: Math.round(u * 1e3) / 1e3,
1545
1548
  totalFoCons: Math.round(d * 1e3) / 1e3,
1546
1549
  totalDgoCons: Math.round(y * 1e3) / 1e3,
1547
1550
  cost: {
1548
- total: Math.round(w * 1e3) / 1e3,
1549
- hire: Math.round(g * 1e3) / 1e3,
1550
- bunker: Math.round(k * 1e3) / 1e3
1551
+ total: Math.round(k * 1e3) / 1e3,
1552
+ hire: Math.round(b * 1e3) / 1e3,
1553
+ bunker: Math.round(S * 1e3) / 1e3
1551
1554
  },
1552
1555
  extend: {
1553
- cps: j,
1554
- eca: b,
1556
+ cps: C,
1557
+ eca: p,
1555
1558
  distanceInECA: Math.round(n * 1e3) / 1e3,
1556
1559
  hoursInECA: Math.round(s * 1e3) / 1e3,
1557
1560
  totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
@@ -1567,7 +1570,7 @@ export {
1567
1570
  Ft as HifleetImpl,
1568
1571
  pt as LoadCondition,
1569
1572
  xt as MyShipImpl,
1570
- Tt as MyVesselImpl,
1573
+ jt as MyVesselImpl,
1571
1574
  Nt as ShipxyImpl,
1572
1575
  Y as SpeedHelper,
1573
1576
  vt as SpeedLabel,