{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "maritime-vessel-map",
  "title": "Maritime Vessel Map",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/maritime-vessel-map/MaritimeVesselMap.tsx",
      "content": "'use client'\n\nimport { useState, useRef } from 'react'\nimport { Map, MapMarker, type MapRef } from '@/components/ui/map'\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\n\nexport interface Vessel {\n  mmsi: string\n  name: string\n  flag: string\n  type: 'Container' | 'Crude Tanker' | 'Bulk Carrier' | 'Tug'\n  coords: [number, number]\n  heading: number\n  speedKnots: number\n  draught: string\n  dest: string\n  eta: string\n  status: 'Underway' | 'Moored' | 'At Anchor'\n}\n\nexport interface MaritimeVesselMapProps {\n  accessToken?: string\n}\n\nexport function MaritimeVesselMap({ accessToken }: MaritimeVesselMapProps) {\n  const mapRef = useRef<MapRef | null>(null)\n\n  const vessels: Vessel[] = [\n    {\n      mmsi: '219018442',\n      name: 'EVER GIVEN',\n      flag: 'PA',\n      type: 'Container',\n      coords: [103.78, 1.25],\n      heading: 110,\n      speedKnots: 14.8,\n      draught: '15.7m',\n      dest: 'SGSIN PEB',\n      eta: 'OCT 24 14:00',\n      status: 'Underway',\n    },\n    {\n      mmsi: '636019812',\n      name: 'NORDIC STAR',\n      flag: 'LR',\n      type: 'Crude Tanker',\n      coords: [103.88, 1.22],\n      heading: 245,\n      speedKnots: 0.2,\n      draught: '12.1m',\n      dest: 'SINGAPORE ANCH',\n      eta: 'OCT 24 08:30',\n      status: 'At Anchor',\n    },\n    {\n      mmsi: '356782000',\n      name: 'PACIFIC RUBY',\n      flag: 'SG',\n      type: 'Bulk Carrier',\n      coords: [103.95, 1.29],\n      heading: 45,\n      speedKnots: 11.2,\n      draught: '10.4m',\n      dest: 'JPTYO',\n      eta: 'OCT 29 06:00',\n      status: 'Underway',\n    },\n    {\n      mmsi: '508111222',\n      name: 'HARBOR VALIANT',\n      flag: 'SG',\n      type: 'Tug',\n      coords: [103.75, 1.28],\n      heading: 180,\n      speedKnots: 6.4,\n      draught: '4.5m',\n      dest: 'PASIR PANJANG',\n      eta: 'OCT 24 12:00',\n      status: 'Underway',\n    },\n  ]\n\n  const [activeVessel, setActiveVessel] = useState<Vessel>(vessels[0])\n\n  const selectVessel = (v: Vessel) => {\n    setActiveVessel(v)\n    mapRef.current?.flyTo({ center: v.coords, zoom: 11.5 })\n  }\n\n  return (\n    <div className=\"grid gap-4 lg:grid-cols-[1fr_320px]\">\n      <div className=\"border-border bg-card relative h-[480px] overflow-hidden rounded-xl border\">\n        <Map\n          ref={mapRef}\n          accessToken={accessToken}\n          variant=\"dark\"\n          center={activeVessel.coords}\n          zoom={10.8}\n          className=\"h-full w-full\"\n        >\n          {vessels.map((v) => (\n            <MapMarker key={v.mmsi} lngLat={v.coords} anchor=\"center\" onClick={() => selectVessel(v)}>\n              <div className=\"group relative flex cursor-pointer flex-col items-center\">\n                <div\n                  className={`flex size-7 items-center justify-center rounded-full font-bold text-cyan-400 ${\n                    activeVessel.mmsi === v.mmsi ? 'bg-cyan-500/20 ring-2 ring-cyan-400' : 'bg-background/80'\n                  }`}\n                  style={{ transform: `rotate(${v.heading}deg)` }}\n                >\n                  ▲\n                </div>\n                <span\n                  className={`border-border bg-card/90 mt-1 rounded border px-1 py-0.5 font-mono text-xs font-semibold tracking-wider whitespace-nowrap shadow-xs ${\n                    activeVessel.mmsi === v.mmsi ? 'border-cyan-400/50 text-cyan-400' : 'text-foreground'\n                  }`}\n                >\n                  {{ v: v.name }['v']}\n                </span>\n              </div>\n            </MapMarker>\n          ))}\n        </Map>\n      </div>\n\n      {/* AIS Telemetry Drawer */}\n      <Card className=\"flex flex-col justify-between\">\n        <CardHeader>\n          <div className=\"flex items-center justify-between\">\n            <Badge variant=\"outline\" className=\"font-mono text-xs\">\n              {activeVessel.type}\n            </Badge>\n            <Badge className=\"border-cyan-500/20 bg-cyan-500/10 text-cyan-600 dark:text-cyan-400\">\n              {activeVessel.status}\n            </Badge>\n          </div>\n          <CardTitle className=\"mt-2 font-mono text-lg\">{activeVessel.name}</CardTitle>\n          <CardDescription className=\"font-mono text-xs\">\n            MMSI: {activeVessel.mmsi} • Flag: {activeVessel.flag}\n          </CardDescription>\n        </CardHeader>\n        <CardContent className=\"space-y-4\">\n          <div className=\"border-border bg-muted/40 grid grid-cols-2 gap-2 rounded-lg border p-2.5 font-mono text-xs\">\n            <div>\n              <div className=\"text-muted-foreground text-xs uppercase\">Speed Over Ground</div>\n              <div className=\"text-foreground text-sm font-bold\">{activeVessel.speedKnots} kts</div>\n            </div>\n            <div>\n              <div className=\"text-muted-foreground text-xs uppercase\">Heading</div>\n              <div className=\"text-foreground text-sm font-bold\">{activeVessel.heading}°</div>\n            </div>\n            <div className=\"mt-2\">\n              <div className=\"text-muted-foreground text-xs uppercase\">Max Draught</div>\n              <div className=\"text-foreground text-sm font-bold\">{activeVessel.draught}</div>\n            </div>\n            <div className=\"mt-2\">\n              <div className=\"text-muted-foreground text-xs uppercase\">Destination</div>\n              <div className=\"text-foreground truncate text-xs font-bold\">{activeVessel.dest}</div>\n            </div>\n          </div>\n\n          <div className=\"border-border space-y-1 border-t pt-3\">\n            <div className=\"text-muted-foreground mb-1 font-mono text-xs tracking-wider uppercase\">\n              Singapore Strait Traffic\n            </div>\n            {vessels.map((v) => (\n              <button\n                key={v.mmsi}\n                type=\"button\"\n                className={`flex w-full items-center justify-between rounded-md px-2 py-1 text-xs transition-colors ${\n                  activeVessel.mmsi === v.mmsi\n                    ? 'bg-accent text-accent-foreground font-semibold'\n                    : 'hover:bg-muted text-muted-foreground'\n                }`}\n                onClick={() => selectVessel(v)}\n              >\n                <span className=\"font-mono\">{v.name}</span>\n                <span className=\"font-mono text-xs opacity-75\">{v.speedKnots} kts</span>\n              </button>\n            ))}\n          </div>\n\n          <Button\n            variant=\"outline\"\n            size=\"sm\"\n            className=\"w-full font-mono text-xs\"\n            onClick={() => selectVessel(activeVessel)}\n          >\n            Center on Vessel\n          </Button>\n        </CardContent>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/MaritimeVesselMap.tsx"
    }
  ],
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/map.json"
  ],
  "description": "Automatic Identification System (AIS) vessel tracking with container ships, tankers, speed, and anchorage status.",
  "categories": [
    "logistics",
    "maritime",
    "map"
  ]
}