vccs
Vue 3용 차트 컴포넌트 모음, Recharts에서 포팅
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Get Cache is a mobile app used in the reforestation industry. See it on the
App Store (iPhone) and the
Play Store (Android).
The feature is an offline preview: it previews the map data stored on the
phone (or browser, since it is a Capacitor app) for use offline, and works
with no network. The vector roads and satellite tile
"blobs" are downloaded dynamically based on the user's location and the pins
and polygons added to the map. Repos:
offline preview GitHub ·
rapper GitHub
Then open.README 전문 보기 ↗Get Cache is a mobile app used in the reforestation industry. See it on the App Store (iPhone) and the Play Store (Android).
The feature is an offline preview: it previews the map data stored on the phone (or browser, since it is a Capacitor app) for use offline, and works with no network. The vector roads and satellite tile "blobs" are downloaded dynamically based on the user's location and the pins and pieces added to the map. Repos: offline preview GitHub · rapper GitHub
git clone https://github.com/Ground-Truth-Data/getCache_offlineMap
cd getCache_offlineMap
cp .env.schema .env # fill the two PUBLIC_GC_tiles_*_worker hosts — ask me for them
npm install
npm run dev # predev runs fetchAssets.sh for the basemap
Then open http://localhost:5173/offlinev10.
svelte.config.js and vite.config.ts expect _rapper/ (the app shell)
beside them. All three are generated by gitEr/syncRapper.sh in the fetch
workspace and never committed: a committed copy drifted from rapper.
Without PUBLIC_GC_tiles_prod_worker the satellite layer still draws but no vector roads
ever download, which looks like a bug rather than missing configuration. The
~50 MB basemap is NOT in git — mobileAssets/ holds only LICENSE.md
(proprietary terms); fetchAssets.sh copies it from a local
ReTreever/static/mobileAssets or downloads the assets-v1 release tarball.
You are set up when: the map shows, you drop a pin near Ottawa
(?at=45.42,-75.70&z=11), and roads appear inside the blob within a minute.
If the satellite photo appears but roads never do, .env is missing or wrong
— the console says so on the first line (PUBLIC_GC_tiles_prod_worker is not set).
?at=lat,lng&z= jumps the camera (lat first, the order a human reads one off
a screen). / lands on the offline preview too — see hooks.ts. The debug rails
are a toggle on the map itself, not a second URL.
I made an explainer video about the "blobs". Very basically I want the blobs to be 1) always on (nothing appears or disappears as you zoom in or out) 2) tiles arrive as fast as possible 3) tiles render as fast as possible. What blobs are meant to look like: a jagged disc of satellite photo and vector roads around a pin. Vector tiles come from a Cloudflare R2 bucket through a Cloudflare Worker (you run a local Worker to test); satellite photos from MapTiler through the same Worker; fires from the NASA FIRMS API. Everything lands in IndexedDB and renders with no network.
The Cloudflare Worker that serves tiles lives in this repo at
workers/worker-local-dev/ (worker-cloud-dev/ and worker-cloud-prod/ are
the copies each cloud tier runs). To run it locally:
cd workers/worker-local-dev && npm run dev, then pick the worker-local-dev
tier in the map's CONFIG card (lib/worker/README.md).
No keys are needed to work on this. The default tier is worker-cloud-dev,
already deployed and already holding every key. A local Worker without a
.dev.vars still serves roads; only /satellite and /fires 500 there, so
blobs bake with no photo and no fires. If you want
those two routes locally, put a gitignored workers/worker-local-dev/.dev.vars
with GC_mapTiler_key= and GC_firms_map_key= (ask Chris for the MapTiler one — the
licence is per-account; FIRMS is free at firms.modaps.eosdis.nasa.gov).
The offline preview is V10, routes/offlinev10/ (its README.md), served at
/app/offlinev10 by every parent. It downloads map tiles and satellite
photos for blobs around pins, stores them in IndexedDB, and renders them
(MapLibre GL) with no network. Tiles come from the Worker; satellite photos
from the imagery registry in lib/contract/satelliteSources.ts.
The debugger IS the map. Same component, docks beside it. Instruments attached to a stand-in produce confident wrong answers.
| Layer | Source | Always on? | Radius per pin |
|---|---|---|---|
| Vector roads — plus water, town labels, hospital/campsite POIs, all in the same blob | One Cloudflare R2 bucket (offline-tiles) holding a full-planet OpenStreetMap extract (planet.pmtiles); the Worker range-reads it and serves one tile per request | highways and major roads yes; small roads and water only inside a disc from z11 / z10 | RADIUS_KM (routes/offlinev10) |
| Satellite photo | MapTiler satellite-v2 at z17 (lib/onPhone/satellite/photoSources.ts), baked on the phone, proxied through the Worker's /satellite route so the key stays a Worker secret | yes | 2 km per photo; photos along a line overlap into a ribbon (lib/onPhone/satellite/satelliteImage.ts) |
| Fires | NASA FIRMS — VIIRS on NOAA-20, NOAA-21 and Suomi-NPP, last 48 h, proxied through the Worker's /fires route so the API key stays a Worker secret | yes — attachFireLayer (lib/onPhone/render/fireLayer.ts) | 500 km (lib/shared/fireContract.ts) |
| Hospitals | the Worker's /hospitals route, from the world list bundled in the Worker | yes | 500 km |
A phone holds at most 1 GB of offline preview data (routes/offlinev10/budget.ts); an LRU cache — a new area evicts the least recently seen, never what is on screen, and an evicted pin downloads again when it comes back into view.
All map code belongs in THIS repo. Not in a parent, not split across both.
getCache_OfflineMap is a narrow name for a folder that also holds fires, hospitals
and places — deliberate: this repo has the debugger, so code here can be
watched while it runs. Do not propose renaming it or a second "shared map" repo.
A parent reaches anything here through the $parent alias, never a relative
climb (rapper's noEscapePlugin throws during build), never a symlink:
import { attachFireLayer } from "$parent/siblings/getCache_OfflineMap/lib/onPhone/render/fireLayer";
| What | Where |
|---|---|
| The map (V10) | routes/offlinev10/ — read its README.md first |
| Fires engine | routes/fires/ — read routes/fires/docs/FIRES.md first |
| Hospitals | routes/hospitals/ — same pattern as fires: own pass, own cache, painted by the page |
| Fires Worker half | lib/worker/firesWorker.ts — workers/worker-local-dev/src/index.ts imports it relatively |
| Tile Worker (Cloudflare, R2) | workers/worker-local-dev/ — workers/worker-local-dev/README.md; worker-cloud-dev/, worker-cloud-prod/ are the deployed twins |
| Worker client (tiers, download, fires fetch) | lib/worker/ — lib/worker/README.md |
| Docs — this repo is PUBLIC: no secret, account or endpoint in any of them | docs/OFFLINE_PLAN.md (laws, stack, acceptance tests), docs/LINES_AND_CORRIDORS.md, routes/fires/docs/FIRES.md |
Map art (pins, fire_icon.webp, fire_intensity/, pdf_maps_icon.webp) | lib/assets/ — committed, imported by URL (import x from "../assets/….webp"), never a /mobileAssets/ string |
Basemap (worldBase, ~50 MB) | static/mobileAssets/worldBase/ (gitignored — fetchAssets.sh fills it; only mobileAssets/LICENSE.md is committed) |
| Storage, bake service, renderer, roads, satellite | lib/onPhone/ |
Tile contract (byte-identical to workers/worker-local-dev/src/) | lib/contract/ |
| Shared helpers, places index, debug panels, map UI components, map state stores | lib/shared/, lib/places/, lib/panels/, lib/mapUi/, lib/mapState/ |
Engine door — HostPorts | lib/shared/hostPorts.ts — Get Cache's implementation: getCache/src/lib/offline/host/retreeverPorts.ts |
Every lib/mapUi component takes a required ports: MapHostPorts prop; every
store factory that needs the host takes it as a parameter. Get Cache's real
store (v2MapStore.svelte.ts) is ASSIGNED to MapHostStore in
retreeverMapPorts.ts — that assignment is the type-check at the boundary.
The store stays in Get Cache on purpose — it IS the database. It comes in as
ports.store.
$lib, never
names a parent (lib/noParentNames.test.ts), never climbs out of itself.
Two doors: lib/shared/hostPorts.ts (data for the engine) and
lib/shared/mapHostPorts.ts (store, icons, share sheet, GPS, q704 for the
map UI). Add a member the day a file needs it.../ climb, never a symlink.tiles-prod is anonymous —
the app has no more standing than a stranger's curl, so a third party
could build their own service on the tile Worker. Add a shared token: the
client sends a header read from .env (beside PUBLIC_GC_tiles_prod_worker), the
Worker rejects requests without it. The token ships in a public web bundle,
so this is a fence, not a lock — the win is rotation. Build and test it
against worker-local-dev.lib/mapUi/ and lib/mapState/ are
mounted only by Get Cache, through retreeverMapPorts.ts.npm test here: rune files (*.svelte.ts and the tests that import them,
e.g. lib/shared/workMeter.test.ts) fail with $state is not defined
— this repo's bare vitest has no Svelte plugin, so they only run under a
parent's suite. routes/fires/masks/urbanExclusion.test.ts SKIPS until
./fetchAssets.sh has run. Anything else is yours.
Load it in a browser and look. Not the terminal, not a test — the screen. A test passing while the page rendered nothing happened repeatedly here.
If the console looks empty, check DevTools' "Custom levels" filter — it
hides console.log by default.
Map-UI door — MapHostPorts { store, ui, gps, scenes?, q704? } | lib/shared/mapHostPorts.ts — Get Cache's implementation: getCache/src/lib/offline/host/retreeverMapPorts.ts |