Files
maptool/public/js/icons.js
T
randy b4a1c6c0cc
CI / check (push) Successful in 19s
CI / deploy (push) Successful in 13s
Add a search box, matching NPS's Park Tiles viewer
Top-left map control (topmost, above Home/zoom) with a text input:
"lat, lng" is parsed and jumped to directly (same plain-text shape the
topbar's coordinate readout already copies to the clipboard), anything
else is geocoded via Nominatim — OSM's own geocoder, free, no API key,
matching the online basemap's own OSM-derived style. Online only, same
story as this app's other non-basemap online features (Radar, the
Wikipedia layer) — no offline geocoding index to fall back to.
2026-09-10 23:59:35 +02:00

430 lines
34 KiB
JavaScript

// Small hand-authored monoline SVG icons for the sidebar, so the app
// doesn't need to vendor an icon font/library for four glyphs.
export const LAYERS_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round">
<path d="M12 3 2 9l10 6 10-6-10-6z"/>
<path d="M2 14l10 6 10-6"/>
</svg>`;
// Two overlapping circles — distinct from LAYERS_ICON's stacked-planes
// look (that one picks a *base* map; this one is for the sidebar flyout
// toggling live overlay layers, e.g. Wikipedia, on top of whichever base
// map is showing) while still reading as "layers combining."
export const OVERLAYS_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round">
<circle cx="9" cy="12" r="6"/>
<circle cx="15" cy="12" r="6"/>
</svg>`;
export const NOTE_PIN_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 21s7-7.58 7-12a7 7 0 0 0-14 0c0 4.42 7 12 7 12z"/>
<path d="M12 6.5v5M9.5 9h5"/>
</svg>`;
export const GPX_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="5" cy="6" r="2"/>
<circle cx="19" cy="18" r="2"/>
<path d="M6.5 7.5C10 11 8 13 12 13s2 5 6.5 5"/>
</svg>`;
export const GNSS_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round">
<circle cx="12" cy="12" r="5.5"/>
<circle cx="12" cy="12" r="1.4" fill="currentColor" stroke="none"/>
<path d="M12 2v3M12 19v3M2 12h3M19 12h3"/>
</svg>`;
export const RULER_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round">
<path d="M4 15 15 4l5 5-11 11-5-5z"/>
<path d="M9 10l1.5 1.5M12 7l1.5 1.5M15 4l1.5 1.5M6 13l1.5 1.5"/>
</svg>`;
// Toolbar readout glyphs (public/js/sun.js's text, assembled with these by
// map.js) — same monoline style as the sidebar icons above, no NPS source
// for either (that set has no sunrise/sunset pictogram).
export const SUNRISE_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 18h18"/>
<path d="M6 18a6 6 0 0 1 12 0"/>
<path d="M12 13V5"/>
<path d="M9 8l3-3 3 3"/>
</svg>`;
export const SUNSET_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 18h18"/>
<path d="M6 18a6 6 0 0 1 12 0"/>
<path d="M12 5v8"/>
<path d="M9 10l3 3 3-3"/>
</svg>`;
export const SEARCH_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="7"/>
<path d="M20 20l-4.35-4.35"/>
</svg>`;
export const NEW_FOLDER_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z"/>
<path d="M12 11v5M9.5 13.5h5"/>
</svg>`;
export const UPLOAD_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 15V4M8 8l4-4 4 4"/>
<path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/>
</svg>`;
// The inverse of UPLOAD_ICON (arrow into the tray, not out of it) — used
// for the import plugins panel (plugins.js), which pulls data in from
// somewhere else rather than sending a file out.
export const PLUGIN_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v11M8 11l4 4 4-4"/>
<path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/>
</svg>`;
// Shown next to each file in the GPX tree, indicating whether it has
// waypoints, a track, or both.
export const WAYPOINT_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 21s7-7.58 7-12a7 7 0 0 0-14 0c0 4.42 7 12 7 12z"/>
<circle cx="12" cy="9" r="2.2"/>
</svg>`;
export const TRACK_ICON = GPX_ICON;
// Shown next to a file whose GeoJSON conversion is NOT yet cached on disk
// (GpxStore#geojson) — the uncommon case, since GpxStore#save converts
// eagerly at upload time; this only happens for a .gpx/.fit dropped
// straight into data/gpx/ on the filesystem, bypassing the app, and not
// yet opened. Everything uploaded normally is cached almost immediately,
// so badging the common case would just be noise — this badges the
// exception instead.
export const PENDING_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="8"/>
<path d="M12 8v4l3 2"/>
</svg>`;
// A small download button next to each tree file's delete button — the
// name link (see gpx.js's _renderFile) does the same thing, but isn't
// obviously clickable at a glance, so this is the discoverable version.
export const DOWNLOAD_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v11M8 11l4 4 4-4"/>
<path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/>
</svg>`;
// Same shape as TRACK_ICON, dashed — a route is planned rather than
// recorded, the same visual convention most map apps use for the
// distinction.
export const ROUTE_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<circle cx="5" cy="6" r="2"/>
<circle cx="19" cy="18" r="2"/>
<path d="M6.5 7.5C10 11 8 13 12 13s2 5 6.5 5" stroke-dasharray="2 2.2"/>
</svg>`;
// A rounded-square badge — used as the map marker for individual waypoints,
// tinted by category color via icon-color (see gpx.js). Not a plain dot,
// which blended in with a base map style's own small circular POI icons,
// and not a pin/teardrop either — a rounded square is the National Park
// Service's own convention for framing these exact category symbols
// (POI_ICONS below), so pairing the two looks native rather than like two
// mismatched icon styles. Centered on the coordinate (no tip to anchor at),
// which also means the category glyph on top needs no offset — both layers
// just share the same center anchor at [0, 0].
export const MAP_MARKER_ICON = `
<svg viewBox="0 0 24 24"><rect x="1" y="1" width="22" height="22" rx="5" fill="currentColor"/></svg>`;
// POI category glyphs (park4night/OsmAnd exports), keyed by the OsmAnd icon
// name a file's <osmand:icon> extension carries — a small curated set for
// the categories park4night actually uses (see waypoint_style in
// lib/maptool/gpx.rb), not an exhaustive OsmAnd icon set.
//
// These are the National Park Service's own map pictograms, not
// hand-drawn — a professional, widely-recognized icon set built for
// exactly this job (small monochrome map markers) beats reinventing "fuel
// pump"/"picnic table" glyphs from scratch. Pulled from
// github.com/nationalparkservice/npmap5-plugins's bundled `symbol-library`
// (src/<name>-22.svg) — an actively-maintained monorepo that's the
// designated replacement for the same org's older standalone
// `symbol-library` repo (confirmed by its maintainer:
// github.com/nationalparkservice/npmap5-plugins/issues/4), with a much
// larger icon vocabulary. CC0-licensed (public domain) — no attribution
// required.
//
// All filled shapes — these render at ~14px on the map, where a hairline
// stroke disappears — and rasterized (non-SDF; a plain colored raster, not
// tinted at render time, see gpx.js's _registerCategoryGlyphs) so only the
// alpha shape matters, not the actual `currentColor` value.
// src/wilderness-22.svg — exported (unlike BICYCLE_TRAIL_ICON below, this
// one's also used outside this file) as the Overlays panel's Terrain
// shading glyph (overlays.js): the closest honest match in NPS's set for
// "mountains/terrain" — it has no weather or elevation-specific pictogram.
export const WILDERNESS_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><polygon points="18,18 13,15 17,15 13,11 16,11 12,7 15,7 12,4 14,4 11,0 8,4 10,4 7,7 10,7 6,11 9,11 5,15 9,15 4,18 10,18 10,22 12,22 12,18 "/></svg>`;
// Hand-drawn, not NPS-sourced — that set has no weather/precipitation
// pictogram to reuse for the Overlays panel's Radar item, unlike Wikipedia
// (WIKI_ICON) and Terrain shading (WILDERNESS_ICON) above.
export const RADAR_CLOUD_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor">
<path d="M17,10.1c-0.4-3-2.9-5.3-6-5.3c-2.5,0-4.7,1.5-5.6,3.8C3.4,8.9,1,11.1,1,13.9C1,16.7,3.3,19,6.1,19h10.3
c2.5,0,4.6-2,4.6-4.5C21,12.2,19.3,10.4,17,10.1z"/>
<rect x="6" y="20" width="1.6" height="2"/>
<rect x="10.2" y="20" width="1.6" height="2"/>
<rect x="14.4" y="20" width="1.6" height="2"/>
</svg>`;
// Hand-drawn, not NPS-sourced — same story as RADAR_CLOUD_ICON above, no
// terrain-shadow/sun-behind-a-ridge pictogram in that set either. Used as
// the Overlays panel's Terrain shadow glyph (shadow.js via overlays.js).
export const TERRAIN_SHADOW_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor">
<circle cx="16" cy="6" r="3"/>
<polygon points="0,19 6,9 9,13 13,6 22,19"/>
</svg>`;
// src/bicycle-trail-22.svg — pulled out to its own constant since it's also
// used unrasterized, inline, as PARK4NIGHT_TAGS.vtt below.
const BICYCLE_TRAIL_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor">
<circle cx="13.9" cy="3" r="2"/>
<path d="M4.5,20C6.4,20,8,18.4,8,16.5S6.4,13,4.5,13S1,14.6,1,16.5S2.6,20,4.5,20z M0,16.5C0,14,2,12,4.5,12S9,14,9,16.5
S7,21,4.5,21S0,19,0,16.5z"/>
<path d="M17.5,20c1.9,0,3.5-1.6,3.5-3.5S19.4,13,17.5,13S14,14.6,14,16.5S15.6,20,17.5,20z M13,16.5c0-2.5,2-4.5,4.5-4.5
s4.5,2,4.5,4.5S20,21,17.5,21S13,19,13,16.5z"/>
<path d="M13.1,9.8c-0.2,0-0.5-0.1-0.7-0.4l-1.1-1.7L9.1,9.9l2.1,1.1c0.9,0.4,0.9,1,0.9,1v5c0,0.5-0.6,0.9-1.2,0.9S10,17.6,10,17v-4
l-3.8-1.9c-0.4-0.3-0.7-0.7-0.7-1.2C5.6,9.5,5.7,9.2,6,9l3.5-3.5C9.9,4.9,10.6,5,10.6,5c0.7,0,1.1,0.6,1.1,0.6l1.8,2.9h2.8
c1,0,1,1.3,0,1.3H13.1L13.1,9.8z"/>
</svg>`;
// src/store-22.svg — NPS's generic shop pictogram, the closest match in
// their set for both a supermarket and a convenience store (no separate
// grocery-specific glyph exists there).
const STORE_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor">
<path d="M20,9c0,0-0.8,3-4,3C16,12,15.8,9.9,20,9z"/>
<path d="M17,14.3c0.5-0.5,1.3-0.9,2.1-0.9c1.6,0,2.9,1.3,2.9,3v0.2l0,0c-0.1,0.6-0.3,1.5-0.7,2.4c0,0-0.8,1.6-1.5,2.3l-0.1,0.1
c-0.3,0.3-0.8,0.5-1.3,0.5c-0.6,0-1.1-0.5-1.5-1c-0.3,0.5-0.9,1-1.5,1c-0.5,0-0.9-0.2-1.3-0.5L14,21.3c-0.7-0.7-1.5-2.3-1.5-2.3
c-0.5-1-0.7-1.8-0.7-2.4l0,0v-0.2c0-1.7,1.3-3,2.9-3C15.7,13.5,16.5,13.8,17,14.3"/>
<polygon points="4,0 8,0 8,2 4,2 "/>
<path d="M7,3H3c0,0-0.7,0.2-1.2,0.7L0.2,5.8C0.1,6,0,5.9,0,6.1V21c0,0.4,0.6,1,1,1h8c0.4,0,1-0.6,1-1V6C10,6,9.6,3.3,7,3z M4,4v5H3
v1H2l-1,1v-1V6h1V5h1L4,4z"/>
</svg>`;
export const POI_ICONS = {
// src/parking-22.svg
amenity_parking: `
<svg viewBox="0 0 22 22"><path fill="currentColor" d="M11.9,11c1.8,0,3.5-1.8,3.5-3.6S13.7,4,11.9,4h-5v7H11.9z M12.1,0C16.2,0,20,3.3,20,7.5c0,4.1-3.9,7.5-8.1,7.5h-5v7H3V0
H12.1z"/></svg>`,
// src/campground-22.svg
tourism_camp_site: `
<svg viewBox="0 0 22 22" fill="currentColor">
<path d="M17,21L9.4,5.8L2,21H0v1h19v-1H17z M5,21l4.5-8.5L14,21H5z"/>
<polygon points="20,18 20,18 12.3,2.9 11.5,4.7 19,19 20.5,19 "/>
<polygon points="15.5,0 14.7,1.7 22,16 22,13 "/>
</svg>`,
// src/picnic-area-22.svg
leisure_picnic_table: `
<svg viewBox="0 0 22 22"><path fill="currentColor" d="M22,11h-6l-2-5h4V4H4v2h4l-2,5H0v2h5l-2,5h2l2-5h8l2,5h2l-2-5h5V11z M8,11l2-5h2l2,5H8z"/></svg>`,
// src/gas-station-22.svg
amenity_fuel: `
<svg viewBox="0 0 22 22"><path fill="currentColor" d="M19,14.4L19,14.4v-1.5V6.2c0-0.7-0.4-1.3-0.9-1.8L15,1.5c-0.2,0-0.8,0.4-0.8,0.4c0,0.2,1.5,1.8,1.5,1.8v2.6
c0,0.9,0.8,1.8,1.7,1.8L18,7.9v5v1.7l1,5.1c0,0.8-0.9,1.3-1.5,1.3C17,21,16,20.5,16,20v-8.9C16,10,15.4,9,14.4,9H12V1h-1V0H3v1H2
v21h10V10.4h2.4c0.4,0,0.6,0.3,0.6,0.7V20c0,1.2,1.2,2,2.5,2c1.2,0,2.5-0.8,2.5-2C20,19.7,19,14.4,19,14.4z M18,7h-1V5h1V7z
M10.5,5.8L9.6,6.6H4.4L3.5,5.8V2.2l0.9-0.9h5.2l0.9,0.9V5.8z"/></svg>`,
// src/lodging-22.svg
tourism_hotel: `
<svg viewBox="0 0 22 22" fill="currentColor">
<polygon points="0,4 2,4 2,12 22,12 22,17 20,17 20,14 2,14 2,17 0,17 "/>
<polygon points="3,11 22,11 22,8 21,7 13,6 7,6 7,9 3,9 "/>
<circle cx="4.5" cy="6.5" r="1.5"/>
</svg>`,
// src/wilderness-22.svg
forest: WILDERNESS_ICON,
// src/bicycle-trail-22.svg
sport_cycling: BICYCLE_TRAIL_ICON,
};
// National Park Service map symbols (same source/license as POI_ICONS above)
// used as small inline glyphs next to a park4night waypoint's Services/
// Activities tags (see PARK4NIGHT_TAGS and formatDescription in
// public/js/gpx.js) — pulled into named constants first since a few codes
// share the same real-world facility (eau_noire/eau_usee are both a dump
// station, gaz/gpl are both a propane refill, peche/peche_pied are both
// fishing) and BICYCLE_TRAIL_ICON is also POI_ICONS.sport_cycling above.
const PETS_ON_LEASH_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g><polygon points="3,12 3,21 4,21 4,22 5,22 5,21 6,21 6,18 9,22 10,22 11,20 8,16 14,16 14,21 15,21 15,22 16,22 16,21 17,21 17,11 13,9 3,9 2,8 1,9 "/><polygon points="13,7 13,1 14,1 14,2 22,6 22,8 17,9 "/><polygon points="0,1 0,2.5 13,8.5 13,7 "/></g></svg>`;
const SHOWERS_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M4.9,12.8c-0.1,0.4,0.2,0.7,0.6,0.8s0.7-0.2,0.8-0.6c0.1-0.4-0.2-0.7-0.6-0.8C5.3,12.1,4.9,12.4,4.9,12.8z M5.5,11.2 c0.1-0.4-0.2-0.7-0.5-0.7S4.3,10.7,4.2,11c-0.1,0.4,0.2,0.7,0.5,0.7C5.1,11.8,5.4,11.6,5.5,11.2z M4.1,8.8c0.3,0,0.6,0.3,0.6,0.6 S4.4,10,4.1,10S3.5,9.7,3.5,9.4S3.8,8.8,4.1,8.8z M3.4,7C3.7,7,4,7.3,4,7.6S3.7,8.2,3.4,8.2S2.8,7.9,2.8,7.6S3.1,7,3.4,7z M2.7,5.4 c0.3,0,0.5,0.2,0.5,0.5S3,6.4,2.7,6.4S2.2,6.2,2.2,5.9S2.4,5.4,2.7,5.4z M2,3.6c0.3,0,0.5,0.2,0.5,0.5S2.3,4.6,2,4.6 S1.5,4.4,1.5,4.1S1.7,3.6,2,3.6z M7.4,10.3c0-0.4,0.3-0.7,0.7-0.6c0.4,0,0.7,0.3,0.6,0.7c0,0.4-0.3,0.7-0.7,0.6 C7.7,11,7.4,10.7,7.4,10.3z M7,8.3c0.3,0,0.6,0.3,0.6,0.6S7.3,9.5,7,9.5S6.4,9.2,6.4,8.9S6.7,8.3,7,8.3z M6,6.9 c0.3,0,0.6,0.3,0.6,0.6S6.3,8.1,6,8.1S5.4,7.8,5.4,7.5S5.7,6.9,6,6.9z M4.9,5.5c0.3,0,0.6,0.3,0.6,0.6S5.2,6.7,4.9,6.7 S4.3,6.4,4.3,6.1S4.6,5.5,4.9,5.5z M3.9,4.2c0.3,0,0.5,0.2,0.5,0.5S4.2,5.2,3.9,5.2S3.4,5,3.4,4.7S3.6,4.2,3.9,4.2z M2.8,2.8 c0.3,0,0.5,0.2,0.5,0.5S3.1,3.8,2.8,3.8S2.3,3.6,2.3,3.3S2.5,2.8,2.8,2.8z M9.3,7.4c-0.4,0-0.7-0.3-0.7-0.6c0-0.4,0.3-0.7,0.6-0.7 c0.4,0,0.7,0.3,0.7,0.6C9.9,7.1,9.6,7.4,9.3,7.4z M8.5,5.7c0,0.3-0.2,0.6-0.6,0.7S7.2,6.1,7.2,5.7S7.5,5.1,7.8,5 C8.1,5,8.4,5.3,8.5,5.7z M7,4.6c0,0.3-0.2,0.6-0.6,0.6C6.1,5.2,5.8,5,5.8,4.6C5.8,4.3,6.1,4,6.4,4C6.7,4,7,4.3,7,4.6z M5,3 c0.3,0,0.6,0.3,0.6,0.6S5.3,4.2,5,4.2S4.4,3.9,4.4,3.6S4.7,3,5,3z M3.6,2c0.3,0,0.5,0.2,0.5,0.5S3.9,3,3.6,3S3.1,2.8,3.1,2.5 S3.3,2,3.6,2z M4.4,1.2c0.3,0,0.5,0.2,0.5,0.5S4.7,2.2,4.4,2.2S3.9,2,3.9,1.7S4.1,1.2,4.4,1.2z M6.3,1.9c0.3,0,0.5,0.2,0.5,0.5 S6.6,2.9,6.3,2.9S5.8,2.7,5.8,2.4S6,1.9,6.3,1.9z M8.1,2.6c0.3,0,0.6,0.3,0.6,0.6S8.4,3.8,8.1,3.8c-0.3,0-0.6-0.3-0.6-0.6 S7.8,2.6,8.1,2.6z M9.9,3.3c0.3,0,0.6,0.3,0.6,0.6s-0.3,0.6-0.6,0.6S9.3,4.2,9.3,3.9S9.6,3.3,9.9,3.3z M11.7,4.1 c0.3,0,0.6,0.3,0.6,0.6S12,5.3,11.7,5.3S11.1,5,11.1,4.7S11.4,4.1,11.7,4.1z M0,1h1V0h4v1H4v1H3v1H2v1H1v1H0V1z M11.5,7 C12.9,7,14,8.1,14,9.5S12.9,12,11.5,12S9,10.9,9,9.5S10.1,7,11.5,7z M14,13v-1h1v-1h1v-1h1V9h1V8h1V7h1V6h1l1,1v1v1h-1v1h-1v1h-1v1 h-1v1h-1v1h-1v8H9v-4H5v-2h1v-1h1v-1h1v-1H14z M10,16h1v2h-1v1h2v-4h-2V16z"/></svg>`;
const SANITARY_DISPOSAL_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g><path d="M20,10V2h-1V1H4v1H3v8h1v1h5V9h1V8h3v1h1v2h8v-1H20z M11,5H6L5,4l1-1h5l1,1L11,5z M17,5h-2l-1-1l1-1h2l1,1L17,5z"/><path d="M10,9h3v3h-3V9z M11,11h1v-1h-1V11z"/><polygon points="8,13 21,13 22,14 22,19 21,20 1,20 0,19 0,14 1,13 4,13 4,14 2,14 1,15 1,18 2,19 10,19 11,18 11,15 10,14 8,14 "/><polygon points="5.5,12 6.5,12 6.5,16 8,16 6,18 4,16 5.5,16 "/></g></svg>`;
const ELECTRICAL_HOOKUP_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M16,6.3V1.1C16,0.5,15.2,0,14.5,0C13.8,0,13,0.5,13,1.1v5.2H8.8V1.1C8.8,0.5,8.2,0,7.5,0C6.8,0,6,0.5,6,1.1v5.2H3.5 c0,0,0,1.4,0,2.2c0,3.1,2.5,5.7,5.7,6.4l0.3,0V22h2.9v-7.1l0.1,0c3.4-0.7,5.9-3.2,5.9-6.4c0-0.8,0-2.2,0-2.2H16z"/></svg>`;
const PROPANE_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M15,4V0H7v4C4.9,4.4,3,6.3,3,8.4v7c0,2.2,1.6,4,3.7,4.4V22h8.6v-2.2c2.1-0.4,3.7-2.2,3.7-4.4v-7C19,6.3,17.1,4.4,15,4z M12,1h2v3h-2V1z M8,1h2v3H8V1z M13,13.6c-0.5,0.8-2.2,1.7-1.7,3.5h-1.1c-0.8-0.9-3.5-3.9-1.3-6c2.2-2,2.5-3.7,1.7-4.5 C10.7,6.6,16.2,8.7,13,13.6z"/></svg>`;
const LAUNDRY_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M3,0v4h16V0H3z M6,3H4V1h2V3z M10,3H8V1h2V3z"/><path d="M3,5v17h16V5H3z M11,19c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S14.3,19,11,19z"/><path d="M6.5,11c-0.6-0.4-0.4,1.3-0.4,2c0,2.7,2.2,4.9,4.9,4.9s4.9-2.2,4.9-4.9c0-0.7,0.1-1.6-0.4-2C10.2,6.7,11.9,14.7,6.5,11z"/></svg>`;
const SWIMMING_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g><polygon points="0,16 1,16 3,17 4,17 6,16 7,16 9,17 10,17 12,16 13,16 15,17 16,17 18,16 19,16 21,17 22,17 22,19 21,19 19,18 18,18 16,19 15,19 13,18 12,18 10,19 9,19 7,18 6,18 4,19 3,19 1,18 0,18 "/><polygon points="6,14 7,14 9,15 10,15 12,14 13,14 15,15 16,15 17.5,14.2 13,7 18,6 20,5 20,4 18,3 10,4 9,5 9,6 11,10 3,15 4,15 "/><circle cx="19.5" cy="10.5" r="2.5"/></g></svg>`;
const DRINKING_WATER_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><polygon points="20,0 18,0 15,20 7,20 4,0 2,0 5.5,22 16.5,22 "/><path d="M15.9,2c-0.4,0.4-0.9,1-1.4,1c-0.7,0-1.3-0.8-1.7-1.4C12.5,2.2,11.7,3,11,3c-0.7,0-1.2-0.8-1.5-1.4C9.1,2.2,8.7,3,8,3 C7.5,3,6.8,2.3,6.4,2L6.2,0.1C6.5,0.6,7.3,1,8,1c0.7,0,1.1-0.4,1.5-1c0.4,0.5,0.8,1,1.5,1c0.7,0,1.5-0.4,1.8-1c0.4,0.5,1,1,1.7,1 c0.7,0,1.3-0.5,1.7-1L15.9,2z"/></svg>`;
const TRASH_DUMPSTER_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M13,7h-2c-1.1,0-1.1,2,0,2h3c0.2,0,1-2,1-2v14c0,0.5,0.5,1,1,1s1-0.4,1-1v-8h1v8c0,0.5,0.5,1,1,1s1-0.4,1-1V7h1v5 c0,1.1,0.5,1.1,1,0V6c0-1.2-1.6-1-3-1h-3c-0.8,0-1.6,0.4-2,1L13,7z M3,16c1.6,0,3,1.4,3,3v3h2l3.5-8.9v-2.9H1.2L1,16H3z M9.6,5.8 L9.6,5.8L9.2,6L9,5.6l0,0L8.6,5.8L8.4,5.4l0,0L8,5.6L7.8,5.2l0,0L7.4,5.4L7.2,5l0,0L6.8,5.2L6.6,4.7L5.4,8.2 C5.3,8.5,5.5,8.8,5.8,8.9l2,0.7C8,9.7,8.3,9.5,8.4,9.3L9.6,5.8z M7.9,2.3L7.3,1.8L0.7,9.7l0.5,0.5L7.9,2.3z M18,0c1.1,0,2,0.9,2,2 s-0.9,2-2,2s-2-0.9-2-2S16.9,0,18,0z M2.5,17C1.1,17,0,18.1,0,19.5S1.1,22,2.5,22S5,20.9,5,19.5S3.9,17,2.5,17z M2.5,21 C1.7,21,1,20.3,1,19.5S1.7,18,2.5,18S4,18.7,4,19.5S3.3,21,2.5,21z"/></svg>`;
const RESTROOMS_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g><rect x="11" y="2" width="2" height="18"/><polygon points="21,7 21,6 20,6 19,6 18,6 17,6 16,6 16,7 15,7 15,8 15,13 16,13 16,8 17,8 17,20 18,20 18,14 19,14 19,20 20,20 20,8 21,8 21,13 22,13 22,8 22,7 "/><polygon points="8,7 6,6 3,6 1,7 1,8 0,12 1,12 2,8 3,8 3,9 1,15 3,15 3,20 4,20 4,15 5,15 5,20 6,20 6,15 8,15 6,9 6,8 7,8 8,12 9,12 8,8 "/><circle cx="4.5" cy="3.5" r="1.5"/><circle cx="18.5" cy="3.5" r="1.5"/></g></svg>`;
const RIVER_RAFTING_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M20.4,17.4c-0.5,0.3-0.9,0.8-1.6,0.8c-0.7,0-1.1-0.5-1.6-0.8c-0.4-0.3-1-0.8-1.6-0.8c-0.6,0-1.2,0.4-1.6,0.8 c-0.3,0.3-0.9,0.8-1.6,0.8c-0.7,0-1.2-0.5-1.6-0.8c-0.4-0.3-0.8-0.8-1.6-0.8c-0.7,0-1.2,0.5-1.6,0.8c-0.4,0.3-0.8,0.8-1.6,0.8 c-0.7,0-1.2-0.5-1.6-0.8c-0.4-0.2-0.7-0.8-1.6-0.8c-0.8,0-1.2,0.5-1.6,0.8C1.2,17.7,0,18.2,0,18.2v1.6v1.6c0,0,1.2-0.5,1.6-0.8 c0.4-0.3,0.8-0.8,1.6-0.8c0.9,0,1.2,0.5,1.6,0.8c0.4,0.3,0.9,0.8,1.6,0.8c0.8,0,1.2-0.5,1.6-0.8c0.4-0.3,0.8-0.8,1.6-0.8 c0.8,0,1.2,0.5,1.6,0.8c0.4,0.3,0.9,0.8,1.6,0.8c0.7,0,1.2-0.5,1.6-0.8c0.4-0.3,1-0.8,1.6-0.8c0.6,0,1.2,0.5,1.6,0.8 c0.5,0.3,0.9,0.8,1.6,0.8c0.6,0,1-0.5,1.6-0.8c0.5-0.3,1.6-0.8,1.6-0.8v-1.6v-1.6C22,16.6,21,17.1,20.4,17.4z"/><path d="M3.1,15c0.9,0,1.2,0.5,1.6,0.8c0.4,0.3,0.9,0.8,1.6,0.8c0.8,0,1.2-0.5,1.6-0.8C8.2,15.6,8.7,15,9.4,15 c0.8,0,1.2,0.5,1.6,0.8c0.4,0.3,0.9,0.8,1.6,0.8c0.7,0,1.2-0.5,1.6-0.8c0.4-0.3,1-0.8,1.6-0.8c0.6,0,1.2,0.5,1.6,0.8 c0.1,0.1,0.2,0.2,0.3,0.2l1.4-0.4c0,0,3,0,3-2.9c0-0.1,0-0.2,0-0.3c-1.9,1.3-6.8,1.6-7.4,1.6H0v2.6c0,0,1.2-0.5,1.6-0.8 C2,15.5,2.3,15,3.1,15z"/><path d="M11.1,2.2l-0.2,0.5C10.7,3,10.4,3.2,10,3.2H9.4C9.8,3.7,10.3,4,10.9,4c1,0,1.8-0.8,1.8-1.8V2.1L11.1,2.2 C11.1,2.1,11.1,2.1,11.1,2.2z"/><path d="M10,2.8c0.2,0,0.4-0.1,0.4-0.3L10.7,2c0.1-0.2,0.3-0.3,0.5-0.3H13c-0.2-1-1.1-1.7-2.1-1.7C9.7,0,8.7,1,8.7,2.2 c0,0.2,0,0.4,0.1,0.6H10z"/><g><path d="M9.4,10C9,10,8.7,9.7,8.6,9.3c0-0.4,0.3-0.8,0.7-0.8L15,8.2c0.5,0,0.8,0.3,0.8,0.7c0,0.4-0.3,0.8-0.7,0.8L9.4,10 C9.5,10,9.4,10,9.4,10z"/></g><path d="M17.2,10.9c-0.3,0.1-0.8,0.3-1.3,0.4l-0.7,0.1c-2,0.3-4.6,0.3-5.8,0.3c0,0,0,0,0,0L9.8,10l0,0l0.6-1.9c0,0,0,0,0,0L10.7,7 L11,6.1l3.4-0.2c0.4,0,0.8-0.4,0.7-0.8c0-0.4-0.3-0.8-0.8-0.7L8.7,4.6c-0.4,0-2.1,3.3-2.1,3.3l-1.2,3.7H0v1.8h14.5 c1.7-0.1,6.1-0.5,7.3-1.6C20.4,10.3,19.2,10,17.2,10.9z"/><g><path d="M15.9,14.6c-0.2,0-0.4-0.1-0.4-0.3L14,4.9c0-0.2,0.1-0.4,0.3-0.5c0.2,0,0.4,0.1,0.5,0.3l1.6,9.4 C16.4,14.4,16.2,14.6,15.9,14.6C16,14.6,16,14.6,15.9,14.6z"/></g></svg>`;
const CLIMBING_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M2.5,9.4c-0.1,0.2-0.2,0.4-0.2,0.7c0,0.1,0,0.2,0,0.4L2.4,16l-1.9,4.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.1,0.7,0.4,1.3,1,1.4 c0.5,0.1,1-0.2,1.3-0.6l2.1-4.5c0-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.1,0-0.2l0-3.4l3.2,1.4l0.5,3.4c0.1,0.5,0.5,0.9,1,1 c0.7,0.1,1.3-0.4,1.4-1c0-0.1,0-0.2,0-0.3l-0.6-4.1c-0.1-0.4-0.3-0.7-0.7-0.9L6.8,11l1.8-3.2l0.9,1.2C9.7,9,9.8,9.1,10,9.2l3.5,1 c0.5,0.1,0.9-0.1,1.1-0.6c0.2-0.5,0-1.1-0.5-1.3c0,0,0,0,0,0l-3-0.9L8.7,4.7C8.3,4.3,7.9,4.1,7.3,4C6.4,3.8,5.5,4.3,5.1,5L2.5,9.4z" /><path d="M12.5,17.4l-0.2,1.7l-6,1.5l0.1,1H21c0.5,0,0.9-0.4,0.9-0.9l0-19.7l-2-0.5l-1.2,5.2l-1.9,0.8l-1.7,4.8l1.6,3.7l-0.5,1.4 L12.5,17.4z"/><ellipse transform="matrix(0.9871 -0.1602 0.1602 0.9871 -0.1902 1.3795)" cx="8.5" cy="1.9" rx="1.9" ry="1.9"/><path d="M4.7,4c0.1-0.3,0.1-0.6-0.2-0.7L3.6,2.8C3.4,2.6,3.1,2.7,2.9,3L0.1,7.8C0,8,0.1,8.4,0.3,8.5L1.2,9C1.5,9.2,1.8,9.1,2,8.8 L4.7,4z"/></svg>`;
const PLAYGROUND_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M4.4,11.7c1.2,0,2.2-1,2.2-2.2c0-1.2-1-2.2-2.2-2.2c-1.2,0-2.2,1-2.2,2.2 C2.2,10.8,3.2,11.7,4.4,11.7z M17,15.4c0.1-0.1,0.2,0,0.3,0l0.4,0.6c0.1,0.1,0,0.2-0.1,0.3l-3,2.1c-0.1,0.1-0.2,0-0.3,0l-0.4-0.6 c-0.1-0.1,0-0.2,0.1-0.3L17,15.4z M13.5,12.7l-1.2-2l-0.6,0.4l1.2,2L13.5,12.7z M10.7,7.9L6,0L5.1,0l4.9,8.4L10.7,7.9z M15.1,12.1 c0.3-0.2,0.6-0.3,0.9-0.3l4.3,0c0.8,0,1.5,0.7,1.5,1.5c0,0.8-0.7,1.5-1.5,1.5l-3.6,0l-4.6,3.2c-1.6,1.1-2.6-0.1-2.6-0.1l-3.6-3.5 c-0.6-0.7-0.5-2,0.3-2.6l5-3.5c0.5-0.4,1.2-0.3,1.7,0.1c0.4,0.5,0.4,1.2-0.1,1.6l-3.2,2.3l2.3,2.2L15.1,12.1z"/></svg>`;
const MOTOR_BIKE_TRAIL_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g><path d="M12.1,16.9c-0.3,0.3-0.7,0.5-1.1,0.5V12l4-1v2L12.1,16.9z"/><path d="M9,5H8V4.1c0,0-0.9,0.2-1.2,0.5l-3,4.6C3.7,9.3,3.7,9.6,3.7,9.8c0,0.5,0.2,0.9,0.6,1.1l4,2.2V17c0,0.5,0.4,1,1,1 c0.5,0,0.8-0.4,0.8-1v-4.7c0,0,0.3-0.8-0.5-1.2L7,9.8L8.8,7l1,1.5C10,8.8,10.2,9,10.5,9H13c1,0,1-1.4,0-1.4h-2l-2-3V5z"/><path d="M19.9,10.7l0.1,0.2c0,0.1-0.1,0.2-0.2,0.2h-0.1c-0.4-0.2-0.7-0.3-1.2-0.3c-0.3,0-0.7,0.1-1.2,0.5l-0.4-0.9 c0.5-0.2,1-0.4,1.5-0.4C19,10,19.4,10.3,19.9,10.7z"/><path d="M3.2,11.4L7,13.7v0.9L2.6,12c-0.3-0.2-0.8-0.3-1.1-0.3c-0.5,0-0.3,0.1-0.7,0.3H0.7c-0.1,0-0.2-0.1-0.2-0.2l0.1-0.2 C1.1,11.2,1,11,1.8,11C2.2,11,2.6,11.1,3.2,11.4L3.2,11.4z"/><path d="M3.5,19.9c1.3,0,2.4-1.1,2.4-2.5s-1.1-2.5-2.4-2.5S1.1,16,1.1,17.4S2.2,19.9,3.5,19.9z M0,17.4c0-2,1.6-3.6,3.5-3.6 S7,15.4,7,17.4S5.4,21,3.5,21S0,19.4,0,17.4z"/><path d="M18.4,19.9c1.4,0,2.5-1.1,2.5-2.5s-1.1-2.5-2.5-2.5s-2.5,1.1-2.5,2.5S17.1,19.9,18.4,19.9z M14.8,17.4c0-2,1.6-3.6,3.6-3.6 s3.6,1.6,3.6,3.6S20.4,21,18.4,21S14.8,19.4,14.8,17.4z"/><path d="M17.6,13L16,9.8C15.8,9.4,15.2,9,14.7,9h-1.1c-0.2,0-0.4,0.3-0.4,0.6s0.2,0.4,0.4,0.4h1.1c0.2,0,0.4,0.1,0.5,0.3l1.6,2.7 H17.6z"/><path d="M12,3h0.9C13,2.8,13,2.7,13,2.5C13,1.1,11.9,0,10.5,0S8,1.1,8,2.5C8,3.1,8.2,3.6,8.5,4H12V3z"/><circle cx="10.5" cy="3.5" r="1.5"/></g></svg>`;
const FISHING_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g><path d="M6.1,13.6L6,13.8L6.1,14l3.9,1c0.2,0.1,0.2,1,0,1H6.1L6,16.1v0.1c4.3,3.4,9.2,4.8,15,4.8V9C11,9,6.1,13.6,6.1,13.6z M13,14 h-1v-1h1V14z"/><path d="M19,1c-3.3,0-5.7,1.5-9.3,4.5c-0.1,0-0.4-0.1-0.4-0.1c-0.6,0-1,0.5-1,1c0,0,0,0.2,0.1,0.3C8.1,6.8,5.3,9.5,5.3,9.5L3,12 c-0.2,0.2-0.7,0-1,0s-0.6,0-0.8-0.3c-0.2-0.2-0.3-0.5-0.3-0.8S1,10.3,1.3,10c0,0,0.2-0.1,0.3-0.2c0,0.2,0.1,0.9,0.1,0.9L4,8 L1.5,8.9C0.9,9.1,0.7,9.4,0.6,9.4c-0.8,0.7-0.9,1.8-0.1,2.9C2,12.9,1.4,12.8,3,13l1-1l1.8-1.8c0,0,2.9-2.8,3-2.8 c0.1,0,0.4,0.1,0.4,0.1c0.6,0,1-0.5,1-1c0,0,0-0.2,0-0.3C13.7,3.3,15.9,2,19,2c0.6,0,3,0,3,0V1H19z"/></g></svg>`;
const SCENIC_VIEWPOINT_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g transform="translate(4.000000, 0.000000)"><path d="M3.2,11c0,1.2-0.9,2.2-2.1,2.2c-1.2,0-2.1-1-2.1-2.2 c0-1.2,0.9-2.2,2.1-2.2C2.2,8.8,3.2,9.8,3.2,11"/><path d="M4.6,10.4v1.3l10.6,0.8v-3L4.6,10.4"/><path d="M2.3,7.5l1.1,0.7L7.7,2L5.3,0.5L2.3,7.5"/><path d="M4.4,9.8l7.9-3.8l-1.4-2.6L3.8,8.6L4.4,9.8z"/><path d="M2.3,14.5l1.1-0.7l4.3,6.2l-2.4,1.5L2.3,14.5"/><path d="M3.8,13.4l0.6-1.2l7.9,3.8l-1.4,2.6L3.8,13.4"/></g></svg>`;
const WALKING_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M10.4,3.6c1,0,1.8-0.8,1.7-1.8c0-1-0.8-1.8-1.8-1.7c-1,0-1.8,0.8-1.7,1.8C8.6,2.8,9.5,3.6,10.4,3.6z"/><path d="M16.5,9.5L13.9,8l-2.2-3.4c-0.3-0.4-0.9-0.8-1.5-0.7C9.7,4,9.3,4.2,9,4.4L5.8,7.7C5.7,7.8,5.6,8,5.6,8.1l-0.4,3.6 c0,0,0,0.1,0,0.1c0,0.4,0.4,0.8,0.8,0.8c0.4,0,0.7-0.4,0.8-0.8l0.3-3.1l1.1-1.1l-1,8.6l-1.9,4.1c-0.1,0.1-0.1,0.3-0.1,0.5 c0,0.7,0.6,1.2,1.2,1.2c0.5,0,0.9-0.3,1.1-0.7l2-4.4c0-0.1,0.2-0.4,0.2-0.5l0.2-2.1l2.1,6.9c0.2,0.5,0.6,0.8,1.2,0.8 c0.7,0,1.2-0.6,1.2-1.2c0-0.1,0-0.1,0-0.2L11.5,11l0.4-3.1l0.8,1.3c0.1,0.1,0.1,0.2,0.2,0.2l2.8,1.6c0.1,0,0.2,0.1,0.4,0.1 c0.4,0,0.8-0.4,0.8-0.8C16.9,9.8,16.7,9.6,16.5,9.5z"/></svg>`;
const GUIDED_TOURS_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><polygon points="19,7 19,6 14,6 14,7 13,7 13,8 13,13 14,13 14,8 15,8 15,20 16,20 16,14 17,14 17,20 18,20 18,8 19,8 20,8 20,7 "/><circle cx="16.5" cy="3.5" r="1.5"/><polygon points="4,7 4,6 1,6 1,7 0,7 0,8 0,13 1,13 1,20 2,20 2,14 3,14 3,20 4,20 4,13 5,13 5,7 "/><circle cx="2.5" cy="3.5" r="1.5"/><polygon points="10,7 10,6 7,6 7,7 6,7 6,8 6,13 7,13 7,20 8,20 8,14 9,14 9,20 10,20 10,13 11,13 11,7 "/><circle cx="8.5" cy="3.5" r="1.5"/><rect x="21" y="4" width="1" height="4"/><rect x="19" y="7" width="2" height="1"/></svg>`;
const WIND_SURFING_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><polygon points="21,20 19,19 18,19 16,20 15,20 13,19 12,19 10,20 9,20 8,20 8,19.5 7,19 6,19 4,20 3,20 1,19 1,21 3,22 4,22 6,21 7,21 9,22 10,22 12,21 13,21 15,22 16,22 18,21 19,21 21,22 22,22 22,20 "/><path d="M10.7,17.5l-2.5-2.4C8.1,15,7.9,15,7.7,15H5l-0.4-1H4v-1h0.2L4,12.4h1.4c0,0,0.3,0,0.4-0.1l2.3-1c0.2-0.1,0.3-0.3,0.3-0.5 c0-0.4-0.3-0.7-0.6-0.7c-0.1,0-0.2,0-0.2,0l-2.1,1h-3c-0.1,0-0.2,0-0.4,0.1V12h-1C1,12.1,1,12.2,1,12.4c0,0.1,0,0.2,0,0.3l1.4,3.2 c0.2,0.5,0.7,0.8,1.2,0.8h3.7l2.2,2.1c0.3,0.3,0.9,0.3,1.2,0C11.1,18.4,11.1,17.8,10.7,17.5z"/><path d="M7,0l7.1,18l7.9-4.9C21.5,5.7,13.4,0.8,7,0z M18,10c-1.5,0-6,0-6,0V9c0,0,4.5,0,6,0c1.8,0,3,2,3,2v1h-1C20,12,18.8,10,18,10 z"/><circle cx="1.5" cy="9.5" r="1.5"/></svg>`;
// These three have no equivalent in the older standalone symbol-library
// repo (see POI_ICONS above) — pulled from npmap5-plugins' bundled,
// actively-maintained symbol-library instead (CC0-licensed), which has a
// much larger vocabulary.
const WIFI_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><g><path d="M11,11.9c-1.9,0-3.6,0.8-4.8,2l1.6,1.6c0.8-0.8,1.9-1.3,3.1-1.3c1.2,0,2.3,0.5,3.1,1.3l1.6-1.6 C14.6,12.7,12.9,11.9,11,11.9z"/><path d="M11,7c-3.1,0-5.9,1.3-7.9,3.3l1.6,1.6c1.6-1.6,3.8-2.6,6.2-2.6c2.4,0,4.6,1,6.2,2.6l1.6-1.6C16.9,8.3,14.1,7,11,7z"/><path d="M11,4.5c3.7,0,7,1.5,9.4,3.9L22,6.7c-2.8-2.8-6.7-4.6-11-4.6c-4.3,0-8.2,1.7-11,4.6l1.6,1.6C4,6,7.3,4.5,11,4.5z"/><circle cx="11" cy="18.3" r="1.6"/></g></svg>`;
const CELLULAR_SIGNAL_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M18.8,3.2l-1.4,1.4C19,6.3,20,8.5,20,11s-1,4.7-2.6,6.4l1.4,1.4c2-2,3.2-4.7,3.2-7.8C22,8,20.8,5.2,18.8,3.2 z"/><path d="M2,11c0-2.5,1-4.7,2.6-6.4L3.2,3.2C1.2,5.2,0,8,0,11c0,3,1.2,5.8,3.2,7.8l1.4-1.4C3,15.7,2,13.5,2,11z"/><path d="M6.1,15.9l1.4-1.4C6.6,13.6,6,12.4,6,11c0-1.4,0.6-2.6,1.5-3.5L6.1,6.1C4.8,7.3,4,9.1,4,11 S4.8,14.7,6.1,15.9z"/><path d="M16,11c0,1.4-0.6,2.6-1.5,3.5l1.4,1.4c1.3-1.3,2.1-3,2.1-4.9c0-1.9-0.8-3.7-2.1-4.9l-1.4,1.4 C15.4,8.4,16,9.6,16,11z"/><path d="M12,13.8c1.2-0.4,2-1.5,2-2.8c0-1.7-1.3-3-3-3s-3,1.3-3,3c0,1.3,0.8,2.4,2,2.8L8.9,20H8v2h0.6h1h2.9h1H14v-2 h-0.9L12,13.8z M9.9,20l1.1-6c0,0,0,0,0,0s0,0,0,0l1.1,6H9.9z"/></svg>`;
const WINTER_RECREATION_AREA_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor"><path d="M10.1,21.4v-2.9l-1.6,0.9l-0.8-0.5v-1l2.4-1.4v-1.9l-1.7,1.1v-2l-1.7,1v2.7L5.7,18l-0.8-0.5v-1.8l-2.5,1.4l-1.1-0.5v-1.2 L4,14l-1.7-0.8v-1.1l0.9-0.5L5.6,13l1.7-1l0,0l-1.7-1l1.6-1l-1.7-1l-2.4,1.4L2.3,10V9l1.6-0.9L1.3,6.7V5.5l1-0.5l2.5,1.5V4.6 l0.8-0.5l0.9,0.5l0,2.8l1.7,1l0-2l1.8,1V5.5L7.6,4.1v-1l0.8-0.5l1.6,0.9V0.6L11,0l0.9,0.6v2.9l1.7-0.9l0.8,0.6V4L12,5.5v1.9l1.7-1 v2.1l1.8-1v-3l0.8-0.4l0.9,0.4v1.9L19.8,5l0.9,0.6v1.1l-2.6,1.5l1.6,0.9v1l-0.8,0.5L16.5,9l-1.7,1.1l1.6,1l-1.7,1l1.7,0.9l2.5-1.4 l0.8,0.6v1L18.2,14l2.5,1.5v1.1l-1,0.5l-2.4-1.4v1.8L16.3,18l-0.8-0.5v-2.8l-1.8-1v1.9l-1.7-1v1.9l2.4,1.4V19l-0.8,0.4l-1.6-0.9v2.9 L11,22L10.1,21.4z M9.4,11.1l0.9,1.3h1.6l0.7-1.3l-0.8-1.4h-1.6L9.4,11.1z"/></svg>`;
// park4night's fixed vocabulary of Services/Activities codes (the ones
// p4n2gpx exports actually use — not necessarily park4night's entire API),
// each with a human label (always shown) and an icon where the NPS set has
// a reasonable match. formatDescription (public/js/gpx.js) reads this;
// an unrecognized code just renders as its raw text, same as before this
// existed, so nothing p4n2gpx might add later is ever hidden.
export const PARK4NIGHT_TAGS = {
// Services
animaux: { icon: PETS_ON_LEASH_ICON, label: "Pets allowed" },
boulangerie: { label: "Bakery nearby" },
caravaneige: { icon: WINTER_RECREATION_AREA_ICON, label: "Winter/snow camping" },
donnees_mobile: { icon: CELLULAR_SIGNAL_ICON, label: "Mobile data coverage" },
douche: { icon: SHOWERS_ICON, label: "Showers" },
eau_noire: { icon: SANITARY_DISPOSAL_ICON, label: "Black water disposal" },
eau_usee: { icon: SANITARY_DISPOSAL_ICON, label: "Grey water disposal" },
electricite: { icon: ELECTRICAL_HOOKUP_ICON, label: "Electricity" },
gaz: { icon: PROPANE_ICON, label: "Gas/propane refill" },
gpl: { icon: PROPANE_ICON, label: "LPG refill" },
lavage: { label: "Vehicle wash" },
laverie: { icon: LAUNDRY_ICON, label: "Laundry" },
piscine: { icon: SWIMMING_ICON, label: "Swimming pool" },
point_eau: { icon: DRINKING_WATER_ICON, label: "Drinking water" },
poubelle: { icon: TRASH_DUMPSTER_ICON, label: "Trash disposal" },
wc_public: { icon: RESTROOMS_ICON, label: "Public toilet" },
wifi: { icon: WIFI_ICON, label: "Wi-Fi" },
// Activities
baignade: { icon: SWIMMING_ICON, label: "Swimming" },
eaux_vives: { icon: RIVER_RAFTING_ICON, label: "Whitewater sports" },
escalade: { icon: CLIMBING_ICON, label: "Climbing" },
jeux_enfants: { icon: PLAYGROUND_ICON, label: "Playground" },
moto: { icon: MOTOR_BIKE_TRAIL_ICON, label: "Motorcycling" },
peche: { icon: FISHING_ICON, label: "Fishing" },
peche_pied: { icon: FISHING_ICON, label: "Shore fishing" },
point_de_vue: { icon: SCENIC_VIEWPOINT_ICON, label: "Scenic viewpoint" },
rando: { icon: WALKING_ICON, label: "Hiking" },
visites: { icon: GUIDED_TOURS_ICON, label: "Sightseeing" },
vtt: { icon: BICYCLE_TRAIL_ICON, label: "Mountain biking" },
windsurf: { icon: WIND_SURFING_ICON, label: "Windsurfing" },
};
// Extends POI_ICONS (and so POI_ICON_KEYS, and what a marker badge can
// show — see gpx.js's _registerCategoryGlyphs) with a handful of the same
// symbols PARK4NIGHT_TAGS above already vendors, reused rather than
// duplicated — this app's own hand-drawn notes (notes.js's icon picker)
// need marker-badge glyphs for "water source"/"dump station"/"viewpoint"
// far more than the original OSM-POI-upload set (parking/hotel/fuel) ever
// covered. Object.assign, not more entries in the POI_ICONS literal
// itself, since these constants are declared below it in this file.
Object.assign(POI_ICONS, {
amenity_drinking_water: DRINKING_WATER_ICON,
amenity_sanitary_dump_station: SANITARY_DISPOSAL_ICON,
amenity_toilets: RESTROOMS_ICON,
shop_gas: PROPANE_ICON,
amenity_electricity: ELECTRICAL_HOOKUP_ICON,
shop_laundry: LAUNDRY_ICON,
leisure_playground: PLAYGROUND_ICON,
tourism_viewpoint: SCENIC_VIEWPOINT_ICON,
leisure_swimming: SWIMMING_ICON,
leisure_fishing: FISHING_ICON,
sport_climbing: CLIMBING_ICON,
route_hiking: WALKING_ICON,
shop_supermarket: STORE_ICON,
shop_convenience: STORE_ICON,
});
// src/bookstore-22.svg (NPS symbol library, same source/license as
// POI_ICONS above) — used as the fixed marker glyph for the "Wikipedia"
// map layer (gpx.js), not part of POI_ICONS itself: that set is keyed by
// OSM/p4n2gpx category and doubles as the note icon-picker's option list
// (notes.js), neither of which applies here — every point on this layer
// gets the same one glyph, there's no per-feature category to key it by.
export const WIKI_ICON = `
<svg viewBox="0 0 22 22" fill="currentColor">
<path d="M16.6,20.7c-0.6,0-0.9-0.4-0.9-0.9c0-0.5,0.3-0.9,0.9-0.9c0.3,0,0.5-0.2,0.5-0.5
S16.9,18,16.6,18c-1.1,0-1.9,0.8-1.9,1.9c0,1,0.7,1.9,1.9,1.9c0.3,0,0.5-0.2,0.5-0.5S16.9,20.7,16.6,20.7L16.6,20.7z"/>
<path d="M5,18c0,0,0,0,0,0c0,3.1,0.5,4,2.7,4l8.9,0c0.3,0,0.5-0.2,0.5-0.5
c0-0.3-0.2-0.5-0.5-0.5H8c-1.5,0-2-0.5-2-3c0,0,0,0,0-0.1c0-0.3-0.2-0.5-0.5-0.5S5,17.7,5,18L5,18z"/>
<path d="M5,8c0-0.6,5-5,5-5h5h1c0.6,0,1,0.4,1,1v14c0,0.6-0.4,1-1,1H6c-0.6,0-1-0.4-1-1
V8z M9,4L6,18c0,0,10,0,10,0c0,0,0-14,0-14C16,4,9,4,9,4z"/>
<path d="M5,6.8c0-0.5,0.4-1.3,0.8-1.6l6.4-4.7C12.7,0.2,13,0.4,13,1v10
c0,0.6-0.3,1.7-0.7,2.1l-6.5,5.3C5.4,18.8,5,18.6,5,18V6.8z"/>
</svg>`;
export const LIVETRACK_ICON = `
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 21s7-7.58 7-12a7 7 0 0 0-14 0c0 4.42 7 12 7 12z"/>
<path d="M8.5 9a3.5 3.5 0 0 1 7 0" stroke-dasharray="1.5 2.2"/>
</svg>`;