import { useEffect, useMemo, useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Link, useSearchParams } from "react-router"; import { classifyRarity, resolvePhenotype, exampleGenome, type Genome, } from "@botanica/genetics"; import { stages, type GrowthStage, type Background } from "@botanica/renderer"; import { PlantPreview } from "../components/PlantPreview"; import { GenomeEditor } from "../components/GenomeEditor"; import { ExportActions } from "../components/ExportActions"; import { QueryMessage } from "../components/QueryMessage"; import { api, plantQuery } from "../lib/api"; export function Lab() { const [search] = useSearchParams(), sourceId = search.get("plant") ?? ""; const catalog = useQuery({ queryKey: ["catalog"], queryFn: api.catalog }), source = useQuery({ ...plantQuery(sourceId), enabled: !!sourceId }); const [genome, setGenome] = useState(() => structuredClone(exampleGenome), ), [stage, setStage] = useState("flowering"), [seed, setSeed] = useState(8155), [golden, setGolden] = useState(false), [background, setBackground] = useState("warm"), [name, setName] = useState("My velvetleaf"); const client = useQueryClient(); const save = useMutation({ mutationFn: api.create, onSuccess: () => { void client.invalidateQueries({ queryKey: ["plants"] }); void client.invalidateQueries({ queryKey: ["collection-stats"] }); void client.invalidateQueries({ queryKey: ["parents"] }); }, }); useEffect(() => { if (source.data) { setGenome(structuredClone(source.data.genome)); setSeed(source.data.visualSeed); setGolden(false); setName((source.data.name + " study").slice(0, 60)); save.reset(); } }, [source.data]); const phenotype = useMemo( () => resolvePhenotype("velvetleaf", genome, golden ? ["golden_veins"] : []), [genome, golden], ), rarity = classifyRarity(phenotype); return ( <>

The plant laboratory

Grow something unexpected.

Edit paired alleles and see their expression. Save a designed founder, then cross saved plants in the breeding lab.

Open breeding lab →
{sourceId && source.isPending && } {source.error && ( void source.refetch()} /> )}
VELVETLEAF / LIVE PREVIEW Genome v1 · Renderer v1

{name || "Velvetleaf"}

{phenotype.pigment} · {phenotype.leafShape} ·{" "} {phenotype.leafPattern}

Resolved phenotype

{( [ "pigment", "leafShape", "leafPattern", "growthHabit", "flowerColor", "flowerDensity", ] as const ).map((key) => (
{key.replace(/([A-Z])/g, " $1")}
{phenotype[key]}
))}
Derived rarity
{rarity.tier} · {rarity.score}/100

{rarity.reasons .map((r) => r.label + " +" + r.points) .join("; ") || "No unusual traits."}

Policy v1 · preview classification {golden ? " includes a manual mutation" : ""}
); }