@idm-plugin/vessel 3.3.9 → 3.4.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
@@ -4,7 +4,7 @@ var U = (E, s, t) => (lt(E, typeof s != "symbol" ? s + "" : s, t), t);
4
4
  import V from "got";
5
5
  import ct from "@log4js-node/log4js-api";
6
6
  import p from "moment";
7
- import { LngLatHelper as z, LaneHelper as L } from "@idm-plugin/geo2";
7
+ import { LngLatHelper as z, LaneHelper as W } from "@idm-plugin/geo2";
8
8
  import { MeteoHelper2 as mt } from "@idm-plugin/meteo2";
9
9
  import { Meteo2Assist as it } from "@idm-plugin/meteo";
10
10
  let f;
@@ -120,11 +120,11 @@ class Ft extends st {
120
120
  * @param options
121
121
  */
122
122
  async search(t, a = {}) {
123
- var d, h;
123
+ var u, h;
124
124
  await this.checkToken(a);
125
125
  const i = /^\d{7}$/.test(t.toString()), n = i ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", o = i ? { imo: t } : { mmsi: t }, e = {
126
126
  headers: {
127
- Authorization: `${(d = this.token) == null ? void 0 : d.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
127
+ Authorization: `${(u = this.token) == null ? void 0 : u.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
128
128
  },
129
129
  searchParams: o
130
130
  };
@@ -133,30 +133,30 @@ class Ft extends st {
133
133
  if (c.status !== 200)
134
134
  return f == null || f.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: c.message, status: c.status, code: c.code }), {};
135
135
  {
136
- const u = c.data;
137
- if (u)
136
+ const d = c.data;
137
+ if (d)
138
138
  return {
139
- mmsi: u.mmsi,
140
- imo: Number.isNaN(u.imo) ? null : Number(u.imo),
141
- callSign: u.callsign,
142
- name: u.nameEn,
143
- nameCn: u.nameCn,
144
- type: u.vesselTypeNameEn,
145
- flagName: u.flagCtry,
146
- clasz: u.classSociety,
147
- dateOfBuild: u.buildYearMonth,
148
- deadweight: u.dwt,
149
- grossTonnage: u.grt,
150
- netTonnage: u.net,
151
- teu: u.teu,
152
- length: u.length,
153
- breadth: u.width,
154
- height: u.height,
155
- draught: u.draught,
156
- speed: u.speed,
157
- passengerCapacity: u.passengercapacity,
139
+ mmsi: d.mmsi,
140
+ imo: Number.isNaN(d.imo) ? null : Number(d.imo),
141
+ callSign: d.callsign,
142
+ name: d.nameEn,
143
+ nameCn: d.nameCn,
144
+ type: d.vesselTypeNameEn,
145
+ flagName: d.flagCtry,
146
+ clasz: d.classSociety,
147
+ dateOfBuild: d.buildYearMonth,
148
+ deadweight: d.dwt,
149
+ grossTonnage: d.grt,
150
+ netTonnage: d.net,
151
+ teu: d.teu,
152
+ length: d.length,
153
+ breadth: d.width,
154
+ height: d.height,
155
+ draught: d.draught,
156
+ speed: d.speed,
157
+ passengerCapacity: d.passengercapacity,
158
158
  vendor: "myvessel",
159
- raw: u
159
+ raw: d
160
160
  };
161
161
  }
162
162
  return {};
@@ -177,11 +177,11 @@ class Ft extends st {
177
177
  return o.status !== 200 ? (f == null || f.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), {}) : o.data;
178
178
  }
179
179
  async realTimePosition(t, a = {}) {
180
- var c, d;
180
+ var c, u;
181
181
  await this.checkToken(a);
182
182
  const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
183
183
  headers: {
184
- Authorization: `${(c = this.token) == null ? void 0 : c.tokenType} ${(d = this.token) == null ? void 0 : d.accessToken}`
184
+ Authorization: `${(c = this.token) == null ? void 0 : c.tokenType} ${(u = this.token) == null ? void 0 : u.accessToken}`
185
185
  },
186
186
  searchParams: { mmsi: t }
187
187
  };
@@ -229,11 +229,11 @@ class Ft extends st {
229
229
  return {};
230
230
  }
231
231
  async calculateRoute(t, a, i = {}) {
232
- var c, d;
232
+ var c, u;
233
233
  await this.checkToken(i);
234
234
  const n = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", o = {
235
235
  headers: {
236
- Authorization: `${(c = this.token) == null ? void 0 : c.tokenType} ${(d = this.token) == null ? void 0 : d.accessToken}`
236
+ Authorization: `${(c = this.token) == null ? void 0 : c.tokenType} ${(u = this.token) == null ? void 0 : u.accessToken}`
237
237
  },
238
238
  json: {
239
239
  startPoint: {
@@ -255,14 +255,14 @@ class Ft extends st {
255
255
  }
256
256
  async trajectory(t, a, i, n, o = !0, e = {}) {
257
257
  await this.checkToken(e);
258
- const c = await this.realTimePosition(t, e), d = p(a), h = p(i), u = [];
259
- for (; h.diff(d, "day", !0) > 30; )
260
- await this.trajectoryIn30Day(t, d, d.clone().add(30, "day"), c, n, u, e), d.add(30, "day");
261
- return await this.trajectoryIn30Day(t, d, h, c, n, u, e), u;
258
+ const c = await this.realTimePosition(t, e), u = p(a), h = p(i), d = [];
259
+ for (; h.diff(u, "day", !0) > 30; )
260
+ await this.trajectoryIn30Day(t, u, u.clone().add(30, "day"), c, n, d, e), u.add(30, "day");
261
+ return await this.trajectoryIn30Day(t, u, h, c, n, d, e), d;
262
262
  }
263
263
  async trajectoryIn30Day(t, a, i, n, o, e, c = {}) {
264
264
  var M, j, I, w, g;
265
- const d = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
265
+ const u = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
266
266
  headers: {
267
267
  Authorization: `${(M = this.token) == null ? void 0 : M.tokenType} ${(j = this.token) == null ? void 0 : j.accessToken}`
268
268
  },
@@ -272,13 +272,13 @@ class Ft extends st {
272
272
  endTime: i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
273
273
  }
274
274
  };
275
- f == null || f.info("[%s] fetch trajectory from: %s - %j", c.requestId, d, h);
276
- const u = await V.post(d, h).json();
277
- if (u.code)
278
- return f == null || f.warn("[%s] fetch trajectory failed: %j", c.requestId, d, { message: u.message, status: u.status, code: u.code }), u;
275
+ f == null || f.info("[%s] fetch trajectory from: %s - %j", c.requestId, u, h);
276
+ const d = await V.post(u, h).json();
277
+ if (d.code)
278
+ return f == null || f.warn("[%s] fetch trajectory failed: %j", c.requestId, u, { message: d.message, status: d.status, code: d.code }), d;
279
279
  let y = -1;
280
- const v = p(`${(w = (I = u.data) == null ? void 0 : I[0]) == null ? void 0 : w.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
281
- return (g = u.data) == null || g.forEach((r) => {
280
+ const v = p(`${(w = (I = d.data) == null ? void 0 : I[0]) == null ? void 0 : w.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
281
+ return (g = d.data) == null || g.forEach((r) => {
282
282
  for (const P in r)
283
283
  !isNaN(r[P]) && Number(r[P]) !== 1 / 0 && (r[P] = Number(r[P]));
284
284
  const b = p(`${r.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), m = r.status, { labelCn: l, labelEn: k } = this.parseStatus(m), S = {
@@ -324,7 +324,7 @@ class Et extends st {
324
324
  for (const v in e)
325
325
  !isNaN(e[v]) && Number(e[v]) !== 1 / 0 && (e[v] = Number(e[v]));
326
326
  e.status = e.sp > 3 ? 0 : 1;
327
- const c = e.status, { labelCn: d, labelEn: h } = this.parseStatus(c), u = p(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
327
+ const c = e.status, { labelCn: u, labelEn: h } = this.parseStatus(c), d = p(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
328
328
  return {
329
329
  mmsi: e.m,
330
330
  name: e.n,
@@ -345,10 +345,10 @@ class Et extends st {
345
345
  dwt: e.dwt,
346
346
  build: e.buildyear,
347
347
  flag: e.fn,
348
- positionTime: u.unix(),
349
- utc: u.utc().format(),
348
+ positionTime: d.unix(),
349
+ utc: d.utc().format(),
350
350
  status: c,
351
- labelCn: d,
351
+ labelCn: u,
352
352
  labelEn: h,
353
353
  method: "position",
354
354
  vendor: "hifleet"
@@ -403,21 +403,21 @@ class Et extends st {
403
403
  imo: !c.imo || isNaN(c.imo) ? null : Number(c.imo),
404
404
  score: c._score
405
405
  });
406
- return e.sort((c, d) => d.score - c.score), e;
406
+ return e.sort((c, u) => u.score - c.score), e;
407
407
  }
408
408
  async trajectory(t, a, i, n, o = !0, e = {}) {
409
409
  var r, b, m;
410
410
  const c = await this.realTimePosition(t, e);
411
- let d = p(a);
412
- const h = p(i), u = p();
411
+ let u = p(a);
412
+ const h = p(i), d = p();
413
413
  if (o) {
414
- let l = h.diff(d, "d", !0);
415
- l < 0 ? d = h.clone().subtract(40, "d") : l < 30 ? d.subtract(10, "d") : l < 60 ? d.subtract(5, "d") : d = h.clone().subtract(80, "d"), l = u.diff(h, "d", !0), h.add(l > 10 ? 240 : l * 24, "h");
414
+ let l = h.diff(u, "d", !0);
415
+ l < 0 ? u = h.clone().subtract(40, "d") : l < 30 ? u.subtract(10, "d") : l < 60 ? u.subtract(5, "d") : u = h.clone().subtract(80, "d"), l = d.diff(h, "d", !0), h.add(l > 10 ? 240 : l * 24, "h");
416
416
  }
417
417
  const y = {
418
418
  searchParams: {
419
419
  endtime: h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
420
- starttime: d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
420
+ starttime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
421
421
  mmsi: t,
422
422
  usertoken: this.token
423
423
  }
@@ -475,7 +475,7 @@ class Nt extends st {
475
475
  const e = o.data[0];
476
476
  for (const y in e)
477
477
  !isNaN(e[y]) && Number(e[y]) !== 1 / 0 && (e[y] = Number(e[y]));
478
- const { labelCn: c, labelEn: d } = await this.parseStatus(e.navistat), h = p.unix(e.lasttime);
478
+ const { labelCn: c, labelEn: u } = await this.parseStatus(e.navistat), h = p.unix(e.lasttime);
479
479
  return {
480
480
  mmsi: e.ShipID,
481
481
  name: e.name,
@@ -493,7 +493,7 @@ class Nt extends st {
493
493
  positionTime: e.lasttime,
494
494
  utc: h.utc().format(),
495
495
  status: e.navistat,
496
- labelEn: d,
496
+ labelEn: u,
497
497
  labelCn: c,
498
498
  method: "position",
499
499
  vendor: "shipxy"
@@ -501,17 +501,17 @@ class Nt extends st {
501
501
  }
502
502
  async trajectory(t, a, i, n, o = !0, e = {}) {
503
503
  var g;
504
- const c = await this.realTimePosition(t, e), d = p(a), h = p(i), u = "https://api.shipxy.com/apicall/GetShipTrack", y = {
504
+ const c = await this.realTimePosition(t, e), u = p(a), h = p(i), d = "https://api.shipxy.com/apicall/GetShipTrack", y = {
505
505
  searchParams: {
506
506
  id: t,
507
507
  k: this.token,
508
508
  enc: 1,
509
509
  cut: 0,
510
- btm: d.unix(),
510
+ btm: u.unix(),
511
511
  etm: h.unix()
512
512
  }
513
- }, v = await V.get(u, y).json();
514
- if (f == null || f.info("[%s] fetch trajectory from: %s - %j", e.requestId, u, y), (v == null ? void 0 : v.status) !== 0)
513
+ }, v = await V.get(d, y).json();
514
+ if (f == null || f.info("[%s] fetch trajectory from: %s - %j", e.requestId, d, y), (v == null ? void 0 : v.status) !== 0)
515
515
  return v;
516
516
  const M = v == null ? void 0 : v.points, j = [], I = p.unix((g = M[0]) == null ? void 0 : g.utc);
517
517
  let w = -1;
@@ -583,35 +583,35 @@ class Tt extends st {
583
583
  }
584
584
  }, e = "https://api3.myships.com/sp/ships/position/latest", c = await V.post(e, o).json();
585
585
  f == null || f.info("[%s] fetch realtime position from: %s - %j", a.requestId, e, o);
586
- const d = c.data[0];
587
- for (const M in d)
588
- !isNaN(d[M]) && Number(d[M]) !== 1 / 0 && (d[M] = Number(d[M]));
589
- const { labelCn: h, labelEn: u } = await this.parseStatus(d.aisNavStatus), y = p.unix(d.posTime);
586
+ const u = c.data[0];
587
+ for (const M in u)
588
+ !isNaN(u[M]) && Number(u[M]) !== 1 / 0 && (u[M] = Number(u[M]));
589
+ const { labelCn: h, labelEn: d } = await this.parseStatus(u.aisNavStatus), y = p.unix(u.posTime);
590
590
  return {
591
591
  ...n,
592
592
  mmsi: t,
593
- lat: Math.round(d.lat / 1e4 / 60 * 1e5) / 1e5,
594
- lng: Math.round(d.lon / 1e4 / 60 * 1e5) / 1e5,
595
- sog: Math.round(d.sog / 10 * 100) / 100,
596
- cog: Math.round(d.cog / 10 * 100) / 100,
597
- hdg: Math.round(d.heading * 100) / 100,
598
- rot: Math.round(d.rot * 100) / 100,
599
- positionTime: d.posTime,
593
+ lat: Math.round(u.lat / 1e4 / 60 * 1e5) / 1e5,
594
+ lng: Math.round(u.lon / 1e4 / 60 * 1e5) / 1e5,
595
+ sog: Math.round(u.sog / 10 * 100) / 100,
596
+ cog: Math.round(u.cog / 10 * 100) / 100,
597
+ hdg: Math.round(u.heading * 100) / 100,
598
+ rot: Math.round(u.rot * 100) / 100,
599
+ positionTime: u.posTime,
600
600
  utc: y.utc().format(),
601
- status: d.aisNavStatus,
602
- labelEn: u,
601
+ status: u.aisNavStatus,
602
+ labelEn: d,
603
603
  labelCn: h,
604
604
  method: "position",
605
605
  vendor: "myship"
606
606
  };
607
607
  }
608
608
  async trajectory(t, a, i, n, o = !0, e = {}) {
609
- const c = p(a), d = p(i), h = await this.getShipId(t), u = await this.getShipInfo(h), y = [];
610
- for (; d.diff(c, "day", !0) > 30; )
611
- await this.trajectoryIn30Day(h, c.unix(), c.add(30, "day").unix(), u, t, n, y);
612
- return await this.trajectoryIn30Day(h, c.unix(), d.unix(), u, t, n, y), y;
609
+ const c = p(a), u = p(i), h = await this.getShipId(t), d = await this.getShipInfo(h), y = [];
610
+ for (; u.diff(c, "day", !0) > 30; )
611
+ await this.trajectoryIn30Day(h, c.unix(), c.add(30, "day").unix(), d, t, n, y);
612
+ return await this.trajectoryIn30Day(h, c.unix(), u.unix(), d, t, n, y), y;
613
613
  }
614
- async trajectoryIn30Day(t, a, i, n, o, e, c, d = {}) {
614
+ async trajectoryIn30Day(t, a, i, n, o, e, c, u = {}) {
615
615
  var I;
616
616
  const h = {
617
617
  headers: {
@@ -622,9 +622,9 @@ class Tt extends st {
622
622
  startTime: a,
623
623
  endTime: i
624
624
  }
625
- }, u = "https://api3.myships.com/sp/ships/position/history", y = await V.post(u, h).json();
626
- if (f == null || f.info("[%s] fetch trajectory from: %s - %j", d.requestId, u, h), y.code !== "0")
627
- return f == null || f.warn("[%s] invoke myship trajectory failed: %j", d.requestId, y), y;
625
+ }, d = "https://api3.myships.com/sp/ships/position/history", y = await V.post(d, h).json();
626
+ if (f == null || f.info("[%s] fetch trajectory from: %s - %j", u.requestId, d, h), y.code !== "0")
627
+ return f == null || f.warn("[%s] invoke myship trajectory failed: %j", u.requestId, y), y;
628
628
  const v = y.data;
629
629
  for (const w in v)
630
630
  !isNaN(v[w]) && Number(v[w]) !== 1 / 0 && (v[w] = Number(v[w]));
@@ -667,19 +667,19 @@ class yt {
667
667
  * @param options
668
668
  */
669
669
  parsePrinciple(s, t = {}) {
670
- var e, c, d;
670
+ var e, c, u;
671
671
  _ == null || _.debug("[%s] parse rule: %s", t.requestId, s);
672
672
  const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = s.match(a) ? (e = s.match(a)) == null ? void 0 : e[0] : void 0, n = i == null ? void 0 : i.split(";");
673
673
  if (!n)
674
674
  return;
675
675
  const o = {};
676
676
  for (let h = 0; h < (n == null ? void 0 : n.length); h++) {
677
- const u = (d = (c = n[h].match(a)) == null ? void 0 : c[0]) == null ? void 0 : d.split("],");
678
- if (h === 0 && !u)
677
+ const d = (u = (c = n[h].match(a)) == null ? void 0 : c[0]) == null ? void 0 : u.split("],");
678
+ if (h === 0 && !d)
679
679
  o.scope = n[0];
680
- else if (u)
681
- for (let y = 0, v = u.length; y < v; y++) {
682
- const M = this.parseRule(u[y]);
680
+ else if (d)
681
+ for (let y = 0, v = d.length; y < v; y++) {
682
+ const M = this.parseRule(d[y]);
683
683
  M && (o[M.level] ? M.key ? o[M.level][M == null ? void 0 : M.key] = M : o[M.level] = M : M.key ? o[M.level] = { [M == null ? void 0 : M.key]: M } : o[M.level] = M);
684
684
  }
685
685
  }
@@ -715,12 +715,12 @@ class yt {
715
715
  checkWeather(s, t, a = {}) {
716
716
  var M, j, I, w, g, r, b, m, l, k, S, D, P, N, A;
717
717
  let i = 0, n = 0, o = 0, e = 0;
718
- const c = Math.round(((j = (M = t == null ? void 0 : t.SEVERE) == null ? void 0 : M.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, d = (w = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : w.number, h = (r = (g = t == null ? void 0 : t.HEAVY) == null ? void 0 : g.sigWave) == null ? void 0 : r.number, u = Math.round((((m = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.wind) == null ? void 0 : m.number) + 2) * 100) / 100, y = (k = (l = t == null ? void 0 : t.SEVERE) == null ? void 0 : l.wind) == null ? void 0 : k.number, v = (D = (S = t == null ? void 0 : t.HEAVY) == null ? void 0 : S.wind) == null ? void 0 : D.number;
718
+ const c = Math.round(((j = (M = t == null ? void 0 : t.SEVERE) == null ? void 0 : M.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, u = (w = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : w.number, h = (r = (g = t == null ? void 0 : t.HEAVY) == null ? void 0 : g.sigWave) == null ? void 0 : r.number, d = Math.round((((m = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.wind) == null ? void 0 : m.number) + 2) * 100) / 100, y = (k = (l = t == null ? void 0 : t.SEVERE) == null ? void 0 : l.wind) == null ? void 0 : k.number, v = (D = (S = t == null ? void 0 : t.HEAVY) == null ? void 0 : S.wind) == null ? void 0 : D.number;
719
719
  for (let x = 0; x < (s == null ? void 0 : s.length); x++) {
720
720
  const T = s[x], q = (N = (P = T == null ? void 0 : T.meteo) == null ? void 0 : P.wave) == null ? void 0 : N.sig, R = (A = T == null ? void 0 : T.meteo) == null ? void 0 : A.wind, J = x ? p(T.eta).diff(p(s[x - 1].eta), "hour", !0) : 0;
721
- e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...q, dgThd4Wv: c, svThd4Wv: d, hvThd4Wv: h }), (q == null ? void 0 : q.height) >= c ? T.isDangerous = !0 : (q == null ? void 0 : q.height) >= d ? T.isSevere = !0 : (q == null ? void 0 : q.height) >= h && (T.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: u, svThd4Wd: y, hvThd4Wd: v }), (R == null ? void 0 : R.scale) >= u ? (T.isDangerous = !0, delete T.isSevere, delete T.isHeavy) : (R == null ? void 0 : R.scale) > y ? (T.isDangerous || (T.isSevere = !0), delete T.isHeavy) : (R == null ? void 0 : R.scale) === v && !T.isDangerous && !T.isSevere && (T.isHeavy = !0), i += T.isDangerous ? J : 0, n += T.isSevere ? J : 0, o += T.isHeavy ? J : 0;
721
+ e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...q, dgThd4Wv: c, svThd4Wv: u, hvThd4Wv: h }), (q == null ? void 0 : q.height) >= c ? T.isDangerous = !0 : (q == null ? void 0 : q.height) >= u ? T.isSevere = !0 : (q == null ? void 0 : q.height) >= h && (T.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: v }), (R == null ? void 0 : R.scale) >= d ? (T.isDangerous = !0, delete T.isSevere, delete T.isHeavy) : (R == null ? void 0 : R.scale) > y ? (T.isDangerous || (T.isSevere = !0), delete T.isHeavy) : (R == null ? void 0 : R.scale) === v && !T.isDangerous && !T.isSevere && (T.isHeavy = !0), i += T.isDangerous ? J : 0, n += T.isSevere ? J : 0, o += T.isHeavy ? J : 0;
722
722
  }
723
- return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, e = Math.round(e), { sample: s, dangerous: i, severe: n, heavy: o, step: e < 3 ? 3 : e, wind: { dgThd4Wd: u, svThd4Wd: y, hvThd4Wd: v }, sig: { dgThd4Wv: c, svThd4Wv: d, hvThd4Wv: h } };
723
+ return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, e = Math.round(e), { sample: s, dangerous: i, severe: n, heavy: o, step: e < 3 ? 3 : e, wind: { dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: v }, sig: { dgThd4Wv: c, svThd4Wv: u, hvThd4Wv: h } };
724
724
  }
725
725
  }
726
726
  const xt = new yt();
@@ -846,9 +846,9 @@ class O {
846
846
  */
847
847
  static assembleProperties(s, t, a, i) {
848
848
  var y;
849
- const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, o = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, c = s.deadweight ?? 67035.7773, d = ((y = s == null ? void 0 : s.type) == null ? void 0 : y.toLowerCase()) || "common";
849
+ const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, o = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, c = s.deadweight ?? 67035.7773, u = ((y = s == null ? void 0 : s.type) == null ? void 0 : y.toLowerCase()) || "common";
850
850
  return {
851
- tag: d.indexOf("container") > -1 ? "container" : d.indexOf("tugs") > -1 ? "tugs" : "common",
851
+ tag: u.indexOf("container") > -1 ? "container" : u.indexOf("tugs") > -1 ? "tugs" : "common",
852
852
  lbp: n,
853
853
  loadCondition: t,
854
854
  draught: o,
@@ -873,7 +873,7 @@ class O {
873
873
  * @param options
874
874
  */
875
875
  static async speedLoseAt(s, t, a, i = "", n = 2, o = !0, e = !1, c = {}) {
876
- let d;
876
+ let u;
877
877
  if (t.velocity && e && (s.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
878
878
  let h;
879
879
  try {
@@ -889,24 +889,24 @@ class O {
889
889
  } catch (M) {
890
890
  C.warn("[%s] meteo2 spot(%j) forecast failed: %s", c.requestId, { ...t, eta: a.utc().format(), source: i }, M);
891
891
  }
892
- const u = O.currentFactor(s.bearing, h == null ? void 0 : h.current, n), y = O.weatherFactor(s, h, u), v = Math.round(s.speed * 1.943844 * 100) / 100;
893
- d = {
892
+ const d = O.currentFactor(s.bearing, h == null ? void 0 : h.current, n), y = O.weatherFactor(s, h, d), v = Math.round((s.speed * 1.943844 + y + d) * 100) / 100;
893
+ u = {
894
894
  meteo: { ...h },
895
895
  wxFactor: y,
896
- cFactor: u,
896
+ cFactor: d,
897
897
  speed: t.velocity && e ? t.velocity : v < 0 ? 1 : v,
898
898
  eta: a.utc().format(),
899
899
  etd: a.utc().format()
900
900
  };
901
901
  } else
902
- d = {
902
+ u = {
903
903
  wxFactor: 0,
904
904
  cFactor: 0,
905
905
  speed: t.velocity && e ? t.velocity : Math.round(s.speed * 1.943844 * 100) / 100,
906
906
  eta: a.utc().format(),
907
907
  etd: a.utc().format()
908
908
  };
909
- return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...d, ...t };
909
+ return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...u, ...t };
910
910
  }
911
911
  /**
912
912
  * 基于步长计算失速样本
@@ -922,15 +922,15 @@ class O {
922
922
  * @param options
923
923
  * @private
924
924
  */
925
- static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", c = !0, d = !1, h = {}) {
925
+ static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", c = !0, u = !1, h = {}) {
926
926
  t.utc();
927
- const u = t.clone().add(14, "days"), y = [], v = [];
927
+ const d = t.clone().add(14, "days"), y = [], v = [];
928
928
  let M = 0, j = 0, I, w;
929
929
  for (let g = 0; g < o.length - 1; g++) {
930
930
  let r = o[g];
931
931
  r.distanceFromStart = Math.round((n + j) * 1e3) / 1e3;
932
932
  const b = o[g + 1];
933
- if (s.bearing = L.calculateBearing(r, b, !b.gcToPrevious), r.bearing = s.bearing, r.suspend && d) {
933
+ if (s.bearing = W.calculateBearing(r, b, !b.gcToPrevious), r.bearing = s.bearing, r.suspend && u) {
934
934
  r.eta = r.eta || t.utc().format(), r.elapsed = r.elapsed ?? 0;
935
935
  const k = r.suspend - r.elapsed;
936
936
  if (i - M > k)
@@ -943,8 +943,8 @@ class O {
943
943
  return r.distanceFromPrevious = j, { etd: t, from: w || r, to: r, next: o.filter((S) => S), wps: y, days: v };
944
944
  } else
945
945
  r.suspend = 0;
946
- c = t.isAfter(u) ? !1 : c, r = await O.speedLoseAt(s, r, t, e, 0, c, d, h), w = w || r, r.important && y.push(r), t.isSameOrAfter(a) && (v.push(r), a.add(24, "hour"));
947
- const m = L.calculateDistance(r, b, !b.gcToPrevious);
946
+ c = t.isAfter(d) ? !1 : c, r = await O.speedLoseAt(s, r, t, e, 0, c, u, h), w = w || r, r.important && y.push(r), t.isSameOrAfter(a) && (v.push(r), a.add(24, "hour"));
947
+ const m = W.calculateDistance(r, b, !b.gcToPrevious);
948
948
  let l = Math.round(m / w.speed * 1e5) / 1e5;
949
949
  if (M + l < i) {
950
950
  if (M += l, t.add(l, "hour"), delete o[g], C == null || C.debug(
@@ -959,7 +959,7 @@ class O {
959
959
  } else {
960
960
  l = i - M, t.add(l, "hour");
961
961
  const k = z.roundPrecision(w.speed * l, 5);
962
- I = L.calculateCoordinate(r, s.bearing, k, "nauticalmiles", !b.gcToPrevious), I.eta = t.utc().format(), o[g] = I, C == null || C.debug(
962
+ I = W.calculateCoordinate(r, s.bearing, k, "nauticalmiles", !b.gcToPrevious), I.eta = t.utc().format(), o[g] = I, C == null || C.debug(
963
963
  `[%s] go to %j from %j with ${k}nm, and cost ${l} hours`,
964
964
  h.requestId,
965
965
  { lat: I.lat, lng: I.lng },
@@ -995,11 +995,11 @@ class O {
995
995
  const i = O.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = O.froudeNumber(s.speed - n, s.lbp), e = O.amendFactor(i, o, s.loadCondition);
996
996
  let c = Math.abs(s.bearing % 360 - (((v = t == null ? void 0 : t.wind) == null ? void 0 : v.degree) % 360 || 0));
997
997
  c = c > 180 ? 360 - c : c;
998
- const d = O.directionFactor(c, (M = t == null ? void 0 : t.wind) == null ? void 0 : M.scale), h = O.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (j = t == null ? void 0 : t.wind) == null ? void 0 : j.kts);
999
- let u = d * e * h / 100 * (s.speed - n);
1000
- u = Math.round(u * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(u) > 1 && (u = u / (Math.abs(Math.round(u)) + 1)), C == null || C.debug("wind wx factor = %d", u), c = Math.abs(s.bearing % 360 - (((w = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : w.degree) % 360 || 0)), c = c > 180 ? 360 - c : c;
998
+ const u = O.directionFactor(c, (M = t == null ? void 0 : t.wind) == null ? void 0 : M.scale), h = O.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (j = t == null ? void 0 : t.wind) == null ? void 0 : j.kts);
999
+ let d = u * e * h / 100 * (s.speed - n);
1000
+ d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), C == null || C.debug("wind wx factor = %d", d), c = Math.abs(s.bearing % 360 - (((w = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : w.degree) % 360 || 0)), c = c > 180 ? 360 - c : c;
1001
1001
  const y = O.waveHeightFactor(((r = (g = t == null ? void 0 : t.wave) == null ? void 0 : g.sig) == null ? void 0 : r.height) ?? 1, c);
1002
- return C == null || C.debug("wave wx factor = %d", y), u = Math.abs(u) > Math.abs(y) ? u : u * 0.3 + y * 0.7, C == null || C.debug("weather factor = %d", u), u = Math.abs(u) > 3 ? 3 * (Math.abs(u) / u) + Math.abs(u) / u * (Math.abs(u) - 2) * 0.1 : u, Math.round((u || 0) * 100) / 100;
1002
+ return C == null || C.debug("wave wx factor = %d", y), d = Math.abs(d) > Math.abs(y) ? d : d * 0.3 + y * 0.7, C == null || C.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;
1003
1003
  }
1004
1004
  /**
1005
1005
  * 全程失速分析(走完航程)
@@ -1014,11 +1014,11 @@ class O {
1014
1014
  * @param useRouteParam
1015
1015
  * @param options
1016
1016
  */
1017
- static async analyseInstant(s, t, a, i, n, o = "", e = 0, c = !0, d = !1, h = {}) {
1017
+ static async analyseInstant(s, t, a, i, n, o = "", e = 0, c = !0, u = !1, h = {}) {
1018
1018
  var K, G, X, Q, Z, $;
1019
- const u = p().valueOf();
1019
+ const d = p().valueOf();
1020
1020
  s.lng = z.convertToStdLng(s.lng);
1021
- const { route: y, waypoints: v } = n.points, M = L.calculateSubRoute(s, y);
1021
+ const { route: y, waypoints: v } = n.points, M = W.calculateSubRoute(s, y);
1022
1022
  if (((K = M[0]) == null ? void 0 : K.length) <= 1)
1023
1023
  return;
1024
1024
  const { v0: j, label: I } = s.sog ? {
@@ -1029,7 +1029,7 @@ class O {
1029
1029
  v0: i.speed,
1030
1030
  label: "CP"
1031
1031
  /* Cp */
1032
- }, w = O.assembleProperties(a, i.loadCondition, j, 0), g = v.length ? L.calculateSubWaypoints(s, v) : [];
1032
+ }, w = O.assembleProperties(a, i.loadCondition, j, 0), g = v.length ? W.calculateSubWaypoints(s, v) : [];
1033
1033
  g.forEach((Y) => Y.important = !0);
1034
1034
  const r = {
1035
1035
  from: { ...s },
@@ -1042,8 +1042,8 @@ class O {
1042
1042
  days: [],
1043
1043
  wps: []
1044
1044
  };
1045
- e || (L.calculateRouteDistance(M) / i.speed <= 72 ? e = 3 : e = 6);
1046
- let m = L.simplifyRouteToCoordinates(M, g, 0), l = 0, k = 0, S = 0, D = 0;
1045
+ e || (W.calculateRouteDistance(M) / i.speed <= 72 ? e = 3 : e = 6);
1046
+ let m = W.simplifyRouteToCoordinates(M, g, 0), l = 0, k = 0, S = 0, D = 0;
1047
1047
  t = p(t).utc();
1048
1048
  const P = t.clone();
1049
1049
  for (; m.length > 0; ) {
@@ -1056,12 +1056,12 @@ class O {
1056
1056
  m,
1057
1057
  o,
1058
1058
  c,
1059
- d,
1059
+ u,
1060
1060
  h
1061
1061
  );
1062
1062
  if ((G = F.from) != null && G.speed && (b.hours.push(F.from), b.wps.push(...F.wps), b.days.push(...F.days)), m = F == null ? void 0 : F.next, !m.length) {
1063
- const W = await O.speedLoseAt(w, F.to, p(F.to.eta), o, 0, c, d, h);
1064
- b.hours.push(W);
1063
+ const L = await O.speedLoseAt(w, F.to, p(F.to.eta), o, 0, c, u, h);
1064
+ L.bearing = w.bearing, b.hours.push(L);
1065
1065
  }
1066
1066
  l += Math.round((((X = F == null ? void 0 : F.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1067
1067
  }
@@ -1074,8 +1074,8 @@ class O {
1074
1074
  Y.positionTime = p.utc(Y.etd || Y.eta).unix();
1075
1075
  const F = b.wps[B - 1];
1076
1076
  if (F) {
1077
- const W = Y.distanceFromStart - F.distanceFromStart, H = p(Y.eta || Y.etd).diff(p(F.etd || F.eta), "h", !0);
1078
- Y.avgSpd = Math.round(W / H * 100) / 100, F.bearing = L.calculateBearing(F, Y);
1077
+ const L = Y.distanceFromStart - F.distanceFromStart, H = p(Y.eta || Y.etd).diff(p(F.etd || F.eta), "h", !0);
1078
+ Y.avgSpd = Math.round(L / H * 100) / 100, F.bearing = W.calculateBearing(F, Y);
1079
1079
  }
1080
1080
  }), b.wps = (Z = b.wps) == null ? void 0 : Z.reduce((Y, B) => (Y.some((F) => Math.round(F.positionTime / 60) === Math.round(B.positionTime / 60)) || Y.push(B), Y), []), r.sample = b;
1081
1081
  const A = b.hours.at(0), x = b.hours.at(-1);
@@ -1087,7 +1087,7 @@ class O {
1087
1087
  hoursInECA: q,
1088
1088
  totalDgoConsInECA: R
1089
1089
  }, r.totalFoCons = tt < 0 ? 0 : tt, r.totalDgoCons = at;
1090
- const et = p().valueOf() - u, ot = (($ = b == null ? void 0 : b.hours) == null ? void 0 : $.length) || 1;
1090
+ const et = p().valueOf() - d, ot = (($ = b == null ? void 0 : b.hours) == null ? void 0 : $.length) || 1;
1091
1091
  return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, et, ot, Math.round(et / ot * 1e3) / 1e3), r;
1092
1092
  }
1093
1093
  /**
@@ -1105,7 +1105,7 @@ class O {
1105
1105
  * @param useRouteParam
1106
1106
  * @param options
1107
1107
  */
1108
- static async analyseInstantWithThreshed(s, t, a, i, n, o, e, c = "", d = 3, h = !0, u = !1, y = {}) {
1108
+ static async analyseInstantWithThreshed(s, t, a, i, n, o, e, c = "", u = 3, h = !0, d = !1, y = {}) {
1109
1109
  var X, Q, Z, $, Y, B;
1110
1110
  const v = p().valueOf();
1111
1111
  s.lng = z.convertToStdLng(s.lng);
@@ -1117,12 +1117,12 @@ class O {
1117
1117
  v0: n.speed,
1118
1118
  label: "CP"
1119
1119
  /* Cp */
1120
- }, I = O.assembleProperties(i, n.loadCondition, M, 0), w = L.calculateSubRoute(s, o);
1120
+ }, I = O.assembleProperties(i, n.loadCondition, M, 0), w = W.calculateSubRoute(s, o);
1121
1121
  if (((X = w[0]) == null ? void 0 : X.length) <= 1)
1122
1122
  return;
1123
- const g = e.length ? L.calculateSubWaypoints(s, e) : [];
1123
+ const g = e.length ? W.calculateSubWaypoints(s, e) : [];
1124
1124
  g.forEach((F) => F.important = !0);
1125
- let r = L.simplifyRouteToCoordinates(w, g, 0), b = 0, m = 0, l = 0, k = 0;
1125
+ let r = W.simplifyRouteToCoordinates(w, g, 0), b = 0, m = 0, l = 0, k = 0;
1126
1126
  const S = {
1127
1127
  hours: [],
1128
1128
  wps: [],
@@ -1131,28 +1131,28 @@ class O {
1131
1131
  t = p(t).utc();
1132
1132
  const D = t.clone();
1133
1133
  for (; r.length > 0; ) {
1134
- const F = d - t.hour() % d;
1135
- let W = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1136
- W = t.clone().add(W, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : W;
1137
- const H = await O.speedLoseInHoursStep(I, t, D, W, b, r, c, h, u, y);
1138
- if ((Q = H.from) != null && Q.speed && (S.hours.push(H.from), H != null && H.wps && S.wps.push(...H.wps), S.days.push(...H.days)), r = H == null ? void 0 : H.next, r.length || S.hours.push(H == null ? void 0 : H.to), b += Math.round((((Z = H == null ? void 0 : H.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !W)
1134
+ const F = u - t.hour() % u;
1135
+ let L = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1136
+ L = t.clone().add(L, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : L;
1137
+ const H = await O.speedLoseInHoursStep(I, t, D, L, b, r, c, h, d, y);
1138
+ if ((Q = H.from) != null && Q.speed && (S.hours.push(H.from), H != null && H.wps && S.wps.push(...H.wps), S.days.push(...H.days)), r = H == null ? void 0 : H.next, r.length || S.hours.push(H == null ? void 0 : H.to), b += Math.round((((Z = H == null ? void 0 : H.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
1139
1139
  break;
1140
1140
  }
1141
- S.wps = ($ = S.wps) == null ? void 0 : $.reduce((F, W) => (F.some((H) => Math.round(p(H.etd).unix() / 60) === Math.round(p(W.etd).unix() / 60)) || F.push(W), F), []), (Y = S.wps) == null || Y.forEach((F, W) => {
1142
- const H = S.wps[W - 1];
1141
+ S.wps = ($ = S.wps) == null ? void 0 : $.reduce((F, L) => (F.some((H) => Math.round(p(H.etd).unix() / 60) === Math.round(p(L.etd).unix() / 60)) || F.push(L), F), []), (Y = S.wps) == null || Y.forEach((F, L) => {
1142
+ const H = S.wps[L - 1];
1143
1143
  if (H) {
1144
1144
  const rt = F.distanceFromStart - H.distanceFromStart, dt = p(F.eta || F.etd).diff(p(H.etd || H.eta), "h", !0);
1145
1145
  F.avgSpd = Math.round(rt / dt * 100) / 100;
1146
- const ut = L.calculateBearing(H, F);
1146
+ const ut = W.calculateBearing(H, F);
1147
1147
  H.bearing = ut;
1148
1148
  }
1149
1149
  });
1150
1150
  const P = S.hours;
1151
1151
  for (let F = 0; F < P.length - 1; F++) {
1152
- const W = p(P[F + 1].eta).diff(P[F].etd, "hour", !0);
1153
- m += P[F].wxFactor * W, l += P[F].cFactor * W, k += W;
1152
+ const L = p(P[F + 1].eta).diff(P[F].etd, "hour", !0);
1153
+ m += P[F].wxFactor * L, l += P[F].cFactor * L, k += L;
1154
1154
  }
1155
- const N = S.hours.at(0), A = S.hours.at(-1), x = await L.calculateRangeRoute(N, A, w), T = await L.calculateRangeWaypoints(N, A, w, g), q = {
1155
+ const N = S.hours.at(0), A = S.hours.at(-1), x = await W.calculateRangeRoute(N, A, w), T = await W.calculateRangeWaypoints(N, A, w, g), q = {
1156
1156
  sample: S,
1157
1157
  distance: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) * 1e4) / 1e4,
1158
1158
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
@@ -1197,14 +1197,14 @@ class O {
1197
1197
  var w, g;
1198
1198
  const o = p().valueOf(), e = [];
1199
1199
  s.speedStep = s.speedStep || 3, s.alterStep = s.alterStep ?? 1;
1200
- const c = L.calculateRouteDistance(i.route);
1201
- let d = 0;
1200
+ const c = W.calculateRouteDistance(i.route);
1201
+ let u = 0;
1202
1202
  a.forEach((r) => {
1203
1203
  const b = Math.ceil(c / r.speed / 24);
1204
- d = d < b ? b : d;
1205
- }), d = d * 1.3;
1206
- const h = p.utc(s.etd).add(d ?? 14, "day");
1207
- let u = 1;
1204
+ u = u < b ? b : u;
1205
+ }), u = u * 1.3;
1206
+ const h = p.utc(s.etd).add(u ?? 14, "day");
1207
+ let d = 1;
1208
1208
  for (const r of a) {
1209
1209
  const b = JSON.parse(JSON.stringify(i.route)), m = JSON.parse(JSON.stringify(i.waypoints)), l = await O.analyseInstantWithThreshed(
1210
1210
  { lat: s.lat, lng: s.lng },
@@ -1220,14 +1220,14 @@ class O {
1220
1220
  s.useRouteParam,
1221
1221
  n
1222
1222
  );
1223
- l && (await O.calculateCost(l, r, s, n), e.push(l), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, u, s.etd, h.format(), {
1223
+ l && (await O.calculateCost(l, r, s, n), e.push(l), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, d, s.etd, h.format(), {
1224
1224
  cost: l.cost.total,
1225
1225
  hire: l.cost.hire,
1226
1226
  bunker: l.cost.bunker,
1227
1227
  distance: l.distance,
1228
1228
  hours: l.totalHrs,
1229
1229
  cp: `${r.speed}/${r.fo}/${r.dgo}`
1230
- })), u++;
1230
+ })), d++;
1231
1231
  }
1232
1232
  e.sort((r, b) => r.cost.total - b.cost.total);
1233
1233
  const y = e.at(0), v = e.at(1), M = [];
@@ -1259,11 +1259,11 @@ class O {
1259
1259
  */
1260
1260
  static async combinedAnalyse(s, t, a, i, n, o, e = {}) {
1261
1261
  e.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", e.requestId, e.level, o);
1262
- const c = await O.alternateAnalyse(s, t, a, i, 0, n, o, e), d = c.reduce((b, m) => b + m.cost.total, 0), h = c.reduce((b, m) => b + m.cost.hire, 0), u = c.reduce((b, m) => b + m.cost.bunker, 0), y = c.reduce((b, m) => b + m.distance, 0), v = c.reduce((b, m) => b + m.totalHrs, 0);
1262
+ const c = await O.alternateAnalyse(s, t, a, i, 0, n, o, e), u = c.reduce((b, m) => b + m.cost.total, 0), h = c.reduce((b, m) => b + m.cost.hire, 0), d = c.reduce((b, m) => b + m.cost.bunker, 0), y = c.reduce((b, m) => b + m.distance, 0), v = c.reduce((b, m) => b + m.totalHrs, 0);
1263
1263
  C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j", e.requestId, e.level, {
1264
- cost: d,
1264
+ cost: u,
1265
1265
  hire: h,
1266
- bunker: u,
1266
+ bunker: d,
1267
1267
  distance: y,
1268
1268
  hours: v
1269
1269
  });
@@ -1274,7 +1274,7 @@ class O {
1274
1274
  bunker: w,
1275
1275
  distance: g,
1276
1276
  hours: r
1277
- }), d < j ? { combined: !0, cost: Math.round(d * 1e3) / 1e3, speeds: c, step: o } : { combined: !0, cost: Math.round(j * 1e3) / 1e3, speeds: M, step: o };
1277
+ }), u < j ? { combined: !0, cost: Math.round(u * 1e3) / 1e3, speeds: c, step: o } : { combined: !0, cost: Math.round(j * 1e3) / 1e3, speeds: M, step: o };
1278
1278
  }
1279
1279
  /**
1280
1280
  * 基于cp索引,交替计算指定步长下的成本
@@ -1289,12 +1289,12 @@ class O {
1289
1289
  */
1290
1290
  static async alternateAnalyse(s, t, a, i, n, o, e, c = {}) {
1291
1291
  var y, v;
1292
- let d = p.utc(s.etd);
1293
- const h = { lat: s.lat, lng: s.lng }, u = [];
1294
- for (; d.isBefore(a); ) {
1295
- const M = d.clone().utc().add(e, "day"), j = JSON.parse(JSON.stringify(o.route)), I = JSON.parse(JSON.stringify(o.waypoints)), w = i[n], g = await O.analyseInstantWithThreshed(
1292
+ let u = p.utc(s.etd);
1293
+ const h = { lat: s.lat, lng: s.lng }, d = [];
1294
+ for (; u.isBefore(a); ) {
1295
+ const M = u.clone().utc().add(e, "day"), j = JSON.parse(JSON.stringify(o.route)), I = JSON.parse(JSON.stringify(o.waypoints)), w = i[n], g = await O.analyseInstantWithThreshed(
1296
1296
  h,
1297
- d.utc().format(),
1297
+ u.utc().format(),
1298
1298
  M,
1299
1299
  t,
1300
1300
  w,
@@ -1311,7 +1311,7 @@ class O {
1311
1311
  c.requestId,
1312
1312
  c.level,
1313
1313
  c.counter,
1314
- d.utc().format(),
1314
+ u.utc().format(),
1315
1315
  M.utc().format(),
1316
1316
  {
1317
1317
  cost: g.cost.total,
@@ -1324,11 +1324,11 @@ class O {
1324
1324
  )), c.counter = c.counter + 1;
1325
1325
  const r = (v = (y = g == null ? void 0 : g.sample) == null ? void 0 : y.hours) == null ? void 0 : v.at(-1);
1326
1326
  if (r)
1327
- h.lat = r.lat, h.lng = r.lng, d = p(r.eta), u.push(g), n = n ? 0 : 1;
1327
+ h.lat = r.lat, h.lng = r.lng, u = p(r.eta), d.push(g), n = n ? 0 : 1;
1328
1328
  else
1329
1329
  break;
1330
1330
  }
1331
- return u;
1331
+ return d;
1332
1332
  }
1333
1333
  /**
1334
1334
  * 计算Speed的cost
@@ -1340,11 +1340,11 @@ class O {
1340
1340
  static async calculateCost(s, t, a, i = {}) {
1341
1341
  var n;
1342
1342
  if (s) {
1343
- const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3, c = Math.round(s.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, d = Math.round((s.totalDgoCons + (((n = s.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
1343
+ const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round(s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3, c = Math.round(s.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, u = Math.round((s.totalDgoCons + (((n = s.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
1344
1344
  s.cost = {
1345
- total: Math.round((e + c + d) * 1e3) / 1e3,
1345
+ total: Math.round((e + c + u) * 1e3) / 1e3,
1346
1346
  hire: e,
1347
- bunker: Math.round((c + d) * 1e3) / 1e3,
1347
+ bunker: Math.round((c + u) * 1e3) / 1e3,
1348
1348
  cp: t
1349
1349
  };
1350
1350
  }
@@ -1355,15 +1355,15 @@ class O {
1355
1355
  *
1356
1356
  */
1357
1357
  static async calculateECA(s, t, a = {}) {
1358
- var c, d, h, u;
1359
- const i = await L.intersectInECA((s == null ? void 0 : s.route) || []);
1358
+ var c, u, h, d;
1359
+ const i = await W.intersectInECA((s == null ? void 0 : s.route) || []);
1360
1360
  let n = 0, o = 0, e = 0;
1361
- (d = (c = s == null ? void 0 : s.sample) == null ? void 0 : c.wps) == null || d.forEach((y) => {
1361
+ (u = (c = s == null ? void 0 : s.sample) == null ? void 0 : c.wps) == null || u.forEach((y) => {
1362
1362
  y.positionTime = p.utc(y.etd || y.eta).unix();
1363
1363
  });
1364
1364
  for (const y of i) {
1365
1365
  n += y.distance;
1366
- const v = await L.deadReckoningTime((h = y.waypoints) == null ? void 0 : h.at(0), s.sample.wps), M = await L.deadReckoningTime((u = y.waypoints) == null ? void 0 : u.at(-1), s.sample.wps);
1366
+ const v = await W.deadReckoningTime((h = y.waypoints) == null ? void 0 : h.at(0), s.sample.wps), M = await W.deadReckoningTime((d = y.waypoints) == null ? void 0 : d.at(-1), s.sample.wps);
1367
1367
  y.in = v, y.out = M, y.totalHrs = z.roundPrecision((M.positionTime - v.positionTime) / 3600, 3), y.totalDgoCons = z.roundPrecision(t.fo / 24 * y.totalHrs, 3), o += y.totalHrs, e += y.totalDgoCons;
1368
1368
  }
1369
1369
  return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3), e = z.roundPrecision(e, 3), {
@@ -1393,7 +1393,7 @@ class O {
1393
1393
  }, 0), c = s.reduce((m, l) => {
1394
1394
  var k;
1395
1395
  return m + (((k = l.extend) == null ? void 0 : k.totalDgoConsInECA) || 0);
1396
- }, 0), d = s.reduce((m, l) => m + l.wxFactor * l.totalHrs / o, 0), h = s.reduce((m, l) => m + l.cFactor * l.totalHrs / o, 0), u = s.reduce((m, l) => m + l.totalFoCons, 0), y = s.reduce((m, l) => m + l.totalDgoCons, 0), v = s.reduce((m, l) => m + l.cost.total, 0), M = s.reduce((m, l) => m + l.cost.hire, 0), j = s.reduce((m, l) => m + l.cost.bunker, 0), I = [], w = [];
1396
+ }, 0), u = s.reduce((m, l) => m + l.wxFactor * l.totalHrs / o, 0), h = s.reduce((m, l) => m + l.cFactor * l.totalHrs / o, 0), d = s.reduce((m, l) => m + l.totalFoCons, 0), y = s.reduce((m, l) => m + l.totalDgoCons, 0), v = s.reduce((m, l) => m + l.cost.total, 0), M = s.reduce((m, l) => m + l.cost.hire, 0), j = s.reduce((m, l) => m + l.cost.bunker, 0), I = [], w = [];
1397
1397
  let g;
1398
1398
  for (const m of s) {
1399
1399
  w.push(...((r = m.extend) == null ? void 0 : r.eca) || []);
@@ -1426,7 +1426,7 @@ class O {
1426
1426
  if (k) {
1427
1427
  const S = m.distanceFromStart - (k.distanceFromStart || 0), D = p(m.eta || m.etd).diff(p(k.etd || k.eta), "hour", !0), P = Math.round(S / D * 100) / 100;
1428
1428
  m.avgSpd = P;
1429
- const N = L.calculateBearing(k, m);
1429
+ const N = W.calculateBearing(k, m);
1430
1430
  k.bearing = N;
1431
1431
  }
1432
1432
  }), {
@@ -1440,9 +1440,9 @@ class O {
1440
1440
  distance: Math.round(i * 1e3) / 1e3,
1441
1441
  totalHrs: Math.round(o * 1e3) / 1e3,
1442
1442
  avgSpeed: Math.round(i / o * 1e3) / 1e3,
1443
- wxFactor: Math.round(d * 1e3) / 1e3,
1443
+ wxFactor: Math.round(u * 1e3) / 1e3,
1444
1444
  cFactor: Math.round(h * 1e3) / 1e3,
1445
- totalFoCons: Math.round(u * 1e3) / 1e3,
1445
+ totalFoCons: Math.round(d * 1e3) / 1e3,
1446
1446
  totalDgoCons: Math.round(y * 1e3) / 1e3,
1447
1447
  cost: {
1448
1448
  total: Math.round(v * 1e3) / 1e3,
@@ -1 +1 @@
1
- (function(q,A){typeof exports=="object"&&typeof module<"u"?A(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"],A):(q=typeof globalThis<"u"?globalThis:q||self,A(q["idm-plugin-vessel"]={},q.got,q["@log4js-node/log4js-api"],q.moment,q["@idm-plugin/geo2"],q["@idm-plugin/meteo2"],q["@idm-plugin/meteo"]))})(this,function(q,A,U,g,N,ft,nt){"use strict";var It=Object.defineProperty;var St=(q,A,U)=>A in q?It(q,A,{enumerable:!0,configurable:!0,writable:!0,value:U}):q[A]=U;var K=(q,A,U)=>(St(q,typeof A!="symbol"?A+"":A,U),U);let m;try{m=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(s){let t,a;switch(s){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class mt extends G{constructor(t,a){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await A.post(a,i).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:g().utc().format()})}async checkToken(t={}){var a;return(!this.token||g().diff(g(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 e,r;await this.checkToken(a);const i="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.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,i,n);const o=await A.post(i,n).json();return o.status!==200?(m==null||m.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),[]):(o.data||[]).map(l=>({mmsi:l.mmsi,name:l.nameEn,nameCn:l.nameCn,imo:Number.isNaN(l.imo)?null:Number(l.imo),callSign:l.callsign,type:l.vesselTypeNameEn,flagName:l.flagCtry,vendor:"myvessel",raw:l}))}async search(t,a={}){var d,l;await this.checkToken(a);const i=/^\d{7}$/.test(t.toString()),n=i?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",o=i?{imo:t}:{mmsi:t},e={headers:{Authorization:`${(d=this.token)==null?void 0:d.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:o};m==null||m.info("[%s] fetch vessel from: %s - %j",a.requestId,n,e);const r=await A.get(n,e).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 u=r.data;if(u)return{mmsi:u.mmsi,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,name:u.nameEn,nameCn:u.nameCn,type:u.vesselTypeNameEn,flagName:u.flagCtry,clasz:u.classSociety,dateOfBuild:u.buildYearMonth,deadweight:u.dwt,grossTonnage:u.grt,netTonnage:u.net,teu:u.teu,length:u.length,breadth:u.width,height:u.height,draught:u.draught,speed:u.speed,passengerCapacity:u.passengercapacity,vendor:"myvessel",raw:u}}return{}}async archives(t,a={}){var e,r;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.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,i,n);const o=await A.post(i,n).json();return o.status!==200?(m==null||m.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),{}):o.data}async realTimePosition(t,a={}){var r,d;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},searchParams:{mmsi:t}};m==null||m.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await A.get(i,n).json();if(o.code)return m==null||m.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),o;const e=o.data;for(const l in e)!isNaN(e[l])&&Number(e[l])!==1/0&&(e[l]=Number(e[l]));if(e){const l=g(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName||e.aisVesselName,imo:e.imo,callSign:e.callsign||e.aisCallSign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?g.utc(e.eta).format():void 0,destination:e.dest,positionTime:l.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,vesselType:e.vesselTypeNameEn,flag:e.flagCtryNameEn,clasz:e.classSociety,build:e.buildYear,dwt:e.dwt,grt:e.grt,net:e.net,method:"position",vendor:"myVessel",utc:l.utc().format()}}else return{}}async calculateRoute(t,a,i={}){var r,d;await this.checkToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},json:{startPoint:{lon:t.lng,lat:t.lat},endPoint:{lon:a.lng,lat:a.lat},maxDraught:i.maxDraught||10,useAIModel:i.useAIModel||!1,withECA:i.withECA||!1}};m==null||m.info("[%s] fetch route from: %s - %j",i.requestId,n,o);const e=await A.post(n,o).json();return e.status!==200?(m==null||m.warn("[%s] fetch route failed: %j",i.requestId,{message:e.message,status:e.status,code:e.code}),{}):e.data}async trajectory(t,a,i,n,o=!0,e={}){await this.checkToken(e);const r=await this.realTimePosition(t,e),d=g(a),l=g(i),u=[];for(;l.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(t,d,d.clone().add(30,"day"),r,n,u,e),d.add(30,"day");return await this.trajectoryIn30Day(t,d,l,r,n,u,e),u}async trajectoryIn30Day(t,a,i,n,o,e,r={}){var M,C,S,w,b;const d="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(C=this.token)==null?void 0:C.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};m==null||m.info("[%s] fetch trajectory from: %s - %j",r.requestId,d,l);const u=await A.post(d,l).json();if(u.code)return m==null||m.warn("[%s] fetch trajectory failed: %j",r.requestId,d,{message:u.message,status:u.status,code:u.code}),u;let y=-1;const v=g(`${(w=(S=u.data)==null?void 0:S[0])==null?void 0:w.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(b=u.data)==null||b.forEach(c=>{for(const Y in c)!isNaN(c[Y])&&Number(c[Y])!==1/0&&(c[Y]=Number(c[Y]));const p=g(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),f=c.status,{labelCn:h,labelEn:k}=this.parseStatus(f),j={mmsi:c.mmsi,imo:n==null?void 0:n.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:f,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?g(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:p.unix(),labelCn:h,labelEn:k,method:"trajectory",vendor:"myVessel",utc:p.utc().format()},x=Math.floor(p.diff(v,"minute",!0)/(o||1));x!==y&&(y=x,e.push(j))}),e}}class yt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},o=await A.post(i,n).json();m==null||m.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const e=o==null?void 0:o.list;if(!e)return m==null||m.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const v in e)!isNaN(e[v])&&Number(e[v])!==1/0&&(e[v]=Number(e[v]));e.status=e.sp>3?0:1;const r=e.status,{labelCn:d,labelEn:l}=this.parseStatus(r),u=g(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?g.utc(e.eta).format():void 0,destination:e.destination,vesselType:e.type,dwt:e.dwt,build:e.buildyear,flag:e.fn,positionTime:u.unix(),utc:u.utc().format(),status:r,labelCn:d,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,a={}){let i="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 o=await A.post(i,n).json();m==null||m.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]);for(const r in o)!isNaN(o[r])&&Number(o[r])!==1/0&&(o[r]=Number(o[r]));const e={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await A.post(i,n).json(),m==null||m.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(e.deadweight=Number(o.dwt)),e}async suggest(t,a={}){const i="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"}},o=await A.post(i,n).json();m==null||m.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const e=[];for(const r of o)e.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 e.sort((r,d)=>d.score-r.score),e}async trajectory(t,a,i,n,o=!0,e={}){var c,p,f;const r=await this.realTimePosition(t,e);let d=g(a);const l=g(i),u=g();if(o){let h=l.diff(d,"d",!0);h<0?d=l.clone().subtract(40,"d"):h<30?d.subtract(10,"d"):h<60?d.subtract(5,"d"):d=l.clone().subtract(80,"d"),h=u.diff(l,"d",!0),l.add(h>10?240:h*24,"h")}const y={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},v="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",M=await A.get(v,y).json();m==null||m.info("[%s] fetch trajectory from: %s - %j",e.requestId,v,y);let C;M&&(C=((p=(c=M.ships)==null?void 0:c.offors)==null?void 0:p.ship)||[],C.length||m==null||m.warn("[%s] fetch trajectory failed: %j",e.requestId,M));const S=[];let w=-1;const b=g(`${(f=C==null?void 0:C[0])==null?void 0:f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const h of C){for(const L in h)!isNaN(h[L])&&Number(h[L])!==1/0&&(h[L]=Number(h[L]));const k=g(`${h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");h.status=h.sp>4?0:1;const{labelEn:j,labelCn:x}=this.parseStatus(h.status),Y={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:k.unix(),utc:k.utc().format(),status:h.status,labelCn:x,labelEn:j,method:"trajectory",vendor:"hifleet"},F=Math.floor(k.diff(b,"minute",!0)/(n||1));F!==w&&(w=F,S.push(Y))}return S}}class Mt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",o=await A.get(n,i).json();if(m==null||m.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const e=o.data[0];for(const y in e)!isNaN(e[y])&&Number(e[y])!==1/0&&(e[y]=Number(e[y]));const{labelCn:r,labelEn:d}=await this.parseStatus(e.navistat),l=g.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:l.utc().format(),status:e.navistat,labelEn:d,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,i,n,o=!0,e={}){var b;const r=await this.realTimePosition(t,e),d=g(a),l=g(i),u="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:d.unix(),etm:l.unix()}},v=await A.get(u,y).json();if(m==null||m.info("[%s] fetch trajectory from: %s - %j",e.requestId,u,y),(v==null?void 0:v.status)!==0)return v;const M=v==null?void 0:v.points,C=[],S=g.unix((b=M[0])==null?void 0:b.utc);let w=-1;for(const c of M){const p=g.unix(c.utc),f={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(c.sog*3600/1e3/1852*100)/100,cog:Math.round(c.cog/100*100)/100,lat:Math.round(c.lat/1e6*1e5)/1e5,lng:Math.round(c.lon/1e6*1e5)/1e5,positionTime:p.unix(),utc:p.utc().format(),method:"trajectory",vendor:"shipxy"},h=Math.floor(p.diff(S,"minute",!0)/(n||1));h!==w&&(w=h,C.push(f))}return C}}class pt extends G{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,a={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",o=await A.post(n,i).json();return m==null||m.info("[%s] fetch ship id from: %s - %j",a.requestId,n,i),o.code!=="0"?o:o.data[0].shipId}async getShipInfo(t,a={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",o=await A.post(n,i).json();if(m==null||m.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const e=o.data;let r=e.imo;return t==="407170"&&(r="9198379",m==null||m.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,e.imo,r)),{mmsi:e.mmsi,name:e.shipnameEn,imo:r,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,a={}){const i=await this.getShipId(t,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},e="https://api3.myships.com/sp/ships/position/latest",r=await A.post(e,o).json();m==null||m.info("[%s] fetch realtime position from: %s - %j",a.requestId,e,o);const d=r.data[0];for(const M in d)!isNaN(d[M])&&Number(d[M])!==1/0&&(d[M]=Number(d[M]));const{labelCn:l,labelEn:u}=await this.parseStatus(d.aisNavStatus),y=g.unix(d.posTime);return{...n,mmsi:t,lat:Math.round(d.lat/1e4/60*1e5)/1e5,lng:Math.round(d.lon/1e4/60*1e5)/1e5,sog:Math.round(d.sog/10*100)/100,cog:Math.round(d.cog/10*100)/100,hdg:Math.round(d.heading*100)/100,rot:Math.round(d.rot*100)/100,positionTime:d.posTime,utc:y.utc().format(),status:d.aisNavStatus,labelEn:u,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,a,i,n,o=!0,e={}){const r=g(a),d=g(i),l=await this.getShipId(t),u=await this.getShipInfo(l),y=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(l,r.unix(),r.add(30,"day").unix(),u,t,n,y);return await this.trajectoryIn30Day(l,r.unix(),d.unix(),u,t,n,y),y}async trajectoryIn30Day(t,a,i,n,o,e,r,d={}){var S;const l={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:i}},u="https://api3.myships.com/sp/ships/position/history",y=await A.post(u,l).json();if(m==null||m.info("[%s] fetch trajectory from: %s - %j",d.requestId,u,l),y.code!=="0")return m==null||m.warn("[%s] invoke myship trajectory failed: %j",d.requestId,y),y;const v=y.data;for(const w in v)!isNaN(v[w])&&Number(v[w])!==1/0&&(v[w]=Number(v[w]));const M=g.unix((S=v[0])==null?void 0:S.posTime);let C=-1;for(const w of v){const b=g.unix(w.posTime),c={imo:n==null?void 0:n.imo,mmsi:o,lat:Math.round(w.lat/1e4/60*1e5)/1e5,lng:Math.round(w.lon/1e4/60*1e5)/1e5,sog:Math.round(w.sog/10*100)/100,cog:Math.round(w.cog/10*100)/100,hdg:Math.round(w.heading*100)/100,rot:Math.round(w.rot*100)/100,positionTime:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"myship"},p=Math.floor(b.diff(M,"minute",!0)/(e||1));p!==C&&(C=p,r.push(c))}return r}}let _;try{_=U.getLogger("vessel")}catch{}finally{}var ct=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(ct||{});class dt{parsePrinciple(s,t={}){var e,r,d;_==null||_.debug("[%s] parse rule: %s",t.requestId,s);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=s.match(a)?(e=s.match(a))==null?void 0:e[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let l=0;l<(n==null?void 0:n.length);l++){const u=(d=(r=n[l].match(a))==null?void 0:r[0])==null?void 0:d.split("],");if(l===0&&!u)o.scope=n[0];else if(u)for(let y=0,v=u.length;y<v;y++){const M=this.parseRule(u[y]);M&&(o[M.level]?M.key?o[M.level][M==null?void 0:M.key]=M:o[M.level]=M:M.key?o[M.level]={[M==null?void 0:M.key]:M}:o[M.level]=M)}}return o}parseRule(s,t={}){var o;_==null||_.debug("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=s==null?void 0:s.match(a))==null?void 0:o[0],n=i==null?void 0:i.split(",");if(n){let e=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return e=isNaN(e)?1:e,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:e,key:n[4]}}}checkWeather(s,t,a={}){var M,C,S,w,b,c,p,f,h,k,j,x,Y,F,L;let i=0,n=0,o=0,e=0;const r=Math.round(((C=(M=t==null?void 0:t.SEVERE)==null?void 0:M.sigWave)==null?void 0:C.number)*1.6*100)/100,d=(w=(S=t==null?void 0:t.SEVERE)==null?void 0:S.sigWave)==null?void 0:w.number,l=(c=(b=t==null?void 0:t.HEAVY)==null?void 0:b.sigWave)==null?void 0:c.number,u=Math.round((((f=(p=t==null?void 0:t.SEVERE)==null?void 0:p.wind)==null?void 0:f.number)+2)*100)/100,y=(k=(h=t==null?void 0:t.SEVERE)==null?void 0:h.wind)==null?void 0:k.number,v=(x=(j=t==null?void 0:t.HEAVY)==null?void 0:j.wind)==null?void 0:x.number;for(let H=0;H<(s==null?void 0:s.length);H++){const E=s[H],P=(F=(Y=E==null?void 0:E.meteo)==null?void 0:Y.wave)==null?void 0:F.sig,V=(L=E==null?void 0:E.meteo)==null?void 0:L.wind,J=H?g(E.eta).diff(g(s[H-1].eta),"hour",!0):0;e=J>e?J:e,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...P,dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}),(P==null?void 0:P.height)>=r?E.isDangerous=!0:(P==null?void 0:P.height)>=d?E.isSevere=!0:(P==null?void 0:P.height)>=l&&(E.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:u,svThd4Wd:y,hvThd4Wd:v}),(V==null?void 0:V.scale)>=u?(E.isDangerous=!0,delete E.isSevere,delete E.isHeavy):(V==null?void 0:V.scale)>y?(E.isDangerous||(E.isSevere=!0),delete E.isHeavy):(V==null?void 0:V.scale)===v&&!E.isDangerous&&!E.isSevere&&(E.isHeavy=!0),i+=E.isDangerous?J:0,n+=E.isSevere?J:0,o+=E.isHeavy?J:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,e=Math.round(e),{sample:s,dangerous:i,severe:n,heavy:o,step:e<3?3:e,wind:{dgThd4Wd:u,svThd4Wd:y,hvThd4Wd:v},sig:{dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}}}}const bt=new dt;let I;try{I=U.getLogger("vessel")}catch{}finally{}const vt=new ft.MeteoHelper2("",!0);var ut=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(ut||{}),lt=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(lt||{}),ht=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ht||{});class W{static blockCoefficient(s,t,a,i){let n=Math.round(s/(t*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],e=o.map(r=>Math.abs(r-n));return o[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,a=9.8){let i=Math.round(Math.sqrt(s*s/(a*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(s,t,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return a==="Laden"&&(o=i[s]),o[0]+o[1]*t+o[2]*Math.pow(t,2)}static directionFactor(s,t=0){let a;return s>30&&s<=60?a=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?a=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(s,t,a,i){let n;return a==="container"?n=.7*i/2+Math.pow(i,3)/(22*Math.pow(s,2/3)):t==="Ballast"?n=.7*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)):n=.5*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)),n}static waveHeightFactor(s,t){s=s<3?s*.7:s,s=s<0?.2:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=s<3?.4:-.3:t>120&&t<=150?a=s<3?.6:-.5:t>150&&t<=180?a=s<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(s,2)+.278*s)*1e4)/1e4}static assembleProperties(s,t,a,i){var y;const n=s.lbp??s.length??s.lengthOverall??198.9642,o=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,r=s.deadweight??67035.7773,d=((y=s==null?void 0:s.type)==null?void 0:y.toLowerCase())||"common";return{tag:d.indexOf("container")>-1?"container":d.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:o,breadthMoulded:e,displacement:Math.round((r/1.025+o*e*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(s,t,a,i="",n=2,o=!0,e=!1,r={}){let d;if(t.velocity&&e&&(s.speed=N.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),o){let l;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:M,marineModels:C}=await nt.Meteo2Assist.autoPickMeteoModel(i),S=await vt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:M,marineModels:C}),[w]=nt.Meteo2Assist.pickHourly(S,a);l=nt.Meteo2Assist.toLegacy(w)}catch(M){I.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:i},M)}const u=W.currentFactor(s.bearing,l==null?void 0:l.current,n),y=W.weatherFactor(s,l,u),v=Math.round(s.speed*1.943844*100)/100;d={meteo:{...l},wxFactor:y,cFactor:u,speed:t.velocity&&e?t.velocity:v<0?1:v,eta:a.utc().format(),etd:a.utc().format()}}else d={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round(s.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,{...d,...t}}static async speedLoseInHoursStep(s,t,a,i,n,o,e="",r=!0,d=!1,l={}){t.utc();const u=t.clone().add(14,"days"),y=[],v=[];let M=0,C=0,S,w;for(let b=0;b<o.length-1;b++){let c=o[b];c.distanceFromStart=Math.round((n+C)*1e3)/1e3;const p=o[b+1];if(s.bearing=N.LaneHelper.calculateBearing(c,p,!p.gcToPrevious),c.bearing=s.bearing,c.suspend&&d){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const k=c.suspend-c.elapsed;if(i-M>k)i=i-M-k,t.add(k,"hour"),c.elapsed=c.suspend;else{const j=i-M;c.elapsed+=j,t.add(j,"hour"),i=0}if(I==null||I.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=C,{etd:t,from:w||c,to:c,next:o.filter(j=>j),wps:y,days:v}}else c.suspend=0;r=t.isAfter(u)?!1:r,c=await W.speedLoseAt(s,c,t,e,0,r,d,l),w=w||c,c.important&&y.push(c),t.isSameOrAfter(a)&&(v.push(c),a.add(24,"hour"));const f=N.LaneHelper.calculateDistance(c,p,!p.gcToPrevious);let h=Math.round(f/w.speed*1e5)/1e5;if(M+h<i){if(M+=h,t.add(h,"hour"),delete o[b],I==null||I.debug(`[%s] go to %j from %j with ${f}nm, and cost ${h} hours`,l.requestId,{lat:p.lat,lng:p.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),C+=f,o.filter(k=>k).length<=1){S=p,S.eta=t.utc().format(),S.distanceFromPrevious=f,S.distanceFromStart=Math.round((n+C)*1e4)/1e4,y.push(S),delete o[b+1];break}}else{h=i-M,t.add(h,"hour");const k=N.LngLatHelper.roundPrecision(w.speed*h,5);S=N.LaneHelper.calculateCoordinate(c,s.bearing,k,"nauticalmiles",!p.gcToPrevious),S.eta=t.utc().format(),o[b]=S,I==null||I.debug(`[%s] go to %j from %j with ${k}nm, and cost ${h} hours`,l.requestId,{lat:S.lat,lng:S.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),C+=k,S.distanceFromPrevious=Math.round(C*1e4)/1e4,S.distanceFromStart=Math.round((n+C)*1e4)/1e4;break}}return{etd:t,from:w,to:S,next:o.filter(b=>b),wps:y,days:v}}static currentFactor(s,t,a=0){const i=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(s,t,a=0){var v,M,C,S,w,b,c;I==null||I.debug("calculate weather factor via: %j",{...s,...t});const i=W.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=N.LngLatHelper.roundPrecision(a*1852/3600,6),o=W.froudeNumber(s.speed-n,s.lbp),e=W.amendFactor(i,o,s.loadCondition);let r=Math.abs(s.bearing%360-(((v=t==null?void 0:t.wind)==null?void 0:v.degree)%360||0));r=r>180?360-r:r;const d=W.directionFactor(r,(M=t==null?void 0:t.wind)==null?void 0:M.scale),l=W.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(C=t==null?void 0:t.wind)==null?void 0:C.kts);let u=d*e*l/100*(s.speed-n);u=Math.round(u*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(u)>1&&(u=u/(Math.abs(Math.round(u))+1)),I==null||I.debug("wind wx factor = %d",u),r=Math.abs(s.bearing%360-(((w=(S=t==null?void 0:t.wave)==null?void 0:S.sig)==null?void 0:w.degree)%360||0)),r=r>180?360-r:r;const y=W.waveHeightFactor(((c=(b=t==null?void 0:t.wave)==null?void 0:b.sig)==null?void 0:c.height)??1,r);return I==null||I.debug("wave wx factor = %d",y),u=Math.abs(u)>Math.abs(y)?u:u*.3+y*.7,I==null||I.debug("weather factor = %d",u),u=Math.abs(u)>3?3*(Math.abs(u)/u)+Math.abs(u)/u*(Math.abs(u)-2)*.1:u,Math.round((u||0)*100)/100}static async analyseInstant(s,t,a,i,n,o="",e=0,r=!0,d=!1,l={}){var X,Q,Z,$,tt,et;const u=g().valueOf();s.lng=N.LngLatHelper.convertToStdLng(s.lng);const{route:y,waypoints:v}=n.points,M=N.LaneHelper.calculateSubRoute(s,y);if(((X=M[0])==null?void 0:X.length)<=1)return;const{v0:C,label:S}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:i.speed,label:"CP"},w=W.assembleProperties(a,i.loadCondition,C,0),b=v.length?N.LaneHelper.calculateSubWaypoints(s,v):[];b.forEach(O=>O.important=!0);const c={from:{...s},route:M,waypoints:b,v0:C,label:S},p={hours:[],days:[],wps:[]};e||(N.LaneHelper.calculateRouteDistance(M)/i.speed<=72?e=3:e=6);let f=N.LaneHelper.simplifyRouteToCoordinates(M,b,0),h=0,k=0,j=0,x=0;t=g(t).utc();const Y=t.clone();for(;f.length>0;){const O=e-t.hour()%e,z=Math.ceil(t.clone().add(O,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,T=await W.speedLoseInHoursStep(w,t,Y,z,h,f,o,r,d,l);if((Q=T.from)!=null&&Q.speed&&(p.hours.push(T.from),p.wps.push(...T.wps),p.days.push(...T.days)),f=T==null?void 0:T.next,!f.length){const B=await W.speedLoseAt(w,T.to,g(T.to.eta),o,0,r,d,l);p.hours.push(B)}h+=Math.round((((Z=T==null?void 0:T.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const F=p.hours;for(let O=0;O<F.length-1;O++){const z=g(F[O+1].eta).diff(F[O].etd,"hour",!0)||1;k+=(F[O].wxFactor||0)*z,j+=(F[O].cFactor||0)*z,x+=z}($=p.wps)==null||$.forEach((O,z)=>{O.positionTime=g.utc(O.etd||O.eta).unix();const T=p.wps[z-1];if(T){const B=O.distanceFromStart-T.distanceFromStart,R=g(O.eta||O.etd).diff(g(T.etd||T.eta),"h",!0);O.avgSpd=Math.round(B/R*100)/100,T.bearing=N.LaneHelper.calculateBearing(T,O)}}),p.wps=(tt=p.wps)==null?void 0:tt.reduce((O,z)=>(O.some(T=>Math.round(T.positionTime/60)===Math.round(z.positionTime/60))||O.push(z),O),[]),c.sample=p;const L=p.hours.at(0),H=p.hours.at(-1);c.distance=Math.round(H.distanceFromStart*1e3)/1e3,c.etd=g(L.eta).utc().format(),c.eta=g(H.eta).utc().format(),c.wxFactor=Math.round(k/x*1e3)/1e3,c.cFactor=Math.round(j/x*1e3)/1e3,c.avgSpeed=Math.round(H.distanceFromStart/x*1e3)/1e3,c.totalHrs=Math.round(x*1e3)/1e3;const{distanceInECA:E,hoursInECA:P,totalDgoConsInECA:V,eca:J}=await this.calculateECA(c,i,l),st=N.LngLatHelper.roundPrecision(i.fo/24*(x-P),3),ot=N.LngLatHelper.roundPrecision(i.dgo/24*x,3);c.extend={eca:J,distanceInECA:E,hoursInECA:P,totalDgoConsInECA:V},c.totalFoCons=st<0?0:st,c.totalDgoCons=ot;const at=g().valueOf()-u,rt=((et=p==null?void 0:p.hours)==null?void 0:et.length)||1;return I==null||I.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,at,rt,Math.round(at/rt*1e3)/1e3),c}static async analyseInstantWithThreshed(s,t,a,i,n,o,e,r="",d=3,l=!0,u=!1,y={}){var Z,$,tt,et,O,z;const v=g().valueOf();s.lng=N.LngLatHelper.convertToStdLng(s.lng);const{v0:M,label:C}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:n.speed,label:"CP"},S=W.assembleProperties(i,n.loadCondition,M,0),w=N.LaneHelper.calculateSubRoute(s,o);if(((Z=w[0])==null?void 0:Z.length)<=1)return;const b=e.length?N.LaneHelper.calculateSubWaypoints(s,e):[];b.forEach(T=>T.important=!0);let c=N.LaneHelper.simplifyRouteToCoordinates(w,b,0),p=0,f=0,h=0,k=0;const j={hours:[],wps:[],days:[]};t=g(t).utc();const x=t.clone();for(;c.length>0;){const T=d-t.hour()%d;let B=Math.ceil(t.clone().add(T,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;B=t.clone().add(B,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:B;const R=await W.speedLoseInHoursStep(S,t,x,B,p,c,r,l,u,y);if(($=R.from)!=null&&$.speed&&(j.hours.push(R.from),R!=null&&R.wps&&j.wps.push(...R.wps),j.days.push(...R.days)),c=R==null?void 0:R.next,c.length||j.hours.push(R==null?void 0:R.to),p+=Math.round((((tt=R==null?void 0:R.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!B)break}j.wps=(et=j.wps)==null?void 0:et.reduce((T,B)=>(T.some(R=>Math.round(g(R.etd).unix()/60)===Math.round(g(B.etd).unix()/60))||T.push(B),T),[]),(O=j.wps)==null||O.forEach((T,B)=>{const R=j.wps[B-1];if(R){const gt=T.distanceFromStart-R.distanceFromStart,wt=g(T.eta||T.etd).diff(g(R.etd||R.eta),"h",!0);T.avgSpd=Math.round(gt/wt*100)/100;const kt=N.LaneHelper.calculateBearing(R,T);R.bearing=kt}});const Y=j.hours;for(let T=0;T<Y.length-1;T++){const B=g(Y[T+1].eta).diff(Y[T].etd,"hour",!0);f+=Y[T].wxFactor*B,h+=Y[T].cFactor*B,k+=B}const F=j.hours.at(0),L=j.hours.at(-1),H=await N.LaneHelper.calculateRangeRoute(F,L,w),E=await N.LaneHelper.calculateRangeWaypoints(F,L,w,b),P={sample:j,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:g(F.eta).utc().format(),eta:g(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(f/k*1e3)/1e3,cFactor:Math.round(h/k*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/k*1e3)/1e3,totalHrs:Math.round(k*1e3)/1e3,from:F,to:L,route:H,waypoints:E,v0:M,label:C},{distanceInECA:V,hoursInECA:J,totalDgoConsInECA:st,eca:ot}=await this.calculateECA(P,n,y),it=N.LngLatHelper.roundPrecision(n.fo/24*(k-J),3),at=N.LngLatHelper.roundPrecision(n.dgo/24*k,3);P.extend={eca:ot,distanceInECA:V,hoursInECA:J,totalDgoConsInECA:st},P.totalDgoCons=at,P.totalFoCons=it<0?0:it;const X=g().valueOf()-v,Q=((z=j==null?void 0:j.hours)==null?void 0:z.length)||1;return I==null||I.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),P}static async analyseCost(s,t,a,i,n={}){var w,b;const o=g().valueOf(),e=[];s.speedStep=s.speedStep||3,s.alterStep=s.alterStep??1;const r=N.LaneHelper.calculateRouteDistance(i.route);let d=0;a.forEach(c=>{const p=Math.ceil(r/c.speed/24);d=d<p?p:d}),d=d*1.3;const l=g.utc(s.etd).add(d??14,"day");let u=1;for(const c of a){const p=JSON.parse(JSON.stringify(i.route)),f=JSON.parse(JSON.stringify(i.waypoints)),h=await W.analyseInstantWithThreshed({lat:s.lat,lng:s.lng},s.etd,l,t,c,p,f,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,n);h&&(await W.calculateCost(h,c,s,n),e.push(h),I==null||I.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,u,s.etd,l.format(),{cost:h.cost.total,hire:h.cost.hire,bunker:h.cost.bunker,distance:h.distance,hours:h.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),u++}e.sort((c,p)=>c.cost.total-p.cost.total);const y=e.at(0),v=e.at(1),M=[];if(M.push({combined:!1,speeds:[y],cost:(w=y.cost)==null?void 0:w.total}),v){const c=y.cost.cp,p=v.cost.cp,f=g(y.eta),h=g(y.etd),k=f.diff(h,"days",!0);let j=Math.ceil(k/2);j=j>7?7:j<s.alterStep?s.alterStep:j;let x=2,Y={combined:!1,speeds:[v],cost:(b=v.cost)==null?void 0:b.total},F;for(;j>=s.alterStep;){const L=await W.combinedAnalyse(s,t,l,[c,p],i,j,{...n,level:x});if(Y.cost>L.cost?F?(F==null?void 0:F.cost)>L.cost&&(F=L):(F=Y,Y=L):(!F||(F==null?void 0:F.cost)>L.cost)&&(F=L),j<=s.alterStep)break;j=Math.ceil(j/2),x+=1}M.push(Y),F&&M.push(F)}const S=g().valueOf()-o;return I==null||I.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,S),M.sort((c,p)=>c.cost-p.cost)}static async combinedAnalyse(s,t,a,i,n,o,e={}){e.counter=1,I==null||I.info("[%s][L%d] analyse with alternate cp in every %d days",e.requestId,e.level,o);const r=await W.alternateAnalyse(s,t,a,i,0,n,o,e),d=r.reduce((p,f)=>p+f.cost.total,0),l=r.reduce((p,f)=>p+f.cost.hire,0),u=r.reduce((p,f)=>p+f.cost.bunker,0),y=r.reduce((p,f)=>p+f.distance,0),v=r.reduce((p,f)=>p+f.totalHrs,0);I==null||I.info("[%s][L%d] cost with cpa/cpb turn: %j",e.requestId,e.level,{cost:d,hire:l,bunker:u,distance:y,hours:v});const M=await W.alternateAnalyse(s,t,a,i,1,n,o,e),C=M.reduce((p,f)=>p+f.cost.total,0),S=M.reduce((p,f)=>p+f.cost.hire,0),w=M.reduce((p,f)=>p+f.cost.bunker,0),b=M.reduce((p,f)=>p+f.distance,0),c=M.reduce((p,f)=>p+f.totalHrs,0);return I==null||I.info("[%s][L%d] cost with cpb/cpa turn: %j",e.requestId,e.level,{cost:C,hire:S,bunker:w,distance:b,hours:c}),d<C?{combined:!0,cost:Math.round(d*1e3)/1e3,speeds:r,step:o}:{combined:!0,cost:Math.round(C*1e3)/1e3,speeds:M,step:o}}static async alternateAnalyse(s,t,a,i,n,o,e,r={}){var y,v;let d=g.utc(s.etd);const l={lat:s.lat,lng:s.lng},u=[];for(;d.isBefore(a);){const M=d.clone().utc().add(e,"day"),C=JSON.parse(JSON.stringify(o.route)),S=JSON.parse(JSON.stringify(o.waypoints)),w=i[n],b=await W.analyseInstantWithThreshed(l,d.utc().format(),M,t,w,C,S,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,r);b&&(await W.calculateCost(b,w,s,r),I==null||I.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,d.utc().format(),M.utc().format(),{cost:b.cost.total,hire:b.cost.hire,bunker:b.cost.bunker,distance:b.distance,hours:b.totalHrs,cp:`${w.speed}/${w.fo}/${w.dgo}`})),r.counter=r.counter+1;const c=(v=(y=b==null?void 0:b.sample)==null?void 0:y.hours)==null?void 0:v.at(-1);if(c)l.lat=c.lat,l.lng=c.lng,d=g(c.eta),u.push(b),n=n?0:1;else break}return u}static async calculateCost(s,t,a,i={}){var n;if(s){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,e=Math.round(s.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3,r=Math.round(s.totalFoCons*(a.priceFO||0)*1e3)/1e3,d=Math.round((s.totalDgoCons+(((n=s.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;s.cost={total:Math.round((e+r+d)*1e3)/1e3,hire:e,bunker:Math.round((r+d)*1e3)/1e3,cp:t}}return s}static async calculateECA(s,t,a={}){var r,d,l,u;const i=await N.LaneHelper.intersectInECA((s==null?void 0:s.route)||[]);let n=0,o=0,e=0;(d=(r=s==null?void 0:s.sample)==null?void 0:r.wps)==null||d.forEach(y=>{y.positionTime=g.utc(y.etd||y.eta).unix()});for(const y of i){n+=y.distance;const v=await N.LaneHelper.deadReckoningTime((l=y.waypoints)==null?void 0:l.at(0),s.sample.wps),M=await N.LaneHelper.deadReckoningTime((u=y.waypoints)==null?void 0:u.at(-1),s.sample.wps);y.in=v,y.out=M,y.totalHrs=N.LngLatHelper.roundPrecision((M.positionTime-v.positionTime)/3600,3),y.totalDgoCons=N.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),o+=y.totalHrs,e+=y.totalDgoCons}return n=N.LngLatHelper.roundPrecision(n,3),o=N.LngLatHelper.roundPrecision(o,3),e=N.LngLatHelper.roundPrecision(e,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:e,eca:i}}static async mergeSpeeds(s,t={}){var c,p;const a={hours:[],wps:[],days:[]},i=s.reduce((f,h)=>f+h.distance,0),n=s.reduce((f,h)=>{var k;return f+(((k=h.extend)==null?void 0:k.distanceInECA)||0)},0),o=s.reduce((f,h)=>f+h.totalHrs,0),e=s.reduce((f,h)=>{var k;return f+(((k=h.extend)==null?void 0:k.hoursInECA)||0)},0),r=s.reduce((f,h)=>{var k;return f+(((k=h.extend)==null?void 0:k.totalDgoConsInECA)||0)},0),d=s.reduce((f,h)=>f+h.wxFactor*h.totalHrs/o,0),l=s.reduce((f,h)=>f+h.cFactor*h.totalHrs/o,0),u=s.reduce((f,h)=>f+h.totalFoCons,0),y=s.reduce((f,h)=>f+h.totalDgoCons,0),v=s.reduce((f,h)=>f+h.cost.total,0),M=s.reduce((f,h)=>f+h.cost.hire,0),C=s.reduce((f,h)=>f+h.cost.bunker,0),S=[],w=[];let b;for(const f of s){w.push(...((c=f.extend)==null?void 0:c.eca)||[]);const h=f.sample.hours,k=f.sample.wps,j=f.sample.days,x=h.at(0);b&&(x.distanceFromPrevious=b.distanceFromPrevious,x.distanceFromStart=b.distanceFromStart,h.forEach((H,E)=>{E&&(H.distanceFromStart=H.distanceFromStart+b.distanceFromStart)}),k.at(0).distanceFromPrevious=b.distanceFromPrevious,k.at(0).distanceFromStart=b.distanceFromStart,k.forEach((H,E)=>{E&&(H.distanceFromStart=H.distanceFromStart+b.distanceFromStart)}),j.at(0).distanceFromPrevious=b.distanceFromPrevious,j.at(0).distanceFromStart=b.distanceFromStart,j.forEach((H,E)=>{E&&(H.distanceFromStart=H.distanceFromStart+b.distanceFromStart)})),x.cp=f.cost.cp;const Y=[f.etd,f.eta],F=S.findIndex(H=>H.id===x.cp.id);F===-1?(x.cp.segment=[Y],S.push(x.cp)):S[F].segment.push(Y),h.forEach(H=>{var P;((P=a.hours)==null?void 0:P.findIndex(V=>V.eta===H.eta))===-1&&a.hours.push(H)}),k.forEach(H=>{var P;((P=a.wps)==null?void 0:P.findIndex(V=>V.eta===H.eta))===-1&&a.wps.push(H)}),j.forEach(H=>{var P;((P=a==null?void 0:a.days)==null?void 0:P.findIndex(V=>V.eta===H.eta))===-1&&a.days.push(H)});const L=(p=a.wps)==null?void 0:p.findIndex(H=>H.eta===x.eta);L===-1?a.wps.push(x):a.wps[L]=x,b=h.at(-1)}return a.wps.sort((f,h)=>{g(f.etd).unix()-g(h.etd).unix()}),a.wps.forEach((f,h)=>{const k=a.wps[h-1];if(k){const j=f.distanceFromStart-(k.distanceFromStart||0),x=g(f.eta||f.etd).diff(g(k.etd||k.eta),"hour",!0),Y=Math.round(j/x*100)/100;f.avgSpd=Y;const F=N.LaneHelper.calculateBearing(k,f);k.bearing=F}}),{sample:a,etd:s.at(0).etd,eta:s.at(-1).eta,from:s.at(0).from,to:s.at(-1).to,v0:s.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(d*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(u*1e3)/1e3,totalDgoCons:Math.round(y*1e3)/1e3,cost:{total:Math.round(v*1e3)/1e3,hire:Math.round(M*1e3)/1e3,bunker:Math.round(C*1e3)/1e3},extend:{cps:S,eca:w,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(e*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:s}}}}q.AISImpl=G,q.AlertHelper=dt,q.AlertLevel=ct,q.HifleetImpl=yt,q.LoadCondition=lt,q.MyShipImpl=pt,q.MyVesselImpl=mt,q.ShipxyImpl=Mt,q.SpeedHelper=W,q.SpeedLabel=ht,q.VesselTag=ut,q.alertHelper=bt,Object.defineProperty(q,Symbol.toStringTag,{value:"Module"})});
1
+ (function(q,A){typeof exports=="object"&&typeof module<"u"?A(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"],A):(q=typeof globalThis<"u"?globalThis:q||self,A(q["idm-plugin-vessel"]={},q.got,q["@log4js-node/log4js-api"],q.moment,q["@idm-plugin/geo2"],q["@idm-plugin/meteo2"],q["@idm-plugin/meteo"]))})(this,function(q,A,U,w,N,ft,nt){"use strict";var It=Object.defineProperty;var St=(q,A,U)=>A in q?It(q,A,{enumerable:!0,configurable:!0,writable:!0,value:U}):q[A]=U;var K=(q,A,U)=>(St(q,typeof A!="symbol"?A+"":A,U),U);let m;try{m=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(s){let t,a;switch(s){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class mt extends G{constructor(t,a){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await A.post(a,i).json();m==null||m.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:w().utc().format()})}async checkToken(t={}){var a;return(!this.token||w().diff(w(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var e,r;await this.checkToken(a);const i="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.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,i,n);const o=await A.post(i,n).json();return o.status!==200?(m==null||m.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),[]):(o.data||[]).map(l=>({mmsi:l.mmsi,name:l.nameEn,nameCn:l.nameCn,imo:Number.isNaN(l.imo)?null:Number(l.imo),callSign:l.callsign,type:l.vesselTypeNameEn,flagName:l.flagCtry,vendor:"myvessel",raw:l}))}async search(t,a={}){var u,l;await this.checkToken(a);const i=/^\d{7}$/.test(t.toString()),n=i?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",o=i?{imo:t}:{mmsi:t},e={headers:{Authorization:`${(u=this.token)==null?void 0:u.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:o};m==null||m.info("[%s] fetch vessel from: %s - %j",a.requestId,n,e);const r=await A.get(n,e).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 e,r;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.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,i,n);const o=await A.post(i,n).json();return o.status!==200?(m==null||m.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),{}):o.data}async realTimePosition(t,a={}){var r,u;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:{mmsi:t}};m==null||m.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await A.get(i,n).json();if(o.code)return m==null||m.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),o;const e=o.data;for(const l in e)!isNaN(e[l])&&Number(e[l])!==1/0&&(e[l]=Number(e[l]));if(e){const l=w(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName||e.aisVesselName,imo:e.imo,callSign:e.callsign||e.aisCallSign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?w.utc(e.eta).format():void 0,destination:e.dest,positionTime:l.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,vesselType:e.vesselTypeNameEn,flag:e.flagCtryNameEn,clasz:e.classSociety,build:e.buildYear,dwt:e.dwt,grt:e.grt,net:e.net,method:"position",vendor:"myVessel",utc:l.utc().format()}}else return{}}async calculateRoute(t,a,i={}){var r,u;await this.checkToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},json:{startPoint:{lon:t.lng,lat:t.lat},endPoint:{lon:a.lng,lat:a.lat},maxDraught:i.maxDraught||10,useAIModel:i.useAIModel||!1,withECA:i.withECA||!1}};m==null||m.info("[%s] fetch route from: %s - %j",i.requestId,n,o);const e=await A.post(n,o).json();return e.status!==200?(m==null||m.warn("[%s] fetch route failed: %j",i.requestId,{message:e.message,status:e.status,code:e.code}),{}):e.data}async trajectory(t,a,i,n,o=!0,e={}){await this.checkToken(e);const r=await this.realTimePosition(t,e),u=w(a),l=w(i),d=[];for(;l.diff(u,"day",!0)>30;)await this.trajectoryIn30Day(t,u,u.clone().add(30,"day"),r,n,d,e),u.add(30,"day");return await this.trajectoryIn30Day(t,u,l,r,n,d,e),d}async trajectoryIn30Day(t,a,i,n,o,e,r={}){var M,C,S,g,b;const u="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(C=this.token)==null?void 0:C.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};m==null||m.info("[%s] fetch trajectory from: %s - %j",r.requestId,u,l);const d=await A.post(u,l).json();if(d.code)return m==null||m.warn("[%s] fetch trajectory failed: %j",r.requestId,u,{message:d.message,status:d.status,code:d.code}),d;let y=-1;const v=w(`${(g=(S=d.data)==null?void 0:S[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(b=d.data)==null||b.forEach(c=>{for(const Y in c)!isNaN(c[Y])&&Number(c[Y])!==1/0&&(c[Y]=Number(c[Y]));const p=w(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),f=c.status,{labelCn:h,labelEn:k}=this.parseStatus(f),j={mmsi:c.mmsi,imo:n==null?void 0:n.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:f,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?w(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:p.unix(),labelCn:h,labelEn:k,method:"trajectory",vendor:"myVessel",utc:p.utc().format()},x=Math.floor(p.diff(v,"minute",!0)/(o||1));x!==y&&(y=x,e.push(j))}),e}}class yt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},o=await A.post(i,n).json();m==null||m.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const e=o==null?void 0:o.list;if(!e)return m==null||m.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const v in e)!isNaN(e[v])&&Number(e[v])!==1/0&&(e[v]=Number(e[v]));e.status=e.sp>3?0:1;const r=e.status,{labelCn:u,labelEn:l}=this.parseStatus(r),d=w(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?w.utc(e.eta).format():void 0,destination:e.destination,vesselType:e.type,dwt:e.dwt,build:e.buildyear,flag:e.fn,positionTime:d.unix(),utc:d.utc().format(),status:r,labelCn:u,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,a={}){let i="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 o=await A.post(i,n).json();m==null||m.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]);for(const r in o)!isNaN(o[r])&&Number(o[r])!==1/0&&(o[r]=Number(o[r]));const e={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await A.post(i,n).json(),m==null||m.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(e.deadweight=Number(o.dwt)),e}async suggest(t,a={}){const i="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"}},o=await A.post(i,n).json();m==null||m.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const e=[];for(const r of o)e.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 e.sort((r,u)=>u.score-r.score),e}async trajectory(t,a,i,n,o=!0,e={}){var c,p,f;const r=await this.realTimePosition(t,e);let u=w(a);const l=w(i),d=w();if(o){let h=l.diff(u,"d",!0);h<0?u=l.clone().subtract(40,"d"):h<30?u.subtract(10,"d"):h<60?u.subtract(5,"d"):u=l.clone().subtract(80,"d"),h=d.diff(l,"d",!0),l.add(h>10?240:h*24,"h")}const y={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},v="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",M=await A.get(v,y).json();m==null||m.info("[%s] fetch trajectory from: %s - %j",e.requestId,v,y);let C;M&&(C=((p=(c=M.ships)==null?void 0:c.offors)==null?void 0:p.ship)||[],C.length||m==null||m.warn("[%s] fetch trajectory failed: %j",e.requestId,M));const S=[];let g=-1;const b=w(`${(f=C==null?void 0:C[0])==null?void 0:f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const h of C){for(const L in h)!isNaN(h[L])&&Number(h[L])!==1/0&&(h[L]=Number(h[L]));const k=w(`${h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");h.status=h.sp>4?0:1;const{labelEn:j,labelCn:x}=this.parseStatus(h.status),Y={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:k.unix(),utc:k.utc().format(),status:h.status,labelCn:x,labelEn:j,method:"trajectory",vendor:"hifleet"},F=Math.floor(k.diff(b,"minute",!0)/(n||1));F!==g&&(g=F,S.push(Y))}return S}}class Mt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",o=await A.get(n,i).json();if(m==null||m.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const e=o.data[0];for(const y in e)!isNaN(e[y])&&Number(e[y])!==1/0&&(e[y]=Number(e[y]));const{labelCn:r,labelEn:u}=await this.parseStatus(e.navistat),l=w.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:l.utc().format(),status:e.navistat,labelEn:u,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,i,n,o=!0,e={}){var b;const r=await this.realTimePosition(t,e),u=w(a),l=w(i),d="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:u.unix(),etm:l.unix()}},v=await A.get(d,y).json();if(m==null||m.info("[%s] fetch trajectory from: %s - %j",e.requestId,d,y),(v==null?void 0:v.status)!==0)return v;const M=v==null?void 0:v.points,C=[],S=w.unix((b=M[0])==null?void 0:b.utc);let g=-1;for(const c of M){const p=w.unix(c.utc),f={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(c.sog*3600/1e3/1852*100)/100,cog:Math.round(c.cog/100*100)/100,lat:Math.round(c.lat/1e6*1e5)/1e5,lng:Math.round(c.lon/1e6*1e5)/1e5,positionTime:p.unix(),utc:p.utc().format(),method:"trajectory",vendor:"shipxy"},h=Math.floor(p.diff(S,"minute",!0)/(n||1));h!==g&&(g=h,C.push(f))}return C}}class pt extends G{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,a={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",o=await A.post(n,i).json();return m==null||m.info("[%s] fetch ship id from: %s - %j",a.requestId,n,i),o.code!=="0"?o:o.data[0].shipId}async getShipInfo(t,a={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",o=await A.post(n,i).json();if(m==null||m.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const e=o.data;let r=e.imo;return t==="407170"&&(r="9198379",m==null||m.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,e.imo,r)),{mmsi:e.mmsi,name:e.shipnameEn,imo:r,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,a={}){const i=await this.getShipId(t,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},e="https://api3.myships.com/sp/ships/position/latest",r=await A.post(e,o).json();m==null||m.info("[%s] fetch realtime position from: %s - %j",a.requestId,e,o);const u=r.data[0];for(const M in u)!isNaN(u[M])&&Number(u[M])!==1/0&&(u[M]=Number(u[M]));const{labelCn:l,labelEn:d}=await this.parseStatus(u.aisNavStatus),y=w.unix(u.posTime);return{...n,mmsi:t,lat:Math.round(u.lat/1e4/60*1e5)/1e5,lng:Math.round(u.lon/1e4/60*1e5)/1e5,sog:Math.round(u.sog/10*100)/100,cog:Math.round(u.cog/10*100)/100,hdg:Math.round(u.heading*100)/100,rot:Math.round(u.rot*100)/100,positionTime:u.posTime,utc:y.utc().format(),status:u.aisNavStatus,labelEn:d,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,a,i,n,o=!0,e={}){const r=w(a),u=w(i),l=await this.getShipId(t),d=await this.getShipInfo(l),y=[];for(;u.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(l,r.unix(),r.add(30,"day").unix(),d,t,n,y);return await this.trajectoryIn30Day(l,r.unix(),u.unix(),d,t,n,y),y}async trajectoryIn30Day(t,a,i,n,o,e,r,u={}){var S;const l={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:i}},d="https://api3.myships.com/sp/ships/position/history",y=await A.post(d,l).json();if(m==null||m.info("[%s] fetch trajectory from: %s - %j",u.requestId,d,l),y.code!=="0")return m==null||m.warn("[%s] invoke myship trajectory failed: %j",u.requestId,y),y;const v=y.data;for(const g in v)!isNaN(v[g])&&Number(v[g])!==1/0&&(v[g]=Number(v[g]));const M=w.unix((S=v[0])==null?void 0:S.posTime);let C=-1;for(const g of v){const b=w.unix(g.posTime),c={imo:n==null?void 0:n.imo,mmsi:o,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:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"myship"},p=Math.floor(b.diff(M,"minute",!0)/(e||1));p!==C&&(C=p,r.push(c))}return r}}let _;try{_=U.getLogger("vessel")}catch{}finally{}var ct=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(ct||{});class dt{parsePrinciple(s,t={}){var e,r,u;_==null||_.debug("[%s] parse rule: %s",t.requestId,s);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=s.match(a)?(e=s.match(a))==null?void 0:e[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let l=0;l<(n==null?void 0:n.length);l++){const d=(u=(r=n[l].match(a))==null?void 0:r[0])==null?void 0:u.split("],");if(l===0&&!d)o.scope=n[0];else if(d)for(let y=0,v=d.length;y<v;y++){const M=this.parseRule(d[y]);M&&(o[M.level]?M.key?o[M.level][M==null?void 0:M.key]=M:o[M.level]=M:M.key?o[M.level]={[M==null?void 0:M.key]:M}:o[M.level]=M)}}return o}parseRule(s,t={}){var o;_==null||_.debug("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=s==null?void 0:s.match(a))==null?void 0:o[0],n=i==null?void 0:i.split(",");if(n){let e=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return e=isNaN(e)?1:e,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:e,key:n[4]}}}checkWeather(s,t,a={}){var M,C,S,g,b,c,p,f,h,k,j,x,Y,F,L;let i=0,n=0,o=0,e=0;const r=Math.round(((C=(M=t==null?void 0:t.SEVERE)==null?void 0:M.sigWave)==null?void 0:C.number)*1.6*100)/100,u=(g=(S=t==null?void 0:t.SEVERE)==null?void 0:S.sigWave)==null?void 0:g.number,l=(c=(b=t==null?void 0:t.HEAVY)==null?void 0:b.sigWave)==null?void 0:c.number,d=Math.round((((f=(p=t==null?void 0:t.SEVERE)==null?void 0:p.wind)==null?void 0:f.number)+2)*100)/100,y=(k=(h=t==null?void 0:t.SEVERE)==null?void 0:h.wind)==null?void 0:k.number,v=(x=(j=t==null?void 0:t.HEAVY)==null?void 0:j.wind)==null?void 0:x.number;for(let H=0;H<(s==null?void 0:s.length);H++){const E=s[H],P=(F=(Y=E==null?void 0:E.meteo)==null?void 0:Y.wave)==null?void 0:F.sig,V=(L=E==null?void 0:E.meteo)==null?void 0:L.wind,J=H?w(E.eta).diff(w(s[H-1].eta),"hour",!0):0;e=J>e?J:e,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...P,dgThd4Wv:r,svThd4Wv:u,hvThd4Wv:l}),(P==null?void 0:P.height)>=r?E.isDangerous=!0:(P==null?void 0:P.height)>=u?E.isSevere=!0:(P==null?void 0:P.height)>=l&&(E.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:v}),(V==null?void 0:V.scale)>=d?(E.isDangerous=!0,delete E.isSevere,delete E.isHeavy):(V==null?void 0:V.scale)>y?(E.isDangerous||(E.isSevere=!0),delete E.isHeavy):(V==null?void 0:V.scale)===v&&!E.isDangerous&&!E.isSevere&&(E.isHeavy=!0),i+=E.isDangerous?J:0,n+=E.isSevere?J:0,o+=E.isHeavy?J:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,e=Math.round(e),{sample:s,dangerous:i,severe:n,heavy:o,step:e<3?3:e,wind:{dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:v},sig:{dgThd4Wv:r,svThd4Wv:u,hvThd4Wv:l}}}}const bt=new dt;let I;try{I=U.getLogger("vessel")}catch{}finally{}const vt=new ft.MeteoHelper2("",!0);var ut=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(ut||{}),lt=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(lt||{}),ht=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ht||{});class W{static blockCoefficient(s,t,a,i){let n=Math.round(s/(t*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],e=o.map(r=>Math.abs(r-n));return o[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,a=9.8){let i=Math.round(Math.sqrt(s*s/(a*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(s,t,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return a==="Laden"&&(o=i[s]),o[0]+o[1]*t+o[2]*Math.pow(t,2)}static directionFactor(s,t=0){let a;return s>30&&s<=60?a=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?a=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(s,t,a,i){let n;return a==="container"?n=.7*i/2+Math.pow(i,3)/(22*Math.pow(s,2/3)):t==="Ballast"?n=.7*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)):n=.5*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)),n}static waveHeightFactor(s,t){s=s<3?s*.7:s,s=s<0?.2:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=s<3?.4:-.3:t>120&&t<=150?a=s<3?.6:-.5:t>150&&t<=180?a=s<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(s,2)+.278*s)*1e4)/1e4}static assembleProperties(s,t,a,i){var y;const n=s.lbp??s.length??s.lengthOverall??198.9642,o=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,r=s.deadweight??67035.7773,u=((y=s==null?void 0:s.type)==null?void 0:y.toLowerCase())||"common";return{tag:u.indexOf("container")>-1?"container":u.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:o,breadthMoulded:e,displacement:Math.round((r/1.025+o*e*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(s,t,a,i="",n=2,o=!0,e=!1,r={}){let u;if(t.velocity&&e&&(s.speed=N.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),o){let l;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:M,marineModels:C}=await nt.Meteo2Assist.autoPickMeteoModel(i),S=await vt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:M,marineModels:C}),[g]=nt.Meteo2Assist.pickHourly(S,a);l=nt.Meteo2Assist.toLegacy(g)}catch(M){I.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:i},M)}const d=W.currentFactor(s.bearing,l==null?void 0:l.current,n),y=W.weatherFactor(s,l,d),v=Math.round((s.speed*1.943844+y+d)*100)/100;u={meteo:{...l},wxFactor:y,cFactor:d,speed:t.velocity&&e?t.velocity:v<0?1:v,eta:a.utc().format(),etd:a.utc().format()}}else u={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round(s.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,{...u,...t}}static async speedLoseInHoursStep(s,t,a,i,n,o,e="",r=!0,u=!1,l={}){t.utc();const d=t.clone().add(14,"days"),y=[],v=[];let M=0,C=0,S,g;for(let b=0;b<o.length-1;b++){let c=o[b];c.distanceFromStart=Math.round((n+C)*1e3)/1e3;const p=o[b+1];if(s.bearing=N.LaneHelper.calculateBearing(c,p,!p.gcToPrevious),c.bearing=s.bearing,c.suspend&&u){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const k=c.suspend-c.elapsed;if(i-M>k)i=i-M-k,t.add(k,"hour"),c.elapsed=c.suspend;else{const j=i-M;c.elapsed+=j,t.add(j,"hour"),i=0}if(I==null||I.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=C,{etd:t,from:g||c,to:c,next:o.filter(j=>j),wps:y,days:v}}else c.suspend=0;r=t.isAfter(d)?!1:r,c=await W.speedLoseAt(s,c,t,e,0,r,u,l),g=g||c,c.important&&y.push(c),t.isSameOrAfter(a)&&(v.push(c),a.add(24,"hour"));const f=N.LaneHelper.calculateDistance(c,p,!p.gcToPrevious);let h=Math.round(f/g.speed*1e5)/1e5;if(M+h<i){if(M+=h,t.add(h,"hour"),delete o[b],I==null||I.debug(`[%s] go to %j from %j with ${f}nm, and cost ${h} hours`,l.requestId,{lat:p.lat,lng:p.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),C+=f,o.filter(k=>k).length<=1){S=p,S.eta=t.utc().format(),S.distanceFromPrevious=f,S.distanceFromStart=Math.round((n+C)*1e4)/1e4,y.push(S),delete o[b+1];break}}else{h=i-M,t.add(h,"hour");const k=N.LngLatHelper.roundPrecision(g.speed*h,5);S=N.LaneHelper.calculateCoordinate(c,s.bearing,k,"nauticalmiles",!p.gcToPrevious),S.eta=t.utc().format(),o[b]=S,I==null||I.debug(`[%s] go to %j from %j with ${k}nm, and cost ${h} hours`,l.requestId,{lat:S.lat,lng:S.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),C+=k,S.distanceFromPrevious=Math.round(C*1e4)/1e4,S.distanceFromStart=Math.round((n+C)*1e4)/1e4;break}}return{etd:t,from:g,to:S,next:o.filter(b=>b),wps:y,days:v}}static currentFactor(s,t,a=0){const i=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(s,t,a=0){var v,M,C,S,g,b,c;I==null||I.debug("calculate weather factor via: %j",{...s,...t});const i=W.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=N.LngLatHelper.roundPrecision(a*1852/3600,6),o=W.froudeNumber(s.speed-n,s.lbp),e=W.amendFactor(i,o,s.loadCondition);let r=Math.abs(s.bearing%360-(((v=t==null?void 0:t.wind)==null?void 0:v.degree)%360||0));r=r>180?360-r:r;const u=W.directionFactor(r,(M=t==null?void 0:t.wind)==null?void 0:M.scale),l=W.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(C=t==null?void 0:t.wind)==null?void 0:C.kts);let d=u*e*l/100*(s.speed-n);d=Math.round(d*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(d)>1&&(d=d/(Math.abs(Math.round(d))+1)),I==null||I.debug("wind wx factor = %d",d),r=Math.abs(s.bearing%360-(((g=(S=t==null?void 0:t.wave)==null?void 0:S.sig)==null?void 0:g.degree)%360||0)),r=r>180?360-r:r;const y=W.waveHeightFactor(((c=(b=t==null?void 0:t.wave)==null?void 0:b.sig)==null?void 0:c.height)??1,r);return I==null||I.debug("wave wx factor = %d",y),d=Math.abs(d)>Math.abs(y)?d:d*.3+y*.7,I==null||I.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 analyseInstant(s,t,a,i,n,o="",e=0,r=!0,u=!1,l={}){var X,Q,Z,$,tt,et;const d=w().valueOf();s.lng=N.LngLatHelper.convertToStdLng(s.lng);const{route:y,waypoints:v}=n.points,M=N.LaneHelper.calculateSubRoute(s,y);if(((X=M[0])==null?void 0:X.length)<=1)return;const{v0:C,label:S}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:i.speed,label:"CP"},g=W.assembleProperties(a,i.loadCondition,C,0),b=v.length?N.LaneHelper.calculateSubWaypoints(s,v):[];b.forEach(O=>O.important=!0);const c={from:{...s},route:M,waypoints:b,v0:C,label:S},p={hours:[],days:[],wps:[]};e||(N.LaneHelper.calculateRouteDistance(M)/i.speed<=72?e=3:e=6);let f=N.LaneHelper.simplifyRouteToCoordinates(M,b,0),h=0,k=0,j=0,x=0;t=w(t).utc();const Y=t.clone();for(;f.length>0;){const O=e-t.hour()%e,z=Math.ceil(t.clone().add(O,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,T=await W.speedLoseInHoursStep(g,t,Y,z,h,f,o,r,u,l);if((Q=T.from)!=null&&Q.speed&&(p.hours.push(T.from),p.wps.push(...T.wps),p.days.push(...T.days)),f=T==null?void 0:T.next,!f.length){const B=await W.speedLoseAt(g,T.to,w(T.to.eta),o,0,r,u,l);B.bearing=g.bearing,p.hours.push(B)}h+=Math.round((((Z=T==null?void 0:T.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const F=p.hours;for(let O=0;O<F.length-1;O++){const z=w(F[O+1].eta).diff(F[O].etd,"hour",!0)||1;k+=(F[O].wxFactor||0)*z,j+=(F[O].cFactor||0)*z,x+=z}($=p.wps)==null||$.forEach((O,z)=>{O.positionTime=w.utc(O.etd||O.eta).unix();const T=p.wps[z-1];if(T){const B=O.distanceFromStart-T.distanceFromStart,R=w(O.eta||O.etd).diff(w(T.etd||T.eta),"h",!0);O.avgSpd=Math.round(B/R*100)/100,T.bearing=N.LaneHelper.calculateBearing(T,O)}}),p.wps=(tt=p.wps)==null?void 0:tt.reduce((O,z)=>(O.some(T=>Math.round(T.positionTime/60)===Math.round(z.positionTime/60))||O.push(z),O),[]),c.sample=p;const L=p.hours.at(0),H=p.hours.at(-1);c.distance=Math.round(H.distanceFromStart*1e3)/1e3,c.etd=w(L.eta).utc().format(),c.eta=w(H.eta).utc().format(),c.wxFactor=Math.round(k/x*1e3)/1e3,c.cFactor=Math.round(j/x*1e3)/1e3,c.avgSpeed=Math.round(H.distanceFromStart/x*1e3)/1e3,c.totalHrs=Math.round(x*1e3)/1e3;const{distanceInECA:E,hoursInECA:P,totalDgoConsInECA:V,eca:J}=await this.calculateECA(c,i,l),st=N.LngLatHelper.roundPrecision(i.fo/24*(x-P),3),ot=N.LngLatHelper.roundPrecision(i.dgo/24*x,3);c.extend={eca:J,distanceInECA:E,hoursInECA:P,totalDgoConsInECA:V},c.totalFoCons=st<0?0:st,c.totalDgoCons=ot;const at=w().valueOf()-d,rt=((et=p==null?void 0:p.hours)==null?void 0:et.length)||1;return I==null||I.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,at,rt,Math.round(at/rt*1e3)/1e3),c}static async analyseInstantWithThreshed(s,t,a,i,n,o,e,r="",u=3,l=!0,d=!1,y={}){var Z,$,tt,et,O,z;const v=w().valueOf();s.lng=N.LngLatHelper.convertToStdLng(s.lng);const{v0:M,label:C}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:n.speed,label:"CP"},S=W.assembleProperties(i,n.loadCondition,M,0),g=N.LaneHelper.calculateSubRoute(s,o);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const b=e.length?N.LaneHelper.calculateSubWaypoints(s,e):[];b.forEach(T=>T.important=!0);let c=N.LaneHelper.simplifyRouteToCoordinates(g,b,0),p=0,f=0,h=0,k=0;const j={hours:[],wps:[],days:[]};t=w(t).utc();const x=t.clone();for(;c.length>0;){const T=u-t.hour()%u;let B=Math.ceil(t.clone().add(T,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;B=t.clone().add(B,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:B;const R=await W.speedLoseInHoursStep(S,t,x,B,p,c,r,l,d,y);if(($=R.from)!=null&&$.speed&&(j.hours.push(R.from),R!=null&&R.wps&&j.wps.push(...R.wps),j.days.push(...R.days)),c=R==null?void 0:R.next,c.length||j.hours.push(R==null?void 0:R.to),p+=Math.round((((tt=R==null?void 0:R.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!B)break}j.wps=(et=j.wps)==null?void 0:et.reduce((T,B)=>(T.some(R=>Math.round(w(R.etd).unix()/60)===Math.round(w(B.etd).unix()/60))||T.push(B),T),[]),(O=j.wps)==null||O.forEach((T,B)=>{const R=j.wps[B-1];if(R){const gt=T.distanceFromStart-R.distanceFromStart,wt=w(T.eta||T.etd).diff(w(R.etd||R.eta),"h",!0);T.avgSpd=Math.round(gt/wt*100)/100;const kt=N.LaneHelper.calculateBearing(R,T);R.bearing=kt}});const Y=j.hours;for(let T=0;T<Y.length-1;T++){const B=w(Y[T+1].eta).diff(Y[T].etd,"hour",!0);f+=Y[T].wxFactor*B,h+=Y[T].cFactor*B,k+=B}const F=j.hours.at(0),L=j.hours.at(-1),H=await N.LaneHelper.calculateRangeRoute(F,L,g),E=await N.LaneHelper.calculateRangeWaypoints(F,L,g,b),P={sample:j,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:w(F.eta).utc().format(),eta:w(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(f/k*1e3)/1e3,cFactor:Math.round(h/k*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/k*1e3)/1e3,totalHrs:Math.round(k*1e3)/1e3,from:F,to:L,route:H,waypoints:E,v0:M,label:C},{distanceInECA:V,hoursInECA:J,totalDgoConsInECA:st,eca:ot}=await this.calculateECA(P,n,y),it=N.LngLatHelper.roundPrecision(n.fo/24*(k-J),3),at=N.LngLatHelper.roundPrecision(n.dgo/24*k,3);P.extend={eca:ot,distanceInECA:V,hoursInECA:J,totalDgoConsInECA:st},P.totalDgoCons=at,P.totalFoCons=it<0?0:it;const X=w().valueOf()-v,Q=((z=j==null?void 0:j.hours)==null?void 0:z.length)||1;return I==null||I.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),P}static async analyseCost(s,t,a,i,n={}){var g,b;const o=w().valueOf(),e=[];s.speedStep=s.speedStep||3,s.alterStep=s.alterStep??1;const r=N.LaneHelper.calculateRouteDistance(i.route);let u=0;a.forEach(c=>{const p=Math.ceil(r/c.speed/24);u=u<p?p:u}),u=u*1.3;const l=w.utc(s.etd).add(u??14,"day");let d=1;for(const c of a){const p=JSON.parse(JSON.stringify(i.route)),f=JSON.parse(JSON.stringify(i.waypoints)),h=await W.analyseInstantWithThreshed({lat:s.lat,lng:s.lng},s.etd,l,t,c,p,f,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,n);h&&(await W.calculateCost(h,c,s,n),e.push(h),I==null||I.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,s.etd,l.format(),{cost:h.cost.total,hire:h.cost.hire,bunker:h.cost.bunker,distance:h.distance,hours:h.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),d++}e.sort((c,p)=>c.cost.total-p.cost.total);const y=e.at(0),v=e.at(1),M=[];if(M.push({combined:!1,speeds:[y],cost:(g=y.cost)==null?void 0:g.total}),v){const c=y.cost.cp,p=v.cost.cp,f=w(y.eta),h=w(y.etd),k=f.diff(h,"days",!0);let j=Math.ceil(k/2);j=j>7?7:j<s.alterStep?s.alterStep:j;let x=2,Y={combined:!1,speeds:[v],cost:(b=v.cost)==null?void 0:b.total},F;for(;j>=s.alterStep;){const L=await W.combinedAnalyse(s,t,l,[c,p],i,j,{...n,level:x});if(Y.cost>L.cost?F?(F==null?void 0:F.cost)>L.cost&&(F=L):(F=Y,Y=L):(!F||(F==null?void 0:F.cost)>L.cost)&&(F=L),j<=s.alterStep)break;j=Math.ceil(j/2),x+=1}M.push(Y),F&&M.push(F)}const S=w().valueOf()-o;return I==null||I.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,S),M.sort((c,p)=>c.cost-p.cost)}static async combinedAnalyse(s,t,a,i,n,o,e={}){e.counter=1,I==null||I.info("[%s][L%d] analyse with alternate cp in every %d days",e.requestId,e.level,o);const r=await W.alternateAnalyse(s,t,a,i,0,n,o,e),u=r.reduce((p,f)=>p+f.cost.total,0),l=r.reduce((p,f)=>p+f.cost.hire,0),d=r.reduce((p,f)=>p+f.cost.bunker,0),y=r.reduce((p,f)=>p+f.distance,0),v=r.reduce((p,f)=>p+f.totalHrs,0);I==null||I.info("[%s][L%d] cost with cpa/cpb turn: %j",e.requestId,e.level,{cost:u,hire:l,bunker:d,distance:y,hours:v});const M=await W.alternateAnalyse(s,t,a,i,1,n,o,e),C=M.reduce((p,f)=>p+f.cost.total,0),S=M.reduce((p,f)=>p+f.cost.hire,0),g=M.reduce((p,f)=>p+f.cost.bunker,0),b=M.reduce((p,f)=>p+f.distance,0),c=M.reduce((p,f)=>p+f.totalHrs,0);return I==null||I.info("[%s][L%d] cost with cpb/cpa turn: %j",e.requestId,e.level,{cost:C,hire:S,bunker:g,distance:b,hours:c}),u<C?{combined:!0,cost:Math.round(u*1e3)/1e3,speeds:r,step:o}:{combined:!0,cost:Math.round(C*1e3)/1e3,speeds:M,step:o}}static async alternateAnalyse(s,t,a,i,n,o,e,r={}){var y,v;let u=w.utc(s.etd);const l={lat:s.lat,lng:s.lng},d=[];for(;u.isBefore(a);){const M=u.clone().utc().add(e,"day"),C=JSON.parse(JSON.stringify(o.route)),S=JSON.parse(JSON.stringify(o.waypoints)),g=i[n],b=await W.analyseInstantWithThreshed(l,u.utc().format(),M,t,g,C,S,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,r);b&&(await W.calculateCost(b,g,s,r),I==null||I.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,u.utc().format(),M.utc().format(),{cost:b.cost.total,hire:b.cost.hire,bunker:b.cost.bunker,distance:b.distance,hours:b.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const c=(v=(y=b==null?void 0:b.sample)==null?void 0:y.hours)==null?void 0:v.at(-1);if(c)l.lat=c.lat,l.lng=c.lng,u=w(c.eta),d.push(b),n=n?0:1;else break}return d}static async calculateCost(s,t,a,i={}){var n;if(s){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,e=Math.round(s.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3,r=Math.round(s.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((s.totalDgoCons+(((n=s.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;s.cost={total:Math.round((e+r+u)*1e3)/1e3,hire:e,bunker:Math.round((r+u)*1e3)/1e3,cp:t}}return s}static async calculateECA(s,t,a={}){var r,u,l,d;const i=await N.LaneHelper.intersectInECA((s==null?void 0:s.route)||[]);let n=0,o=0,e=0;(u=(r=s==null?void 0:s.sample)==null?void 0:r.wps)==null||u.forEach(y=>{y.positionTime=w.utc(y.etd||y.eta).unix()});for(const y of i){n+=y.distance;const v=await N.LaneHelper.deadReckoningTime((l=y.waypoints)==null?void 0:l.at(0),s.sample.wps),M=await N.LaneHelper.deadReckoningTime((d=y.waypoints)==null?void 0:d.at(-1),s.sample.wps);y.in=v,y.out=M,y.totalHrs=N.LngLatHelper.roundPrecision((M.positionTime-v.positionTime)/3600,3),y.totalDgoCons=N.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),o+=y.totalHrs,e+=y.totalDgoCons}return n=N.LngLatHelper.roundPrecision(n,3),o=N.LngLatHelper.roundPrecision(o,3),e=N.LngLatHelper.roundPrecision(e,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:e,eca:i}}static async mergeSpeeds(s,t={}){var c,p;const a={hours:[],wps:[],days:[]},i=s.reduce((f,h)=>f+h.distance,0),n=s.reduce((f,h)=>{var k;return f+(((k=h.extend)==null?void 0:k.distanceInECA)||0)},0),o=s.reduce((f,h)=>f+h.totalHrs,0),e=s.reduce((f,h)=>{var k;return f+(((k=h.extend)==null?void 0:k.hoursInECA)||0)},0),r=s.reduce((f,h)=>{var k;return f+(((k=h.extend)==null?void 0:k.totalDgoConsInECA)||0)},0),u=s.reduce((f,h)=>f+h.wxFactor*h.totalHrs/o,0),l=s.reduce((f,h)=>f+h.cFactor*h.totalHrs/o,0),d=s.reduce((f,h)=>f+h.totalFoCons,0),y=s.reduce((f,h)=>f+h.totalDgoCons,0),v=s.reduce((f,h)=>f+h.cost.total,0),M=s.reduce((f,h)=>f+h.cost.hire,0),C=s.reduce((f,h)=>f+h.cost.bunker,0),S=[],g=[];let b;for(const f of s){g.push(...((c=f.extend)==null?void 0:c.eca)||[]);const h=f.sample.hours,k=f.sample.wps,j=f.sample.days,x=h.at(0);b&&(x.distanceFromPrevious=b.distanceFromPrevious,x.distanceFromStart=b.distanceFromStart,h.forEach((H,E)=>{E&&(H.distanceFromStart=H.distanceFromStart+b.distanceFromStart)}),k.at(0).distanceFromPrevious=b.distanceFromPrevious,k.at(0).distanceFromStart=b.distanceFromStart,k.forEach((H,E)=>{E&&(H.distanceFromStart=H.distanceFromStart+b.distanceFromStart)}),j.at(0).distanceFromPrevious=b.distanceFromPrevious,j.at(0).distanceFromStart=b.distanceFromStart,j.forEach((H,E)=>{E&&(H.distanceFromStart=H.distanceFromStart+b.distanceFromStart)})),x.cp=f.cost.cp;const Y=[f.etd,f.eta],F=S.findIndex(H=>H.id===x.cp.id);F===-1?(x.cp.segment=[Y],S.push(x.cp)):S[F].segment.push(Y),h.forEach(H=>{var P;((P=a.hours)==null?void 0:P.findIndex(V=>V.eta===H.eta))===-1&&a.hours.push(H)}),k.forEach(H=>{var P;((P=a.wps)==null?void 0:P.findIndex(V=>V.eta===H.eta))===-1&&a.wps.push(H)}),j.forEach(H=>{var P;((P=a==null?void 0:a.days)==null?void 0:P.findIndex(V=>V.eta===H.eta))===-1&&a.days.push(H)});const L=(p=a.wps)==null?void 0:p.findIndex(H=>H.eta===x.eta);L===-1?a.wps.push(x):a.wps[L]=x,b=h.at(-1)}return a.wps.sort((f,h)=>{w(f.etd).unix()-w(h.etd).unix()}),a.wps.forEach((f,h)=>{const k=a.wps[h-1];if(k){const j=f.distanceFromStart-(k.distanceFromStart||0),x=w(f.eta||f.etd).diff(w(k.etd||k.eta),"hour",!0),Y=Math.round(j/x*100)/100;f.avgSpd=Y;const F=N.LaneHelper.calculateBearing(k,f);k.bearing=F}}),{sample:a,etd:s.at(0).etd,eta:s.at(-1).eta,from:s.at(0).from,to:s.at(-1).to,v0:s.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(u*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(d*1e3)/1e3,totalDgoCons:Math.round(y*1e3)/1e3,cost:{total:Math.round(v*1e3)/1e3,hire:Math.round(M*1e3)/1e3,bunker:Math.round(C*1e3)/1e3},extend:{cps:S,eca:g,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(e*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:s}}}}q.AISImpl=G,q.AlertHelper=dt,q.AlertLevel=ct,q.HifleetImpl=yt,q.LoadCondition=lt,q.MyShipImpl=pt,q.MyVesselImpl=mt,q.ShipxyImpl=Mt,q.SpeedHelper=W,q.SpeedLabel=ht,q.VesselTag=ut,q.alertHelper=bt,Object.defineProperty(q,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "3.3.9",
4
+ "version": "3.4.1",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [