UNPKG

@idmwx/idmui-mapbox3

Version:

idm mapbox 3

1,317 lines (1,316 loc) 259 kB
var Ns = Object.defineProperty; var Hs = (t, e, n) => e in t ? Ns(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n; var ve = (t, e, n) => (Hs(t, typeof e != "symbol" ? e + "" : e, n), n); import le from "mapbox-gl"; import { MapboxHelper as Fs, MapboxGL as Ws } from "@idmwx/idmui-gl3"; import { openBlock as h, createElementBlock as u, createElementVNode as i, resolveComponent as T, normalizeStyle as ae, toDisplayString as r, createCommentVNode as I, Fragment as G, renderList as j, normalizeClass as V, createVNode as C, withCtx as W, createBlock as J, mergeProps as Y, createTextVNode as X, withModifiers as te, withDirectives as _e, vShow as ke, shallowRef as zs } from "vue"; import { ElScrollbar as tt, ElProgress as Ps } from "element-plus"; import S from "moment"; import { CompanyHelper as Bs, VoyageHelper as Q, VoyageTagKey as et } from "@idm-plugin/tag"; import { CaretBottom as Gs, CaretRight as Us, Delete as Zs, Filter as $s, AlarmClock as Cs, Search as Ls } from "@element-plus/icons-vue"; import q from "axios"; import { LngLatHelper as z, AisHelper as js, LaneHelper as se } from "@idm-plugin/geo"; import * as be from "echarts"; import * as B from "@turf/turf"; const K = (t, e) => { const n = t.__vccOpts || t; for (const [a, s] of e) n[a] = s; return n; }, qs = { name: "MapInitial", props: { center: { type: Object, default: () => ({}) }, token: { type: String, default: "" } }, emits: ["initialized"], data() { return { helper: void 0, map: void 0, lngLat: void 0, marker: void 0 }; }, watch: { center: { handler() { this.$nextTick(() => { var e, n, a, s, l; ((n = (e = this.center) == null ? void 0 : e.position) == null ? void 0 : n.length) === 2 && ((a = this.center) != null && a.flyTo) && ((l = this.map) == null || l.flyTo({ center: (s = this.center) == null ? void 0 : s.position })); const t = document.getElementById("center-marker"); this.marker = new le.Marker(t).setLngLat([this.center.position[0], this.center.position[1]]).addTo(this.map), this.marker._element.style.display = "block"; }); }, deep: !0 } // token: { // handler() { // if (this.token) { // this.initMap() // } // }, // }, }, mounted() { this.initMap(); }, methods: { initMap() { this.helper = new Fs(this.token), le.accessToken = "pk.eyJ1IjoibmVhdGNoZW5oZW5nIiwiYSI6ImNsdXM3cnBmODBsemgycW1vaXc1bjV6bXMifQ.w6fqHGRbhNhLvm0LnX4ZVw"; const t = new le.Map({ container: "map", // style: 'mapbox://styles/neatchenheng/clxwst0tq00wd01rn0usb2eer', style: { version: 8, name: "idm-mapbox-gl3", lights: [], fog: { color: "#ffffff", range: [0.5, 10], "high-color": "#245cdf", "space-color": ["interpolate", ["linear"], ["zoom"], 4, "#010b19", 7, "#367ab9"], "horizon-blend": ["interpolate", ["linear"], ["zoom"], 4, 0.2, 7, 0.1], "star-intensity": ["interpolate", ["linear"], ["zoom"], 5, 0.35, 6, 0] // 'vertical-range': [0, 0], }, bearing: 0, pitch: 1, sprite: "https://fontnik.idmwx.com/sprite/sprite", glyphs: "https://fontnik.idmwx.com/{fontstack}/{range}.pbf", projection: { name: "equirectangular" }, sources: { composite: this.helper.mapboxCustomer.source, i4: this.helper.i4.source, hi: this.helper.hi.source }, layers: [ this.helper.mapboxCustomer.layers.water, this.helper.mapboxCustomer.layers.waterDeplth, this.helper.i4.layer, this.helper.hi.layer, this.helper.mapboxCustomer.layers.countryBoundary, this.helper.mapboxCustomer.layers.countryAdmin0Boundary, this.helper.mapboxCustomer.layers.countryAdmin0BoundaryDisputed, this.helper.mapboxCustomer.layers.countryLabel, this.helper.mapboxCustomer.layers.world12nm, this.helper.mapboxCustomer.layers.worldMarineLine, this.helper.mapboxCustomer.layers.worldMarineLabel, this.helper.mapboxCustomer.layers.chinaRouteLine, this.helper.mapboxCustomer.layers.chinaRouteFill, this.helper.mapboxCustomer.layers.chinaRouteLabel // this.helper.mapboxCustomer.layers.iceEdgeLine, ] }, zoom: 2, minZoom: 0, maxZoom: 16, center: [120, 30], maxBounds: [ [-720, -85], [720, 85] ], preserveDrawingBuffer: !0, projection: "mercator", attributionControl: !1 }); t.on("load", () => { this.map = t, this.$emit("initialized", this.map), this.initControl(); }); }, initControl() { var e; const t = new le.ScaleControl({ maxWidth: 80, unit: "imperial" }); (e = this.map) == null || e.addControl(t), t.setUnit("metric"); }, handleAddMarker(t) { t.addTo(this.map); } } }, Js = { class: "initial-map-box" }; function Xs(t, e, n, a, s, l) { return h(), u("div", Js, e[0] || (e[0] = [ i("div", { id: "map" }, null, -1), i("div", { id: "center-marker" }, null, -1) ])); } const Rs = /* @__PURE__ */ K(qs, [["render", Xs], ["__scopeId", "data-v-62e37626"]]), Qs = function(t) { typeof t == "string" && (t = Number(t)); let e; switch (t) { case 7: e = "Sun"; break; case 1: e = "Mon"; break; case 2: e = "Tue"; break; case 3: e = "Wed"; break; case 4: e = "Thu"; break; case 5: e = "Fri"; break; case 6: e = "Sat"; break; default: e = "-"; } return e; }; class Ks { constructor() { ve(this, "mediaRecorder", null); ve(this, "recordedChunks", []); ve(this, "stream", null); ve(this, "_isRecording", !1); ve(this, "_isStreamReady", !1); ve(this, "_frameRate", 15); // 默认15fps,减小文件大小 ve(this, "_onStreamEnd", null); } /** * 初始化屏幕共享流(让用户选择共享窗口)并进入全屏 */ async initStream(e = 15, n) { if (this._isStreamReady || this.stream) return console.warn("[MapRecorder] 流已初始化"), !0; this._frameRate = e, this._onStreamEnd = n || null; try { return this.stream = await navigator.mediaDevices.getDisplayMedia({ video: { width: { ideal: 1440, max: 1440 }, // 限制宽度为1440 height: { ideal: 810, max: 810 }, // 16:9 比例对应高度 frameRate: { ideal: e, max: 30 }, displaySurface: "window" }, audio: !1 }), this.stream.getVideoTracks()[0].onended = () => { var a; this._isStreamReady = !1, (a = this._onStreamEnd) == null || a.call(this); }, this._isStreamReady = !0, await this.enterFullscreen(), !0; } catch (a) { return console.error("[MapRecorder] 初始化屏幕共享失败:", a), !1; } } /** * 开始录制(需要先调用 initStream) */ async startRecording() { if (!this._isStreamReady || !this.stream) { console.warn("[MapRecorder] 流未初始化,请先调用 initStream"); return; } if (this._isRecording) { console.warn("[MapRecorder] 已在录制中"); return; } this.recordedChunks = []; try { const e = this.getSupportedMimeType(); this.mediaRecorder = new MediaRecorder(this.stream, { mimeType: e, videoBitsPerSecond: 4e6 // 4 Mbps,平衡清晰度和文件大小 }), this.mediaRecorder.ondataavailable = (n) => { n.data.size > 0 && this.recordedChunks.push(n.data); }, this.mediaRecorder.start(100), this._isRecording = !0; } catch (e) { throw console.error("[MapRecorder] 录制启动失败:", e), e; } } /** * 进入全屏模式 */ async enterFullscreen() { try { const e = document.documentElement; e.requestFullscreen ? await e.requestFullscreen() : e.webkitRequestFullscreen && await e.webkitRequestFullscreen(); } catch (e) { console.warn("[MapRecorder] 无法进入全屏:", e); } } /** * 退出全屏模式 */ async exitFullscreen() { try { (document.fullscreenElement || document.webkitFullscreenElement) && (document.exitFullscreen ? await document.exitFullscreen() : document.webkitExitFullscreen && await document.webkitExitFullscreen()); } catch (e) { console.warn("[MapRecorder] 无法退出全屏:", e); } } /** * 停止共享并退出全屏(不下载文件) */ async stopSharing() { this._isRecording && this.mediaRecorder && (this._isRecording = !1, this.mediaRecorder.stop(), this.mediaRecorder = null, this.recordedChunks = []), this.stream && (this.stream.getTracks().forEach((e) => e.stop()), this.stream = null), this._isStreamReady = !1, await this.exitFullscreen(); } get isStreamReady() { return this._isStreamReady; } /** * 获取支持的 MIME 类型 */ getSupportedMimeType() { const e = ["video/mp4;codecs=h264", "video/mp4", "video/webm;codecs=vp9", "video/webm;codecs=vp8", "video/webm"]; for (const n of e) if (MediaRecorder.isTypeSupported(n)) return n; return "video/webm"; } /** * 停止录制并返回 Blob(保留共享流,支持多次录制) */ async stop() { return !this._isRecording || !this.mediaRecorder ? null : (this._isRecording = !1, new Promise((e) => { if (!this.mediaRecorder) { e(null); return; } this.mediaRecorder.onstop = () => { var s; const n = ((s = this.mediaRecorder) == null ? void 0 : s.mimeType) || "video/webm", a = new Blob(this.recordedChunks, { type: n }); this.recordedChunks = [], this.mediaRecorder = null, e(a); }, this.mediaRecorder.stop(); })); } /** * 下载视频文件 */ download(e) { const n = e.type.includes("mp4") ? "mp4" : "webm", s = `ORM-Record-${S().format("yyyyMMDD-HHmm")}.${n}`, l = URL.createObjectURL(e), d = document.createElement("a"); d.href = l, d.download = s, d.style.display = "none", document.body.appendChild(d), d.click(), setTimeout(() => { document.body.removeChild(d), URL.revokeObjectURL(l); }, 100); } get isRecording() { return this._isRecording; } } const Ys = { name: "MapTimeline", components: { ElScrollbar: tt }, props: { realTime: { type: Object }, startDate: { type: Object, default: () => S().add(-14, "day") }, endDate: { type: Object, default: () => S().add(13, "day") }, reset: { type: Number, default: 0 }, interval: { type: Number, default: 3 }, bottom: { type: Number, default: 0 }, top: { type: Number, default: void 0 } }, emits: ["realTime", "dateChange", "timeZone", "startTs"], data() { return { hours: 0, paused: !0, animation: void 0, resetTime: !1, startTime: 0, progress: 0, step: 0, frequency: 1e3, //ms showTimezone: !1, timeZone: 0, hourOptions: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], offsets: [-12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 录制相关 recordEnabled: !1, isRecording: !1, recorder: null }; }, computed: { dates() { const t = []; if (this.startDate && this.endDate) { const e = this.startDate.clone().utc().set({ hour: 0, minute: 0, second: 0, millisecond: 0 }); for (; e.isSameOrBefore(this.endDate); ) t.push(e.clone()), e.add(1, "day"); } return t; }, computeTotalHours() { var e; return ((e = this.computeOffsetEndDate) == null ? void 0 : e.diff(this.computeOffsetStartDate, "h", !0)) + 24 || 1; }, computeOffsetStartDate() { return this.$emit("startTs", S(this.dates[0]).format()), this.dates[0]; }, computeOffsetEndDate() { return this.dates[this.dates.length - 1]; }, computeDate() { return function(t) { return `${t == null ? void 0 : t.utc().format("MMM-DD")} ${Qs(t == null ? void 0 : t.utc().format("E"))}`; }; }, totalDays() { return Math.ceil(this.computeTotalHours / 24); }, defaultDays() { return this.totalDays < 7 ? this.totalDays : 7; }, computedHourWidth() { return Math.ceil((document.body.clientWidth - 220) / (this.defaultDays * 24)); }, computedLocalTime() { return S(this.realTime).utc().add(this.timeZone, "h").format("yyyy-MM-DD/HHmm"); }, computedUTCTime() { return (t) => S(t).utc().format("yyyy-MM-DD HH:mm[Z]"); }, computedStep() { return function(t) { return t % this.interval === (this.timeZone + 12) % this.interval; }; } }, watch: { hours: { handler() { var s, l, d, c, o; const t = (s = this.computeOffsetStartDate) == null ? void 0 : s.clone().add(this.hours - this.timeZone, "h"); this.$emit("realTime", t); const e = document.documentElement.clientWidth - ((l = document.getElementsByClassName("buttons")[0]) == null ? void 0 : l.clientWidth), n = (o = (c = (d = this.$refs.scrollBar) == null ? void 0 : d.$el) == null ? void 0 : c.firstChild) == null ? void 0 : o.scrollLeft, a = this.hours * this.computedHourWidth; a < (e - 220) / 2 ? this.$refs.scrollBar.setScrollLeft(0) : a >= (e - 220) / 2 + n && this.$refs.scrollBar.setScrollLeft(n + this.computedHourWidth * this.interval); } }, step: { handler() { this.hours >= this.computeTotalHours ? this.pause() : this.step >= 0 && (this.hours += this.interval); } }, reset: { handler() { this.reset && this.handleReset(); } }, // 监听录制开关变化 recordEnabled: { async handler(t, e) { t !== e && (t ? await this.initRecordStream() : await this.stopSharing()); } } }, mounted() { this.timeZone = Number(localStorage.getItem("timeZone")) || 0, this.$emit("timeZone", this.timeZone), this.handleReset(); }, methods: { async pause() { this.animation && cancelAnimationFrame(this.animation), this.paused = !0, this.isRecording && await this.stopRecording(); }, async resume() { var t; this.resetTime = !0, this.paused = !1, this.recordEnabled && ((t = this.recorder) != null && t.isStreamReady) && await this.startRecording(), this.animateSpeeds(); }, animateSpeeds(t) { this.resetTime ? (this.startTime = performance.now() - this.progress, this.resetTime = !1) : this.progress = t - this.startTime, this.step = Math.floor(this.progress / this.frequency), this.animation = requestAnimationFrame(this.animateSpeeds); }, handleJump(t, e) { if (t > this.computeTotalHours) return !1; t = t < 0 ? 0 : t, e ? this.hours = t : this.hours = Math.ceil((t - (this.timeZone + 12) % this.interval) / this.interval) * this.interval + (this.timeZone + 12) % this.interval; }, handleClickHourText(t) { }, handleReset() { this.pause(), this.resetTime = !0, this.startTime = 0, this.progress = 0, this.realTime ? this.hours = Math.ceil(this.realTime.diff(this.computeOffsetStartDate, "hour", !0) + this.timeZone) : this.hours = Math.ceil(S().diff(this.computeOffsetStartDate, "hour", !0) + this.timeZone), setTimeout(() => { var e; const t = Math.ceil(this.hours / 24) - Math.floor(this.defaultDays / 2); (e = this.$refs.scrollBar) == null || e.setScrollLeft(this.computedHourWidth * 24 * t - this.computedHourWidth * (this.hours % 24)); }, 500); }, setTimezone(t) { this.timeZone = t, this.$emit("timeZone", this.timeZone), localStorage.setItem("timeZone", this.timeZone), this.showTimezone = !1, this.handleReset(); }, // 初始化录制流(选择共享窗口并全屏) async initRecordStream() { try { this.recorder = new Ks(), await this.recorder.initStream(30, () => { this.recordEnabled = !1, this.isRecording = !1; }) || (this.recordEnabled = !1, this.recorder = null); } catch (t) { console.error("[TimePlayer] 初始化共享流失败:", t), this.recordEnabled = !1, this.recorder = null; } }, // 开始录制(需要先初始化共享流) async startRecording() { try { this.recorder && (await this.recorder.startRecording(), this.isRecording = !0); } catch (t) { console.error("[TimePlayer] 录制启动失败:", t), this.isRecording = !1; } }, // 停止录制并下载 async stopRecording() { try { if (this.recorder) { const t = await this.recorder.stop(); t && this.recorder.download(t); } } catch (t) { console.error("[TimePlayer] 录制停止失败:", t); } finally { this.isRecording = !1; } }, // 停止共享并退出全屏 async stopSharing() { try { this.recorder && await this.recorder.stopSharing(); } catch (t) { console.error("[TimePlayer] 停止共享失败:", t); } finally { this.isRecording = !1, this.recorder = null; } } } }, ei = { key: 0, class: "record-logo" }, ti = { style: { padding: "6px 16px", margin: "auto", background: "linear-gradient(90deg, #3468F5 0%, #5AC1F9 100%)", color: "var(--idm-white)", "border-radius": "16px", "font-size": "16px" } }, si = { class: "timezone" }, ii = { key: 0, class: "list" }, li = ["onClick"], ni = { class: "flex-start", style: { "box-shadow": "0px 2px 12px 0px rgba(0, 0, 0, 0.5)" } }, ai = { class: "flex-col-between-center" }, oi = { class: "buttons flex-row-end-center" }, ri = { class: "timeline" }, di = { key: 0, class: "day" }, ci = { class: "date flex-row-center-end" }, hi = { class: "hours flex-row-start-center" }, ui = ["onClick"]; function fi(t, e, n, a, s, l) { const d = T("ElScrollbar"); return h(), u("div", { ref: "mapTimeline", class: "map-timeline-container", style: ae({ bottom: n.bottom + "px" }) }, [ s.recordEnabled ? (h(), u("div", ei, [ e[7] || (e[7] = i("div", { class: "flex-center" }, [ i("img", { src: "https://osshz.idmwx.com/asset/logo/logo_984x984.png", style: { height: "64px", width: "auto" } }), i("div", { style: { "margin-left": "8px", "font-size": "20px", "font-style": "italic", "font-weight": "600", width: "auto" } }, "Weather Routing") ], -1)), i("div", ti, r(l.computedUTCTime(n.realTime)), 1) ])) : I("", !0), i("div", si, [ s.showTimezone ? (h(), u("div", ii, [ (h(!0), u(G, null, j(s.offsets, (c) => (h(), u("div", { key: c, class: "item", onClick: (o) => l.setTimezone(c) }, r(c < 0 ? c : "+" + c), 9, li))), 128)) ])) : I("", !0), i("div", { class: "btn", onClick: e[0] || (e[0] = (c) => s.showTimezone = !s.showTimezone) }, "UTC " + r(s.timeZone < 0 ? s.timeZone : "+" + s.timeZone), 1) ]), i("div", ni, [ i("div", ai, [ i("div", oi, [ i("div", { class: V(["btn-block", s.recordEnabled ? "active" : ""]), onClick: e[1] || (e[1] = (c) => s.recordEnabled = !s.recordEnabled) }, r(s.recordEnabled ? "录制中" : "录制"), 3), i("div", { class: V(s.hours - n.interval < 0 ? "iconfont button disable" : "iconfont button"), style: { transform: "rotate(180deg)" }, onClick: e[2] || (e[2] = (c) => l.handleJump(s.hours - n.interval, !0)) }, "  ", 2), s.paused ? (h(), u("div", { key: 0, class: "iconfont button play", onClick: e[3] || (e[3] = (...c) => l.resume && l.resume(...c)) }, "")) : (h(), u("div", { key: 1, class: "iconfont button play", onClick: e[4] || (e[4] = (...c) => l.pause && l.pause(...c)) }, "")), i("div", { class: V(s.hours + n.interval > l.computeTotalHours ? "iconfont button disable" : "iconfont button"), onClick: e[5] || (e[5] = (c) => l.handleJump(s.hours + n.interval, !0)) }, "  ", 2) ]) ]), C(d, { ref: "scrollBar", class: "progress-box" }, { default: W(() => [ i("div", ri, [ (h(!0), u(G, null, j(l.computeTotalHours, (c, o) => { var p; return h(), u(G, { key: c }, [ o % 24 === 0 ? (h(), u("div", di, [ i("div", ci, r(l.computeDate((p = l.computeOffsetStartDate) == null ? void 0 : p.clone().add(c, "h"))), 1), e[8] || (e[8] = i("div", { style: { width: "2px", height: "50px", "background-color": "var(--idm-black-1)", position: "relative", "margin-top": "-50px", left: "-1px", "z-index": "3" } }, null, -1)), i("div", hi, [ (h(!0), u(G, null, j(s.hourOptions, (m) => (h(), u("div", { key: c + "-" + m, class: V(c + m <= s.hours ? "hour-bg active" : "hour-bg"), style: ae({ width: l.computedHourWidth + "px" }), onClick: (f) => l.handleJump(c + m) }, [ i("div", { class: V(["hour", c + m <= s.hours ? "active" : "", l.computedStep(m + 1) ? "step" : ""]) }, [ l.computedStep(m) ? (h(), u("span", { key: 0, class: "text", style: ae({ marginLeft: l.computedHourWidth * -1 + "px" }), onClick: e[6] || (e[6] = (...f) => l.handleClickHourText && l.handleClickHourText(...f)) }, r(m < 10 ? "0" + m : m), 5)) : I("", !0) ], 2) ], 14, ui))), 128)) ]) ])) : I("", !0) ], 64); }), 128)) ]) ]), _: 1 }, 512) ]) ], 4); } const Ts = /* @__PURE__ */ K(Ys, [["render", fi], ["__scopeId", "data-v-7d6ca345"]]); const pi = { name: "MapMeteo", components: { MapboxGL: Ws }, props: { token: { type: String, default: "" }, permission: { type: Number, default: 0 }, map: { type: Object, default: void 0 }, forecastModel: { type: String } }, emits: ["measurable"], data() { return { showPointRpt: !1, pointQuery: {} }; }, methods: { handleMore(t) { this.pointQuery = { ...t, d: 7, st: 6 }; }, handleMeasurableChange(t) { this.$emit("measurable", t); } } }, gi = { class: "meteo-gl" }; function mi(t, e, n, a, s, l) { const d = T("MapboxGL"); return h(), u("div", gi, [ n.map ? (h(), J(d, Y({ key: 0, ref: "mapboxGl3", map: n.map, token: n.token, permission: n.permission, forecastModel: n.forecastModel }, t.$attrs), null, 16, ["map", "token", "permission", "forecastModel"])) : I("", !0) ]); } const Ss = /* @__PURE__ */ K(pi, [["render", mi]]); const yi = { name: "VoyageFleet", components: { ElScrollbar: tt, CaretBottom: Gs, CaretRight: Us, Delete: Zs, ViewFilter: $s }, props: { permission: { type: Number, default: void 0 }, token: { type: String }, voyageId: { type: String, default: void 0 }, voyageVersion: { type: Number, default: 0 }, route: { type: Object, default: void 0 }, weights: { type: Object, default: void 0 }, voyageToggle: { type: Boolean, default: !1 }, toggleVersion: { type: Number, default: 0 }, isLogin: { type: Boolean, default: void 0 } }, emits: ["login", "update", "select", "voyageToggle", "hide", "toggleVersion", "handlePort", "handleCoord", "handleOtherVessel", "handleCloseAll"], data() { return { right: 10, listQuery: { vid: void 0, id: void 0, smp: !0, pid: void 0, pn: 1, ps: 500 }, model: "inService", activeStatus: "Underway", filterVersion: 0, voyageList: [], followList: [], filterList: [], total: 0, voyage: void 0, hide: !1, items: [], placeholder: "Name/IMO", keyword: void 0, gateway: "https://cbe.idmwx.com", CompanyHelper: Bs, showAlertCheckbox: !1, alertTagList: [], alertOption: { weather: Q.WEATHER_TAG, sailing: Q.SAILING_TAG }, checkParams: { weather: { checkAll: !1, isIndeterminate: !1 }, sailing: { checkAll: !1, isIndeterminate: !1 } } }; }, computed: { computePosition() { return function(t) { return t ? z.lat2pretty(t == null ? void 0 : t.lat, 2).pretty + " / " + z.lng2pretty(t == null ? void 0 : t.lng, 2).pretty : "-"; }; } }, watch: { "route.query.vid": { handler() { var t, e; (e = (t = this.route) == null ? void 0 : t.query) != null && e.vid ? this.handleVoyageIdChange() : (this.fetchMyActiveVoyage(), this.fetchMyFollows()); }, immediate: !0 }, voyageToggle: { handler() { this.voyageToggle && (this.model = "inService", this.fetchMyFollows()); } }, filterVersion: { handler() { var t, e; if (this.model === "inService") { let n = []; ((t = this.alertTagList) == null ? void 0 : t.length) > 0 ? n = this.voyageList.filter((a, s) => this.alertTagList.some((l) => a.tag & l)) : n = this.voyageList, this.keyword ? this.filterList = n.filter((a, s) => { var f, b, k, w, M, v, R, N, g, _, E, L, A, O, H, y, P; const l = (f = this.keyword) == null ? void 0 : f.toLowerCase().replace(/\s/g, ""), d = (w = (k = (b = a == null ? void 0 : a.vessel) == null ? void 0 : b.name) == null ? void 0 : k.toLowerCase()) == null ? void 0 : w.replace(/\s/g, ""), c = (R = (v = (M = a.company) == null ? void 0 : M.name) == null ? void 0 : v.toLowerCase()) == null ? void 0 : R.replace(/\s/g, ""), o = (E = (_ = (g = (N = a == null ? void 0 : a.vessel) == null ? void 0 : N.imo) == null ? void 0 : g.toString()) == null ? void 0 : _.toLowerCase()) == null ? void 0 : E.replace(/\s/g, ""), p = (O = (A = (L = a == null ? void 0 : a.pic) == null ? void 0 : L.email) == null ? void 0 : A.toLowerCase()) == null ? void 0 : O.replace(/\s/g, ""), m = (P = (y = (H = a == null ? void 0 : a.pic2) == null ? void 0 : H.email) == null ? void 0 : y.toLowerCase()) == null ? void 0 : P.replace(/\s/g, ""); return this.permission & this.CompanyHelper.LEVEL.Prime ? (d == null ? void 0 : d.indexOf(l)) > -1 || (c == null ? void 0 : c.indexOf(l)) > -1 || (o == null ? void 0 : o.indexOf(l)) > -1 || (p == null ? void 0 : p.indexOf(l)) > -1 || (m == null ? void 0 : m.indexOf(l)) > -1 : (d == null ? void 0 : d.indexOf(l)) > -1 || (o == null ? void 0 : o.indexOf(l)) > -1; }) : this.filterList = n, this.total = (e = this.voyageList) == null ? void 0 : e.length, this.$nextTick(() => { this.filterList.some((a) => a.status === "Underway") ? this.activeStatus = "Underway" : this.filterList.some((a) => a.status === "Reached") ? this.activeStatus = "Reached" : this.filterList.some((a) => a.status === "Ready") ? this.activeStatus = "Ready" : this.activeStatus = ""; }), this.$emit("update", this.filterList); } else this.keyword ? this.filterList = this.followList.filter((n, a) => { var f, b, k, w, M, v, R, N, g, _, E, L, A, O, H, y, P; const s = (f = this.keyword) == null ? void 0 : f.toLowerCase().replace(/\s/g, ""), l = (w = (k = (b = n == null ? void 0 : n.vessel) == null ? void 0 : b.name) == null ? void 0 : k.toLowerCase()) == null ? void 0 : w.replace(/\s/g, ""), d = (N = (R = (v = (M = n == null ? void 0 : n.vessel) == null ? void 0 : M.imo) == null ? void 0 : v.toString()) == null ? void 0 : R.toLowerCase()) == null ? void 0 : N.replace(/\s/g, ""), c = this.voyageList.find((U) => { var D; return U.id === ((D = n.voyage) == null ? void 0 : D.id); }), o = (E = (_ = (g = c == null ? void 0 : c.company) == null ? void 0 : g.name) == null ? void 0 : _.toLowerCase()) == null ? void 0 : E.replace(/\s/g, ""), p = (O = (A = (L = c == null ? void 0 : c.pic) == null ? void 0 : L.email) == null ? void 0 : A.toLowerCase()) == null ? void 0 : O.replace(/\s/g, ""), m = (P = (y = (H = c == null ? void 0 : c.pic2) == null ? void 0 : H.email) == null ? void 0 : y.toLowerCase()) == null ? void 0 : P.replace(/\s/g, ""); return this.permission & this.CompanyHelper.LEVEL.Prime ? (l == null ? void 0 : l.indexOf(s)) > -1 || (o == null ? void 0 : o.indexOf(s)) > -1 || (d == null ? void 0 : d.indexOf(s)) > -1 || (p == null ? void 0 : p.indexOf(s)) > -1 || (m == null ? void 0 : m.indexOf(s)) > -1 : (l == null ? void 0 : l.indexOf(s)) > -1 || (d == null ? void 0 : d.indexOf(s)) > -1; }) : this.filterList = this.followList, this.total = this.followList.length, this.$emit("update", this.filterList); }, immediate: !0 }, model: { handler() { this.filterVersion = Math.random(), this.model === "myFollows" && this.fetchMyFollows(), this.voyage = {}, this.$emit("select", this.voyage); } }, keyword: { handler() { this.filterVersion = Math.random(); }, immediate: !0 }, voyageVersion: { handler() { if (this.voyageId) { let t = 0; this.filterList.forEach((n, a) => { n.id === this.voyageId && (this.voyage = n, t = a); }); const e = document.getElementsByClassName("el-scrollbar")[0].firstChild; e.scrollTop = (t - 10) * 42; } }, immediate: !0 }, toggleVersion: { handler() { this.$nextTick(() => { var t; this.right = (((t = document.getElementsByClassName("right-bar")[0]) == null ? void 0 : t.clientWidth) || 0) + 10; }); }, deep: !0, immediate: !0 }, hide: { handler() { this.hide || this.$emit("update", this.voyageList); } } }, mounted() { this.permission & this.CompanyHelper.LEVEL.Prime ? this.placeholder = "Name/IMO/Company/PIC" : this.placeholder = "Name/IMO"; }, methods: { async handleVoyageIdChange() { var n; await this.fetchMyActiveVoyage(), this.$emit("voyageToggle", !1); const t = this.voyageList.filter((a) => { var s, l; return a.id === ((l = (s = this.route) == null ? void 0 : s.query) == null ? void 0 : l.vid); })[0]; this.$emit("select", t); const e = (n = t == null ? void 0 : t.vessel) == null ? void 0 : n.imo; this.keyword = e + ""; }, async fetchMyActiveVoyage() { var e, n, a, s; const t = await q.get(`${this.gateway}/api/rsv/voyages/my/active`, { headers: { Authorization: this.token }, params: this.listQuery }); if (((e = t == null ? void 0 : t.data) == null ? void 0 : e.code) === 0) { const l = Q.WEATHER_TAG, d = Q.SAILING_TAG; this.voyageList = (s = (a = (n = t.data) == null ? void 0 : n.data) == null ? void 0 : a.rows) == null ? void 0 : s.map((c) => (c.weatherTag = l.some((o) => c.tag & o.weight), c.sailingTag = d.some((o) => c.tag & o.weight), c)), this.hide || this.$emit("update", this.voyageList), this.filterVersion = Math.random(); } }, async fetchMyFollows() { var e, n, a, s; const t = await q.get(`${this.gateway}/api/rsv/follows`, { headers: { Authorization: this.token }, params: { pn: 1, ps: 1e4, b: 1 } }); if (((e = t == null ? void 0 : t.data) == null ? void 0 : e.code) === 0) { const l = Q.WEATHER_TAG, d = Q.SAILING_TAG; let c = 0; this.followList = (s = (a = (n = t.data) == null ? void 0 : n.data) == null ? void 0 : a.rows) == null ? void 0 : s.map((o) => (o.weatherTag = l.some((p) => o.tag & p.weight), o.sailingTag = d.some((p) => o.tag & p.weight), o.watchedIndex = o.voyage ? void 0 : ++c, o.followed = !0, o)), this.filterVersion = Math.random(); } }, handleFleetHide(t) { this.hide = t, this.$emit("hide", t); }, handleVoyageClick(t) { this.$emit("handleCloseAll"), this.voyage = t, this.$emit("select", this.voyage); }, handleRowClick(t) { this.$emit("handleCloseAll"), t.voyage ? (this.voyage = this.voyageList.find((e) => { var n; return e.id === ((n = t.voyage) == null ? void 0 : n.id); }), this.$emit("select", this.voyage)) : t.coordinate ? this.$emit("handleCoord", t.coordinate) : t.port ? this.$emit("handlePort", t.port) : t.vessel && this.$emit("handleOtherVessel", t.vessel); }, handleToggleFollow(t) { var e, n; t.follow ? this.handleCancelFollow((n = t == null ? void 0 : t.follow) == null ? void 0 : n.id) : this.handleFollow((e = t == null ? void 0 : t.vessel) == null ? void 0 : e.id); }, async handleFollow(t) { await q.post(`${this.gateway}/api/rsv/follows`, { vesselId: t }, { headers: { Authorization: this.token } }).then((e) => { var n, a, s, l, d; ((n = e.data) == null ? void 0 : n.code) === 0 && (this.fetchMyFollows(), this.voyageList.find((c) => { var o; return ((o = c == null ? void 0 : c.vessel) == null ? void 0 : o.id) === t; }).follow = { id: (a = e.data.data) == null ? void 0 : a.id, voyageId: (s = e.data.data) == null ? void 0 : s.voyageId, ownerId: (d = (l = e.data.data) == null ? void 0 : l.owner) == null ? void 0 : d.id }); }), this.filterVersion = Math.random(); }, handleCancelFollow(t) { q.delete(`${this.gateway}/api/rsv/follows/${t}`, { headers: { Authorization: this.token } }).then((e) => { var n; ((n = e.data) == null ? void 0 : n.code) === 0 && (this.model === "inService" ? this.voyageList.find((a) => { var s; return ((s = a.follow) == null ? void 0 : s.id) === t; }).follow = void 0 : (this.fetchMyActiveVoyage(), this.followList = this.followList.filter((a) => (a == null ? void 0 : a.id) !== t)), this.filterVersion = Math.random()); }); }, handleToggle() { this.isLogin ? (this.$emit("voyageToggle", !this.voyageToggle), this.$emit("toggleVersion")) : this.$emit("login"); }, handleClose() { this.$emit("voyageToggle", !1); }, handleCheckAllChange(t, e) { var n, a, s; t ? ((a = (n = this.alertOption) == null ? void 0 : n[e]) == null || a.forEach((l) => { this.alertTagList.push(l.weight); }), this.alertTagList = [...new Set(this.alertTagList)]) : this.alertTagList = (s = this.alertTagList) == null ? void 0 : s.filter((l) => { var d, c; return !((c = (d = this.alertOption) == null ? void 0 : d[e]) != null && c.some((o) => l === o.weight)); }), this.checkParams[e].isIndeterminate = !1, this.filterVersion = Math.random(); }, handleCheckItemChange(t, e) { var a, s, l; const n = (a = t == null ? void 0 : t.filter((d) => this.alertOption[e].some((c) => d === c.weight))) == null ? void 0 : a.length; this.checkParams[e].checkAll = n === ((s = this.alertOption[e]) == null ? void 0 : s.length), this.checkParams[e].isIndeterminate = n > 0 && n < ((l = this.alertOption[e]) == null ? void 0 : l.length), this.filterVersion = Math.random(); } } }, vi = { class: "voyage-fleet-container" }, bi = { class: "header-box flex-space" }, xi = { style: { "font-size": "14px" } }, _i = { class: "switch-box flex-space" }, ki = { class: "search-box flex-between" }, wi = { class: "status-label flex-between" }, Li = { class: "flex-start" }, Ci = ["onClick"], Ri = { style: { "font-size": "14px", "font-weight": "400" } }, Ti = { key: 0, class: "voyage-list" }, Si = ["onClick"], Mi = { class: "flex-start" }, Oi = { class: "vessel-name" }, Di = { key: 0, class: "iconfont alert-icon" }, Ei = { key: 1, class: "iconfont alert-icon" }, Ai = ["onClick"], Ii = { key: 0, class: "iconfont" }, Vi = { key: 1, class: "iconfont" }, Ni = { key: 1, class: "voyage-list followed" }, Hi = ["onClick"], Fi = { key: 0, class: "flex-space", style: { height: "100%" } }, Wi = { class: "flex-col-space-start" }, zi = { class: "vessel-name" }, Pi = { class: "flex-start" }, Bi = { key: 0, class: "iconfont alert-icon" }, Gi = { key: 1, class: "iconfont alert-icon" }, Ui = ["onClick"], Zi = { key: 1, class: "flex-space", style: { height: "100%" } }, $i = { class: "flex-col-space-start" }, ji = { class: "vessel-name" }, qi = ["onClick"], Ji = { class: "display-box" }, Xi = { style: { "pointer-events": "none" } }, Qi = { class: "content-box" }; function Ki(t, e, n, a, s, l) { var N; const d = T("ElTooltip"), c = T("ElInput"), o = T("ViewFilter"), p = T("el-icon"), m = T("CaretBottom"), f = T("CaretRight"), b = T("ElScrollbar"), k = T("Delete"), w = T("el-checkbox"), M = T("el-checkbox-group"), v = T("ElDivider"), R = T("ElDialog"); return h(), u("div", vi, [ i("div", { class: "menu-bar-box", style: ae({ right: s.right + "px" }) }, [ C(d, { placement: "left", effect: "light", content: "Fleet", "show-after": 1e3 }, { default: W(() => [ i("div", { class: V(["toggle", n.voyageToggle ? "active" : ""]), onClick: e[0] || (e[0] = (g) => l.handleToggle()) }, e[21] || (e[21] = [ i("i", { class: "iconfont" }, "", -1) ]), 2) ]), _: 1 }) ], 4), i("div", { class: "main-box flex-start", style: ae({ right: n.voyageToggle ? "0px" : "-290px" }) }, [ i("div", { class: V(["active-voyages", n.voyageToggle ? "right-bar" : ""]) }, [ i("div", bi, [ i("label", null, [ e[22] || (e[22] = X("Fleets ")), i("span", xi, " ( " + r(s.total) + " )", 1) ]), i("div", { class: "iconfont close-btn", onClick: e[1] || (e[1] = (...g) => l.handleClose && l.handleClose(...g)) }, "") ]), i("div", _i, [ i("div", { class: V(s.model === "inService" ? "item active" : "item"), onClick: e[2] || (e[2] = (g) => s.model = "inService") }, "In Service", 2), i("div", { class: V(s.model === "myFollows" ? "item active" : "item"), onClick: e[3] || (e[3] = (g) => s.model = "myFollows") }, "My Follows", 2) ]), i("div", ki, [ C(c, { placeholder: s.placeholder, modelValue: s.keyword, "onUpdate:modelValue": e[4] || (e[4] = (g) => s.keyword = g), class: "input", style: { flex: "1" }, clearable: "", onFocus: e[5] || (e[5] = (g) => s.placeholder = ""), onBlur: e[6] || (e[6] = (g) => s.placeholder = "Name/IMO") }, null, 8, ["placeholder", "modelValue"]), s.model === "inService" ? (h(), J(p, { key: 0, onClick: e[7] || (e[7] = (g) => s.showAlertCheckbox = !0), style: { width: "30px" }, color: (N = s.alertTagList) != null && N.length ? "var(--idm-primary-color)" : "" }, { default: W(() => [ C(o) ]), _: 1 }, 8, ["color"])) : I("", !0) ]), s.model === "inService" ? (h(), u(G, { key: 0 }, j(["Underway", "Reached", "Ready"], (g) => (h(), u(G, { key: g }, [ i("div", wi, [ i("div", Li, [ C(p, { class: "caret-btn" }, { default: W(() => [ s.activeStatus === g ? (h(), J(m, { key: 0, onClick: e[8] || (e[8] = (_) => s.activeStatus = "") })) : (h(), J(f, { key: 1, onClick: (_) => s.activeStatus = g }, null, 8, ["onClick"])) ]), _: 2 }, 1024), i("label", { onClick: (_) => s.activeStatus = s.activeStatus === "" ? g : "" }, [ X(r(g) + " ", 1), i("span", Ri, " ( " + r(s.filterList.filter((_) => _.status === g).length) + " )", 1) ], 8, Ci) ]), g === "Underway" ? (h(), u("i", { key: 0, class: V(`iconfont icon ${g}`) }, "", 2)) : I("", !0), g === "Reached" ? (h(), u("i", { key: 1, class: V(`iconfont icon ${g}`) }, "", 2)) : I("", !0), g === "Ready" ? (h(), u("i", { key: 2, class: V(`iconfont icon ${g}`) }, "", 2)) : I("", !0) ]), s.activeStatus === g ? (h(), u("div", Ti, [ C(b, null, { default: W(() => [ (h(!0), u(G, null, j(s.filterList.filter((_) => _.status === g), (_) => { var E, L; return h(), u("div", { key: _.id, class: V(((E = s.voyage) == null ? void 0 : E.id) === _.id ? "flex-space voyage-item active" : "flex-space voyage-item"), onClick: (A) => l.handleVoyageClick(_) }, [ i("div", Mi, [ i("span", Oi, r((L = _.vessel) == null ? void 0 : L.name), 1), _.weatherTag ? (h(), u("span", Di, "")) : I("", !0), _.sailingTag ? (h(), u("span", Ei, "")) : I("", !0) ]), i("div", { class: V(["follow-icons", _.follow ? "active" : ""]), onClick: te((A) => l.handleToggleFollow(_), ["stop"]) }, [ _.follow ? (h(), u("span", Ii, "")) : (h(), u("span", Vi, "")) ], 10, Ai) ], 10, Si); }), 128)) ]), _: 2 }, 1024) ])) : I("", !0) ], 64))), 64)) : (h(), u("div", Ni, [ C(b, null, { default: W(() => [ (h(!0), u(G, null, j(s.filterList, (g) => { var _, E, L, A, O, H, y; return h(), u("div", { key: g.id || Math.random(), class: V((_ = s.voyage) != null && _.id && ((E = s.voyage) == null ? void 0 : E.id) === ((L = g == null ? void 0 : g.voyage) == null ? void 0 : L.id) ? "voyage-item active" : "voyage-item"), onClick: (P) => l.handleRowClick(g) }, [ g.voyage ? (h(), u("div", Fi, [ i("div", Wi, [ i("div", zi, r((A = g == null ? void 0 : g.vessel) == null ? void 0 : A.name), 1), i("div", Pi, [ i("span", { class: V(`status-tag ${(O = g == null ? void 0 : g.voyage) == null ? void 0 : O.status}`) }, r((H = g == null ? void 0 : g.voyage) == null ? void 0 : H.status), 3), g.weatherTag ? (h(), u("span", Bi, "")) : I("", !0), g.sailingTag ? (h(), u("span", Gi, "")) : I("", !0) ]) ]), i("div", { class: "follow-icons active", onClick: te((P) => l.handleCancelFollow(g.id), ["stop"]) }, e[23] || (e[23] = [ i("span", { class: "iconfont" }, "", -1) ]), 8, Ui) ])) : g != null && g.vessel ? (h(), u("div", Zi, [ i("div", $i, [ i("div", ji, r((y = g == null ? void 0 : g.vessel) == null ? void 0 : y.name), 1), e[24] || (e[24] = i("div", { class: "flex-start" }, [ i("span", { class: "status-tag vessel-tag" }, "Followed") ], -1)) ]), i("div", { class: "delete-icons active", onClick: te((P) => l.handleCancelFollow(g.id), ["stop"]) }, [ C(p, null, { default: W(() => [ C(k) ]), _: 1 }) ], 8, qi) ])) : I("", !0) ], 10, Hi); }), 128)) ]), _: 1 }) ])), i("view", Ji, [ e[25] || (e[25] = i("span", { class: "text" }, "Display on the map", -1)), s.hide ? (h(), u("span", { key: 1, class: "iconfont switch-off", onClick: e[10] || (e[10] = (g) => l.handleFleetHide(!1)) }, "")) : (h(), u("span", { key: 0, class: "iconfont switch-on", onClick: e[9] || (e[9] = (g) => l.handleFleetHide(!0)) }, "")) ]) ], 2) ], 4), i("div", Xi, [ C(R, { modelValue: s.showAlertCheckbox, "onUpdate:modelValue": e[20] || (e[20] = (g) => s.showAlertCheckbox = g), title: "Vessel Under Alert", width: "400", class: "alert-checkbox-dialog", draggable: !0, "show-close": !1, modal: !1, "close-on-click-modal": !1 }, { default: W(() => [ i("div", { class: "iconfont close-btn", onClick: e[11] || (e[11] = (g) => s.showAlertCheckbox = !1) }, ""), i("div", Qi, [ C(w, { modelValue: s.checkParams.weather.checkAll, "onUpdate:modelValue": e[12] || (e[12] = (g) => s.checkParams.weather.checkAll = g), indeterminate: s.checkParams.weather.isIndeterminate, onChange: e[13] || (e[13] = (g) => l.handleCheckAllChange(g, "weather")) }, { default: W(() => e[26] || (e[26] = [ i("span", { class: "title" }, "Adverse Weather Alert", -1), i("span", { class: "iconfont alert-icon" }, "", -1) ])), _: 1, __: [26] }, 8, ["modelValue", "indeterminate"]), C(M, { modelValue: s.alertTagList, "onUpdate:modelValue": e[14] || (e[14] = (g) => s.alertTagList = g), onChange: e[15] || (e[15] = (g) => l.handleCheckItemChange(g, "weather")) }, { default: W(() => [ (h(!0), u(G, null, j(s.alertOption.weather, (g) => { var _, E; return h(), J(w, { label: (E = (_ = g.name) == null ? void 0 : _.split(" ")) == null ? void 0 : E[2], value: g.weight }, null, 8, ["label", "value"]); }), 256)) ]), _: 1 }, 8, ["modelValue"]), C(v, { style: { margin: "5px 0", "border-top": "none" } }), C(w, { modelValue: s.checkParams.sailing.checkAll, "onUpdate:modelValue": e[16] || (e[16] = (g) => s.checkParams.sailing.checkAll = g), indeterminate: s.checkParams.sailing.isIndeterminate, onChange: e[17] || (e[17] = (g) => l.handleCheckAllChange(g, "sailing")) }, { default: W(() => e[27] || (e[27] = [ i("span", { class: "title" }, "Sailing Alert", -1), i("span", { class: "iconfont alert-icon" }, "", -1) ])), _: 1, __: [27] }, 8, ["modelValue", "indeterminate"]), C(M, { modelValue: s.alertTagList, "onUpdate:modelValue": e[18] || (e[18] = (g) => s.alertTagList = g), onChange: e[19] || (e[19] = (g) => l.handleCheckItemChange(g, "sailing")) }, { default: W(() => [ (h(!0), u(G, null, j(s.alertOption.sailing, (g) => (h(), J(w, { label: g.name, value: g.weight }, null, 8, ["label", "value"]))), 256)) ]), _: 1 }, 8, ["modelValue"]) ]) ]), _: 1 }, 8, ["modelValue"]) ]) ]); } const Ms = /* @__PURE__ */ K(yi, [["render", Ki], ["__scopeId", "data-v-4b59a018"]]); const Yi = { name: "VoyageSummary", components: { ElProgress: Ps, ElScrollbar: tt, AlarmClock: Cs }, props: { voyage: { type: Object, default: void 0 }, leg: { type: Object, default: void 0 }, bps: { type: Object, default: void 0 }, permission: { type: Number }, cpList: { type: Array, default: void 0 } }, emits: ["center"], data() { return { rank: 1 }; }, computed: { currentLeg() { var t, e; return (e = (t = this.voyage) == null ? void 0 : t.legs) == null ? void 0 : e.find((n) => n.rank === this.rank); }, computeLat() { return function(t) { return `${z.lat2pretty(t, 2).pretty}`; }; }, computeLng() { return function(t) {