@idm-plugin/vessel 3.5.0 → 3.5.1

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
@@ -7,9 +7,9 @@ import w from "moment";
7
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
- let M;
10
+ let g;
11
11
  try {
12
- M = dt.getLogger("vessel");
12
+ g = dt.getLogger("vessel");
13
13
  } catch {
14
14
  } finally {
15
15
  }
@@ -70,7 +70,7 @@ class jt extends at {
70
70
  grant_type: "client_credentials"
71
71
  }
72
72
  }, n = await B.post(a, o).json();
73
- M == null || M.info("[%s] fetch access token from: %s - %j", t.requestId, a, n), n.error || (this.token = {
73
+ g == null || g.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,
@@ -100,9 +100,9 @@ class jt 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, o, n);
103
+ g == null || g.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, o, n);
104
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) => ({
105
+ return i.status !== 200 ? (g == null || g.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), []) : (i.data || []).map((u) => ({
106
106
  mmsi: u.mmsi,
107
107
  name: u.nameEn,
108
108
  nameCn: u.nameCn,
@@ -128,10 +128,10 @@ class jt extends at {
128
128
  },
129
129
  searchParams: i
130
130
  };
131
- M == null || M.info("[%s] fetch vessel from: %s - %j", a.requestId, n, s);
131
+ g == null || g.info("[%s] fetch vessel from: %s - %j", a.requestId, n, s);
132
132
  const r = await B.get(n, s).json();
133
133
  if (r.status !== 200)
134
- return M == null || M.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
134
+ return g == null || g.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
135
135
  {
136
136
  const d = r.data;
137
137
  if (d)
@@ -172,9 +172,9 @@ class jt 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, o, n);
175
+ g == null || g.info("[%s] fetch vessel archive from: %s - %j", a.requestId, o, n);
176
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;
177
+ return i.status !== 200 ? (g == null || g.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), {}) : i.data;
178
178
  }
179
179
  async realTimePosition(t, a = {}) {
180
180
  var r, l;
@@ -185,10 +185,10 @@ class jt extends at {
185
185
  },
186
186
  searchParams: { mmsi: t }
187
187
  };
188
- M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
188
+ g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
189
189
  const i = await B.get(o, n).json();
190
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;
191
+ return g == null || g.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), i;
192
192
  const s = i.data;
193
193
  for (const u in s)
194
194
  !isNaN(s[u]) && Number(s[u]) !== 1 / 0 && (s[u] = Number(s[u]));
@@ -263,12 +263,12 @@ class jt extends at {
263
263
  },
264
264
  json: u
265
265
  };
266
- M == null || M.info("[%s] fetch route from: %s - %j", s.requestId, l, d);
266
+ g == null || g.info("[%s] fetch route from: %s - %j", s.requestId, l, d);
267
267
  const y = await B.post(l, d).json();
268
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 }), {};
269
+ return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message: y.message, status: y.status, code: y.code }), {};
270
270
  {
271
- const C = {
271
+ const I = {
272
272
  status: "Success",
273
273
  nodes: [],
274
274
  seas: [],
@@ -277,65 +277,65 @@ class jt extends at {
277
277
  route: [],
278
278
  distance: 0,
279
279
  memo: ""
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,
280
+ }, { nodes: p, seas: v, tracks: m, specialRegions: c, ecaLength: h } = y.data;
281
+ I.nodes = p == null ? void 0 : p.map((M) => ({
282
+ code: M.nodeCode,
283
+ nameEn: M.nameEn,
284
+ nameCn: M.nameCn,
285
285
  // 中心
286
286
  center: {
287
- lat: Math.round(g.lat * 1e6) / 1e6,
288
- lng: Math.round(g.lon * 1e6) / 1e6
287
+ lat: Math.round(M.lat * 1e6) / 1e6,
288
+ lng: Math.round(M.lon * 1e6) / 1e6
289
289
  },
290
290
  // 起点
291
291
  start: {
292
- lat: Math.round(g.startLat * 1e6) / 1e6,
293
- lng: Math.round(g.startLon * 1e6) / 1e6
292
+ lat: Math.round(M.startLat * 1e6) / 1e6,
293
+ lng: Math.round(M.startLon * 1e6) / 1e6
294
294
  },
295
295
  // 终点
296
296
  end: {
297
- lat: Math.round(g.endLat * 1e6) / 1e6,
298
- lng: Math.round(g.endLat * 1e6) / 1e6
297
+ lat: Math.round(M.endLat * 1e6) / 1e6,
298
+ lng: Math.round(M.endLat * 1e6) / 1e6
299
299
  },
300
300
  // 是否为不可避开关键节点
301
- isKey: g.isKeyNode,
301
+ isKey: M.isKeyNode,
302
302
  // 重要枢纽节点
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,
303
+ isHub: M.isHubNode
304
+ })), I.seas = v == null ? void 0 : v.map((M) => ({
305
+ code: M.mrgidSea,
306
+ nameEn: M.nameEn,
307
+ nameCn: M.nameCn,
308
308
  center: {
309
- lat: Math.round(g.centerLat * 1e6) / 1e6,
310
- lng: Math.round(g.centerLon * 1e6) / 1e6
309
+ lat: Math.round(M.centerLat * 1e6) / 1e6,
310
+ lng: Math.round(M.centerLon * 1e6) / 1e6
311
311
  },
312
312
  min: {
313
- lat: Math.round(g.minLat * 1e6) / 1e6,
314
- lng: Math.round(g.minLon * 1e6) / 1e6
313
+ lat: Math.round(M.minLat * 1e6) / 1e6,
314
+ lng: Math.round(M.minLon * 1e6) / 1e6
315
315
  },
316
316
  max: {
317
- lat: Math.round(g.maxLat * 1e6) / 1e6,
318
- lng: Math.round(g.maxLon * 1e6) / 1e6
317
+ lat: Math.round(M.maxLat * 1e6) / 1e6,
318
+ lng: Math.round(M.maxLon * 1e6) / 1e6
319
319
  },
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) => ({
326
- code: I.regionCode,
327
- nameCn: I.nameCn,
328
- nameEn: I.nameEn,
329
- type: I.regionType,
330
- distance: I.length
320
+ level: M.mapLevel
321
+ })), c == null || c.map((M) => {
322
+ M.regionLength && I.regions.push({
323
+ type: M.regionType,
324
+ distance: M.regionLength,
325
+ rows: M.regions.map((j) => ({
326
+ code: j.regionCode,
327
+ nameCn: j.nameCn,
328
+ nameEn: j.nameEn,
329
+ type: j.regionType,
330
+ distance: j.length
331
331
  }))
332
332
  });
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;
333
+ }), I.waypoints = m == null ? void 0 : m.map((M) => ({
334
+ lat: Math.round(M.lat * 1e5) / 1e5,
335
+ lng: Math.round(M.lon * 1e5) / 1e5
336
+ })), (S = I.waypoints) != null && S.length && (I.waypoints = O.simplifyCoordinates(I.waypoints), I.route = O.divideAccordingToLng(I.waypoints), I.distance = O.calculateRouteDistance(I.route), I.distanceInECA = h);
337
+ const C = w().diff(r, "second");
338
+ return I.memo = `time cost: ${C}s`, g.info("[%s] calculate route cost: %d seconds", s.requestId, C), I;
339
339
  }
340
340
  }
341
341
  async trajectory(t, a, o, n, i = !0, s = {}) {
@@ -346,7 +346,7 @@ class jt extends at {
346
346
  return await this.trajectoryIn30Day(t, l, u, r, n, d, s), d;
347
347
  }
348
348
  async trajectoryIn30Day(t, a, o, n, i, s, r = {}) {
349
- var b, S, C, p, v;
349
+ var b, S, I, p, v;
350
350
  const l = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", u = {
351
351
  headers: {
352
352
  Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(S = this.token) == null ? void 0 : S.accessToken}`
@@ -357,16 +357,16 @@ class jt extends at {
357
357
  endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
358
358
  }
359
359
  };
360
- M == null || M.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, u);
360
+ g == null || g.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, u);
361
361
  const d = await B.post(l, u).json();
362
362
  if (d.code)
363
- return M == null || M.warn("[%s] fetch trajectory failed: %j", r.requestId, l, { message: d.message, status: d.status, code: d.code }), d;
363
+ return g == null || g.warn("[%s] fetch trajectory failed: %j", r.requestId, l, { message: d.message, status: d.status, code: d.code }), d;
364
364
  let y = -1;
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");
365
+ const k = w(`${(p = (I = d.data) == null ? void 0 : I[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
366
366
  return (v = d.data) == null || v.forEach((m) => {
367
367
  for (const P in m)
368
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 = {
369
+ const c = w(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), h = m.status, { labelCn: f, labelEn: C } = this.parseStatus(h), M = {
370
370
  mmsi: m.mmsi,
371
371
  imo: n == null ? void 0 : n.imo,
372
372
  lat: m.lat,
@@ -375,17 +375,17 @@ class jt extends at {
375
375
  cog: m.cog,
376
376
  hdg: m.hdg,
377
377
  draught: m.draught,
378
- status: f,
378
+ status: h,
379
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
380
  destination: m.dest,
381
381
  positionTime: c.unix(),
382
- labelCn: h,
383
- labelEn: g,
382
+ labelCn: f,
383
+ labelEn: C,
384
384
  method: "trajectory",
385
385
  vendor: "myVessel",
386
386
  utc: c.utc().format()
387
- }, F = Math.floor(c.diff(k, "minute", !0) / (i || 1));
388
- F !== y && (y = F, s.push(I));
387
+ }, j = Math.floor(c.diff(k, "minute", !0) / (i || 1));
388
+ j !== y && (y = j, s.push(M));
389
389
  }), s;
390
390
  }
391
391
  }
@@ -402,10 +402,10 @@ class Ft extends at {
402
402
  usertoken: this.token
403
403
  }
404
404
  }, i = await B.post(o, n).json();
405
- M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
405
+ g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
406
406
  const s = i == null ? void 0 : i.list;
407
407
  if (!s)
408
- return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, o, i), i;
408
+ return g == null || g.warn("[%s] fetch realtime position failed: %j", a.requestId, o, i), i;
409
409
  for (const k in s)
410
410
  !isNaN(s[k]) && Number(s[k]) !== 1 / 0 && (s[k] = Number(s[k]));
411
411
  s.status = s.sp > 3 ? 0 : 1;
@@ -452,7 +452,7 @@ class Ft extends at {
452
452
  }
453
453
  };
454
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]);
455
+ g == null || g.info("[%s] fetch vessel props from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]);
456
456
  for (const r in i)
457
457
  !isNaN(i[r]) && Number(i[r]) !== 1 / 0 && (i[r] = Number(i[r]));
458
458
  const s = {
@@ -465,7 +465,7 @@ class Ft extends at {
465
465
  draught: i.dr,
466
466
  type: i.t
467
467
  };
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;
468
+ return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", i = await B.post(o, n).json(), g == null || g.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;
469
469
  }
470
470
  async suggest(t, a = {}) {
471
471
  const o = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
@@ -478,7 +478,7 @@ class Ft extends at {
478
478
  Host: "www.hifleet.com"
479
479
  }
480
480
  }, i = await B.post(o, n).json();
481
- M == null || M.info("[%s] suggest vessel props from: %s - %j", a.requestId, o, n);
481
+ g == null || g.info("[%s] suggest vessel props from: %s - %j", a.requestId, o, n);
482
482
  const s = [];
483
483
  for (const r of i)
484
484
  s.push({
@@ -491,13 +491,13 @@ class Ft extends at {
491
491
  return s.sort((r, l) => l.score - r.score), s;
492
492
  }
493
493
  async trajectory(t, a, o, n, i = !0, s = {}) {
494
- var m, c, f;
494
+ var m, c, h;
495
495
  const r = await this.realTimePosition(t, s);
496
496
  let l = w(a);
497
497
  const u = w(o), d = w();
498
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");
499
+ let f = u.diff(l, "d", !0);
500
+ f < 0 ? l = u.clone().subtract(40, "d") : f < 30 ? l.subtract(10, "d") : f < 60 ? l.subtract(5, "d") : l = u.clone().subtract(80, "d"), f = d.diff(u, "d", !0), u.add(f > 10 ? 240 : f * 24, "h");
501
501
  }
502
502
  const y = {
503
503
  searchParams: {
@@ -507,38 +507,38 @@ class Ft extends at {
507
507
  usertoken: this.token
508
508
  }
509
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);
510
+ g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, k, y);
511
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 = [];
512
+ b && (S = ((c = (m = b.ships) == null ? void 0 : m.offors) == null ? void 0 : c.ship) || [], S.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
513
+ const I = [];
514
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,
515
+ const v = w(`${(h = S == null ? void 0 : S[0]) == null ? void 0 : h.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
516
+ for (const f of S) {
517
+ for (const H in f)
518
+ !isNaN(f[H]) && Number(f[H]) !== 1 / 0 && (f[H] = Number(f[H]));
519
+ const C = w(`${f.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
520
+ f.status = f.sp > 4 ? 0 : 1;
521
+ const { labelEn: M, labelCn: j } = this.parseStatus(f.status), P = {
522
+ mmsi: f.m,
523
+ name: f.n,
524
524
  imo: r == null ? void 0 : r.imo,
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,
534
- labelCn: F,
535
- labelEn: I,
525
+ lat: f.la,
526
+ lng: f.lo,
527
+ draught: f.draught,
528
+ sog: f.sp,
529
+ cog: f.co,
530
+ hdg: f.hdg,
531
+ positionTime: C.unix(),
532
+ utc: C.utc().format(),
533
+ status: f.status,
534
+ labelCn: j,
535
+ labelEn: M,
536
536
  method: "trajectory",
537
537
  vendor: "hifleet"
538
- }, D = Math.floor(g.diff(v, "minute", !0) / (n || 1));
539
- D !== p && (p = D, C.push(P));
538
+ }, D = Math.floor(C.diff(v, "minute", !0) / (n || 1));
539
+ D !== p && (p = D, I.push(P));
540
540
  }
541
- return C;
541
+ return I;
542
542
  }
543
543
  }
544
544
  class Nt extends at {
@@ -555,7 +555,7 @@ class Nt extends at {
555
555
  enc: 1
556
556
  }
557
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)
558
+ if (g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o), (i == null ? void 0 : i.status) !== 0)
559
559
  return i;
560
560
  const s = i.data[0];
561
561
  for (const y in s)
@@ -596,12 +596,12 @@ class Nt extends at {
596
596
  etm: u.unix()
597
597
  }
598
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)
599
+ if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, d, y), (k == null ? void 0 : k.status) !== 0)
600
600
  return k;
