tane/apps/app_seeds/tool
vjrj a534c14983 refactor(branding): rename app Tanemaki → Tane
Public name is now Tane (種, "seed"); Tanemaki (種まき, "to scatter seeds")
is kept only as etymology in the About screen and onboarding.

App not yet distributed, so format tokens rename cleanly with no migration:
backup extension .tanemaki→.tane, QR scheme tanemaki://→tane://, file
prefixes tane-*. Website link and species-catalog User-Agent →
tane.comunes.org. Android label capitalised to "Tane".

Identity/crypto constants already use org.comunes.tane (derivation, HKDF
backup, sync namespace, TANE1 recovery tag) — left untouched, so keys,
backups and sync are unaffected. Tests updated; analyze + full suite green.
2026-07-12 13:04:16 +02:00
..
curated_overrides.json feat(species): expand catalog to ~1200 edible species from Wikidata 2026-07-10 02:00:47 +02:00
gen_species_catalog.dart refactor(branding): rename app Tanemaki → Tane 2026-07-12 13:04:16 +02:00
README.md feat(species): expand catalog to ~1200 edible species from Wikidata 2026-07-10 02:00:47 +02:00

Species catalog generator

Regenerates assets/catalog/species.json — the bundled, offline, multilingual catalog of edible / cultivated plant species the app seeds into the encrypted database at first run.

cd apps/app_seeds
dart run tool/gen_species_catalog.dart        # writes species.json (version 3)
dart run tool/gen_species_catalog.dart --dry  # prints stats, writes nothing

The generated JSON is committed to the repo — the app never queries the network for it (local-first, offline).

Sources & licensing

  • Names come only from Wikidata labels and aliases. Wikidata is CC0 (public domain), so the bundled data carries no attribution burden and is clean for redistribution under the app's AGPL-3.0 license.
  • gbif_key links the GBIF taxonomic backbone. It is used only as an identifier (a fact, not copyrightable text) — no GBIF vernacular text is bundled, so no CC-BY attribution is triggered.
  • Curated core crops (names, family and viability_years) live in curated_overrides.json, hand-maintained. For a listed species the curated common names win (placed first, never dropped) and its family/viability override Wikidata; Wikidata still adds more languages. A curated species is always kept even if it would miss the relevance floor.
  • viability_years (seed longevity) is not in Wikidata — it comes only from the curated overrides (public-domain agricultural-extension figures). Species without an entry simply get no age-based expiry warning.

What it does

  1. Phase 1 — species list (SPARQL): taxa with a binomial name that are a crop (P279* Q235352), the source/ingredient of a food (P1672/P366/reverse P1582P279* Q2095), with scientific name (P225) and GBIF key (P846).
  2. Phase 2 — names + family: rdfs:label (primary) + skos:altLabel (aliases), batched over the species and filtered to the bundled languages; the family is walked up P171* to the family-rank ancestor.
  3. Transform (buildCatalog, pure & unit-tested): dedup by scientific name; drop non-vernacular noise (the binomial itself, author citations, var./× ranks, abbreviated initials); merge the curated overrides (authoritative, first); require a real vernacular in ≥ 4 languages as a relevance floor so the long tail of obscure single-label taxa is dropped; sort; serialize.

The current run yields ~1200 species (assets/catalog/species.json ≈ 1.5 MB).

Bundled languages

es, en, fr, de, it, pt, ca, gl, eu, ar, zh, ja, ru — a multilingual seed, not a ceiling (Latin + Arabic RTL + CJK + Cyrillic). Edit kCatalogLanguages in gen_species_catalog.dart to widen coverage, then regenerate. A species with no name in any bundled language is dropped (add its language rather than assuming es/en).