@idm-plugin/vessel 1.8.5 → 1.8.6

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
@@ -69,30 +69,30 @@ class Ct extends et {
69
69
  client_secret: this.clientSecret,
70
70
  grant_type: "client_credentials"
71
71
  }
72
- }, o = await B.post(n, i).json();
73
- p == null || p.info("[%s] fetch access token from: %s - %j", t.requestId, n, o), o.error || (this.token = {
74
- accessToken: o.access_token,
75
- tokenType: o.token_type,
76
- expiresIn: o.expires_in,
77
- scope: o.scope,
78
- jti: o.jti,
72
+ }, a = await B.post(n, i).json();
73
+ p == null || p.info("[%s] fetch access token from: %s - %j", t.requestId, n, a), a.error || (this.token = {
74
+ accessToken: a.access_token,
75
+ tokenType: a.token_type,
76
+ expiresIn: a.expires_in,
77
+ scope: a.scope,
78
+ jti: a.jti,
79
79
  issuedAt: b().utc().format()
80
80
  });
81
81
  }
82
82
  async realTimePosition(t, n = {}) {
83
83
  var h, M, l;
84
84
  (!this.token || b().diff(b(this.token.issuedAt), "seconds") > ((h = this.token) == null ? void 0 : h.expiresIn) - 300) && await this.authToken(n);
85
- const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", o = {
85
+ const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", a = {
86
86
  headers: {
87
87
  Authorization: `${(M = this.token) == null ? void 0 : M.tokenType} ${(l = this.token) == null ? void 0 : l.accessToken}`
88
88
  },
89
89
  searchParams: { mmsi: t }
90
90
  };
91
- p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, o);
92
- const a = await B.get(i, o).json();
93
- if (a.code)
94
- return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, i, { message: a.message, status: a.status, code: a.code }), a;
95
- const s = a.data;
91
+ p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, a);
92
+ const o = await B.get(i, a).json();
93
+ if (o.code)
94
+ return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, i, { message: o.message, status: o.status, code: o.code }), o;
95
+ const s = o.data;
96
96
  for (const g in s)
97
97
  !isNaN(s[g]) && Number(s[g]) !== 1 / 0 && (s[g] = Number(s[g]));
98
98
  const d = b(`${s.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
@@ -121,14 +121,14 @@ class Ct extends et {
121
121
  utc: d.utc().format()
122
122
  };
123
123
  }
124
- async trajectory(t, n, i, o, a = !0, s = {}) {
124
+ async trajectory(t, n, i, a, o = !0, s = {}) {
125
125
  (!this.token || b().diff(b(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(s);
126
126
  const d = await this.realTimePosition(t, s), r = b(n), h = b(i), M = [];
127
127
  for (; h.diff(r, "day", !0) > 30; )
128
- await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), d, o, M, s), r.add(30, "day");
129
- return await this.trajectoryIn30Day(t, r, h, d, o, M, s), M;
128
+ await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), d, a, M, s), r.add(30, "day");
129
+ return await this.trajectoryIn30Day(t, r, h, d, a, M, s), M;
130
130
  }
131
- async trajectoryIn30Day(t, n, i, o, a, s, d = {}) {
131
+ async trajectoryIn30Day(t, n, i, a, o, s, d = {}) {
132
132
  var f, x, I, m, v;
133
133
  const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
134
134
  headers: {
@@ -151,7 +151,7 @@ class Ct extends et {
151
151
  !isNaN(c[Y]) && Number(c[Y]) !== 1 / 0 && (c[Y] = Number(c[Y]));
152
152
  const w = b(`${c.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), y = c.status, { labelCn: u, labelEn: k } = this.parseStatus(y), S = {
153
153
  mmsi: c.mmsi,
154
- imo: o == null ? void 0 : o.imo,
154
+ imo: a == null ? void 0 : a.imo,
155
155
  lat: c.lat,
156
156
  lng: c.lon,
157
157
  sog: c.sog,
@@ -167,7 +167,7 @@ class Ct extends et {
167
167
  method: "trajectory",
168
168
  vendor: "myVessel",
169
169
  utc: w.utc().format()
170
- }, D = Math.floor(w.diff(g, "minute", !0) / (a || 1));
170
+ }, D = Math.floor(w.diff(g, "minute", !0) / (o || 1));
171
171
  D !== l && (l = D, s.push(S));
172
172
  }), s;
173
173
  }
@@ -179,16 +179,16 @@ class Et extends et {
179
179
  this.token = t;
180
180
  }
181
181
  async realTimePosition(t, n = {}) {
182
- const i = "https://api.hifleet.com/position/position/get/token", o = {
182
+ const i = "https://api.hifleet.com/position/position/get/token", a = {
183
183
  searchParams: {
184
184
  mmsi: t,
185
185
  usertoken: this.token
186
186
  }
187
- }, a = await B.post(i, o).json();
188
- p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, o);
189
- const s = a == null ? void 0 : a.list;
187
+ }, o = await B.post(i, a).json();
188
+ p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, a);
189
+ const s = o == null ? void 0 : o.list;
190
190
  if (!s)
191
- return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, i, a), a;
191
+ return p == null || p.warn("[%s] fetch realtime position failed: %j", n.requestId, i, o), o;
192
192
  for (const g in s)
193
193
  !isNaN(s[g]) && Number(s[g]) !== 1 / 0 && (s[g] = Number(s[g]));
194
194
  s.status = s.sp > 3 ? 0 : 1;
@@ -220,7 +220,7 @@ class Et extends et {
220
220
  }
221
221
  async search(t, n = {}) {
222
222
  let i = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
223
- const o = {
223
+ const a = {
224
224
  searchParams: {
225
225
  keyword: t
226
226
  },
@@ -230,24 +230,24 @@ class Et extends et {
230
230
  Host: "www.hifleet.com"
231
231
  }
232
232
  };
233
- let a = await B.post(i, o).json();
234
- p == null || p.info("[%s] fetch vessel props from: %s - %j", n.requestId, i, o), a instanceof Array && (a = a[0]);
235
- for (const d in a)
236
- !isNaN(a[d]) && Number(a[d]) !== 1 / 0 && (a[d] = Number(a[d]));
233
+ let o = await B.post(i, a).json();
234
+ p == null || p.info("[%s] fetch vessel props from: %s - %j", n.requestId, i, a), o instanceof Array && (o = o[0]);
235
+ for (const d in o)
236
+ !isNaN(o[d]) && Number(o[d]) !== 1 / 0 && (o[d] = Number(o[d]));
237
237
  const s = {
238
- mmsi: a.m,
239
- name: a.n,
240
- imo: a.i,
241
- callSign: a.c,
242
- length: a.l,
243
- breadth: a.b,
244
- draught: a.dr,
245
- type: a.t
238
+ mmsi: o.m,
239
+ name: o.n,
240
+ imo: o.i,
241
+ callSign: o.c,
242
+ length: o.l,
243
+ breadth: o.b,
244
+ draught: o.dr,
245
+ type: o.t
246
246
  };
247
- return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await B.post(i, o).json(), p == null || p.info("[%s] search vessel dead weight from: %s - %j", n.requestId, i, o), a instanceof Array && (a = a[0]), a && (s.deadweight = Number(a.dwt)), s;
247
+ return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, a).json(), p == null || p.info("[%s] search vessel dead weight from: %s - %j", n.requestId, i, a), o instanceof Array && (o = o[0]), o && (s.deadweight = Number(o.dwt)), s;
248
248
  }
249
249
  async suggest(t, n = {}) {
250
- const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", o = {
250
+ const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", a = {
251
251
  searchParams: {
252
252
  q: t
253
253
  },
@@ -256,10 +256,10 @@ class Et extends et {
256
256
  Origin: "https://www.hifleet.com",
257
257
  Host: "www.hifleet.com"
258
258
  }
259
- }, a = await B.post(i, o).json();
260
- p == null || p.info("[%s] suggest vessel props from: %s - %j", n.requestId, i, o);
259
+ }, o = await B.post(i, a).json();
260
+ p == null || p.info("[%s] suggest vessel props from: %s - %j", n.requestId, i, a);
261
261
  const s = [];
262
- for (const d of a)
262
+ for (const d of o)
263
263
  s.push({
264
264
  mmsi: !d.mmsi || isNaN(d.mmsi) ? null : Number(d.mmsi),
265
265
  name: d.name,
@@ -269,12 +269,12 @@ class Et extends et {
269
269
  });
270
270
  return s.sort((d, r) => r.score - d.score), s;
271
271
  }
272
- async trajectory(t, n, i, o, a = !0, s = {}) {
272
+ async trajectory(t, n, i, a, o = !0, s = {}) {
273
273
  var c, w, y;
274
274
  const d = await this.realTimePosition(t, s);
275
275
  let r = b(n);
276
276
  const h = b(i), M = b();
277
- if (a) {
277
+ if (o) {
278
278
  let u = h.diff(r, "d", !0);
279
279
  u < 0 ? r = h.clone().subtract(40, "d") : u < 30 ? r.subtract(10, "d") : u < 60 ? r.subtract(5, "d") : r = h.clone().subtract(80, "d"), u = M.diff(h, "d", !0), h.add(u > 10 ? 240 : u * 24, "h");
280
280
  }
@@ -314,7 +314,7 @@ class Et extends et {
314
314
  labelEn: S,
315
315
  method: "trajectory",
316
316
  vendor: "hifleet"
317
- }, E = Math.floor(k.diff(v, "minute", !0) / (o || 1));
317
+ }, E = Math.floor(k.diff(v, "minute", !0) / (a || 1));
318
318
  E !== m && (m = E, I.push(Y));
319
319
  }
320
320
  return I;
@@ -333,10 +333,10 @@ class Nt extends et {
333
333
  k: this.token,
334
334
  enc: 1
335
335
  }
336
- }, o = "https://api.shipxy.com/apicall/GetSingleShip", a = await B.get(o, i).json();
337
- if (p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, o, i), (a == null ? void 0 : a.status) !== 0)
338
- return a;
339
- const s = a.data[0];
336
+ }, a = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(a, i).json();
337
+ if (p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, a, i), (o == null ? void 0 : o.status) !== 0)
338
+ return o;
339
+ const s = o.data[0];
340
340
  for (const l in s)
341
341
  !isNaN(s[l]) && Number(s[l]) !== 1 / 0 && (s[l] = Number(s[l]));
342
342
  const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), h = b.unix(s.lasttime);
@@ -363,7 +363,7 @@ class Nt extends et {
363
363
  vendor: "shipxy"
364
364
  };
365
365
  }
366
- async trajectory(t, n, i, o, a = !0, s = {}) {
366
+ async trajectory(t, n, i, a, o = !0, s = {}) {
367
367
  var v;
368
368
  const d = await this.realTimePosition(t, s), r = b(n), h = b(i), M = "https://api.shipxy.com/apicall/GetShipTrack", l = {
369
369
  searchParams: {
@@ -391,7 +391,7 @@ class Nt extends et {
391
391
  utc: w.utc().format(),
392
392
  method: "trajectory",
393
393
  vendor: "shipxy"
394
- }, u = Math.floor(w.diff(I, "minute", !0) / (o || 1));
394
+ }, u = Math.floor(w.diff(I, "minute", !0) / (a || 1));
395
395
  u !== m && (m = u, x.push(y));
396
396
  }
397
397
  return x;
@@ -411,8 +411,8 @@ class Tt extends et {
411
411
  json: {
412
412
  mmsiList: t
413
413
  }
414
- }, o = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await B.post(o, i).json();
415
- return p == null || p.info("[%s] fetch ship id from: %s - %j", n.requestId, o, i), a.code !== "0" ? a : a.data[0].shipId;
414
+ }, a = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await B.post(a, i).json();
415
+ return p == null || p.info("[%s] fetch ship id from: %s - %j", n.requestId, a, i), o.code !== "0" ? o : o.data[0].shipId;
416
416
  }
417
417
  async getShipInfo(t, n = {}) {
418
418
  const i = {
@@ -422,10 +422,10 @@ class Tt extends et {
422
422
  json: {
423
423
  shipId: t
424
424
  }
425
- }, o = "https://api3.myships.com/sp/ships/aissta", a = await B.post(o, i).json();
426
- if (p == null || p.info("[%s] fetch ship info from: %s - %j", n.requestId, o, i), a.code !== "0")
427
- return a;
428
- const s = a.data;
425
+ }, a = "https://api3.myships.com/sp/ships/aissta", o = await B.post(a, i).json();
426
+ if (p == null || p.info("[%s] fetch ship info from: %s - %j", n.requestId, a, i), o.code !== "0")
427
+ return o;
428
+ const s = o.data;
429
429
  let d = s.imo;
430
430
  return t === "407170" && (d = "9198379", p == null || p.warn("[%s] ship(%s) imo error: %s, should be %s", n.requestId, t, s.imo, d)), {
431
431
  mmsi: s.mmsi,
@@ -438,21 +438,21 @@ class Tt extends et {
438
438
  };
439
439
  }
440
440
  async realTimePosition(t, n = {}) {
441
- const i = await this.getShipId(t, n), o = await this.getShipInfo(i, n), a = {
441
+ const i = await this.getShipId(t, n), a = await this.getShipInfo(i, n), o = {
442
442
  headers: {
443
443
  appKey: this.token
444
444
  },
445
445
  json: {
446
446
  shipId: i
447
447
  }
448
- }, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s, a).json();
449
- p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, s, a);
448
+ }, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s, o).json();
449
+ p == null || p.info("[%s] fetch realtime position from: %s - %j", n.requestId, s, o);
450
450
  const r = d.data[0];
451
451
  for (const f in r)
452
452
  !isNaN(r[f]) && Number(r[f]) !== 1 / 0 && (r[f] = Number(r[f]));
453
453
  const { labelCn: h, labelEn: M } = await this.parseStatus(r.aisNavStatus), l = b.unix(r.posTime);
454
454
  return {
455
- ...o,
455
+ ...a,
456
456
  mmsi: t,
457
457
  lat: Math.round(r.lat / 1e4 / 60 * 1e5) / 1e5,
458
458
  lng: Math.round(r.lon / 1e4 / 60 * 1e5) / 1e5,
@@ -469,13 +469,13 @@ class Tt extends et {
469
469
  vendor: "myship"
470
470
  };
471
471
  }