601
- const b = k == null ? void 0 : k.points, S = [], C = w.unix((v = b[0]) == null ? void 0 : v.utc);
601
+ const b = k == null ? void 0 : k.points, S = [], I = w.unix((v = b[0]) == null ? void 0 : v.utc);
602
602
  let p = -1;
603
603
  for (const m of b) {
604
- const c = w.unix(m.utc), f = {
604
+ const c = w.unix(m.utc), h = {
605
605
  imo: r == null ? void 0 : r.imo,
606
606
  mmsi: t,
607
607
  sog: Math.round(m.sog * 3600 / 1e3 / 1852 * 100) / 100,
@@ -612,8 +612,8 @@ class Nt extends at {
612
612
  utc: c.utc().format(),
613
613
  method: "trajectory",
614
614
  vendor: "shipxy"
615
- }, h = Math.floor(c.diff(C, "minute", !0) / (n || 1));
616
- h !== p && (p = h, S.push(f));
615
+ }, f = Math.floor(c.diff(I, "minute", !0) / (n || 1));
616
+ f !== p && (p = f, S.push(h));
617
617
  }
618
618
  return S;
619
619
  }
@@ -633,7 +633,7 @@ class xt extends at {
633
633
  mmsiList: t
634
634
  }
635
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;
636
+ return g == null || g.info("[%s] fetch ship id from: %s - %j", a.requestId, n, o), i.code !== "0" ? i : i.data[0].shipId;
637
637
  }
638
638
  async getShipInfo(t, a = {}) {
639
639
  const o = {
@@ -644,11 +644,11 @@ class xt extends at {
644
644
  shipId: t
645
645
  }
646
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")
647
+ if (g == null || g.info("[%s] fetch ship info from: %s - %j", a.requestId, n, o), i.code !== "0")
648
648
  return i;
649
649
  const s = i.data;
650
650
  let r = s.imo;
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)), {
651
+ return t === "407170" && (r = "9198379", g == null || g.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, s.imo, r)), {
652
652
  mmsi: s.mmsi,
653
653
  name: s.shipnameEn,
654
654
  imo: r,
@@ -667,7 +667,7 @@ class xt extends at {
667
667
  shipId: o
668
668
  }
669
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);
670
+ g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, i);
671
671
  const l = r.data[0];
672
672
  for (const b in l)
673
673
  !isNaN(l[b]) && Number(l[b]) !== 1 / 0 && (l[b] = Number(l[b]));
@@ -697,7 +697,7 @@ class xt extends at {
697
697
  return await this.trajectoryIn30Day(u, r.unix(), l.unix(), d, t, n, y), y;
698
698
  }
699
699
  async trajectoryIn30Day(t, a, o, n, i, s, r, l = {}) {
700
- var C;
700
+ var I;
701
701
  const u = {
702
702
  headers: {
703
703
  appKey: this.token
@@ -708,12 +708,12 @@ class xt extends at {
708
708
  endTime: o
709
709
  }
710
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;
711
+ if (g == null || g.info("[%s] fetch trajectory from: %s - %j", l.requestId, d, u), y.code !== "0")
712
+ return g == null || g.warn("[%s] invoke myship trajectory failed: %j", l.requestId, y), y;
713
713
  const k = y.data;
714
714
  for (const p in k)
715
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);
716
+ const b = w.unix((I = k[0]) == null ? void 0 : I.posTime);
717
717
  let S = -1;
718
718
  for (const p of k) {
719
719
  const v = w.unix(p.posTime), m = {
@@ -798,20 +798,20 @@ class Mt {
798
798
  * @param options
799
799
  */
800
800
  checkWeather(e, t, a = {}) {
801
- var b, S, C, p, v, m, c, f, h, g, I, F, P, D, H;
801
+ var b, S, I, p, v, m, c, h, f, C, M, j, P, D, H;
802
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;
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 = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : p.number, u = (m = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : m.number, d = Math.round((((h = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : h.number) + 2) * 100) / 100, y = (C = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.wind) == null ? void 0 : C.number, k = (j = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
804
+ for (let F = 0; F < (e == null ? void 0 : e.length); F++) {
805
+ const N = e[F], 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 = F ? w(N.eta).diff(w(e[F - 1].eta), "hour", !0) : 0;
806
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;
807
807
  }
808
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 } };
809
809
  }
810
810
  }
811
811
  const Dt = new Mt();
812
- let T;
812
+ let E;
813
813
  try {
814
- T = dt.getLogger("vessel");
814
+ E = dt.getLogger("vessel");
815
815
  } catch {
816
816
  } finally {
817
817
  }
@@ -963,16 +963,16 @@ class Y {
963
963
  let u;
964
964
  try {
965
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, {
966
+ const { weatherModels: b, marineModels: S } = await ct.autoPickMeteoModel(o), I = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
967
967
  ...r,
968
968
  pastDays: 1,
969
969
  forecastDays: 1,
970
970
  weatherModels: b,
971
971
  marineModels: S
972
- }), [p] = ct.pickHourly(C, a);
972
+ }), [p] = ct.pickHourly(I, a);
973
973
  u = ct.toLegacy(p);
974
974
  } catch (b) {
975
- T.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, b);
975
+ E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, b);
976
976
  }
977
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
978
  l = {
@@ -1010,46 +1010,46 @@ class Y {
1010
1010
  static async speedLoseInHoursStep(e, t, a, o, n, i, s = "", r = !0, l = !1, u = {}) {
1011
1011
  t.utc();
1012
1012
  const d = t.clone().add(14, "days"), y = [], k = [], b = [];
1013
- let S = 0, C = 0, p, v;
1013
+ let S = 0, I = 0, p, v;
1014
1014
  for (let m = 0; m < i.length - 1; m++) {
1015
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) {
1016
+ c.distanceFromStart = Math.round((n + I) * 1e3) / 1e3;
1017
+ const h = i[m + 1];
1018
+ if (e.bearing = O.calculateBearing(c, h, !h.gcToPrevious), c.bearing = e.bearing, c.suspend && l) {
1019
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;
1020
+ const M = c.suspend - c.elapsed;
1021
+ if (o - S > M)
1022
+ o = o - S - M, t.add(M, "hour"), c.elapsed = c.suspend;
1023
1023
  else {
1024
- const F = o - S;
1025
- c.elapsed += F, t.add(F, "hour"), o = 0;
1024
+ const j = o - S;
1025
+ c.elapsed += j, t.add(j, "hour"), o = 0;
1026
1026
  }
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 };
1027
+ if (E == null || E.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`, u.requestId, c), o === 0)
1028
+ return c.distanceFromPrevious = I, { etd: t, from: v || c, to: c, next: i.filter((j) => j), wps: y, days: k, all: b };
1029
1029
  } else
1030
1030
  c.suspend = 0;
1031
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`,
1032
+ const f = O.calculateDistance(c, h, !h.gcToPrevious);
1033
+ let C = Math.round(f / v.speed * 1e5) / 1e5;
1034
+ if (S + C < o) {
1035
+ if (S += C, t.add(C, "hour"), delete i[m], E == null || E.debug(
1036
+ `[%s] go to %j from %j with ${f}nm, and cost ${C} hours`,
1037
1037
  u.requestId,
1038
- { lat: f.lat, lng: f.lng },
1038
+ { lat: h.lat, lng: h.lng },
1039
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];
1040
+ ), I += f, i.filter((M) => M).length <= 1) {
1041
+ p = h, p.eta = t.utc().format(), p.distanceFromPrevious = f, p.distanceFromStart = Math.round((n + I) * 1e4) / 1e4, y.push(p), b.push(p), delete i[m + 1];
1042
1042
  break;
1043
1043
  }
1044
1044
  } else {
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`,
1045
+ C = o - S, t.add(C, "hour");
1046
+ const M = z.roundPrecision(v.speed * C, 5);
1047
+ p = O.calculateCoordinate(c, e.bearing, M, "nauticalmiles", !h.gcToPrevious), p.eta = t.utc().format(), i[m] = p, E == null || E.debug(
1048
+ `[%s] go to %j from %j with ${M}nm, and cost ${C} hours`,
1049
1049
  u.requestId,
1050
1050
  { lat: p.lat, lng: p.lng },
1051
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;
1052
+ ), I += M, p.distanceFromPrevious = Math.round(I * 1e4) / 1e4, p.distanceFromStart = Math.round((n + I) * 1e4) / 1e4;
1053
1053
  break;
1054
1054
  }
1055
1055
  }
@@ -1075,15 +1075,15 @@ class Y {
1075
1075
  * @param cFactor 洋流因子
1076
1076
  */
1077
1077
  static weatherFactor(e, t, a = 0) {
1078
- var k, b, S, C, p, v, m;
1079
- T == null || T.debug("calculate weather factor via: %j", { ...e, ...t });
1078
+ var k, b, S, I, p, v, m;
1079
+ E == null || E.debug("calculate weather factor via: %j", { ...e, ...t });
1080
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
1081
  let r = O.includedAngle(e.bearing, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.degree);
1082
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
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);
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)), E == null || E.debug("wind wx factor = %d", d), r = O.includedAngle(e.bearing, (p = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : p.degree);
1085
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;
1086
+ return E == null || E.debug("wave wx factor = %d", y), d = Math.abs(d) > Math.abs(y) ? d : d * 0.3 + y * 0.7, E == null || E.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;
1087
1087
  }
1088
1088
  /**
1089
1089
  * 以12小时级别去掉重复的days
@@ -1121,7 +1121,7 @@ class Y {
1121
1121
  const { route: y, waypoints: k } = n.points, b = O.calculateSubRoute(e, y);
1122
1122
  if (((_ = b[0]) == null ? void 0 : _.length) <= 1)
1123
1123
  return;
1124
- const { v0: S, label: C } = e.sog ? {
1124
+ const { v0: S, label: I } = e.sog ? {
1125
1125
  v0: e.sog,
1126
1126
  label: e.label || "Other"
1127
1127
  /* Instruct */
@@ -1136,7 +1136,7 @@ class Y {
1136
1136
  route: b,
1137
1137
  waypoints: v,
1138
1138
  v0: S,
1139
- label: C
1139
+ label: I
1140
1140
  }, c = {
1141
1141
  hours: [],
1142
1142
  days: [],
@@ -1144,45 +1144,45 @@ class Y {
1144
1144
  all: []
1145
1145
  };
1146
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;
1147
+ let h = O.simplifyRouteToCoordinates(b, v, 0), f = 0, C = 0, M = 0, j = 0;
1148
1148
  t = w(t).utc();
1149
1149
  const P = t.clone();
1150
- for (; f.length > 0; ) {
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(
1150
+ for (; h.length > 0; ) {
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, T = await Y.speedLoseInHoursStep(
1152
1152
  p,
1153
1153
  t,
1154
1154
  P,
1155
1155
  V,
1156
- h,
1157
1156
  f,
1157
+ h,
1158
1158
  i,
1159
1159
  r,
1160
1160
  l,
1161
1161
  u
1162
1162
  );
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);
1163
+ if (c.all.push(...T.all), (G = T.from) != null && G.speed && (c.hours.push(T.from), c.wps.push(...T.wps), c.days.push(...T.days)), h = T == null ? void 0 : T.next, !h.length) {
1164
+ const L = await Y.speedLoseAt(p, T.to, w(T.to.eta), i, 0, r, l, u);
1165
1165
  L.bearing = p.bearing, c.hours.push(L), c.all.push(L);
1166
1166
  }
1167
- h += Math.round((((X = E == null ? void 0 : E.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1167
+ f += Math.round((((X = T == null ? void 0 : T.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1168
1168
  }
1169
1169
  const D = c.hours;
1170
1170
  for (let A = 0; A < D.length - 1; A++) {
1171
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;
1172
+ C += (D[A].wxFactor || 0) * V, M += (D[A].cFactor || 0) * V, j += V;
1173
1173
  }
1174
1174
  const H = D.reduce((A, V) => A + (V.suspend || 0), 0);
1175
1175
  (Q = c.wps) == null || Q.forEach((A, V) => {
1176
1176
  A.positionTime = w.utc(A.etd || A.eta).unix();
1177
- const E = c.wps[V - 1];
1178
- if (E) {
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);
1177
+ const T = c.wps[V - 1];
1178
+ if (T) {
1179
+ const L = A.distanceFromStart - T.distanceFromStart, q = w(A.eta || A.etd).diff(w(T.etd || T.eta), "h", !0);
1180
+ A.avgSpd = Math.round(L / q * 100) / 100, T.bearing = O.calculateBearing(T, A);
1181
1181
  }
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);
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((T) => Math.round(T.positionTime / 60) === Math.round(V.positionTime / 60)) || A.push(V), A), []), m.sample = c;
1183
+ const F = c.hours.at(0), N = c.hours.at(-1);
1184
+ m.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, m.etd = w(F.eta).utc().format(), m.eta = w(N.eta).utc().format(), m.wxFactor = Math.round(C / j * 1e3) / 1e3, m.cFactor = Math.round(M / j * 1e3) / 1e3, m.avgSpeed = Math.round(N.distanceFromStart / j * 1e3) / 1e3, m.totalHrs = Math.round(j * 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 * (j - K), 3), ot = z.roundPrecision(o.dgo / 24 * j + R, 3);
1186
1186
  m.extend = {
1187
1187
  eca: tt,
1188
1188
  distanceInECA: W,
@@ -1191,7 +1191,7 @@ class Y {
1191
1191
  totalDgoConsInSuspend: R
1192
1192
  }, m.totalFoCons = et < 0 ? 0 : et, m.totalDgoCons = ot;
1193
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;
1194
+ return E == null || E.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;
1195
1195
  }
1196
1196
  /**
1197
1197
  * 分段失速分析(最多走hours 小时)
@@ -1220,58 +1220,58 @@ class Y {
1220
1220
  v0: n.speed,
1221
1221
  label: "CP"
1222
1222
  /* Cp */
1223
- }, C = Y.assembleProperties(o, n.loadCondition, b, 0), p = O.calculateSubRoute(e, i);
1223
+ }, I = Y.assembleProperties(o, n.loadCondition, b, 0), p = O.calculateSubRoute(e, i);
1224
1224
  if (((X = p[0]) == null ? void 0 : X.length) <= 1)
1225
1225
  return;
1226
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
+ v.forEach((T) => T.important = !0);
1228
+ let m = O.simplifyRouteToCoordinates(p, v, 0), c = 0, h = 0, f = 0, C = 0;
1229
+ const M = {
1230
1230
  hours: [],
1231
1231
  wps: [],
1232
1232
  days: [],
1233
1233
  all: []
1234
1234
  };
1235
1235
  t = w(t).utc();
1236
- const F = t.clone();
1236
+ const j = t.clone();
1237
1237
  for (; m.length > 0; ) {
1238
- const E = l - t.hour() % l;
1239
- let L = Math.ceil(t.clone().add(E, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1238
+ const T = l - t.hour() % l;
1239
+ let L = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1240
1240
  L = t.clone().add(L, "h").isSameOrAfter(a) ? a.diff(t, "h", !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)
1241
+ const q = await Y.speedLoseInHoursStep(I, t, j, L, c, m, r, u, d, y);
1242
+ if (M.all.push(...q.all), (Q = q.from) != null && Q.speed && (M.hours.push(q.from), q != null && q.wps && M.wps.push(...q.wps), M.days.push(...q.days)), m = q == null ? void 0 : q.next, m.length || M.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)
1243
1243
  break;
1244
1244
  }
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];
1245
+ M.wps = await Y.reduceWPS(M.wps), M.days = await Y.reduceDays(M.days), M.all = ($ = M.all) == null ? void 0 : $.reduce((T, L) => (L.positionTime = w.utc(L.etd || L.eta).unix(), T.some((q) => Math.round(w(q.etd).unix() / 60) === Math.round(w(L.etd).unix() / 60)) || T.push(L), T), []), (A = M.wps) == null || A.forEach((T, L) => {
1246
+ const q = M.wps[L - 1];
1247
1247
  if (q) {
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;
1248
+ const ut = T.distanceFromStart - q.distanceFromStart, lt = w(T.eta || T.etd).diff(w(q.etd || q.eta), "h", !0);
1249
+ q.bearing = O.calculateBearing(q, T), T.avgSpd = Math.round(ut / lt * 100) / 100;
1250
1250
  }
1251
1251
  });
1252
- const P = I.hours;
1253
- for (let E = 0; E < P.length - 1; E++) {
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;
1252
+ const P = M.hours;
1253
+ for (let T = 0; T < P.length - 1; T++) {
1254
+ const L = w(P[T + 1].eta).diff(P[T].etd, "hour", !0);
1255
+ h += P[T].wxFactor * L, f += P[T].cFactor * L, C += L;
1256
1256
  }
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
+ const D = P.reduce((T, L) => T + (L.suspend || 0), 0), H = M.hours.at(0), F = M.hours.at(-1), N = await O.calculateRangeRoute(H, F, p), R = await O.calculateRangeWaypoints(H, F, p, v), W = {
1258
+ sample: M,
1259
+ distance: Math.round(((F == null ? void 0 : F.distanceFromStart) || 0) * 1e4) / 1e4,
1260
1260
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
1261
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,
1262
+ eta: w(F == null ? void 0 : F.eta).utc().format(),
1263
+ wxFactor: Math.round(h / C * 1e3) / 1e3,
1264
+ cFactor: Math.round(f / C * 1e3) / 1e3,
1265
+ avgSpeed: Math.round(((F == null ? void 0 : F.distanceFromStart) || 0) / C * 1e3) / 1e3,
1266
+ totalHrs: Math.round(C * 1e3) / 1e3,
1267
1267
  suspend: Math.round(D * 1e3) / 1e3,
1268
1268
  from: H,
1269
- to: j,
1269
+ to: F,
1270
1270
  route: N,
1271
1271
  waypoints: R,
1272
1272
  v0: b,
1273
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);
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 * (C - tt), 3), st = z.roundPrecision(n.dgo / 24 * C + K, 3);
1275
1275
  W.extend = {
1276
1276
  eca: ot,
1277
1277
  distanceInECA: nt,
@@ -1279,8 +1279,8 @@ class Y {
1279
1279
  totalDgoConsInECA: et,
1280
1280
  totalDgoConsInSuspend: K
1281
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;
1282
+ const _ = w().valueOf() - k, G = ((V = M == null ? void 0 : M.hours) == null ? void 0 : V.length) || 1;
1283
+ return E == null || E.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;
1284
1284
  }
1285
1285
  /**
1286
1286
  * 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
@@ -1310,46 +1310,46 @@ class Y {
1310
1310
  const u = w.utc(e.etd).add(l ?? 14, "day");
1311
1311
  let d = 1;
1312
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(
1313
+ const c = JSON.parse(JSON.stringify(o.route)), h = JSON.parse(JSON.stringify(o.waypoints)), f = await Y.analyseInstantWithThreshed(
1314
1314
  { lat: e.lat, lng: e.lng },
1315
1315
  e.etd,
1316
1316
  u,
1317
1317
  t,
1318
1318
  m,
1319
1319
  c,
1320
- f,
1320
+ h,
1321
1321
  e.meteoVendor,
1322
1322
  e.speedStep,
1323
1323
  e.useMeteo,
1324
1324
  e.useRouteParam,
1325
1325
  n
1326
1326
  );
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,
1327
+ f && (await Y.calculateCost(f, m, e, n), s.push(f), E == null || E.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, d, e.etd, u.format(), {
1328
+ cost: f.cost.total,
1329
+ hire: f.cost.hire,
1330
+ bunker: f.cost.bunker,
1331
+ distance: f.distance,
1332
+ hours: f.totalHrs,
1333
1333
  cp: `${m.speed}/${m.fo}/${m.dgo}`
1334
1334
  })), d++;
1335
1335
  }
1336
1336
  s.sort((m, c) => m.cost.total - c.cost.total);
1337
1337
  const y = s.at(0), k = s.at(1), b = [];
1338
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)
1339
+ const m = y.cost.cp, c = k.cost.cp, h = w(y.eta), f = w(y.etd), C = h.diff(f, "days", !0);
1340
+ let M = Math.ceil(C / 2);
1341
+ M = M > 7 ? 7 : M < e.alterStep ? e.alterStep : M;
1342
+ let j = 2, P = { combined: !1, speeds: [k], cost: (v = k.cost) == null ? void 0 : v.total }, D;
1343
+ for (; M >= e.alterStep; ) {
1344
+ const H = await Y.combinedAnalyse(e, t, u, [m, c], o, M, { ...n, level: j });
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), M <= e.alterStep)
1346
1346
  break;
1347
- I = Math.ceil(I / 2), F += 1;
1347
+ M = Math.ceil(M / 2), j += 1;
1348
1348
  }
1349
1349
  b.push(P), D && b.push(D);
1350
1350
  }
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);
1351
+ const I = w().valueOf() - i;
1352
+ return E == null || E.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, I), b.sort((m, c) => m.cost - c.cost);
1353
1353
  }
1354
1354
  /**
1355
1355
  * 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
@@ -1362,19 +1362,19 @@ class Y {
1362
1362
  * @param options
1363
1363
  */
1364
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, {
1365
+ s.counter = 1, E == null || E.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, h) => c + h.cost.total, 0), u = r.reduce((c, h) => c + h.cost.hire, 0), d = r.reduce((c, h) => c + h.cost.bunker, 0), y = r.reduce((c, h) => c + h.distance, 0), k = r.reduce((c, h) => c + h.totalHrs, 0);
1367
+ E == null || E.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1368
1368
  cost: l,
1369
1369
  hire: u,
1370
1370
  bunker: d,
1371
1371
  distance: y,
1372
1372
  hours: k
1373
1373
  });
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, {
1374
+ const b = await Y.alternateAnalyse(e, t, a, o, 1, n, i, s), S = b.reduce((c, h) => c + h.cost.total, 0), I = b.reduce((c, h) => c + h.cost.hire, 0), p = b.reduce((c, h) => c + h.cost.bunker, 0), v = b.reduce((c, h) => c + h.distance, 0), m = b.reduce((c, h) => c + h.totalHrs, 0);
1375
+ return E == null || E.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
1376
1376
  cost: S,
1377
- hire: C,
1377
+ hire: I,
1378
1378
  bunker: p,
1379
1379
  distance: v,
1380
1380
  hours: m
@@ -1396,21 +1396,21 @@ class Y {
1396
1396
  let l = w.utc(e.etd);
1397
1397
  const u = { lat: e.lat, lng: e.lng }, d = [];
1398
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(
1399
+ const b = l.clone().utc().add(s, "day"), S = JSON.parse(JSON.stringify(i.route)), I = JSON.parse(JSON.stringify(i.waypoints)), p = o[n], v = await Y.analyseInstantWithThreshed(
1400
1400
  u,
1401
1401
  l.utc().format(),
1402
1402
  b,
1403
1403
  t,
1404
1404
  p,
1405
1405
  S,
1406
- C,
1406
+ I,
1407
1407
  e.meteoVendor,
1408
1408
  e.speedStep,
1409
1409
  e.useMeteo,
1410
1410
  e.useRouteParam,
1411
1411
  r
1412
1412
  );
1413
- v && (await Y.calculateCost(v, p, e, r), T == null || T.info(
1413
+ v && (await Y.calculateCost(v, p, e, r), E == null || E.info(
1414
1414
  "[%s][L%d-%d] analyse from %s to %s cost: %j",
1415
1415
  r.requestId,
1416
1416
  r.level,
@@ -1489,48 +1489,48 @@ class Y {
1489
1489
  hours: [],
1490
1490
  wps: [],
1491
1491
  days: []
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 = [];
1492
+ }, o = e.reduce((h, f) => h + f.distance, 0), n = e.reduce((h, f) => {
1493
+ var C;
1494
+ return h + (((C = f.extend) == null ? void 0 : C.distanceInECA) || 0);
1495
+ }, 0), i = e.reduce((h, f) => h + f.totalHrs, 0), s = e.reduce((h, f) => {
1496
+ var C;
1497
+ return h + (((C = f.extend) == null ? void 0 : C.hoursInECA) || 0);
1498
+ }, 0), r = e.reduce((h, f) => {
1499
+ var C;
1500
+ return h + (((C = f.extend) == null ? void 0 : C.totalDgoConsInECA) || 0);
1501
+ }, 0), l = e.reduce((h, f) => h + f.wxFactor * f.totalHrs / i, 0), u = e.reduce((h, f) => h + f.cFactor * f.totalHrs / i, 0), d = e.reduce((h, f) => h + f.totalFoCons, 0), y = e.reduce((h, f) => h + f.totalDgoCons, 0), k = e.reduce((h, f) => h + f.cost.total, 0), b = e.reduce((h, f) => h + f.cost.hire, 0), S = e.reduce((h, f) => h + f.cost.bunker, 0), I = [], p = [];
1502
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) => {
1503
+ for (const h of e) {
1504
+ p.push(...((m = h.extend) == null ? void 0 : m.eca) || []);
1505
+ const f = h.sample.hours, C = h.sample.wps, M = h.sample.days, j = f.at(0);
1506
+ v && (j.distanceFromPrevious = v.distanceFromPrevious, j.distanceFromStart = v.distanceFromStart, f.forEach((F, N) => {
1507
+ N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1508
+ }), C.at(0).distanceFromPrevious = v.distanceFromPrevious, C.at(0).distanceFromStart = v.distanceFromStart, C.forEach((F, N) => {
1509
+ N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1510
+ }), M.at(0).distanceFromPrevious = v.distanceFromPrevious, M.at(0).distanceFromStart = v.distanceFromStart, M.forEach((F, N) => {
1511
+ N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1512
+ })), j.cp = h.cost.cp;
1513
+ const P = [h.etd, h.eta], D = I.findIndex((F) => F.id === j.cp.id);
1514
+ D === -1 ? (j.cp.segment = [P], I.push(j.cp)) : I[D].segment.push(P), f.forEach((F) => {
1515
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) => {
1516
+ ((R = a.hours) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.hours.push(F);
1517
+ }), C.forEach((F) => {
1518
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) => {
1519
+ ((R = a.wps) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.wps.push(F);
1520
+ }), M.forEach((F) => {
1521
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);
1522
+ ((R = a == null ? void 0 : a.days) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.days.push(F);
1523
1523
  });
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);
1524
+ const H = (c = a.wps) == null ? void 0 : c.findIndex((F) => F.eta === j.eta);
1525
+ H === -1 ? a.wps.push(j) : a.wps[H] = j, v = f.at(-1);
1526
1526
  }
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;
1527
+ return a.wps.sort((h, f) => w(h.etd).unix() - w(f.etd).unix()), a.wps.forEach((h, f) => {
1528
+ const C = a.wps[f - 1];
1529
+ if (C) {
1530
+ const M = h.distanceFromStart - (C.distanceFromStart || 0), j = w(h.eta || h.etd).diff(w(C.etd || C.eta), "hour", !0), P = Math.round(M / j * 100) / 100;
1531
+ h.avgSpd = P;
1532
+ const D = O.calculateBearing(C, h);
1533
+ C.bearing = D;
1534
1534
  }
1535
1535
  }), {
1536
1536
  sample: a,
@@ -1553,7 +1553,7 @@ class Y {
1553
1553
  bunker: Math.round(S * 1e3) / 1e3
1554
1554
  },
1555
1555
  extend: {
1556
- cps: C,
1556
+ cps: I,
1557
1557
  eca: p,
1558
1558
  distanceInECA: Math.round(n * 1e3) / 1e3,
1559
1559
  hoursInECA: Math.round(s * 1e3) / 1e3,
@@ -1 +1 @@
1
- (function(D,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],x):(D=typeof globalThis<"u"?globalThis:D||self,x(D["idm-plugin-vessel"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,x,U,v,E,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(D,x,U)=>x in D?Ct(D,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):D[x]=U;var _=(D,x,U)=>(St(D,typeof x!="symbol"?x+"":x,U),U);let p;try{p=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();p==null||p.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async checkToken(t={}){var a;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}async suggest(t,a={}){var s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};p==null||p.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(p==null||p.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};p==null||p.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return p==null||p.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const d=r.data;if(d)return{mmsi:d.mmsi,imo:Number.isNaN(d.imo)?null:Number(d.imo),callSign:d.callsign,name:d.nameEn,nameCn:d.nameCn,type:d.vesselTypeNameEn,flagName:d.flagCtry,clasz:d.classSociety,dateOfBuild:d.buildYearMonth,deadweight:d.dwt,grossTonnage:d.grt,netTonnage:d.net,teu:d.teu,length:d.length,breadth:d.width,height:d.height,draught:d.draught,speed:d.speed,passengerCapacity:d.passengercapacity,vendor:"myvessel",raw:d}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};p==null||p.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(p==null||p.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return p==null||p.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=v(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.dest,positionTime:u.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,T;const r=v();await this.checkToken(s);const l="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",u={endPoint:{lon:a.lng,lat:a.lat},maxDraught:s.draught||10,useAIModel:s.useAIModel||!1,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const d={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};p==null||p.info("[%s] fetch route from: %s - %j",s.requestId,l,d);const y=await x.post(l,d).json();if(y.status!==200)return p==null||p.warn("[%s] fetch route failed: %j",s.requestId,{message:y.message,status:y.status,code:y.code}),{};{const C={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:w,tracks:f,specialRegions:c}=y.data;C.nodes=g==null?void 0:g.map(M=>({code:M.nodeCode,nameEn:M.nameEn,nameCn:M.nameCn,center:{lat:Math.round(M.lat*1e6)/1e6,lng:Math.round(M.lon*1e6)/1e6},start:{lat:Math.round(M.startLat*1e6)/1e6,lng:Math.round(M.startLon*1e6)/1e6},end:{lat:Math.round(M.endLat*1e6)/1e6,lng:Math.round(M.endLat*1e6)/1e6},isKey:M.isKeyNode,isHub:M.isHubNode})),C.seas=w==null?void 0:w.map(M=>({code:M.mrgidSea,nameEn:M.nameEn,nameCn:M.nameCn,center:{lat:Math.round(M.centerLat*1e6)/1e6,lng:Math.round(M.centerLon*1e6)/1e6},min:{lat:Math.round(M.minLat*1e6)/1e6,lng:Math.round(M.minLon*1e6)/1e6},max:{lat:Math.round(M.maxLat*1e6)/1e6,lng:Math.round(M.maxLon*1e6)/1e6},level:M.mapLevel})),c==null||c.map(M=>{M.regionLength&&C.regions.push({type:M.regionType,distance:M.regionLength,rows:M.regions.map(k=>({code:k.regionCode,nameCn:k.nameCn,nameEn:k.nameEn,type:k.regionType,distance:k.length}))})}),C.waypoints=f==null?void 0:f.map(M=>({lat:Math.round(M.lat*1e5)/1e5,lng:Math.round(M.lon*1e5)/1e5})),(T=C.waypoints)!=null&&T.length&&(C.waypoints=E.LaneHelper.simplifyCoordinates(C.waypoints),C.route=E.LaneHelper.divideAccordingToLng(C.waypoints),C.distance=E.LaneHelper.calculateRouteDistance(C.route));const h=v().diff(r,"second");return C.memo=`time cost: ${h}s`,p.info("[%s] calculate route cost: %d seconds",s.requestId,h),C}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,d,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,d,s),d}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,T,C,g,w;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(T=this.token)==null?void 0:T.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};p==null||p.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const d=await x.post(l,u).json();if(d.code)return p==null||p.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:d.message,status:d.status,code:d.code}),d;let y=-1;const I=v(`${(g=(C=d.data)==null?void 0:C[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(w=d.data)==null||w.forEach(f=>{for(const q in f)!isNaN(f[q])&&Number(f[q])!==1/0&&(f[q]=Number(f[q]));const c=v(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),m=f.status,{labelCn:h,labelEn:M}=this.parseStatus(m),k={mmsi:f.mmsi,imo:n==null?void 0:n.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:m,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta)?v(`${f.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:f.dest,positionTime:c.unix(),labelCn:h,labelEn:M,method:"trajectory",vendor:"myVessel",utc:c.utc().format()},F=Math.floor(c.diff(I,"minute",!0)/(i||1));F!==y&&(y=F,s.push(k))}),s}}class Mt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return p==null||p.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:u}=this.parseStatus(r),d=v(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:d.unix(),utc:d.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let i=await x.post(o,n).json();p==null||p.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),p==null||p.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},i=await x.post(o,n).json();p==null||p.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var f,c,m;const r=await this.realTimePosition(t,s);let l=v(a);const u=v(o),d=v();if(i){let h=u.diff(l,"d",!0);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")}const y={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,y).json();p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,y);let T;b&&(T=((c=(f=b.ships)==null?void 0:f.offors)==null?void 0:c.ship)||[],T.length||p==null||p.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const C=[];let g=-1;const w=v(`${(m=T==null?void 0:T[0])==null?void 0:m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const h of T){for(const R in h)!isNaN(h[R])&&Number(h[R])!==1/0&&(h[R]=Number(h[R]));const M=v(`${h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");h.status=h.sp>4?0:1;const{labelEn:k,labelCn:F}=this.parseStatus(h.status),q={mmsi:h.m,name:h.n,imo:r==null?void 0:r.imo,lat:h.la,lng:h.lo,draught:h.draught,sog:h.sp,cog:h.co,hdg:h.hdg,positionTime:M.unix(),utc:M.utc().format(),status:h.status,labelCn:F,labelEn:k,method:"trajectory",vendor:"hifleet"},N=Math.floor(M.diff(w,"minute",!0)/(n||1));N!==g&&(g=N,C.push(q))}return C}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=v.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var w;const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(d,y).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,d,y),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,T=[],C=v.unix((w=b[0])==null?void 0:w.utc);let g=-1;for(const f of b){const c=v.unix(f.utc),m={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:c.unix(),utc:c.utc().format(),method:"trajectory",vendor:"shipxy"},h=Math.floor(c.diff(C,"minute",!0)/(n||1));h!==g&&(g=h,T.push(m))}return T}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return p==null||p.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(p==null||p.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",p==null||p.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:d}=await this.parseStatus(l.aisNavStatus),y=v.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:y.utc().format(),status:l.aisNavStatus,labelEn:d,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=v(a),l=v(o),u=await this.getShipId(t),d=await this.getShipInfo(u),y=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),d,t,n,y);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),d,t,n,y),y}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var C;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},d="https://api3.myships.com/sp/ships/position/history",y=await x.post(d,u).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",l.requestId,d,u),y.code!=="0")return p==null||p.warn("[%s] invoke myship trajectory failed: %j",l.requestId,y),y;const I=y.data;for(const g in I)!isNaN(I[g])&&Number(I[g])!==1/0&&(I[g]=Number(I[g]));const b=v.unix((C=I[0])==null?void 0:C.posTime);let T=-1;for(const g of I){const w=v.unix(g.posTime),f={imo:n==null?void 0:n.imo,mmsi:i,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"myship"},c=Math.floor(w.diff(b,"minute",!0)/(s||1));c!==T&&(T=c,r.push(f))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const d=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!d)i.scope=n[0];else if(d)for(let y=0,I=d.length;y<I;y++){const b=this.parseRule(d[y]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,T,C,g,w,f,c,m,h,M,k,F,q,N,R;let o=0,n=0,i=0,s=0;const r=Math.round(((T=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:T.number)*1.6*100)/100,l=(g=(C=t==null?void 0:t.SEVERE)==null?void 0:C.sigWave)==null?void 0:g.number,u=(f=(w=t==null?void 0:t.HEAVY)==null?void 0:w.sigWave)==null?void 0:f.number,d=Math.round((((m=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:m.number)+2)*100)/100,y=(M=(h=t==null?void 0:t.SEVERE)==null?void 0:h.wind)==null?void 0:M.number,I=(F=(k=t==null?void 0:t.HEAVY)==null?void 0:k.wind)==null?void 0:F.number;for(let L=0;L<(e==null?void 0:e.length);L++){const H=e[L],V=(N=(q=H==null?void 0:H.meteo)==null?void 0:q.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=L?v(H.eta).diff(v(e[L-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=u&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I}),(B==null?void 0:B.scale)>=d?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>y?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===I&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),o+=H.isDangerous?K:0,n+=H.isSevere?K:0,i+=H.isHeavy?K:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const vt=new lt;let S;try{S=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ht||{}),ft=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(ft||{}),mt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(mt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var y;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";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:b,marineModels:T}=await ot.Meteo2Assist.autoPickMeteoModel(o),C=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:b,marineModels:T}),[g]=ot.Meteo2Assist.pickHourly(C,a);u=ot.Meteo2Assist.toLegacy(g)}catch(b){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},b)}const d=O.currentFactor(e.bearing,u==null?void 0:u.current,n),y=O.weatherFactor(e,u,d),I=Math.round((e.speed*1.943844+y+d)*100)/100;l={meteo:{...u},wxFactor:y,cFactor:d,speed:t.velocity&&s?t.velocity:I<0?1:I,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const d=t.clone().add(14,"days"),y=[],I=[],b=[];let T=0,C=0,g,w;for(let f=0;f<i.length-1;f++){let c=i[f];c.distanceFromStart=Math.round((n+C)*1e3)/1e3;const m=i[f+1];if(e.bearing=E.LaneHelper.calculateBearing(c,m,!m.gcToPrevious),c.bearing=e.bearing,c.suspend&&l){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const k=c.suspend-c.elapsed;if(o-T>k)o=o-T-k,t.add(k,"hour"),c.elapsed=c.suspend;else{const F=o-T;c.elapsed+=F,t.add(F,"hour"),o=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`,u.requestId,c),o===0)return c.distanceFromPrevious=C,{etd:t,from:w||c,to:c,next:i.filter(F=>F),wps:y,days:I,all:b}}else c.suspend=0;r=t.isAfter(d)?!1:r,c=await O.speedLoseAt(e,c,t,s,0,r,l,u),b.push(c),w=w||c,c.important&&y.push(c),t.isSameOrAfter(a)&&(I.push(c),a.add(24,"hour"));const h=E.LaneHelper.calculateDistance(c,m,!m.gcToPrevious);let M=Math.round(h/w.speed*1e5)/1e5;if(T+M<o){if(T+=M,t.add(M,"hour"),delete i[f],S==null||S.debug(`[%s] go to %j from %j with ${h}nm, and cost ${M} hours`,u.requestId,{lat:m.lat,lng:m.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),C+=h,i.filter(k=>k).length<=1){g=m,g.eta=t.utc().format(),g.distanceFromPrevious=h,g.distanceFromStart=Math.round((n+C)*1e4)/1e4,y.push(g),b.push(g),delete i[f+1];break}}else{M=o-T,t.add(M,"hour");const k=E.LngLatHelper.roundPrecision(w.speed*M,5);g=E.LaneHelper.calculateCoordinate(c,e.bearing,k,"nauticalmiles",!m.gcToPrevious),g.eta=t.utc().format(),i[f]=g,S==null||S.debug(`[%s] go to %j from %j with ${k}nm, and cost ${M} hours`,u.requestId,{lat:g.lat,lng:g.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),C+=k,g.distanceFromPrevious=Math.round(C*1e4)/1e4,g.distanceFromStart=Math.round((n+C)*1e4)/1e4;break}}return{etd:t,from:w,to:g,next:i.filter(f=>f),wps:y,days:I,all:b}}static currentFactor(e,t,a=0){const o=E.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t,a=0){var I,b,T,C,g,w,f;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=E.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=E.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(T=t==null?void 0:t.wind)==null?void 0:T.kts);let d=l*s*u/100*(e.speed-n);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=E.LaneHelper.includedAngle(e.bearing,(g=(C=t==null?void 0:t.wave)==null?void 0:C.sig)==null?void 0:g.degree);const y=O.waveHeightFactor(((f=(w=t==null?void 0:t.wave)==null?void 0:w.sig)==null?void 0:f.height)??1,r);return S==null||S.debug("wave wx factor = %d",y),d=Math.abs(d)>Math.abs(y)?d:d*.3+y*.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)*.1:d,Math.round((d||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=v.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(v(n.etd).unix()/t)===Math.floor(v(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const d=v().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{route:y,waypoints:I}=n.points,b=E.LaneHelper.calculateSubRoute(e,y);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:T,label:C}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},g=O.assembleProperties(a,o.loadCondition,T,0),w=I.length?E.LaneHelper.calculateSubWaypoints(e,I):[];w.forEach(P=>P.important=!0);const f={from:{...e},route:b,waypoints:w,v0:T,label:C},c={hours:[],days:[],wps:[],all:[]};s||(E.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let m=E.LaneHelper.simplifyRouteToCoordinates(b,w,0),h=0,M=0,k=0,F=0;t=v(t).utc();const q=t.clone();for(;m.length>0;){const P=s-t.hour()%s,z=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,q,z,h,m,i,r,l,u);if(c.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(c.hours.push(j.from),c.wps.push(...j.wps),c.days.push(...j.days)),m=j==null?void 0:j.next,!m.length){const W=await O.speedLoseAt(g,j.to,v(j.to.eta),i,0,r,l,u);W.bearing=g.bearing,c.hours.push(W),c.all.push(W)}h+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=c.hours;for(let P=0;P<N.length-1;P++){const z=v(N[P+1].eta).diff(N[P].etd,"hour",!0)||1;M+=(N[P].wxFactor||0)*z,k+=(N[P].cFactor||0)*z,F+=z}const R=N.reduce((P,z)=>P+(z.suspend||0),0);($=c.wps)==null||$.forEach((P,z)=>{P.positionTime=v.utc(P.etd||P.eta).unix();const j=c.wps[z-1];if(j){const W=P.distanceFromStart-j.distanceFromStart,Y=v(P.eta||P.etd).diff(v(j.etd||j.eta),"h",!0);P.avgSpd=Math.round(W/Y*100)/100,j.bearing=E.LaneHelper.calculateBearing(j,P)}}),c.wps=await O.reduceWPS(c.wps),c.days=await O.reduceDays(c.days),c.all=(tt=c.all)==null?void 0:tt.reduce((P,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),P.some(j=>Math.round(j.positionTime/60)===Math.round(z.positionTime/60))||P.push(z),P),[]),f.sample=c;const L=c.hours.at(0),H=c.hours.at(-1);f.distance=Math.round(H.distanceFromStart*1e3)/1e3,f.etd=v(L.eta).utc().format(),f.eta=v(H.eta).utc().format(),f.wxFactor=Math.round(M/F*1e3)/1e3,f.cFactor=Math.round(k/F*1e3)/1e3,f.avgSpeed=Math.round(H.distanceFromStart/F*1e3)/1e3,f.totalHrs=Math.round(F*1e3)/1e3,f.suspend=Math.round(R*1e3)/1e3;const V=E.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(f,o,u),at=E.LngLatHelper.roundPrecision(o.fo/24*(F-K),3),rt=E.LngLatHelper.roundPrecision(o.dgo/24*F+V,3);f.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},f.totalFoCons=at<0?0:at,f.totalDgoCons=rt;const nt=v().valueOf()-d,dt=((et=c==null?void 0:c.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,d=!1,y={}){var Z,$,tt,et,P,z;const I=v().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},C=O.assembleProperties(o,n.loadCondition,b,0),g=E.LaneHelper.calculateSubRoute(e,i);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const w=s.length?E.LaneHelper.calculateSubWaypoints(e,s):[];w.forEach(j=>j.important=!0);let f=E.LaneHelper.simplifyRouteToCoordinates(g,w,0),c=0,m=0,h=0,M=0;const k={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const F=t.clone();for(;f.length>0;){const j=l-t.hour()%l;let W=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const Y=await O.speedLoseInHoursStep(C,t,F,W,c,f,r,u,d,y);if(k.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(k.hours.push(Y.from),Y!=null&&Y.wps&&k.wps.push(...Y.wps),k.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||k.hours.push(Y==null?void 0:Y.to),c+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!W)break}k.wps=await O.reduceWPS(k.wps),k.days=await O.reduceDays(k.days),k.all=(et=k.all)==null?void 0:et.reduce((j,W)=>(W.positionTime=v.utc(W.etd||W.eta).unix(),j.some(Y=>Math.round(v(Y.etd).unix()/60)===Math.round(v(W.etd).unix()/60))||j.push(W),j),[]),(P=k.wps)==null||P.forEach((j,W)=>{const Y=k.wps[W-1];if(Y){const It=j.distanceFromStart-Y.distanceFromStart,kt=v(j.eta||j.etd).diff(v(Y.etd||Y.eta),"h",!0);Y.bearing=E.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/kt*100)/100}});const q=k.hours;for(let j=0;j<q.length-1;j++){const W=v(q[j+1].eta).diff(q[j].etd,"hour",!0);m+=q[j].wxFactor*W,h+=q[j].cFactor*W,M+=W}const N=q.reduce((j,W)=>j+(W.suspend||0),0),R=k.hours.at(0),L=k.hours.at(-1),H=await E.LaneHelper.calculateRangeRoute(R,L,g),V=await E.LaneHelper.calculateRangeWaypoints(R,L,g,w),B={sample:k,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(m/M*1e3)/1e3,cFactor:Math.round(h/M*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/M*1e3)/1e3,totalHrs:Math.round(M*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:L,route:H,waypoints:V,v0:b,label:T},K=E.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,y),ct=E.LngLatHelper.roundPrecision(n.fo/24*(M-st),3),nt=E.LngLatHelper.roundPrecision(n.dgo/24*M+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=v().valueOf()-I,Q=((z=k==null?void 0:k.hours)==null?void 0:z.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",y==null?void 0:y.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,o,n={}){var g,w;const i=v().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=E.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(f=>{const c=Math.ceil(r/f.speed/24);l=l<c?c:l}),l=l*1.3;const u=v.utc(e.etd).add(l??14,"day");let d=1;for(const f of a){const c=JSON.parse(JSON.stringify(o.route)),m=JSON.parse(JSON.stringify(o.waypoints)),h=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,f,c,m,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);h&&(await O.calculateCost(h,f,e,n),s.push(h),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,e.etd,u.format(),{cost:h.cost.total,hire:h.cost.hire,bunker:h.cost.bunker,distance:h.distance,hours:h.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),d++}s.sort((f,c)=>f.cost.total-c.cost.total);const y=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[y],cost:(g=y.cost)==null?void 0:g.total}),I){const f=y.cost.cp,c=I.cost.cp,m=v(y.eta),h=v(y.etd),M=m.diff(h,"days",!0);let k=Math.ceil(M/2);k=k>7?7:k<e.alterStep?e.alterStep:k;let F=2,q={combined:!1,speeds:[I],cost:(w=I.cost)==null?void 0:w.total},N;for(;k>=e.alterStep;){const R=await O.combinedAnalyse(e,t,u,[f,c],o,k,{...n,level:F});if(q.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=q,q=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),k<=e.alterStep)break;k=Math.ceil(k/2),F+=1}b.push(q),N&&b.push(N)}const C=v().valueOf()-i;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,C),b.sort((f,c)=>f.cost-c.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((c,m)=>c+m.cost.total,0),u=r.reduce((c,m)=>c+m.cost.hire,0),d=r.reduce((c,m)=>c+m.cost.bunker,0),y=r.reduce((c,m)=>c+m.distance,0),I=r.reduce((c,m)=>c+m.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:d,distance:y,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),T=b.reduce((c,m)=>c+m.cost.total,0),C=b.reduce((c,m)=>c+m.cost.hire,0),g=b.reduce((c,m)=>c+m.cost.bunker,0),w=b.reduce((c,m)=>c+m.distance,0),f=b.reduce((c,m)=>c+m.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:T,hire:C,bunker:g,distance:w,hours:f}),l<T?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(T*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var y,I;let l=v.utc(e.etd);const u={lat:e.lat,lng:e.lng},d=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),T=JSON.parse(JSON.stringify(i.route)),C=JSON.parse(JSON.stringify(i.waypoints)),g=o[n],w=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,g,T,C,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);w&&(await O.calculateCost(w,g,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:w.cost.total,hire:w.cost.hire,bunker:w.cost.bunker,distance:w.distance,hours:w.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const f=(I=(y=w==null?void 0:w.sample)==null?void 0:y.hours)==null?void 0:I.at(-1);if(f)u.lat=f.lat,u.lng=f.lng,l=v(f.eta),d.push(w),n=n?0:1;else break}return d}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,d;const o=await E.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(y=>{y.positionTime=v.utc(y.etd||y.eta).unix()});for(const y of o){n+=y.distance;const I=await E.LaneHelper.deadReckoningTime((u=y.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await E.LaneHelper.deadReckoningTime((d=y.waypoints)==null?void 0:d.at(-1),e.sample.all||e.sample.wps);y.in=I,y.out=b,y.totalHrs=E.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),y.totalDgoCons=E.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),i+=y.totalHrs,s+=y.totalDgoCons}return n=E.LngLatHelper.roundPrecision(n,3),i=E.LngLatHelper.roundPrecision(i,3),s=E.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var f,c;const a={hours:[],wps:[],days:[]},o=e.reduce((m,h)=>m+h.distance,0),n=e.reduce((m,h)=>{var M;return m+(((M=h.extend)==null?void 0:M.distanceInECA)||0)},0),i=e.reduce((m,h)=>m+h.totalHrs,0),s=e.reduce((m,h)=>{var M;return m+(((M=h.extend)==null?void 0:M.hoursInECA)||0)},0),r=e.reduce((m,h)=>{var M;return m+(((M=h.extend)==null?void 0:M.totalDgoConsInECA)||0)},0),l=e.reduce((m,h)=>m+h.wxFactor*h.totalHrs/i,0),u=e.reduce((m,h)=>m+h.cFactor*h.totalHrs/i,0),d=e.reduce((m,h)=>m+h.totalFoCons,0),y=e.reduce((m,h)=>m+h.totalDgoCons,0),I=e.reduce((m,h)=>m+h.cost.total,0),b=e.reduce((m,h)=>m+h.cost.hire,0),T=e.reduce((m,h)=>m+h.cost.bunker,0),C=[],g=[];let w;for(const m of e){g.push(...((f=m.extend)==null?void 0:f.eca)||[]);const h=m.sample.hours,M=m.sample.wps,k=m.sample.days,F=h.at(0);w&&(F.distanceFromPrevious=w.distanceFromPrevious,F.distanceFromStart=w.distanceFromStart,h.forEach((L,H)=>{H&&(L.distanceFromStart=L.distanceFromStart+w.distanceFromStart)}),M.at(0).distanceFromPrevious=w.distanceFromPrevious,M.at(0).distanceFromStart=w.distanceFromStart,M.forEach((L,H)=>{H&&(L.distanceFromStart=L.distanceFromStart+w.distanceFromStart)}),k.at(0).distanceFromPrevious=w.distanceFromPrevious,k.at(0).distanceFromStart=w.distanceFromStart,k.forEach((L,H)=>{H&&(L.distanceFromStart=L.distanceFromStart+w.distanceFromStart)})),F.cp=m.cost.cp;const q=[m.etd,m.eta],N=C.findIndex(L=>L.id===F.cp.id);N===-1?(F.cp.segment=[q],C.push(F.cp)):C[N].segment.push(q),h.forEach(L=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===L.eta))===-1&&a.hours.push(L)}),M.forEach(L=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===L.eta))===-1&&a.wps.push(L)}),k.forEach(L=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===L.eta))===-1&&a.days.push(L)});const R=(c=a.wps)==null?void 0:c.findIndex(L=>L.eta===F.eta);R===-1?a.wps.push(F):a.wps[R]=F,w=h.at(-1)}return a.wps.sort((m,h)=>v(m.etd).unix()-v(h.etd).unix()),a.wps.forEach((m,h)=>{const M=a.wps[h-1];if(M){const k=m.distanceFromStart-(M.distanceFromStart||0),F=v(m.eta||m.etd).diff(v(M.etd||M.eta),"hour",!0),q=Math.round(k/F*100)/100;m.avgSpd=q;const N=E.LaneHelper.calculateBearing(M,m);M.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(d*1e3)/1e3,totalDgoCons:Math.round(y*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(T*1e3)/1e3},extend:{cps:C,eca:g,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}D.AISImpl=G,D.AlertHelper=lt,D.AlertLevel=ut,D.HifleetImpl=Mt,D.LoadCondition=ft,D.MyShipImpl=gt,D.MyVesselImpl=pt,D.ShipxyImpl=bt,D.SpeedHelper=O,D.SpeedLabel=mt,D.VesselTag=ht,D.alertHelper=vt,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
1
+ (function(D,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],x):(D=typeof globalThis<"u"?globalThis:D||self,x(D["idm-plugin-vessel"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,x,U,v,F,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(D,x,U)=>x in D?Ct(D,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):D[x]=U;var _=(D,x,U)=>(St(D,typeof x!="symbol"?x+"":x,U),U);let M;try{M=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async checkToken(t={}){var a;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}async suggest(t,a={}){var s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const d=r.data;if(d)return{mmsi:d.mmsi,imo:Number.isNaN(d.imo)?null:Number(d.imo),callSign:d.callsign,name:d.nameEn,nameCn:d.nameCn,type:d.vesselTypeNameEn,flagName:d.flagCtry,clasz:d.classSociety,dateOfBuild:d.buildYearMonth,deadweight:d.dwt,grossTonnage:d.grt,netTonnage:d.net,teu:d.teu,length:d.length,breadth:d.width,height:d.height,draught:d.draught,speed:d.speed,passengerCapacity:d.passengercapacity,vendor:"myvessel",raw:d}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=v(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.dest,positionTime:u.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,T;const r=v();await this.checkToken(s);const l="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",u={endPoint:{lon:a.lng,lat:a.lat},maxDraught:s.draught||10,useAIModel:s.useAIModel||!1,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const d={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,d);const y=await x.post(l,d).json();if(y.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:y.message,status:y.status,code:y.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:w,tracks:f,specialRegions:c,ecaLength:h}=y.data;k.nodes=g==null?void 0:g.map(p=>({code:p.nodeCode,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.lat*1e6)/1e6,lng:Math.round(p.lon*1e6)/1e6},start:{lat:Math.round(p.startLat*1e6)/1e6,lng:Math.round(p.startLon*1e6)/1e6},end:{lat:Math.round(p.endLat*1e6)/1e6,lng:Math.round(p.endLat*1e6)/1e6},isKey:p.isKeyNode,isHub:p.isHubNode})),k.seas=w==null?void 0:w.map(p=>({code:p.mrgidSea,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.centerLat*1e6)/1e6,lng:Math.round(p.centerLon*1e6)/1e6},min:{lat:Math.round(p.minLat*1e6)/1e6,lng:Math.round(p.minLon*1e6)/1e6},max:{lat:Math.round(p.maxLat*1e6)/1e6,lng:Math.round(p.maxLon*1e6)/1e6},level:p.mapLevel})),c==null||c.map(p=>{p.regionLength&&k.regions.push({type:p.regionType,distance:p.regionLength,rows:p.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=f==null?void 0:f.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(T=k.waypoints)!=null&&T.length&&(k.waypoints=F.LaneHelper.simplifyCoordinates(k.waypoints),k.route=F.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=F.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=h);const C=v().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,d,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,d,s),d}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,T,k,g,w;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(T=this.token)==null?void 0:T.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const d=await x.post(l,u).json();if(d.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:d.message,status:d.status,code:d.code}),d;let y=-1;const I=v(`${(g=(k=d.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(w=d.data)==null||w.forEach(f=>{for(const q in f)!isNaN(f[q])&&Number(f[q])!==1/0&&(f[q]=Number(f[q]));const c=v(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),h=f.status,{labelCn:m,labelEn:C}=this.parseStatus(h),p={mmsi:f.mmsi,imo:n==null?void 0:n.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:h,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,destination:f.dest,positionTime:c.unix(),labelCn:m,labelEn:C,method:"trajectory",vendor:"myVessel",utc:c.utc().format()},L=Math.floor(c.diff(I,"minute",!0)/(i||1));L!==y&&(y=L,s.push(p))}),s}}class Mt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:u}=this.parseStatus(r),d=v(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:d.unix(),utc:d.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let i=await x.post(o,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},i=await x.post(o,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var f,c,h;const r=await this.realTimePosition(t,s);let l=v(a);const u=v(o),d=v();if(i){let m=u.diff(l,"d",!0);m<0?l=u.clone().subtract(40,"d"):m<30?l.subtract(10,"d"):m<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),m=d.diff(u,"d",!0),u.add(m>10?240:m*24,"h")}const y={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,y).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,y);let T;b&&(T=((c=(f=b.ships)==null?void 0:f.offors)==null?void 0:c.ship)||[],T.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let g=-1;const w=v(`${(h=T==null?void 0:T[0])==null?void 0:h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const m of T){for(const R in m)!isNaN(m[R])&&Number(m[R])!==1/0&&(m[R]=Number(m[R]));const C=v(`${m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");m.status=m.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(m.status),q={mmsi:m.m,name:m.n,imo:r==null?void 0:r.imo,lat:m.la,lng:m.lo,draught:m.draught,sog:m.sp,cog:m.co,hdg:m.hdg,positionTime:C.unix(),utc:C.utc().format(),status:m.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(w,"minute",!0)/(n||1));N!==g&&(g=N,k.push(q))}return k}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=v.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var w;const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(d,y).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,d,y),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,T=[],k=v.unix((w=b[0])==null?void 0:w.utc);let g=-1;for(const f of b){const c=v.unix(f.utc),h={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:c.unix(),utc:c.utc().format(),method:"trajectory",vendor:"shipxy"},m=Math.floor(c.diff(k,"minute",!0)/(n||1));m!==g&&(g=m,T.push(h))}return T}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:d}=await this.parseStatus(l.aisNavStatus),y=v.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:y.utc().format(),status:l.aisNavStatus,labelEn:d,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=v(a),l=v(o),u=await this.getShipId(t),d=await this.getShipInfo(u),y=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),d,t,n,y);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),d,t,n,y),y}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},d="https://api3.myships.com/sp/ships/position/history",y=await x.post(d,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,d,u),y.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,y),y;const I=y.data;for(const g in I)!isNaN(I[g])&&Number(I[g])!==1/0&&(I[g]=Number(I[g]));const b=v.unix((k=I[0])==null?void 0:k.posTime);let T=-1;for(const g of I){const w=v.unix(g.posTime),f={imo:n==null?void 0:n.imo,mmsi:i,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"myship"},c=Math.floor(w.diff(b,"minute",!0)/(s||1));c!==T&&(T=c,r.push(f))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const d=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!d)i.scope=n[0];else if(d)for(let y=0,I=d.length;y<I;y++){const b=this.parseRule(d[y]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,T,k,g,w,f,c,h,m,C,p,L,q,N,R;let o=0,n=0,i=0,s=0;const r=Math.round(((T=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:T.number)*1.6*100)/100,l=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,u=(f=(w=t==null?void 0:t.HEAVY)==null?void 0:w.sigWave)==null?void 0:f.number,d=Math.round((((h=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:h.number)+2)*100)/100,y=(C=(m=t==null?void 0:t.SEVERE)==null?void 0:m.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let E=0;E<(e==null?void 0:e.length);E++){const H=e[E],V=(N=(q=H==null?void 0:H.meteo)==null?void 0:q.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=E?v(H.eta).diff(v(e[E-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=u&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I}),(B==null?void 0:B.scale)>=d?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>y?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===I&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),o+=H.isDangerous?K:0,n+=H.isSevere?K:0,i+=H.isHeavy?K:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const vt=new lt;let S;try{S=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ht||{}),ft=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(ft||{}),mt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(mt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var y;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";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=F.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:b,marineModels:T}=await ot.Meteo2Assist.autoPickMeteoModel(o),k=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:b,marineModels:T}),[g]=ot.Meteo2Assist.pickHourly(k,a);u=ot.Meteo2Assist.toLegacy(g)}catch(b){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},b)}const d=O.currentFactor(e.bearing,u==null?void 0:u.current,n),y=O.weatherFactor(e,u,d),I=Math.round((e.speed*1.943844+y+d)*100)/100;l={meteo:{...u},wxFactor:y,cFactor:d,speed:t.velocity&&s?t.velocity:I<0?1:I,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const d=t.clone().add(14,"days"),y=[],I=[],b=[];let T=0,k=0,g,w;for(let f=0;f<i.length-1;f++){let c=i[f];c.distanceFromStart=Math.round((n+k)*1e3)/1e3;const h=i[f+1];if(e.bearing=F.LaneHelper.calculateBearing(c,h,!h.gcToPrevious),c.bearing=e.bearing,c.suspend&&l){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const p=c.suspend-c.elapsed;if(o-T>p)o=o-T-p,t.add(p,"hour"),c.elapsed=c.suspend;else{const L=o-T;c.elapsed+=L,t.add(L,"hour"),o=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`,u.requestId,c),o===0)return c.distanceFromPrevious=k,{etd:t,from:w||c,to:c,next:i.filter(L=>L),wps:y,days:I,all:b}}else c.suspend=0;r=t.isAfter(d)?!1:r,c=await O.speedLoseAt(e,c,t,s,0,r,l,u),b.push(c),w=w||c,c.important&&y.push(c),t.isSameOrAfter(a)&&(I.push(c),a.add(24,"hour"));const m=F.LaneHelper.calculateDistance(c,h,!h.gcToPrevious);let C=Math.round(m/w.speed*1e5)/1e5;if(T+C<o){if(T+=C,t.add(C,"hour"),delete i[f],S==null||S.debug(`[%s] go to %j from %j with ${m}nm, and cost ${C} hours`,u.requestId,{lat:h.lat,lng:h.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),k+=m,i.filter(p=>p).length<=1){g=h,g.eta=t.utc().format(),g.distanceFromPrevious=m,g.distanceFromStart=Math.round((n+k)*1e4)/1e4,y.push(g),b.push(g),delete i[f+1];break}}else{C=o-T,t.add(C,"hour");const p=F.LngLatHelper.roundPrecision(w.speed*C,5);g=F.LaneHelper.calculateCoordinate(c,e.bearing,p,"nauticalmiles",!h.gcToPrevious),g.eta=t.utc().format(),i[f]=g,S==null||S.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.requestId,{lat:g.lat,lng:g.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),k+=p,g.distanceFromPrevious=Math.round(k*1e4)/1e4,g.distanceFromStart=Math.round((n+k)*1e4)/1e4;break}}return{etd:t,from:w,to:g,next:i.filter(f=>f),wps:y,days:I,all:b}}static currentFactor(e,t,a=0){const o=F.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t,a=0){var I,b,T,k,g,w,f;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=F.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=F.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(T=t==null?void 0:t.wind)==null?void 0:T.kts);let d=l*s*u/100*(e.speed-n);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=F.LaneHelper.includedAngle(e.bearing,(g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.degree);const y=O.waveHeightFactor(((f=(w=t==null?void 0:t.wave)==null?void 0:w.sig)==null?void 0:f.height)??1,r);return S==null||S.debug("wave wx factor = %d",y),d=Math.abs(d)>Math.abs(y)?d:d*.3+y*.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)*.1:d,Math.round((d||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=v.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(v(n.etd).unix()/t)===Math.floor(v(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const d=v().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{route:y,waypoints:I}=n.points,b=F.LaneHelper.calculateSubRoute(e,y);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:T,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},g=O.assembleProperties(a,o.loadCondition,T,0),w=I.length?F.LaneHelper.calculateSubWaypoints(e,I):[];w.forEach(P=>P.important=!0);const f={from:{...e},route:b,waypoints:w,v0:T,label:k},c={hours:[],days:[],wps:[],all:[]};s||(F.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let h=F.LaneHelper.simplifyRouteToCoordinates(b,w,0),m=0,C=0,p=0,L=0;t=v(t).utc();const q=t.clone();for(;h.length>0;){const P=s-t.hour()%s,z=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,q,z,m,h,i,r,l,u);if(c.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(c.hours.push(j.from),c.wps.push(...j.wps),c.days.push(...j.days)),h=j==null?void 0:j.next,!h.length){const W=await O.speedLoseAt(g,j.to,v(j.to.eta),i,0,r,l,u);W.bearing=g.bearing,c.hours.push(W),c.all.push(W)}m+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=c.hours;for(let P=0;P<N.length-1;P++){const z=v(N[P+1].eta).diff(N[P].etd,"hour",!0)||1;C+=(N[P].wxFactor||0)*z,p+=(N[P].cFactor||0)*z,L+=z}const R=N.reduce((P,z)=>P+(z.suspend||0),0);($=c.wps)==null||$.forEach((P,z)=>{P.positionTime=v.utc(P.etd||P.eta).unix();const j=c.wps[z-1];if(j){const W=P.distanceFromStart-j.distanceFromStart,Y=v(P.eta||P.etd).diff(v(j.etd||j.eta),"h",!0);P.avgSpd=Math.round(W/Y*100)/100,j.bearing=F.LaneHelper.calculateBearing(j,P)}}),c.wps=await O.reduceWPS(c.wps),c.days=await O.reduceDays(c.days),c.all=(tt=c.all)==null?void 0:tt.reduce((P,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),P.some(j=>Math.round(j.positionTime/60)===Math.round(z.positionTime/60))||P.push(z),P),[]),f.sample=c;const E=c.hours.at(0),H=c.hours.at(-1);f.distance=Math.round(H.distanceFromStart*1e3)/1e3,f.etd=v(E.eta).utc().format(),f.eta=v(H.eta).utc().format(),f.wxFactor=Math.round(C/L*1e3)/1e3,f.cFactor=Math.round(p/L*1e3)/1e3,f.avgSpeed=Math.round(H.distanceFromStart/L*1e3)/1e3,f.totalHrs=Math.round(L*1e3)/1e3,f.suspend=Math.round(R*1e3)/1e3;const V=F.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(f,o,u),at=F.LngLatHelper.roundPrecision(o.fo/24*(L-K),3),rt=F.LngLatHelper.roundPrecision(o.dgo/24*L+V,3);f.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},f.totalFoCons=at<0?0:at,f.totalDgoCons=rt;const nt=v().valueOf()-d,dt=((et=c==null?void 0:c.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,d=!1,y={}){var Z,$,tt,et,P,z;const I=v().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},k=O.assembleProperties(o,n.loadCondition,b,0),g=F.LaneHelper.calculateSubRoute(e,i);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const w=s.length?F.LaneHelper.calculateSubWaypoints(e,s):[];w.forEach(j=>j.important=!0);let f=F.LaneHelper.simplifyRouteToCoordinates(g,w,0),c=0,h=0,m=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const L=t.clone();for(;f.length>0;){const j=l-t.hour()%l;let W=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const Y=await O.speedLoseInHoursStep(k,t,L,W,c,f,r,u,d,y);if(p.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(p.hours.push(Y.from),Y!=null&&Y.wps&&p.wps.push(...Y.wps),p.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||p.hours.push(Y==null?void 0:Y.to),c+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!W)break}p.wps=await O.reduceWPS(p.wps),p.days=await O.reduceDays(p.days),p.all=(et=p.all)==null?void 0:et.reduce((j,W)=>(W.positionTime=v.utc(W.etd||W.eta).unix(),j.some(Y=>Math.round(v(Y.etd).unix()/60)===Math.round(v(W.etd).unix()/60))||j.push(W),j),[]),(P=p.wps)==null||P.forEach((j,W)=>{const Y=p.wps[W-1];if(Y){const It=j.distanceFromStart-Y.distanceFromStart,kt=v(j.eta||j.etd).diff(v(Y.etd||Y.eta),"h",!0);Y.bearing=F.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/kt*100)/100}});const q=p.hours;for(let j=0;j<q.length-1;j++){const W=v(q[j+1].eta).diff(q[j].etd,"hour",!0);h+=q[j].wxFactor*W,m+=q[j].cFactor*W,C+=W}const N=q.reduce((j,W)=>j+(W.suspend||0),0),R=p.hours.at(0),E=p.hours.at(-1),H=await F.LaneHelper.calculateRangeRoute(R,E,g),V=await F.LaneHelper.calculateRangeWaypoints(R,E,g,w),B={sample:p,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(h/C*1e3)/1e3,cFactor:Math.round(m/C*1e3)/1e3,avgSpeed:Math.round(((E==null?void 0:E.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:E,route:H,waypoints:V,v0:b,label:T},K=F.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,y),ct=F.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=F.LngLatHelper.roundPrecision(n.dgo/24*C+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=v().valueOf()-I,Q=((z=p==null?void 0:p.hours)==null?void 0:z.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",y==null?void 0:y.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,o,n={}){var g,w;const i=v().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=F.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(f=>{const c=Math.ceil(r/f.speed/24);l=l<c?c:l}),l=l*1.3;const u=v.utc(e.etd).add(l??14,"day");let d=1;for(const f of a){const c=JSON.parse(JSON.stringify(o.route)),h=JSON.parse(JSON.stringify(o.waypoints)),m=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,f,c,h,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);m&&(await O.calculateCost(m,f,e,n),s.push(m),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,e.etd,u.format(),{cost:m.cost.total,hire:m.cost.hire,bunker:m.cost.bunker,distance:m.distance,hours:m.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),d++}s.sort((f,c)=>f.cost.total-c.cost.total);const y=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[y],cost:(g=y.cost)==null?void 0:g.total}),I){const f=y.cost.cp,c=I.cost.cp,h=v(y.eta),m=v(y.etd),C=h.diff(m,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,q={combined:!1,speeds:[I],cost:(w=I.cost)==null?void 0:w.total},N;for(;p>=e.alterStep;){const R=await O.combinedAnalyse(e,t,u,[f,c],o,p,{...n,level:L});if(q.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=q,q=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(q),N&&b.push(N)}const k=v().valueOf()-i;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),b.sort((f,c)=>f.cost-c.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((c,h)=>c+h.cost.total,0),u=r.reduce((c,h)=>c+h.cost.hire,0),d=r.reduce((c,h)=>c+h.cost.bunker,0),y=r.reduce((c,h)=>c+h.distance,0),I=r.reduce((c,h)=>c+h.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:d,distance:y,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),T=b.reduce((c,h)=>c+h.cost.total,0),k=b.reduce((c,h)=>c+h.cost.hire,0),g=b.reduce((c,h)=>c+h.cost.bunker,0),w=b.reduce((c,h)=>c+h.distance,0),f=b.reduce((c,h)=>c+h.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:T,hire:k,bunker:g,distance:w,hours:f}),l<T?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(T*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var y,I;let l=v.utc(e.etd);const u={lat:e.lat,lng:e.lng},d=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),T=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),g=o[n],w=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,g,T,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);w&&(await O.calculateCost(w,g,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:w.cost.total,hire:w.cost.hire,bunker:w.cost.bunker,distance:w.distance,hours:w.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const f=(I=(y=w==null?void 0:w.sample)==null?void 0:y.hours)==null?void 0:I.at(-1);if(f)u.lat=f.lat,u.lng=f.lng,l=v(f.eta),d.push(w),n=n?0:1;else break}return d}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,d;const o=await F.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(y=>{y.positionTime=v.utc(y.etd||y.eta).unix()});for(const y of o){n+=y.distance;const I=await F.LaneHelper.deadReckoningTime((u=y.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await F.LaneHelper.deadReckoningTime((d=y.waypoints)==null?void 0:d.at(-1),e.sample.all||e.sample.wps);y.in=I,y.out=b,y.totalHrs=F.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),y.totalDgoCons=F.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),i+=y.totalHrs,s+=y.totalDgoCons}return n=F.LngLatHelper.roundPrecision(n,3),i=F.LngLatHelper.roundPrecision(i,3),s=F.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var f,c;const a={hours:[],wps:[],days:[]},o=e.reduce((h,m)=>h+m.distance,0),n=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((h,m)=>h+m.totalHrs,0),s=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((h,m)=>h+m.wxFactor*m.totalHrs/i,0),u=e.reduce((h,m)=>h+m.cFactor*m.totalHrs/i,0),d=e.reduce((h,m)=>h+m.totalFoCons,0),y=e.reduce((h,m)=>h+m.totalDgoCons,0),I=e.reduce((h,m)=>h+m.cost.total,0),b=e.reduce((h,m)=>h+m.cost.hire,0),T=e.reduce((h,m)=>h+m.cost.bunker,0),k=[],g=[];let w;for(const h of e){g.push(...((f=h.extend)==null?void 0:f.eca)||[]);const m=h.sample.hours,C=h.sample.wps,p=h.sample.days,L=m.at(0);w&&(L.distanceFromPrevious=w.distanceFromPrevious,L.distanceFromStart=w.distanceFromStart,m.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)}),C.at(0).distanceFromPrevious=w.distanceFromPrevious,C.at(0).distanceFromStart=w.distanceFromStart,C.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)}),p.at(0).distanceFromPrevious=w.distanceFromPrevious,p.at(0).distanceFromStart=w.distanceFromStart,p.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)})),L.cp=h.cost.cp;const q=[h.etd,h.eta],N=k.findIndex(E=>E.id===L.cp.id);N===-1?(L.cp.segment=[q],k.push(L.cp)):k[N].segment.push(q),m.forEach(E=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.hours.push(E)}),C.forEach(E=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.wps.push(E)}),p.forEach(E=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.days.push(E)});const R=(c=a.wps)==null?void 0:c.findIndex(E=>E.eta===L.eta);R===-1?a.wps.push(L):a.wps[R]=L,w=m.at(-1)}return a.wps.sort((h,m)=>v(h.etd).unix()-v(m.etd).unix()),a.wps.forEach((h,m)=>{const C=a.wps[m-1];if(C){const p=h.distanceFromStart-(C.distanceFromStart||0),L=v(h.eta||h.etd).diff(v(C.etd||C.eta),"hour",!0),q=Math.round(p/L*100)/100;h.avgSpd=q;const N=F.LaneHelper.calculateBearing(C,h);C.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(d*1e3)/1e3,totalDgoCons:Math.round(y*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(T*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}D.AISImpl=G,D.AlertHelper=lt,D.AlertLevel=ut,D.HifleetImpl=Mt,D.LoadCondition=ft,D.MyShipImpl=gt,D.MyVesselImpl=pt,D.ShipxyImpl=bt,D.SpeedHelper=O,D.SpeedLabel=mt,D.VesselTag=ht,D.alertHelper=vt,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "3.5.0",
4
+ "version": "3.5.1",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [