{
  "!starter": {
    "scope": "html",
    "prefix": "!starter",
    "description": "Full manifest: page shell + map + layer + click overlay + legend",
    "body": [
      "<!DOCTYPE html>",
      "<html>",
      "<head>",
      "  <meta charset=\"utf-8\" />",
      "  <title>${1:My map}</title>",
      "  <script type=\"module\">",
      "    import \"@nika-js/onlymap\";",
      "    import \"@nika-js/onlymap/onlymapjs.css\";",
      "  </script>",
      "  <style>",
      "    html, body { margin: 0; height: 100%; }",
      "    om-map { display: block; height: 100vh; }",
      "  </style>",
      "</head>",
      "<body>",
      "",
      "  <!-- validate → live error panel while you hand-author (strip for production); map-id identifies this map artifact (delete to opt out of telemetry dedup) -->",
      "  <om-map center=\"[-122.42, 37.77]\" zoom=\"${2:11}\" basemap=\"maplibre\" map-id=\"$UUID\" validate>",
      "",
      "    <!-- One data layer: type + data URL + accessors. pickable → behaviors can fire. -->",
      "    <om-layer id=\"${3:points}\" type=\"ScatterplotLayer\"",
      "                data=\"${4:../data/bikes.json}\"",
      "                label=\"${5:Points}\" color=\"${6:#e63946}\"",
      "                get-position=\"[\\$lon, \\$lat]\"",
      "                radius=\"${7:6}\" radius-units=\"pixels\"",
      "                pickable></om-layer>",
      "",
      "    <!-- Rich HTML popup — follows the last click via anchor-from=\"selection\" -->",
      "    <om-overlay id=\"${3:points}-detail\" anchor-from=\"selection\" visible=\"false\">",
      "      <div class=\"popup\"><strong>{{name}}</strong></div>",
      "    </om-overlay>",
      "    <om-behavior on=\"click\" layer=\"${3:points}\" action=\"show-overlay\"",
      "                   target=\"${3:points}-detail\"></om-behavior>",
      "",
      "    <!-- Built-in legend — reads label/color from each <om-layer> -->",
      "    <om-widget type=\"legend\" title=\"Layers\" position=\"top-right\"></om-widget>",
      "",
      "    <!-- Shown only where scripts never run (chat-app/email file previews) — hidden once the map boots -->",
      "    <om-fallback>",
      "      <p>This interactive map requires JavaScript.<br />Open this file in a web browser such as Chrome, Safari, or Firefox.</p>",
      "    </om-fallback>",
      "",
      "  </om-map>",
      "",
      "</body>",
      "</html>",
      "$0"
    ]
  },

  "!page": {
    "scope": "html",
    "prefix": "!page",
    "description": "HTML page shell that loads OnlyMapJS from npm",
    "body": [
      "<!DOCTYPE html>",
      "<html>",
      "<head>",
      "  <meta charset=\"utf-8\" />",
      "  <title>${1:My map}</title>",
      "  <script type=\"module\">",
      "    import \"@nika-js/onlymap\";",
      "    import \"@nika-js/onlymap/onlymapjs.css\";",
      "  </script>",
      "  <style>",
      "    html, body { margin: 0; height: 100%; }",
      "    om-map { display: block; height: 100vh; }",
      "  </style>",
      "</head>",
      "<body>",
      "",
      "  $0",
      "",
      "</body>",
      "</html>"
    ]
  },

  "!map": {
    "scope": "html",
    "prefix": "!map",
    "description": "<om-map> root with camera + basemap + validate",
    "body": [
      "<!-- validate → on-page error panel; basemap=\"maplibre\" needs no token; map-id identifies this map artifact (delete to opt out of telemetry dedup) -->",
      "<om-map center=\"[-122.42, 37.77]\" zoom=\"${1:11}\" basemap=\"maplibre\" map-id=\"$UUID\" validate>",
      "",
      "  $0",
      "",
      "  <!-- Shown only where scripts never run (chat-app/email file previews) -->",
      "  <om-fallback>",
      "    <p>This interactive map requires JavaScript — open this file in a web browser.</p>",
      "  </om-fallback>",
      "",
      "</om-map>"
    ]
  },

  "!layer": {
    "scope": "html",
    "prefix": "!layer",
    "description": "ScatterplotLayer — points from a data URL",
    "body": [
      "<!-- data: JSON/GeoJSON/CSV URL, or use a <script type=\"application/json\"> child -->",
      "<om-layer id=\"${1:points}\" type=\"ScatterplotLayer\"",
      "            data=\"${2:../data/bikes.json}\"",
      "            label=\"${3:Points}\" color=\"${4:#e63946}\"",
      "            get-position=\"[\\$lon, \\$lat]\"",
      "            radius=\"${5:6}\" radius-units=\"pixels\"",
      "            pickable></om-layer>$0"
    ]
  },

  "!geojson": {
    "scope": "html",
    "prefix": "!geojson",
    "description": "GeoJsonLayer — polygons/lines from GeoJSON",
    "body": [
      "<om-layer id=\"${1:regions}\" type=\"GeoJsonLayer\"",
      "            data=\"${2:../data/regions.geojson}\"",
      "            label=\"${3:Regions}\" color=\"${4:#3388ff}\"",
      "            filled stroked pickable",
      "            get-line-color=\"[20,20,20]\"",
      "            line-width-min-pixels=\"2\"></om-layer>$0"
    ]
  },

  "!raster": {
    "scope": "html",
    "prefix": "!raster",
    "description": "COGLayer — GeoTIFF/COG raster (src streams by Range request; set min/max for float data)",
    "body": [
      "<om-layer id=\"${1:dem}\" type=\"COGLayer\"",
      "            src=\"${2:../data/elevation.tif}\"",
      "            label=\"${3:Elevation}\"",
      "            min=\"${4:0}\" max=\"${5:1900}\" colormap=\"${6|viridis,gray,plasma,inferno,magma,cividis,rdylgn,rdbu,spectral,terrain,jet,turbo|}\"",
      "            opacity=\"0.85\"></om-layer>$0"
    ]
  },

  "!overlay": {
    "scope": "html",
    "prefix": "!overlay",
    "description": "<om-overlay> popup + click behavior wired to a layer",
    "body": [
      "<!-- {{field}} interpolates the picked feature; HTML-escaped by default -->",
      "<om-overlay id=\"${1:detail}\" anchor-from=\"selection\" visible=\"false\">",
      "  <div class=\"popup\"><strong>{{${2:name}}}</strong></div>",
      "</om-overlay>",
      "<om-behavior on=\"click\" layer=\"${3:points}\" action=\"show-overlay\"",
      "               target=\"${1:detail}\"></om-behavior>$0"
    ]
  },

  "!legend": {
    "scope": "html",
    "prefix": "!legend",
    "description": "Built-in legend widget",
    "body": [
      "<om-widget type=\"legend\" title=\"${1:Layers}\" position=\"${2|top-right,top-left,bottom-right,bottom-left|}\"></om-widget>$0"
    ]
  },

  "!draw": {
    "scope": "html",
    "prefix": "!draw",
    "description": "Manual drawing: sketch layer + capture toolbar",
    "body": [
      "<om-layer id=\"${1:sketch}\" type=\"GeoJsonLayer\" data=\"draw:${1:sketch}\"",
      "            get-fill-color=\"[80, 140, 255, 90]\" get-line-color=\"[40, 90, 220]\"",
      "            point-radius-min-pixels=\"6\" line-width-min-pixels=\"3\" stroked filled pickable></om-layer>",
      "<om-widget type=\"draw\" target=\"${1:sketch}\" position=\"${2|top-left,top-right,bottom-left,bottom-right|}\"",
      "             modes=\"${3:point line polygon}\" save=\"${4|both,download,file-system|}\"></om-widget>$0"
    ]
  },

  "!behavior": {
    "scope": "html",
    "prefix": "!behavior",
    "description": "Declarative <om-behavior> (click / hover / load / …)",
    "body": [
      "<om-behavior on=\"${1|click,hover,drag,load,data-loaded|}\" layer=\"${2:points}\"",
      "               action=\"${3|show-overlay,hide-overlay,show-tooltip,hide-tooltip,toggle-layer,filter-layer,highlight-feature,zoom-to-feature|}\"",
      "               target=\"${4:detail}\"></om-behavior>$0"
    ]
  },

  "!fallback": {
    "scope": "html",
    "prefix": "!fallback",
    "description": "<om-fallback> — no-JS fallback for shared/previewed files (hidden once the map boots)",
    "body": [
      "<!-- Shown only where scripts never run (chat-app/email file previews, iOS QuickLook) -->",
      "<om-fallback>",
      "  <p>${1:This interactive map requires JavaScript.}<br />",
      "     ${2:Open this file in a web browser such as Chrome, Safari, or Firefox.}</p>",
      "</om-fallback>$0"
    ]
  },

  "!inline-data": {
    "scope": "html",
    "prefix": "!inline-data",
    "description": "Inline JSON data child (zero network requests — good for demos/tests)",
    "body": [
      "<script type=\"application/json\">",
      "[",
      "  { \"id\": \"a\", \"name\": \"Alpha\", \"lon\": -122.42, \"lat\": 37.77, \"value\": 3 }",
      "  $0",
      "]",
      "</script>"
    ]
  }
}
