@mxtommy/kip 4.8.2 → 4.8.4

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/package.json +27 -4
  3. package/public/{chunk-BIYHVfJl.js → chunk-07zHjmg-.js} +1 -1
  4. package/public/{chunk-NnB8OYZt.js → chunk-0z3nIRXw.js} +1 -1
  5. package/public/{chunk-CCiqU2uY.js → chunk-B09jfNia.js} +1 -1
  6. package/public/{chunk-Bq-eHuZV.js → chunk-B0D54iJs.js} +1 -1
  7. package/public/{chunk-DfGLo6Tb.js → chunk-B0eE4udE.js} +1 -1
  8. package/public/{chunk-CkfPr-c5.js → chunk-B9nVBlGj.js} +1 -1
  9. package/public/{chunk-B8zRhoG8.js → chunk-BFpzxIIT.js} +1 -1
  10. package/public/{chunk-D_wrJJxl.js → chunk-BIb-xYiS.js} +1 -1
  11. package/public/{chunk-CSpA60X7.js → chunk-BJ-wyixK.js} +1 -1
  12. package/public/{chunk-Bb1mO304.js → chunk-BLEZOsfR.js} +1 -1
  13. package/public/{chunk-7lulvsGI.js → chunk-BN7A4g6c.js} +1 -1
  14. package/public/{chunk-h2q_pbbF.js → chunk-BTOTKeBo.js} +1 -1
  15. package/public/{chunk-DjavLLpP.js → chunk-BUguZ7cK.js} +1 -1
  16. package/public/{chunk-B8gfh4xf.js → chunk-BZx964-p.js} +1 -1
  17. package/public/{chunk-CcvYOops.js → chunk-BeM64etA.js} +1 -1
  18. package/public/{chunk-DSvdWjO4.js → chunk-BfiyH3nV.js} +1 -1
  19. package/public/{chunk-B_PiPxb4.js → chunk-BjINKQ03.js} +1 -1
  20. package/public/{chunk-BdBWqZzL.js → chunk-BpcNrtxJ.js} +1 -1
  21. package/public/{chunk-C4FGoLDg.js → chunk-BuvyF0y5.js} +1 -1
  22. package/public/{chunk-DGOvRnAo.js → chunk-C6b8CVno.js} +1 -1
  23. package/public/{chunk-BgyxBAyq.js → chunk-CCfhzpE8.js} +1 -1
  24. package/public/{chunk-CoEM_FqS.js → chunk-CHAFm_nM.js} +1 -1
  25. package/public/{chunk-D0MyVrEL.js → chunk-CIGP2YJm.js} +1 -1
  26. package/public/{chunk-Bhah8DNM.js → chunk-CLTHuhlN.js} +1 -1
  27. package/public/{chunk-B6XxnPxk.js → chunk-CLs_NL1y.js} +1 -1
  28. package/public/{chunk-Cr34s2uQ.js → chunk-COI6IBXH.js} +1 -1
  29. package/public/{chunk-BxV0O2fU.js → chunk-CQMVIDcp.js} +1 -1
  30. package/public/{chunk-CHKQxw6E.js → chunk-CXvWM_vF.js} +1 -1
  31. package/public/{chunk-Di5pPpU7.js → chunk-CYYBxjrc.js} +1 -1
  32. package/public/{chunk-BW4m3O2L.js → chunk-C_OZJltF.js} +1 -1
  33. package/public/{chunk-CjsnWLUr.js → chunk-Co2wVrD6.js} +1 -1
  34. package/public/{chunk-DMhuBqKs.js → chunk-CoCQ3DW2.js} +1 -1
  35. package/public/{chunk-DMoEBcor.js → chunk-CxPx4NZv.js} +1 -1
  36. package/public/{chunk-CdSWuWKr.js → chunk-CyVRpGoJ.js} +1 -1
  37. package/public/{chunk-Dv77RFHm.js → chunk-D-_-GUVr.js} +1 -1
  38. package/public/{chunk-CU8RPnsi.js → chunk-D1HYfaL_.js} +1 -1
  39. package/public/{chunk-DBA0eRqb.js → chunk-D2953Rfp.js} +1 -1
  40. package/public/{chunk-Cu9FE8cB.js → chunk-DIl1k00y.js} +1 -1
  41. package/public/{chunk-CyURmwWh.js → chunk-DPnbM-aB.js} +1 -1
  42. package/public/{chunk-8hkXyEzG.js → chunk-DTN-sa1K.js} +1 -1
  43. package/public/{chunk-C3CwUYvD.js → chunk-DUEKoZhd.js} +1 -1
  44. package/public/{chunk-COMZv7NY.js → chunk-DmkAKXR1.js} +1 -1
  45. package/public/{chunk-zg7II0hz.js → chunk-Do8wqING.js} +1 -1
  46. package/public/{chunk-oPq9Nexl.js → chunk-JhFkJS7i.js} +1 -1
  47. package/public/{chunk-CJIxuzvd.js → chunk-OeQDZKFO.js} +1 -1
  48. package/public/{chunk-Bz9bswDl.js → chunk-_zRMMvCu.js} +1 -1
  49. package/public/{chunk-D-xDPCf7.js → chunk-eQ1pa34Q.js} +1 -1
  50. package/public/{chunk-DVB9tiW3.js → chunk-ibauGmSP.js} +1 -1
  51. package/public/{chunk-oZiyAw_P.js → chunk-otzyItXL.js} +1 -1
  52. package/public/{chunk-B6AwCAvV.js → chunk-q9NoPvcx.js} +1 -1
  53. package/public/{chunk-B15lj2T8.js → chunk-szQs8fiq.js} +1 -1
  54. package/public/{chunk-o977r5_s.js → chunk-x7L6DXVK.js} +1 -1
  55. package/public/index.html +1 -1
  56. package/public/{main-BNR44HGB.js → main-YKDNK5VZ.js} +4 -4
  57. package/plugin/history-series.service.js +0 -637
  58. package/plugin/index.js +0 -1322
  59. package/plugin/kip-series-contract.js +0 -31
  60. package/plugin/openApi.json +0 -855
  61. package/plugin/sqlite-history-storage.service.js +0 -1124
  62. package/plugin/src/history-series.service.js +0 -634
  63. package/plugin/src/index.js +0 -1322
  64. package/plugin/src/kip-series-contract.js +0 -31
  65. package/plugin/src/openApi.json +0 -855
  66. package/plugin/src/sqlite-history-storage.service.js +0 -1122
@@ -1 +1 @@
1
- import {g as ge$1}from'./chunk-TakPRI3t.js';import {d1 as Hj,w,du as p,C as Ff,ao as ue,bu as ut$1,G as Gi,aR as lt$1,a as G,$ as $j,v as vt$1,D as Dt,dG as rn,F as Fa,dn as ge,dH as ac,cw as z,cv as G$1,dI as cn,dJ as nc,dK as qn,dL as zn,dM as pa,J as JD,O as Op,R as Rp,y as yt$1,b as wt,cG as Ht,cH as R,cI as ee,cJ as Nt,cK as Lt,cR as zt,bg as mt$1,P as Pi,k as Qh,_ as _w,u as ul,T as TT,cn as wd,c as $h,cV as Td,cf as xh,bl as Jw,e as EE,B as Bh,an as Hh,M as Mw,s as sg,f as eg,K as Kw,aS as De,aY as xe,ab as te,aj as zm,a_ as Gp,cO as eu,aI as ms,dN as Q,h as Fw,g as qw,X as xw,Y as Aw,bp as gl,dj as Nw,d as ig,aA as gg,l as ud,m as dd,dO as fp}from'./main-BNR44HGB.js';import {u}from'./chunk-BgyxBAyq.js';import {c}from'./chunk-D_wrJJxl.js';var K=false,Je=250,it=600*1e3,st=500,nt=15e3,rt=["atons.urn:mrn:imo:mmsi:*","shore.basestations.urn:mrn:imo:mmsi:*","vessels.urn:mrn:imo:mmsi:*","sar.urn:mrn:imo:mmsi:*"],ot=[{prefix:"atons.urn:mrn:imo:mmsi:",type:"aton"},{prefix:"shore.basestations.urn:mrn:imo:mmsi:",type:"basestation"},{prefix:"vessels.urn:mrn:imo:mmsi:",type:"vessel"},{prefix:"sar.urn:mrn:imo:mmsi:",type:"sar"}],at="self.navigation.*",et=(()=>{class l{data=w(De);destroyRef=w(xe);tracks=new Map;contextIndex=new Map;mmsiIndex=new Map;maxTargets=st;targetTtlMs=it;targetsDirty$=new te;ownShipDirty$=new te;pendingOwnShip={};_targets=vt$1([]);_ownShip=vt$1({});_hasCollisionRiskData=vt$1(false);targets=this._targets.asReadonly();ownShip=this._ownShip.asReadonly();hasCollisionRiskData=this._hasCollisionRiskData.asReadonly();getBearingTrue(e,t){if(typeof e.latitude!="number"||typeof e.longitude!="number"||typeof t.latitude!="number"||typeof t.longitude!="number")return null;let i=e.latitude*Math.PI/180,s=t.latitude*Math.PI/180,r=(t.longitude-e.longitude)*Math.PI/180,o=Math.sin(r)*Math.cos(s),n=Math.cos(i)*Math.sin(s)-Math.sin(i)*Math.cos(s)*Math.cos(r),d=Math.atan2(o,n)*180/Math.PI;return this.wrapDegrees(d)}constructor(){zm(...rt.map(t=>this.data.subscribePathTree(t))).pipe(Gp(this.destroyRef)).subscribe(t=>this.handleAisTreeUpdate(t)),this.data.subscribePathTree(at).pipe(Gp(this.destroyRef)).subscribe(t=>this.handleOwnShipTreeUpdate(t)),this.targetsDirty$.pipe(eu(Je,void 0,{leading:true,trailing:true}),Gp(this.destroyRef)).subscribe(()=>this.flushTargetsSignal()),ms(nt).pipe(Gp(this.destroyRef)).subscribe(()=>this.evictStaleTracks(Date.now())),this.ownShipDirty$.pipe(eu(Je,void 0,{leading:true,trailing:true}),Gp(this.destroyRef)).subscribe(()=>this.flushOwnShip());}handleAisTreeUpdate(e){let t=this.matchAisContext(e.path);t&&(this.applyAisUpdate({context:t.context,type:t.type,path:t.path,value:e.update.data.value,timestampMs:this.toTimestampMs(e.update.data.timestamp)}));}handleOwnShipTreeUpdate(e){if(!e.path.startsWith("self."))return;let t=e.path.slice(5);this.applyOwnShipUpdate(t,e.update.data.value);}matchAisContext(e){for(let t of ot){if(!e.startsWith(t.prefix))continue;let i=e.indexOf(".",t.prefix.length);return i===-1?null:{context:e.slice(0,i),path:e.slice(i+1),type:t.type}}return null}applyOwnShipUpdate(e,t){let i=G$1({},this.pendingOwnShip),s=this.readPositionValue(t);switch(e){case "navigation.position":s&&(i.position=s);break;case "navigation.position.latitude":{let r=this.toNumberOrUndefined(t);if(r===void 0)return;i.position=z(G$1({},i.position??{}),{latitude:r});}break;case "navigation.position.longitude":{let r=this.toNumberOrUndefined(t);if(r===void 0)return;i.position=z(G$1({},i.position??{}),{longitude:r});}break;case "navigation.headingTrue":i.headingTrue=this.toNumberOrUndefined(t);break;case "navigation.courseOverGroundTrue":i.courseOverGroundTrue=this.toNumberOrUndefined(t);break;case "navigation.speedOverGround":i.speedOverGround=this.toNumberOrUndefined(t);break;default:return}this.pendingOwnShip=i,this.ownShipDirty$.next();}flushOwnShip(){this.ownShipChanged(this._ownShip(),this.pendingOwnShip)&&this._ownShip.set(this.pendingOwnShip);}ownShipChanged(e,t){return e.headingTrue!==t.headingTrue||e.courseOverGroundTrue!==t.courseOverGroundTrue||e.speedOverGround!==t.speedOverGround||e.position?.latitude!==t.position?.latitude||e.position?.longitude!==t.position?.longitude}applyAisUpdate(e){let t=this.resolveTrack(e);if(t){switch(t.lastUpdateAt=e.timestampMs,e.path.startsWith("navigation.closestApproach.")&&this.isVesselLike(t)&&!t.closestApproach&&(t.closestApproach={}),e.path){case "mmsi":this.applyMmsi(t,e.value);break;case "name":t.name=this.toStringOrUndefined(e.value);break;case "communication.callsignVhf":this.isVesselLike(t)&&(t.callsign=this.toStringOrUndefined(e.value));break;case "navigation.destination":case "navigation.destination.commonName":this.isVesselLike(t)&&(t.destination=this.toStringOrUndefined(e.value));break;case "navigation.destination.eta":this.isVesselLike(t)&&(t.eta=this.toStringOrUndefined(e.value));break;case "design.beam":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{beam:this.toNumberOrUndefined(e.value)}));break;case "design.length.overall":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{length:z(G$1({},t.design?.length??{}),{overall:this.toNumberOrUndefined(e.value)})}));break;case "design.length.hull":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{length:z(G$1({},t.design?.length??{}),{hull:this.toNumberOrUndefined(e.value)})}));break;case "design.length.waterline":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{length:z(G$1({},t.design?.length??{}),{waterline:this.toNumberOrUndefined(e.value)})}));break;case "design.draft.maximum":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{draft:z(G$1({},t.design?.draft??{}),{maximum:this.toNumberOrUndefined(e.value)})}));break;case "design.draft.minimum":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{draft:z(G$1({},t.design?.draft??{}),{minimum:this.toNumberOrUndefined(e.value)})}));break;case "design.draft.current":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{draft:z(G$1({},t.design?.draft??{}),{current:this.toNumberOrUndefined(e.value)})}));break;case "design.draft.canoe":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{draft:z(G$1({},t.design?.draft??{}),{canoe:this.toNumberOrUndefined(e.value)})}));break;case "registrations.imo":this.isVesselLike(t)&&(t.imo=this.toStringOrUndefined(e.value));break;case "navigation.courseOverGroundTrue":this.isVesselLike(t)&&(t.courseOverGroundTrue=this.toNumberOrUndefined(e.value));break;case "navigation.headingTrue":this.isVesselLike(t)&&(t.headingTrue=this.toNumberOrUndefined(e.value));break;case "navigation.rateOfTurn":this.isVesselLike(t)&&(t.rateOfTurn=this.toNumberOrUndefined(e.value));break;case "navigation.specialManeuver":this.isVesselLike(t)&&(t.specialManeuver=this.toStringOrUndefined(e.value));break;case "navigation.speedOverGround":this.isVesselLike(t)&&(t.speedOverGround=this.toNumberOrUndefined(e.value));break;case "navigation.state":this.isVesselLike(t)&&(t.navState=this.toStringOrUndefined(e.value));break;case "sensors.ais.class":t.ais.class=this.normalizeAisClass(e.value);break;case "sensors.ais.status":{let i=this.normalizeAisStatus(e.value);if(!i)break;if(i==="remove"){this.removeTrack(t);return}t.ais.status=i;}break;case "sensors.ais.fromBow":this.isVesselLike(t)&&(t.fromBow=this.toNumberOrUndefined(e.value));break;case "sensors.ais.fromCenter":this.isVesselLike(t)&&(t.fromCenter=this.toNumberOrUndefined(e.value));break;case "navigation.position.latitude":{let i=this.toNumberOrUndefined(e.value);if(i===void 0)break;t.position=z(G$1({},t.position??{}),{latitude:i}),t.lastPositionAt=e.timestampMs;}break;case "navigation.position.longitude":{let i=this.toNumberOrUndefined(e.value);if(i===void 0)break;t.position=z(G$1({},t.position??{}),{longitude:i}),t.lastPositionAt=e.timestampMs;}break;case "navigation.position.altitude":{let i=this.toNumberOrUndefined(e.value);t.position&&(t.position=z(G$1({},t.position),{altitude:i}));}break;case "navigation.position":{let i=this.readPositionValue(e.value);i&&(t.position=i,t.lastPositionAt=e.timestampMs);}break;case "atonType.id":this.isAton(t)&&(t.typeId=this.toNumberOrUndefined(e.value));break;case "atonType.name":this.isAton(t)&&(t.typeName=this.toStringOrUndefined(e.value));break;case "virtual":this.isAton(t)&&(t.virtual=!!e.value);break;case "offPosition":this.isAton(t)&&(t.offPosition=!!e.value);break;case "design.aisShipType.id":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{aisShipType:z(G$1({},t.design?.aisShipType??{}),{id:this.toNumberOrUndefined(e.value)})}));break;case "design.aisShipType.name":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{aisShipType:z(G$1({},t.design?.aisShipType??{}),{name:this.toStringOrUndefined(e.value)})}));break;case "navigation.closestApproach.distance":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.distance=this.toNumberOrUndefined(e.value));break;case "navigation.closestApproach.timeTo":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.timeTo=this.toNumberOrUndefined(e.value));break;case "navigation.closestApproach.range":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.range=this.toNumberOrUndefined(e.value));break;case "navigation.closestApproach.bearing":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.bearing=this.toNumberOrUndefined(e.value));break;case "navigation.closestApproach.collisionRiskRating":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.collisionRiskRating=this.toNumberOrUndefined(e.value));break}this.updateTargetsSignal();}}resolveTrack(e){let t=this.contextIndex.get(e.context),i=e.timestampMs,s=t?this.tracks.get(t):null;if(s)return s;let r=this.createTrack(e.context,e.type,i,void 0);return this.contextIndex.set(e.context,r.id),r}createTrack(e,t,i,s){let r=this.buildTrackId(s??e),o=this.buildBaseTarget(e,t,i,s,r),n;switch(t){case "vessel":n=z(G$1({},o),{type:"vessel",closestApproach:{}});break;case "sar":n=z(G$1({},o),{type:"sar",closestApproach:{}});break;case "aton":n=z(G$1({},o),{type:"aton"});break;default:n=z(G$1({},o),{type:"basestation"});break}return this.tracks.set(n.id,n),s&&this.addMmsiIndex(s,n.id),this.enforceTargetCap(),this.updateTargetsSignal(),n}buildTrackId(e){if(!this.tracks.has(e))return e;let t=1;for(;this.tracks.has(`${e}-${t}`);)t+=1;return `${e}-${t}`}applyMmsi(e,t){let i=this.toStringOrUndefined(t);if(!i)return;let s=this.getTracksByMmsi(i).filter(r=>r.id!==e.id);s.length&&(this.markConflict(i),K),e.mmsi&&e.mmsi!==i&&this.removeMmsiIndex(e.mmsi,e.id),e.mmsi=i,this.addMmsiIndex(i,e.id);}removeTrack(e){this.tracks.delete(e.id),e.mmsi&&this.removeMmsiIndex(e.mmsi,e.id);for(let[t,i]of this.contextIndex.entries())i===e.id&&this.contextIndex.delete(t);this.updateTargetsSignal();}updateTargetsSignal(){this.targetsDirty$.next();}enforceTargetCap(){for(;this.tracks.size>this.maxTargets;){let e=null;for(let t of this.tracks.values())(!e||t.lastUpdateAt<e.lastUpdateAt)&&(e=t);if(!e)break;this.removeTrack(e);}}evictStaleTracks(e){let t=e-this.targetTtlMs,i=[];for(let s of this.tracks.values())s.lastUpdateAt<t&&i.push(s);for(let s of i)this.removeTrack(s);this.enforceTargetCap();}flushTargetsSignal(){let e=Array.from(this.tracks.values()).filter(i=>!!i.mmsi||!!i.position),t=e.some(i=>{if(!this.isVesselLike(i))return false;let s=i.closestApproach??{};return Object.prototype.hasOwnProperty.call(s,"collisionRiskRating")});this._targets.set(e),this._hasCollisionRiskData.set(t);}getTracksByMmsi(e){let t=this.mmsiIndex.get(e);return t?Array.from(t).map(i=>this.tracks.get(i)).filter(i=>!!i):[]}addMmsiIndex(e,t){this.mmsiIndex.has(e)||this.mmsiIndex.set(e,new Set),this.mmsiIndex.get(e).add(t);}removeMmsiIndex(e,t){let i=this.mmsiIndex.get(e);i&&(i.delete(t),i.size||this.mmsiIndex.delete(e));}markConflict(e){let t=this.getTracksByMmsi(e);for(let i of t)i.conflicted=true;}normalizeAisClass(e){let t=typeof e=="string"?e.toUpperCase():"";if(t==="A")return "A";if(t==="B")return "B"}normalizeAisStatus(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="unconfirmed"||t==="confirmed"||t==="lost"||t==="remove")return t}toTimestampMs(e){if(!e)return Date.now();let t=e instanceof Date?e.getTime():Date.parse(e);return Number.isFinite(t)?t:Date.now()}toNumberOrUndefined(e){let t=Number(e);return Number.isFinite(t)?t:void 0}toStringOrUndefined(e){if(e==null)return;let t=String(e).trim();return t.length?t:void 0}wrapDegrees(e){let t=e%360;return t<0?t+360:t}buildBaseTarget(e,t,i,s,r){return {id:r,context:e,type:t,ais:{class:void 0,status:"unconfirmed"},conflicted:false,mmsi:s,position:void 0,lastUpdateAt:i,lastPositionAt:void 0}}isVesselLike(e){return e.type==="vessel"||e.type==="sar"}isAton(e){return e.type==="aton"}readPositionValue(e){if(!e||typeof e!="object")return;let t=this.toNumberOrUndefined(e.latitude),i=this.toNumberOrUndefined(e.longitude);if(t===void 0||i===void 0)return;let s=this.toNumberOrUndefined(e.altitude);return {latitude:t,longitude:i,altitude:s}}static \u0275fac=function(t){return new(t||l)};static \u0275prov=Q({token:l,factory:l.\u0275fac,providedIn:"root"})}return l})();var lt=["radarSvg"],ct=["menuAnchor"],dt=["menuTrigger"],ht=(l,I)=>I.id;function ut(l,I){l&1&&(wd(),Pi(0,"svg",7),$h(1,"path",17),Pi(2,"text",18),TT(3,"N"),ul()());}function mt(l,I){l&1&&(wd(),Pi(0,"svg",7),$h(1,"path",19),ul());}function gt(l,I){if(l&1){let e=Fw();Pi(0,"button",20),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("noCollisionRisk"))}),Pi(1,"mat-icon"),TT(2,"security"),ul()();}if(l&2){let e=qw();sg("is-active",e.isFilterEnabled("noCollisionRisk"));}}function pt(l,I){if(l&1){let e=Fw();Pi(0,"button",22),Qh("click",function(){let i=ud(e).$implicit,s=qw(2);return dd(s.onMenuItemSelect(i))}),$h(1,"img",23),Pi(2,"span",24),TT(3),ul()();}if(l&2){let e=I.$implicit;EE(),ig("visibility",e.iconHref?"visible":"hidden"),Hh("src",e.iconHref??null,fp),EE(2),gg(e.label);}}function ft(l,I){if(l&1&&xw(0,pt,4,4,"button",21,ht),l&2){let e=qw();Aw(e.menuItems());}}function St(l,I){if(l&1){let e=Fw();Pi(0,"button",25),TT(1,"Filter Targets"),ul(),Pi(2,"button",26),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("anchoredMoored"))}),Pi(3,"mat-icon",27),TT(4),ul(),Pi(5,"span"),TT(6,"Anchored/Moored"),ul()(),Pi(7,"button",26),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("allAton"))}),Pi(8,"mat-icon",27),TT(9),ul(),Pi(10,"span"),TT(11,"All AtoN"),ul()(),Pi(12,"button",26),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("allButSar"))}),Pi(13,"mat-icon",27),TT(14),ul(),Pi(15,"span"),TT(16,"All but SAR"),ul()(),Pi(17,"button",26),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("allVessels"))}),Pi(18,"mat-icon",27),TT(19),ul(),Pi(20,"span"),TT(21,"All Vessels"),ul()(),Pi(22,"button",28)(23,"span"),TT(24,"Vessel Type"),ul(),Pi(25,"mat-icon"),TT(26,"chevron_right"),ul()();}if(l&2){let e=qw(),t=Jw(26);EE(4),gl(" ",e.isFilterEnabled("anchoredMoored")?"check_box":"check_box_outline_blank"," "),EE(5),gl(" ",e.isFilterEnabled("allAton")?"check_box":"check_box_outline_blank"," "),EE(5),gl(" ",e.isFilterEnabled("allButSar")?"check_box":"check_box_outline_blank"," "),EE(5),gl(" ",e.isFilterEnabled("allVessels")?"check_box":"check_box_outline_blank"," "),EE(3),Bh("matMenuTriggerFor",t);}}function vt(l,I){if(l&1){let e=Fw();Pi(0,"button",26),Qh("click",function(){let i=ud(e).$implicit,s=qw(2);return dd(s.toggleVesselTypeFilter(i))}),Pi(1,"mat-icon",27),TT(2),ul(),Pi(3,"span"),TT(4),ul()();}if(l&2){let e=I.$implicit,t=qw(2);EE(2),gl(" ",t.isVesselTypeFilterEnabled(e)?"check_box":"check_box_outline_blank"," "),EE(2),gg(t.formatVesselTypeLabel(e));}}function bt(l,I){if(l&1&&xw(0,vt,5,2,"button",29,Nw),l&2){let e=qw();Aw(e.vesselTypeFilters);}}function yt(l,I){l&1&&$h(0,"div",16);}var Qt=(()=>{class l{static TARGET_ICON_SIZE_PX=16;static OWN_SHIP_ICON_SIZE_PX=84;static HIT_RADIUS_PX=28;static ICON_RENDER_DEBOUNCE_MS=50;static ROTATION_SETTLE_DEADBAND_DEG=1;static ROTATION_ONLY_FRAME_MS=33;id=Hj.required();type=Hj.required();theme=Hj.required();runtime=w(p);ais=w(et);dialog=w(Ff);ngZone=w(ue);units=w(ut$1);settings=w(Gi);toast=w(lt$1);dashboard=w(G);static DEFAULT_CONFIG={filterSelfPaths:false,enableTimeout:false,dataTimeout:5,ais:{filters:{anchoredMoored:false,noCollisionRisk:false,allAton:false,allButSar:false,allVessels:false,vesselTypes:[]},viewMode:"course-up",rangeRings:[1,3,6,12,24,48],rangeIndex:"3",showCogVectors:true,cogVectorsMinutes:10,showLostTargets:true,showUnconfirmedTargets:true,showSelf:true},color:"grey"};svgRef=$j.required("radarSvg");menuAnchorRef=$j.required("menuAnchor");menuTrigger=$j.required("menuTrigger");hostSize=vt$1(null);renderState=null;selectedId=vt$1(null);localViewMode=vt$1(null);localRangeIndex=vt$1(null);effectiveViewMode=Dt(()=>this.localViewMode()??this.runtime.options()?.ais?.viewMode??"course-up");effectiveRangeIndex=Dt(()=>{let e=this.resolveRangeIndex(this.runtime.options()?.ais),t=this.runtime.options()?.ais?.rangeRings??[3,6,12,24,48],i=Math.max(0,t.length-1),s=this.localRangeIndex()??e;return Math.min(Math.max(s,0),i)});svg;root;ringsLayer;rotationGroup;vectorsLayer;targetsLayer;selectedLayer;ownShipLayer;viewRotationSmoothed=null;lastRotationAt=null;lastViewRotation=0;hasRenderedOnce=false;renderFrame=null;rotationFrameTimer=null;iconRenderTimer=null;iconCache=new Map;targetCache=new Map;lastOriginKey=null;ringCache=null;ownShipIconHref=null;menuItems=vt$1([]);menuPoint=null;lastRenderTargets=[];lastRenderScale=1;lastRenderSize=null;hitRadiusPx=l.HIT_RADIUS_PX;lastFiltersSignature=null;lastRenderSignature=null;ownShipVectorCache=null;filterState=vt$1({anchoredMoored:false,noCollisionRisk:false,allAton:false,allButSar:false,allVessels:false,vesselTypes:new Set});vesselTypeFilters=rn.filter(e=>e!=="vessel/self"&&e!=="vessel/unknown"&&e!=="vessel/spare");hasActiveFilters=Dt(()=>{let e=this.filterState();return e.anchoredMoored||e.allAton||e.allButSar||e.allVessels||e.vesselTypes.size>0});hasCollisionRiskData=this.ais.hasCollisionRiskData;constructor(){this.warnIfRemoteDataDisabled(),this.loadOwnShipIcon(),Fa(()=>{let e=this.hostSize(),t=this.runtime.options(),i=this.theme(),s=this.ais.targets(),r=this.ais.ownShip();!e||!t||!i||(ge(()=>{this.renderState={size:e,cfg:t,theme:i,targets:s,ownShip:r},this.syncFiltersFromConfig(t);}),this.scheduleRender());}),Fa(()=>{this.localViewMode(),this.localRangeIndex(),this.selectedId(),this.filterState(),ge(()=>{this.scheduleRender();});});}warnIfRemoteDataDisabled(){this.settings.signalKSubscribeAll||this.toast.show('AIS data is disabled in your connection. To see radar targets, go to Settings -> Options -> Connectivity, enable "Subscribe to remote sources messages", then reconnect.',0,false,"warn");}loadOwnShipIcon(){this.ngZone.runOutsideAngular(()=>{ac().then(e=>{this.ownShipIconHref=e,this.scheduleRenderDebounced();});});}ngAfterViewInit(){this.initSvg(),this.scheduleRender();}onResized(e){this.hostSize.set({width:e.width,height:e.height});}initSvg(){this.svg=ge$1(this.svgRef().nativeElement),this.svg.attr("class","ais-radar"),this.root=this.svg.append("g").attr("class","radar-root"),this.ringsLayer=this.root.append("g").attr("class","radar-rings"),this.rotationGroup=this.root.append("g").attr("class","radar-rotation"),this.vectorsLayer=this.rotationGroup.append("g").attr("class","radar-vectors"),this.targetsLayer=this.rotationGroup.append("g").attr("class","radar-targets"),this.selectedLayer=this.rotationGroup.append("g").attr("class","radar-selected"),this.ownShipLayer=this.root.append("g").attr("class","radar-ownship-layer"),this.svg.on("click",()=>{this.selectedId.set(null),this.closeTargetMenu();});}scheduleRender(){this.renderFrame===null&&this.ngZone.runOutsideAngular(()=>{this.renderFrame=requestAnimationFrame(()=>{this.renderFrame=null,this.render();});});}scheduleRenderDebounced(){this.iconRenderTimer===null&&this.ngZone.runOutsideAngular(()=>{this.iconRenderTimer=window.setTimeout(()=>{this.iconRenderTimer=null,this.scheduleRender();},l.ICON_RENDER_DEBOUNCE_MS);});}scheduleRotationOnlyRender(){this.rotationFrameTimer!==null||this.renderFrame!==null||this.ngZone.runOutsideAngular(()=>{this.rotationFrameTimer=window.setTimeout(()=>{this.rotationFrameTimer=null,this.scheduleRender();},l.ROTATION_ONLY_FRAME_MS);});}render(){if(!this.renderState||!this.svg||!this.root||!this.rotationGroup)return;let{size:e,cfg:t,theme:i,targets:s,ownShip:r}=this.renderState,o=Math.max(1,e.width),n=Math.max(1,e.height),d=Math.min(o,n)/2,u=(Math.min(o,n)-35)/Math.min(o,n),b=Math.hypot(o,n)/2/u,c$1=t.ais??{},T=c$1.rangeRings?.length?c$1.rangeRings:[3,6,12,24,48],x=this.effectiveRangeIndex(),a=T[x]??T[0],M=this.resolveRingCountForRange(a),S=this.localViewMode()??c$1.viewMode??"course-up",_=this.toDegreesIfRadians(r.courseOverGroundTrue),C=this.toDegreesIfRadians(r.headingTrue),V=_!==null||C!==null,m=S==="course-up"?_??C??0:0,B=this.viewRotationSmoothed!==null&&Math.abs(this.shortestAngleDelta(this.viewRotationSmoothed,m))<=l.ROTATION_SETTLE_DEADBAND_DEG,$=this.buildFilterStateSignature(this.filterState()),U=r.position?`${r.position.latitude},${r.position.longitude}`:"none",F={sizeKey:`${o}x${n}`,viewMode:S,rangeIndex:x,rangesKey:T.join(","),showSelf:c$1.showSelf??true,showCogVectors:c$1.showCogVectors??true,showLostTargets:c$1.showLostTargets??true,showUnconfirmedTargets:c$1.showUnconfirmedTargets??true,filtersKey:$,selectedId:this.selectedId(),targetsRef:s,ownPosKey:U,themeRef:i,color:t.color},L=!this.lastRenderSignature||!this.signaturesEqual(this.lastRenderSignature,F);if(!L&&B&&this.hasRenderedOnce)return;this.lastRenderSignature=F;let v=S==="course-up"&&V?this.smoothRotation(m):0,te=S==="course-up"?Math.abs(this.shortestAngleDelta(v,m)):0;this.lastViewRotation=v,this.svg.attr("viewBox",`${-o/2} ${-n/2} ${o} ${n}`),this.root.attr("transform",`scale(${u})`),this.rotationGroup.attr("transform",`rotate(${this.wrapDegrees(-v)})`);let me=this.wrapDegrees((_??C??0)-v);if(L){let ie=c(t.color??"contrast",i).dim;this.renderRings(M,a,d,b,v,u,c$1.showSelf??true,me,ie);}if(this.ownShipLayer?.select("g.radar-ownship").attr("transform",`rotate(${me})`),r.position&&this.hasValidPosition(r.position)&&(this.renderOwnShipVector(r,a,d,v,c$1),L)){let ie=b/d*a,W=this.buildTargets(s,r.position,a,ie,d,0,c$1);this.lastRenderTargets=W,this.lastRenderScale=u,this.lastRenderSize=e,this.renderTargetVectors(W,a,d,0,c$1),this.renderTargets(W,u),this.renderSelected(W,u);}this.raiseOwnshipAndVector(),this.hasRenderedOnce=true,te>l.ROTATION_SETTLE_DEADBAND_DEG&&(L?this.scheduleRender():this.scheduleRotationOnlyRender());}signaturesEqual(e,t){return e.sizeKey===t.sizeKey&&e.viewMode===t.viewMode&&e.rangeIndex===t.rangeIndex&&e.rangesKey===t.rangesKey&&e.showSelf===t.showSelf&&e.showCogVectors===t.showCogVectors&&e.showLostTargets===t.showLostTargets&&e.showUnconfirmedTargets===t.showUnconfirmedTargets&&e.filtersKey===t.filtersKey&&e.selectedId===t.selectedId&&e.targetsRef===t.targetsRef&&e.ownPosKey===t.ownPosKey&&e.themeRef===t.themeRef&&e.color===t.color}renderRings(e,t,i,s,r,o,n,d,u){if(!this.ringsLayer)return;let b=`${t.toFixed(3)}|${i.toFixed(3)}|${s.toFixed(3)}|${e}`;if(!this.ringCache||this.ringCache.key!==b){let m=t/Math.max(1,e),B=s/i*t,$=[];for(let v=m;v<=B+1e-6;v+=m)$.push(v);let U=$.map(v=>({value:v,radius:v/t*i})).filter(v=>v.radius<=s+1e-6),F=20,L=U.flatMap(v=>[{key:`${v.value}-top`,value:v.value,x:0,y:-v.radius+F},{key:`${v.value}-bottom`,value:v.value,x:0,y:v.radius-F}]);this.ringCache={key:b,rings:U,labels:L};}let c=this.ringCache;if(!c)return;let T=c.rings,x=this.ringsLayer.selectAll("circle.ring").data(T,m=>m.value.toString());x.enter().append("circle").attr("class","ring").merge(x).attr("r",m=>m.radius).attr("stroke",u),x.exit().remove();let a=c.labels,M=this.ringsLayer.selectAll("text.ring-label").data(a,m=>m.key);M.enter().append("text").attr("class","ring-label").merge(M).attr("x",m=>m.x).attr("y",m=>m.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(m=>`${m.value}`),M.exit().remove();let S=this.ringsLayer.selectAll("circle.radar-center").data(n?[]:[{r:Math.max(3,i*.01)}]);S.enter().append("circle").attr("class","radar-center").merge(S).attr("cx",0).attr("cy",0).attr("r",m=>m.r).attr("fill",u),S.exit().remove();let _=this.ownShipLayer.selectAll("g.radar-ownship").data(n?[{size:this.resolveOwnShipBaseSize(o)}]:[]),C=_.enter().append("g").attr("class","radar-ownship");C.append("image").attr("class","ownship-icon").attr("href",this.ownShipIconHref??null).attr("xlink:href",this.ownShipIconHref??null);let V=C.merge(_);V.attr("transform",`rotate(${d})`),V.select("image.ownship-icon").attr("href",this.ownShipIconHref??null).attr("xlink:href",this.ownShipIconHref??null).attr("display",this.ownShipIconHref?null:"none").attr("width",m=>m.size).attr("height",m=>m.size).attr("x",m=>-m.size/2).attr("y",m=>-m.size/2),_.exit().remove();}toggleViewMode(){let e=this.localViewMode()??this.runtime.options()?.ais?.viewMode??"course-up";this.localViewMode.set(e==="course-up"?"north-up":"course-up");}incrementRange(){this.localRangeIndex.set(Math.max(this.effectiveRangeIndex()-1,0));}decrementRange(){let e=this.runtime.options()?.ais?.rangeRings??[3,6,12,24,48],t=Math.max(0,e.length-1);this.localRangeIndex.set(Math.min(this.effectiveRangeIndex()+1,t));}toggleFilter(e){this.filterState.update(t=>z(G$1({},t),{[e]:!t[e]}));}toggleVesselTypeFilter(e){this.filterState.update(t=>{let i=new Set(t.vesselTypes);return i.has(e)?i.delete(e):i.add(e),z(G$1({},t),{vesselTypes:i})});}isFilterEnabled(e){return this.filterState()[e]}isVesselTypeFilterEnabled(e){return this.filterState().vesselTypes.has(e)}formatVesselTypeLabel(e){let t=e.replace("vessel/","");switch(t){case "pleasurecraft":return "Pleasure Craft";case "highspeed":return "High Speed";case "sar":return "SAR";case "law":return "Law Enforcement";default:return `${t.charAt(0).toUpperCase()}${t.slice(1)}`}}syncFiltersFromConfig(e){let t=e.ais?.filters;if(!t)return;let i=this.buildFilterSignature(t);i!==this.lastFiltersSignature&&(this.lastFiltersSignature=i,this.filterState.set({anchoredMoored:t.anchoredMoored??false,noCollisionRisk:t.noCollisionRisk??false,allAton:t.allAton??false,allButSar:t.allButSar??false,allVessels:t.allVessels??false,vesselTypes:new Set(t.vesselTypes??[])}));}buildFilterSignature(e){let t=[...e?.vesselTypes??[]].sort();return JSON.stringify({anchoredMoored:e?.anchoredMoored??false,noCollisionRisk:e?.noCollisionRisk??false,allAton:e?.allAton??false,allButSar:e?.allButSar??false,allVessels:e?.allVessels??false,vesselTypes:t})}buildFilterStateSignature(e){let t=[...e.vesselTypes].sort();return JSON.stringify({anchoredMoored:e.anchoredMoored,noCollisionRisk:e.noCollisionRisk,allAton:e.allAton,allButSar:e.allButSar,allVessels:e.allVessels,vesselTypes:t})}resolveRingCountForRange(e){return [3].find(i=>this.isNiceStep(e/i))??4}isNiceStep(e){return [.5,1,2,2.5,3,4,5,6,8,10,12,15,20,25].some(i=>Math.abs(e-i)<1e-6)}resolveRangeIndex(e){return e?Number(e.rangeIndex):0}buildTargets(e,t,i,s,r,o,n){let d=n.showLostTargets??true,u=n.showUnconfirmedTargets??true,b=`${t.latitude?.toFixed(6)}|${t.longitude?.toFixed(6)}`;this.lastOriginKey!==b&&(this.targetCache.clear(),this.lastOriginKey=b);let c=new Set;for(let a of e)c.add(a.id);for(let a of this.targetCache.keys())c.has(a)||this.targetCache.delete(a);for(let a of this.iconCache.keys())c.has(a)||this.iconCache.delete(a);let T=[];for(let a of e)a.ais.status==="remove"&&(this.targetCache.delete(a.id),this.iconCache.delete(a.id),this.selectedId()===a.id&&this.selectedId.set(null));let x=e.filter(a=>a.ais.status==="remove"||a.ais.status==="lost"&&!d||a.ais.status==="unconfirmed"&&!u||!a.position||!this.hasValidPosition(a.position)?false:!this.shouldFilterTarget(a));for(let a of x){let M=this.buildTrackSignature(a),S=this.targetCache.get(a.id);if(!S||S.signature!==M){let F=this.distanceNm(t,a.position),L=this.ais.getBearingTrue(t,a.position)??0,v=this.toDegreesIfRadians(this.isVesselLike(a)?a.headingTrue:null),te=this.toDegreesIfRadians(this.isVesselLike(a)?a.courseOverGroundTrue:null);S={signature:M,distanceNm:F,bearing:L,trackHeading:v,trackCog:te},this.targetCache.set(a.id,S);}if(S.distanceNm>s)continue;let{href:_,scale:C}=this.resolveIconCached(a),V=this.wrapDegrees(S.bearing-o),{x:m,y:B}=this.polarToCartesian(V,S.distanceNm,i,r),$=a.type==="aton"||a.type==="basestation"?0:this.wrapDegrees((S.trackHeading??S.trackCog??0)-o),U=this.buildClassName({id:a.id,status:a.ais.status,aisClass:a.ais.class,type:a.type,navState:this.isVesselLike(a)?a.navState:void 0});T.push({id:a.id,raw:a,x:m,y:B,heading:$,status:a.ais.status,aisClass:a.ais.class,type:a.type,iconHref:_,iconScale:C,navState:this.isVesselLike(a)?a.navState:void 0,sog:this.isVesselLike(a)?a.speedOverGround:void 0,cog:S.trackCog??null,className:U});}return T}renderTargetVectors(e,t,i,s,r){if(!this.vectorsLayer)return;let o=r.showCogVectors??true,n=Math.max(6,i*.04),d=(r.cogVectorsMinutes??5)*60,u=n*.8,b=[];for(let c of e)if(this.isVesselLike(c.raw)&&!this.isStationaryNavState(c.raw.navState)&&o&&typeof c.sog=="number"&&typeof c.cog=="number"){let T=this.wrapDegrees(c.cog-s),x=this.offsetPoint(c.x,c.y,T,u),a=c.sog*d/1852,M=Math.max(0,a/t*i-u);if(M<=0)continue;let S=this.offsetPoint(x.x,x.y,T,M),_=this.resolveTargetVectorStroke(c.raw);b.push({id:c.id,x1:x.x,y1:x.y,x2:S.x,y2:S.y,className:c.className,stroke:_});}this.renderVectorLines(this.vectorsLayer,"motion-vector",b);}renderOwnShipVector(e,t,i,s,r){if(!this.ownShipLayer)return;let o=Math.max(6,i*.04),n=(r.cogVectorsMinutes??5)*60,d=o*.8,u=[];if(!(r.showSelf??true)){this.ownShipVectorCache=null,this.renderVectorLines(this.ownShipLayer,"ownship-vector",u);return}let c=this.toDegreesIfRadians(e.courseOverGroundTrue),T=e.speedOverGround;if(c===null||typeof T!="number"){this.ownShipVectorCache=null,this.renderVectorLines(this.ownShipLayer,"ownship-vector",u);return}let x=T*n/1852,a=Math.max(0,x/t*i-d);if(a<=0){this.ownShipVectorCache=null,this.renderVectorLines(this.ownShipLayer,"ownship-vector",u);return}let M=[c.toFixed(6),T.toFixed(6),t.toFixed(6),i.toFixed(6),n,d.toFixed(6)].join("|");if(!this.ownShipVectorCache||this.ownShipVectorCache.key!==M){let C=this.wrapDegrees(c),V=this.offsetPoint(0,0,C,d),m=this.offsetPoint(V.x,V.y,C,a);this.ownShipVectorCache={key:M,tipX:V.x,tipY:V.y,endX:m.x,endY:m.y};}let S=this.rotatePoint(this.ownShipVectorCache.tipX,this.ownShipVectorCache.tipY,-s),_=this.rotatePoint(this.ownShipVectorCache.endX,this.ownShipVectorCache.endY,-s);u.push({id:"ownship",x1:S.x,y1:S.y,x2:_.x,y2:_.y,className:"ownship-vector",stroke:"var(--kip-orange-color)"}),this.renderVectorLines(this.ownShipLayer,"ownship-vector",u);}rotatePoint(e,t,i){let s=i*Math.PI/180,r=Math.cos(s),o=Math.sin(s);return {x:e*r-t*o,y:e*o+t*r}}renderVectorLines(e,t,i){let s=e.selectAll(`line.${t}`).data(i,o=>o.id);s.enter().append("line").attr("class",o=>`${t} ${o.className}`).merge(s).attr("x1",o=>o.x1).attr("y1",o=>o.y1).attr("x2",o=>o.x2).attr("y2",o=>o.y2).style("stroke",o=>o.stroke??"#50505f").style("stroke-width",2).style("opacity",1).style("stroke-dasharray","15, 7"),s.exit().remove();let r=e.selectAll(`circle.${t}-tip`).data(i,o=>o.id);r.enter().append("circle").attr("class",o=>`${t}-tip ${o.className}`).merge(r).attr("cx",o=>o.x2).attr("cy",o=>o.y2).attr("r",2.5).style("fill",o=>o.stroke??"#50505f").style("stroke",o=>o.stroke??"#50505f").style("stroke-width",2).style("opacity",1).style("stroke-dasharray","15, 7"),r.exit().remove();}renderTargets(e,t){if(!this.targetsLayer)return;let i=this.resolveTargetBaseSize(t),s=this.targetsLayer.selectAll("g.target").data(e,n=>n.id),r=s.enter().append("g").on("click",(n,d)=>{n.stopPropagation(),this.handleTargetClick(n,d);});r.append("image").attr("class","target-icon"),r.append("title");let o=r.merge(s);o.attr("transform",n=>`translate(${n.x}, ${n.y}) rotate(${n.heading})`).attr("class",n=>`target ${n.className}`),o.select("image.target-icon").attr("href",n=>n.iconHref??null).attr("xlink:href",n=>n.iconHref??null).attr("display",n=>n.iconHref?null:"none").attr("width",n=>i*n.iconScale).attr("height",n=>i*n.iconScale).attr("x",n=>-(i*n.iconScale)/2).attr("y",n=>-(i*n.iconScale)/2),o.select("title").text(n=>`${n.raw.name??n.raw.mmsi??"AIS Target"}`),s.exit().remove();}renderSelected(e,t){if(!this.selectedLayer)return;let i=e.filter(u=>u.id===this.selectedId()),s=this.resolveTargetBaseSize(t),r=s*1.4,o=Math.min(r,Math.max(4,s*.6)),n=this.buildCornerBoxPath(r,o),d=this.selectedLayer.selectAll("path.selected-ring").data(i,u=>u.id);d.enter().append("path").attr("class","selected-ring").merge(d).attr("transform",u=>`translate(${u.x}, ${u.y})`).attr("d",n),d.exit().remove();}resolveTargetBaseSize(e){let t=Math.max(.2,e);return l.TARGET_ICON_SIZE_PX/t}resolveOwnShipBaseSize(e){let t=Math.max(.2,e);return l.OWN_SHIP_ICON_SIZE_PX/t}raiseOwnshipAndVector(){this.ownShipLayer?.raise();}onMenuItemSelect(e){this.openTargetDialog(e.target,e.iconHref),this.selectedId.set(null),this.closeTargetMenu();}handleTargetClick(e,t){let i=this.resolveMenuItems(e,t);if(i.length<=1){this.openTargetDialog(t.raw,t.iconHref);return}this.menuItems.set(i),this.menuPoint=this.resolveMenuPoint(e),this.positionMenuAnchor(),this.menuTrigger().openMenu();}openTargetDialog(e,t){this.selectedId.set(e.id);let i=this.snapshotAisTrack(e);this.dialog.openAisDetailDialog({title:this.buildTargetTitle(i),iconHref:t??void 0,component:"ais-target",componentType:cn,payload:{target:i}}).subscribe();}snapshotAisTrack(e){return structuredClone(e)}resolveMenuItems(e,t){return this.findTargetsNearEvent(e,t).map(s=>({id:s.id,label:this.buildTargetMenuLabel(s.raw),iconHref:s.iconHref,target:s.raw}))}findTargetsNearEvent(e,t){let i=this.lastRenderTargets.length?this.lastRenderTargets:[t],s=this.eventToRadarPoint(e);if(!s)return [t];let r=this.hitRadiusPx/this.lastRenderScale,o=i.map((n,d)=>{let u=n.x-s.x,b=n.y-s.y,c=Math.hypot(u,b);return {candidate:n,distance:c,index:d}}).filter(n=>n.distance<=r).sort((n,d)=>n.distance-d.distance||n.index-d.index).map(n=>n.candidate);return o.length?o:[t]}eventToRadarPoint(e){if(!this.lastRenderSize)return null;let s=this.svgRef().nativeElement.getBoundingClientRect(),r=e.clientX-s.left,o=e.clientY-s.top,n=(r-s.width/2)/this.lastRenderScale,d=(o-s.height/2)/this.lastRenderScale,u=this.lastViewRotation*Math.PI/180,b=Math.cos(u),c=Math.sin(u);return {x:n*b-d*c,y:n*c+d*b}}resolveMenuPoint(e){let t=this.svgRef().nativeElement.closest(".ais-radar-container");if(!t)return null;let i=t.getBoundingClientRect();return {x:e.clientX-i.left,y:e.clientY-i.top}}positionMenuAnchor(){let e=this.menuAnchorRef().nativeElement;this.menuPoint&&(e.style.left=`${this.menuPoint.x}px`,e.style.top=`${this.menuPoint.y}px`);}closeTargetMenu(){this.resetTargetMenuState(),this.menuTrigger().menuOpen&&this.menuTrigger().closeMenu();}resetTargetMenuState(){this.menuItems.set([]),this.menuPoint=null;}buildTargetMenuLabel(e){return this.isAton(e)&&e.typeName?e.typeName:e.name??e.mmsi??"AIS Target"}buildTargetTitle(e){let t=this.isAton(e)&&e.typeName?e.typeName:e.name??e.type??"AIS Target",i=e.ais.status;return i==="unconfirmed"||i==="lost"||i==="remove"?`${t} - ${i}`:t}resolveIconCached(e){let t=this.buildIconSignature(e),i=this.iconCache.get(e.id);if(i&&i.signature===t)return i.icon;let s=this.resolveIconScale(e.type),r={href:i?.icon.href??null,scale:s};this.iconCache.set(e.id,{signature:t,icon:r});let o=e.ais.status==="remove"?void 0:e.ais.status;return this.ngZone.runOutsideAngular(()=>{nc({mmsi:e.mmsi??"",type:e.type,navState:this.isVesselLike(e)?e.navState:void 0,aisShipTypeId:this.isVesselLike(e)?e.design?.aisShipType?.id:void 0,atonVirtual:this.isAton(e)?e.virtual:void 0,atonTypeId:this.isAton(e)?e.typeId:void 0,status:o,collisionRiskRating:this.isVesselLike(e)?e.closestApproach?.collisionRiskRating:void 0}).then(n=>{let d=this.iconCache.get(e.id);!d||d.signature!==t||(d.icon={href:n,scale:s},this.scheduleRenderDebounced());});}),r}resolveIconScale(e){switch(e){case "aton":return 3.5;case "basestation":return 3;case "sar":return 2.4;case "vessel":return 3;default:return 2.4}}buildIconSignature(e){let t=e.ais.status==="lost"?"unconfirmed":e.ais.status;return [e.mmsi,e.type,this.isVesselLike(e)?e.navState:void 0,this.isVesselLike(e)?e.design?.aisShipType?.id:void 0,this.isAton(e)?e.virtual:void 0,this.isAton(e)?e.typeId:void 0,t,this.isVesselLike(e)?e.closestApproach?.collisionRiskRating:void 0].join("|")}buildClassName(e){let t=[`status-${e.status}`,`type-${e.type}`,e.aisClass?`class-${e.aisClass.toLowerCase()}`:"class-unknown"];if(e.navState){let i=e.navState.toLowerCase();i.includes("moored")&&t.push("state-moored"),i.includes("anchored")&&t.push("state-anchored");}return e.id===this.selectedId()&&t.push("is-selected"),t.join(" ")}resolveTargetVectorStroke(e){if(e.ais.status!=="confirmed")return "#50505f";let t=e.closestApproach?.collisionRiskRating,i=typeof t=="number"?t:Number(t);return Number.isFinite(i)?i<qn?"red":i<zn?"yellow":"#50505f":"#50505f"}shouldFilterTarget(e){let t=this.filterState();if(!t.anchoredMoored&&!t.noCollisionRisk&&!t.allAton&&!t.allButSar&&!t.allVessels&&t.vesselTypes.size===0)return false;if(t.anchoredMoored&&this.isVesselLike(e)&&this.isStationaryNavState(e.navState)||t.noCollisionRisk&&this.isVesselLike(e)&&(e.ais.status!=="confirmed"||this.isStationaryNavState(e.navState)||this.isNoCollisionRisk(e))||t.allAton&&e.type==="aton"||t.allButSar&&e.type!=="sar"||t.allVessels&&this.isVesselLike(e))return true;if(t.vesselTypes.size>0&&this.isVesselLike(e)){let i=this.resolveVesselIconKey(e);if(i&&t.vesselTypes.has(i))return true}return false}isNoCollisionRisk(e){let t=e.closestApproach?.collisionRiskRating;if(!Object.prototype.hasOwnProperty.call(e.closestApproach??{},"collisionRiskRating"))return false;if(t==null)return true;let i=typeof t=="number"?t:Number(t);return Number.isFinite(i)?i>=zn:true}resolveVesselIconKey(e){if(!this.isVesselLike(e))return null;let t=pa({mmsi:e.mmsi??e.id??"",type:e.type,aisShipTypeId:e.design?.aisShipType?.id});return t.startsWith("vessel/")?t:null}polarToCartesian(e,t,i,s){let r=e*Math.PI/180,o=t/i*s;return {x:o*Math.sin(r),y:-o*Math.cos(r)}}hasValidPosition(e){return typeof e?.latitude=="number"&&Number.isFinite(e.latitude)&&typeof e?.longitude=="number"&&Number.isFinite(e.longitude)}offsetPoint(e,t,i,s){let r=i*Math.PI/180;return {x:e+s*Math.sin(r),y:t-s*Math.cos(r)}}wrapDegrees(e){let t=e%360;return t<0?t+360:t}isStationaryNavState(e){if(typeof e=="number"&&Number.isFinite(e))return e===1||e===5;if(typeof e!="string")return false;let t=e.trim().toLowerCase().replace(/\s+/g," ");if(!t.length)return false;let i=Number(t);return Number.isFinite(i)?i===1||i===5:t.includes("moored")||t.includes("anchored")||t.includes("at anchor")}shortestAngleDelta(e,t){return (t-e+540)%360-180}buildTrackSignature(e){let t=e.position??{};return [t.latitude,t.longitude,this.isVesselLike(e)?e.headingTrue:void 0,this.isVesselLike(e)?e.courseOverGroundTrue:void 0].join("|")}isVesselLike(e){return e.type==="vessel"||e.type==="sar"}isAton(e){return e.type==="aton"}buildCornerBoxPath(e,t){let i=e,s=Math.min(Math.max(t,0),i);return [`M ${-i} ${-i} h ${s}`,`M ${-i} ${-i} v ${s}`,`M ${i} ${-i} h ${-s}`,`M ${i} ${-i} v ${s}`,`M ${-i} ${i} h ${s}`,`M ${-i} ${i} v ${-s}`,`M ${i} ${i} h ${-s}`,`M ${i} ${i} v ${-s}`].join(" ")}smoothRotation(e){let t=performance.now();if(this.viewRotationSmoothed===null||this.lastRotationAt===null)return this.viewRotationSmoothed=this.wrapDegrees(e),this.lastRotationAt=t,this.viewRotationSmoothed;let i=Math.min(250,Math.max(0,t-this.lastRotationAt)),s=Math.min(1,i/200),r=this.shortestAngleDelta(this.viewRotationSmoothed,e);return this.viewRotationSmoothed=this.wrapDegrees(this.viewRotationSmoothed+r*s),this.lastRotationAt=t,this.viewRotationSmoothed}toDegreesIfRadians(e){return typeof e!="number"||!Number.isFinite(e)?null:this.units.convertToUnit("deg",e)}distanceNm(e,t){let s=e.latitude*Math.PI/180,r=t.latitude*Math.PI/180,o=(t.latitude-e.latitude)*Math.PI/180,n=(t.longitude-e.longitude)*Math.PI/180,d=Math.sin(o/2),u=Math.sin(n/2),b=d*d+Math.cos(s)*Math.cos(r)*u*u;return 6371e3*(2*Math.atan2(Math.sqrt(b),Math.sqrt(1-b)))/1852}ngOnDestroy(){this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.rotationFrameTimer!==null&&(window.clearTimeout(this.rotationFrameTimer),this.rotationFrameTimer=null),this.iconRenderTimer!==null&&(window.clearTimeout(this.iconRenderTimer),this.iconRenderTimer=null);}static \u0275fac=function(t){return new(t||l)};static \u0275cmp=JD({type:l,selectors:[["widget-ais-radar"]],viewQuery:function(t,i){t&1&&eg(i.svgRef,lt,5)(i.menuAnchorRef,ct,5)(i.menuTrigger,dt,5),t&2&&Kw(3);},inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"]},decls:29,vars:9,consts:[["radarSvg",""],["menuAnchor","","menuTrigger","matMenuTrigger"],["targetMenu","matMenu"],["filterMenu","matMenu"],["vesselTypeMenu","matMenu"],["kipResizeObserver","",1,"ais-radar-container",3,"kipResize"],["type","button","matMiniFab","",1,"ais-radar-mode-toggle-button",3,"click","matTooltip"],["viewBox","0 0 40 40","aria-hidden","true",1,"ais-mode-icon"],["type","button","matMiniFab","","matTooltip","Increase range","aria-label","Increase range",1,"ais-radar-range-button","ais-radar-range-plus",3,"click"],["type","button","matMiniFab","","matTooltip","Decrease range","aria-label","Decrease range",1,"ais-radar-range-button","ais-radar-range-minus",3,"click"],["type","button","matMiniFab","","matTooltip","Filter targets","aria-label","Filter targets",1,"ais-radar-range-button","ais-radar-filter-button",3,"matMenuTriggerFor"],["type","button","matMiniFab","","matTooltip","Show only collision risk targets","aria-label","No collision risk filter",1,"ais-radar-range-button","ais-radar-collision-button",3,"is-active"],["role","img","aria-label","AIS radar display",1,"ais-radar"],["type","button","aria-hidden","true","tabindex","-1",1,"ais-radar-menu-anchor",3,"matMenuTriggerFor"],[3,"closed"],["matMenuContent",""],[1,"widgetOverlay"],["stroke","currentColor","d","M10 8 L20 2 L30 8",1,"ais-mode-icon-chev"],["fill","currentColor","x","20","y","31",1,"ais-mode-icon-letter"],["fill","currentColor","d","M20 4 L34 36 L20 28 L6 36 Z",1,"ais-mode-icon-vessel"],["type","button","matMiniFab","","matTooltip","Show only collision risk targets","aria-label","No collision risk filter",1,"ais-radar-range-button","ais-radar-collision-button",3,"click"],["mat-menu-item","","type","button",1,"ais-radar-menu-item"],["mat-menu-item","","type","button",1,"ais-radar-menu-item",3,"click"],["alt","","aria-hidden","true",1,"target-menu-icon"],[1,"target-menu-label"],["mat-menu-item","","disabled","",1,"ais-filter-menu-header"],["mat-menu-item","","type","button",3,"click"],["aria-hidden","true",1,"ais-filter-check"],["mat-menu-item","",3,"matMenuTriggerFor"],["mat-menu-item","","type","button"]],template:function(t,i){if(t&1&&(Pi(0,"div",5),Qh("kipResize",function(r){return i.onResized(r)}),Pi(1,"button",6),Qh("click",function(){return i.toggleViewMode()}),_w(2,ut,4,0,":svg:svg",7)(3,mt,2,0,":svg:svg",7),ul(),Pi(4,"button",8),Qh("click",function(){return i.incrementRange()}),Pi(5,"mat-icon"),TT(6,"add"),ul()(),Pi(7,"button",9),Qh("click",function(){return i.decrementRange()}),Pi(8,"mat-icon"),TT(9,"remove"),ul()(),Pi(10,"button",10)(11,"mat-icon"),TT(12,"filter_list"),ul()(),_w(13,gt,3,2,"button",11),wd(),$h(14,"svg",12,0),Td(),$h(16,"button",13,1),ul(),Pi(19,"mat-menu",14,2),Qh("closed",function(){return i.resetTargetMenuState()}),xh(21,ft,2,0,"ng-template",15),ul(),Pi(22,"mat-menu",null,3),xh(24,St,27,5,"ng-template",15),ul(),Pi(25,"mat-menu",null,4),xh(27,bt,2,0,"ng-template",15),ul(),_w(28,yt,1,0,"div",16)),t&2){let s=Jw(20),r=Jw(23);EE(),Bh("matTooltip",i.effectiveViewMode()==="north-up"?"Change to North-Up mode":"Change to Course-Up mode"),Hh("aria-label",i.effectiveViewMode()==="north-up"?"North up mode":"Course up mode"),EE(),Mw(i.effectiveViewMode()==="north-up"?2:3),EE(8),sg("is-active",i.hasActiveFilters()),Bh("matMenuTriggerFor",r),EE(3),Mw(i.hasCollisionRiskData()?13:-1),EE(3),Bh("matMenuTriggerFor",s),EE(12),Mw(i.dashboard.isDashboardStatic()?-1:28);}},dependencies:[u,Op,Rp,yt$1,wt,Ht,R,ee,Nt,Lt,zt,mt$1],encapsulation:2})}return l})();export{Qt as WidgetAisRadarComponent};
1
+ import {g as ge$1}from'./chunk-TakPRI3t.js';import {d1 as Hj,w,du as p,C as Ff,ao as ue,bu as ut$1,G as Gi,aR as lt$1,a as G,$ as $j,v as vt$1,D as Dt,dG as rn,F as Fa,dn as ge,dH as ac,cw as z,cv as G$1,dI as cn,dJ as nc,dK as qn,dL as zn,dM as pa,J as JD,O as Op,R as Rp,y as yt$1,b as wt,cG as Ht,cH as R,cI as ee,cJ as Nt,cK as Lt,cR as zt,bg as mt$1,P as Pi,k as Qh,_ as _w,u as ul,T as TT,cn as wd,c as $h,cV as Td,cf as xh,bl as Jw,e as EE,B as Bh,an as Hh,M as Mw,s as sg,f as eg,K as Kw,aS as De,aY as xe,ab as te,aj as zm,a_ as Gp,cO as eu,aI as ms,dN as Q,h as Fw,g as qw,X as xw,Y as Aw,bp as gl,dj as Nw,d as ig,aA as gg,l as ud,m as dd,dO as fp}from'./main-YKDNK5VZ.js';import {u}from'./chunk-CCfhzpE8.js';import {c}from'./chunk-BIb-xYiS.js';var K=false,Je=250,it=600*1e3,st=500,nt=15e3,rt=["atons.urn:mrn:imo:mmsi:*","shore.basestations.urn:mrn:imo:mmsi:*","vessels.urn:mrn:imo:mmsi:*","sar.urn:mrn:imo:mmsi:*"],ot=[{prefix:"atons.urn:mrn:imo:mmsi:",type:"aton"},{prefix:"shore.basestations.urn:mrn:imo:mmsi:",type:"basestation"},{prefix:"vessels.urn:mrn:imo:mmsi:",type:"vessel"},{prefix:"sar.urn:mrn:imo:mmsi:",type:"sar"}],at="self.navigation.*",et=(()=>{class l{data=w(De);destroyRef=w(xe);tracks=new Map;contextIndex=new Map;mmsiIndex=new Map;maxTargets=st;targetTtlMs=it;targetsDirty$=new te;ownShipDirty$=new te;pendingOwnShip={};_targets=vt$1([]);_ownShip=vt$1({});_hasCollisionRiskData=vt$1(false);targets=this._targets.asReadonly();ownShip=this._ownShip.asReadonly();hasCollisionRiskData=this._hasCollisionRiskData.asReadonly();getBearingTrue(e,t){if(typeof e.latitude!="number"||typeof e.longitude!="number"||typeof t.latitude!="number"||typeof t.longitude!="number")return null;let i=e.latitude*Math.PI/180,s=t.latitude*Math.PI/180,r=(t.longitude-e.longitude)*Math.PI/180,o=Math.sin(r)*Math.cos(s),n=Math.cos(i)*Math.sin(s)-Math.sin(i)*Math.cos(s)*Math.cos(r),d=Math.atan2(o,n)*180/Math.PI;return this.wrapDegrees(d)}constructor(){zm(...rt.map(t=>this.data.subscribePathTree(t))).pipe(Gp(this.destroyRef)).subscribe(t=>this.handleAisTreeUpdate(t)),this.data.subscribePathTree(at).pipe(Gp(this.destroyRef)).subscribe(t=>this.handleOwnShipTreeUpdate(t)),this.targetsDirty$.pipe(eu(Je,void 0,{leading:true,trailing:true}),Gp(this.destroyRef)).subscribe(()=>this.flushTargetsSignal()),ms(nt).pipe(Gp(this.destroyRef)).subscribe(()=>this.evictStaleTracks(Date.now())),this.ownShipDirty$.pipe(eu(Je,void 0,{leading:true,trailing:true}),Gp(this.destroyRef)).subscribe(()=>this.flushOwnShip());}handleAisTreeUpdate(e){let t=this.matchAisContext(e.path);t&&(this.applyAisUpdate({context:t.context,type:t.type,path:t.path,value:e.update.data.value,timestampMs:this.toTimestampMs(e.update.data.timestamp)}));}handleOwnShipTreeUpdate(e){if(!e.path.startsWith("self."))return;let t=e.path.slice(5);this.applyOwnShipUpdate(t,e.update.data.value);}matchAisContext(e){for(let t of ot){if(!e.startsWith(t.prefix))continue;let i=e.indexOf(".",t.prefix.length);return i===-1?null:{context:e.slice(0,i),path:e.slice(i+1),type:t.type}}return null}applyOwnShipUpdate(e,t){let i=G$1({},this.pendingOwnShip),s=this.readPositionValue(t);switch(e){case "navigation.position":s&&(i.position=s);break;case "navigation.position.latitude":{let r=this.toNumberOrUndefined(t);if(r===void 0)return;i.position=z(G$1({},i.position??{}),{latitude:r});}break;case "navigation.position.longitude":{let r=this.toNumberOrUndefined(t);if(r===void 0)return;i.position=z(G$1({},i.position??{}),{longitude:r});}break;case "navigation.headingTrue":i.headingTrue=this.toNumberOrUndefined(t);break;case "navigation.courseOverGroundTrue":i.courseOverGroundTrue=this.toNumberOrUndefined(t);break;case "navigation.speedOverGround":i.speedOverGround=this.toNumberOrUndefined(t);break;default:return}this.pendingOwnShip=i,this.ownShipDirty$.next();}flushOwnShip(){this.ownShipChanged(this._ownShip(),this.pendingOwnShip)&&this._ownShip.set(this.pendingOwnShip);}ownShipChanged(e,t){return e.headingTrue!==t.headingTrue||e.courseOverGroundTrue!==t.courseOverGroundTrue||e.speedOverGround!==t.speedOverGround||e.position?.latitude!==t.position?.latitude||e.position?.longitude!==t.position?.longitude}applyAisUpdate(e){let t=this.resolveTrack(e);if(t){switch(t.lastUpdateAt=e.timestampMs,e.path.startsWith("navigation.closestApproach.")&&this.isVesselLike(t)&&!t.closestApproach&&(t.closestApproach={}),e.path){case "mmsi":this.applyMmsi(t,e.value);break;case "name":t.name=this.toStringOrUndefined(e.value);break;case "communication.callsignVhf":this.isVesselLike(t)&&(t.callsign=this.toStringOrUndefined(e.value));break;case "navigation.destination":case "navigation.destination.commonName":this.isVesselLike(t)&&(t.destination=this.toStringOrUndefined(e.value));break;case "navigation.destination.eta":this.isVesselLike(t)&&(t.eta=this.toStringOrUndefined(e.value));break;case "design.beam":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{beam:this.toNumberOrUndefined(e.value)}));break;case "design.length.overall":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{length:z(G$1({},t.design?.length??{}),{overall:this.toNumberOrUndefined(e.value)})}));break;case "design.length.hull":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{length:z(G$1({},t.design?.length??{}),{hull:this.toNumberOrUndefined(e.value)})}));break;case "design.length.waterline":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{length:z(G$1({},t.design?.length??{}),{waterline:this.toNumberOrUndefined(e.value)})}));break;case "design.draft.maximum":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{draft:z(G$1({},t.design?.draft??{}),{maximum:this.toNumberOrUndefined(e.value)})}));break;case "design.draft.minimum":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{draft:z(G$1({},t.design?.draft??{}),{minimum:this.toNumberOrUndefined(e.value)})}));break;case "design.draft.current":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{draft:z(G$1({},t.design?.draft??{}),{current:this.toNumberOrUndefined(e.value)})}));break;case "design.draft.canoe":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{draft:z(G$1({},t.design?.draft??{}),{canoe:this.toNumberOrUndefined(e.value)})}));break;case "registrations.imo":this.isVesselLike(t)&&(t.imo=this.toStringOrUndefined(e.value));break;case "navigation.courseOverGroundTrue":this.isVesselLike(t)&&(t.courseOverGroundTrue=this.toNumberOrUndefined(e.value));break;case "navigation.headingTrue":this.isVesselLike(t)&&(t.headingTrue=this.toNumberOrUndefined(e.value));break;case "navigation.rateOfTurn":this.isVesselLike(t)&&(t.rateOfTurn=this.toNumberOrUndefined(e.value));break;case "navigation.specialManeuver":this.isVesselLike(t)&&(t.specialManeuver=this.toStringOrUndefined(e.value));break;case "navigation.speedOverGround":this.isVesselLike(t)&&(t.speedOverGround=this.toNumberOrUndefined(e.value));break;case "navigation.state":this.isVesselLike(t)&&(t.navState=this.toStringOrUndefined(e.value));break;case "sensors.ais.class":t.ais.class=this.normalizeAisClass(e.value);break;case "sensors.ais.status":{let i=this.normalizeAisStatus(e.value);if(!i)break;if(i==="remove"){this.removeTrack(t);return}t.ais.status=i;}break;case "sensors.ais.fromBow":this.isVesselLike(t)&&(t.fromBow=this.toNumberOrUndefined(e.value));break;case "sensors.ais.fromCenter":this.isVesselLike(t)&&(t.fromCenter=this.toNumberOrUndefined(e.value));break;case "navigation.position.latitude":{let i=this.toNumberOrUndefined(e.value);if(i===void 0)break;t.position=z(G$1({},t.position??{}),{latitude:i}),t.lastPositionAt=e.timestampMs;}break;case "navigation.position.longitude":{let i=this.toNumberOrUndefined(e.value);if(i===void 0)break;t.position=z(G$1({},t.position??{}),{longitude:i}),t.lastPositionAt=e.timestampMs;}break;case "navigation.position.altitude":{let i=this.toNumberOrUndefined(e.value);t.position&&(t.position=z(G$1({},t.position),{altitude:i}));}break;case "navigation.position":{let i=this.readPositionValue(e.value);i&&(t.position=i,t.lastPositionAt=e.timestampMs);}break;case "atonType.id":this.isAton(t)&&(t.typeId=this.toNumberOrUndefined(e.value));break;case "atonType.name":this.isAton(t)&&(t.typeName=this.toStringOrUndefined(e.value));break;case "virtual":this.isAton(t)&&(t.virtual=!!e.value);break;case "offPosition":this.isAton(t)&&(t.offPosition=!!e.value);break;case "design.aisShipType.id":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{aisShipType:z(G$1({},t.design?.aisShipType??{}),{id:this.toNumberOrUndefined(e.value)})}));break;case "design.aisShipType.name":this.isVesselLike(t)&&(t.design=z(G$1({},t.design??{}),{aisShipType:z(G$1({},t.design?.aisShipType??{}),{name:this.toStringOrUndefined(e.value)})}));break;case "navigation.closestApproach.distance":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.distance=this.toNumberOrUndefined(e.value));break;case "navigation.closestApproach.timeTo":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.timeTo=this.toNumberOrUndefined(e.value));break;case "navigation.closestApproach.range":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.range=this.toNumberOrUndefined(e.value));break;case "navigation.closestApproach.bearing":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.bearing=this.toNumberOrUndefined(e.value));break;case "navigation.closestApproach.collisionRiskRating":this.isVesselLike(t)&&t.closestApproach&&(t.closestApproach.collisionRiskRating=this.toNumberOrUndefined(e.value));break}this.updateTargetsSignal();}}resolveTrack(e){let t=this.contextIndex.get(e.context),i=e.timestampMs,s=t?this.tracks.get(t):null;if(s)return s;let r=this.createTrack(e.context,e.type,i,void 0);return this.contextIndex.set(e.context,r.id),r}createTrack(e,t,i,s){let r=this.buildTrackId(s??e),o=this.buildBaseTarget(e,t,i,s,r),n;switch(t){case "vessel":n=z(G$1({},o),{type:"vessel",closestApproach:{}});break;case "sar":n=z(G$1({},o),{type:"sar",closestApproach:{}});break;case "aton":n=z(G$1({},o),{type:"aton"});break;default:n=z(G$1({},o),{type:"basestation"});break}return this.tracks.set(n.id,n),s&&this.addMmsiIndex(s,n.id),this.enforceTargetCap(),this.updateTargetsSignal(),n}buildTrackId(e){if(!this.tracks.has(e))return e;let t=1;for(;this.tracks.has(`${e}-${t}`);)t+=1;return `${e}-${t}`}applyMmsi(e,t){let i=this.toStringOrUndefined(t);if(!i)return;let s=this.getTracksByMmsi(i).filter(r=>r.id!==e.id);s.length&&(this.markConflict(i),K),e.mmsi&&e.mmsi!==i&&this.removeMmsiIndex(e.mmsi,e.id),e.mmsi=i,this.addMmsiIndex(i,e.id);}removeTrack(e){this.tracks.delete(e.id),e.mmsi&&this.removeMmsiIndex(e.mmsi,e.id);for(let[t,i]of this.contextIndex.entries())i===e.id&&this.contextIndex.delete(t);this.updateTargetsSignal();}updateTargetsSignal(){this.targetsDirty$.next();}enforceTargetCap(){for(;this.tracks.size>this.maxTargets;){let e=null;for(let t of this.tracks.values())(!e||t.lastUpdateAt<e.lastUpdateAt)&&(e=t);if(!e)break;this.removeTrack(e);}}evictStaleTracks(e){let t=e-this.targetTtlMs,i=[];for(let s of this.tracks.values())s.lastUpdateAt<t&&i.push(s);for(let s of i)this.removeTrack(s);this.enforceTargetCap();}flushTargetsSignal(){let e=Array.from(this.tracks.values()).filter(i=>!!i.mmsi||!!i.position),t=e.some(i=>{if(!this.isVesselLike(i))return false;let s=i.closestApproach??{};return Object.prototype.hasOwnProperty.call(s,"collisionRiskRating")});this._targets.set(e),this._hasCollisionRiskData.set(t);}getTracksByMmsi(e){let t=this.mmsiIndex.get(e);return t?Array.from(t).map(i=>this.tracks.get(i)).filter(i=>!!i):[]}addMmsiIndex(e,t){this.mmsiIndex.has(e)||this.mmsiIndex.set(e,new Set),this.mmsiIndex.get(e).add(t);}removeMmsiIndex(e,t){let i=this.mmsiIndex.get(e);i&&(i.delete(t),i.size||this.mmsiIndex.delete(e));}markConflict(e){let t=this.getTracksByMmsi(e);for(let i of t)i.conflicted=true;}normalizeAisClass(e){let t=typeof e=="string"?e.toUpperCase():"";if(t==="A")return "A";if(t==="B")return "B"}normalizeAisStatus(e){if(e==null)return;let t=String(e).toLowerCase();if(t==="unconfirmed"||t==="confirmed"||t==="lost"||t==="remove")return t}toTimestampMs(e){if(!e)return Date.now();let t=e instanceof Date?e.getTime():Date.parse(e);return Number.isFinite(t)?t:Date.now()}toNumberOrUndefined(e){let t=Number(e);return Number.isFinite(t)?t:void 0}toStringOrUndefined(e){if(e==null)return;let t=String(e).trim();return t.length?t:void 0}wrapDegrees(e){let t=e%360;return t<0?t+360:t}buildBaseTarget(e,t,i,s,r){return {id:r,context:e,type:t,ais:{class:void 0,status:"unconfirmed"},conflicted:false,mmsi:s,position:void 0,lastUpdateAt:i,lastPositionAt:void 0}}isVesselLike(e){return e.type==="vessel"||e.type==="sar"}isAton(e){return e.type==="aton"}readPositionValue(e){if(!e||typeof e!="object")return;let t=this.toNumberOrUndefined(e.latitude),i=this.toNumberOrUndefined(e.longitude);if(t===void 0||i===void 0)return;let s=this.toNumberOrUndefined(e.altitude);return {latitude:t,longitude:i,altitude:s}}static \u0275fac=function(t){return new(t||l)};static \u0275prov=Q({token:l,factory:l.\u0275fac,providedIn:"root"})}return l})();var lt=["radarSvg"],ct=["menuAnchor"],dt=["menuTrigger"],ht=(l,I)=>I.id;function ut(l,I){l&1&&(wd(),Pi(0,"svg",7),$h(1,"path",17),Pi(2,"text",18),TT(3,"N"),ul()());}function mt(l,I){l&1&&(wd(),Pi(0,"svg",7),$h(1,"path",19),ul());}function gt(l,I){if(l&1){let e=Fw();Pi(0,"button",20),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("noCollisionRisk"))}),Pi(1,"mat-icon"),TT(2,"security"),ul()();}if(l&2){let e=qw();sg("is-active",e.isFilterEnabled("noCollisionRisk"));}}function pt(l,I){if(l&1){let e=Fw();Pi(0,"button",22),Qh("click",function(){let i=ud(e).$implicit,s=qw(2);return dd(s.onMenuItemSelect(i))}),$h(1,"img",23),Pi(2,"span",24),TT(3),ul()();}if(l&2){let e=I.$implicit;EE(),ig("visibility",e.iconHref?"visible":"hidden"),Hh("src",e.iconHref??null,fp),EE(2),gg(e.label);}}function ft(l,I){if(l&1&&xw(0,pt,4,4,"button",21,ht),l&2){let e=qw();Aw(e.menuItems());}}function St(l,I){if(l&1){let e=Fw();Pi(0,"button",25),TT(1,"Filter Targets"),ul(),Pi(2,"button",26),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("anchoredMoored"))}),Pi(3,"mat-icon",27),TT(4),ul(),Pi(5,"span"),TT(6,"Anchored/Moored"),ul()(),Pi(7,"button",26),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("allAton"))}),Pi(8,"mat-icon",27),TT(9),ul(),Pi(10,"span"),TT(11,"All AtoN"),ul()(),Pi(12,"button",26),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("allButSar"))}),Pi(13,"mat-icon",27),TT(14),ul(),Pi(15,"span"),TT(16,"All but SAR"),ul()(),Pi(17,"button",26),Qh("click",function(){ud(e);let i=qw();return dd(i.toggleFilter("allVessels"))}),Pi(18,"mat-icon",27),TT(19),ul(),Pi(20,"span"),TT(21,"All Vessels"),ul()(),Pi(22,"button",28)(23,"span"),TT(24,"Vessel Type"),ul(),Pi(25,"mat-icon"),TT(26,"chevron_right"),ul()();}if(l&2){let e=qw(),t=Jw(26);EE(4),gl(" ",e.isFilterEnabled("anchoredMoored")?"check_box":"check_box_outline_blank"," "),EE(5),gl(" ",e.isFilterEnabled("allAton")?"check_box":"check_box_outline_blank"," "),EE(5),gl(" ",e.isFilterEnabled("allButSar")?"check_box":"check_box_outline_blank"," "),EE(5),gl(" ",e.isFilterEnabled("allVessels")?"check_box":"check_box_outline_blank"," "),EE(3),Bh("matMenuTriggerFor",t);}}function vt(l,I){if(l&1){let e=Fw();Pi(0,"button",26),Qh("click",function(){let i=ud(e).$implicit,s=qw(2);return dd(s.toggleVesselTypeFilter(i))}),Pi(1,"mat-icon",27),TT(2),ul(),Pi(3,"span"),TT(4),ul()();}if(l&2){let e=I.$implicit,t=qw(2);EE(2),gl(" ",t.isVesselTypeFilterEnabled(e)?"check_box":"check_box_outline_blank"," "),EE(2),gg(t.formatVesselTypeLabel(e));}}function bt(l,I){if(l&1&&xw(0,vt,5,2,"button",29,Nw),l&2){let e=qw();Aw(e.vesselTypeFilters);}}function yt(l,I){l&1&&$h(0,"div",16);}var Qt=(()=>{class l{static TARGET_ICON_SIZE_PX=16;static OWN_SHIP_ICON_SIZE_PX=84;static HIT_RADIUS_PX=28;static ICON_RENDER_DEBOUNCE_MS=50;static ROTATION_SETTLE_DEADBAND_DEG=1;static ROTATION_ONLY_FRAME_MS=33;id=Hj.required();type=Hj.required();theme=Hj.required();runtime=w(p);ais=w(et);dialog=w(Ff);ngZone=w(ue);units=w(ut$1);settings=w(Gi);toast=w(lt$1);dashboard=w(G);static DEFAULT_CONFIG={filterSelfPaths:false,enableTimeout:false,dataTimeout:5,ais:{filters:{anchoredMoored:false,noCollisionRisk:false,allAton:false,allButSar:false,allVessels:false,vesselTypes:[]},viewMode:"course-up",rangeRings:[1,3,6,12,24,48],rangeIndex:"3",showCogVectors:true,cogVectorsMinutes:10,showLostTargets:true,showUnconfirmedTargets:true,showSelf:true},color:"grey"};svgRef=$j.required("radarSvg");menuAnchorRef=$j.required("menuAnchor");menuTrigger=$j.required("menuTrigger");hostSize=vt$1(null);renderState=null;selectedId=vt$1(null);localViewMode=vt$1(null);localRangeIndex=vt$1(null);effectiveViewMode=Dt(()=>this.localViewMode()??this.runtime.options()?.ais?.viewMode??"course-up");effectiveRangeIndex=Dt(()=>{let e=this.resolveRangeIndex(this.runtime.options()?.ais),t=this.runtime.options()?.ais?.rangeRings??[3,6,12,24,48],i=Math.max(0,t.length-1),s=this.localRangeIndex()??e;return Math.min(Math.max(s,0),i)});svg;root;ringsLayer;rotationGroup;vectorsLayer;targetsLayer;selectedLayer;ownShipLayer;viewRotationSmoothed=null;lastRotationAt=null;lastViewRotation=0;hasRenderedOnce=false;renderFrame=null;rotationFrameTimer=null;iconRenderTimer=null;iconCache=new Map;targetCache=new Map;lastOriginKey=null;ringCache=null;ownShipIconHref=null;menuItems=vt$1([]);menuPoint=null;lastRenderTargets=[];lastRenderScale=1;lastRenderSize=null;hitRadiusPx=l.HIT_RADIUS_PX;lastFiltersSignature=null;lastRenderSignature=null;ownShipVectorCache=null;filterState=vt$1({anchoredMoored:false,noCollisionRisk:false,allAton:false,allButSar:false,allVessels:false,vesselTypes:new Set});vesselTypeFilters=rn.filter(e=>e!=="vessel/self"&&e!=="vessel/unknown"&&e!=="vessel/spare");hasActiveFilters=Dt(()=>{let e=this.filterState();return e.anchoredMoored||e.allAton||e.allButSar||e.allVessels||e.vesselTypes.size>0});hasCollisionRiskData=this.ais.hasCollisionRiskData;constructor(){this.warnIfRemoteDataDisabled(),this.loadOwnShipIcon(),Fa(()=>{let e=this.hostSize(),t=this.runtime.options(),i=this.theme(),s=this.ais.targets(),r=this.ais.ownShip();!e||!t||!i||(ge(()=>{this.renderState={size:e,cfg:t,theme:i,targets:s,ownShip:r},this.syncFiltersFromConfig(t);}),this.scheduleRender());}),Fa(()=>{this.localViewMode(),this.localRangeIndex(),this.selectedId(),this.filterState(),ge(()=>{this.scheduleRender();});});}warnIfRemoteDataDisabled(){this.settings.signalKSubscribeAll||this.toast.show('AIS data is disabled in your connection. To see radar targets, go to Settings -> Options -> Connectivity, enable "Subscribe to remote sources messages", then reconnect.',0,false,"warn");}loadOwnShipIcon(){this.ngZone.runOutsideAngular(()=>{ac().then(e=>{this.ownShipIconHref=e,this.scheduleRenderDebounced();});});}ngAfterViewInit(){this.initSvg(),this.scheduleRender();}onResized(e){this.hostSize.set({width:e.width,height:e.height});}initSvg(){this.svg=ge$1(this.svgRef().nativeElement),this.svg.attr("class","ais-radar"),this.root=this.svg.append("g").attr("class","radar-root"),this.ringsLayer=this.root.append("g").attr("class","radar-rings"),this.rotationGroup=this.root.append("g").attr("class","radar-rotation"),this.vectorsLayer=this.rotationGroup.append("g").attr("class","radar-vectors"),this.targetsLayer=this.rotationGroup.append("g").attr("class","radar-targets"),this.selectedLayer=this.rotationGroup.append("g").attr("class","radar-selected"),this.ownShipLayer=this.root.append("g").attr("class","radar-ownship-layer"),this.svg.on("click",()=>{this.selectedId.set(null),this.closeTargetMenu();});}scheduleRender(){this.renderFrame===null&&this.ngZone.runOutsideAngular(()=>{this.renderFrame=requestAnimationFrame(()=>{this.renderFrame=null,this.render();});});}scheduleRenderDebounced(){this.iconRenderTimer===null&&this.ngZone.runOutsideAngular(()=>{this.iconRenderTimer=window.setTimeout(()=>{this.iconRenderTimer=null,this.scheduleRender();},l.ICON_RENDER_DEBOUNCE_MS);});}scheduleRotationOnlyRender(){this.rotationFrameTimer!==null||this.renderFrame!==null||this.ngZone.runOutsideAngular(()=>{this.rotationFrameTimer=window.setTimeout(()=>{this.rotationFrameTimer=null,this.scheduleRender();},l.ROTATION_ONLY_FRAME_MS);});}render(){if(!this.renderState||!this.svg||!this.root||!this.rotationGroup)return;let{size:e,cfg:t,theme:i,targets:s,ownShip:r}=this.renderState,o=Math.max(1,e.width),n=Math.max(1,e.height),d=Math.min(o,n)/2,u=(Math.min(o,n)-35)/Math.min(o,n),b=Math.hypot(o,n)/2/u,c$1=t.ais??{},T=c$1.rangeRings?.length?c$1.rangeRings:[3,6,12,24,48],x=this.effectiveRangeIndex(),a=T[x]??T[0],M=this.resolveRingCountForRange(a),S=this.localViewMode()??c$1.viewMode??"course-up",_=this.toDegreesIfRadians(r.courseOverGroundTrue),C=this.toDegreesIfRadians(r.headingTrue),V=_!==null||C!==null,m=S==="course-up"?_??C??0:0,B=this.viewRotationSmoothed!==null&&Math.abs(this.shortestAngleDelta(this.viewRotationSmoothed,m))<=l.ROTATION_SETTLE_DEADBAND_DEG,$=this.buildFilterStateSignature(this.filterState()),U=r.position?`${r.position.latitude},${r.position.longitude}`:"none",F={sizeKey:`${o}x${n}`,viewMode:S,rangeIndex:x,rangesKey:T.join(","),showSelf:c$1.showSelf??true,showCogVectors:c$1.showCogVectors??true,showLostTargets:c$1.showLostTargets??true,showUnconfirmedTargets:c$1.showUnconfirmedTargets??true,filtersKey:$,selectedId:this.selectedId(),targetsRef:s,ownPosKey:U,themeRef:i,color:t.color},L=!this.lastRenderSignature||!this.signaturesEqual(this.lastRenderSignature,F);if(!L&&B&&this.hasRenderedOnce)return;this.lastRenderSignature=F;let v=S==="course-up"&&V?this.smoothRotation(m):0,te=S==="course-up"?Math.abs(this.shortestAngleDelta(v,m)):0;this.lastViewRotation=v,this.svg.attr("viewBox",`${-o/2} ${-n/2} ${o} ${n}`),this.root.attr("transform",`scale(${u})`),this.rotationGroup.attr("transform",`rotate(${this.wrapDegrees(-v)})`);let me=this.wrapDegrees((_??C??0)-v);if(L){let ie=c(t.color??"contrast",i).dim;this.renderRings(M,a,d,b,v,u,c$1.showSelf??true,me,ie);}if(this.ownShipLayer?.select("g.radar-ownship").attr("transform",`rotate(${me})`),r.position&&this.hasValidPosition(r.position)&&(this.renderOwnShipVector(r,a,d,v,c$1),L)){let ie=b/d*a,W=this.buildTargets(s,r.position,a,ie,d,0,c$1);this.lastRenderTargets=W,this.lastRenderScale=u,this.lastRenderSize=e,this.renderTargetVectors(W,a,d,0,c$1),this.renderTargets(W,u),this.renderSelected(W,u);}this.raiseOwnshipAndVector(),this.hasRenderedOnce=true,te>l.ROTATION_SETTLE_DEADBAND_DEG&&(L?this.scheduleRender():this.scheduleRotationOnlyRender());}signaturesEqual(e,t){return e.sizeKey===t.sizeKey&&e.viewMode===t.viewMode&&e.rangeIndex===t.rangeIndex&&e.rangesKey===t.rangesKey&&e.showSelf===t.showSelf&&e.showCogVectors===t.showCogVectors&&e.showLostTargets===t.showLostTargets&&e.showUnconfirmedTargets===t.showUnconfirmedTargets&&e.filtersKey===t.filtersKey&&e.selectedId===t.selectedId&&e.targetsRef===t.targetsRef&&e.ownPosKey===t.ownPosKey&&e.themeRef===t.themeRef&&e.color===t.color}renderRings(e,t,i,s,r,o,n,d,u){if(!this.ringsLayer)return;let b=`${t.toFixed(3)}|${i.toFixed(3)}|${s.toFixed(3)}|${e}`;if(!this.ringCache||this.ringCache.key!==b){let m=t/Math.max(1,e),B=s/i*t,$=[];for(let v=m;v<=B+1e-6;v+=m)$.push(v);let U=$.map(v=>({value:v,radius:v/t*i})).filter(v=>v.radius<=s+1e-6),F=20,L=U.flatMap(v=>[{key:`${v.value}-top`,value:v.value,x:0,y:-v.radius+F},{key:`${v.value}-bottom`,value:v.value,x:0,y:v.radius-F}]);this.ringCache={key:b,rings:U,labels:L};}let c=this.ringCache;if(!c)return;let T=c.rings,x=this.ringsLayer.selectAll("circle.ring").data(T,m=>m.value.toString());x.enter().append("circle").attr("class","ring").merge(x).attr("r",m=>m.radius).attr("stroke",u),x.exit().remove();let a=c.labels,M=this.ringsLayer.selectAll("text.ring-label").data(a,m=>m.key);M.enter().append("text").attr("class","ring-label").merge(M).attr("x",m=>m.x).attr("y",m=>m.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(m=>`${m.value}`),M.exit().remove();let S=this.ringsLayer.selectAll("circle.radar-center").data(n?[]:[{r:Math.max(3,i*.01)}]);S.enter().append("circle").attr("class","radar-center").merge(S).attr("cx",0).attr("cy",0).attr("r",m=>m.r).attr("fill",u),S.exit().remove();let _=this.ownShipLayer.selectAll("g.radar-ownship").data(n?[{size:this.resolveOwnShipBaseSize(o)}]:[]),C=_.enter().append("g").attr("class","radar-ownship");C.append("image").attr("class","ownship-icon").attr("href",this.ownShipIconHref??null).attr("xlink:href",this.ownShipIconHref??null);let V=C.merge(_);V.attr("transform",`rotate(${d})`),V.select("image.ownship-icon").attr("href",this.ownShipIconHref??null).attr("xlink:href",this.ownShipIconHref??null).attr("display",this.ownShipIconHref?null:"none").attr("width",m=>m.size).attr("height",m=>m.size).attr("x",m=>-m.size/2).attr("y",m=>-m.size/2),_.exit().remove();}toggleViewMode(){let e=this.localViewMode()??this.runtime.options()?.ais?.viewMode??"course-up";this.localViewMode.set(e==="course-up"?"north-up":"course-up");}incrementRange(){this.localRangeIndex.set(Math.max(this.effectiveRangeIndex()-1,0));}decrementRange(){let e=this.runtime.options()?.ais?.rangeRings??[3,6,12,24,48],t=Math.max(0,e.length-1);this.localRangeIndex.set(Math.min(this.effectiveRangeIndex()+1,t));}toggleFilter(e){this.filterState.update(t=>z(G$1({},t),{[e]:!t[e]}));}toggleVesselTypeFilter(e){this.filterState.update(t=>{let i=new Set(t.vesselTypes);return i.has(e)?i.delete(e):i.add(e),z(G$1({},t),{vesselTypes:i})});}isFilterEnabled(e){return this.filterState()[e]}isVesselTypeFilterEnabled(e){return this.filterState().vesselTypes.has(e)}formatVesselTypeLabel(e){let t=e.replace("vessel/","");switch(t){case "pleasurecraft":return "Pleasure Craft";case "highspeed":return "High Speed";case "sar":return "SAR";case "law":return "Law Enforcement";default:return `${t.charAt(0).toUpperCase()}${t.slice(1)}`}}syncFiltersFromConfig(e){let t=e.ais?.filters;if(!t)return;let i=this.buildFilterSignature(t);i!==this.lastFiltersSignature&&(this.lastFiltersSignature=i,this.filterState.set({anchoredMoored:t.anchoredMoored??false,noCollisionRisk:t.noCollisionRisk??false,allAton:t.allAton??false,allButSar:t.allButSar??false,allVessels:t.allVessels??false,vesselTypes:new Set(t.vesselTypes??[])}));}buildFilterSignature(e){let t=[...e?.vesselTypes??[]].sort();return JSON.stringify({anchoredMoored:e?.anchoredMoored??false,noCollisionRisk:e?.noCollisionRisk??false,allAton:e?.allAton??false,allButSar:e?.allButSar??false,allVessels:e?.allVessels??false,vesselTypes:t})}buildFilterStateSignature(e){let t=[...e.vesselTypes].sort();return JSON.stringify({anchoredMoored:e.anchoredMoored,noCollisionRisk:e.noCollisionRisk,allAton:e.allAton,allButSar:e.allButSar,allVessels:e.allVessels,vesselTypes:t})}resolveRingCountForRange(e){return [3].find(i=>this.isNiceStep(e/i))??4}isNiceStep(e){return [.5,1,2,2.5,3,4,5,6,8,10,12,15,20,25].some(i=>Math.abs(e-i)<1e-6)}resolveRangeIndex(e){return e?Number(e.rangeIndex):0}buildTargets(e,t,i,s,r,o,n){let d=n.showLostTargets??true,u=n.showUnconfirmedTargets??true,b=`${t.latitude?.toFixed(6)}|${t.longitude?.toFixed(6)}`;this.lastOriginKey!==b&&(this.targetCache.clear(),this.lastOriginKey=b);let c=new Set;for(let a of e)c.add(a.id);for(let a of this.targetCache.keys())c.has(a)||this.targetCache.delete(a);for(let a of this.iconCache.keys())c.has(a)||this.iconCache.delete(a);let T=[];for(let a of e)a.ais.status==="remove"&&(this.targetCache.delete(a.id),this.iconCache.delete(a.id),this.selectedId()===a.id&&this.selectedId.set(null));let x=e.filter(a=>a.ais.status==="remove"||a.ais.status==="lost"&&!d||a.ais.status==="unconfirmed"&&!u||!a.position||!this.hasValidPosition(a.position)?false:!this.shouldFilterTarget(a));for(let a of x){let M=this.buildTrackSignature(a),S=this.targetCache.get(a.id);if(!S||S.signature!==M){let F=this.distanceNm(t,a.position),L=this.ais.getBearingTrue(t,a.position)??0,v=this.toDegreesIfRadians(this.isVesselLike(a)?a.headingTrue:null),te=this.toDegreesIfRadians(this.isVesselLike(a)?a.courseOverGroundTrue:null);S={signature:M,distanceNm:F,bearing:L,trackHeading:v,trackCog:te},this.targetCache.set(a.id,S);}if(S.distanceNm>s)continue;let{href:_,scale:C}=this.resolveIconCached(a),V=this.wrapDegrees(S.bearing-o),{x:m,y:B}=this.polarToCartesian(V,S.distanceNm,i,r),$=a.type==="aton"||a.type==="basestation"?0:this.wrapDegrees((S.trackHeading??S.trackCog??0)-o),U=this.buildClassName({id:a.id,status:a.ais.status,aisClass:a.ais.class,type:a.type,navState:this.isVesselLike(a)?a.navState:void 0});T.push({id:a.id,raw:a,x:m,y:B,heading:$,status:a.ais.status,aisClass:a.ais.class,type:a.type,iconHref:_,iconScale:C,navState:this.isVesselLike(a)?a.navState:void 0,sog:this.isVesselLike(a)?a.speedOverGround:void 0,cog:S.trackCog??null,className:U});}return T}renderTargetVectors(e,t,i,s,r){if(!this.vectorsLayer)return;let o=r.showCogVectors??true,n=Math.max(6,i*.04),d=(r.cogVectorsMinutes??5)*60,u=n*.8,b=[];for(let c of e)if(this.isVesselLike(c.raw)&&!this.isStationaryNavState(c.raw.navState)&&o&&typeof c.sog=="number"&&typeof c.cog=="number"){let T=this.wrapDegrees(c.cog-s),x=this.offsetPoint(c.x,c.y,T,u),a=c.sog*d/1852,M=Math.max(0,a/t*i-u);if(M<=0)continue;let S=this.offsetPoint(x.x,x.y,T,M),_=this.resolveTargetVectorStroke(c.raw);b.push({id:c.id,x1:x.x,y1:x.y,x2:S.x,y2:S.y,className:c.className,stroke:_});}this.renderVectorLines(this.vectorsLayer,"motion-vector",b);}renderOwnShipVector(e,t,i,s,r){if(!this.ownShipLayer)return;let o=Math.max(6,i*.04),n=(r.cogVectorsMinutes??5)*60,d=o*.8,u=[];if(!(r.showSelf??true)){this.ownShipVectorCache=null,this.renderVectorLines(this.ownShipLayer,"ownship-vector",u);return}let c=this.toDegreesIfRadians(e.courseOverGroundTrue),T=e.speedOverGround;if(c===null||typeof T!="number"){this.ownShipVectorCache=null,this.renderVectorLines(this.ownShipLayer,"ownship-vector",u);return}let x=T*n/1852,a=Math.max(0,x/t*i-d);if(a<=0){this.ownShipVectorCache=null,this.renderVectorLines(this.ownShipLayer,"ownship-vector",u);return}let M=[c.toFixed(6),T.toFixed(6),t.toFixed(6),i.toFixed(6),n,d.toFixed(6)].join("|");if(!this.ownShipVectorCache||this.ownShipVectorCache.key!==M){let C=this.wrapDegrees(c),V=this.offsetPoint(0,0,C,d),m=this.offsetPoint(V.x,V.y,C,a);this.ownShipVectorCache={key:M,tipX:V.x,tipY:V.y,endX:m.x,endY:m.y};}let S=this.rotatePoint(this.ownShipVectorCache.tipX,this.ownShipVectorCache.tipY,-s),_=this.rotatePoint(this.ownShipVectorCache.endX,this.ownShipVectorCache.endY,-s);u.push({id:"ownship",x1:S.x,y1:S.y,x2:_.x,y2:_.y,className:"ownship-vector",stroke:"var(--kip-orange-color)"}),this.renderVectorLines(this.ownShipLayer,"ownship-vector",u);}rotatePoint(e,t,i){let s=i*Math.PI/180,r=Math.cos(s),o=Math.sin(s);return {x:e*r-t*o,y:e*o+t*r}}renderVectorLines(e,t,i){let s=e.selectAll(`line.${t}`).data(i,o=>o.id);s.enter().append("line").attr("class",o=>`${t} ${o.className}`).merge(s).attr("x1",o=>o.x1).attr("y1",o=>o.y1).attr("x2",o=>o.x2).attr("y2",o=>o.y2).style("stroke",o=>o.stroke??"#50505f").style("stroke-width",2).style("opacity",1).style("stroke-dasharray","15, 7"),s.exit().remove();let r=e.selectAll(`circle.${t}-tip`).data(i,o=>o.id);r.enter().append("circle").attr("class",o=>`${t}-tip ${o.className}`).merge(r).attr("cx",o=>o.x2).attr("cy",o=>o.y2).attr("r",2.5).style("fill",o=>o.stroke??"#50505f").style("stroke",o=>o.stroke??"#50505f").style("stroke-width",2).style("opacity",1).style("stroke-dasharray","15, 7"),r.exit().remove();}renderTargets(e,t){if(!this.targetsLayer)return;let i=this.resolveTargetBaseSize(t),s=this.targetsLayer.selectAll("g.target").data(e,n=>n.id),r=s.enter().append("g").on("click",(n,d)=>{n.stopPropagation(),this.handleTargetClick(n,d);});r.append("image").attr("class","target-icon"),r.append("title");let o=r.merge(s);o.attr("transform",n=>`translate(${n.x}, ${n.y}) rotate(${n.heading})`).attr("class",n=>`target ${n.className}`),o.select("image.target-icon").attr("href",n=>n.iconHref??null).attr("xlink:href",n=>n.iconHref??null).attr("display",n=>n.iconHref?null:"none").attr("width",n=>i*n.iconScale).attr("height",n=>i*n.iconScale).attr("x",n=>-(i*n.iconScale)/2).attr("y",n=>-(i*n.iconScale)/2),o.select("title").text(n=>`${n.raw.name??n.raw.mmsi??"AIS Target"}`),s.exit().remove();}renderSelected(e,t){if(!this.selectedLayer)return;let i=e.filter(u=>u.id===this.selectedId()),s=this.resolveTargetBaseSize(t),r=s*1.4,o=Math.min(r,Math.max(4,s*.6)),n=this.buildCornerBoxPath(r,o),d=this.selectedLayer.selectAll("path.selected-ring").data(i,u=>u.id);d.enter().append("path").attr("class","selected-ring").merge(d).attr("transform",u=>`translate(${u.x}, ${u.y})`).attr("d",n),d.exit().remove();}resolveTargetBaseSize(e){let t=Math.max(.2,e);return l.TARGET_ICON_SIZE_PX/t}resolveOwnShipBaseSize(e){let t=Math.max(.2,e);return l.OWN_SHIP_ICON_SIZE_PX/t}raiseOwnshipAndVector(){this.ownShipLayer?.raise();}onMenuItemSelect(e){this.openTargetDialog(e.target,e.iconHref),this.selectedId.set(null),this.closeTargetMenu();}handleTargetClick(e,t){let i=this.resolveMenuItems(e,t);if(i.length<=1){this.openTargetDialog(t.raw,t.iconHref);return}this.menuItems.set(i),this.menuPoint=this.resolveMenuPoint(e),this.positionMenuAnchor(),this.menuTrigger().openMenu();}openTargetDialog(e,t){this.selectedId.set(e.id);let i=this.snapshotAisTrack(e);this.dialog.openAisDetailDialog({title:this.buildTargetTitle(i),iconHref:t??void 0,component:"ais-target",componentType:cn,payload:{target:i}}).subscribe();}snapshotAisTrack(e){return structuredClone(e)}resolveMenuItems(e,t){return this.findTargetsNearEvent(e,t).map(s=>({id:s.id,label:this.buildTargetMenuLabel(s.raw),iconHref:s.iconHref,target:s.raw}))}findTargetsNearEvent(e,t){let i=this.lastRenderTargets.length?this.lastRenderTargets:[t],s=this.eventToRadarPoint(e);if(!s)return [t];let r=this.hitRadiusPx/this.lastRenderScale,o=i.map((n,d)=>{let u=n.x-s.x,b=n.y-s.y,c=Math.hypot(u,b);return {candidate:n,distance:c,index:d}}).filter(n=>n.distance<=r).sort((n,d)=>n.distance-d.distance||n.index-d.index).map(n=>n.candidate);return o.length?o:[t]}eventToRadarPoint(e){if(!this.lastRenderSize)return null;let s=this.svgRef().nativeElement.getBoundingClientRect(),r=e.clientX-s.left,o=e.clientY-s.top,n=(r-s.width/2)/this.lastRenderScale,d=(o-s.height/2)/this.lastRenderScale,u=this.lastViewRotation*Math.PI/180,b=Math.cos(u),c=Math.sin(u);return {x:n*b-d*c,y:n*c+d*b}}resolveMenuPoint(e){let t=this.svgRef().nativeElement.closest(".ais-radar-container");if(!t)return null;let i=t.getBoundingClientRect();return {x:e.clientX-i.left,y:e.clientY-i.top}}positionMenuAnchor(){let e=this.menuAnchorRef().nativeElement;this.menuPoint&&(e.style.left=`${this.menuPoint.x}px`,e.style.top=`${this.menuPoint.y}px`);}closeTargetMenu(){this.resetTargetMenuState(),this.menuTrigger().menuOpen&&this.menuTrigger().closeMenu();}resetTargetMenuState(){this.menuItems.set([]),this.menuPoint=null;}buildTargetMenuLabel(e){return this.isAton(e)&&e.typeName?e.typeName:e.name??e.mmsi??"AIS Target"}buildTargetTitle(e){let t=this.isAton(e)&&e.typeName?e.typeName:e.name??e.type??"AIS Target",i=e.ais.status;return i==="unconfirmed"||i==="lost"||i==="remove"?`${t} - ${i}`:t}resolveIconCached(e){let t=this.buildIconSignature(e),i=this.iconCache.get(e.id);if(i&&i.signature===t)return i.icon;let s=this.resolveIconScale(e.type),r={href:i?.icon.href??null,scale:s};this.iconCache.set(e.id,{signature:t,icon:r});let o=e.ais.status==="remove"?void 0:e.ais.status;return this.ngZone.runOutsideAngular(()=>{nc({mmsi:e.mmsi??"",type:e.type,navState:this.isVesselLike(e)?e.navState:void 0,aisShipTypeId:this.isVesselLike(e)?e.design?.aisShipType?.id:void 0,atonVirtual:this.isAton(e)?e.virtual:void 0,atonTypeId:this.isAton(e)?e.typeId:void 0,status:o,collisionRiskRating:this.isVesselLike(e)?e.closestApproach?.collisionRiskRating:void 0}).then(n=>{let d=this.iconCache.get(e.id);!d||d.signature!==t||(d.icon={href:n,scale:s},this.scheduleRenderDebounced());});}),r}resolveIconScale(e){switch(e){case "aton":return 3.5;case "basestation":return 3;case "sar":return 2.4;case "vessel":return 3;default:return 2.4}}buildIconSignature(e){let t=e.ais.status==="lost"?"unconfirmed":e.ais.status;return [e.mmsi,e.type,this.isVesselLike(e)?e.navState:void 0,this.isVesselLike(e)?e.design?.aisShipType?.id:void 0,this.isAton(e)?e.virtual:void 0,this.isAton(e)?e.typeId:void 0,t,this.isVesselLike(e)?e.closestApproach?.collisionRiskRating:void 0].join("|")}buildClassName(e){let t=[`status-${e.status}`,`type-${e.type}`,e.aisClass?`class-${e.aisClass.toLowerCase()}`:"class-unknown"];if(e.navState){let i=e.navState.toLowerCase();i.includes("moored")&&t.push("state-moored"),i.includes("anchored")&&t.push("state-anchored");}return e.id===this.selectedId()&&t.push("is-selected"),t.join(" ")}resolveTargetVectorStroke(e){if(e.ais.status!=="confirmed")return "#50505f";let t=e.closestApproach?.collisionRiskRating,i=typeof t=="number"?t:Number(t);return Number.isFinite(i)?i<qn?"red":i<zn?"yellow":"#50505f":"#50505f"}shouldFilterTarget(e){let t=this.filterState();if(!t.anchoredMoored&&!t.noCollisionRisk&&!t.allAton&&!t.allButSar&&!t.allVessels&&t.vesselTypes.size===0)return false;if(t.anchoredMoored&&this.isVesselLike(e)&&this.isStationaryNavState(e.navState)||t.noCollisionRisk&&this.isVesselLike(e)&&(e.ais.status!=="confirmed"||this.isStationaryNavState(e.navState)||this.isNoCollisionRisk(e))||t.allAton&&e.type==="aton"||t.allButSar&&e.type!=="sar"||t.allVessels&&this.isVesselLike(e))return true;if(t.vesselTypes.size>0&&this.isVesselLike(e)){let i=this.resolveVesselIconKey(e);if(i&&t.vesselTypes.has(i))return true}return false}isNoCollisionRisk(e){let t=e.closestApproach?.collisionRiskRating;if(!Object.prototype.hasOwnProperty.call(e.closestApproach??{},"collisionRiskRating"))return false;if(t==null)return true;let i=typeof t=="number"?t:Number(t);return Number.isFinite(i)?i>=zn:true}resolveVesselIconKey(e){if(!this.isVesselLike(e))return null;let t=pa({mmsi:e.mmsi??e.id??"",type:e.type,aisShipTypeId:e.design?.aisShipType?.id});return t.startsWith("vessel/")?t:null}polarToCartesian(e,t,i,s){let r=e*Math.PI/180,o=t/i*s;return {x:o*Math.sin(r),y:-o*Math.cos(r)}}hasValidPosition(e){return typeof e?.latitude=="number"&&Number.isFinite(e.latitude)&&typeof e?.longitude=="number"&&Number.isFinite(e.longitude)}offsetPoint(e,t,i,s){let r=i*Math.PI/180;return {x:e+s*Math.sin(r),y:t-s*Math.cos(r)}}wrapDegrees(e){let t=e%360;return t<0?t+360:t}isStationaryNavState(e){if(typeof e=="number"&&Number.isFinite(e))return e===1||e===5;if(typeof e!="string")return false;let t=e.trim().toLowerCase().replace(/\s+/g," ");if(!t.length)return false;let i=Number(t);return Number.isFinite(i)?i===1||i===5:t.includes("moored")||t.includes("anchored")||t.includes("at anchor")}shortestAngleDelta(e,t){return (t-e+540)%360-180}buildTrackSignature(e){let t=e.position??{};return [t.latitude,t.longitude,this.isVesselLike(e)?e.headingTrue:void 0,this.isVesselLike(e)?e.courseOverGroundTrue:void 0].join("|")}isVesselLike(e){return e.type==="vessel"||e.type==="sar"}isAton(e){return e.type==="aton"}buildCornerBoxPath(e,t){let i=e,s=Math.min(Math.max(t,0),i);return [`M ${-i} ${-i} h ${s}`,`M ${-i} ${-i} v ${s}`,`M ${i} ${-i} h ${-s}`,`M ${i} ${-i} v ${s}`,`M ${-i} ${i} h ${s}`,`M ${-i} ${i} v ${-s}`,`M ${i} ${i} h ${-s}`,`M ${i} ${i} v ${-s}`].join(" ")}smoothRotation(e){let t=performance.now();if(this.viewRotationSmoothed===null||this.lastRotationAt===null)return this.viewRotationSmoothed=this.wrapDegrees(e),this.lastRotationAt=t,this.viewRotationSmoothed;let i=Math.min(250,Math.max(0,t-this.lastRotationAt)),s=Math.min(1,i/200),r=this.shortestAngleDelta(this.viewRotationSmoothed,e);return this.viewRotationSmoothed=this.wrapDegrees(this.viewRotationSmoothed+r*s),this.lastRotationAt=t,this.viewRotationSmoothed}toDegreesIfRadians(e){return typeof e!="number"||!Number.isFinite(e)?null:this.units.convertToUnit("deg",e)}distanceNm(e,t){let s=e.latitude*Math.PI/180,r=t.latitude*Math.PI/180,o=(t.latitude-e.latitude)*Math.PI/180,n=(t.longitude-e.longitude)*Math.PI/180,d=Math.sin(o/2),u=Math.sin(n/2),b=d*d+Math.cos(s)*Math.cos(r)*u*u;return 6371e3*(2*Math.atan2(Math.sqrt(b),Math.sqrt(1-b)))/1852}ngOnDestroy(){this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.rotationFrameTimer!==null&&(window.clearTimeout(this.rotationFrameTimer),this.rotationFrameTimer=null),this.iconRenderTimer!==null&&(window.clearTimeout(this.iconRenderTimer),this.iconRenderTimer=null);}static \u0275fac=function(t){return new(t||l)};static \u0275cmp=JD({type:l,selectors:[["widget-ais-radar"]],viewQuery:function(t,i){t&1&&eg(i.svgRef,lt,5)(i.menuAnchorRef,ct,5)(i.menuTrigger,dt,5),t&2&&Kw(3);},inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"]},decls:29,vars:9,consts:[["radarSvg",""],["menuAnchor","","menuTrigger","matMenuTrigger"],["targetMenu","matMenu"],["filterMenu","matMenu"],["vesselTypeMenu","matMenu"],["kipResizeObserver","",1,"ais-radar-container",3,"kipResize"],["type","button","matMiniFab","",1,"ais-radar-mode-toggle-button",3,"click","matTooltip"],["viewBox","0 0 40 40","aria-hidden","true",1,"ais-mode-icon"],["type","button","matMiniFab","","matTooltip","Increase range","aria-label","Increase range",1,"ais-radar-range-button","ais-radar-range-plus",3,"click"],["type","button","matMiniFab","","matTooltip","Decrease range","aria-label","Decrease range",1,"ais-radar-range-button","ais-radar-range-minus",3,"click"],["type","button","matMiniFab","","matTooltip","Filter targets","aria-label","Filter targets",1,"ais-radar-range-button","ais-radar-filter-button",3,"matMenuTriggerFor"],["type","button","matMiniFab","","matTooltip","Show only collision risk targets","aria-label","No collision risk filter",1,"ais-radar-range-button","ais-radar-collision-button",3,"is-active"],["role","img","aria-label","AIS radar display",1,"ais-radar"],["type","button","aria-hidden","true","tabindex","-1",1,"ais-radar-menu-anchor",3,"matMenuTriggerFor"],[3,"closed"],["matMenuContent",""],[1,"widgetOverlay"],["stroke","currentColor","d","M10 8 L20 2 L30 8",1,"ais-mode-icon-chev"],["fill","currentColor","x","20","y","31",1,"ais-mode-icon-letter"],["fill","currentColor","d","M20 4 L34 36 L20 28 L6 36 Z",1,"ais-mode-icon-vessel"],["type","button","matMiniFab","","matTooltip","Show only collision risk targets","aria-label","No collision risk filter",1,"ais-radar-range-button","ais-radar-collision-button",3,"click"],["mat-menu-item","","type","button",1,"ais-radar-menu-item"],["mat-menu-item","","type","button",1,"ais-radar-menu-item",3,"click"],["alt","","aria-hidden","true",1,"target-menu-icon"],[1,"target-menu-label"],["mat-menu-item","","disabled","",1,"ais-filter-menu-header"],["mat-menu-item","","type","button",3,"click"],["aria-hidden","true",1,"ais-filter-check"],["mat-menu-item","",3,"matMenuTriggerFor"],["mat-menu-item","","type","button"]],template:function(t,i){if(t&1&&(Pi(0,"div",5),Qh("kipResize",function(r){return i.onResized(r)}),Pi(1,"button",6),Qh("click",function(){return i.toggleViewMode()}),_w(2,ut,4,0,":svg:svg",7)(3,mt,2,0,":svg:svg",7),ul(),Pi(4,"button",8),Qh("click",function(){return i.incrementRange()}),Pi(5,"mat-icon"),TT(6,"add"),ul()(),Pi(7,"button",9),Qh("click",function(){return i.decrementRange()}),Pi(8,"mat-icon"),TT(9,"remove"),ul()(),Pi(10,"button",10)(11,"mat-icon"),TT(12,"filter_list"),ul()(),_w(13,gt,3,2,"button",11),wd(),$h(14,"svg",12,0),Td(),$h(16,"button",13,1),ul(),Pi(19,"mat-menu",14,2),Qh("closed",function(){return i.resetTargetMenuState()}),xh(21,ft,2,0,"ng-template",15),ul(),Pi(22,"mat-menu",null,3),xh(24,St,27,5,"ng-template",15),ul(),Pi(25,"mat-menu",null,4),xh(27,bt,2,0,"ng-template",15),ul(),_w(28,yt,1,0,"div",16)),t&2){let s=Jw(20),r=Jw(23);EE(),Bh("matTooltip",i.effectiveViewMode()==="north-up"?"Change to North-Up mode":"Change to Course-Up mode"),Hh("aria-label",i.effectiveViewMode()==="north-up"?"North up mode":"Course up mode"),EE(),Mw(i.effectiveViewMode()==="north-up"?2:3),EE(8),sg("is-active",i.hasActiveFilters()),Bh("matMenuTriggerFor",r),EE(3),Mw(i.hasCollisionRiskData()?13:-1),EE(3),Bh("matMenuTriggerFor",s),EE(12),Mw(i.dashboard.isDashboardStatic()?-1:28);}},dependencies:[u,Op,Rp,yt$1,wt,Ht,R,ee,Nt,Lt,zt,mt$1],encapsulation:2})}return l})();export{Qt as WidgetAisRadarComponent};
@@ -1 +1 @@
1
- import {d1 as Hj,w,du as p,dv as rt,aZ as R,D as Dt,$ as $j,v as vt,F as Fa,dn as ge,J as JD,cp as Uh,f as eg,K as Kw}from'./main-BNR44HGB.js';import {c}from'./chunk-D_wrJJxl.js';var E=["canvasMainRef"],O=(()=>{class s{id=Hj.required();type=Hj.required();theme=Hj.required();static DEFAULT_CONFIG={displayName:"Gauge Label",filterSelfPaths:true,paths:{stringPath:{description:"String Data",path:null,source:null,pathType:"string",isPathConfigurable:true,sampleTime:500}},color:"contrast",enableTimeout:false,dataTimeout:5};runtime=w(p);stream=w(rt);canvas=w(R);normalizedConfig=Dt(()=>this.runtime.options()??s.DEFAULT_CONFIG);stringPathConfig=Dt(()=>this.normalizedConfig().paths?.stringPath);canvasMainRef=$j.required("canvasMainRef");canvasElement;canvasCtx=null;titleBitmap=null;titleBitmapText=null;cssWidth=0;cssHeight=0;dataValue=null;labelColor=vt("");valueColor="";isDestroyed=false;streamRegistered=false;constructor(){Fa(()=>{let t=this.theme();ge(()=>{t&&(this.setColors(),this.drawWidget());});}),Fa(()=>{this.normalizedConfig();this.isDestroyed||!this.canvasCtx||ge(()=>{this.setColors(),this.startWidget(),this.drawWidget();});});}ngOnInit(){this.setColors();}ngAfterViewInit(){this.canvasElement=this.canvasMainRef().nativeElement,this.canvasCtx=this.canvasElement.getContext("2d"),this.canvas.registerCanvas(this.canvasElement,{autoRelease:true,onResize:(t,e)=>{this.cssWidth=t,this.cssHeight=e,this.drawWidget();}}),this.cssHeight=Math.round(this.canvasElement.getBoundingClientRect().height),this.cssWidth=Math.round(this.canvasElement.getBoundingClientRect().width),!this.isDestroyed&&this.startWidget();}startWidget(){this.dataValue=null,this.streamRegistered||(this.stringPathConfig()?.path?(this.stream.observe("stringPath",e=>{this.dataValue=e.data.value,this.drawWidget();}),this.streamRegistered=true):this.drawWidget());}setColors(){let e=this.normalizedConfig().color??"contrast";this.labelColor.set(c(e,this.theme()).dim),this.valueColor=c(e,this.theme()).color;}ngOnDestroy(){this.isDestroyed=true;try{this.canvas.unregisterCanvas(this.canvasElement);}catch(t){}}drawWidget(){if(!this.canvasCtx)return;let t=Math.floor(this.cssHeight*.1),i=this.normalizedConfig().displayName??"Gauge Label",y=i+"|"+this.labelColor();(!this.titleBitmap||this.titleBitmap.width!==this.canvasElement.width||this.titleBitmap.height!==this.canvasElement.height||this.titleBitmapText!==y)&&(this.titleBitmap=this.canvas.createTitleBitmap(i,this.labelColor(),"normal",this.cssWidth,this.cssHeight),this.titleBitmapText=i+"|"+this.labelColor()),this.canvas.clearCanvas(this.canvasCtx,this.cssWidth,this.cssHeight),this.titleBitmap&&this.titleBitmap.width>0&&this.titleBitmap.height>0&&this.canvasCtx.drawImage(this.titleBitmap,0,0,this.cssWidth,this.cssHeight);let b=this.dataValue===null?"--":this.dataValue,h=this.canvas.EDGE_BUFFER||10,d=Math.max(0,this.cssHeight-t-2*h),W=Math.max(0,Math.floor(this.cssWidth-2*h)),w=Math.max(0,Math.floor(d)),D=Math.floor(this.cssWidth/2),B=Math.floor(t+h+d/2);this.canvas.drawText(this.canvasCtx,b,D,B,W,w,"bold",this.valueColor,"center","middle");}static \u0275fac=function(e){return new(e||s)};static \u0275cmp=JD({type:s,selectors:[["widget-text"]],viewQuery:function(e,i){e&1&&eg(i.canvasMainRef,E,5),e&2&&Kw();},inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"]},decls:2,vars:0,consts:[["canvasMainRef",""],[1,"text-canvas"]],template:function(e,i){e&1&&Uh(0,"canvas",1,0);},styles:["[_nghost-%COMP%]{display:block;width:100%;height:100%;overflow:hidden}.text-canvas[_ngcontent-%COMP%]{display:block;width:100%!important;height:100%!important;min-height:1px}"]})}return s})();export{O as WidgetTextComponent};
1
+ import {d1 as Hj,w,du as p,dv as rt,aZ as R,D as Dt,$ as $j,v as vt,F as Fa,dn as ge,J as JD,cp as Uh,f as eg,K as Kw}from'./main-YKDNK5VZ.js';import {c}from'./chunk-BIb-xYiS.js';var E=["canvasMainRef"],O=(()=>{class s{id=Hj.required();type=Hj.required();theme=Hj.required();static DEFAULT_CONFIG={displayName:"Gauge Label",filterSelfPaths:true,paths:{stringPath:{description:"String Data",path:null,source:null,pathType:"string",isPathConfigurable:true,sampleTime:500}},color:"contrast",enableTimeout:false,dataTimeout:5};runtime=w(p);stream=w(rt);canvas=w(R);normalizedConfig=Dt(()=>this.runtime.options()??s.DEFAULT_CONFIG);stringPathConfig=Dt(()=>this.normalizedConfig().paths?.stringPath);canvasMainRef=$j.required("canvasMainRef");canvasElement;canvasCtx=null;titleBitmap=null;titleBitmapText=null;cssWidth=0;cssHeight=0;dataValue=null;labelColor=vt("");valueColor="";isDestroyed=false;streamRegistered=false;constructor(){Fa(()=>{let t=this.theme();ge(()=>{t&&(this.setColors(),this.drawWidget());});}),Fa(()=>{this.normalizedConfig();this.isDestroyed||!this.canvasCtx||ge(()=>{this.setColors(),this.startWidget(),this.drawWidget();});});}ngOnInit(){this.setColors();}ngAfterViewInit(){this.canvasElement=this.canvasMainRef().nativeElement,this.canvasCtx=this.canvasElement.getContext("2d"),this.canvas.registerCanvas(this.canvasElement,{autoRelease:true,onResize:(t,e)=>{this.cssWidth=t,this.cssHeight=e,this.drawWidget();}}),this.cssHeight=Math.round(this.canvasElement.getBoundingClientRect().height),this.cssWidth=Math.round(this.canvasElement.getBoundingClientRect().width),!this.isDestroyed&&this.startWidget();}startWidget(){this.dataValue=null,this.streamRegistered||(this.stringPathConfig()?.path?(this.stream.observe("stringPath",e=>{this.dataValue=e.data.value,this.drawWidget();}),this.streamRegistered=true):this.drawWidget());}setColors(){let e=this.normalizedConfig().color??"contrast";this.labelColor.set(c(e,this.theme()).dim),this.valueColor=c(e,this.theme()).color;}ngOnDestroy(){this.isDestroyed=true;try{this.canvas.unregisterCanvas(this.canvasElement);}catch(t){}}drawWidget(){if(!this.canvasCtx)return;let t=Math.floor(this.cssHeight*.1),i=this.normalizedConfig().displayName??"Gauge Label",y=i+"|"+this.labelColor();(!this.titleBitmap||this.titleBitmap.width!==this.canvasElement.width||this.titleBitmap.height!==this.canvasElement.height||this.titleBitmapText!==y)&&(this.titleBitmap=this.canvas.createTitleBitmap(i,this.labelColor(),"normal",this.cssWidth,this.cssHeight),this.titleBitmapText=i+"|"+this.labelColor()),this.canvas.clearCanvas(this.canvasCtx,this.cssWidth,this.cssHeight),this.titleBitmap&&this.titleBitmap.width>0&&this.titleBitmap.height>0&&this.canvasCtx.drawImage(this.titleBitmap,0,0,this.cssWidth,this.cssHeight);let b=this.dataValue===null?"--":this.dataValue,h=this.canvas.EDGE_BUFFER||10,d=Math.max(0,this.cssHeight-t-2*h),W=Math.max(0,Math.floor(this.cssWidth-2*h)),w=Math.max(0,Math.floor(d)),D=Math.floor(this.cssWidth/2),B=Math.floor(t+h+d/2);this.canvas.drawText(this.canvasCtx,b,D,B,W,w,"bold",this.valueColor,"center","middle");}static \u0275fac=function(e){return new(e||s)};static \u0275cmp=JD({type:s,selectors:[["widget-text"]],viewQuery:function(e,i){e&1&&eg(i.canvasMainRef,E,5),e&2&&Kw();},inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"]},decls:2,vars:0,consts:[["canvasMainRef",""],[1,"text-canvas"]],template:function(e,i){e&1&&Uh(0,"canvas",1,0);},styles:["[_nghost-%COMP%]{display:block;width:100%;height:100%;overflow:hidden}.text-canvas[_ngcontent-%COMP%]{display:block;width:100%!important;height:100%!important;min-height:1px}"]})}return s})();export{O as WidgetTextComponent};