472
- async trajectory(t, n, i, o, a = !0, s = {}) {
472
+ async trajectory(t, n, i, a, o = !0, s = {}) {
473
473
  const d = b(n), r = b(i), h = await this.getShipId(t), M = await this.getShipInfo(h), l = [];
474
474
  for (; r.diff(d, "day", !0) > 30; )
475
- await this.trajectoryIn30Day(h, d.unix(), d.add(30, "day").unix(), M, t, o, l);
476
- return await this.trajectoryIn30Day(h, d.unix(), r.unix(), M, t, o, l), l;
475
+ await this.trajectoryIn30Day(h, d.unix(), d.add(30, "day").unix(), M, t, a, l);
476
+ return await this.trajectoryIn30Day(h, d.unix(), r.unix(), M, t, a, l), l;
477
477
  }
478
- async trajectoryIn30Day(t, n, i, o, a, s, d, r = {}) {
478
+ async trajectoryIn30Day(t, n, i, a, o, s, d, r = {}) {
479
479
  var I;
480
480
  const h = {
481
481
  headers: {
@@ -496,8 +496,8 @@ class Tt extends et {
496
496
  let x = -1;
497
497
  for (const m of g) {
498
498
  const v = b.unix(m.posTime), c = {
499
- imo: o == null ? void 0 : o.imo,
500
- mmsi: a,
499
+ imo: a == null ? void 0 : a.imo,
500
+ mmsi: o,
501
501
  lat: Math.round(m.lat / 1e4 / 60 * 1e5) / 1e5,
502
502
  lng: Math.round(m.lon / 1e4 / 60 * 1e5) / 1e5,
503
503
  sog: Math.round(m.sog / 10 * 100) / 100,
@@ -533,21 +533,21 @@ class Mt {
533
533
  parsePrinciple(e, t = {}) {
534
534
  var s, d, r;
535
535
  _ == null || _.info("[%s] parse rule: %s", t.requestId, e);
536
- const n = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = e.match(n) ? (s = e.match(n)) == null ? void 0 : s[0] : void 0, o = i == null ? void 0 : i.split(";");
537
- if (!o)
536
+ const n = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = e.match(n) ? (s = e.match(n)) == null ? void 0 : s[0] : void 0, a = i == null ? void 0 : i.split(";");
537
+ if (!a)
538
538
  return;
539
- const a = {};
540
- for (let h = 0; h < (o == null ? void 0 : o.length); h++) {
541
- const M = (r = (d = o[h].match(n)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
539
+ const o = {};
540
+ for (let h = 0; h < (a == null ? void 0 : a.length); h++) {
541
+ const M = (r = (d = a[h].match(n)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
542
542
  if (h === 0 && !M)
543
- a.scope = o[0];
543
+ o.scope = a[0];
544
544
  else if (M)
545
545
  for (let l = 0, g = M.length; l < g; l++) {
546
546
  const f = this.parseRule(M[l]);
547
- f && (a[f.level] ? f.key ? a[f.level][f == null ? void 0 : f.key] = f : a[f.level] = f : f.key ? a[f.level] = { [f == null ? void 0 : f.key]: f } : a[f.level] = f);
547
+ f && (o[f.level] ? f.key ? o[f.level][f == null ? void 0 : f.key] = f : o[f.level] = f : f.key ? o[f.level] = { [f == null ? void 0 : f.key]: f } : o[f.level] = f);
548
548
  }
549
549
  }
550
- return a;
550
+ return o;
551
551
  }
552
552
  /**
553
553
  * 解析单一告警规则
@@ -556,16 +556,16 @@ class Mt {
556
556
  * @param options
557
557
  */
558
558
  parseRule(e, t = {}) {
559
- var a;
559
+ var o;
560
560
  _ == null || _.info("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
561
- const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (a = e == null ? void 0 : e.match(n)) == null ? void 0 : a[0], o = i == null ? void 0 : i.split(",");
562
- if (o)
561
+ const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (o = e == null ? void 0 : e.match(n)) == null ? void 0 : o[0], a = i == null ? void 0 : i.split(",");
562
+ if (a)
563
563
  return {
564
- operator: o[0],
565
- number: Number.isNaN(Number(o[1])) ? o[1] : Number(o[1]),
566
- level: o[2],
567
- time: Number(o[3]),
568
- key: o[4]
564
+ operator: a[0],
565
+ number: Number.isNaN(Number(a[1])) ? a[1] : Number(a[1]),
566
+ level: a[2],
567
+ time: Number(a[3]),
568
+ key: a[4]
569
569
  };
570
570
  }
571
571
  /**
@@ -576,13 +576,13 @@ class Mt {
576
576
  */
577
577
  checkWeather(e, t, n = {}) {
578
578
  var f, x, I, m, v, c, w, y, u, k, S, D, Y, E, P;
579
- let i = 0, o = 0, a = 0, s = 0;
579
+ let i = 0, a = 0, o = 0, s = 0;
580
580
  const d = Math.round(((x = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.sigWave) == null ? void 0 : x.number) * 1.6 * 100) / 100, r = (m = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : m.number, h = (c = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : c.number, M = Math.round((((y = (w = t == null ? void 0 : t.SEVERE) == null ? void 0 : w.wind) == null ? void 0 : y.number) + 2) * 100) / 100, l = (k = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : k.number, g = (D = (S = t == null ? void 0 : t.HEAVY) == null ? void 0 : S.wind) == null ? void 0 : D.number;
581
581
  for (let T = 0; T < (e == null ? void 0 : e.length); T++) {
582
582
  const N = e[T], A = (E = (Y = N == null ? void 0 : N.meteo) == null ? void 0 : Y.wave) == null ? void 0 : E.sig, R = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wind, K = T ? b(N.eta).diff(b(e[T - 1].eta), "hour", !0) : 0;
583
- s = K > s ? K : s, _ == null || _.info("[%s] check sig.wave: %j", n.requestId, { ...A, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h }), (A == null ? void 0 : A.height) >= d ? N.isDangerous = !0 : (A == null ? void 0 : A.height) >= r ? N.isSevere = !0 : (A == null ? void 0 : A.height) >= h && (N.isHeavy = !0), _ == null || _.info("[%s] check wind: %j", n.requestId, { ...R, dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: g }), (R == null ? void 0 : R.scale) >= M ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > l ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === g && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? K : 0, o += N.isSevere ? K : 0, a += N.isHeavy ? K : 0;
583
+ s = K > s ? K : s, _ == null || _.info("[%s] check sig.wave: %j", n.requestId, { ...A, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h }), (A == null ? void 0 : A.height) >= d ? N.isDangerous = !0 : (A == null ? void 0 : A.height) >= r ? N.isSevere = !0 : (A == null ? void 0 : A.height) >= h && (N.isHeavy = !0), _ == null || _.info("[%s] check wind: %j", n.requestId, { ...R, dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: g }), (R == null ? void 0 : R.scale) >= M ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > l ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === g && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? K : 0, a += N.isSevere ? K : 0, o += N.isHeavy ? K : 0;
584
584
  }
585
- return i = Math.round(i * 100) / 100, o = Math.round(o * 100) / 100, a = Math.round(a * 100) / 100, s = Math.round(s), { sample: e, dangerous: i, severe: o, heavy: a, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: g }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h } };
585
+ return i = Math.round(i * 100) / 100, a = Math.round(a * 100) / 100, o = Math.round(o * 100) / 100, s = Math.round(s), { sample: e, dangerous: i, severe: a, heavy: o, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: g }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h } };
586
586
  }
587
587
  }
588
588
  const Dt = new Mt();
@@ -608,10 +608,10 @@ class O {
608
608
  * @return [0.55, 0.85]
609
609
  */
610
610
  static blockCoefficient(e, t, n, i) {
611
- let o = Math.round(e / (t * n * i) * 100) / 100;
612
- o = o < 0.55 ? 0.55 : o > 0.85 ? 0.85 : o;
613
- const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = a.map((d) => Math.abs(d - o));
614
- return a[s.indexOf(Math.min(...s))];
611
+ let a = Math.round(e / (t * n * i) * 100) / 100;
612
+ a = a < 0.55 ? 0.55 : a > 0.85 ? 0.85 : a;
613
+ const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = o.map((d) => Math.abs(d - a));
614
+ return o[s.indexOf(Math.min(...s))];
615
615
  }
616
616
  /**
617
617
  * @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
@@ -645,7 +645,7 @@ class O {
645
645
  0.8: [2.6, -13.1, -15.1],
646
646
  0.85: [3.1, -18.7, 28]
647
647
  };
648
- let a = {
648
+ let o = {
649
649
  0.55: [1.7, -1.4, -7.4],
650
650
  0.6: [2.2, -2.5, -9.7],
651
651
  0.65: [2.6, -3.7, -11.6],
@@ -654,7 +654,7 @@ class O {
654
654
  0.8: [3, -16.3, -21.6],
655
655
  0.85: [3.4, -20.9, 31.8]
656
656
  }[e];
657
- return n === "Laden" && (a = i[e]), a[0] + a[1] * t + a[2] * Math.pow(t, 2);
657
+ return n === "Laden" && (o = i[e]), o[0] + o[1] * t + o[2] * Math.pow(t, 2);
658
658
  }
659
659
  /**
660
660
  * 失速方向因子
@@ -684,8 +684,8 @@ class O {
684
684
  */
685
685
  static vesselTagFactor(e, t, n, i = 0) {
686
686
  i = i > 6 ? i - 0.9 * (i - 6) : i;
687
- let o;
688
- return n === "container" ? o = 0.7 * i + Math.pow(i, 6.5) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? o = 0.7 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(e, 2 / 3)) : o = 0.5 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(e, 2 / 3)), o;
687
+ let a;
688
+ return n === "container" ? a = 0.7 * i + Math.pow(i, 6.5) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? a = 0.7 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(e, 2 / 3)) : a = 0.5 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(e, 2 / 3)), a;
689
689
  }
690
690
  /**
691
691
  * 浪高影响因子
@@ -707,16 +707,16 @@ class O {
707
707
  */
708
708
  static assembleProperties(e, t, n, i) {
709
709
  var l;
710
- const o = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, a = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, d = e.deadweight ?? 67035.7773, r = ((l = e == null ? void 0 : e.type) == null ? void 0 : l.toLowerCase()) || "common";
710
+ const a = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, o = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, d = e.deadweight ?? 67035.7773, r = ((l = e == null ? void 0 : e.type) == null ? void 0 : l.toLowerCase()) || "common";
711
711
  return {
712
712
  tag: r.indexOf("container") > -1 ? "container" : r.indexOf("tugs") > -1 ? "tugs" : "common",
713
- lbp: o,
713
+ lbp: a,
714
714
  loadCondition: t,
715
- draught: a,
715
+ draught: o,
716
716
  breadthMoulded: s,
717
717
  // 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
718
718
  // 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
719
- displacement: Math.round((d / 1.025 + a * s * o * 0.7) * 1e4) / 1e4,
719
+ displacement: Math.round((d / 1.025 + o * s * a * 0.7) * 1e4) / 1e4,
720
720
  // 换算为m/s
721
721
  speed: Math.round((n ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
722
722
  bearing: i || 90
@@ -732,9 +732,9 @@ class O {
732
732
  * @param useMeteo true 启用气象分析
733
733
  * @param useRouteParam true 启用设置速度
734
734
  */
735
- static async speedLoseAt(e, t, n, i = "", o = 2, a = !0, s = !1, d = {}) {
735
+ static async speedLoseAt(e, t, n, i = "", a = 2, o = !0, s = !1, d = {}) {
736
736
  let r;
737
- if (t.velocity && s && (e.speed = J.roundPrecision(t.velocity * 1852 / 3600, 6)), a) {
737
+ if (t.velocity && s && (e.speed = J.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
738
738
  let h;
739
739
  if (d.meteo2)
740
740
  try {
@@ -745,7 +745,7 @@ class O {
745
745
  }
746
746
  else
747
747
  h = await mt.queryPointFactor(t.lng, t.lat, n.valueOf(), "wind,wave,current,watertemp", i, d);
748
- const M = O.weatherFactor(e, h), l = O.currentFactor(e.bearing, h == null ? void 0 : h.current, o), g = Math.round((e.speed * 1.943844 + M + l) * 100) / 100;
748
+ const M = O.weatherFactor(e, h), l = O.currentFactor(e.bearing, h == null ? void 0 : h.current, a), g = Math.round((e.speed * 1.943844 + M + l) * 100) / 100;
749
749
  r = {
750
750
  meteo: { ...h },
751
751
  wxFactor: M,
@@ -777,14 +777,14 @@ class O {
777
777
  * @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
778
778
  * @private
779
779
  */
780
- static async speedLoseInHoursStep(e, t, n, i, o, a, s = "", d = !0, r = !1, h = {}) {
780
+ static async speedLoseInHoursStep(e, t, n, i, a, o, s = "", d = !0, r = !1, h = {}) {
781
781
  t.utc();
782
782
  const M = t.clone().add(14, "days"), l = [], g = [];
783
783
  let f = 0, x = 0, I, m;
784
- for (let v = 0; v < a.length - 1; v++) {
785
- let c = a[v];
786
- c.distanceFromStart = Math.round((o + x) * 1e4) / 1e4;
787
- const w = a[v + 1];
784
+ for (let v = 0; v < o.length - 1; v++) {
785
+ let c = o[v];
786
+ c.distanceFromStart = Math.round((a + x) * 1e4) / 1e4;
787
+ const w = o[v + 1];
788
788
  if (e.bearing = W.calculateBearing(c, w, !w.gcToPrevious), c.bearing = e.bearing, c.suspend && r) {
789
789
  c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
790
790
  const k = c.suspend - c.elapsed;
@@ -795,35 +795,35 @@ class O {
795
795
  c.elapsed += S, t.add(S, "hour"), i = 0;
796
796
  }
797
797
  if (F == null || F.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`, h.requestId, c), i === 0)
798
- return c.distanceFromPrevious = x, { etd: t, from: m || c, to: c, next: a.filter((S) => S), wps: l, days: g };
798
+ return c.distanceFromPrevious = x, { etd: t, from: m || c, to: c, next: o.filter((S) => S), wps: l, days: g };
799
799
  } else
800
800
  c.suspend = 0;
801
801
  d = t.isAfter(M) ? !1 : d, c = await O.speedLoseAt(e, c, t, s, 0, d, r, h), m = m || c, c.important && l.push(c), t.isSameOrAfter(n) && (g.push(c), n.add(24, "hour"));
802
802
  const y = W.calculateDistance(c, w, !w.gcToPrevious);
803
803
  let u = Math.round(y / m.speed * 1e5) / 1e5;
804
804
  if (f + u < i) {
805
- if (f += u, t.add(u, "hour"), delete a[v], F == null || F.debug(
805
+ if (f += u, t.add(u, "hour"), delete o[v], F == null || F.debug(
806
806
  `[%s] go to %j from %j with ${y}nm, and cost ${u} hours`,
807
807
  h.requestId,
808
808
  { lat: w.lat, lng: w.lng },
809
809
  { lat: m.lat, lng: m.lng, etd: m.etd }
810
- ), x += y, a.filter((k) => k).length <= 1) {
811
- I = w, I.eta = t.utc().format(), I.distanceFromPrevious = y, I.distanceFromStart = Math.round((o + x) * 1e4) / 1e4, l.push(I), delete a[v + 1];
810
+ ), x += y, o.filter((k) => k).length <= 1) {
811
+ I = w, I.eta = t.utc().format(), I.distanceFromPrevious = y, I.distanceFromStart = Math.round((a + x) * 1e4) / 1e4, l.push(I), delete o[v + 1];
812
812
  break;
813
813
  }
814
814
  } else {
815
815
  u = i - f, t.add(u, "hour");
816
816
  const k = J.roundPrecision(m.speed * u, 5);
817
- I = W.calculateCoordinate(c, e.bearing, k, "nauticalmiles", !w.gcToPrevious), I.eta = t.utc().format(), a[v] = I, F == null || F.debug(
817
+ I = W.calculateCoordinate(c, e.bearing, k, "nauticalmiles", !w.gcToPrevious), I.eta = t.utc().format(), o[v] = I, F == null || F.debug(
818
818
  `[%s] go to %j from %j with ${k}nm, and cost ${u} hours`,
819
819
  h.requestId,
820
820
  { lat: I.lat, lng: I.lng },
821
821
  { lat: c.lat, lng: c.lng, etd: c.etd }
822
- ), x += k, I.distanceFromPrevious = Math.round(x * 1e4) / 1e4, I.distanceFromStart = Math.round((o + x) * 1e4) / 1e4;
822
+ ), x += k, I.distanceFromPrevious = Math.round(x * 1e4) / 1e4, I.distanceFromStart = Math.round((a + x) * 1e4) / 1e4;
823
823
  break;
824
824
  }
825
825
  }
826
- return { etd: t, from: m, to: I, next: a.filter((v) => v), wps: l, days: g };
826
+ return { etd: t, from: m, to: I, next: o.filter((v) => v), wps: l, days: g };
827
827
  }
828
828
  /**
829
829
  * 洋流影响因子
@@ -835,8 +835,8 @@ class O {
835
835
  const i = (e - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
836
836
  if (Math.abs(i) === Math.PI / 2)
837
837
  return 0;
838
- let o = ((t == null ? void 0 : t.kts) || 0) * Math.cos(i);
839
- return n & 2 ? o = Math.ceil(o * 100) / 100 : n & 1 ? o = Math.floor(o * 100) / 100 : o = Math.round(o * 100) / 100, Math.abs(o) > 5 ? 0 : o;
838
+ let a = ((t == null ? void 0 : t.kts) || 0) * Math.cos(i);
839
+ return n & 2 ? a = Math.ceil(a * 100) / 100 : n & 1 ? a = Math.floor(a * 100) / 100 : a = Math.round(a * 100) / 100, Math.abs(a) > 5 ? 0 : a;
840
840
  }
841
841
  /**
842
842
  * 风浪影响因子
@@ -846,13 +846,13 @@ class O {
846
846
  static weatherFactor(e, t) {
847
847
  var M, l, g, f, x, I, m;
848
848
  F == null || F.debug("calculate weather factor via: %j", { ...e, ...t });
849
- const n = O.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), i = O.froudeNumber(e.speed, e.lbp), o = O.amendFactor(n, i, e.loadCondition);
850
- let a = Math.abs(e.bearing % 360 - (((M = t == null ? void 0 : t.wind) == null ? void 0 : M.degree) % 360 || 0));
851
- a = a > 180 ? 360 - a : a;
852
- const s = O.directionFactor(a, (l = t == null ? void 0 : t.wind) == null ? void 0 : l.scale), d = O.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (g = t == null ? void 0 : t.wind) == null ? void 0 : g.scale);
853
- let r = s * o * d / 100 * e.speed;
854
- r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), F == null || F.debug("wind wx factor = %d", r), a = Math.abs(e.bearing % 360 - (((x = (f = t == null ? void 0 : t.wave) == null ? void 0 : f.sig) == null ? void 0 : x.degree) % 360 || 0));
855
- const h = O.waveHeightFactor(((m = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : m.height) ?? 1, a);
849
+ const n = O.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), i = O.froudeNumber(e.speed, e.lbp), a = O.amendFactor(n, i, e.loadCondition);
850
+ let o = Math.abs(e.bearing % 360 - (((M = t == null ? void 0 : t.wind) == null ? void 0 : M.degree) % 360 || 0));
851
+ o = o > 180 ? 360 - o : o;
852
+ const s = O.directionFactor(o, (l = t == null ? void 0 : t.wind) == null ? void 0 : l.scale), d = O.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (g = t == null ? void 0 : t.wind) == null ? void 0 : g.scale);
853
+ let r = s * a * d / 100 * e.speed;
854
+ r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), F == null || F.debug("wind wx factor = %d", r), o = Math.abs(e.bearing % 360 - (((x = (f = t == null ? void 0 : t.wave) == null ? void 0 : f.sig) == null ? void 0 : x.degree) % 360 || 0));
855
+ const h = O.waveHeightFactor(((m = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : m.height) ?? 1, o);
856
856
  return F == null || F.debug("wave wx factor = %d", h), r = r * 0.4 + h, F == null || F.debug("weather factor = %d", r), r = Math.abs(r) > 4 ? 4 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 4) * 0.1 : r, Math.round((r || 0) * 100) / 100;
857
857
  }
858
858
  /**
@@ -867,11 +867,11 @@ class O {
867
867
  * @param useMeteo true 启用气象分析
868
868
  * @param useRouteParam
869
869
  */
870
- static async analyseInstant(e, t, n, i, o, a = "", s = 0, d = !0, r = !1, h = {}) {
870
+ static async analyseInstant(e, t, n, i, a, o = "", s = 0, d = !0, r = !1, h = {}) {
871
871
  var z, U, Q, X, Z, $;
872
872
  const M = b().valueOf();
873
873
  e.lng = J.convertToStdLng(e.lng);
874
- const { route: l, waypoints: g } = o.points, f = W.calculateSubRoute(e, l);
874
+ const { route: l, waypoints: g } = a.points, f = W.calculateSubRoute(e, l);
875
875
  if (((z = f[0]) == null ? void 0 : z.length) <= 1)
876
876
  return;
877
877
  const { v0: x, label: I } = e.sog ? {
@@ -907,7 +907,7 @@ class O {
907
907
  V,
908
908
  u,
909
909
  y,
910
- a,
910
+ o,
911
911
  d,
912
912
  r,
913
913
  h
@@ -954,7 +954,7 @@ class O {
954
954
  * @param useMeteo true 启用气象分析
955
955
  * @param useRouteParam
956
956
  */
957
- static async analyseInstantWithThreshed(e, t, n, i, o, a, s, d = "", r = 3, h = !0, M = !1, l = {}) {
957
+ static async analyseInstantWithThreshed(e, t, n, i, a, o, s, d = "", r = 3, h = !0, M = !1, l = {}) {
958
958
  var Q, X, Z, $, q, V;
959
959
  const g = b().valueOf();
960
960
  e.lng = J.convertToStdLng(e.lng);
@@ -963,10 +963,10 @@ class O {
963
963
  label: "Other"
964
964
  /* Instruct */
965
965
  } : {
966
- v0: o.speed,
966
+ v0: a.speed,
967
967
  label: "CP"
968
968
  /* Cp */
969
- }, I = O.assembleProperties(i, o.loadCondition, f, 0), m = W.calculateSubRoute(e, a);
969
+ }, I = O.assembleProperties(i, a.loadCondition, f, 0), m = W.calculateSubRoute(e, o);
970
970
  if (((Q = m[0]) == null ? void 0 : Q.length) <= 1)
971
971
  return;
972
972
  const v = s.length ? W.calculateSubWaypoints(e, s) : [];
@@ -1017,7 +1017,7 @@ class O {
1017
1017
  waypoints: N,
1018
1018
  v0: f,
1019
1019
  label: x
1020
- }, { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: st, eca: at } = await this.calculateECA(A, o, l), rt = J.roundPrecision(o.fo / 24 * (k - K), 3), tt = J.roundPrecision(o.dgo / 24 * k, 3);
1020
+ }, { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: st, eca: at } = await this.calculateECA(A, a, l), rt = J.roundPrecision(a.fo / 24 * (k - K), 3), tt = J.roundPrecision(a.dgo / 24 * k, 3);
1021
1021
  A.extend = {
1022
1022
  eca: at,
1023
1023
  distanceInECA: R,
@@ -1042,10 +1042,10 @@ class O {
1042
1042
  * @param lane 基础航线(重要转向点)
1043
1043
  * @param options
1044
1044
  */
1045
- static async analyseCost(e, t, n, i, o = {}) {
1045
+ static async analyseCost(e, t, n, i, a = {}) {
1046
1046
  var m, v;
1047
- const a = b().valueOf(), s = [];
1048
- o.meteo2 = o.meteo2 || !0, e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
1047
+ const o = b().valueOf(), s = [];
1048
+ a.meteo2 = a.meteo2 || !0, e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
1049
1049
  const d = W.calculateRouteDistance(i.route);
1050
1050
  let r = 0;
1051
1051
  n.forEach((c) => {
@@ -1067,9 +1067,9 @@ class O {
1067
1067
  e.speedStep,
1068
1068
  e.useMeteo,
1069
1069
  e.useRouteParam,
1070
- o
1070
+ a
1071
1071
  );
1072
- u && (await O.calculateCost(u, c, e, o), s.push(u), F == null || F.info("[%s][L%d-%d] analyse from %s to %s cost: %j", o.requestId, 1, M, e.etd, h.format(), {
1072
+ u && (await O.calculateCost(u, c, e, a), s.push(u), F == null || F.info("[%s][L%d-%d] analyse from %s to %s cost: %j", a.requestId, 1, M, e.etd, h.format(), {
1073
1073
  cost: u.cost.total,
1074
1074
  hire: u.cost.hire,
1075
1075
  bunker: u.cost.bunker,
@@ -1086,15 +1086,15 @@ class O {
1086
1086
  S = S > 7 ? 7 : S < e.alterStep ? e.alterStep : S;
1087
1087
  let D = 2, Y = { combined: !1, speeds: [g], cost: (v = g.cost) == null ? void 0 : v.total }, E;
1088
1088
  for (; S >= e.alterStep; ) {
1089
- const P = await O.combinedAnalyse(e, t, h, [c, w], i, S, { ...o, level: D });
1089
+ const P = await O.combinedAnalyse(e, t, h, [c, w], i, S, { ...a, level: D });
1090
1090
  if (Y.cost > P.cost ? E ? (E == null ? void 0 : E.cost) > P.cost && (E = P) : (E = Y, Y = P) : (!E || (E == null ? void 0 : E.cost) > P.cost) && (E = P), S <= e.alterStep)
1091
1091
  break;
1092
1092
  S = Math.ceil(S / 2), D += 1;
1093
1093
  }
1094
1094
  f.push(Y), E && f.push(E);
1095
1095
  }
1096
- const I = b().valueOf() - a;
1097
- return F == null || F.info("[%s] analyse elapsed: %d ms", o == null ? void 0 : o.requestId, I), f.sort((c, w) => c.cost - w.cost);
1096
+ const I = b().valueOf() - o;
1097
+ return F == null || F.info("[%s] analyse elapsed: %d ms", a == null ? void 0 : a.requestId, I), f.sort((c, w) => c.cost - w.cost);
1098
1098
  }
1099
1099
  /**
1100
1100
  * 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
@@ -1106,12 +1106,12 @@ class O {
1106
1106
  * @param step 步长,7,4,2,1
1107
1107
  * @param options
1108
1108
  */
1109
- static async combinedAnalyse(e, t, n, i, o, a, s = {}) {
1110
- s.counter = 1, F == null || F.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, a);
1111
- const d = await O.alternateAnalyse(e, t, n, i, 0, o, a, s), r = d.reduce((I, m) => I + m.cost.total, 0), h = d.reduce((I, m) => I + m.cost.hire, 0), M = d.reduce((I, m) => I + m.cost.bunker, 0);
1109
+ static async combinedAnalyse(e, t, n, i, a, o, s = {}) {
1110
+ s.counter = 1, F == null || F.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, o);
1111
+ const d = await O.alternateAnalyse(e, t, n, i, 0, a, o, s), r = d.reduce((I, m) => I + m.cost.total, 0), h = d.reduce((I, m) => I + m.cost.hire, 0), M = d.reduce((I, m) => I + m.cost.bunker, 0);
1112
1112
  F == null || F.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, { cost: r, hire: h, bunker: M });
1113
- const l = await O.alternateAnalyse(e, t, n, i, 1, o, a, s), g = l.reduce((I, m) => I + m.cost.total, 0), f = l.reduce((I, m) => I + m.cost.hire, 0), x = l.reduce((I, m) => I + m.cost.bunker, 0);
1114
- return F == null || F.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, { cost: g, hire: f, bunker: x }), r < g ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step: a } : { combined: !0, cost: Math.round(g * 1e3) / 1e3, speeds: l, step: a };
1113
+ const l = await O.alternateAnalyse(e, t, n, i, 1, a, o, s), g = l.reduce((I, m) => I + m.cost.total, 0), f = l.reduce((I, m) => I + m.cost.hire, 0), x = l.reduce((I, m) => I + m.cost.bunker, 0);
1114
+ return F == null || F.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, { cost: g, hire: f, bunker: x }), r < g ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step: o } : { combined: !0, cost: Math.round(g * 1e3) / 1e3, speeds: l, step: o };
1115
1115
  }
1116
1116
  /**
1117
1117
  * 基于cp索引,交替计算指定步长下的成本
@@ -1124,12 +1124,12 @@ class O {
1124
1124
  * @param step 步长,7,4,2,1
1125
1125
  * @param options
1126
1126
  */
1127
- static async alternateAnalyse(e, t, n, i, o, a, s, d = {}) {
1127
+ static async alternateAnalyse(e, t, n, i, a, o, s, d = {}) {
1128
1128
  var l, g;
1129
1129
  let r = b.utc(e.etd);
1130
1130
  const h = { lat: e.lat, lng: e.lng }, M = [];
1131
1131
  for (; r.isBefore(n); ) {
1132
- const f = r.clone().utc().add(s, "day"), x = JSON.parse(JSON.stringify(a.route)), I = JSON.parse(JSON.stringify(a.waypoints)), m = i[o], v = await O.analyseInstantWithThreshed(
1132
+ const f = r.clone().utc().add(s, "day"), x = JSON.parse(JSON.stringify(o.route)), I = JSON.parse(JSON.stringify(o.waypoints)), m = i[a], v = await O.analyseInstantWithThreshed(
1133
1133
  h,
1134
1134
  r.utc().format(),
1135
1135
  f,
@@ -1161,7 +1161,7 @@ class O {
1161
1161
  )), d.counter = d.counter + 1;
1162
1162
  const c = (g = (l = v == null ? void 0 : v.sample) == null ? void 0 : l.hours) == null ? void 0 : g.at(-1);
1163
1163
  if (c)
1164
- h.lat = c.lat, h.lng = c.lng, r = b(c.eta), M.push(v), o = o ? 0 : 1;
1164
+ h.lat = c.lat, h.lng = c.lng, r = b(c.eta), M.push(v), a = a ? 0 : 1;
1165
1165
  else
1166
1166
  break;
1167
1167
  }
@@ -1175,12 +1175,12 @@ class O {
1175
1175
  * @param options
1176
1176
  */
1177
1177
  static async calculateCost(e, t, n, i = {}) {
1178
- var o;
1178
+ var a;
1179
1179
  if (e) {
1180
- const a = Math.round(e.totalHrs / 24 * (n.dailyHire || 0) * (1 - (n.addComm || 0)) * 1e3) / 1e3, s = Math.round(e.totalFoCons * (n.priceFO || 0) * 1e3) / 1e3, d = Math.round((e.totalDgoCons + (((o = e.extend) == null ? void 0 : o.totalDgoConsInECA) || 0)) * (n.priceDGO || 0) * 1e3) / 1e3;
1180
+ const o = Math.round(e.totalHrs / 24 * (n.dailyHire || 0) * (1 - (n.addComm || 0)) * 1e3) / 1e3, s = Math.round(e.totalFoCons * (n.priceFO || 0) * 1e3) / 1e3, d = Math.round((e.totalDgoCons + (((a = e.extend) == null ? void 0 : a.totalDgoConsInECA) || 0)) * (n.priceDGO || 0) * 1e3) / 1e3;
1181
1181
  e.cost = {
1182
- total: Math.round((a + s + d) * 1e3) / 1e3,
1183
- hire: a,
1182
+ total: Math.round((o + s + d) * 1e3) / 1e3,
1183
+ hire: o,
1184
1184
  bunker: Math.round((s + d) * 1e3) / 1e3,
1185
1185
  cp: t
1186
1186
  };
@@ -1193,18 +1193,18 @@ class O {
1193
1193
  static async calculateECA(e, t, n = {}) {
1194
1194
  var d, r;
1195
1195
  const i = await W.intersectInECA(e.route);
1196
- let o = 0, a = 0, s = 0;
1196
+ let a = 0, o = 0, s = 0;
1197
1197
  e.sample.wps.forEach((h) => {
1198
1198
  h.positionTime = b.utc(h.etd || h.eta).unix();
1199
1199
  });
1200
1200
  for (const h of i) {
1201
- o += h.distance;
1201
+ a += h.distance;
1202
1202
  const M = await W.deadReckoningTime((d = h.waypoints) == null ? void 0 : d.at(0), e.sample.wps), l = await W.deadReckoningTime((r = h.waypoints) == null ? void 0 : r.at(-1), e.sample.wps);
1203
- h.in = M, h.out = l, h.totalHrs = J.roundPrecision((l.positionTime - M.positionTime) / 3600, 2), h.totalDgoCons = J.roundPrecision(t.fo / 24 * h.totalHrs, 3), a += h.totalHrs, s += h.totalDgoCons;
1203
+ h.in = M, h.out = l, h.totalHrs = J.roundPrecision((l.positionTime - M.positionTime) / 3600, 2), h.totalDgoCons = J.roundPrecision(t.fo / 24 * h.totalHrs, 3), o += h.totalHrs, s += h.totalDgoCons;
1204
1204
  }
1205
- return o = J.roundPrecision(o, 3), a = J.roundPrecision(a, 3), s = J.roundPrecision(s, 3), {
1206
- distanceInECA: o,
1207
- hoursInECA: a,
1205
+ return a = J.roundPrecision(a, 3), o = J.roundPrecision(o, 3), s = J.roundPrecision(s, 3), {
1206
+ distanceInECA: a,
1207
+ hoursInECA: o,
1208
1208
  totalDgoConsInECA: s,
1209
1209
  eca: i
1210
1210
  };
@@ -1220,16 +1220,16 @@ class O {
1220
1220
  hours: [],
1221
1221
  wps: [],
1222
1222
  days: []
1223
- }, i = e.reduce((y, u) => y + u.distance, 0), o = e.reduce((y, u) => {
1223
+ }, i = e.reduce((y, u) => y + u.distance, 0), a = e.reduce((y, u) => {
1224
1224
  var k;
1225
1225
  return y + (((k = u.extend) == null ? void 0 : k.distanceInECA) || 0);
1226
- }, 0), a = e.reduce((y, u) => y + u.totalHrs, 0), s = e.reduce((y, u) => {
1226
+ }, 0), o = e.reduce((y, u) => y + u.totalHrs, 0), s = e.reduce((y, u) => {
1227
1227
  var k;
1228
1228
  return y + (((k = u.extend) == null ? void 0 : k.hoursInECA) || 0);
1229
1229
  }, 0), d = e.reduce((y, u) => {
1230
1230
  var k;
1231
1231
  return y + (((k = u.extend) == null ? void 0 : k.totalDgoConsInECA) || 0);
1232
- }, 0), r = e.reduce((y, u) => y + u.wxFactor * u.totalHrs / a, 0), h = e.reduce((y, u) => y + u.cFactor * u.totalHrs / a, 0), M = e.reduce((y, u) => y + u.totalFoCons, 0), l = e.reduce((y, u) => y + u.totalDgoCons, 0), g = e.reduce((y, u) => y + u.cost.total, 0), f = e.reduce((y, u) => y + u.cost.hire, 0), x = e.reduce((y, u) => y + u.cost.bunker, 0), I = [], m = [];
1232
+ }, 0), r = e.reduce((y, u) => y + u.wxFactor * u.totalHrs / o, 0), h = e.reduce((y, u) => y + u.cFactor * u.totalHrs / o, 0), M = e.reduce((y, u) => y + u.totalFoCons, 0), l = e.reduce((y, u) => y + u.totalDgoCons, 0), g = e.reduce((y, u) => y + u.cost.total, 0), f = e.reduce((y, u) => y + u.cost.hire, 0), x = e.reduce((y, u) => y + u.cost.bunker, 0), I = [], m = [];
1233
1233
  let v;
1234
1234
  for (const y of e) {
1235
1235
  m.push(...((c = y.extend) == null ? void 0 : c.eca) || []);
@@ -1274,10 +1274,10 @@ class O {
1274
1274
  v0: e.at(0).v0,
1275
1275
  label: "Combined",
1276
1276
  distance: Math.round(i * 1e4) / 1e4,
1277
- totalHrs: Math.round(a * 1e3) / 1e3,
1278
- avgSpeed: Math.round(i / a * 1e3) / 1e3,
1279
- wxFactor: Math.round(r / a * 1e3) / 1e3,
1280
- cFactor: Math.round(h / a * 1e3) / 1e3,
1277
+ totalHrs: Math.round(o * 1e3) / 1e3,
1278
+ avgSpeed: Math.round(i / o * 1e3) / 1e3,
1279
+ wxFactor: Math.round(r * 1e3) / 1e3,
1280
+ cFactor: Math.round(h * 1e3) / 1e3,
1281
1281
  totalFoCons: Math.round(M * 1e3) / 1e3,
1282
1282
  totalDgoCons: Math.round(l * 1e3) / 1e3,
1283
1283
  cost: {
@@ -1288,7 +1288,7 @@ class O {
1288
1288
  extend: {
1289
1289
  cps: I,
1290
1290
  eca: m,
1291
- distanceInECA: Math.round(o * 1e4) / 1e4,
1291
+ distanceInECA: Math.round(a * 1e4) / 1e4,
1292
1292
  hoursInECA: Math.round(s * 1e3) / 1e3,
1293
1293
  totalDgoConsInECA: Math.round(d * 1e3) / 1e3,
1294
1294
  speeds: e
@@ -1 +1 @@
1
- (function(q,R){typeof exports=="object"&&typeof module<"u"?R(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],R):(q=typeof globalThis<"u"?globalThis:q||self,R(q["idm-plugin-rabbitmq"]={},q.got,q["@log4js-node/log4js-api"],q.moment,q["@idm-plugin/geo2"],q["@idm-plugin/meteo2"],q["@idm-plugin/meteo"]))})(this,function(q,R,G,b,T,rt,ct){"use strict";var St=Object.defineProperty;var kt=(q,R,G)=>R in q?St(q,R,{enumerable:!0,configurable:!0,writable:!0,value:G}):q[R]=G;var z=(q,R,G)=>(kt(q,typeof R!="symbol"?R+"":R,G),G);let g;try{g=G.getLogger("vessel")}catch{}finally{}class U{parseStatus(e){let t,o;switch(e){case 0:t="在航(主机推动)",o="The engine is in use";break;case 1:t="锚泊",o="Anchored";break;case 2:t="失控",o="Not operated";break;case 3:t="操纵受限",o="Limited airworthiness";break;case 4:t="吃水受限",o="Limited by ship's draft";break;case 5:t="靠泊",o="Mooring";break;case 6:t="搁浅",o="Stranded";break;case 7:t="捕捞作业",o="Engaged in fishing";break;case 8:t="靠帆船提供动力",o="Sailing";break;default:t="未定义",o="Undefined"}return{labelCn:t,labelEn:o}}}class yt extends U{constructor(t,o){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=t,this.clientSecret=o}async authToken(t={}){const o="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await R.post(o,i).json();g==null||g.info("[%s] fetch access token from: %s - %j",t.requestId,o,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:b().utc().format()})}async realTimePosition(t,o={}){var l,M,h;(!this.token||b().diff(b(this.token.issuedAt),"seconds")>((l=this.token)==null?void 0:l.expiresIn)-300)&&await this.authToken(o);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(h=this.token)==null?void 0:h.accessToken}`},searchParams:{mmsi:t}};g==null||g.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const a=await R.get(i,n).json();if(a.code)return g==null||g.warn("[%s] fetch realtime position failed: %j",o.requestId,i,{message:a.message,status:a.status,code:a.code}),a;const s=a.data;for(const p in s)!isNaN(s[p])&&Number(s[p])!==1/0&&(s[p]=Number(s[p]));const d=b(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName,imo:s.imo,callSign:s.callsign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?b.utc(s.eta).format():void 0,destination:s.dest,positionTime:d.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,o,i,n,a=!0,s={}){(!this.token||b().diff(b(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(t,s),r=b(o),l=b(i),M=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,n,M,s),r.add(30,"day");return await this.trajectoryIn30Day(t,r,l,d,n,M,s),M}async trajectoryIn30Day(t,o,i,n,a,s,d={}){var f,j,I,m,v;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(j=this.token)==null?void 0:j.accessToken}`},json:{mmsi:t,startTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};g==null||g.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,l);const M=await R.post(r,l).json();if(M.code)return g==null||g.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:M.message,status:M.status,code:M.code}),M;let h=-1;const p=b(`${(m=(I=M.data)==null?void 0:I[0])==null?void 0:m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=M.data)==null||v.forEach(c=>{for(const P in c)!isNaN(c[P])&&Number(c[P])!==1/0&&(c[P]=Number(c[P]));const w=b(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),y=c.status,{labelCn:u,labelEn:S}=this.parseStatus(y),F={mmsi:c.mmsi,imo:n==null?void 0:n.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:y,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?b(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:w.unix(),labelCn:u,labelEn:S,method:"trajectory",vendor:"myVessel",utc:w.utc().format()},N=Math.floor(w.diff(p,"minute",!0)/(a||1));N!==h&&(h=N,s.push(F))}),s}}class Mt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},a=await R.post(i,n).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const s=a==null?void 0:a.list;if(!s)return g==null||g.warn("[%s] fetch realtime position failed: %j",o.requestId,i,a),a;for(const p in s)!isNaN(s[p])&&Number(s[p])!==1/0&&(s[p]=Number(s[p]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:l}=this.parseStatus(d),M=b(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?b.utc(s.eta).format():void 0,destination:s.destination,positionTime:M.unix(),utc:M.utc().format(),status:d,labelCn:r,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,o={}){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 a=await R.post(i,n).json();g==null||g.info("[%s] fetch vessel props from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]);for(const d in a)!isNaN(a[d])&&Number(a[d])!==1/0&&(a[d]=Number(a[d]));const s={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr,type:a.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await R.post(i,n).json(),g==null||g.info("[%s] search vessel dead weight from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]),a&&(s.deadweight=Number(a.dwt)),s}async suggest(t,o={}){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"}},a=await R.post(i,n).json();g==null||g.info("[%s] suggest vessel props from: %s - %j",o.requestId,i,n);const s=[];for(const d of a)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(t,o,i,n,a=!0,s={}){var c,w,y;const d=await this.realTimePosition(t,s);let r=b(o);const l=b(i),M=b();if(a){let u=l.diff(r,"d",!0);u<0?r=l.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=l.clone().subtract(80,"d"),u=M.diff(l,"d",!0),l.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},p="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await R.get(p,h).json();g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,p,h);let j;f&&(j=((w=(c=f.ships)==null?void 0:c.offors)==null?void 0:w.ship)||[],j.length||g==null||g.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const I=[];let m=-1;const v=b(`${(y=j==null?void 0:j[0])==null?void 0:y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of j){for(const L in u)!isNaN(u[L])&&Number(u[L])!==1/0&&(u[L]=Number(u[L]));const S=b(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:F,labelCn:N}=this.parseStatus(u.status),P={mmsi:u.m,name:u.n,imo:d==null?void 0:d.imo,lat:u.la,lng:u.lo,draught:u.draught,sog:u.sp,cog:u.co,hdg:u.hdg,positionTime:S.unix(),utc:S.utc().format(),status:u.status,labelCn:N,labelEn:F,method:"trajectory",vendor:"hifleet"},H=Math.floor(S.diff(v,"minute",!0)/(n||1));H!==m&&(m=H,I.push(P))}return I}}class pt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",a=await R.get(n,i).json();if(g==null||g.info("[%s] fetch realtime position from: %s - %j",o.requestId,n,i),(a==null?void 0:a.status)!==0)return a;const s=a.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),l=b.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:l.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,o,i,n,a=!0,s={}){var v;const d=await this.realTimePosition(t,s),r=b(o),l=b(i),M="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:l.unix()}},p=await R.get(M,h).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,M,h),(p==null?void 0:p.status)!==0)return p;const f=p==null?void 0:p.points,j=[],I=b.unix((v=f[0])==null?void 0:v.utc);let m=-1;for(const c of f){const w=b.unix(c.utc),y={imo:d==null?void 0:d.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:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(w.diff(I,"minute",!0)/(n||1));u!==m&&(m=u,j.push(y))}return j}}class bt extends U{constructor(t){super();z(this,"token");this.token=t}async getShipId(t,o={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await R.post(n,i).json();return g==null||g.info("[%s] fetch ship id from: %s - %j",o.requestId,n,i),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,o={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",a=await R.post(n,i).json();if(g==null||g.info("[%s] fetch ship info from: %s - %j",o.requestId,n,i),a.code!=="0")return a;const s=a.data;let d=s.imo;return t==="407170"&&(d="9198379",g==null||g.warn("[%s] ship(%s) imo error: %s, should be %s",o.requestId,t,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,o={}){const i=await this.getShipId(t,o),n=await this.getShipInfo(i,o),a={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await R.post(s,a).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",o.requestId,s,a);const r=d.data[0];for(const f in r)!isNaN(r[f])&&Number(r[f])!==1/0&&(r[f]=Number(r[f]));const{labelCn:l,labelEn:M}=await this.parseStatus(r.aisNavStatus),h=b.unix(r.posTime);return{...n,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:h.utc().format(),status:r.aisNavStatus,labelEn:M,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,o,i,n,a=!0,s={}){const d=b(o),r=b(i),l=await this.getShipId(t),M=await this.getShipInfo(l),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(l,d.unix(),d.add(30,"day").unix(),M,t,n,h);return await this.trajectoryIn30Day(l,d.unix(),r.unix(),M,t,n,h),h}async trajectoryIn30Day(t,o,i,n,a,s,d,r={}){var I;const l={headers:{appKey:this.token},json:{shipId:t,startTime:o,endTime:i}},M="https://api3.myships.com/sp/ships/position/history",h=await R.post(M,l).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",r.requestId,M,l),h.code!=="0")return g==null||g.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const p=h.data;for(const m in p)!isNaN(p[m])&&Number(p[m])!==1/0&&(p[m]=Number(p[m]));const f=b.unix((I=p[0])==null?void 0:I.posTime);let j=-1;for(const m of p){const v=b.unix(m.posTime),c={imo:n==null?void 0:n.imo,mmsi:a,lat:Math.round(m.lat/1e4/60*1e5)/1e5,lng:Math.round(m.lon/1e4/60*1e5)/1e5,sog:Math.round(m.sog/10*100)/100,cog:Math.round(m.cog/10*100)/100,hdg:Math.round(m.heading*100)/100,rot:Math.round(m.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},w=Math.floor(v.diff(f,"minute",!0)/(s||1));w!==j&&(j=w,d.push(c))}return d}}let _;try{_=G.getLogger("vessel")}catch{}finally{}var dt=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(dt||{});class ut{parsePrinciple(e,t={}){var s,d,r;_==null||_.info("[%s] parse rule: %s",t.requestId,e);const o=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(o)?(s=e.match(o))==null?void 0:s[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const a={};for(let l=0;l<(n==null?void 0:n.length);l++){const M=(r=(d=n[l].match(o))==null?void 0:d[0])==null?void 0:r.split("],");if(l===0&&!M)a.scope=n[0];else if(M)for(let h=0,p=M.length;h<p;h++){const f=this.parseRule(M[h]);f&&(a[f.level]?f.key?a[f.level][f==null?void 0:f.key]=f:a[f.level]=f:f.key?a[f.level]={[f==null?void 0:f.key]:f}:a[f.level]=f)}}return a}parseRule(e,t={}){var a;_==null||_.info("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const o=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(a=e==null?void 0:e.match(o))==null?void 0:a[0],n=i==null?void 0:i.split(",");if(n)return{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:Number(n[3]),key:n[4]}}checkWeather(e,t,o={}){var f,j,I,m,v,c,w,y,u,S,F,N,P,H,L;let i=0,n=0,a=0,s=0;const d=Math.round(((j=(f=t==null?void 0:t.SEVERE)==null?void 0:f.sigWave)==null?void 0:j.number)*1.6*100)/100,r=(m=(I=t==null?void 0:t.SEVERE)==null?void 0:I.sigWave)==null?void 0:m.number,l=(c=(v=t==null?void 0:t.HEAVY)==null?void 0:v.sigWave)==null?void 0:c.number,M=Math.round((((y=(w=t==null?void 0:t.SEVERE)==null?void 0:w.wind)==null?void 0:y.number)+2)*100)/100,h=(S=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:S.number,p=(N=(F=t==null?void 0:t.HEAVY)==null?void 0:F.wind)==null?void 0:N.number;for(let x=0;x<(e==null?void 0:e.length);x++){const E=e[x],A=(H=(P=E==null?void 0:E.meteo)==null?void 0:P.wave)==null?void 0:H.sig,V=(L=E==null?void 0:E.meteo)==null?void 0:L.wind,K=x?b(E.eta).diff(b(e[x-1].eta),"hour",!0):0;s=K>s?K:s,_==null||_.info("[%s] check sig.wave: %j",o.requestId,{...A,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}),(A==null?void 0:A.height)>=d?E.isDangerous=!0:(A==null?void 0:A.height)>=r?E.isSevere=!0:(A==null?void 0:A.height)>=l&&(E.isHeavy=!0),_==null||_.info("[%s] check wind: %j",o.requestId,{...V,dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:p}),(V==null?void 0:V.scale)>=M?(E.isDangerous=!0,delete E.isSevere,delete E.isHeavy):(V==null?void 0:V.scale)>h?(E.isDangerous||(E.isSevere=!0),delete E.isHeavy):(V==null?void 0:V.scale)===p&&!E.isDangerous&&!E.isSevere&&(E.isHeavy=!0),i+=E.isDangerous?K:0,n+=E.isSevere?K:0,a+=E.isHeavy?K:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,a=Math.round(a*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:n,heavy:a,step:s<3?3:s,wind:{dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:p},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}}}}const gt=new ut;let k;try{k=G.getLogger("vessel")}catch{}finally{}const vt=new rt.MeteoHelper2("",!0);var lt=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(lt||{}),ht=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(ht||{}),ft=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ft||{});class W{static blockCoefficient(e,t,o,i){let n=Math.round(e/(t*o*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const a=[.55,.6,.65,.7,.75,.8,.85],s=a.map(d=>Math.abs(d-n));return a[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,o=9.8){let i=Math.round(Math.sqrt(e*e/(o*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,t,o){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 a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return o==="Laden"&&(a=i[e]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(e,t=0){let o;return e>30&&e<=60?o=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?o=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?o=(.4-.03*Math.pow(t-8,2))/2:o=1,Math.round(o*1e5)/1e5}static vesselTagFactor(e,t,o,i=0){i=i>6?i-.9*(i-6):i;let n;return o==="container"?n=.7*i+Math.pow(i,6.5)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)):n=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let o;return t>30&&t<=60?o=-.6:t>60&&t<=90?o=-.4:t>90&&t<=120?o=e<3?.4:-.3:t>120&&t<=150?o=e<3?.6:-.5:t>150&&t<=180?o=e<3?.7:-.6:o=-.7,Math.round(o*(.144*Math.pow(e,2)+.178*e)*1e4)/1e4}static assembleProperties(e,t,o,i){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,a=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,d=e.deadweight??67035.7773,r=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:a,breadthMoulded:s,displacement:Math.round((d/1.025+a*s*n*.7)*1e4)/1e4,speed:Math.round((o??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,o,i="",n=2,a=!0,s=!1,d={}){let r;if(t.velocity&&s&&(e.speed=T.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){let l;if(d.meteo2)try{const f=await vt.spotForecast(t.lat,t.lng,o.utc().format(),!1,!1,!0,d),[j]=ct.Meteo2Assist.pickHourly(f,o);l=ct.Meteo2Assist.toLegacy(j)}catch(f){k.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...t,eta:o.utc().format()},f)}else l=await rt.MeteoHelper.queryPointFactor(t.lng,t.lat,o.valueOf(),"wind,wave,current,watertemp",i,d);const M=W.weatherFactor(e,l),h=W.currentFactor(e.bearing,l==null?void 0:l.current,n),p=Math.round((e.speed*1.943844+M+h)*100)/100;r={meteo:{...l},wxFactor:M,cFactor:h,speed:t.velocity&&s?t.velocity:p<0?1:p,eta:o.utc().format(),etd:o.utc().format()}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round((e.speed*1.943844+0+0)*100)/100,eta:o.utc().format(),etd:o.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(e,t,o,i,n,a,s="",d=!0,r=!1,l={}){t.utc();const M=t.clone().add(14,"days"),h=[],p=[];let f=0,j=0,I,m;for(let v=0;v<a.length-1;v++){let c=a[v];c.distanceFromStart=Math.round((n+j)*1e4)/1e4;const w=a[v+1];if(e.bearing=T.LaneHelper.calculateBearing(c,w,!w.gcToPrevious),c.bearing=e.bearing,c.suspend&&r){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const S=c.suspend-c.elapsed;if(i-f>S)i=i-f-S,t.add(S,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,t.add(F,"hour"),i=0}if(k==null||k.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=j,{etd:t,from:m||c,to:c,next:a.filter(F=>F),wps:h,days:p}}else c.suspend=0;d=t.isAfter(M)?!1:d,c=await W.speedLoseAt(e,c,t,s,0,d,r,l),m=m||c,c.important&&h.push(c),t.isSameOrAfter(o)&&(p.push(c),o.add(24,"hour"));const y=T.LaneHelper.calculateDistance(c,w,!w.gcToPrevious);let u=Math.round(y/m.speed*1e5)/1e5;if(f+u<i){if(f+=u,t.add(u,"hour"),delete a[v],k==null||k.debug(`[%s] go to %j from %j with ${y}nm, and cost ${u} hours`,l.requestId,{lat:w.lat,lng:w.lng},{lat:m.lat,lng:m.lng,etd:m.etd}),j+=y,a.filter(S=>S).length<=1){I=w,I.eta=t.utc().format(),I.distanceFromPrevious=y,I.distanceFromStart=Math.round((n+j)*1e4)/1e4,h.push(I),delete a[v+1];break}}else{u=i-f,t.add(u,"hour");const S=T.LngLatHelper.roundPrecision(m.speed*u,5);I=T.LaneHelper.calculateCoordinate(c,e.bearing,S,"nauticalmiles",!w.gcToPrevious),I.eta=t.utc().format(),a[v]=I,k==null||k.debug(`[%s] go to %j from %j with ${S}nm, and cost ${u} hours`,l.requestId,{lat:I.lat,lng:I.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),j+=S,I.distanceFromPrevious=Math.round(j*1e4)/1e4,I.distanceFromStart=Math.round((n+j)*1e4)/1e4;break}}return{etd:t,from:m,to:I,next:a.filter(v=>v),wps:h,days:p}}static currentFactor(e,t,o=0){const i=(e-(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 o&2?n=Math.ceil(n*100)/100:o&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t){var M,h,p,f,j,I,m;k==null||k.debug("calculate weather factor via: %j",{...e,...t});const o=W.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),i=W.froudeNumber(e.speed,e.lbp),n=W.amendFactor(o,i,e.loadCondition);let a=Math.abs(e.bearing%360-(((M=t==null?void 0:t.wind)==null?void 0:M.degree)%360||0));a=a>180?360-a:a;const s=W.directionFactor(a,(h=t==null?void 0:t.wind)==null?void 0:h.scale),d=W.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(p=t==null?void 0:t.wind)==null?void 0:p.scale);let r=s*n*d/100*e.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),k==null||k.debug("wind wx factor = %d",r),a=Math.abs(e.bearing%360-(((j=(f=t==null?void 0:t.wave)==null?void 0:f.sig)==null?void 0:j.degree)%360||0));const l=W.waveHeightFactor(((m=(I=t==null?void 0:t.wave)==null?void 0:I.sig)==null?void 0:m.height)??1,a);return k==null||k.debug("wave wx factor = %d",l),r=r*.4+l,k==null||k.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(e,t,o,i,n,a="",s=0,d=!0,r=!1,l={}){var Q,X,Z,$,tt,et;const M=b().valueOf();e.lng=T.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:p}=n.points,f=T.LaneHelper.calculateSubRoute(e,h);if(((Q=f[0])==null?void 0:Q.length)<=1)return;const{v0:j,label:I}=e.sog?{v0:e.sog,label:"Other"}:{v0:i.speed,label:"CP"},m=W.assembleProperties(o,i.loadCondition,j,0),v=p.length?T.LaneHelper.calculateSubWaypoints(e,p):[];v.forEach(Y=>Y.important=!0);const c={from:{...e},route:f,waypoints:v,v0:j,label:I},w={hours:[],days:[],wps:[]};s||(T.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let y=T.LaneHelper.simplifyRouteToCoordinates(f,v,0),u=0,S=0,F=0,N=0;t=b(t).utc();const P=t.clone();for(;y.length>0;){const Y=s-t.hour()%s,J=Math.ceil(t.clone().add(Y,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,C=await W.speedLoseInHoursStep(m,t,P,J,u,y,a,d,r,l);(X=C.from)!=null&&X.speed&&(w.hours.push(C.from),w.wps.push(...C.wps),w.days.push(...C.days)),y=C==null?void 0:C.next,y.length||w.hours.push(C==null?void 0:C.to),u+=Math.round((((Z=C==null?void 0:C.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const H=w.hours;for(let Y=0;Y<H.length-1;Y++){const J=b(H[Y+1].eta).diff(H[Y].etd,"hour",!0)||1;S+=(H[Y].wxFactor||0)*J,F+=(H[Y].cFactor||0)*J,N+=J}($=w.wps)==null||$.forEach((Y,J)=>{Y.positionTime=b.utc(Y.etd||Y.eta).unix();const C=w.wps[J-1];if(C){const B=Y.distanceFromStart-C.distanceFromStart,O=b(Y.eta||Y.etd).diff(b(C.etd||C.eta),"h",!0);Y.avgSpd=Math.round(B/O*100)/100;const it=T.LaneHelper.calculateBearing(C,Y);C.bearing=it}}),w.wps=(tt=w.wps)==null?void 0:tt.reduce((Y,J)=>(Y.some(C=>Math.round(C.positionTime/60)===Math.round(J.positionTime/60))||Y.push(J),Y),[]),c.sample=w;const L=w.hours.at(0),x=w.hours.at(-1);c.distance=Math.round(x.distanceFromStart*1e4)/1e4,c.etd=b(L.eta).utc().format(),c.eta=b(x.eta).utc().format(),c.wxFactor=Math.round(S/N*1e4)/1e4,c.cFactor=Math.round(F/N*1e4)/1e4,c.avgSpeed=Math.round(x.distanceFromStart/N*1e4)/1e4,c.totalHrs=Math.round(N*1e4)/1e4;const{distanceInECA:E,hoursInECA:A,totalDgoConsInECA:V,eca:K}=await this.calculateECA(c,i,l),at=T.LngLatHelper.roundPrecision(i.fo/24*(N-A),3),nt=T.LngLatHelper.roundPrecision(i.dgo/24*N,3);c.extend={eca:K,distanceInECA:E,hoursInECA:A,totalDgoConsInECA:V},c.totalFoCons=at,c.totalDgoCons=nt;const st=b().valueOf()-M,ot=((et=w==null?void 0:w.hours)==null?void 0:et.length)||1;return k==null||k.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,st,ot,Math.round(st/ot*1e3)/1e3),c}static async analyseInstantWithThreshed(e,t,o,i,n,a,s,d="",r=3,l=!0,M=!1,h={}){var Z,$,tt,et,Y,J;const p=b().valueOf();e.lng=T.LngLatHelper.convertToStdLng(e.lng);const{v0:f,label:j}=e.sog?{v0:e.sog,label:"Other"}:{v0:n.speed,label:"CP"},I=W.assembleProperties(i,n.loadCondition,f,0),m=T.LaneHelper.calculateSubRoute(e,a);if(((Z=m[0])==null?void 0:Z.length)<=1)return;const v=s.length?T.LaneHelper.calculateSubWaypoints(e,s):[];v.forEach(C=>C.important=!0);let c=T.LaneHelper.simplifyRouteToCoordinates(m,v,0),w=0,y=0,u=0,S=0;const F={hours:[],wps:[],days:[]};t=b(t).utc();const N=t.clone();for(;c.length>0;){const C=r-t.hour()%r;let B=Math.ceil(t.clone().add(C,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;B=t.clone().add(B,"h").isSameOrAfter(o)?o.diff(t,"h",!0)*1e4/1e4:B;const O=await W.speedLoseInHoursStep(I,t,N,B,w,c,d,l,M,h);if(($=O.from)!=null&&$.speed&&(F.hours.push(O.from),O!=null&&O.wps&&F.wps.push(...O.wps),F.days.push(...O.days)),c=O==null?void 0:O.next,c.length||F.hours.push(O==null?void 0:O.to),w+=Math.round((((tt=O==null?void 0:O.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!B)break}F.wps=(et=F.wps)==null?void 0:et.reduce((C,B)=>(C.some(O=>Math.round(b(O.etd).unix()/60)===Math.round(b(B.etd).unix()/60))||C.push(B),C),[]),(Y=F.wps)==null||Y.forEach((C,B)=>{const O=F.wps[B-1];if(O){const it=C.distanceFromStart-O.distanceFromStart,wt=b(C.eta||C.etd).diff(b(O.etd||O.eta),"h",!0);C.avgSpd=Math.round(it/wt*100)/100;const It=T.LaneHelper.calculateBearing(O,C);O.bearing=It}});const P=F.hours;for(let C=0;C<P.length-1;C++){const B=b(P[C+1].eta).diff(P[C].etd,"hour",!0);y+=P[C].wxFactor*B,u+=P[C].cFactor*B,S+=B}const H=F.hours.at(0),L=F.hours.at(-1),x=await T.LaneHelper.calculateRangeRoute(H,L,m),E=await T.LaneHelper.calculateRangeWaypoints(H,L,m,v),A={sample:F,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:b(H.eta).utc().format(),eta:b(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(y/S*1e4)/1e4,cFactor:Math.round(u/S*1e4)/1e4,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/S*1e4)/1e4,totalHrs:Math.round(S*1e4)/1e4,from:H,to:L,route:x,waypoints:E,v0:f,label:j},{distanceInECA:V,hoursInECA:K,totalDgoConsInECA:at,eca:nt}=await this.calculateECA(A,n,h),mt=T.LngLatHelper.roundPrecision(n.fo/24*(S-K),3),st=T.LngLatHelper.roundPrecision(n.dgo/24*S,3);A.extend={eca:nt,distanceInECA:V,hoursInECA:K,totalDgoConsInECA:at},A.totalDgoCons=st,A.totalFoCons=mt;const Q=b().valueOf()-p,X=((J=F==null?void 0:F.hours)==null?void 0:J.length)||1;return k==null||k.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,Q,X,Math.round(Q/X*1e3)/1e3),A}static async analyseCost(e,t,o,i,n={}){var m,v;const a=b().valueOf(),s=[];n.meteo2=n.meteo2||!0,e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const d=T.LaneHelper.calculateRouteDistance(i.route);let r=0;o.forEach(c=>{const w=Math.ceil(d/c.speed/24);r=r<w?w:r}),r=r*1.3;const l=b.utc(e.etd).add(r??14,"day");let M=1;for(const c of o){const w=JSON.parse(JSON.stringify(i.route)),y=JSON.parse(JSON.stringify(i.waypoints)),u=await W.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,l,t,c,w,y,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);u&&(await W.calculateCost(u,c,e,n),s.push(u),k==null||k.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,M,e.etd,l.format(),{cost:u.cost.total,hire:u.cost.hire,bunker:u.cost.bunker,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),M++}s.sort((c,w)=>c.cost.total-w.cost.total);const h=s.at(0),p=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(m=h.cost)==null?void 0:m.total}),p){const c=h.cost.cp,w=p.cost.cp,y=b(h.eta),u=b(h.etd),S=y.diff(u,"days",!0);let F=Math.ceil(S/2);F=F>7?7:F<e.alterStep?e.alterStep:F;let N=2,P={combined:!1,speeds:[p],cost:(v=p.cost)==null?void 0:v.total},H;for(;F>=e.alterStep;){const L=await W.combinedAnalyse(e,t,l,[c,w],i,F,{...n,level:N});if(P.cost>L.cost?H?(H==null?void 0:H.cost)>L.cost&&(H=L):(H=P,P=L):(!H||(H==null?void 0:H.cost)>L.cost)&&(H=L),F<=e.alterStep)break;F=Math.ceil(F/2),N+=1}f.push(P),H&&f.push(H)}const I=b().valueOf()-a;return k==null||k.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,I),f.sort((c,w)=>c.cost-w.cost)}static async combinedAnalyse(e,t,o,i,n,a,s={}){s.counter=1,k==null||k.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,a);const d=await W.alternateAnalyse(e,t,o,i,0,n,a,s),r=d.reduce((I,m)=>I+m.cost.total,0),l=d.reduce((I,m)=>I+m.cost.hire,0),M=d.reduce((I,m)=>I+m.cost.bunker,0);k==null||k.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:r,hire:l,bunker:M});const h=await W.alternateAnalyse(e,t,o,i,1,n,a,s),p=h.reduce((I,m)=>I+m.cost.total,0),f=h.reduce((I,m)=>I+m.cost.hire,0),j=h.reduce((I,m)=>I+m.cost.bunker,0);return k==null||k.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:p,hire:f,bunker:j}),r<p?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:a}:{combined:!0,cost:Math.round(p*1e3)/1e3,speeds:h,step:a}}static async alternateAnalyse(e,t,o,i,n,a,s,d={}){var h,p;let r=b.utc(e.etd);const l={lat:e.lat,lng:e.lng},M=[];for(;r.isBefore(o);){const f=r.clone().utc().add(s,"day"),j=JSON.parse(JSON.stringify(a.route)),I=JSON.parse(JSON.stringify(a.waypoints)),m=i[n],v=await W.analyseInstantWithThreshed(l,r.utc().format(),f,t,m,j,I,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,d);v&&(await W.calculateCost(v,m,e,d),k==null||k.info("[%s][L%d-%d] analyse from %s to %s cost: %j",d.requestId,d.level,d.counter,r.utc().format(),f.utc().format(),{cost:v.cost.total,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),d.counter=d.counter+1;const c=(p=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:p.at(-1);if(c)l.lat=c.lat,l.lng=c.lng,r=b(c.eta),M.push(v),n=n?0:1;else break}return M}static async calculateCost(e,t,o,i={}){var n;if(e){const a=Math.round(e.totalHrs/24*(o.dailyHire||0)*(1-(o.addComm||0))*1e3)/1e3,s=Math.round(e.totalFoCons*(o.priceFO||0)*1e3)/1e3,d=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(o.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((a+s+d)*1e3)/1e3,hire:a,bunker:Math.round((s+d)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,o={}){var d,r;const i=await T.LaneHelper.intersectInECA(e.route);let n=0,a=0,s=0;e.sample.wps.forEach(l=>{l.positionTime=b.utc(l.etd||l.eta).unix()});for(const l of i){n+=l.distance;const M=await T.LaneHelper.deadReckoningTime((d=l.waypoints)==null?void 0:d.at(0),e.sample.wps),h=await T.LaneHelper.deadReckoningTime((r=l.waypoints)==null?void 0:r.at(-1),e.sample.wps);l.in=M,l.out=h,l.totalHrs=T.LngLatHelper.roundPrecision((h.positionTime-M.positionTime)/3600,2),l.totalDgoCons=T.LngLatHelper.roundPrecision(t.fo/24*l.totalHrs,3),a+=l.totalHrs,s+=l.totalDgoCons}return n=T.LngLatHelper.roundPrecision(n,3),a=T.LngLatHelper.roundPrecision(a,3),s=T.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:a,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(e,t={}){var c,w;const o={hours:[],wps:[],days:[]},i=e.reduce((y,u)=>y+u.distance,0),n=e.reduce((y,u)=>{var S;return y+(((S=u.extend)==null?void 0:S.distanceInECA)||0)},0),a=e.reduce((y,u)=>y+u.totalHrs,0),s=e.reduce((y,u)=>{var S;return y+(((S=u.extend)==null?void 0:S.hoursInECA)||0)},0),d=e.reduce((y,u)=>{var S;return y+(((S=u.extend)==null?void 0:S.totalDgoConsInECA)||0)},0),r=e.reduce((y,u)=>y+u.wxFactor*u.totalHrs/a,0),l=e.reduce((y,u)=>y+u.cFactor*u.totalHrs/a,0),M=e.reduce((y,u)=>y+u.totalFoCons,0),h=e.reduce((y,u)=>y+u.totalDgoCons,0),p=e.reduce((y,u)=>y+u.cost.total,0),f=e.reduce((y,u)=>y+u.cost.hire,0),j=e.reduce((y,u)=>y+u.cost.bunker,0),I=[],m=[];let v;for(const y of e){m.push(...((c=y.extend)==null?void 0:c.eca)||[]);const u=y.sample.hours,S=y.sample.wps,F=y.sample.days,N=u.at(0);v&&(N.distanceFromPrevious=v.distanceFromPrevious,N.distanceFromStart=v.distanceFromStart,u.forEach((x,E)=>{E&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)}),S.at(0).distanceFromPrevious=v.distanceFromPrevious,S.at(0).distanceFromStart=v.distanceFromStart,S.forEach((x,E)=>{E&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)}),F.at(0).distanceFromPrevious=v.distanceFromPrevious,F.at(0).distanceFromStart=v.distanceFromStart,F.forEach((x,E)=>{E&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)})),N.cp=y.cost.cp;const P=[y.etd,y.eta],H=I.findIndex(x=>x.id===N.cp.id);H===-1?(N.cp.segment=[P],I.push(N.cp)):I[H].segment.push(P),u.forEach(x=>{var A;((A=o.hours)==null?void 0:A.findIndex(V=>V.eta===x.eta))===-1&&o.hours.push(x)}),S.forEach(x=>{var A;((A=o.wps)==null?void 0:A.findIndex(V=>V.eta===x.eta))===-1&&o.wps.push(x)}),F.forEach(x=>{var A;((A=o==null?void 0:o.days)==null?void 0:A.findIndex(V=>V.eta===x.eta))===-1&&o.days.push(x)});const L=(w=o.wps)==null?void 0:w.findIndex(x=>x.eta===N.eta);L===-1?o.wps.push(N):o.wps[L]=N,v=u.at(-1)}return o.wps.sort((y,u)=>{b(y.etd).unix()-b(u.etd).unix()}),o.wps.forEach((y,u)=>{const S=o.wps[u-1];if(S){const F=y.distanceFromStart-(S.distanceFromStart||0),N=b(y.eta||y.etd).diff(b(S.etd||S.eta),"hour",!0),P=Math.round(F/N*100)/100;y.avgSpd=P;const H=T.LaneHelper.calculateBearing(S,y);S.bearing=H}}),{sample:o,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(i*1e4)/1e4,totalHrs:Math.round(a*1e3)/1e3,avgSpeed:Math.round(i/a*1e3)/1e3,wxFactor:Math.round(r/a*1e3)/1e3,cFactor:Math.round(l/a*1e3)/1e3,totalFoCons:Math.round(M*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(p*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(j*1e3)/1e3},extend:{cps:I,eca:m,distanceInECA:Math.round(n*1e4)/1e4,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:e}}}}q.AISImpl=U,q.AlertHelper=ut,q.AlertLevel=dt,q.HifleetImpl=Mt,q.LoadCondition=ht,q.MyShipImpl=bt,q.MyVesselImpl=yt,q.ShipxyImpl=pt,q.SpeedHelper=W,q.SpeedLabel=ft,q.VesselTag=lt,q.alertHelper=gt,Object.defineProperty(q,Symbol.toStringTag,{value:"Module"})});
1
+ (function(q,R){typeof exports=="object"&&typeof module<"u"?R(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],R):(q=typeof globalThis<"u"?globalThis:q||self,R(q["idm-plugin-rabbitmq"]={},q.got,q["@log4js-node/log4js-api"],q.moment,q["@idm-plugin/geo2"],q["@idm-plugin/meteo2"],q["@idm-plugin/meteo"]))})(this,function(q,R,G,b,T,rt,ct){"use strict";var St=Object.defineProperty;var kt=(q,R,G)=>R in q?St(q,R,{enumerable:!0,configurable:!0,writable:!0,value:G}):q[R]=G;var z=(q,R,G)=>(kt(q,typeof R!="symbol"?R+"":R,G),G);let g;try{g=G.getLogger("vessel")}catch{}finally{}class U{parseStatus(e){let t,o;switch(e){case 0:t="在航(主机推动)",o="The engine is in use";break;case 1:t="锚泊",o="Anchored";break;case 2:t="失控",o="Not operated";break;case 3:t="操纵受限",o="Limited airworthiness";break;case 4:t="吃水受限",o="Limited by ship's draft";break;case 5:t="靠泊",o="Mooring";break;case 6:t="搁浅",o="Stranded";break;case 7:t="捕捞作业",o="Engaged in fishing";break;case 8:t="靠帆船提供动力",o="Sailing";break;default:t="未定义",o="Undefined"}return{labelCn:t,labelEn:o}}}class yt extends U{constructor(t,o){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=t,this.clientSecret=o}async authToken(t={}){const o="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},a=await R.post(o,i).json();g==null||g.info("[%s] fetch access token from: %s - %j",t.requestId,o,a),a.error||(this.token={accessToken:a.access_token,tokenType:a.token_type,expiresIn:a.expires_in,scope:a.scope,jti:a.jti,issuedAt:b().utc().format()})}async realTimePosition(t,o={}){var l,M,h;(!this.token||b().diff(b(this.token.issuedAt),"seconds")>((l=this.token)==null?void 0:l.expiresIn)-300)&&await this.authToken(o);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",a={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(h=this.token)==null?void 0:h.accessToken}`},searchParams:{mmsi:t}};g==null||g.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,a);const n=await R.get(i,a).json();if(n.code)return g==null||g.warn("[%s] fetch realtime position failed: %j",o.requestId,i,{message:n.message,status:n.status,code:n.code}),n;const s=n.data;for(const p in s)!isNaN(s[p])&&Number(s[p])!==1/0&&(s[p]=Number(s[p]));const d=b(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName,imo:s.imo,callSign:s.callsign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?b.utc(s.eta).format():void 0,destination:s.dest,positionTime:d.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,o,i,a,n=!0,s={}){(!this.token||b().diff(b(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(t,s),r=b(o),l=b(i),M=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,a,M,s),r.add(30,"day");return await this.trajectoryIn30Day(t,r,l,d,a,M,s),M}async trajectoryIn30Day(t,o,i,a,n,s,d={}){var f,j,I,m,v;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(j=this.token)==null?void 0:j.accessToken}`},json:{mmsi:t,startTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};g==null||g.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,l);const M=await R.post(r,l).json();if(M.code)return g==null||g.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:M.message,status:M.status,code:M.code}),M;let h=-1;const p=b(`${(m=(I=M.data)==null?void 0:I[0])==null?void 0:m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=M.data)==null||v.forEach(c=>{for(const P in c)!isNaN(c[P])&&Number(c[P])!==1/0&&(c[P]=Number(c[P]));const w=b(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),y=c.status,{labelCn:u,labelEn:S}=this.parseStatus(y),F={mmsi:c.mmsi,imo:a==null?void 0:a.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:y,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?b(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:w.unix(),labelCn:u,labelEn:S,method:"trajectory",vendor:"myVessel",utc:w.utc().format()},N=Math.floor(w.diff(p,"minute",!0)/(n||1));N!==h&&(h=N,s.push(F))}),s}}class Mt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i="https://api.hifleet.com/position/position/get/token",a={searchParams:{mmsi:t,usertoken:this.token}},n=await R.post(i,a).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,a);const s=n==null?void 0:n.list;if(!s)return g==null||g.warn("[%s] fetch realtime position failed: %j",o.requestId,i,n),n;for(const p in s)!isNaN(s[p])&&Number(s[p])!==1/0&&(s[p]=Number(s[p]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:l}=this.parseStatus(d),M=b(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?b.utc(s.eta).format():void 0,destination:s.destination,positionTime:M.unix(),utc:M.utc().format(),status:d,labelCn:r,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,o={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const a={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let n=await R.post(i,a).json();g==null||g.info("[%s] fetch vessel props from: %s - %j",o.requestId,i,a),n instanceof Array&&(n=n[0]);for(const d in n)!isNaN(n[d])&&Number(n[d])!==1/0&&(n[d]=Number(n[d]));const s={mmsi:n.m,name:n.n,imo:n.i,callSign:n.c,length:n.l,breadth:n.b,draught:n.dr,type:n.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",n=await R.post(i,a).json(),g==null||g.info("[%s] search vessel dead weight from: %s - %j",o.requestId,i,a),n instanceof Array&&(n=n[0]),n&&(s.deadweight=Number(n.dwt)),s}async suggest(t,o={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",a={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},n=await R.post(i,a).json();g==null||g.info("[%s] suggest vessel props from: %s - %j",o.requestId,i,a);const s=[];for(const d of n)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(t,o,i,a,n=!0,s={}){var c,w,y;const d=await this.realTimePosition(t,s);let r=b(o);const l=b(i),M=b();if(n){let u=l.diff(r,"d",!0);u<0?r=l.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=l.clone().subtract(80,"d"),u=M.diff(l,"d",!0),l.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},p="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await R.get(p,h).json();g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,p,h);let j;f&&(j=((w=(c=f.ships)==null?void 0:c.offors)==null?void 0:w.ship)||[],j.length||g==null||g.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const I=[];let m=-1;const v=b(`${(y=j==null?void 0:j[0])==null?void 0:y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of j){for(const L in u)!isNaN(u[L])&&Number(u[L])!==1/0&&(u[L]=Number(u[L]));const S=b(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:F,labelCn:N}=this.parseStatus(u.status),P={mmsi:u.m,name:u.n,imo:d==null?void 0:d.imo,lat:u.la,lng:u.lo,draught:u.draught,sog:u.sp,cog:u.co,hdg:u.hdg,positionTime:S.unix(),utc:S.utc().format(),status:u.status,labelCn:N,labelEn:F,method:"trajectory",vendor:"hifleet"},H=Math.floor(S.diff(v,"minute",!0)/(a||1));H!==m&&(m=H,I.push(P))}return I}}class pt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i={searchParams:{id:t,k:this.token,enc:1}},a="https://api.shipxy.com/apicall/GetSingleShip",n=await R.get(a,i).json();if(g==null||g.info("[%s] fetch realtime position from: %s - %j",o.requestId,a,i),(n==null?void 0:n.status)!==0)return n;const s=n.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),l=b.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:l.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,o,i,a,n=!0,s={}){var v;const d=await this.realTimePosition(t,s),r=b(o),l=b(i),M="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:l.unix()}},p=await R.get(M,h).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,M,h),(p==null?void 0:p.status)!==0)return p;const f=p==null?void 0:p.points,j=[],I=b.unix((v=f[0])==null?void 0:v.utc);let m=-1;for(const c of f){const w=b.unix(c.utc),y={imo:d==null?void 0:d.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:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(w.diff(I,"minute",!0)/(a||1));u!==m&&(m=u,j.push(y))}return j}}class bt extends U{constructor(t){super();z(this,"token");this.token=t}async getShipId(t,o={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},a="https://api3.myships.com/sp/ships/getShipIdByMMSI",n=await R.post(a,i).json();return g==null||g.info("[%s] fetch ship id from: %s - %j",o.requestId,a,i),n.code!=="0"?n:n.data[0].shipId}async getShipInfo(t,o={}){const i={headers:{appKey:this.token},json:{shipId:t}},a="https://api3.myships.com/sp/ships/aissta",n=await R.post(a,i).json();if(g==null||g.info("[%s] fetch ship info from: %s - %j",o.requestId,a,i),n.code!=="0")return n;const s=n.data;let d=s.imo;return t==="407170"&&(d="9198379",g==null||g.warn("[%s] ship(%s) imo error: %s, should be %s",o.requestId,t,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,o={}){const i=await this.getShipId(t,o),a=await this.getShipInfo(i,o),n={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await R.post(s,n).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",o.requestId,s,n);const r=d.data[0];for(const f in r)!isNaN(r[f])&&Number(r[f])!==1/0&&(r[f]=Number(r[f]));const{labelCn:l,labelEn:M}=await this.parseStatus(r.aisNavStatus),h=b.unix(r.posTime);return{...a,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:h.utc().format(),status:r.aisNavStatus,labelEn:M,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,o,i,a,n=!0,s={}){const d=b(o),r=b(i),l=await this.getShipId(t),M=await this.getShipInfo(l),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(l,d.unix(),d.add(30,"day").unix(),M,t,a,h);return await this.trajectoryIn30Day(l,d.unix(),r.unix(),M,t,a,h),h}async trajectoryIn30Day(t,o,i,a,n,s,d,r={}){var I;const l={headers:{appKey:this.token},json:{shipId:t,startTime:o,endTime:i}},M="https://api3.myships.com/sp/ships/position/history",h=await R.post(M,l).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",r.requestId,M,l),h.code!=="0")return g==null||g.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const p=h.data;for(const m in p)!isNaN(p[m])&&Number(p[m])!==1/0&&(p[m]=Number(p[m]));const f=b.unix((I=p[0])==null?void 0:I.posTime);let j=-1;for(const m of p){const v=b.unix(m.posTime),c={imo:a==null?void 0:a.imo,mmsi:n,lat:Math.round(m.lat/1e4/60*1e5)/1e5,lng:Math.round(m.lon/1e4/60*1e5)/1e5,sog:Math.round(m.sog/10*100)/100,cog:Math.round(m.cog/10*100)/100,hdg:Math.round(m.heading*100)/100,rot:Math.round(m.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},w=Math.floor(v.diff(f,"minute",!0)/(s||1));w!==j&&(j=w,d.push(c))}return d}}let _;try{_=G.getLogger("vessel")}catch{}finally{}var dt=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(dt||{});class ut{parsePrinciple(e,t={}){var s,d,r;_==null||_.info("[%s] parse rule: %s",t.requestId,e);const o=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(o)?(s=e.match(o))==null?void 0:s[0]:void 0,a=i==null?void 0:i.split(";");if(!a)return;const n={};for(let l=0;l<(a==null?void 0:a.length);l++){const M=(r=(d=a[l].match(o))==null?void 0:d[0])==null?void 0:r.split("],");if(l===0&&!M)n.scope=a[0];else if(M)for(let h=0,p=M.length;h<p;h++){const f=this.parseRule(M[h]);f&&(n[f.level]?f.key?n[f.level][f==null?void 0:f.key]=f:n[f.level]=f:f.key?n[f.level]={[f==null?void 0:f.key]:f}:n[f.level]=f)}}return n}parseRule(e,t={}){var n;_==null||_.info("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const o=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(n=e==null?void 0:e.match(o))==null?void 0:n[0],a=i==null?void 0:i.split(",");if(a)return{operator:a[0],number:Number.isNaN(Number(a[1]))?a[1]:Number(a[1]),level:a[2],time:Number(a[3]),key:a[4]}}checkWeather(e,t,o={}){var f,j,I,m,v,c,w,y,u,S,F,N,P,H,L;let i=0,a=0,n=0,s=0;const d=Math.round(((j=(f=t==null?void 0:t.SEVERE)==null?void 0:f.sigWave)==null?void 0:j.number)*1.6*100)/100,r=(m=(I=t==null?void 0:t.SEVERE)==null?void 0:I.sigWave)==null?void 0:m.number,l=(c=(v=t==null?void 0:t.HEAVY)==null?void 0:v.sigWave)==null?void 0:c.number,M=Math.round((((y=(w=t==null?void 0:t.SEVERE)==null?void 0:w.wind)==null?void 0:y.number)+2)*100)/100,h=(S=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:S.number,p=(N=(F=t==null?void 0:t.HEAVY)==null?void 0:F.wind)==null?void 0:N.number;for(let x=0;x<(e==null?void 0:e.length);x++){const E=e[x],A=(H=(P=E==null?void 0:E.meteo)==null?void 0:P.wave)==null?void 0:H.sig,V=(L=E==null?void 0:E.meteo)==null?void 0:L.wind,K=x?b(E.eta).diff(b(e[x-1].eta),"hour",!0):0;s=K>s?K:s,_==null||_.info("[%s] check sig.wave: %j",o.requestId,{...A,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}),(A==null?void 0:A.height)>=d?E.isDangerous=!0:(A==null?void 0:A.height)>=r?E.isSevere=!0:(A==null?void 0:A.height)>=l&&(E.isHeavy=!0),_==null||_.info("[%s] check wind: %j",o.requestId,{...V,dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:p}),(V==null?void 0:V.scale)>=M?(E.isDangerous=!0,delete E.isSevere,delete E.isHeavy):(V==null?void 0:V.scale)>h?(E.isDangerous||(E.isSevere=!0),delete E.isHeavy):(V==null?void 0:V.scale)===p&&!E.isDangerous&&!E.isSevere&&(E.isHeavy=!0),i+=E.isDangerous?K:0,a+=E.isSevere?K:0,n+=E.isHeavy?K:0}return i=Math.round(i*100)/100,a=Math.round(a*100)/100,n=Math.round(n*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:a,heavy:n,step:s<3?3:s,wind:{dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:p},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}}}}const gt=new ut;let k;try{k=G.getLogger("vessel")}catch{}finally{}const vt=new rt.MeteoHelper2("",!0);var lt=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(lt||{}),ht=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(ht||{}),ft=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ft||{});class W{static blockCoefficient(e,t,o,i){let a=Math.round(e/(t*o*i)*100)/100;a=a<.55?.55:a>.85?.85:a;const n=[.55,.6,.65,.7,.75,.8,.85],s=n.map(d=>Math.abs(d-a));return n[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,o=9.8){let i=Math.round(Math.sqrt(e*e/(o*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,t,o){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let n={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return o==="Laden"&&(n=i[e]),n[0]+n[1]*t+n[2]*Math.pow(t,2)}static directionFactor(e,t=0){let o;return e>30&&e<=60?o=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?o=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?o=(.4-.03*Math.pow(t-8,2))/2:o=1,Math.round(o*1e5)/1e5}static vesselTagFactor(e,t,o,i=0){i=i>6?i-.9*(i-6):i;let a;return o==="container"?a=.7*i+Math.pow(i,6.5)/(22*Math.pow(e,2/3)):t==="Ballast"?a=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)):a=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)),a}static waveHeightFactor(e,t){e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let o;return t>30&&t<=60?o=-.6:t>60&&t<=90?o=-.4:t>90&&t<=120?o=e<3?.4:-.3:t>120&&t<=150?o=e<3?.6:-.5:t>150&&t<=180?o=e<3?.7:-.6:o=-.7,Math.round(o*(.144*Math.pow(e,2)+.178*e)*1e4)/1e4}static assembleProperties(e,t,o,i){var h;const a=e.lbp??e.length??e.lengthOverall??198.9642,n=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,d=e.deadweight??67035.7773,r=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:a,loadCondition:t,draught:n,breadthMoulded:s,displacement:Math.round((d/1.025+n*s*a*.7)*1e4)/1e4,speed:Math.round((o??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,o,i="",a=2,n=!0,s=!1,d={}){let r;if(t.velocity&&s&&(e.speed=T.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),n){let l;if(d.meteo2)try{const f=await vt.spotForecast(t.lat,t.lng,o.utc().format(),!1,!1,!0,d),[j]=ct.Meteo2Assist.pickHourly(f,o);l=ct.Meteo2Assist.toLegacy(j)}catch(f){k.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...t,eta:o.utc().format()},f)}else l=await rt.MeteoHelper.queryPointFactor(t.lng,t.lat,o.valueOf(),"wind,wave,current,watertemp",i,d);const M=W.weatherFactor(e,l),h=W.currentFactor(e.bearing,l==null?void 0:l.current,a),p=Math.round((e.speed*1.943844+M+h)*100)/100;r={meteo:{...l},wxFactor:M,cFactor:h,speed:t.velocity&&s?t.velocity:p<0?1:p,eta:o.utc().format(),etd:o.utc().format()}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round((e.speed*1.943844+0+0)*100)/100,eta:o.utc().format(),etd:o.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(e,t,o,i,a,n,s="",d=!0,r=!1,l={}){t.utc();const M=t.clone().add(14,"days"),h=[],p=[];let f=0,j=0,I,m;for(let v=0;v<n.length-1;v++){let c=n[v];c.distanceFromStart=Math.round((a+j)*1e4)/1e4;const w=n[v+1];if(e.bearing=T.LaneHelper.calculateBearing(c,w,!w.gcToPrevious),c.bearing=e.bearing,c.suspend&&r){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const S=c.suspend-c.elapsed;if(i-f>S)i=i-f-S,t.add(S,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,t.add(F,"hour"),i=0}if(k==null||k.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=j,{etd:t,from:m||c,to:c,next:n.filter(F=>F),wps:h,days:p}}else c.suspend=0;d=t.isAfter(M)?!1:d,c=await W.speedLoseAt(e,c,t,s,0,d,r,l),m=m||c,c.important&&h.push(c),t.isSameOrAfter(o)&&(p.push(c),o.add(24,"hour"));const y=T.LaneHelper.calculateDistance(c,w,!w.gcToPrevious);let u=Math.round(y/m.speed*1e5)/1e5;if(f+u<i){if(f+=u,t.add(u,"hour"),delete n[v],k==null||k.debug(`[%s] go to %j from %j with ${y}nm, and cost ${u} hours`,l.requestId,{lat:w.lat,lng:w.lng},{lat:m.lat,lng:m.lng,etd:m.etd}),j+=y,n.filter(S=>S).length<=1){I=w,I.eta=t.utc().format(),I.distanceFromPrevious=y,I.distanceFromStart=Math.round((a+j)*1e4)/1e4,h.push(I),delete n[v+1];break}}else{u=i-f,t.add(u,"hour");const S=T.LngLatHelper.roundPrecision(m.speed*u,5);I=T.LaneHelper.calculateCoordinate(c,e.bearing,S,"nauticalmiles",!w.gcToPrevious),I.eta=t.utc().format(),n[v]=I,k==null||k.debug(`[%s] go to %j from %j with ${S}nm, and cost ${u} hours`,l.requestId,{lat:I.lat,lng:I.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),j+=S,I.distanceFromPrevious=Math.round(j*1e4)/1e4,I.distanceFromStart=Math.round((a+j)*1e4)/1e4;break}}return{etd:t,from:m,to:I,next:n.filter(v=>v),wps:h,days:p}}static currentFactor(e,t,o=0){const i=(e-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let a=((t==null?void 0:t.kts)||0)*Math.cos(i);return o&2?a=Math.ceil(a*100)/100:o&1?a=Math.floor(a*100)/100:a=Math.round(a*100)/100,Math.abs(a)>5?0:a}static weatherFactor(e,t){var M,h,p,f,j,I,m;k==null||k.debug("calculate weather factor via: %j",{...e,...t});const o=W.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),i=W.froudeNumber(e.speed,e.lbp),a=W.amendFactor(o,i,e.loadCondition);let n=Math.abs(e.bearing%360-(((M=t==null?void 0:t.wind)==null?void 0:M.degree)%360||0));n=n>180?360-n:n;const s=W.directionFactor(n,(h=t==null?void 0:t.wind)==null?void 0:h.scale),d=W.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(p=t==null?void 0:t.wind)==null?void 0:p.scale);let r=s*a*d/100*e.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),k==null||k.debug("wind wx factor = %d",r),n=Math.abs(e.bearing%360-(((j=(f=t==null?void 0:t.wave)==null?void 0:f.sig)==null?void 0:j.degree)%360||0));const l=W.waveHeightFactor(((m=(I=t==null?void 0:t.wave)==null?void 0:I.sig)==null?void 0:m.height)??1,n);return k==null||k.debug("wave wx factor = %d",l),r=r*.4+l,k==null||k.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(e,t,o,i,a,n="",s=0,d=!0,r=!1,l={}){var Q,X,Z,$,tt,et;const M=b().valueOf();e.lng=T.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:p}=a.points,f=T.LaneHelper.calculateSubRoute(e,h);if(((Q=f[0])==null?void 0:Q.length)<=1)return;const{v0:j,label:I}=e.sog?{v0:e.sog,label:"Other"}:{v0:i.speed,label:"CP"},m=W.assembleProperties(o,i.loadCondition,j,0),v=p.length?T.LaneHelper.calculateSubWaypoints(e,p):[];v.forEach(Y=>Y.important=!0);const c={from:{...e},route:f,waypoints:v,v0:j,label:I},w={hours:[],days:[],wps:[]};s||(T.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let y=T.LaneHelper.simplifyRouteToCoordinates(f,v,0),u=0,S=0,F=0,N=0;t=b(t).utc();const P=t.clone();for(;y.length>0;){const Y=s-t.hour()%s,J=Math.ceil(t.clone().add(Y,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,C=await W.speedLoseInHoursStep(m,t,P,J,u,y,n,d,r,l);(X=C.from)!=null&&X.speed&&(w.hours.push(C.from),w.wps.push(...C.wps),w.days.push(...C.days)),y=C==null?void 0:C.next,y.length||w.hours.push(C==null?void 0:C.to),u+=Math.round((((Z=C==null?void 0:C.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const H=w.hours;for(let Y=0;Y<H.length-1;Y++){const J=b(H[Y+1].eta).diff(H[Y].etd,"hour",!0)||1;S+=(H[Y].wxFactor||0)*J,F+=(H[Y].cFactor||0)*J,N+=J}($=w.wps)==null||$.forEach((Y,J)=>{Y.positionTime=b.utc(Y.etd||Y.eta).unix();const C=w.wps[J-1];if(C){const B=Y.distanceFromStart-C.distanceFromStart,O=b(Y.eta||Y.etd).diff(b(C.etd||C.eta),"h",!0);Y.avgSpd=Math.round(B/O*100)/100;const it=T.LaneHelper.calculateBearing(C,Y);C.bearing=it}}),w.wps=(tt=w.wps)==null?void 0:tt.reduce((Y,J)=>(Y.some(C=>Math.round(C.positionTime/60)===Math.round(J.positionTime/60))||Y.push(J),Y),[]),c.sample=w;const L=w.hours.at(0),x=w.hours.at(-1);c.distance=Math.round(x.distanceFromStart*1e4)/1e4,c.etd=b(L.eta).utc().format(),c.eta=b(x.eta).utc().format(),c.wxFactor=Math.round(S/N*1e4)/1e4,c.cFactor=Math.round(F/N*1e4)/1e4,c.avgSpeed=Math.round(x.distanceFromStart/N*1e4)/1e4,c.totalHrs=Math.round(N*1e4)/1e4;const{distanceInECA:E,hoursInECA:A,totalDgoConsInECA:V,eca:K}=await this.calculateECA(c,i,l),at=T.LngLatHelper.roundPrecision(i.fo/24*(N-A),3),nt=T.LngLatHelper.roundPrecision(i.dgo/24*N,3);c.extend={eca:K,distanceInECA:E,hoursInECA:A,totalDgoConsInECA:V},c.totalFoCons=at,c.totalDgoCons=nt;const st=b().valueOf()-M,ot=((et=w==null?void 0:w.hours)==null?void 0:et.length)||1;return k==null||k.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,st,ot,Math.round(st/ot*1e3)/1e3),c}static async analyseInstantWithThreshed(e,t,o,i,a,n,s,d="",r=3,l=!0,M=!1,h={}){var Z,$,tt,et,Y,J;const p=b().valueOf();e.lng=T.LngLatHelper.convertToStdLng(e.lng);const{v0:f,label:j}=e.sog?{v0:e.sog,label:"Other"}:{v0:a.speed,label:"CP"},I=W.assembleProperties(i,a.loadCondition,f,0),m=T.LaneHelper.calculateSubRoute(e,n);if(((Z=m[0])==null?void 0:Z.length)<=1)return;const v=s.length?T.LaneHelper.calculateSubWaypoints(e,s):[];v.forEach(C=>C.important=!0);let c=T.LaneHelper.simplifyRouteToCoordinates(m,v,0),w=0,y=0,u=0,S=0;const F={hours:[],wps:[],days:[]};t=b(t).utc();const N=t.clone();for(;c.length>0;){const C=r-t.hour()%r;let B=Math.ceil(t.clone().add(C,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;B=t.clone().add(B,"h").isSameOrAfter(o)?o.diff(t,"h",!0)*1e4/1e4:B;const O=await W.speedLoseInHoursStep(I,t,N,B,w,c,d,l,M,h);if(($=O.from)!=null&&$.speed&&(F.hours.push(O.from),O!=null&&O.wps&&F.wps.push(...O.wps),F.days.push(...O.days)),c=O==null?void 0:O.next,c.length||F.hours.push(O==null?void 0:O.to),w+=Math.round((((tt=O==null?void 0:O.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!B)break}F.wps=(et=F.wps)==null?void 0:et.reduce((C,B)=>(C.some(O=>Math.round(b(O.etd).unix()/60)===Math.round(b(B.etd).unix()/60))||C.push(B),C),[]),(Y=F.wps)==null||Y.forEach((C,B)=>{const O=F.wps[B-1];if(O){const it=C.distanceFromStart-O.distanceFromStart,wt=b(C.eta||C.etd).diff(b(O.etd||O.eta),"h",!0);C.avgSpd=Math.round(it/wt*100)/100;const It=T.LaneHelper.calculateBearing(O,C);O.bearing=It}});const P=F.hours;for(let C=0;C<P.length-1;C++){const B=b(P[C+1].eta).diff(P[C].etd,"hour",!0);y+=P[C].wxFactor*B,u+=P[C].cFactor*B,S+=B}const H=F.hours.at(0),L=F.hours.at(-1),x=await T.LaneHelper.calculateRangeRoute(H,L,m),E=await T.LaneHelper.calculateRangeWaypoints(H,L,m,v),A={sample:F,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:b(H.eta).utc().format(),eta:b(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(y/S*1e4)/1e4,cFactor:Math.round(u/S*1e4)/1e4,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/S*1e4)/1e4,totalHrs:Math.round(S*1e4)/1e4,from:H,to:L,route:x,waypoints:E,v0:f,label:j},{distanceInECA:V,hoursInECA:K,totalDgoConsInECA:at,eca:nt}=await this.calculateECA(A,a,h),mt=T.LngLatHelper.roundPrecision(a.fo/24*(S-K),3),st=T.LngLatHelper.roundPrecision(a.dgo/24*S,3);A.extend={eca:nt,distanceInECA:V,hoursInECA:K,totalDgoConsInECA:at},A.totalDgoCons=st,A.totalFoCons=mt;const Q=b().valueOf()-p,X=((J=F==null?void 0:F.hours)==null?void 0:J.length)||1;return k==null||k.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,Q,X,Math.round(Q/X*1e3)/1e3),A}static async analyseCost(e,t,o,i,a={}){var m,v;const n=b().valueOf(),s=[];a.meteo2=a.meteo2||!0,e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const d=T.LaneHelper.calculateRouteDistance(i.route);let r=0;o.forEach(c=>{const w=Math.ceil(d/c.speed/24);r=r<w?w:r}),r=r*1.3;const l=b.utc(e.etd).add(r??14,"day");let M=1;for(const c of o){const w=JSON.parse(JSON.stringify(i.route)),y=JSON.parse(JSON.stringify(i.waypoints)),u=await W.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,l,t,c,w,y,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,a);u&&(await W.calculateCost(u,c,e,a),s.push(u),k==null||k.info("[%s][L%d-%d] analyse from %s to %s cost: %j",a.requestId,1,M,e.etd,l.format(),{cost:u.cost.total,hire:u.cost.hire,bunker:u.cost.bunker,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),M++}s.sort((c,w)=>c.cost.total-w.cost.total);const h=s.at(0),p=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(m=h.cost)==null?void 0:m.total}),p){const c=h.cost.cp,w=p.cost.cp,y=b(h.eta),u=b(h.etd),S=y.diff(u,"days",!0);let F=Math.ceil(S/2);F=F>7?7:F<e.alterStep?e.alterStep:F;let N=2,P={combined:!1,speeds:[p],cost:(v=p.cost)==null?void 0:v.total},H;for(;F>=e.alterStep;){const L=await W.combinedAnalyse(e,t,l,[c,w],i,F,{...a,level:N});if(P.cost>L.cost?H?(H==null?void 0:H.cost)>L.cost&&(H=L):(H=P,P=L):(!H||(H==null?void 0:H.cost)>L.cost)&&(H=L),F<=e.alterStep)break;F=Math.ceil(F/2),N+=1}f.push(P),H&&f.push(H)}const I=b().valueOf()-n;return k==null||k.info("[%s] analyse elapsed: %d ms",a==null?void 0:a.requestId,I),f.sort((c,w)=>c.cost-w.cost)}static async combinedAnalyse(e,t,o,i,a,n,s={}){s.counter=1,k==null||k.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,n);const d=await W.alternateAnalyse(e,t,o,i,0,a,n,s),r=d.reduce((I,m)=>I+m.cost.total,0),l=d.reduce((I,m)=>I+m.cost.hire,0),M=d.reduce((I,m)=>I+m.cost.bunker,0);k==null||k.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:r,hire:l,bunker:M});const h=await W.alternateAnalyse(e,t,o,i,1,a,n,s),p=h.reduce((I,m)=>I+m.cost.total,0),f=h.reduce((I,m)=>I+m.cost.hire,0),j=h.reduce((I,m)=>I+m.cost.bunker,0);return k==null||k.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:p,hire:f,bunker:j}),r<p?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:n}:{combined:!0,cost:Math.round(p*1e3)/1e3,speeds:h,step:n}}static async alternateAnalyse(e,t,o,i,a,n,s,d={}){var h,p;let r=b.utc(e.etd);const l={lat:e.lat,lng:e.lng},M=[];for(;r.isBefore(o);){const f=r.clone().utc().add(s,"day"),j=JSON.parse(JSON.stringify(n.route)),I=JSON.parse(JSON.stringify(n.waypoints)),m=i[a],v=await W.analyseInstantWithThreshed(l,r.utc().format(),f,t,m,j,I,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,d);v&&(await W.calculateCost(v,m,e,d),k==null||k.info("[%s][L%d-%d] analyse from %s to %s cost: %j",d.requestId,d.level,d.counter,r.utc().format(),f.utc().format(),{cost:v.cost.total,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),d.counter=d.counter+1;const c=(p=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:p.at(-1);if(c)l.lat=c.lat,l.lng=c.lng,r=b(c.eta),M.push(v),a=a?0:1;else break}return M}static async calculateCost(e,t,o,i={}){var a;if(e){const n=Math.round(e.totalHrs/24*(o.dailyHire||0)*(1-(o.addComm||0))*1e3)/1e3,s=Math.round(e.totalFoCons*(o.priceFO||0)*1e3)/1e3,d=Math.round((e.totalDgoCons+(((a=e.extend)==null?void 0:a.totalDgoConsInECA)||0))*(o.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((n+s+d)*1e3)/1e3,hire:n,bunker:Math.round((s+d)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,o={}){var d,r;const i=await T.LaneHelper.intersectInECA(e.route);let a=0,n=0,s=0;e.sample.wps.forEach(l=>{l.positionTime=b.utc(l.etd||l.eta).unix()});for(const l of i){a+=l.distance;const M=await T.LaneHelper.deadReckoningTime((d=l.waypoints)==null?void 0:d.at(0),e.sample.wps),h=await T.LaneHelper.deadReckoningTime((r=l.waypoints)==null?void 0:r.at(-1),e.sample.wps);l.in=M,l.out=h,l.totalHrs=T.LngLatHelper.roundPrecision((h.positionTime-M.positionTime)/3600,2),l.totalDgoCons=T.LngLatHelper.roundPrecision(t.fo/24*l.totalHrs,3),n+=l.totalHrs,s+=l.totalDgoCons}return a=T.LngLatHelper.roundPrecision(a,3),n=T.LngLatHelper.roundPrecision(n,3),s=T.LngLatHelper.roundPrecision(s,3),{distanceInECA:a,hoursInECA:n,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(e,t={}){var c,w;const o={hours:[],wps:[],days:[]},i=e.reduce((y,u)=>y+u.distance,0),a=e.reduce((y,u)=>{var S;return y+(((S=u.extend)==null?void 0:S.distanceInECA)||0)},0),n=e.reduce((y,u)=>y+u.totalHrs,0),s=e.reduce((y,u)=>{var S;return y+(((S=u.extend)==null?void 0:S.hoursInECA)||0)},0),d=e.reduce((y,u)=>{var S;return y+(((S=u.extend)==null?void 0:S.totalDgoConsInECA)||0)},0),r=e.reduce((y,u)=>y+u.wxFactor*u.totalHrs/n,0),l=e.reduce((y,u)=>y+u.cFactor*u.totalHrs/n,0),M=e.reduce((y,u)=>y+u.totalFoCons,0),h=e.reduce((y,u)=>y+u.totalDgoCons,0),p=e.reduce((y,u)=>y+u.cost.total,0),f=e.reduce((y,u)=>y+u.cost.hire,0),j=e.reduce((y,u)=>y+u.cost.bunker,0),I=[],m=[];let v;for(const y of e){m.push(...((c=y.extend)==null?void 0:c.eca)||[]);const u=y.sample.hours,S=y.sample.wps,F=y.sample.days,N=u.at(0);v&&(N.distanceFromPrevious=v.distanceFromPrevious,N.distanceFromStart=v.distanceFromStart,u.forEach((x,E)=>{E&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)}),S.at(0).distanceFromPrevious=v.distanceFromPrevious,S.at(0).distanceFromStart=v.distanceFromStart,S.forEach((x,E)=>{E&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)}),F.at(0).distanceFromPrevious=v.distanceFromPrevious,F.at(0).distanceFromStart=v.distanceFromStart,F.forEach((x,E)=>{E&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)})),N.cp=y.cost.cp;const P=[y.etd,y.eta],H=I.findIndex(x=>x.id===N.cp.id);H===-1?(N.cp.segment=[P],I.push(N.cp)):I[H].segment.push(P),u.forEach(x=>{var A;((A=o.hours)==null?void 0:A.findIndex(V=>V.eta===x.eta))===-1&&o.hours.push(x)}),S.forEach(x=>{var A;((A=o.wps)==null?void 0:A.findIndex(V=>V.eta===x.eta))===-1&&o.wps.push(x)}),F.forEach(x=>{var A;((A=o==null?void 0:o.days)==null?void 0:A.findIndex(V=>V.eta===x.eta))===-1&&o.days.push(x)});const L=(w=o.wps)==null?void 0:w.findIndex(x=>x.eta===N.eta);L===-1?o.wps.push(N):o.wps[L]=N,v=u.at(-1)}return o.wps.sort((y,u)=>{b(y.etd).unix()-b(u.etd).unix()}),o.wps.forEach((y,u)=>{const S=o.wps[u-1];if(S){const F=y.distanceFromStart-(S.distanceFromStart||0),N=b(y.eta||y.etd).diff(b(S.etd||S.eta),"hour",!0),P=Math.round(F/N*100)/100;y.avgSpd=P;const H=T.LaneHelper.calculateBearing(S,y);S.bearing=H}}),{sample:o,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(i*1e4)/1e4,totalHrs:Math.round(n*1e3)/1e3,avgSpeed:Math.round(i/n*1e3)/1e3,wxFactor:Math.round(r*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(M*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(p*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(j*1e3)/1e3},extend:{cps:I,eca:m,distanceInECA:Math.round(a*1e4)/1e4,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:e}}}}q.AISImpl=U,q.AlertHelper=ut,q.AlertLevel=dt,q.HifleetImpl=Mt,q.LoadCondition=ht,q.MyShipImpl=bt,q.MyVesselImpl=yt,q.ShipxyImpl=pt,q.SpeedHelper=W,q.SpeedLabel=ft,q.VesselTag=lt,q.alertHelper=gt,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": "1.8.5",
4
+ "version": "1.8.6",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [