AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻譯準備中
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Drop-in OpenStreetMap maps with custom colors. No API key, no Google, no build step — one folder, one div, one script tag.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A drop-in map for any website. It uses free OpenStreetMap data, so you don't need Google, an API key, a billing account, or a build step. You can recolor every part of it.
Live demo and theme builder → Examples: basic · multiple pins檢視完整 README ↗A drop-in map for any website. It uses free OpenStreetMap data, so you don't need Google, an API key, a billing account, or a build step. You can recolor every part of it.
Live demo and theme builder → Examples: basic · multiple pins
<div>, one <script>. You don't write any JavaScript unless you want to.Copy the openpin/ folder into your website, for example to /openpin/.
That's all there is to it. The folder holds everything the map needs: the script, its CSS, the map style, the icons, and MapLibre.
your-site/
├── index.html
└── openpin/ ← copy this whole folder
├── openpin.js
├── openpin.css
├── style.json
├── sprites/
└── maplibre/
Paste these two parts into your page wherever you want the map to appear:
<div
data-openpin
data-lat="30.79694"
data-lng="-86.68139"
data-zoom="14.7"
data-label="Baker Feed & Country Store"
data-home-label="Back to Baker"
style="height: 480px">
5791 Highway 4, Baker, Florida
</div>
<script type="module" src="/openpin/openpin.js"></script>
data-lat and data-lng to your location (see Finding your coordinates).<div>. Put your address there.<script> line once per page, even when the page has several maps.Browsers won't load this kind of script from a file you double-click (a file:// address). Run a small local web server from the folder that contains your page:
npx serve .
python -m http.server 8000
Then open the address it prints. On a real web host it works as is.
Theme builder: open index.html from this repo through a local server. You can pick a place and colors there, and it writes the code to paste for you.
<div data-openpin data-theme="midnight" ...></div>
| Theme | Look |
|---|---|
country (default) | Warm cream land, sage parks, golden highways, a barn-red pin |
coastal | Light and airy, blue water, a teal pin |
mono | Quiet grays that suit almost any brand |
midnight | A dark map with an amber pin |
sputnik | Deep navy land, golden highways, a red pin |
gmaps | Light gray land, sky-blue water, and yellow highways, like the big street-map apps |
vivid | Bright: cream land, electric-blue water, orange highways, a hot-pink pin |
evergreen | Greens throughout: sage land, deep-green highways, teal water |
blueprint | White linework on blueprint blue, a yellow pin |
vintage | A sepia paper atlas with rust-red highways |
Add data-colors with only the colors you want to change. Everything else comes from the theme.
<div
data-openpin
data-lat="30.79694" data-lng="-86.68139"
data-theme="coastal"
data-colors='{"pin": "#c2410c", "highway": "#f0a95b", "water": "#7fb8d6"}'
style="height: 480px">
</div>
Wrap
data-colorsin single quotes, because the JSON inside uses double quotes.
Every color you can set:
| Key | What it colors |
|---|---|
background | Open land (the base color of the map) |
developed | Towns, commercial, industrial, schools, parking |
green | Parks, fields, farmland, grass |
forest | Woods and forest |
bare | Sand, rock, glaciers |
water | Lakes, ocean, wide rivers |
waterway | Streams, canals, and narrow rivers (lines) |
building | Building fill |
buildingOutline | Building edges |
road | Regular streets and paths |
roadCasing | The thin edge line along roads |
highway | Highways and main roads |
rail | Railways |
boundary | State and country borders |
label | Street names, place names, all map text |
labelHalo | The glow behind map text that keeps it readable |
icon | Small point-of-interest icons and shields |
pin | Your location pin |
pinIcon | The house or dot inside the pin |
surface | Background of the buttons, pin label, and attribution |
text | Text and icons on those buttons |
border | Edges of those buttons |
Colors can be any CSS color: #c2410c, rgb(194 65 12), hsl(20 88% 40%), or tomato.
For a dark map, set surface to a dark color. The zoom buttons flip their icons automatically.
Tips for a good-looking map
background, developed, green, and forest close in brightness. They cover most of the map.label contrast strongly with background. Set labelHalo to roughly your background color.pin and highway the most saturated colors. They're what people look for first.The buttons and pin label use CSS custom properties, so you can override them in your own stylesheet:
.openpin {
--openpin-font: "DM Sans", sans-serif; /* defaults to your page's font */
--openpin-radius: 12px; /* button and label corners */
--openpin-shadow: none;
}
The text on the map itself (street names) uses Noto Sans from the tile server.
| Attribute | Example | Meaning |
|---|---|---|
data-openpin | (no value) | Required. Marks the element as a map. |
data-lat, data-lng | 30.79694, -86.68139 | Location. Required unless you use data-markers. |
data-zoom | 14.7 | 3 = country, 10 = city, 15 = streets, 18 = buildings. Default 14. |
data-label | Baker Feed & Country Store | Text above the pin. |
data-home-label | Back to Baker | Button that returns to the starting view. false hides it. |
data-address | 5791 Hwy 4, Baker, FL | Shown while loading or if the map fails. |
data-link | https://… | Where clicking the pin goes. Defaults to OpenStreetMap. |
data-theme | coastal | country, coastal, mono, midnight, sputnik, gmaps, vivid, evergreen, blueprint, or vintage. |
data-colors | '{"pin":"#c2410c"}' | Color overrides (JSON). |
data-markers | '[{"lat":30.4,"lng":-87.2,"label":"Pensacola"}]' | Several pins (JSON). The map fits them all on screen. |
data-pin | dot | Pin icon: house (default), dot, or none. |
data-scroll-zoom | true | cooperative (default, Ctrl/⌘ + scroll to zoom), true, or false. |
data-lazy | false | Load immediately instead of when the map is near the screen. |
For more control, import the module yourself:
<div id="locations" style="height: 520px"></div>
<script type="module">
import { createMap } from '/openpin/openpin.js';
const locations = createMap('#locations', {
theme: 'coastal',
colors: { pin: '#c2410c' },
homeLabel: 'Show all locations',
markers: [
{ lat: 30.4213, lng: -87.2169, label: 'Pensacola' },
{ lat: 30.3960, lng: -86.4958, label: 'Destin', pin: 'dot' },
{ lat: 30.7835, lng: -86.5547, label: 'Crestview', color: '#0f766e' },
],
});
// Later: recolor without reloading.
locations.setColors('midnight');
locations.setColors({ highway: '#ff9900' });
// Use the full MapLibre map once it's drawn.
const map = await locations.ready; // null if it couldn't load
map?.flyTo({ center: [-86.5547, 30.7835], zoom: 13 });
</script>
createMap(target, options) accepts the same settings as the attributes, written in camelCase (homeLabel, scrollZoom, zoomButtons, showLabels), plus:
| Option | Meaning |
|---|---|
center | [lng, lat] array or { lat, lng } object. |
markers | Array of { lat, lng, label?, link?, color?, pin?, showLabel? }. Use link: false for a pin that isn't a link. |
marker: false | Show no pin at all. |
minZoom, maxZoom | Zoom limits. Defaults are 2 and 18. |
padding | Space around pins when fitting several. A number, or {top, bottom, left, right}. |
timeout | Milliseconds to wait for tiles before showing the fallback. Default 20000. |
loadingText, unavailableText | Fallback messages. |
onReady(map, maplibregl) | Called once the map is drawn. |
mapOptions | Passed straight to MapLibre's Map. |
The returned controller has:
| Member | Meaning |
|---|---|
ready | A promise. Resolves with the MapLibre map, or null if the map couldn't load. |
map, maplibregl | The MapLibre map and library (null until loaded). |
setColors(themeOrColors) | Recolor live, using a theme name or a colors object. |
recenter() | Go back to the starting view. |
load() | Load now, even if the map is off screen. |
destroy() | Remove the map. |
Events: the map element fires openpin:ready (event.detail.map) and openpin:error. If tiles were slow but arrive later, openpin:ready still fires, even after openpin:error.
Other exports: themes, colorRoles, getMap(element), autoInit(root), resolveColors(theme, colors), toLngLat(value), and openStreetMapUrl([lng, lat]). The same functions are available as window.OpenPin for plain scripts.
latitude, longitude.You can also right-click any spot in Google Maps. The first line of the menu is latitude, longitude.
⚠️ When you write a location as an array, the order is
[longitude, latitude](x, y).{ lat, lng }objects anddata-lat/data-lngattributes avoid that mix-up.
Visitors usually want directions on their phone. You can link to any maps app. None of them need a key:
<!-- OpenStreetMap -->
<a href="https://www.openstreetmap.org/directions?to=30.79694%2C-86.68139">Get directions</a>
<!-- Apple Maps (opens the Maps app on iPhone and Mac) -->
<a href="https://maps.apple.com/?daddr=30.79694,-86.68139">Get directions</a>
<!-- Google Maps (a plain link; no API needed) -->
<a href="https://www.google.com/maps/dir/?api=1&destination=30.79694,-86.68139">Get directions</a>
openpin folder (by FTP or file manager on WordPress, or as hosted files elsewhere). Then paste the two-part snippet into a Custom HTML or Embed block and use the full URL in src.public/. Call createMap(ref) after the component mounts and controller.destroy() when it unmounts. Load it with import(/* @vite-ignore */ '/openpin/openpin.js') so your bundler doesn't try to bundle it.static/ or public/ and paste the snippet into a template.tiles.versatiles.org. It needs no key or sign-up. It's a community service, so for a high-traffic site, read their usage guide or host your own tiles. To switch tile servers, edit the sources and glyphs URLs in style.json.worker-src 'self' blob:, connect-src https://tiles.versatiles.org, and img-src data: blob:.| Problem | Fix |
|---|---|
| The map area is blank or 0px tall | Give the element a height (style="height: 480px"). |
| "Loading map…" never finishes on your computer | Use a local server (see step 3), not a double-clicked file. |
| Error in the console: Failed to load module script | The src path is wrong. Open that URL in your browser to check it. |
| The pin is in the ocean or the wrong hemisphere | Latitude and longitude are swapped. Arrays are [lng, lat]. |
| Nothing happens on a page that adds the div later (single-page apps) | Call OpenPin.autoInit() or createMap(el, …) after adding it. |
The OpenPin code is under the MIT License. The bundled MapLibre GL JS is BSD-3-Clause (openpin/maplibre/LICENSE.txt). The map style is adapted from the VersaTiles CC0 style. Map data © OpenStreetMap contributors (ODbL). See THIRD-PARTY-NOTICES.md.
data-zoom-buttons | false | Hide the + / − buttons. |
data-show-labels | false | Hide the text above pins. |
data-attribution | Map by <a href="…">You</a> | Extra credit in the (i) attribution, shown after "OpenPin by SputnikFX". |
aria-label | Map of our store | Name for screen readers. Default: "Map showing {label}". |