UNPKG

fleeta-components

Version:

A comprehensive React component library for fleet management applications

3 lines (2 loc) β€’ 29.1 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("clsx"),require("tailwind-merge"),require("zustand"),require("react/jsx-runtime"),require("react"),require("lucide-react"),require("react-map-gl")):"function"==typeof define&&define.amd?define(["exports","clsx","tailwind-merge","zustand","react/jsx-runtime","react","lucide-react","react-map-gl"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).FleetAComponents={},e.clsx,e.tailwindMerge,e.zustand,e["react/jsx-runtime"],e.React,e.LucideReact,e.ReactMapGL)}(this,(function(e,t,n,s,a,r,l,o){"use strict";function i(...e){return n.twMerge(t.clsx(e))}function c({icon:e=a.jsx(l.Car,{size:8}),speed:t,course:n,speedUnit:s="km/h",className:r}){const o=null!=t?Math.round(t):null;return a.jsxs("div",{className:i("relative flex flex-col items-center",r),style:{marginTop:"-10px"},children:[a.jsx("div",{className:"relative z-10 w-5 h-5 bg-primary rounded-full flex items-center justify-center text-white shadow-lg transition-transform border-0 border-white dark:border-gray-800",children:e}),a.jsx("div",{className:"absolute top-full left-1/2 -translate-x-1/2 mt-1 bg-black/30 text-white px-2 py-0.5 rounded text-xs flex items-center gap-1 whitespace-nowrap min-w-[60px] justify-center",children:a.jsxs("div",{className:"absolute top-full left-1/2 -translate-x-1/2 mt-1 bg-black/30 dark:bg-gray-900/50 text-white dark:text-gray-100 px-2 py-0.5 rounded text-xs flex items-center gap-1 whitespace-nowrap min-w-[60px] justify-center",children:[a.jsx("span",{className:"flex-shrink-0",children:null!==o?o:"--"})," ",s,null!==n&&a.jsxs("span",{className:"ml-2 border-l border-white/20 dark:border-gray-400/30 pl-2",title:"Vehicle heading",children:[Math.round(n??0),"Β°"]})]})})]})}const u={streets:"mapbox://styles/mapbox/streets-v12",satellite:"mapbox://styles/mapbox/satellite-v9",outdoors:"mapbox://styles/mapbox/outdoors-v12",light:"mapbox://styles/mapbox/light-v11",dark:"mapbox://styles/mapbox/dark-v11"},d=s.create((e=>({style:"streets",setStyle:t=>e({style:t})})));function h({sensorData:e,currentTime:t,videoDuration:n=60,className:s}){const l=r.useMemo((()=>{if(!e||!Array.isArray(e))return[];return e.filter((e=>(t??0)>=e.timestamp&&null!==e.x&&null!==e.y&&null!==e.z))}),[e,t]);r.useMemo((()=>l.length?l[l.length-1]:null),[l]);const o=r.useMemo((()=>{if(!l.length)return 1;const e=Math.max(...l.map((e=>Math.abs(e.x||0)))),t=Math.max(...l.map((e=>Math.abs(e.y||0)))),n=Math.max(...l.map((e=>Math.abs(e.z||0))));return Math.max(e,t,n,1)/127.5}),[l]),c=e=>{if(null===e)return 50;const t=(e=>null===e?0:e/127.5)(e);return Math.max(10,Math.min(90,50-t/o*40))};return a.jsxs("div",{className:i("relative bg-blue-900/50 rounded-xl",s),style:{width:"100%",height:"100%"},children:[a.jsxs("svg",{width:"100%",height:"100%",viewBox:"0 0 100 100",preserveAspectRatio:"none",className:"overflow-visible",children:[a.jsx("line",{x1:"0",y1:"50%",x2:"100%",y2:"50%",stroke:"#4b5563",strokeWidth:"2"}),(()=>{if(!l.length)return[];const e=[],t=[],n=[];l.forEach(((s,r)=>{const l=c(s.x),o=c(s.y),i=c(s.z);e.push(a.jsx("line",{x1:25,y1:"50%",x2:25,y2:`${l}%`,stroke:"#8b5cf6",strokeWidth:"10","data-timestamp":s.timestamp.toFixed(2)},`x-${r}`)),t.push(a.jsx("line",{x1:50,y1:"50%",x2:50,y2:`${o}%`,stroke:"#10b981",strokeWidth:"10","data-timestamp":s.timestamp.toFixed(2)},`y-${r}`)),n.push(a.jsx("line",{x1:75,y1:"50%",x2:75,y2:`${i}%`,stroke:"#3b82f6",strokeWidth:"10","data-timestamp":s.timestamp.toFixed(2)},`z-${r}`))}));const s=[];return e.length>0&&s.push(e[e.length-1]),t.length>0&&s.push(t[t.length-1]),n.length>0&&s.push(n[n.length-1]),s})()]}),(!e||!Array.isArray(e)||!l.length)&&a.jsx("div",{className:"absolute inset-0 flex items-center justify-center z-20",children:a.jsx("div",{className:"text-white/50 text-xs"})})]})}const m={};function p({height:e="200px",gpsPoints:t=[],currentTime:n,sensorData:s,showEventComponent:p=!0,videoDuration:x=60,className:g,speedUnit:f="km/h",mapStyle:v}){var y,b,w;const N=r.useRef(null),j=r.useRef(null),M=r.useRef(Math.random().toString(36).substr(2,9)),[E,S]=r.useState(!1),[k,T]=r.useState({longitude:-122.4194,latitude:37.7749,zoom:13,pitch:0,bearing:0}),[C,R]=r.useState(!1),[P,L]=r.useState(null),{style:z}=d(),A=r.useMemo((()=>P||(v||(C?"dark":"light"))),[P,v,z,C]),F=u[A];r.useEffect((()=>{const e=()=>{const e=document.documentElement.classList.contains("dark"),t=window.matchMedia("(prefers-color-scheme: dark)").matches,n=e||!document.documentElement.classList.contains("light")&&t;R(n)};e();const t=new MutationObserver(e);t.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]});const n=window.matchMedia("(prefers-color-scheme: dark)"),s=()=>e();return n.addEventListener?n.addEventListener("change",s):n.addListener(s),()=>{t.disconnect(),n.removeEventListener?n.removeEventListener("change",s):n.removeListener(s)}}),[]);const D=(null==m?void 0:m.VITE_MAPBOX_ACCESS_TOKEN)||"";r.useEffect((()=>{j.current&&S(!0)}),[]),r.useEffect((()=>{if(E&&N.current){const e=N.current.getCanvas();e&&(e.style.borderRadius="0.375rem")}}),[E,N.current]),r.useEffect((()=>{if(N.current&&E){setTimeout((()=>{N.current&&N.current.resize()}),300);const e=new ResizeObserver((()=>{N.current&&setTimeout((()=>{N.current.resize()}),50)}));if(j.current){e.observe(j.current);const t=j.current.parentElement;t&&e.observe(t)}return[100,300,500,800].forEach((e=>{setTimeout((()=>{N.current&&N.current.resize()}),e)})),()=>{e.disconnect()}}}),[E]);const O=r.useMemo((()=>(null==t?void 0:t.length)?t.filter((e=>{const t=Number(e.lat),n=Number(e.lng);return null!=e.lat&&null!=e.lng&&!isNaN(t)&&!isNaN(n)&&isFinite(t)&&isFinite(n)&&t>=-90&&90>=t&&n>=-180&&180>=n})):[]),[t]),U=O.length>0;r.useEffect((()=>{O.length>0&&null!==O[0].lat&&null!==O[0].lng&&T((e=>({...e,longitude:O[0].lng,latitude:O[0].lat})))}),[O]);const V=r.useMemo((()=>{if(!(null==O?void 0:O.length)||void 0===n)return[];const e=n;return O.filter((t=>e>=t.relativeTime))}),[O,n]),G=r.useMemo((()=>{if(!(null==O?void 0:O.length)||void 0===n)return null;const e=n;return O.find(((t,n)=>{const s=O[n+1];if(!s)return!0;return e>=t.relativeTime&&s.relativeTime>e}))}),[O,n]);r.useEffect((()=>{G&&N.current&&T((e=>({...e,longitude:Number(G.lng),latitude:Number(G.lat),zoom:e.zoom})))}),[G]);const I=[{key:"auto",label:"Auto",icon:"πŸŒ“"},{key:"light",label:"Light",icon:"β˜€οΈ"},{key:"dark",label:"Dark",icon:"πŸŒ™"},{key:"streets",label:"Streets",icon:"πŸ—ΊοΈ"},{key:"satellite",label:"Satellite",icon:"πŸ›°οΈ"},{key:"outdoors",label:"Outdoors",icon:"πŸ”οΈ"}];return D?a.jsxs("div",{ref:j,className:i("relative w-full p-1",g),style:{height:e},children:[a.jsxs("div",{className:"flex items-center justify-between h-[30px]",children:[a.jsxs("h4",{className:"text-xs font-medium text-gray-300 dark:text-gray-300 flex items-center flex-1",children:["GPS Navigation",G&&a.jsxs("span",{className:"ml-2 text-xs font-normal text-gray-300 dark:text-gray-300 flex items-center gap-1",children:[null==(y=G.lat)?void 0:y.toFixed(2),"Β°, ",null==(b=G.lng)?void 0:b.toFixed(2),"Β°",null!==G.speedKmh&&` β€’ ${Math.round("mph"===f?.621371*G.speedKmh:G.speedKmh)} ${f}`,null!==G.course&&` β€’ ${Math.round(G.course)}Β° heading`]})]}),a.jsx("div",{className:"flex items-center gap-1 mx-2",children:a.jsxs("div",{className:"relative group",children:[a.jsxs("button",{className:"flex items-center gap-1 px-2 py-1 text-xs bg-black/20 hover:bg-black/30 text-gray-300 rounded transition-colors",children:[a.jsx(l.Layers,{className:"w-3 h-3"}),a.jsx("span",{className:"hidden sm:inline",children:P?null==(w=I.find((e=>e.key===P)))?void 0:w.label:"Auto"})]}),a.jsx("div",{className:"absolute top-full right-0 mt-1 bg-gray-800 border border-gray-600 rounded shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50 min-w-[120px]",children:I.map((e=>a.jsxs("button",{onClick:()=>{var t;L("auto"===(t=e.key)?null:t)},className:i("w-full text-left px-3 py-2 text-xs hover:bg-gray-700 text-gray-300 flex items-center gap-2 transition-colors","auto"===e.key&&!P||e.key===P?"bg-gray-700":""),children:[a.jsx("span",{children:e.icon}),a.jsx("span",{children:e.label})]},e.key)))})]})}),p&&s&&a.jsx("div",{className:"flex-shrink-0 h-[25px] w-[55px] flex items-center justify-center ml-auto pr-2",children:a.jsx(h,{sensorData:s,currentTime:n,videoDuration:x||60,className:"h-[25px] rounded"})})]}),!U&&a.jsx("div",{className:"absolute inset-0 flex items-center justify-center z-20 pointer-events-none",children:a.jsx("div",{className:"bg-black/50 px-6 py-3 rounded-lg text-white text-sm",children:"No GPS data found in this recording"})}),a.jsx("div",{className:"absolute inset-0 top-[40px] bottom-0",style:{transition:"width 0.3s ease, height 0.3s ease",width:"100%",height:"calc(100% - 40px)"},children:E&&a.jsx("div",{style:{width:"100%",height:"100%",position:"relative",overflow:"hidden"},className:"map-container",children:a.jsxs(o.Map,{ref:N,...k,onMove:e=>T(e.viewState),mapStyle:F,mapboxAccessToken:D,style:{width:"100%",height:"100%"},children:[G&&null!=G.lat&&null!=G.lng&&a.jsx(o.Marker,{longitude:G.lng,latitude:G.lat,anchor:"top",children:a.jsx(c,{icon:a.jsx(l.Car,{size:16}),speed:null!==(null==G?void 0:G.speedKmh)?"mph"===f?.621371*G.speedKmh:G.speedKmh:void 0,course:null==G?void 0:G.course,speedUnit:f})}),0===O.length&&a.jsx(o.Marker,{longitude:k.longitude,latitude:k.latitude,anchor:"center",children:a.jsx("div",{className:"w-8 h-8 bg-gray-500/50 rounded-full flex items-center justify-center text-white animate-pulse",children:a.jsx(l.MapPin,{size:16})})}),a.jsx(o.NavigationControl,{position:"top-right",showCompass:!1}),V.length>1&&a.jsx(o.Source,{id:"device-route",type:"geojson",data:{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:V.map((e=>[e.lng,e.lat]))}},children:a.jsx(o.Layer,{id:"route-line",type:"line",paint:{"line-color":"#61007D","line-width":3,"line-opacity":.8}})})]},`map-${M.current}`)})})]}):a.jsx("div",{className:i("flex items-center justify-center h-full",g),style:{height:e},children:a.jsxs("div",{className:"text-center",children:[a.jsx(l.AlertTriangle,{className:"w-8 h-8 text-amber-500 mx-auto mb-2"}),a.jsx("p",{className:"text-sm text-gray-600 dark:text-gray-400",children:"Mapbox access token is missing"})]})})}function x(e){const t=Math.floor(e/60),n=Math.floor(e%60);return`${t.toString().padStart(2,"0")}:${n.toString().padStart(2,"0")}`}function g(e,t,n){return e?t||[]:n||[]}const f={isLoading:(e,t)=>e||t,hasVideo:(e,t)=>Boolean(e&&!t),shouldShowMap:(e,t)=>e&&t,shouldShowEventComponent:(e,t)=>e&&t};function v({videoState:e,handlers:t,showControls:n,hasVideo:s,isLoading:r,onDownload:o,showMap:c=!1}){return n&&s&&!r&&e.showControls?a.jsx("div",{className:"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-4",children:a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx("button",{onClick:t.handlePlayPause,className:"p-2 rounded-md bg-white/20 text-white hover:bg-white/30 transition-colors",children:a.jsx(e.playing?l.Pause:l.Play,{size:20})}),a.jsxs("div",{className:"flex gap-1",children:[a.jsx("button",{onClick:()=>t.handleFrameStep("backward"),className:"p-1 rounded text-white/80 hover:text-white transition-colors",title:"Step backward 0.1s",children:a.jsx(l.SkipBack,{size:16})}),a.jsx("button",{onClick:()=>t.handleFrameStep("forward"),className:"p-1 rounded text-white/80 hover:text-white transition-colors",title:"Step forward 0.1s",children:a.jsx(l.SkipForward,{size:16})})]}),a.jsx("input",{type:"range",min:0,max:e.duration||0,value:e.currentTime,step:"0.1",onChange:t.handleSeek,className:"flex-1 h-2 bg-white/20 rounded-lg appearance-none cursor-pointer accent-white"}),a.jsxs("div",{className:"text-sm text-white font-mono min-w-[80px] text-right",children:[x(e.currentTime)," / ",x(e.duration)]}),a.jsx("button",{onClick:t.handleMute,className:"p-1 rounded text-white/80 hover:text-white transition-colors",children:a.jsx(e.muted?l.VolumeX:l.Volume2,{size:20})}),a.jsx("input",{type:"range",min:0,max:1,value:e.muted?0:e.volume,step:"0.01",onChange:t.handleVolumeChange,className:"w-20 h-1 bg-white/20 rounded-lg appearance-none cursor-pointer accent-white"}),a.jsxs("div",{className:"flex gap-1 border-l border-white/20 pl-3 ml-2",children:[o&&a.jsx("button",{onClick:o,className:"p-1 rounded text-white/80 hover:text-white transition-colors",title:"Download video",children:a.jsx(l.Download,{size:16})}),a.jsx("button",{onClick:t.handleToggleHorizontalFlip,className:i("p-1 rounded transition-colors",e.isHorizontalFlipped?"text-blue-400 hover:text-blue-300":"text-white/80 hover:text-white"),title:"Flip horizontally",children:a.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[a.jsx("path",{d:"M8 3H5a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h3"}),a.jsx("path",{d:"M16 3h3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-3"}),a.jsx("path",{d:"M12 20v2"}),a.jsx("path",{d:"M12 14v2"}),a.jsx("path",{d:"M12 8v2"}),a.jsx("path",{d:"M12 2v2"})]})}),a.jsx("button",{onClick:t.handleToggleVerticalFlip,className:i("p-1 rounded transition-colors mr-1",e.isVerticalFlipped?"text-blue-400 hover:text-blue-300":"text-white/80 hover:text-white"),title:"Flip vertically",children:a.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[a.jsx("path",{d:"M21 8V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v3"}),a.jsx("path",{d:"M21 16v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3"}),a.jsx("path",{d:"M4 12H2"}),a.jsx("path",{d:"M10 12H8"}),a.jsx("path",{d:"M16 12h-2"}),a.jsx("path",{d:"M22 12h-2"})]})}),c&&a.jsx("button",{onClick:t.handleToggleMap,className:i("p-1 rounded transition-colors mr-1",e.showMap?"text-blue-400 hover:text-blue-300":"text-white/80 hover:text-white"),title:"Toggle map",children:a.jsx(l.Map,{size:16})}),a.jsx("button",{onClick:t.handleFullscreen,className:"p-1 rounded text-white/80 hover:text-white transition-colors",title:"Toggle fullscreen",children:a.jsx(l.Maximize2,{size:16})})]})]})}):null}var y=(e=>(e.THUMBNAIL="thum",e.GPS="gps ",e.GSENSOR="3gf ",e.LTE="lte ",e))(y||{}),b=(e=>(e.NOT_STARTED="NOT_STARTED",e.SUCCESS="SUCCESS",e.NO_DATA="NO_DATA",e.INVALID_FORMAT="INVALID_FORMAT",e.DECODE_ERROR="DECODE_ERROR",e.ERROR="ERROR",e))(b||{});function w(e,t){if(!e||!t)return null;const n="N"===t||"S"===t?2:3,s=parseInt(e.slice(0,n),10),a=parseFloat(e.slice(n));if(isNaN(s)||isNaN(a))return null;let r=s+a/60;return"S"!==t&&"W"!==t||(r*=-1),r}function N(e){if(!e)return{status:b.NO_DATA,points:[]};let t;try{t=atob(e)}catch(l){throw new Error("Invalid base64 data: 디코딩에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.")}const n=t.split(/\r?\n|\r/).filter((e=>e.trim().length>0)),s=new Map;for(let o=0;n.length>o;o++){const e=n[o].trim().match(/^\[(\d+)\]\$(\w+),(.*)$/);if(!e)continue;const[,t,a,r]=e,l=Number(t)/1e3,i=r.split(",");if("GPGGA"===a||"GNGGA"===a){const e=w(i[1],i[2]),t=w(i[3],i[4]);if(null!==e&&null!==t&&!isNaN(e)&&!isNaN(t))if(s.has(l)){const n=s.get(l);s.set(l,{...n,lat:e,lng:t})}else s.set(l,{timestamp:l,lat:e,lng:t,relativeTime:0,speedKnots:null,speedKmh:null,course:null})}else if("GPRMC"===a||"GNRMC"===a){if("A"!==i[1])continue;const e=i[6]?parseFloat(i[6]):null,t=i[7]?parseFloat(i[7]):null,n=null===e||isNaN(e)?null:1.852*e;if(s.has(l)){const a=s.get(l);s.set(l,{...a,speedKnots:isNaN(e??NaN)?null:e,speedKmh:n,course:isNaN(t??NaN)?null:t})}else s.set(l,{timestamp:l,lat:null,lng:null,relativeTime:0,speedKnots:isNaN(e??NaN)?null:e,speedKmh:n,course:isNaN(t??NaN)?null:t})}}const a=Array.from(s.values()).sort(((e,t)=>e.timestamp-t.timestamp));if(0===a.length)return{status:b.NO_DATA,points:[]};const r=a[0].timestamp;return a.forEach((e=>{e.relativeTime=e.timestamp-r})),{status:b.SUCCESS,points:a}}var j=(e=>(e.NOT_STARTED="NOT_STARTED",e.SUCCESS="SUCCESS",e.NO_DATA="NO_DATA",e.INVALID_FORMAT="INVALID_FORMAT",e.DECODE_ERROR="DECODE_ERROR",e.ERROR="ERROR",e))(j||{});function M(e){if(!e)return{status:j.NO_DATA,points:[]};try{const t=function(e){const t=60,n=function(e){if("undefined"!=typeof window&&"function"==typeof window.atob){const t=window.atob(e.replace(/\s/g,"")),n=t.length,s=new Uint8Array(n);for(let e=0;n>e;e++)s[e]=t.charCodeAt(e);return s}if("undefined"!=typeof Buffer)return new Uint8Array(Buffer.from(e,"base64"));throw new Error("Base64 decode not supported in this environment")}(e),s=new DataView(n.buffer),a=[];let r=[];const l=[],o=[],i=[];function c(e,t,n=10){e.push(t),e.length>n&&e.shift()}function u(e){return 0===e.length?0:e.reduce(((e,t)=>e+t),0)/e.length}for(let x=0;n.length>x;){const e=Math.floor(s.getUint32(x,!1)/100)/10;if(e>t)break;x+=4;const n=s.getInt16(x,!1),a=Math.max(Math.min(n,255),-255);x+=2;const l=s.getInt16(x,!1),o=Math.max(Math.min(l,255),-255);x+=2;const i=s.getInt16(x,!1),c=Math.max(Math.min(i,255),-255);x+=2,r.push({timestamp:e,x:a,y:o,z:c})}if(580>r.length){const e=r[r.length-1],t=60-((null==e?void 0:e.timestamp)??60)+2;r=r.map((e=>({...e,timestamp:t+e.timestamp})))}const d=r.filter((e=>null!==e.x&&null!==e.y&&null!==e.z)),h=u(d.map((e=>e.x))),m=u(d.map((e=>e.y))),p=u(d.map((e=>e.z)));r=r.map((e=>({timestamp:e.timestamp,x:null!==e.x?e.x-h:null,y:null!==e.y?e.y-m:null,z:null!==e.z?e.z-p:null})));for(const x of r){const e=Math.floor(x.timestamp),{x:t,y:n,z:s}=x;if(null!==t&&null!==n&&null!==s)if(a[e]){const r=a[e];a[e]={timestamp:e,x:null!==r.x&&Math.abs(r.x)<Math.abs(t)?t:r.x,y:null!==r.y&&Math.abs(r.y)<Math.abs(n)?n:r.y,z:null!==r.z&&Math.abs(r.z)<Math.abs(s)?s:r.z}}else a[e]={timestamp:e,x:t,y:n,z:s}}for(const x of r){const e=Math.floor(x.timestamp),{x:t,y:n,z:s}=x;if(null!==t&&null!==n&&null!==s){const r=t-u(l),d=n-u(o),h=s-u(i);if(a[e]){const t=a[e];a[e]={timestamp:e,x:null!==t.x&&Math.abs(t.x)<Math.abs(r)?r:t.x,y:null!==t.y&&Math.abs(t.y)<Math.abs(d)?d:t.y,z:null!==t.z&&Math.abs(t.z)<Math.abs(h)?h:t.z}}else a[e]={timestamp:e,x:r,y:d,z:h};c(l,t),c(o,n),c(i,s)}}return a.filter(Boolean).sort(((e,t)=>e.timestamp-t.timestamp))}(e);return{status:j.SUCCESS,points:t}}catch(t){return t instanceof Error&&t.message.includes("Base64")?{status:j.DECODE_ERROR,points:[]}:{status:j.ERROR,points:[]}}}const E=1048576;async function S(e){try{const t=new AbortController;let n;if(n=await fetch(e,{method:"GET",mode:"cors",credentials:"omit",cache:"no-cache",headers:{Range:"bytes=0-1048575"},signal:t.signal}),n.ok||416!==n.status){if(!n.ok)throw new Error(`Failed to fetch MP4 file: ${n.status} ${n.statusText}`)}else if(t.abort(),n=await fetch(e,{method:"GET",mode:"cors",credentials:"omit",cache:"no-cache"}),!n.ok)throw new Error(`Failed to fetch MP4 file: ${n.status} ${n.statusText}`);const s=await n.blob(),a=new File([s],"video.mp4",{type:"video/mp4"});return await T(a)}catch(t){return{gps:{status:b.ERROR,points:[]},sensor:{status:j.ERROR,points:[]},thumbnail:null}}}async function k(e){const t=Math.min(E,e.size);try{const n=await function(e,t,n){return new Promise(((s,a)=>{const r=new FileReader;r.onload=()=>{r.result instanceof ArrayBuffer?s(r.result):a(new Error("Failed to read file as ArrayBuffer"))},r.onerror=()=>{a(new Error("Error reading file"))};const l=e.slice(t,n);r.readAsArrayBuffer(l)}))}(e,0,t),s=function(e){const t=new DataView(e);let n=0;for(;e.byteLength-8>n;)try{const e=t.getUint32(n,!1);if("free"===String.fromCharCode(t.getUint8(n+4),t.getUint8(n+5),t.getUint8(n+6),t.getUint8(n+7)))return n+8;if(0===e)break;n+=8>e?8:e}catch(s){n+=8}return-1}(n);if(-1===s)return{success:!1,error:"No user data found in MP4 file (free box not found)"};const a=function(e,t){const n=new DataView(e),s=[];let a=t;const r={[y.THUMBNAIL]:81928,[y.GPS]:163848,[y.GSENSOR]:61448,[y.LTE]:61448};for(;e.byteLength-8>a;)try{if(a+8>e.byteLength)break;const t=n.getUint32(a,!1),l=String.fromCharCode(n.getUint8(a+4),n.getUint8(a+5),n.getUint8(a+6),n.getUint8(a+7));if(Object.values(y).includes(l)){const n=l;if(t===r[n]){const r=a+8,l=t-8;if(e.byteLength>=r+l){const t=e.slice(r,r+l);s.push({type:n,size:l,data:t})}}}if(0===t)break;a+=8>t?8:t}catch(l){a+=8}return s}(n,s);if(0===a.length)return{success:!1,error:"No valid data chunks found in MP4 file"};const r={};return a.forEach((e=>{switch(e.type){case y.THUMBNAIL:r.thumbnail=e;break;case y.GPS:r.gps=e;break;case y.GSENSOR:r.gSensor=e;break;case y.LTE:r.lte=e}})),{success:!0,data:r}}catch(n){return{success:!1,error:n instanceof Error?n.message:"Unknown error parsing MP4 file"}}}async function T(e){Math.min(E,e.size);try{const n=await k(e);if(!n.success||!n.data)return{gps:null,sensor:null,thumbnail:null};let s=null;if(n.data.gps)try{const e=(new TextDecoder).decode(n.data.gps.data);s=N(btoa(e))}catch(t){s={status:b.ERROR,points:[]}}let a=null;if(n.data.gSensor)try{const e=new Uint8Array(n.data.gSensor.data);a=M(btoa(Array.from(e).map((e=>String.fromCharCode(e))).join("")))}catch(t){}let r=null;if(n.data.thumbnail)try{const e=new Blob([n.data.thumbnail.data],{type:"image/jpeg"});r=URL.createObjectURL(e)}catch(t){}return{gps:s,sensor:a,thumbnail:r}}catch(t){return{gps:null,sensor:null,thumbnail:null}}}const C="FleetA Components";e.EventComponent=h,e.GpsParsingStatus=b,e.LIBRARY_NAME=C,e.MAP_STYLES=u,e.MapComponent=p,e.SensorParsingStatus=j,e.VERSION="1.0.0",e.VehicleMarker=c,e.VideoPlayer=function({videoUrl:e,autoPlay:t=!0,showControls:n=!0,className:s,onTimeUpdate:o,onDurationChange:c,onPlay:u,onPause:d,onEnded:h,onError:m,onDownload:x,initialHorizontalFlip:y=!1,initialVerticalFlip:b=!1,loading:w=!1,loadingMessage:N="Loading video...",showMap:j=!1,showEventComponent:M=!0,mapPosition:E=null,gpsPoints:k=[],sensorData:T=null,mapHeight:C="200px",speedUnit:R="km/h",enableMetadataParsing:P=!1,mapStyle:L}){const z=r.useRef(null),A=r.useRef(null),[F,D]=function(e){const{initialHorizontalFlip:t=!1,initialVerticalFlip:n=!1,showMap:s=!1,showEventComponent:a=!0}=e,[l,o]=r.useState({playing:!1,muted:!1,volume:1,currentTime:0,duration:0,loading:!1,error:null,isHorizontalFlipped:t,isVerticalFlipped:n,showMap:s,showEventComponent:a,showControls:!1,controlsTimer:null,autoParsedGpsPoints:null,autoParsedSensorData:null,parsingInProgress:!1});return[l,o]}({initialHorizontalFlip:y,initialVerticalFlip:b,showMap:j,showEventComponent:M});!function(e,t,n){r.useEffect((()=>{e&&t?(async()=>{var e,s;n((e=>({...e,parsingInProgress:!0,autoParsedGpsPoints:null,autoParsedSensorData:null})));try{const a=await S(t),r=(null==(e=a.gps)?void 0:e.points)||[],l=(null==(s=a.sensor)?void 0:s.points)||[];n((e=>({...e,autoParsedGpsPoints:r,autoParsedSensorData:l,parsingInProgress:!1})))}catch(a){n((e=>({...e,autoParsedGpsPoints:[],autoParsedSensorData:[],parsingInProgress:!1})))}})():n((e=>({...e,autoParsedGpsPoints:[],autoParsedSensorData:[],parsingInProgress:!1})))}),[e,t,n])}(P||!1,e,D),function(e,t,n,s,a,l){r.useEffect((()=>{if(e&&n.current){const r=n.current;let o;if(a((e=>({...e,loading:!0,error:null,playing:!1,currentTime:0,duration:0}))),r.src=e,r.muted=s.muted,r.load(),t){const e=()=>{r.paused&&(r.muted=!0,o=r.play().then((()=>{a((e=>({...e,playing:!0}))),null==l||l()})).catch((e=>{a((e=>({...e,playing:!1,error:"Autoplay failed. Click play button to start."})))}))),r.removeEventListener("canplaythrough",e)};return r.addEventListener("canplaythrough",e),()=>{void 0!==o&&o.then((()=>{r.pause()})).catch((()=>{})),r.removeEventListener("canplaythrough",e)}}}}),[e,t,l,s.muted,n,a])}(e,t||!1,z,F,D,u),function(e,t,n,s,a,l,o,i){r.useEffect((()=>{const r=e.current;if(!r)return;const c=()=>{const e=r.duration||0;t((t=>({...t,duration:e,loading:!1}))),null==s||s(e)},u=()=>{const e=r.currentTime||0;t((t=>.1>Math.abs(t.currentTime-e)?t:{...t,currentTime:e})),null==n||n(e)},d=()=>{t((e=>({...e,playing:!0}))),null==a||a()},h=()=>{t((e=>({...e,playing:!1}))),null==l||l()},m=()=>{t((e=>({...e,playing:!1}))),null==o||o()},p=()=>{const e="Video playback error occurred";t((t=>({...t,error:e,loading:!1,playing:!1}))),null==i||i(e)},x=()=>{t((e=>({...e,loading:!0})))},g=()=>{t((e=>({...e,loading:!1})))};return r.addEventListener("loadedmetadata",c),r.addEventListener("timeupdate",u),r.addEventListener("play",d),r.addEventListener("pause",h),r.addEventListener("ended",m),r.addEventListener("error",p),r.addEventListener("loadstart",x),r.addEventListener("canplay",g),()=>{r.removeEventListener("loadedmetadata",c),r.removeEventListener("timeupdate",u),r.removeEventListener("play",d),r.removeEventListener("pause",h),r.removeEventListener("ended",m),r.removeEventListener("error",p),r.removeEventListener("loadstart",x),r.removeEventListener("canplay",g)}}),[e,t,n,s,a,l,o,i])}(z,D,o,c,u,d,h,m),function(e,t){r.useEffect((()=>{if(e){t((e=>({...e,showControls:!0})));const e=setTimeout((()=>{t((e=>({...e,showControls:!1})))}),4e3);return()=>{clearTimeout(e)}}}),[e,t])}(e,D),function(e,t,n){r.useEffect((()=>{const n=e.current;n&&n.muted!==t&&(n.muted=t)}),[t,n,e])}(z,F.muted,e),function(e,t,n){r.useEffect((()=>{n((n=>({...n,showMap:e,showEventComponent:t})))}),[e,t,n])}(j||!1,M||!1,D);const O=function(e,t,n,s,a){return{handlePlayPause:()=>{const t=e.current;t&&(t.paused?t.play().catch((e=>{const t="Failed to play video";s((e=>({...e,error:t}))),null==a||a(t)})):2>t.readyState||t.pause())},handleSeek:t=>{const a=e.current,r=Number(t.target.value);!a||isNaN(r)||0>r||r>n.duration||2>a.readyState||(a.currentTime=r,s((e=>({...e,currentTime:r}))))},handleVolumeChange:t=>{const n=e.current,a=Number(t.target.value);n&&(n.volume=a,s((e=>({...e,volume:a,muted:0===a}))))},handleMute:()=>{const t=e.current;t&&s((e=>{const n=!e.muted;return t.muted=n,{...e,muted:n}}))},handleFullscreen:()=>{const e=t.current;!document.fullscreenElement&&(null==e?void 0:e.requestFullscreen)?e.requestFullscreen().catch((e=>{})):document.fullscreenElement&&document.exitFullscreen&&document.exitFullscreen().catch((e=>{}))},handleFrameStep:t=>{const a=e.current;if(!a||2>a.readyState)return;const r="forward"===t?Math.min(n.duration,n.currentTime+.1):Math.max(0,n.currentTime-.1);a.currentTime=r,s((e=>({...e,currentTime:r})))},handleToggleHorizontalFlip:()=>{s((e=>({...e,isHorizontalFlipped:!e.isHorizontalFlipped})))},handleToggleVerticalFlip:()=>{s((e=>({...e,isVerticalFlipped:!e.isVerticalFlipped})))},handleToggleMap:()=>{s((e=>({...e,showMap:!e.showMap})))},handleMouseEnter:()=>{s((e=>({...e,showControls:!0})))},handleMouseLeave:()=>{s((e=>({...e,showControls:!1})))}}}(z,A,F,D,m),U=f.isLoading(w||!1,F.loading),V=F.error,G=f.hasVideo(e,!!V),I=f.shouldShowMap(F.showMap,G),_=f.shouldShowEventComponent(F.showEventComponent,G),B=g(P||!1,F.autoParsedGpsPoints,k),H=g(P||!1,F.autoParsedSensorData,T),$=function(e,t){const n=[];return e&&n.push("scaleX(-1)"),t&&n.push("scaleY(-1)"),n.join(" ")}(F.isHorizontalFlipped,F.isVerticalFlipped),K=function(e){return e?"h-[calc(100%-200px)]":"h-full"}(I);return a.jsxs("div",{ref:A,onMouseOver:O.handleMouseEnter,onMouseOut:O.handleMouseLeave,className:i("relative w-full h-full bg-black rounded overflow-hidden flex flex-col",s),children:[a.jsxs("div",{className:i("relative flex-1 min-h-0",K),children:[G&&a.jsx("video",{ref:z,className:"w-full h-full object-contain",preload:"auto",playsInline:!0,muted:t,style:{transform:$},onClick:O.handlePlayPause,onLoadStart:()=>D((e=>({...e,loading:!0}))),onCanPlay:()=>D((e=>({...e,loading:!1}))),onError:e=>{const t="Video failed to load. Please check the URL or try a different video.";D((e=>({...e,error:t,loading:!1}))),null==m||m(t)}}),(U||F.parsingInProgress)&&!G&&a.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-black/80",children:a.jsxs("div",{className:"text-center text-white",children:[a.jsx(l.Loader2,{size:48,className:"mx-auto mb-4 animate-spin"}),a.jsx("p",{className:"text-lg",children:F.parsingInProgress?"Parsing video metadata...":N})]})}),V&&a.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-black/80",children:a.jsxs("div",{className:"text-center text-red-400 p-8",children:[a.jsx("p",{className:"text-lg mb-2",children:"Playback Error"}),a.jsx("p",{className:"text-sm",children:F.error})]})}),!G&&!U&&!V&&a.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-900",children:a.jsxs("div",{className:"text-center text-gray-400",children:[a.jsx(l.Play,{size:48,className:"mx-auto mb-4 opacity-50"}),a.jsx("p",{className:"text-lg",children:"No video loaded"})]})}),a.jsx(v,{videoState:F,handlers:O,showControls:n||!1,hasVideo:G,isLoading:U,onDownload:x,showMap:j})]}),F.showMap&&a.jsx("div",{className:"border-t border-gray-800 overflow-hidden rounded-b-lg h-[300px] bg-gray-900 relative",children:a.jsx(p,{height:"100%",gpsPoints:B,currentTime:F.currentTime,className:"w-full h-full",sensorData:H,showEventComponent:_||!1,videoDuration:F.duration||60,speedUnit:R,mapStyle:L},`map-${e}`)})]})},e.cn=i,e.default=C,e.extractMetadata=T,e.fetchAndParseMP4=S,e.parseGpsData=N,e.parseMP4UserData=k,e.parseSensorData=M,e.useMapStyleStore=d,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})})); //# sourceMappingURL=index.umd.js.map