From d2f947903545d2e494e21d64b715c2615729f83c Mon Sep 17 00:00:00 2001 From: "marcin p. joachimiak" <4625870+realmarcin@users.noreply.github.com> Date: Mon, 14 Sep 2026 17:51:35 -0700 Subject: [PATCH 01/11] fix: enforce honest taxon embedding coverage Refs #900; full verified graph regeneration remains tracked separately. --- src/communitymech/cli.py | 4 +- src/communitymech/embedding/aggregator.py | 55 +++++++---------- .../visualization/umap_generator.py | 16 ++--- tests/test_embedding/test_aggregator.py | 5 +- tests/test_graph_projection_correctness.py | 60 +++++++++++++++++++ 5 files changed, 94 insertions(+), 46 deletions(-) create mode 100644 tests/test_graph_projection_correctness.py diff --git a/src/communitymech/cli.py b/src/communitymech/cli.py index 78bb9ef7c..7a7d778eb 100644 --- a/src/communitymech/cli.py +++ b/src/communitymech/cli.py @@ -633,8 +633,8 @@ def _apply_batch_report(report_path: Path): ) @click.option( "--include-hosts/--exclude-hosts", - default=False, - help="Include non-microbial host taxa in representations (default: exclude)", + default=True, + help="Count all requested taxa (default); host exclusion requires independent evidence.", ) def generate_umap( communities_dir: Path, diff --git a/src/communitymech/embedding/aggregator.py b/src/communitymech/embedding/aggregator.py index 436e317c4..85e5d6d45 100644 --- a/src/communitymech/embedding/aggregator.py +++ b/src/communitymech/embedding/aggregator.py @@ -23,7 +23,7 @@ def aggregate_community( community_yaml_path: str, min_coverage: float = 0.5, aggregation_method: str = "mean", - exclude_hosts: bool = True, + exclude_hosts: bool = False, ) -> tuple[np.ndarray, dict[str, Any]] | None: """Aggregate embeddings for a community from its YAML file. @@ -31,20 +31,27 @@ def aggregate_community( community_yaml_path: Path to community YAML file min_coverage: Minimum fraction of taxa that must have embeddings aggregation_method: Aggregation method ("mean" or "sum") - exclude_hosts: If True, exclude non-microbial taxa (hosts) from coverage calculation + exclude_hosts: Deprecated; true fails without an independent host classifier. Returns: Tuple of (community_vector, metadata) or None if coverage too low Metadata includes: - coverage_pct: Percentage of taxa with embeddings - - num_taxa: Total number of taxa in community - - num_microbial_taxa: Number of microbial taxa (when exclude_hosts=True) + - num_taxa: Number of unique requested taxa + - num_embedded_taxa: Number of requested taxa with vectors - taxa_found: List of taxa IDs found in embeddings - taxa_missing: List of taxa IDs missing from embeddings - - taxa_excluded: List of host taxa excluded (when exclude_hosts=True) + - taxa_excluded: Empty; no host classification was attempted - aggregation_method: Method used for aggregation """ + if exclude_hosts: + raise ValueError( + "Host exclusion requires independent taxonomy evidence; " + "missing vectors are not hosts" + ) + if not 0 <= min_coverage <= 1: + raise ValueError("min_coverage must be between 0 and 1") # Parse YAML with open(community_yaml_path) as f: community_data = yaml.safe_load(f) @@ -59,7 +66,6 @@ def aggregate_community( found_embeddings = [] found_ids = [] missing_ids = [] - excluded_ids = [] for taxon_id in taxon_ids: if taxon_id in self.embeddings: @@ -68,25 +74,10 @@ def aggregate_community( else: missing_ids.append(taxon_id) - # Determine coverage denominator based on exclude_hosts setting - if exclude_hosts: - # Only count taxa that have embeddings (microbes) in denominator - # Taxa without embeddings are assumed to be hosts and excluded - excluded_ids = missing_ids.copy() - missing_ids = [] - microbial_taxa_count = len(found_ids) - coverage = 1.0 if microbial_taxa_count > 0 else 0.0 - else: - # Traditional coverage: found / total - microbial_taxa_count = len(taxon_ids) - coverage = len(found_ids) / len(taxon_ids) if taxon_ids else 0.0 - - # Skip if no microbial taxa found - if not found_embeddings: - return None - - # Check coverage (only relevant when exclude_hosts=False) - if not exclude_hosts and coverage < min_coverage: + # Every unique requested taxon is in the denominator. An absent + # graph vector is missing data, never evidence of a host classification. + coverage = len(found_ids) / len(taxon_ids) + if not found_embeddings or coverage < min_coverage: return None # Aggregate embeddings @@ -101,14 +92,14 @@ def aggregate_community( metadata = { "coverage_pct": coverage * 100, "num_taxa": len(taxon_ids), - "num_microbial_taxa": microbial_taxa_count, + "num_embedded_taxa": len(found_ids), + "coverage_denominator": "unique_requested_taxa", "taxa_found": found_ids, "taxa_missing": missing_ids, "aggregation_method": aggregation_method, } - if exclude_hosts: - metadata["taxa_excluded"] = excluded_ids + metadata["taxa_excluded"] = [] return community_vector, metadata @@ -135,14 +126,14 @@ def _extract_taxon_ids(self, community_data: dict[str, Any]) -> list[str]: if taxon_id and taxon_id.startswith("NCBITaxon:"): taxon_ids.append(taxon_id) - return taxon_ids + return list(dict.fromkeys(taxon_ids)) def aggregate_communities( self, community_dir: str, min_coverage: float = 0.5, aggregation_method: str = "mean", - exclude_hosts: bool = True, + exclude_hosts: bool = False, ) -> tuple[dict[str, np.ndarray], dict[str, dict[str, Any]]]: """Aggregate all communities in a directory. @@ -150,7 +141,7 @@ def aggregate_communities( community_dir: Directory containing community YAML files min_coverage: Minimum coverage threshold aggregation_method: Aggregation method - exclude_hosts: If True, exclude non-microbial taxa from coverage calculation + exclude_hosts: Deprecated; true requires an independent host classifier. Returns: Tuple of: @@ -178,6 +169,6 @@ def aggregate_communities( community_vectors[community_id] = vector community_metadata[community_id] = metadata else: - print(f"āš ļø Skipping {community_id} (no microbial taxa with embeddings)") + print(f"āš ļø Skipping {community_id} (no vectors or below minimum taxon coverage)") return community_vectors, community_metadata diff --git a/src/communitymech/visualization/umap_generator.py b/src/communitymech/visualization/umap_generator.py index 2f7331700..08086efae 100644 --- a/src/communitymech/visualization/umap_generator.py +++ b/src/communitymech/visualization/umap_generator.py @@ -33,7 +33,7 @@ def generate( n_neighbors: int = 15, min_dist: float = 0.1, min_coverage: float = 0.5, - exclude_hosts: bool = True, + exclude_hosts: bool = False, ): """Generate interactive UMAP visualization. @@ -50,7 +50,7 @@ def generate( n_neighbors: UMAP n_neighbors parameter min_dist: UMAP min_dist parameter min_coverage: Minimum embedding coverage for communities - exclude_hosts: Exclude non-microbial taxa (hosts) from representation + exclude_hosts: Deprecated; true fails without independent host evidence. """ output_path = Path(output_path) if output_path is not None else DOCS / "community_umap.html" print("=" * 60) @@ -72,10 +72,7 @@ def generate( print(f"\nšŸ“¦ Aggregated {len(community_vectors)} communities") skipped = self._count_yaml_files(communities_dir) - len(community_vectors) - if exclude_hosts: - print(f" (excluded non-microbial host taxa from {skipped} communities)") - else: - print(f" (skipped {skipped} due to low coverage)") + print(f" (skipped {skipped} due to no vectors or low taxon coverage)") # Step 3: Run dimensionality reduction (PaCMAP default, UMAP optional) reducer = UMAPReducer( @@ -150,8 +147,7 @@ def _build_community_data( # Get name name = yaml_data.get("name", community_id.replace("_", " ")) - # Use microbial taxa count if available (when exclude_hosts=True) - num_taxa = metadata.get("num_microbial_taxa", metadata.get("num_taxa", 0)) + num_taxa = metadata.get("num_taxa", 0) community_data.append( { @@ -166,6 +162,10 @@ def _build_community_data( "num_taxa": num_taxa, "num_interactions": num_interactions, "coverage_pct": metadata.get("coverage_pct", 0.0), + "coverage_denominator": metadata.get("coverage_denominator", "unknown"), + "num_embedded_taxa": metadata.get("num_embedded_taxa", 0), + "taxa_missing": metadata.get("taxa_missing", []), + "aggregation_method": metadata.get("aggregation_method", "unknown"), "url": f"communities/{community_id}.html", } ) diff --git a/tests/test_embedding/test_aggregator.py b/tests/test_embedding/test_aggregator.py index 38a50818f..76cbab1fe 100644 --- a/tests/test_embedding/test_aggregator.py +++ b/tests/test_embedding/test_aggregator.py @@ -86,10 +86,7 @@ def test_aggregator_low_coverage(): try: aggregator = CommunityVectorAggregator(embeddings) # Only 1/3 taxa have embeddings, below 0.5 threshold. - # Pass exclude_hosts=False so the strict coverage check applies; - # the default exclude_hosts=True treats missing taxa as hosts and - # would consider this community fully covered. - result = aggregator.aggregate_community(yaml_path, min_coverage=0.5, exclude_hosts=False) + result = aggregator.aggregate_community(yaml_path, min_coverage=0.5) assert result is None diff --git a/tests/test_graph_projection_correctness.py b/tests/test_graph_projection_correctness.py new file mode 100644 index 000000000..c28cb3b18 --- /dev/null +++ b/tests/test_graph_projection_correctness.py @@ -0,0 +1,60 @@ +"""Unknown vectors cannot supply host evidence or increase taxon coverage.""" + +import numpy as np +import pytest +import yaml + +from communitymech.embedding.aggregator import CommunityVectorAggregator + + +def community(tmp_path, taxa): + path = tmp_path / "example.yaml" + path.write_text( + yaml.safe_dump({"taxonomy": [{"taxon_term": {"term": {"id": taxon}}} for taxon in taxa]}) + ) + return str(path) + + +def test_default_threshold_counts_missing_taxa(tmp_path): + path = community(tmp_path, ["NCBITaxon:1", "NCBITaxon:2"]) + aggregator = CommunityVectorAggregator({"NCBITaxon:1": np.array([1.0, 2.0])}) + assert aggregator.aggregate_community(path, min_coverage=0.9) is None + vector, metadata = aggregator.aggregate_community(path, min_coverage=0.5) + np.testing.assert_array_equal(vector, [1.0, 2.0]) + assert metadata["coverage_pct"] == 50.0 + assert metadata["num_taxa"] == 2 + assert metadata["num_embedded_taxa"] == 1 + assert metadata["taxa_missing"] == ["NCBITaxon:2"] + assert metadata["taxa_excluded"] == [] + assert metadata["coverage_denominator"] == "unique_requested_taxa" + assert "num_microbial_taxa" not in metadata + + +def test_duplicate_taxa_neither_reweight_vectors_nor_denominator(tmp_path): + path = community(tmp_path, ["NCBITaxon:1", "NCBITaxon:1", "NCBITaxon:2"]) + aggregator = CommunityVectorAggregator( + {"NCBITaxon:1": np.array([0.0, 2.0]), "NCBITaxon:2": np.array([2.0, 0.0])} + ) + vector, metadata = aggregator.aggregate_community(path) + np.testing.assert_array_equal(vector, [1.0, 1.0]) + assert metadata["num_taxa"] == 2 + summed, _ = aggregator.aggregate_community(path, aggregation_method="sum") + np.testing.assert_array_equal(summed, [2.0, 2.0]) + + +def test_unsupported_host_exclusion_and_invalid_threshold_fail(tmp_path): + path = community(tmp_path, ["NCBITaxon:1"]) + aggregator = CommunityVectorAggregator({}) + with pytest.raises(ValueError, match="independent taxonomy evidence"): + aggregator.aggregate_community(path, exclude_hosts=True) + for invalid in (-0.1, 1.1): + with pytest.raises(ValueError, match="min_coverage"): + aggregator.aggregate_community(path, min_coverage=invalid) + assert aggregator.aggregate_community(path, min_coverage=0) is None + + +def test_cli_defaults_include_all_requested_taxa(): + from communitymech.cli import generate_umap + + parameter = next(item for item in generate_umap.params if item.name == "include_hosts") + assert parameter.default is True From fcf0127e6371cc3d3e072a3bf0bfb5f230c380cc Mon Sep 17 00:00:00 2001 From: "marcin p. joachimiak" <4625870+realmarcin@users.noreply.github.com> Date: Mon, 14 Sep 2026 18:07:40 -0700 Subject: [PATCH 02/11] feat: export versioned semantic text for shared fleet maps --- docs/TEXT_MAP_INPUTS.md | 22 + .../Aspergillus_Indium_LED_Recovery.html | 1480 ++++++++++++++++ ...ls_MODEL2204300002_Kefir_Rothia_Model.html | 1305 ++++++++++++++ .../Chromobacterium_Gold_Biocyanidation.html | 1518 ++++++++++++++++ .../Methylobacterium_REE_Ewaste_Platform.html | 1567 +++++++++++++++++ justfile | 16 +- scripts/text_map_inputs.py | 7 + src/communitymech/render.py | 23 + src/communitymech/text_map_inputs.py | 257 +++ tests/test_text_map_inputs.py | 169 ++ 10 files changed, 6360 insertions(+), 4 deletions(-) create mode 100644 docs/TEXT_MAP_INPUTS.md create mode 100644 docs/isolates/Aspergillus_Indium_LED_Recovery.html create mode 100644 docs/isolates/BioModels_MODEL2204300002_Kefir_Rothia_Model.html create mode 100644 docs/isolates/Chromobacterium_Gold_Biocyanidation.html create mode 100644 docs/isolates/Methylobacterium_REE_Ewaste_Platform.html create mode 100755 scripts/text_map_inputs.py create mode 100644 src/communitymech/text_map_inputs.py create mode 100644 tests/test_text_map_inputs.py diff --git a/docs/TEXT_MAP_INPUTS.md b/docs/TEXT_MAP_INPUTS.md new file mode 100644 index 000000000..10b87829c --- /dev/null +++ b/docs/TEXT_MAP_INPUTS.md @@ -0,0 +1,22 @@ +# Common semantic text map inputs + +Includes canonical community records and separately stored isolate records in +the text map; the graph community projection keeps its own population policy. +Stable CommunityMech IDs link to existing community pages. Text includes names, +descriptions, ecological class/state, environments, named taxa/roles, +interactions and measured environmental factors. Citations, evidence snippets, +history, grounding annotations and identifiers are excluded. + +Export with `just text-map-inputs --output data/text_map/inputs.jsonl`. Without `--output`, the command validates a preview. `--record` (repeatable repository-relative YAML path) and `--limit` explicitly select canary subsets; ordinary exports cover every eligible record. + +Each JSONL row has exactly `identifier`, `label`, `category`, `page`, `source_path`, `text`, `text_sha256`, and `adapter_version`. The text digest is SHA-256 over the exact UTF-8 text. Input order and text are deterministic; duplicate IDs and unreadable records fail. This adapter makes no model call. Common model/projection generation and publication require the fleet pipeline and full-input checks. + +Changing provenance-only fields leaves semantic text unchanged. Editing a selected semantic field changes its digest. This text view supplements the existing graph view; it does not alter graph aggregation or its scientific interpretation. + +The `page` field is relative to the directory containing the published map +folder: from `text-map/index.html`, the shared renderer uses `../` plus `page`. +This repository publishes the contents of `docs/`, so the bundle is staged at +`docs/text-map/` and links resolve to records in the same published site root. + +Isolate detail pages are published in `docs/isolates/` by `just gen-html`; +the community browser and graph population remain communities only. diff --git a/docs/isolates/Aspergillus_Indium_LED_Recovery.html b/docs/isolates/Aspergillus_Indium_LED_Recovery.html new file mode 100644 index 000000000..97ee2b1c8 --- /dev/null +++ b/docs/isolates/Aspergillus_Indium_LED_Recovery.html @@ -0,0 +1,1480 @@ + + + + + + Aspergillus Indium LCD Recovery Platform - CommunityMech + + + +
+
+ ← Back to Communities +

Aspergillus Indium LCD Recovery Platform

+
+
+ +
+ +
+ +
+ + + +
+

An engineered Aspergillus niger monoculture bioplatform for recovering indium from waste liquid crystal display panels by indirect fungal bioleaching. The 2021 study compared three bioleaching approaches from general and optimized fermentation systems, showed that fermentation-method optimization improved indium bioleaching efficiency from 12.3% to 100%, and identified carboxy groups from organic acids and proteins as the critical proton donors for indium leaching. The abstract also reports that optimized fermentation increased dissociative H+, effective carboxyl groups for metal oxide leaching, and oxalic acid output, whereas A. niger biomass interfered with indium recovery by blocking H+ access to the oxide phase and adsorbing In3+. +

+
+ + + + +
+

Taxonomy

+ + + + + + + + + + + + + + + + + + + + + + + + +
TaxonOntology IDFunctional RolesAbundance
+ Aspergillus niger + + + NCBITaxon:5061 + + + +
+ + PRIMARY_PRODUCER + + PRIMARY_DEGRADER + +
+ +
DOMINANT
+
    + +
  • + + PMID:34111782 + + - SUPPORT (IN_VITRO) + +
    "niger) to produce low-concentration organic acids is challenging for dissolving In3O2 from waste LCD (liquid crystal display) panels with high toxicity"
    + +
  • + +
+
+
+ +
+

Ecological Interactions

+ + + +
+
+ + Ecological interaction network for Aspergillus Indium LCD Recovery Platform + Bipartite graph where circle nodes represent taxa and each ecological interaction is drawn as a distinct non-circular symbol, with colour repeating the same distinction. + +
+
+ Taxon +
+
+ Other +
+
+
+ + +
+
+

Fermentation Component Optimization

+ +
+ + +

Source Taxon: Aspergillus niger

+ + + + + +

Metabolites: + + oxalic acid + (CHEBI:16995), + + hydron + (CHEBI:15378) + +

+ + + +

Biological Processes:

+
    + +
  • + organic acid biosynthetic process + (GO:0016053) +
  • + +
  • + carboxylic acid metabolic process + (GO:0019752) +
  • + +
+ + + +
+ Downstream Effects: + +
+ → Carboxy-Group Proton Release for Indium Leaching +
+ +
+ + + +

Evidence

+
    + +
  • +
    + + PMID:34111782 + + - SUPPORT (IN_VITRO) +
    + +
    "The effective components increased after optimizing, including the dissociative H+ concentration, the effective carboxyl groups for leaching metal oxides, and the output of oxalic acid"
    + +
  • + +
+ +
+ +
+
+

Carboxy-Group Proton Release for Indium Leaching

+ +
+ + +

Source Taxon: Aspergillus niger

+ + + + + +

Metabolites: + + oxalic acid + (CHEBI:16995), + + protein + (CHEBI:36080), + + hydron + (CHEBI:15378) + +

+ + + +

Biological Processes:

+ + + + +
+ Downstream Effects: + +
+ → Indium Oxide Dissolution and Mobilization +
+ +
+ + + +

Evidence

+
    + +
  • +
    + + PMID:34111782 + + - SUPPORT (IN_VITRO) +
    + +
    "Carboxy groups from organic acids and proteins were the critical substances to release H+ for leaching indium mainly competed with iron via reactions analysis"
    + +
  • + +
+ +
+ +
+
+

Indium Oxide Dissolution and Mobilization

+ +
+ + +

Source Taxon: Aspergillus niger

+ + + + + +

Metabolites: + + indium(3+) + (CHEBI:49664), + + hydron + (CHEBI:15378) + +

+ + + +

Biological Processes:

+ + + + +
+ Downstream Effects: + +
+ → Fermentation-Broth Indium Recovery +
+ +
+ + + +

Evidence

+
    + +
  • +
    + + PMID:34111782 + + - SUPPORT (IN_VITRO) +
    + +
    "niger) to produce low-concentration organic acids is challenging for dissolving In3O2 from waste LCD (liquid crystal display) panels with high toxicity"
    + +
  • + +
+ +
+ +
+
+

Biomass Inhibition of Indium Recovery

+ +
+ + +

Source Taxon: Aspergillus niger

+ + + + + +

Metabolites: + + indium(3+) + (CHEBI:49664), + + hydron + (CHEBI:15378) + +

+ + + + + +
+ Downstream Effects: + +
+ → Fermentation-Broth Indium Recovery +
+ +
+ + + +

Evidence

+
    + +
  • +
    + + PMID:34111782 + + - SUPPORT (IN_VITRO) +
    + +
    "A. niger biomass prevented the contact between H+ and In3O2 and adsorbed In3+ adverse to indium recovery"
    + +
  • + +
+ +
+ +
+
+

Fermentation-Broth Indium Recovery

+ +
+ + +

Source Taxon: Aspergillus niger

+ + + + + +

Metabolites: + + indium(3+) + (CHEBI:49664) + +

+ + + + + + + +

Evidence

+
    + +
  • +
    + + PMID:34111782 + + - SUPPORT (IN_VITRO) +
    + +
    "The indium bioleaching efficiency can be improved from 12.3% to 100% by fermentation method optimization"
    + +
  • + +
  • +
    + + PMID:34111782 + + - SUPPORT (IN_VITRO) +
    + +
    "The bioleaching effects of fermentation broth for indium can be further promoted by controlling bioleaching process parameters"
    + +
  • + +
+ +
+ + +
+ + + + + + + + +
+

Environmental Factors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FactorValueUnit
Fermentation Method Optimization100% indium bioleaching efficiency
+
    + +
  • + + PMID:34111782 + + - SUPPORT (IN_VITRO) + +
    "The indium bioleaching efficiency can be improved from 12.3% to 100% by fermentation method optimization"
    + +
  • + +
+
Effective Leaching Componentsoptimized H+, carboxyl groups, and oxalic acid outputN/A
+
    + +
  • + + PMID:34111782 + + - SUPPORT (IN_VITRO) + +
    "The effective components increased after optimizing, including the dissociative H+ concentration, the effective carboxyl groups for leaching metal oxides, and the output of oxalic acid"
    + +
  • + +
+
Bioleaching Process Parameterstunable fermentation-broth leaching parametersN/A
+
    + +
  • + + PMID:34111782 + + - SUPPORT (IN_VITRO) + +
    "The bioleaching effects of fermentation broth for indium can be further promoted by controlling bioleaching process parameters"
    + +
  • + +
+
A. niger Biomassinhibitory to indium recoveryN/A
+
    + +
  • + + PMID:34111782 + + - SUPPORT (IN_VITRO) + +
    "A. niger biomass prevented the contact between H+ and In3O2 and adsorbed In3+ adverse to indium recovery"
    + +
  • + +
+
+
+ + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/docs/isolates/BioModels_MODEL2204300002_Kefir_Rothia_Model.html b/docs/isolates/BioModels_MODEL2204300002_Kefir_Rothia_Model.html new file mode 100644 index 000000000..1f180abb6 --- /dev/null +++ b/docs/isolates/BioModels_MODEL2204300002_Kefir_Rothia_Model.html @@ -0,0 +1,1305 @@ + + + + + + BioModels MODEL2204300002 Kefir Rothia Model - CommunityMech + + + +
+
+ ← Back to Communities +

BioModels MODEL2204300002 Kefir Rothia Model

+
+
+ +
+ +
+ +
+ + + +
+

BioModels record MODEL2204300002 contains a genome-scale metabolic model for Rothia kefirresidentii KRP, a kefir-grain isolate whose genome was used in kefir community amino-acid flux modeling.

+
+ + + + +
+

Taxonomy

+ + + + + + + + + + + + + + + + + + + + + + + + +
TaxonOntology IDFunctional RolesAbundance
+ Rothia kefirresidentii KRP + + + NCBITaxon:32207 + + + + N/A
+
    + +
  • + + PMID:28963201 + + - SUPPORT (IN_VITRO) + +
    "Rothia kefirresidentii KRP, and Streptococcus kefirresidentii YK, isolated from kefir grains collected from private sources in Germany"
    + +
  • + +
  • + + PMID:28963201 + + - SUPPORT (IN_VITRO) + +
    "NDFM00000000 for R.Ā kefirresidentii KRP"
    + +
  • + +
+
+
+ +
+

Ecological Interactions

+ + + +
+
+ + Ecological interaction network for BioModels MODEL2204300002 Kefir Rothia Model + Bipartite graph where circle nodes represent taxa and each ecological interaction is drawn as a distinct non-circular symbol, with colour repeating the same distinction. + +
+
+ Taxon +
+
+ Other +
+
+
+ + +
+
+

Rothia KRP GAM Agar Isolation

+ +
+ + + + + + + + +

Biological Processes:

+ + + + +
+ Downstream Effects: + +
+ → Rothia KRP Whole-Genome Assembly +
+ +
+ + + +

Evidence

+
    + +
  • +
    + + PMID:28963201 + + - SUPPORT (IN_VITRO) +
    + +
    "R. kefirresidentii KRP (ISC 156) was isolated from ground kefir grains, plated in serial dilutions on GAM agar and grown for 2 days at 30°C"
    + +
  • + +
+ +
+ +
+
+

Rothia KRP Whole-Genome Assembly

+ +
+ + + + + + +

Metabolites: + + deoxyribonucleic acid + (CHEBI:16991) + +

+ + + + + +
+ Downstream Effects: + +
+ → Rothia KRP Genome-Scale Amino-Acid Flux Model +
+ +
+ + + +

Evidence

+
    + +
  • +
    + + PMID:28963201 + + - SUPPORT (IN_VITRO) +
    + +
    "The draft genome sizes are 5,057,314Ā bp (GC content, 45.62%) for B.Ā kefirresidentii Opo, 2,522,693Ā bp (GC content, 58.47%) for R.Ā kefirresidentii KRP"
    + +
  • + +
  • +
    + + PMID:28963201 + + - SUPPORT (IN_VITRO) +
    + +
    "NDFM00000000 for R.Ā kefirresidentii KRP"
    + +
  • + +
+ +
+ +
+
+

Rothia KRP Genome-Scale Amino-Acid Flux Model

+ +
+ + + + + + +

Metabolites: + + amino acid + (CHEBI:33709) + +

+ + + +

Biological Processes:

+
    + +
  • + amino acid metabolic process + (GO:0006520) +
  • + +
  • + amino acid transport + (GO:0006865) +
  • + +
+ + + + + +

Evidence

+
    + +
  • +
    + + PMID:33398099 + + - SUPPORT (COMPUTATIONAL) +
    + +
    "Genome-scale metabolic models were reconstructed for all bacterial species"
    + +
  • + +
  • +
    + + PMID:33398099 + + - SUPPORT (COMPUTATIONAL) +
    + +
    "The models were used to simulate the expected uptake/secretion rates of amino acids using flux balance analysis"
    + +
  • + +
+ +
+ + +
+ + + +
+

Associated Datasets

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DatasetTypeRepositoryAccession
+ BioModels model file + +
SBML file deposited as MODEL2204300002. + +
OTHEROTHER + + MODEL2204300002.xml + +
+ Primary publication + +
Publication associated with kefir microbial interaction modeling. + +
OTHEROTHER + + doi:10.1038/s41564-020-00816-5 + +
+ Rothia kefirresidentii KRP WGS assembly + +
DDBJ/ENA/GenBank whole-genome shotgun accession for the KRP draft genome. + +
OTHEROTHER + + NDFM00000000 + +
+
+ + + + +
+

External Resources

+ + + + + + + + + + + + + + + + + + + + + + +
NameRepositoryResource ID
+ BioModels entry + +
Kefir interactions model for Rothia kefirresidentii KRP. + +
BIOMODELS + + MODEL2204300002 + +
+
    + +
  • + + PMID:33398099 + + - SUPPORT (COMPUTATIONAL) + +
    "Metabolic cooperation and spatiotemporal niche partitioning in a kefir microbial community."
    + +
  • + +
+
+
+ + + + + + +
+

Growth Media

+ + + +
+ +
+ + + + + + + + + + \ No newline at end of file diff --git a/docs/isolates/Chromobacterium_Gold_Biocyanidation.html b/docs/isolates/Chromobacterium_Gold_Biocyanidation.html new file mode 100644 index 000000000..736d4173e --- /dev/null +++ b/docs/isolates/Chromobacterium_Gold_Biocyanidation.html @@ -0,0 +1,1518 @@ + + + + + + Chromobacterium Gold Biocyanidation Platform - CommunityMech + + + +
+
+ ← Back to Communities +

Chromobacterium Gold Biocyanidation Platform

+
+
+ +
+ +
+ +
+ + + +
+

An engineered bioplatform utilizing the purple pigmented bacterium Chromobacterium violaceum for sustainable gold extraction from refractory ores and electronic waste through biological cyanide production (biocyanidation). This system represents an environmentally-friendly alternative to conventional chemical cyanide leaching, producing controlled amounts of biogenic cyanide that complexes gold as soluble Au(CN)₂⁻ while simultaneously metabolizing excess cyanide to prevent environmental toxicity. C. violaceum is a versatile heterotrophic bacterium that produces the purple pigment violacein and synthesizes cyanide through hydrogen cyanide (HCN) biosynthesis pathways. The bacterium is pre-grown in nutrient medium to stationary phase, then activated for cyanide production upon exposure to ground refractory gold ores or electronic scrap (PCBs, connectors). Operating at near-neutral pH (6.5-7.5) and mesophilic temperature (28-32°C), the system achieves gold extraction efficiencies comparable to chemical cyanidation (70-85% recovery) from refractory sulfide ores and precious metal-bearing e-waste. The process requires ore grinding pretreatment to liberate gold particles and operates in aerated bioreactors with glycerol or glucose as carbon source. Biocyanidation kinetics are slower than chemical leaching (7-14 days vs. 24-48 hours) but offer significant advantages: lower cyanide concentrations (50-200 ppm vs. 500-2000 ppm), ambient temperature operation, biological cyanide detoxification, and reduced environmental liability. The platform enables decentralized gold recovery from low-grade ores and artisanal mining operations while avoiding hazardous chemical transport. Gold is recovered from pregnant leach solution by activated carbon adsorption followed by elution and electrowinning or zinc cementation. +

+
+ + + + +
+

Taxonomy

+ + + + + + + + + + + + + + + + + + + + + + + + +
TaxonOntology IDFunctional RolesAbundance
+ Chromobacterium violaceum + + + NCBITaxon:536 + + + +
+ + PRIMARY_PRODUCER + + PRIMARY_DEGRADER + +
+ +
DOMINANT
+ +
+
+ +
+

Ecological Interactions

+ + + +
+
+ + Ecological interaction network for Chromobacterium Gold Biocyanidation Platform + Bipartite graph where circle nodes represent taxa and each ecological interaction is drawn as a distinct non-circular symbol, with colour repeating the same distinction (mutualism, competition, commensalism). + +
+
+ Taxon +
+
+ Mutualism +
+
+ Competition +
+
+ Commensalism +
+
+
+ + +
+
+

Biogenic Cyanide Production from Glycine

+ COMMENSALISM +
+ + +

Source Taxon: Chromobacterium violaceum

+ + + + + +

Metabolites: + + glycine + (CHEBI:15428), + + hydrogen cyanide + (CHEBI:18407), + + cyanide + (CHEBI:17514), + + glycerol + (CHEBI:17754), + + D-glucose + (CHEBI:17634) + +

+ + + +

Biological Processes:

+
    + +
  • + hydrogen cyanide biosynthetic process + (GO:0046202) +
  • + +
  • + glycine metabolic process + (GO:0006544) +
  • + +
+ + + +
+ Downstream Effects: + +
+ → Gold Cyanide Complexation and Dissolution +
+ +
+ + + +

Evidence

+ + +
+ +
+
+

Gold Cyanide Complexation and Dissolution

+ MUTUALISM +
+ + +

Source Taxon: Chromobacterium violaceum

+ + + + + +

Metabolites: + + cyanide + (CHEBI:17514), + + gold atom + (CHEBI:29287), + + dicyanoaurate(1-) + (CHEBI:49491), + + dioxygen + (CHEBI:15379), + + arsenopyrite + (CHEBI:75861), + + pyrite + (CHEBI:86471) + +

+ + + + + + + +

Evidence

+
    + +
  • +
    + + doi:10.1007/s10163-014-0276-4 + + - SUPPORT (IN_VITRO) +
    + +
    "used to leach out gold from the waste printed circuit boards"
    + +
  • + +
  • +
    + + doi:10.1007/s10163-014-0276-4 + + - SUPPORT (IN_VITRO) +
    + +
    "Bioleaching of gold from waste printed circuit boards by Chromobacterium violaceum"
    + +
  • + +
+ +
+ +
+
+

Oxygen-Supported PCB Gold Leaching

+ COMMENSALISM +
+ + +

Source Taxon: Chromobacterium violaceum

+ + + + + +

Metabolites: + + hydrogen cyanide + (CHEBI:18407), + + dioxygen + (CHEBI:15379), + + gold atom + (CHEBI:29287) + +

+ + + +

Biological Processes:

+ + + + + + +

Evidence

+ + +
+ +
+
+

Ore Pretreatment and Particle Size Effects

+ COMPETITION +
+ + +

Source Taxon: Chromobacterium violaceum

+ + + + + +

Metabolites: + + arsenopyrite + (CHEBI:75861), + + pyrite + (CHEBI:86471) + +

+ + + +

Biological Processes:

+
    + +
  • + response to metal ion + (GO:0010038) +
  • + +
+ + + +
+ Downstream Effects: + +
+ → Gold Cyanide Complexation and Dissolution +
+ +
+ + + +

Evidence

+ + +
+ + +
+ + + + + + + + +
+

Environmental Factors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FactorValueUnit
pH6.5-7.5pH units
Temperature28-32°C
Biocyanide Concentration50-200ppm CN⁻
Leaching Time7-14days
Gold Extraction Efficiency70-85% recovery
Ore Pulp Density5-15% w/v
Particle Size (Ore Grinding)200-400mesh (37-74 μm)
+ +
Carbon Source for Bacterial GrowthGlycerol or glucosequalitative
+ +
Oxygen RequirementAerobic with aerationqualitative
+
    + +
  • + + doi:10.1007/s10163-014-0276-4 + + - SUPPORT (IN_VITRO) + +
    "The dissolved oxygen concentration in every solution decreased to a minimal level after 24 h without oxygen supplement"
    + +
  • + +
+
Pre-growth and Activation ProtocolStationary phase pre-growthqualitative
Substrate Ore TypesRefractory arsenopyrite, pyrite, carbonaceous sulfidesqualitative
+ +
+
+ + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/docs/isolates/Methylobacterium_REE_Ewaste_Platform.html b/docs/isolates/Methylobacterium_REE_Ewaste_Platform.html new file mode 100644 index 000000000..f858ebec1 --- /dev/null +++ b/docs/isolates/Methylobacterium_REE_Ewaste_Platform.html @@ -0,0 +1,1567 @@ + + + + + + Methylobacterium REE E-waste Platform - CommunityMech + + + +
+
+ ← Back to Communities +

Methylobacterium REE E-waste Platform

+
+
+ +
+ +
+ +
+ + + +
+

An engineered monoculture bioplatform based on the mesophilic methylotrophic bacterium Methylobacterium extorquens AM1 for sustainable recovery of rare earth elements (REE) from electronic waste. This system represents a paradigm shift in critical materials recovery through non-acidic, green bioprocessing that eliminates the harsh chemical leaching typical of conventional REE extraction. M. extorquens naturally accumulates REE in intracellular polyphosphate granules during methanol metabolism, achieving baseline bioaccumulation of 3.2 mg Nd/g dry cell weight. Through metabolic engineering, lanthanophore mll expression increased REE bioaccumulation to 80 mg Nd/g dry weight, and deletion of exopolyphosphatase (ppx) enhanced Nd accumulation to 202 mg Nd/g dry weight. The platform achieves remarkable selectivity with 98% of accumulated metal being REE and 96.8% of that being neodymium, critical for permanent magnet recycling. The system operates at near-neutral pH (6.9), mesophilic temperature (29-30°C), and scales to 10-liter bioreactors with controlled organic acid supplementation (5-15 mM citrate). After bioleaching with citrate, 58.7 ppm REE are mobilized from electronic waste (magnet swarf), followed by cellular bioaccumulation and recovery. This consolidated platform integrates leaching, bioaccumulation, and recovery in a single organism, offering environmental advantages over acidic chemical processing while addressing circular economy needs for critical materials in clean energy technologies. +

+
+ + + + +
+

Taxonomy

+ + + + + + + + + + + + + + + + + + + + + + + + +
TaxonOntology IDFunctional RolesAbundance
+ Methylobacterium extorquens + + + NCBITaxon:408 + + + +
+ + PRIMARY_DEGRADER + +
+ +
DOMINANT
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "The mesophilic methylotrophic bacterium Methylobacterium extorquens AM1 was previously shown to grow using electronic waste by naturally acquiring REEs to power methanol metabolism"
    + +
  • + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "The mesophilic methylotrophic bacterium Methylobacterium extorquens AM1 was previously shown to grow using electronic waste by naturally acquiring REEs"
    + +
  • + +
+
+
+ +
+

Ecological Interactions

+ + + +
+
+ + Ecological interaction network for Methylobacterium REE E-waste Platform + Bipartite graph where circle nodes represent taxa and each ecological interaction is drawn as a distinct non-circular symbol, with colour repeating the same distinction. + +
+
+ Taxon +
+
+ Other +
+
+
+ + +
+
+

Organic Acid-Mediated REE Bioleaching

+ +
+ + +

Source Taxon: Methylobacterium extorquens

+ + + + + +

Metabolites: + + citric acid + (CHEBI:30769), + + gluconic acid + (CHEBI:24266), + + oxalic acid + (CHEBI:16995), + + neodymium(3+) + (CHEBI:229785) + +

+ + + +

Biological Processes:

+
    + +
  • + organic acid metabolic process + (GO:0006082) +
  • + +
+ + + +
+ Downstream Effects: + +
+ → Lanthanophore-Mediated REE Bioaccumulation +
+ +
+ + + +

Evidence

+
    + +
  • +
    + + PMID:38150661 + + - SUPPORT (IN_VITRO) +
    + +
    "The addition of organic acids increases REE leaching in a nonspecific manner"
    + +
  • + +
+ +
+ +
+
+

Lanthanophore-Mediated REE Bioaccumulation

+ +
+ + +

Source Taxon: Methylobacterium extorquens

+ + + + + +

Metabolites: + + neodymium(3+) + (CHEBI:229785), + + praseodymium(3+) + (CHEBI:229784), + + dysprosium(3+) + (CHEBI:33377) + +

+ + + +

Biological Processes:

+
    + +
  • + metal ion transport + (GO:0030001) +
  • + +
  • + cellular response to metal ion + (GO:0071248) +
  • + +
+ + + +
+ Downstream Effects: + +
+ → Polyphosphate Granule REE Sequestration +
+ +
+ + + +

Evidence

+
    + +
  • +
    + + PMID:38150661 + + - SUPPORT (IN_VITRO) +
    + +
    "REEs are stored intracellularly in polyphosphate granules, and genetic engineering to eliminate exopolyphosphatase activity increases metal accumulation, confirming the link between phosphate metabolism and biological REE use"
    + +
  • + +
  • +
    + + PMID:38150661 + + - SUPPORT (IN_VITRO) +
    + +
    "In cell samples, 98.0% of the accumulated metal was REE, 96.8% of which was Nd"
    + +
  • + +
+ +
+ +
+
+

Polyphosphate Granule REE Sequestration

+ +
+ + +

Source Taxon: Methylobacterium extorquens

+ + + + + +

Metabolites: + + neodymium(3+) + (CHEBI:229785), + + polyphosphate + (CHEBI:16838) + +

+ + + +

Biological Processes:

+
    + +
  • + polyphosphate catabolic process + (GO:0006798) +
  • + +
+ + + + + +

Evidence

+
    + +
  • +
    + + PMID:38150661 + + - SUPPORT (IN_VITRO) +
    + +
    "REEs are stored intracellularly in polyphosphate granules, and genetic engineering to eliminate exopolyphosphatase activity increases metal accumulation, confirming the link between phosphate metabolism and biological REE use"
    + +
  • + +
  • +
    + + PMID:38150661 + + - SUPPORT (IN_VITRO) +
    + +
    "A ppx (encoding exopolyphosphatase) deletion strain was generated and assessed for REE bioaccumulation, showing a ∼5.5-fold increase in Nd levels reaching 202 mg Nd/g DW"
    + +
  • + +
+ +
+ +
+
+

Methanol-Powered REE Acquisition Metabolism

+ +
+ + +

Source Taxon: Methylobacterium extorquens

+ + + + + +

Metabolites: + + methanol + (CHEBI:17790), + + neodymium(3+) + (CHEBI:229785), + + formaldehyde + (CHEBI:16842) + +

+ + + +

Biological Processes:

+
    + +
  • + methanol metabolic process + (GO:0015945) +
  • + +
+ + + + + +

Evidence

+
    + +
  • +
    + + PMID:38150661 + + - SUPPORT (IN_VITRO) +
    + +
    "The mesophilic methylotrophic bacterium Methylobacterium extorquens AM1 was previously shown to grow using electronic waste by naturally acquiring REEs to power methanol metabolism"
    + +
  • + +
+ +
+ + +
+ + + + + + + + +
+

Environmental Factors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FactorValueUnit
pH6.9pH units
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "Bioreactor parameters were as follows: agitation, 500 rpm; air flow, 200–2000 sccm; temperature, 29.5 °C; and pH, 6.9. The pH of the bioreactor was maintained by using 1 M NaOH"
    + +
  • + +
+
Temperature29-30°C
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "Bioreactor parameters were as follows: agitation, 500 rpm; air flow, 200–2000 sccm; temperature, 29.5 °C; and pH, 6.9"
    + +
  • + +
+
Bioreactor Scale10liters
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "we assessed process performance at a 10 L scale using optimized media and 1% Nd magnet swarf pulp density"
    + +
  • + +
+
Medium CompositionHyphoMOD minimal mediumN/A
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "a modified formulation of Hypho (HyphoMOD) containing 1.27 g/L of K2HPO4 and 1.30 g/L of NaH2PO4.H2O was used"
    + +
  • + +
+
REE Bioaccumulation Capacity202mg Nd/g dry cell weight
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "A ppx (encoding exopolyphosphatase) deletion strain was generated and assessed for REE bioaccumulation, showing a ∼5.5-fold increase in Nd levels reaching 202 mg Nd/g DW"
    + +
  • + +
+
REE Selectivity and Purity98%% REE purity
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "In cell samples, 98.0% of the accumulated metal was REE, 96.8% of which was Nd"
    + +
  • + +
+
Substrate E-waste CompositionNd-Fe-B magnet swarfN/A
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "Iron was the primary metal component of Nd magnet swarf (68.0% Fe), rendering nonselective leaching and uptake mechanisms insufficient for effective REE bioaccumulation. Nd was the second most abundant metal measured (26.7% Nd)"
    + +
  • + +
+
Citrate Leaching Efficiency58.7ppm REE leached
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "After 28 h of incubation, 8.2 ± 0.1 and 58.7 ± 0.6 ppm of REE were leached into the supernatant supplemented with 5 mM and 15 mM citrate, respectively"
    + +
  • + +
+
Genetic Engineering Strategyppx deletionN/A
+
    + +
  • + + PMID:38150661 + + - SUPPORT (IN_VITRO) + +
    "A ppx (encoding exopolyphosphatase) deletion strain was generated and assessed for REE bioaccumulation, showing a ∼5.5-fold increase in Nd levels reaching 202 mg Nd/g DW"
    + +
  • + +
+
+
+ + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/justfile b/justfile index 08d085548..d4c2764d7 100644 --- a/justfile +++ b/justfile @@ -454,15 +454,19 @@ check-docs-current: # writes, so the stale page stays tracked and published while the diff stays # empty. f8d85b1 is a rename of exactly that shape. orphans="" - for page in docs/communities/*.html; do - record="kb/communities/$(basename "$page" .html).yaml" - [ -f "$record" ] || orphans="$orphans $(basename "$page")" + for page in docs/communities/*.html docs/isolates/*.html; do + [ -e "$page" ] || continue + case "$page" in + docs/isolates/*) record="data/isolates/$(basename "$page" .html).yaml" ;; + *) record="kb/communities/$(basename "$page" .html).yaml" ;; + esac + [ -f "$record" ] || orphans="$orphans $page" done if [ -n "$orphans" ]; then echo "āŒ published pages with no record (delete them):$orphans" exit 1 fi - # That loop covers docs/communities/ only. The TOP-LEVEL pages + # That loop covers community and isolate detail pages. The TOP-LEVEL pages # (community_umap.html, community_graph.html, browser.html) embed record ids # and links too, and a rename left dead ones there with every gate green # (#714). They are checked by @@ -795,3 +799,7 @@ validate-history target="history": uv run linkml-validate \ --schema src/communitymech/schema/history.yaml --target-class HistoryRecord "$target" fi + +# Full canonical semantic text by default; --record/--limit are explicit canaries. +text-map-inputs *args: + uv run python scripts/text_map_inputs.py {{args}} diff --git a/scripts/text_map_inputs.py b/scripts/text_map_inputs.py new file mode 100755 index 000000000..0c95f6c66 --- /dev/null +++ b/scripts/text_map_inputs.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +"""Export versioned semantic YAML text for the common fleet map.""" + +from communitymech.text_map_inputs import main + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/src/communitymech/render.py b/src/communitymech/render.py index 2a86f83b0..70da89dea 100644 --- a/src/communitymech/render.py +++ b/src/communitymech/render.py @@ -73,6 +73,19 @@ def render_community( return html + def render_isolates(self, isolates_dir: Path, output_dir: Path) -> list[str]: + """Render isolate detail pages without changing the community browser population.""" + if not isolates_dir.is_dir(): + raise ValueError(f"missing isolate corpus: {isolates_dir}") + failed = [] + for yaml_path in sorted(isolates_dir.glob("*.yaml")): + try: + self.render_community(yaml_path, output_dir / f"{yaml_path.stem}.html") + except Exception as error: + print(f" āœ— {yaml_path.name}: {error}") + failed.append(yaml_path.name) + return failed + def render_all( self, communities_dir: Path = Path("kb/communities"), @@ -191,6 +204,11 @@ def main(): default="kb/communities", help="Directory containing community YAML files", ) + parser.add_argument( + "--isolates-dir", + default="data/isolates", + help="Isolate detail records, published separately from the community browser", + ) parser.add_argument( "--output-dir", default=str(DOCS / "communities"), @@ -217,6 +235,11 @@ def main(): communities_dir=Path(args.communities_dir), output_dir=Path(args.output_dir), ) + failed.extend( + renderer.render_isolates( + Path(args.isolates_dir), Path(args.output_dir).parent / "isolates" + ) + ) if failed: raise SystemExit(1) diff --git a/src/communitymech/text_map_inputs.py b/src/communitymech/text_map_inputs.py new file mode 100644 index 000000000..6e7826e9f --- /dev/null +++ b/src/communitymech/text_map_inputs.py @@ -0,0 +1,257 @@ +"""Versioned semantic YAML text for the common fleet map; no model calls. + +Includes canonical community records and separately stored isolate records in +the text map; the graph community projection keeps its own population policy. +Stable CommunityMech IDs link to existing community pages. Text includes names, +descriptions, ecological class/state, environments, named taxa/roles, +interactions and measured environmental factors. Citations, evidence snippets, +history, grounding annotations and identifiers are excluded. +""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import os +import sys +import tempfile +from collections.abc import Iterator +from contextlib import nullcontext +from pathlib import Path +from urllib.parse import quote + +import yaml + +REPO_ROOT = Path(__file__).resolve().parents[2] +ADAPTER_VERSION = "communitymech-semantic-v1" +RECORD_ROOTS = ("kb/communities", "data/isolates") + + +def clean(value: object) -> str: + return " ".join(str(value).split()) if value is not None else "" + + +def enum_text(value: object) -> str: + return clean(value).lower().replace("_", " ") + + +def label_of(value: object) -> str: + if isinstance(value, str): + return clean(value) + if not isinstance(value, dict): + return "" + return clean( + value.get("preferred_term") + or value.get("label") + or value.get("name") + or (value.get("term") or {}).get("label") + ) + + +def add(lines: list[str], label: str, value: object) -> None: + text = clean(value) + if text: + lines.append(f"{label}: {text}") + + +def _load(path: Path) -> dict: + with path.open(encoding="utf-8") as stream: + record = yaml.safe_load(stream) + if not isinstance(record, dict): + raise TypeError(f"record is not a YAML mapping: {path}") + return record + + +def _discover(directory: Path) -> Iterator[Path]: + with os.scandir(directory) as entries: + for entry in entries: + if entry.is_symlink(): + raise ValueError(f"symlink in corpus: {entry.path}") + if entry.is_dir(follow_symlinks=False): + yield from _discover(Path(entry.path)) + elif entry.name.endswith(".yaml") and entry.is_file(follow_symlinks=False): + yield Path(entry.path) + + +def _record_path(root: Path, relative: str) -> Path: + path = Path(relative) + if path.is_absolute() or ".." in path.parts or path.suffix != ".yaml": + raise ValueError(f"not a repository-relative corpus YAML path: {relative}") + source = root / path + if not any(source.is_relative_to(root / directory) for directory in RECORD_ROOTS): + raise ValueError(f"record leaves the corpus: {relative}") + if any( + (root / Path(*path.parts[:length])).is_symlink() for length in range(1, len(path.parts) + 1) + ): + raise ValueError(f"symlink in corpus path: {relative}") + if not source.is_file(): + raise ValueError(f"missing corpus record: {relative}") + return source + + +def include_record(record: dict) -> bool: + return True + + +def build_context(paths: list[Path]) -> dict: + return {} + + +def record_details(record: dict, path: Path) -> tuple[str, str, str, str]: + return ( + record.get("id"), + clean(record.get("name")), + clean(record.get("community_category")) or "UNKNOWN", + ("isolates/" if path.parent.name == "isolates" else "communities/") + + quote(path.stem, safe="-._") + + ".html", + ) + + +def semantic_text(record: dict, context: dict | None = None) -> str: + lines = [] + add(lines, "name", record.get("name")) + add(lines, "description", record.get("description")) + for field in ("community_category", "ecological_state", "community_origin"): + add(lines, field.replace("_", " "), enum_text(record.get(field))) + add(lines, "environment", label_of(record.get("environment_term"))) + for taxon in record.get("taxonomy") or []: + add(lines, "taxon", label_of(taxon.get("taxon_term"))) + for field in ("functional_role", "abundance_level"): + add(lines, field.replace("_", " "), enum_text(taxon.get(field))) + for interaction in record.get("ecological_interactions") or []: + add(lines, "interaction", interaction.get("name")) + add(lines, "interaction type", enum_text(interaction.get("interaction_type"))) + add(lines, "interaction description", interaction.get("description")) + for field in ("metabolites", "biological_processes"): + for value in interaction.get(field) or []: + add(lines, field.replace("_", " "), label_of(value)) + for factor in record.get("environmental_factors") or []: + add(lines, "environmental factor", factor.get("name")) + add(lines, "value", factor.get("value")) + add(lines, "factor description", factor.get("description")) + return "\n".join(lines) + "\n" + + +def iter_inputs( + root: Path = REPO_ROOT, *, records: list[str] | None = None, limit: int | None = None +) -> Iterator[dict]: + root = root.resolve() + if limit is not None and limit < 1: + raise ValueError("limit must be a positive integer") + paths = [] + for directory in RECORD_ROOTS: + corpus = root / directory + if not corpus.is_dir() or any( + (root / Path(*Path(directory).parts[:length])).is_symlink() + for length in range(1, len(Path(directory).parts) + 1) + ): + raise ValueError(f"missing real corpus directory: {corpus}") + paths.extend(_discover(corpus)) + context = build_context(paths) + selected = [_record_path(root, relative) for relative in records] if records else paths + if len(set(selected)) != len(selected): + raise ValueError("duplicate selected record path") + selected = sorted(selected) + identifiers = set() + count = 0 + for path in selected: + record = _load(path) + if not include_record(record): + continue + identifier, label, category, page = record_details(record, path) + if not all( + isinstance(value, str) and value.strip() + for value in (identifier, label, category, page) + ): + raise ValueError(f"missing record identity, label, category or page: {path}") + if identifier in identifiers: + raise ValueError(f"duplicate record identifier: {identifier}") + identifiers.add(identifier) + text = semantic_text(record, context) + yield { + "identifier": identifier, + "label": label, + "category": category, + "page": page, + "source_path": path.relative_to(root).as_posix(), + "text": text, + "text_sha256": hashlib.sha256(text.encode("utf-8")).hexdigest(), + "adapter_version": ADAPTER_VERSION, + } + count += 1 + if limit is not None and count >= limit: + break + + +def export_inputs( + root: Path, output: Path | None, *, records: list[str] | None = None, limit: int | None = None +) -> dict: + destination = output.resolve() if output is not None else None + if destination is not None and destination.suffix != ".jsonl": + raise ValueError("output must have a .jsonl suffix") + temporary = None + digest = hashlib.sha256() + count = 0 + try: + if destination is not None: + destination.parent.mkdir(parents=True, exist_ok=True) + with ( + tempfile.NamedTemporaryFile( + mode="wb", prefix=".text-map-", dir=destination.parent, delete=False + ) + if destination is not None + else nullcontext() + ) as handle: + if handle is not None: + temporary = Path(handle.name) + for record in iter_inputs(root, records=records, limit=limit): + data = (json.dumps(record, sort_keys=True, ensure_ascii=False) + "\n").encode( + "utf-8" + ) + digest.update(data) + count += 1 + if handle is not None: + handle.write(data) + if not count: + raise ValueError("selection contains no eligible corpus records") + if temporary is not None: + temporary.replace(destination) + return { + "mode": "export" if destination else "preview", + "scope": "subset" if records or limit is not None else "full", + "records": count, + "adapter_version": ADAPTER_VERSION, + "jsonl_sha256": digest.hexdigest(), + "output": str(destination) if destination else None, + } + finally: + if temporary is not None: + temporary.unlink(missing_ok=True) + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, default=REPO_ROOT) + parser.add_argument( + "--output", type=Path, help="write JSONL atomically; otherwise validate a preview" + ) + parser.add_argument( + "--record", action="append", help="repeat a repo-relative path for an explicit canary" + ) + parser.add_argument( + "--limit", type=int, help="explicit canary limit; normal exports cover the full corpus" + ) + args = parser.parse_args(argv) + try: + result = export_inputs(args.root, args.output, records=args.record, limit=args.limit) + except (OSError, ValueError, TypeError, yaml.YAMLError) as error: + print(f"text-map inputs refused: {error}", file=sys.stderr) + return 2 + print(json.dumps(result, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_text_map_inputs.py b/tests/test_text_map_inputs.py new file mode 100644 index 000000000..d70d6cece --- /dev/null +++ b/tests/test_text_map_inputs.py @@ -0,0 +1,169 @@ +"""Semantic adapter behavior, corpus boundaries, identity and atomic refusal.""" + +import copy +import hashlib +import json +from pathlib import Path + +import pytest +import yaml + +from communitymech import text_map_inputs as adapter + +SOURCE = "kb/communities/example.yaml" +RECORD = { + "id": "CommunityMech:000001", + "name": "Example community", + "community_category": "BIOREMEDIATION", + "description": "Degrades aromatic compounds", + "taxonomy": [ + { + "taxon_term": { + "preferred_term": "Example taxon", + "term": {"id": "NCBITaxon:987", "label": "Example taxon"}, + }, + "functional_role": "DEGRADER", + } + ], +} +LABEL_FIELD = "name" +PAGE = "communities/example.html" + + +def fixture_tree(root): + for directory in adapter.RECORD_ROOTS: + (root / directory).mkdir(parents=True, exist_ok=True) + path = root / SOURCE + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(yaml.safe_dump(RECORD)) + if adapter.ADAPTER_VERSION.startswith("traitmech-"): + parent = path.with_name("parent.yaml") + parent.write_text( + yaml.safe_dump( + { + "identifier": "METPO:parent", + "label": "Resolved parent", + "trait_category": "ECOLOGY", + } + ) + ) + return path + + +def test_exact_contract_and_semantic_digest_ignores_provenance(tmp_path): + path = fixture_tree(tmp_path) + row = next(adapter.iter_inputs(tmp_path, records=[SOURCE])) + assert set(row) == { + "identifier", + "label", + "category", + "page", + "source_path", + "text", + "text_sha256", + "adapter_version", + } + assert row["page"] == PAGE + assert row["source_path"] == SOURCE + assert row["text_sha256"] == hashlib.sha256(row["text"].encode("utf-8")).hexdigest() + assert "REJECTED_SENTINEL" not in row["text"] + record = copy.deepcopy(RECORD) + record.update( + { + "curation_history": [{"notes": "PRIVATE_PROVENANCE_SENTINEL"}], + "references": [{"reference": "PMID:999999"}], + "evidence": [{"snippet": "PRIVATE_PROVENANCE_SENTINEL"}], + "notes": "PRIVATE_PROVENANCE_SENTINEL", + } + ) + path.write_text(yaml.safe_dump(record)) + unchanged = next(adapter.iter_inputs(tmp_path, records=[SOURCE])) + assert unchanged["text_sha256"] == row["text_sha256"] + assert "PRIVATE_PROVENANCE_SENTINEL" not in unchanged["text"] + record[LABEL_FIELD] = "A different biological entity" + path.write_text(yaml.safe_dump(record)) + changed = next(adapter.iter_inputs(tmp_path, records=[SOURCE])) + assert changed["text_sha256"] != row["text_sha256"] + + +def test_canary_and_full_keep_identical_semantics(tmp_path): + fixture_tree(tmp_path) + full = list(adapter.iter_inputs(tmp_path)) + subset = list(adapter.iter_inputs(tmp_path, records=[SOURCE])) + assert subset[0] == next(row for row in full if row["source_path"] == SOURCE) + if adapter.ADAPTER_VERSION.startswith("traitmech-"): + assert "Resolved parent" in subset[0]["text"] + assert "METPO:parent" not in subset[0]["text"] + result = adapter.export_inputs(tmp_path, tmp_path / "records.jsonl", limit=1) + assert result["records"] == 1 and result["scope"] == "subset" + result = adapter.export_inputs(tmp_path, None) + assert result["records"] == len(full) and result["scope"] == "full" + + +def test_atomic_failure_preserves_previous_output(tmp_path): + path = fixture_tree(tmp_path) + output = tmp_path / "records.jsonl" + output.write_text("previous output") + broken = path.with_name("zz_broken.yaml") + broken.write_text("not: [valid YAML") + with pytest.raises(yaml.YAMLError): + adapter.export_inputs(tmp_path, output) + assert output.read_text() == "previous output" + assert not list(tmp_path.glob(".text-map-*")) + + +def test_selection_cannot_escape_or_repeat(tmp_path): + fixture_tree(tmp_path) + for selection in (["../outside.yaml"], [SOURCE, SOURCE]): + with pytest.raises(ValueError): + list(adapter.iter_inputs(tmp_path, records=selection)) + with pytest.raises(ValueError, match="positive"): + list(adapter.iter_inputs(tmp_path, limit=0)) + + +def test_symlinked_yaml_is_refused(tmp_path): + path = fixture_tree(tmp_path) + alias = path.with_name("alias.yaml") + alias.symlink_to(path) + with pytest.raises(ValueError, match="symlink"): + list(adapter.iter_inputs(tmp_path)) + + +def test_isolate_link_has_generated_detail_without_changing_browser(tmp_path): + from communitymech.render import CommunityRenderer + + fixture_tree(tmp_path) + record = copy.deepcopy(RECORD) + record["id"] = "CommunityMech:isolate" + record["name"] = "Isolate detail test" + source = "data/isolates/isolated.yaml" + (tmp_path / source).write_text(yaml.safe_dump(record)) + browser = tmp_path / "docs/browser.html" + browser.parent.mkdir(parents=True) + browser.write_text("community population unchanged") + renderer = CommunityRenderer() + failed = renderer.render_isolates(tmp_path / "data/isolates", tmp_path / "docs/isolates") + assert failed == [] + row = next(adapter.iter_inputs(tmp_path, records=[source])) + assert row["page"] == "isolates/isolated.html" + assert "Isolate detail test" in (tmp_path / "docs" / row["page"]).read_text() + assert browser.read_text() == "community population unchanged" + (tmp_path / "data/isolates/broken.yaml").write_text("not: [valid") + assert renderer.render_isolates(tmp_path / "data/isolates", tmp_path / "docs/isolates") == [ + "broken.yaml" + ] + + +def test_export_round_trip_and_map_sibling_route(tmp_path): + from urllib.parse import urljoin + + fixture_tree(tmp_path) + output = tmp_path / "output.jsonl" + receipt = adapter.export_inputs(tmp_path, output, records=[SOURCE]) + row = json.loads(output.read_text()) + assert receipt["jsonl_sha256"] == hashlib.sha256(output.read_bytes()).hexdigest() + assert Path(row["source_path"]).suffix == ".yaml" + assert ( + urljoin("https://example.test/deployment/text-map/index.html", "../" + row["page"]) + == "https://example.test/deployment/" + PAGE + ) From 51e1bcb87ae18b2991e9b9e2ce8bb44b5ab5eb11 Mon Sep 17 00:00:00 2001 From: "marcin p. joachimiak" <4625870+realmarcin@users.noreply.github.com> Date: Mon, 14 Sep 2026 19:06:22 -0700 Subject: [PATCH 03/11] Bind graph coordinates to parsed source bytes and complete provenance Addresses #900 and #905. Historical arrays remain unverified; full artifact regeneration follows this reviewed source checkpoint. --- docs/GRAPH_PROVENANCE.md | 22 + src/communitymech/embedding/aggregator.py | 51 ++ src/communitymech/embedding/dimensionality.py | 75 ++- src/communitymech/embedding/graph_layout.py | 39 +- src/communitymech/embedding/loader.py | 88 +-- src/communitymech/graph_embedding_receipts.py | 504 ++++++++++++++++++ .../templates/community_umap.html | 9 + .../visualization/umap_generator.py | 55 +- tests/test_graph_sfdp_receipt.py | 24 + tests/test_graph_source_identity.py | 32 ++ 10 files changed, 798 insertions(+), 101 deletions(-) create mode 100644 docs/GRAPH_PROVENANCE.md create mode 100644 src/communitymech/graph_embedding_receipts.py create mode 100644 tests/test_graph_sfdp_receipt.py create mode 100644 tests/test_graph_source_identity.py diff --git a/docs/GRAPH_PROVENANCE.md b/docs/GRAPH_PROVENANCE.md new file mode 100644 index 000000000..c36023db6 --- /dev/null +++ b/docs/GRAPH_PROVENANCE.md @@ -0,0 +1,22 @@ +# CommunityMech community graph provenance + +Graph maps retain their KG-Microbe DeepWalk features and domain matching policies. The fleet's common BGE text map is a separate view. This work follows #900 and #905. + +Use `UMAPVisualizationGenerator().generate(embeddings_path="/path/to/source.tsv.gz", method="pacmap")` from `communitymech.visualization.umap_generator`. It defaults to `kb/communities` and `docs/community_umap.html`. For the retained graph layout pass `method="sfdp", output_path="docs/community_graph.html"`. Each HTML gains sibling `.points.json` and `.metadata.json` artifacts. `method="umap"` is an explicit alternative. + +The population is communities. Isolate files are explicitly recorded as outside this graph view. The coverage denominator is all unique requested taxon IDs; missing graph vectors do not identify hosts. The ledger includes found/missing taxa, coverage, aggregation weights and communities omitted below the threshold. Host exclusion still requires independent evidence and is not inferred here. + +New generation reads the selected TSV or TSV.gz stream directly and hashes the exact bytes while parsing. Old basename/size/mtime pickle caches are ignored, including when `force_reload` is false. The scan is streaming and retains only required node vectors; the full source file is still read once per generation. Do not infer source identity by hashing a different file beside old coordinates. + +Schema-v2 receipts bind the full corpus, matching/omission ledger, ordered reducer matrix, actual algorithm/normalization/settings and installed backend versions to checksums of every output. PaCMAP records fitted pair counts. The sfdp backend, where available, records the symmetric union-kNN construction, DOT checksum, Graphviz version and command arguments. Failed generation leaves previous outputs unchanged; publication rolls back ordinary write failures. A process kill can leave a `.graph-recovery-*` directory for recovery and is not claimed to be an atomic website deployment. + +Validate a completed generation with: + +```python +from pathlib import Path +from communitymech.graph_embedding_receipts import load_receipt + +receipt = load_receipt(Path("path/to/projection.metadata.json")) +``` + +This verifies all sibling artifacts declared by the receipt. It is not a tool for attaching newly guessed provenance to legacy arrays. Full published artifacts must be regenerated from reviewed current inputs before the graph correction is considered complete. diff --git a/src/communitymech/embedding/aggregator.py b/src/communitymech/embedding/aggregator.py index 85e5d6d45..88d0e8986 100644 --- a/src/communitymech/embedding/aggregator.py +++ b/src/communitymech/embedding/aggregator.py @@ -59,6 +59,17 @@ def aggregate_community( # Extract NCBITaxon IDs from taxonomy section taxon_ids = self._extract_taxon_ids(community_data) + self.last_metadata = { + "record_id": community_data.get("id", Path(community_yaml_path).stem), + "coverage_pct": 0.0, + "num_taxa": len(taxon_ids), + "num_embedded_taxa": 0, + "coverage_denominator": "unique_requested_taxa", + "taxa_found": [], + "taxa_missing": [], + "taxa_excluded": [], + "aggregation_method": aggregation_method, + } if not taxon_ids: return None @@ -77,6 +88,12 @@ def aggregate_community( # Every unique requested taxon is in the denominator. An absent # graph vector is missing data, never evidence of a host classification. coverage = len(found_ids) / len(taxon_ids) + self.last_metadata.update( + coverage_pct=coverage * 100, + num_embedded_taxa=len(found_ids), + taxa_found=found_ids, + taxa_missing=missing_ids, + ) if not found_embeddings or coverage < min_coverage: return None @@ -100,6 +117,7 @@ def aggregate_community( } metadata["taxa_excluded"] = [] + self.last_metadata.update(metadata) return community_vector, metadata @@ -151,6 +169,7 @@ def aggregate_communities( community_dir_path = Path(community_dir) community_vectors = {} community_metadata = {} + self.ledger = [] yaml_files = sorted(community_dir_path.glob("*.yaml")) @@ -164,6 +183,38 @@ def aggregate_communities( exclude_hosts=exclude_hosts, ) + metadata = self.last_metadata + self.ledger.append( + { + "identifier": community_id, + "record_id": metadata["record_id"], + "source_path": yaml_path.name, + "source_nodes": metadata["taxa_found"], + "missing_nodes": metadata["taxa_missing"], + "match_method": "taxon_ids", + "status": ( + "projected" + if result is not None + else ( + "no_vectors" + if not metadata["taxa_found"] + else "below_coverage_threshold" + ) + ), + "aggregation_method": aggregation_method, + "minimum_taxon_coverage": min_coverage, + "coverage_denominator": "unique_requested_taxa", + "requested_taxa": metadata["num_taxa"], + "found_taxa": metadata["num_embedded_taxa"], + "coverage_pct": metadata["coverage_pct"], + "weight_per_source": ( + (1 / len(metadata["taxa_found"]) if aggregation_method == "mean" else 1) + if metadata["taxa_found"] + else 0 + ), + } + ) + if result is not None: vector, metadata = result community_vectors[community_id] = vector diff --git a/src/communitymech/embedding/dimensionality.py b/src/communitymech/embedding/dimensionality.py index 7b6b987ec..f39cafab5 100644 --- a/src/communitymech/embedding/dimensionality.py +++ b/src/communitymech/embedding/dimensionality.py @@ -2,9 +2,10 @@ import numpy as np import pandas as pd -import umap # type: ignore[import-untyped] from sklearn.preprocessing import normalize # type: ignore[import-untyped] +from communitymech.graph_embedding_receipts import matrix_receipt, projection_receipt + class UMAPReducer: """Reduce high-dimensional embeddings to 2D using PaCMAP or UMAP. @@ -57,39 +58,71 @@ def fit_transform( - umap_y: float """ if not community_vectors: - return pd.DataFrame(columns=["community_id", "umap_x", "umap_y"]) + raise ValueError("No community vectors to project") # Convert dict to matrix - community_ids = list(community_vectors.keys()) + community_ids = sorted(community_vectors) vectors_matrix = np.vstack([community_vectors[cid] for cid in community_ids]) print(f"šŸ”„ Running {self.method.upper()} on {len(community_ids)} communities...") print(f" Input shape: {vectors_matrix.shape}") if self.method == "pacmap": - import pacmap # type: ignore[import-untyped] - - # L2-normalize rows to mirror cosine geometry, then PCA-init + fixed seed. + import pacmap + + parameters = { + "n_components": self.n_components, + "random_state": self.random_state, + "n_neighbors": None, + "MN_ratio": 0.5, + "FP_ratio": 2.0, + "distance": "euclidean", + "lr": 1.0, + "num_iters": (100, 100, 250), + "apply_pca": True, + "knn_backend": "faiss", + } normalized_vectors = normalize(vectors_matrix.astype("float32")) - coords = pacmap.PaCMAP( - n_components=self.n_components, - random_state=self.random_state, - ).fit_transform(normalized_vectors, init="pca") + vectors_receipt = matrix_receipt(normalized_vectors, community_ids) + reducer = pacmap.PaCMAP(**parameters) + coords = reducer.fit_transform(normalized_vectors, init="pca") + projection = projection_receipt( + self.method, parameters, reducer=reducer, normalization="l2", initialization="pca" + ) elif self.method == "sfdp": - # Force-directed (Graphviz sfdp) layout of the mutual-kNN graph over - # the KG embeddings — a global-structure-first graph view. from communitymech.embedding.graph_layout import sfdp_layout - coords = sfdp_layout(vectors_matrix, k=15, seed=self.random_state) - else: - reducer = umap.UMAP( - n_neighbors=self.n_neighbors, - min_dist=self.min_dist, - metric=self.metric, - random_state=self.random_state, - n_components=self.n_components, + coords, graph = sfdp_layout( + vectors_matrix, + k=15, + seed=self.random_state, + return_receipt=True, + record_ids=community_ids, ) + vectors_receipt = graph.pop("matrix") + projection = projection_receipt( + self.method, {"k": 15, "seed": self.random_state}, normalization="l2", graph=graph + ) + elif self.method == "umap": + import umap + + parameters = { + "n_neighbors": self.n_neighbors, + "min_dist": self.min_dist, + "metric": self.metric, + "random_state": self.random_state, + "n_components": self.n_components, + } + vectors_receipt = matrix_receipt(vectors_matrix, community_ids) + reducer = umap.UMAP(**parameters) coords = reducer.fit_transform(vectors_matrix) + projection = projection_receipt( + self.method, parameters, reducer=reducer, normalization="none" + ) + else: + raise ValueError(f"Unknown community projection: {self.method}") + if np.asarray(coords).shape != (len(community_ids), 2) or not np.isfinite(coords).all(): + raise ValueError("Projection must return finite coordinates for every community") print(f"āœ… {self.method.upper()} complete. Output shape: {coords.shape}") @@ -102,4 +135,6 @@ def fit_transform( } ) + df.attrs["projection"] = projection + df.attrs["matrix"] = vectors_receipt return df diff --git a/src/communitymech/embedding/graph_layout.py b/src/communitymech/embedding/graph_layout.py index 43be58023..838906de8 100644 --- a/src/communitymech/embedding/graph_layout.py +++ b/src/communitymech/embedding/graph_layout.py @@ -1,23 +1,27 @@ -"""Force-directed 2D layout of a mutual-kNN graph over embeddings, via Graphviz sfdp. +"""Force-directed 2D layout of a symmetric union-kNN graph over embeddings, via Graphviz sfdp. Self-contained: scikit-learn (kNN) + the `sfdp` binary (Graphviz). No pygraphviz/ pydot needed. Deterministic-ish via -Gstart=. Rows are L2-normalized so the Euclidean kNN mirrors the cosine metric used elsewhere. Output row order == input. """ +import hashlib import subprocess import numpy as np from sklearn.neighbors import kneighbors_graph # type: ignore[import-untyped] from sklearn.preprocessing import normalize # type: ignore[import-untyped] +from communitymech.graph_embedding_receipts import matrix_receipt -def sfdp_layout(matrix, k=15, seed=42, sfdp_bin="sfdp"): + +def sfdp_layout(matrix, k=15, seed=42, sfdp_bin="sfdp", *, return_receipt=False, record_ids=None): """Return an (n, 2) float32 array of 2D coordinates for the rows of `matrix`.""" matrix = normalize(np.asarray(matrix, dtype="float32")) n = matrix.shape[0] if n == 0: return np.zeros((0, 2), dtype="float32") + requested_k = k k = min(k, max(1, n - 1)) adj = kneighbors_graph(matrix, n_neighbors=k, mode="connectivity") adj = adj.maximum(adj.T) # symmetric union-kNN graph @@ -28,7 +32,10 @@ def sfdp_layout(matrix, k=15, seed=42, sfdp_bin="sfdp"): if i != j } dot = "\n".join( - ["graph G {"] + [f"{i};" for i in range(n)] + [f"{i}--{j};" for i, j in edges] + ["}"] + ["graph G {"] + + [f"{i};" for i in range(n)] + + [f"{i}--{j};" for i, j in sorted(edges)] + + ["}"] ) out = subprocess.run( [sfdp_bin, "-Tplain", f"-Gstart={seed}", "-Goverlap=prism", "-Gsmoothing=triangle"], @@ -40,10 +47,36 @@ def sfdp_layout(matrix, k=15, seed=42, sfdp_bin="sfdp"): if out.returncode != 0: raise RuntimeError(f"sfdp failed (is graphviz installed?): {out.stderr[:300]}") xy = np.zeros((n, 2), dtype="float32") + seen = set() for ln in out.stdout.splitlines(): if ln.startswith("node "): p = ln.split() idx = int(p[1]) + if idx in seen or not 0 <= idx < n: + raise ValueError("sfdp returned an invalid or repeated node") + seen.add(idx) xy[idx, 0] = float(p[2]) xy[idx, 1] = float(p[3]) + if len(seen) != n or not np.isfinite(xy).all(): + raise ValueError("sfdp did not return finite coordinates for every node") + if return_receipt: + version = subprocess.run( + [sfdp_bin, "-V"], capture_output=True, text=True, check=True + ).stderr.strip() + if not version: + raise ValueError("sfdp did not identify its Graphviz version") + graph = { + "construction": "symmetric_union_knn", + "metric": "euclidean", + "requested_k": requested_k, + "effective_k": k, + "edges": len(edges), + "dot_sha256": hashlib.sha256(dot.encode()).hexdigest(), + "graphviz_version": version, + "arguments": ["-Tplain", f"-Gstart={seed}", "-Goverlap=prism", "-Gsmoothing=triangle"], + "matrix": matrix_receipt( + matrix, record_ids if record_ids is not None else [str(i) for i in range(n)] + ), + } + return xy, graph return xy diff --git a/src/communitymech/embedding/loader.py b/src/communitymech/embedding/loader.py index a747f903c..0473a2c1e 100644 --- a/src/communitymech/embedding/loader.py +++ b/src/communitymech/embedding/loader.py @@ -1,25 +1,22 @@ -"""Efficient loading of KG-Microbe embeddings with caching.""" +"""Streaming source-bound loading of selected KG-Microbe vectors.""" -import gzip -import hashlib -import pickle from pathlib import Path import numpy as np -from tqdm import tqdm +from communitymech.graph_embedding_receipts import GraphSource from communitymech.paths import REPO_ROOT class EmbeddingLoader: - """Load and cache node embeddings from KG-Microbe TSV.gz file.""" + """Read node embeddings directly from the selected KG-Microbe source.""" def __init__(self, embeddings_path: str, cache_dir: str | Path = REPO_ROOT / ".umap_cache"): """Initialize loader. Args: embeddings_path: Path to embeddings TSV.gz file - cache_dir: Directory for pickle cache + cache_dir: Compatibility directory; legacy pickle caches are ignored """ self.embeddings_path = Path(embeddings_path) self.cache_dir = Path(cache_dir) @@ -29,86 +26,25 @@ def load_embeddings( self, prefixes: list[str] | None = None, force_reload: bool = False, + node_ids=None, ) -> dict[str, np.ndarray]: """Load embeddings filtered by node ID prefixes. Args: prefixes: List of CURIE prefixes to filter (e.g., ["NCBITaxon"]) - If None, loads all embeddings (not recommended for 3.2GB file) - force_reload: If True, ignore cache and reload from TSV.gz + If None, selects NCBITaxon nodes + force_reload: Compatibility option; the source is always read Returns: - Dictionary mapping node_id → 512-dim numpy array + Dictionary mapping node_id to a source-dimensional numpy array """ if prefixes is None: prefixes = ["NCBITaxon"] # Default to taxonomy only - # Generate cache filename keyed on (embeddings-file identity, prefixes) - # so swapping the embeddings file (e.g. v2 → v3) automatically - # invalidates the cache instead of silently reusing stale vectors. - prefix_tag = "_".join(sorted(prefixes)) - try: - st = self.embeddings_path.stat() - fp = f"{st.st_size}-{int(st.st_mtime)}" - except OSError: - fp = "nostat" - # Non-cryptographic cache key (content fingerprint), not a security digest. - digest = hashlib.sha1( - f"{self.embeddings_path.name}|{fp}|{prefix_tag}".encode(), - usedforsecurity=False, - ).hexdigest()[:12] - cache_name = f"{prefix_tag}_embeddings__{digest}.pkl" - cache_path = self.cache_dir / cache_name - - # Try loading from cache - if not force_reload and cache_path.exists(): - print(f"šŸ“¦ Loading embeddings from cache: {cache_path}") - # S301: cache file is written by this same module to a path - # under self.cache_dir (a developer-controlled location); never - # loaded from an untrusted source. - with open(cache_path, "rb") as f: - embeddings = pickle.load(f) # noqa: S301 - print(f"āœ… Loaded {len(embeddings):,} embeddings from cache") - return embeddings - - # Load from TSV.gz - print(f"šŸ“‚ Loading embeddings from {self.embeddings_path.name}") - print(f" Filtering to prefixes: {', '.join(prefixes)}") - - embeddings = {} - - # First pass: count total lines for progress bar - print(" Counting lines...") - with gzip.open(self.embeddings_path, "rt") as f: - total_lines = sum(1 for _ in f) - - # Second pass: parse and filter - with gzip.open(self.embeddings_path, "rt") as f: - for line in tqdm(f, total=total_lines, desc=" Parsing", unit=" nodes"): - parts = line.strip().split("\t") - if len(parts) < 2: - continue - - node_id = parts[0] - - # Check if node_id matches any prefix - if not any(node_id.startswith(f"{prefix}:") for prefix in prefixes): - continue - - # Parse embedding vector - try: - vector = np.array([float(x) for x in parts[1:]], dtype=np.float32) - embeddings[node_id] = vector - except (ValueError, IndexError): - continue - - print(f"āœ… Loaded {len(embeddings):,} embeddings") - - # Save to cache - print(f"šŸ’¾ Caching to {cache_path}") - with open(cache_path, "wb") as f: - pickle.dump(embeddings, f, protocol=pickle.HIGHEST_PROTOCOL) - + # #905: legacy caches are not a source receipt. Read actual bytes. + source = GraphSource(self.embeddings_path, prefixes, node_ids=node_ids) + embeddings = {node: np.asarray(vector, dtype=np.float32) for node, vector in source} + self.source_receipt = source.receipt return embeddings def get_embedding_dim(self, embeddings: dict[str, np.ndarray]) -> int: diff --git a/src/communitymech/graph_embedding_receipts.py b/src/communitymech/graph_embedding_receipts.py new file mode 100644 index 000000000..2274de2c6 --- /dev/null +++ b/src/communitymech/graph_embedding_receipts.py @@ -0,0 +1,504 @@ +"""Source-bound receipts for graph maps. Standard library; no legacy cache loading. + +Consumers own matching, aggregation and projection. Verified generation reads +the source stream directly and stages new outputs; historical arrays cannot +acquire provenance by passing an old cache to this module. +""" + +from __future__ import annotations + +import gzip +import hashlib +import importlib.metadata +import io +import json +import math +import os +import re +import shutil +import struct +import tempfile +from pathlib import Path + +SCHEMA_VERSION = 2 + + +def canonical(value: object) -> bytes: + return json.dumps( + value, sort_keys=True, separators=(",", ":"), ensure_ascii=False, allow_nan=False + ).encode("utf-8") + + +def file_sha256(path: Path) -> str: + digest = hashlib.sha256() + with Path(path).open("rb") as stream: + for chunk in iter(lambda: stream.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def _frame(digest, value: str) -> None: + payload = value.encode("utf-8") + digest.update(struct.pack(">Q", len(payload))) + digest.update(payload) + + +class _HashingReader(io.RawIOBase): + def __init__(self, stream): + self.stream = stream + self.digest = hashlib.sha256() + self.count = 0 + + def readable(self): + return True + + def readinto(self, buffer): + data = self.stream.read(len(buffer)) + buffer[: len(data)] = data + self.digest.update(data) + self.count += len(data) + return len(data) + + +class GraphSource: + """Read selected node vectors while hashing the exact source bytes consumed. + + Exhaust the iterator before using ``receipt``. Empty selection is recorded; + malformed selected rows, repeated IDs, inconsistent dimensions and nonfinite + values are errors. No basename/mtime cache or pickle is consulted. + """ + + def __init__(self, path: Path, prefixes, *, node_ids=None, node_filter=None, filter_name=None): + self.path = Path(path) + self.prefixes = tuple(sorted({p.rstrip(":") for p in prefixes})) + self.node_ids = None if node_ids is None else frozenset(node_ids) + if (node_filter is None) != (filter_name is None): + raise ValueError("a graph node filter requires an explicit policy name") + self.node_filter = node_filter + self.filter_name = filter_name + self.receipt: dict | None = None + self._started = False + + def __iter__(self): + if self._started: + raise ValueError("graph source reader is single-use") + self._started = True + seen = set() + dimension = None + lines = 0 + with self.path.open("rb") as raw: + before = os.fstat(raw.fileno()) + meter = _HashingReader(raw) + binary = ( + gzip.GzipFile(fileobj=meter, mode="rb") + if self.path.suffix == ".gz" + else io.BufferedReader(meter) + ) + with io.TextIOWrapper(binary, encoding="utf-8") as stream: + for line in stream: + lines += 1 + node, separator, rest = line.rstrip("\r\n").partition("\t") + if not any(node.startswith(prefix + ":") for prefix in self.prefixes): + continue + if self.node_ids is not None and node not in self.node_ids: + continue + if self.node_filter is not None and not self.node_filter(node): + continue + if node in seen: + raise ValueError(f"duplicate selected graph node: {node}") + if not separator: + raise ValueError(f"missing vector for selected graph node: {node}") + try: + vector = [float(value) for value in rest.split("\t")] + except ValueError as error: + raise ValueError(f"malformed graph vector for {node}") from error + if ( + len(vector) < 2 + or not all(math.isfinite(v) for v in vector) + or not any(vector) + ): + raise ValueError(f"invalid graph vector for {node}") + if dimension is None: + dimension = len(vector) + if len(vector) != dimension: + raise ValueError(f"inconsistent graph vector dimension for {node}") + seen.add(node) + yield node, vector + after = os.fstat(raw.fileno()) + if (before.st_dev, before.st_ino, before.st_size, before.st_mtime_ns) != ( + after.st_dev, + after.st_ino, + after.st_size, + after.st_mtime_ns, + ) or meter.count != before.st_size: + raise ValueError("graph source changed or was not completely consumed") + self.receipt = { + "filename": self.path.name, + "sha256": meter.digest.hexdigest(), + "bytes": meter.count, + "physical_lines": lines, + "parser": "graph-tsv-numeric-v1", + "prefixes": list(self.prefixes), + "selection": "prefixes" if self.node_ids is None else "explicit-node-ids", + "filter_policy": self.filter_name, + "requested_node_ids_sha256": ( + None + if self.node_ids is None + else hashlib.sha256(canonical(sorted(self.node_ids))).hexdigest() + ), + "selected_nodes": len(seen), + "dimensions": dimension, + "selected_node_ids_sha256": hashlib.sha256(canonical(sorted(seen))).hexdigest(), + "lineage": "parsed-source-bytes", + } + + +def corpus_receipt(paths, root: Path) -> dict: + root = Path(root).resolve() + digest = hashlib.sha256() + entries = [] + for path in sorted(Path(p) for p in paths): + if path.is_symlink(): + raise ValueError(f"corpus symlink refused: {path}") + relative = path.resolve().relative_to(root).as_posix() + checksum = file_sha256(path) + _frame(digest, relative) + _frame(digest, checksum) + entries.append({"path": relative, "sha256": checksum}) + if not entries or len({e["path"] for e in entries}) != len(entries): + raise ValueError("corpus must contain unique input files") + return {"count": len(entries), "sha256": digest.hexdigest(), "files": entries} + + +def matrix_receipt(rows, identifiers, *, dtype="float32-le") -> dict: + formats = {"float32-le": "f", "float64-le": "d"} + if dtype not in formats: + raise ValueError("unsupported graph vector storage dtype") + ids = list(identifiers) + if len(set(ids)) != len(ids): + raise ValueError("duplicate projected record identity") + digest = hashlib.sha256() + dimension = None + count = 0 + for identifier, row in zip(ids, rows, strict=True): + count += 1 + if not isinstance(identifier, str) or not identifier: + raise ValueError("projected record identity must be nonempty") + values = [float(v) for v in row] + if len(values) < 2 or not all(math.isfinite(v) for v in values) or not any(values): + raise ValueError("projected vectors must be finite and nonzero") + dimension = len(values) if dimension is None else dimension + if len(values) != dimension: + raise ValueError("projected vectors have inconsistent dimensions") + digest.update(struct.pack("<" + formats[dtype] * dimension, *values)) + if count < 1: + raise ValueError("projection requires at least one graph vector") + return { + "sha256": digest.hexdigest(), + "shape": [count, dimension], + "dtype": dtype, + "row_ids": ids, + "row_ids_sha256": hashlib.sha256(canonical(ids)).hexdigest(), + } + + +def software_versions(*names) -> dict: + return {name: importlib.metadata.version(name) for name in names} + + +def projection_receipt( + method, parameters, *, normalization, initialization=None, reducer=None, graph=None +) -> dict: + if method not in {"pacmap", "umap", "sfdp"}: + raise ValueError(f"unknown projection method: {method}") + result = { + "method": method, + "parameters": parameters, + "normalization": normalization, + "initialization": initialization, + } + if method == "pacmap": + result.update( + implementation="pacmap.PaCMAP", + effective_pairs={ + "neighbors": int(reducer.n_neighbors), + "mid_near": int(reducer.n_MN), + "further": int(reducer.n_FP), + }, + library_versions=software_versions( + "pacmap", "numpy", "numba", "scikit-learn", "faiss-cpu" + ), + ) + elif method == "umap": + result.update( + implementation="umap.UMAP", + effective_neighbors=int(reducer._n_neighbors), + library_versions=software_versions("umap-learn", "numpy", "numba", "scikit-learn"), + ) + else: + if not graph: + raise ValueError("sfdp requires actual graph/backend provenance") + result.update( + implementation="graphviz.sfdp", + graph=graph, + library_versions=software_versions("numpy", "scikit-learn"), + ) + canonical(result) + return result + + +def make_receipt(*, source, corpus, ledger, matrix, projection, coverage, auxiliary=None): + if not source or source.get("lineage") != "parsed-source-bytes": + raise ValueError("graph provenance requires a freshly parsed source receipt") + if ( + coverage.get("projected") != matrix["shape"][0] + or coverage.get("eligible", 0) < coverage["projected"] + ): + raise ValueError("graph coverage is inconsistent with projected vectors") + result = { + "schema_version": SCHEMA_VERSION, + "embedding_family": "kg_microbe_deepwalk", + "source": source, + "corpus": corpus, + "auxiliary_inputs": auxiliary or {}, + "matching": {"sha256": hashlib.sha256(canonical(ledger)).hexdigest(), "rows": ledger}, + "matrix": matrix, + "input_dimensions": matrix["shape"][1], + "projection": projection, + "coverage": coverage, + } + _validate_core(result) + return result + + +def _validate_core(receipt): + def checksum(value): + return isinstance(value, str) and re.fullmatch(r"[0-9a-f]{64}", value) + + source, matrix = receipt["source"], receipt["matrix"] + corpus, matching, projection = receipt["corpus"], receipt["matching"], receipt["projection"] + if ( + receipt.get("schema_version") != SCHEMA_VERSION + or receipt.get("embedding_family") != "kg_microbe_deepwalk" + or source.get("lineage") != "parsed-source-bytes" + or not checksum(source.get("sha256")) + or type(source.get("bytes")) is not int + or source["bytes"] < 1 + or not isinstance(source.get("filename"), str) + or not source["filename"] + or not checksum(corpus.get("sha256")) + or type(corpus.get("count")) is not int + or corpus["count"] < 1 + or corpus.get("count") != len(corpus.get("files", [])) + ): + raise ValueError("invalid graph source or corpus receipt") + corpus_digest = hashlib.sha256() + corpus_paths = [] + for entry in corpus["files"]: + name = entry.get("path") + if ( + not isinstance(name, str) + or not name + or Path(name).is_absolute() + or ".." in Path(name).parts + or not checksum(entry.get("sha256")) + ): + raise ValueError("invalid graph corpus input identity") + corpus_paths.append(name) + _frame(corpus_digest, name) + _frame(corpus_digest, entry["sha256"]) + if len(set(corpus_paths)) != len(corpus_paths) or corpus_digest.hexdigest() != corpus["sha256"]: + raise ValueError("graph corpus ledger checksum mismatch") + shape = matrix.get("shape") + ids = matrix.get("row_ids") + if ( + not isinstance(shape, list) + or len(shape) != 2 + or any(type(size) is not int for size in shape) + or shape[0] < 1 + or shape[1] < 2 + or not isinstance(ids, list) + or len(ids) != shape[0] + or any(not isinstance(identifier, str) or not identifier for identifier in ids) + or len(set(ids)) != len(ids) + or not checksum(matrix.get("sha256")) + or matrix.get("dtype") not in {"float32-le", "float64-le"} + or hashlib.sha256(canonical(ids)).hexdigest() != matrix.get("row_ids_sha256") + or receipt.get("input_dimensions") != shape[1] + ): + raise ValueError("invalid ordered graph matrix receipt") + rows = matching.get("rows") + if ( + not isinstance(rows, list) + or hashlib.sha256(canonical(rows)).hexdigest() != matching.get("sha256") + or any( + not isinstance(row, dict) + or not isinstance(row.get("identifier"), str) + or not row["identifier"] + or not isinstance(row.get("source_nodes"), list) + or any(not isinstance(node, str) or not node for node in row["source_nodes"]) + or not isinstance(row.get("status"), str) + or (row["status"] == "projected" and not row["source_nodes"]) + for row in rows + ) + or len({row["identifier"] for row in rows}) != len(rows) + or {row["identifier"] for row in rows if row["status"] == "projected"} != set(ids) + ): + raise ValueError("invalid graph matching ledger") + coverage = receipt["coverage"] + if ( + type(coverage.get("projected")) is not int + or coverage["projected"] != shape[0] + or type(coverage.get("eligible")) is not int + or coverage["eligible"] < shape[0] + or coverage["eligible"] != len(rows) + or projection.get("method") not in {"pacmap", "umap", "sfdp"} + or not isinstance(projection.get("parameters"), dict) + or projection.get("normalization") not in {"l2", "none"} + or not isinstance(projection.get("library_versions"), dict) + or not projection["library_versions"] + or any( + not isinstance(version, str) or not version + for version in projection["library_versions"].values() + ) + ): + raise ValueError("invalid graph coverage or reducer provenance") + method = projection["method"] + if method == "pacmap": + pairs = projection.get("effective_pairs", {}) + if ( + projection.get("implementation") != "pacmap.PaCMAP" + or set(pairs) != {"neighbors", "mid_near", "further"} + or any(type(count) is not int or count < 0 for count in pairs.values()) + or pairs["neighbors"] < 1 + or pairs["further"] < 1 + ): + raise ValueError("invalid effective PaCMAP reducer provenance") + elif method == "umap": + if ( + projection.get("implementation") != "umap.UMAP" + or type(projection.get("effective_neighbors")) is not int + or projection["effective_neighbors"] < 1 + ): + raise ValueError("invalid effective UMAP reducer provenance") + else: + graph = projection.get("graph", {}) + if ( + projection.get("implementation") != "graphviz.sfdp" + or graph.get("construction") != "symmetric_union_knn" + or not checksum(graph.get("dot_sha256")) + or not graph.get("graphviz_version") + or not graph.get("arguments") + or type(graph.get("effective_k")) is not int + or graph["effective_k"] < 1 + or type(graph.get("edges")) is not int + or graph["edges"] < 1 + ): + raise ValueError("invalid actual sfdp graph provenance") + canonical(receipt) + + +def validate_receipt(receipt, files: dict[str, Path]) -> None: + if receipt.get("schema_version") != SCHEMA_VERSION: + raise ValueError("unsupported graph receipt schema") + _validate_core(receipt) + if receipt["source"].get("lineage") != "parsed-source-bytes": + raise ValueError("unverified graph source lineage") + if set(receipt.get("outputs", {})) != set(files): + raise ValueError("graph output set differs from the receipt") + if ( + hashlib.sha256(canonical(receipt["matching"]["rows"])).hexdigest() + != receipt["matching"]["sha256"] + ): + raise ValueError("graph matching receipt checksum mismatch") + for name, path in files.items(): + if Path(path).is_symlink() or file_sha256(path) != receipt["outputs"][name]: + raise ValueError(f"graph output checksum mismatch: {name}") + + +def load_receipt(path: Path) -> dict: + path = Path(path) + if path.is_symlink(): + raise ValueError("symlinked graph receipt refused") + receipt = json.loads(path.read_text()) + if not isinstance(receipt, dict): + raise ValueError("graph receipt must be a JSON object") + names = receipt.get("outputs", {}) + if ( + not isinstance(names, dict) + or not names + or any(not isinstance(name, str) or not name or Path(name).name != name for name in names) + ): + raise ValueError("graph receipt outputs must name sibling artifacts") + validate_receipt(receipt, {name: path.parent / name for name in names}) + return receipt + + +def publish_artifacts(staged: dict[Path, Path], receipt_path: Path, receipt: dict) -> dict: + """Promote generated files and their receipt, restoring originals on errors. + + Caller owns the repository lock. Receipts are promoted last. A process kill + may leave a recovery directory; retain it instead of claiming atomic live + serving. All artifacts must have distinct basenames for unambiguous checks. + """ + receipt_path = Path(receipt_path) + destinations = [Path(path) for path in staged] + if ( + not destinations + or receipt_path.is_symlink() + or len({p.name for p in destinations}) != len(destinations) + or any(p.parent.resolve() != receipt_path.parent.resolve() for p in destinations) + or receipt_path.resolve() in {path.resolve() for path in destinations} + or any(p.is_symlink() for p in destinations) + ): + raise ValueError("graph artifacts must have distinct, non-symlinked sibling destinations") + metadata = { + **receipt, + "outputs": {target.name: file_sha256(origin) for target, origin in staged.items()}, + } + validate_receipt(metadata, {target.name: origin for target, origin in staged.items()}) + receipt_path.parent.mkdir(parents=True, exist_ok=True) + recovery = Path(tempfile.mkdtemp(prefix=".graph-recovery-", dir=receipt_path.parent)) + changes = [] + success = False + try: + receipt_stage = recovery / "new-receipt.json" + receipt_stage.write_bytes(canonical(metadata) + b"\n") + for index, (target, origin) in enumerate([*staged.items(), (receipt_path, receipt_stage)]): + target = Path(target) + target.parent.mkdir(parents=True, exist_ok=True) + backup = recovery / f"previous-{index}" + existed = target.exists() + if existed: + shutil.copyfile(target, backup) + changes.append((target, backup if existed else None)) + # Stage in each destination filesystem before atomic replacement. + fd, temporary_name = tempfile.mkstemp(prefix=".graph-publish-", dir=target.parent) + os.close(fd) + temporary = Path(temporary_name) + try: + shutil.copyfile(origin, temporary) + expected = ( + file_sha256(receipt_stage) + if target == receipt_path + else metadata["outputs"][target.name] + ) + if file_sha256(temporary) != expected: + raise ValueError( + f"staged graph artifact changed during publication: {target.name}" + ) + os.replace(temporary, target) + finally: + temporary.unlink(missing_ok=True) + success = True + except BaseException: + for target, previous_path in reversed(changes): + if previous_path is None: + target.unlink(missing_ok=True) + else: + os.replace(previous_path, target) + raise + finally: + if success or not any(recovery.glob("previous-*")): + shutil.rmtree(recovery) + return metadata diff --git a/src/communitymech/templates/community_umap.html b/src/communitymech/templates/community_umap.html index e579ff11b..c8360154e 100644 --- a/src/communitymech/templates/community_umap.html +++ b/src/communitymech/templates/community_umap.html @@ -543,6 +543,15 @@

Community Embedding Space

2D projection of {{ num_communities }} microbial communities based on taxonomic composition

← Back to Community Index + {% if graph_receipt %} +

Source: {{ graph_receipt.source.filename|e }}. + {{ graph_receipt.coverage.projected }} of {{ graph_receipt.coverage.eligible }} communities projected; + {{ graph_receipt.coverage.excluded_isolate_files|length }} isolate records are outside this graph view. + Taxon coverage counts every unique requested taxon; missing vectors are not host classifications. + Source, coverage and projection receipt.

+ {% else %} +

Legacy graph coordinates; source lineage is unverified.

+ {% endif %}
diff --git a/src/communitymech/visualization/umap_generator.py b/src/communitymech/visualization/umap_generator.py index 08086efae..73f412b98 100644 --- a/src/communitymech/visualization/umap_generator.py +++ b/src/communitymech/visualization/umap_generator.py @@ -1,6 +1,7 @@ """Generate interactive UMAP visualization of community embedding space.""" import json +import tempfile from pathlib import Path from typing import Any @@ -12,6 +13,7 @@ EmbeddingLoader, UMAPReducer, ) +from communitymech.graph_embedding_receipts import corpus_receipt, make_receipt, publish_artifacts from communitymech.paths import DOCS, REPO_ROOT @@ -58,8 +60,20 @@ def generate( print("=" * 60) # Step 1: Load embeddings + corpus_dir = Path(communities_dir) + corpus_paths = sorted(corpus_dir.glob("*.yaml")) + corpus = corpus_receipt(corpus_paths, corpus_dir) + required_nodes = set() + extractor = CommunityVectorAggregator({}) + for path in corpus_paths: + record = yaml.safe_load(path.read_text()) + if not isinstance(record, dict): + raise ValueError(f"Invalid community record: {path}") + required_nodes.update(extractor._extract_taxon_ids(record)) loader = EmbeddingLoader(embeddings_path, cache_dir=cache_dir) - embeddings = loader.load_embeddings(prefixes=["NCBITaxon"], force_reload=force_reload) + embeddings = loader.load_embeddings( + prefixes=["NCBITaxon"], force_reload=force_reload, node_ids=required_nodes + ) embedding_dim = loader.get_embedding_dim(embeddings) print(f"šŸ“Š Embedding dimension: {embedding_dim}") @@ -90,7 +104,41 @@ def generate( # UMAP vs graph-layout wording from the actual reduction method. projection_labels = {"pacmap": "PaCMAP", "umap": "UMAP", "sfdp": "Layout"} projection_label = projection_labels.get(method, method.upper()) - self._render_html(community_data, output_path, template_dir, projection_label) + if len(community_data) != len(umap_df): + raise ValueError("Community display metadata dropped projected records") + isolates_dir = corpus_dir.parent.parent / "data" / "isolates" + coverage = { + "eligible": corpus["count"], + "projected": len(umap_df), + "omitted": corpus["count"] - len(umap_df), + "population": "communities_only", + "minimum_taxon_coverage": min_coverage, + "host_classification": "not_attempted", + "excluded_isolate_files": sorted(p.name for p in isolates_dir.glob("*.yaml")), + } + receipt = make_receipt( + source=loader.source_receipt, + corpus=corpus, + ledger=aggregator.ledger, + matrix=umap_df.attrs["matrix"], + projection=umap_df.attrs["projection"], + coverage=coverage, + ) + output_path.parent.mkdir(parents=True, exist_ok=True) + with tempfile.TemporaryDirectory( + prefix=".community-graph-", dir=output_path.parent + ) as temporary: + staged_html = Path(temporary) / output_path.name + self._render_html(community_data, staged_html, template_dir, projection_label, receipt) + staged_points = staged_html.with_suffix(".points.json") + staged_points.write_text(json.dumps(community_data, indent=2)) + if corpus_receipt(sorted(corpus_dir.glob("*.yaml")), corpus_dir) != corpus: + raise ValueError("Community corpus changed during graph generation") + publish_artifacts( + {output_path: staged_html, output_path.with_suffix(".points.json"): staged_points}, + output_path.with_suffix(".metadata.json"), + receipt, + ) print(f"\nāœ… UMAP visualization generated: {output_path}") print("=" * 60) @@ -178,6 +226,7 @@ def _render_html( output_path: str | Path, template_dir: str | None = None, projection_label: str = "PaCMAP", + graph_receipt: dict | None = None, ): """Render HTML template with community data. @@ -204,6 +253,8 @@ def _render_html( community_data_json=json.dumps(community_data, indent=2), num_communities=len(community_data), projection_label=projection_label, + graph_receipt=graph_receipt, + receipt_filename=Path(output_path).with_suffix(".metadata.json").name, ) # Write output diff --git a/tests/test_graph_sfdp_receipt.py b/tests/test_graph_sfdp_receipt.py new file mode 100644 index 000000000..9119c9b95 --- /dev/null +++ b/tests/test_graph_sfdp_receipt.py @@ -0,0 +1,24 @@ +"""Graphviz must return one finite coordinate per actual projected row.""" + +import shutil + +import numpy as np +import pytest + +from communitymech.embedding.graph_layout import sfdp_layout + + +@pytest.mark.skipif( + shutil.which("sfdp") is None, reason="Graphviz sfdp is an optional graph backend" +) +def test_real_sfdp_returns_all_rows_and_actual_graph_receipt(): + matrix = np.random.default_rng(42).normal(size=(12, 5)) + points, graph = sfdp_layout( + matrix, k=3, return_receipt=True, record_ids=[f"row:{i}" for i in range(12)] + ) + assert points.shape == (12, 2) and np.isfinite(points).all() + assert graph["construction"] == "symmetric_union_knn" + assert graph["effective_k"] == 3 and graph["edges"] > 0 + assert "graphviz" in graph["graphviz_version"].lower() + assert graph["matrix"]["shape"] == [12, 5] + assert graph["matrix"]["row_ids"][0] == "row:0" diff --git a/tests/test_graph_source_identity.py b/tests/test_graph_source_identity.py new file mode 100644 index 000000000..03afe6ea6 --- /dev/null +++ b/tests/test_graph_source_identity.py @@ -0,0 +1,32 @@ +"""Ordinary loaders must read replaced graph bytes without an mtime cache hit.""" + +import gzip +import os +import pickle + +import numpy as np + +from communitymech.embedding.loader import EmbeddingLoader + + +def test_same_size_same_mtime_source_replacement_is_not_a_cache_hit(tmp_path): + path = tmp_path / "same-name.tsv.gz" + cache = tmp_path / "cache" + cache.mkdir() + + def replace(a, b): + path.write_bytes(gzip.compress(f"node\td1\td2\nNCBITaxon:1\t{a}\t{b}\n".encode(), mtime=0)) + + replace(1, 2) + before = path.stat() + first = EmbeddingLoader(str(path), cache_dir=cache).load_embeddings() + # Existing unbound pickles cannot establish which source supplied vectors. + (cache / "old-embeddings.pkl").write_bytes( + pickle.dumps({"NCBITaxon:1": np.array([99.0, 99.0])}) + ) + replace(3, 4) + assert path.stat().st_size == before.st_size + os.utime(path, ns=(before.st_atime_ns, before.st_mtime_ns)) + second = EmbeddingLoader(str(path), cache_dir=cache).load_embeddings() + np.testing.assert_array_equal(first["NCBITaxon:1"], [1.0, 2.0]) + np.testing.assert_array_equal(second["NCBITaxon:1"], [3.0, 4.0]) From fbf30921b6648f5608678387746fdb84ade9b572 Mon Sep 17 00:00:00 2001 From: "marcin p. joachimiak" <4625870+realmarcin@users.noreply.github.com> Date: Mon, 14 Sep 2026 19:07:52 -0700 Subject: [PATCH 04/11] feat: publish source-verified fleet BGE PaCMAP with guarded site navigation --- .github/workflows/generate-pages.yaml | 17 + conf/text_map.yaml | 2 + .../index.html | 41 ++ .../manifest.json | 1 + .../points.json | 1 + data/text_map/current.json | 1 + docs/TEXT_MAP_INPUTS.md | 24 + docs/browser.html | 3 +- docs/index.html | 5 +- docs/text-map/index.html | 41 ++ docs/text-map/manifest.json | 1 + docs/text-map/points.json | 1 + justfile | 6 +- scripts/embedding_pipeline.py | 685 ++++++++++++++++++ scripts/stage_text_map.py | 11 + src/communitymech/render.py | 16 +- src/communitymech/templates/index.html | 3 +- src/communitymech/templates/landing.html | 5 +- src/communitymech/text_map_publish.py | 24 + src/communitymech/text_map_site.py | 92 +++ tests/test_text_map_recipes.py | 33 + tests/test_text_map_site.py | 259 +++++++ 22 files changed, 1264 insertions(+), 8 deletions(-) create mode 100644 conf/text_map.yaml create mode 100644 data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/index.html create mode 100644 data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/manifest.json create mode 100644 data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/points.json create mode 100644 data/text_map/current.json create mode 100644 docs/text-map/index.html create mode 100644 docs/text-map/manifest.json create mode 100644 docs/text-map/points.json create mode 100644 scripts/embedding_pipeline.py create mode 100644 scripts/stage_text_map.py create mode 100644 src/communitymech/text_map_publish.py create mode 100644 src/communitymech/text_map_site.py create mode 100644 tests/test_text_map_recipes.py create mode 100644 tests/test_text_map_site.py diff --git a/.github/workflows/generate-pages.yaml b/.github/workflows/generate-pages.yaml index 69da0bdc7..fc4b756ff 100644 --- a/.github/workflows/generate-pages.yaml +++ b/.github/workflows/generate-pages.yaml @@ -11,6 +11,13 @@ on: branches: [main] paths: - "docs/**" + - "kb/communities/**" + - "data/isolates/**" + - "data/text_map/**" + - "conf/text_map.yaml" + - "src/communitymech/text_map_*.py" + - "scripts/stage_text_map.py" + - "scripts/embedding_pipeline.py" - ".github/workflows/generate-pages.yaml" workflow_dispatch: @@ -33,6 +40,16 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Set up Python for map validation + uses: actions/setup-python@v5 + with: + python-version-file: .python-version + + - name: Validate and stage the configured semantic text map + run: | + python -m pip install --quiet pyyaml + python scripts/stage_text_map.py + - name: Configure Pages uses: actions/configure-pages@v5 with: diff --git a/conf/text_map.yaml b/conf/text_map.yaml new file mode 100644 index 000000000..c03c73edc --- /dev/null +++ b/conf/text_map.yaml @@ -0,0 +1,2 @@ +# Enable only after reviewing a full-input bundle and installing the governed runtime. +enabled: true diff --git a/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/index.html b/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/index.html new file mode 100644 index 000000000..c9b1e390b --- /dev/null +++ b/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/index.html @@ -0,0 +1,41 @@ + + +communitymech semantic text map + +

communitymech semantic text map

Showing 372 of 372 input records. +PaCMAP positions summarize similarity between record descriptions.

+ +

Select a point to open its record.

+ +

+

Map provenance and coverage

+ + \ No newline at end of file diff --git a/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/manifest.json b/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/manifest.json new file mode 100644 index 000000000..d4757c8b4 --- /dev/null +++ b/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/manifest.json @@ -0,0 +1 @@ +{"coverage":{"displayed":372,"eligible":372,"maximum":50000,"omitted":0,"selection":"bottom-k-sha256(seed,identifier)","total":372},"encoder":{"dimension":1024,"dtype":"float32-le","format_version":1,"inference_device":"mps:0","library_versions":{"numpy":"2.3.5","sentence-transformers":"6.0.0","tokenizers":"0.23.2","torch":"2.14.0","transformers":"5.17.0"},"max_seq_length":512,"model":"BAAI/bge-large-en-v1.5","normalized":true,"pooling":"sentence-transformers-model","query_instruction":null,"revision":"d4aa6901d3a41ba39fb536a557fa166f842b0e09","truncation":"tail","weight_dtype":"torch.float32"},"encoder_profile_sha256":"3346a4c533aeac55dfcf54b6c4f3fb74e22f3ad4682c53f5215b539ac5ba0627","files":{"index.html":"ff21002c80d803d28295b946e8a3cbe6706083c4ece6c49371cfa63a2cae9978","points.json":"30c98b2a63ac00e49705058581acf699b85ab3a7b912a33aef3336c9330a9b62"},"format_version":1,"generated_at_utc":"2026-09-15T01:15:56.769129+00:00","inputs":{"adapter_version":"communitymech-semantic-v1","categories":{"AMD":7,"BIOMINING":13,"BIOREMEDIATION":53,"BIOTECHNOLOGY":64,"CARBON_SEQUESTRATION":12,"DIET":7,"EXTREME_ENVIRONMENT":15,"LIGNOCELLULOSE":31,"METAL_REDUCTION":3,"METHANOGENESIS":14,"ORAL":5,"OTHER":38,"PHYTOPLANKTON":14,"RHIZOSPHERE":64,"SYNTROPHY":32},"corpus_sha256":"ca0b9e902e0e62b04efd56d339e743a2290737890961e6f146770a522f32bf92","count":372,"input_sha256":"ac00a842989e6d6debb8bac51c41632f855f93bd8d3ec58d6f88d72cd8ff523b","records_sha256":"6ecf47bdd7b6b3fdd523d83c6788348284bcbb6c6d517d0d5350e4cc7c1e9dd1"},"projection":{"FP_ratio":2.0,"MN_ratio":0.5,"apply_pca":true,"dimensions":2,"distance":"euclidean","effective_pairs":{"further":30,"mid_near":8,"neighbors":15},"implementation":"pacmap.PaCMAP","initialization":"pca","iterations":[100,100,250],"knn_backend":"faiss","learning_rate":1.0,"library_versions":{"faiss-cpu":"1.15.0","numba":"0.63.1","numpy":"2.3.5","pacmap":"0.9.1","scikit-learn":"1.8.0"},"method":"pacmap","neighbors":15,"requested_neighbors":15,"seed":42},"representation":"semantic-text","source_vectors":{"dtype":"float32-le","order":"points.json","sha256":"393f2b6037fca355d4cf7609fb134170e40118d8cc183c8157abba14846c334a","shape":[372,1024],"storage":"local-profile-bound-cache"}} diff --git a/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/points.json b/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/points.json new file mode 100644 index 000000000..81bece12c --- /dev/null +++ b/data/text_map/87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc/points.json @@ -0,0 +1 @@ +[{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000253","label":"Premature Infant Gut Escherichia In-Situ Physiological-Condition Community","page":"communities/Premature_Infant_Gut_Escherichia_Diametric_Ratio_Community.html","source_path":"kb/communities/Premature_Infant_Gut_Escherichia_Diametric_Ratio_Community.yaml","text_sha256":"67205c25d3f4d1ed9fc4ceaceda915c5d9e30d3fa443c244d0434f28b01218d7","x":3.2307217121124268,"y":3.371659755706787},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000181","label":"Pseudomonas-Rhodococcus Chloronitrobenzene Coculture","page":"communities/Pseudomonas_Rhodococcus_Chloronitrobenzene_Coculture.html","source_path":"kb/communities/Pseudomonas_Rhodococcus_Chloronitrobenzene_Coculture.yaml","text_sha256":"da78170c9066bedd392987d83cadefaa13688bddb593c5060ae787db04575da0","x":-0.6078157424926758,"y":-0.48021653294563293},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000238","label":"Acetylene-Fueled Trichloroethene Dechlorination Groundwater Enrichment","page":"communities/Acetylene_Fueled_TCE_Dechlorination_Groundwater_Enrichment.html","source_path":"kb/communities/Acetylene_Fueled_TCE_Dechlorination_Groundwater_Enrichment.yaml","text_sha256":"d41977e75e3e07b84497035cb5110cc454c24592b390e7b2dc54d06b49fb78ec","x":-1.9608172178268433,"y":-1.3322618007659912},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000283","label":"Sesame-flavor Baijiu Fuqu SynCom (13-genus)","page":"communities/SynCom_Sesame_Flavor_Baijiu_Fuqu_13Genus.html","source_path":"kb/communities/SynCom_Sesame_Flavor_Baijiu_Fuqu_13Genus.yaml","text_sha256":"39996efb04ee9ee66173d1c46e19a8066a10815e6cc437e9df4d864477ae8dc4","x":2.9754321575164795,"y":0.8567348122596741},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000174","label":"Clostridium cellulovorans-Methanosarcina barkeri Cellulose Methane Coculture","page":"communities/Clostridium_Cellulovorans_Methanosarcina_Cellulose_Methane_Coculture.html","source_path":"kb/communities/Clostridium_Cellulovorans_Methanosarcina_Cellulose_Methane_Coculture.yaml","text_sha256":"71d4ac19aa9dcb05b870a19ca32fbe2938935b01a2046a3396b0b34bb37766cf","x":-2.175126314163208,"y":1.9358447790145874},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000302","label":"SynCom MetG2 Rhizobacteria Sugarcane Stress Resilience","page":"communities/SynCom_MetG2_Rhizobacteria_Sugarcane_Stress_Resilience.html","source_path":"kb/communities/SynCom_MetG2_Rhizobacteria_Sugarcane_Stress_Resilience.yaml","text_sha256":"b5d97fa90a128e64006f6799ef58106b80a64a78a24457c191b7d20cb29e63a1","x":4.068554878234863,"y":-2.5681259632110596},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000169","label":"Methylocaldum-Methyloceanibacter Methane Cross-Feeding Coculture","page":"communities/Methylocaldum_Methyloceanibacter_Methane_Crossfeeding_Coculture.html","source_path":"kb/communities/Methylocaldum_Methyloceanibacter_Methane_Crossfeeding_Coculture.yaml","text_sha256":"6ce03369bea38101c0b97778938d42253de2c660ab873389d203b23e69f9c750","x":-3.331669330596924,"y":2.5319433212280273},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000121","label":"Methane Oxidation-Cr(VI) Reduction SynCom","page":"communities/Methane_Oxidation_CrVI_Reduction_SynCom.html","source_path":"kb/communities/Methane_Oxidation_CrVI_Reduction_SynCom.yaml","text_sha256":"dd57711476dd0625d34c721f17adb84f7d82cb6cdd18d7d0682a153b6d59bd10","x":-2.6406538486480713,"y":2.756192207336426},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000002","label":"AMD Nitrososphaerota Archaeal Community","page":"communities/AMD_Nitrososphaerota_Archaeal.html","source_path":"kb/communities/AMD_Nitrososphaerota_Archaeal.yaml","text_sha256":"0266d839420377de9eb37ce08a6d9dbfdb9ac90b4a32be489d267c7aa7de9f16","x":-3.63478684425354,"y":-4.350777626037598},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000313","label":"Chlorella fusca CHK0059 Keystone-Taxa Antifungal SynCom","page":"communities/Chlorella_Keystone_Taxa_Antifungal_SynCom.html","source_path":"kb/communities/Chlorella_Keystone_Taxa_Antifungal_SynCom.yaml","text_sha256":"e907346f4566c3c9b63a260e3a204cfb6bc40f63f8593d4dff16b90015a029d6","x":3.533454656600952,"y":-0.9772730469703674},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000116","label":"Aerobic Denitrification Disturbance-Stable SynCom","page":"communities/Aerobic_Denitrification_Disturbance_SynCom.html","source_path":"kb/communities/Aerobic_Denitrification_Disturbance_SynCom.yaml","text_sha256":"4429fce85132bd50dbb5a35d3bb739b1194e4f583fae5c9734f1d2b09f3ac2d8","x":-0.8535351157188416,"y":-2.381023406982422},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000003","label":"At-RSPHERE SynCom","page":"communities/At_RSPHERE_SynCom.html","source_path":"kb/communities/At_RSPHERE_SynCom.yaml","text_sha256":"f8f2c5ae7b4c27c001f44aa0708eeb8e2bc9b1b8f57924ea983c38b328fd2eb9","x":3.5365118980407715,"y":-2.551745891571045},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000319","label":"SPRUCE Peatland Warming Microbial Community","page":"communities/SPRUCE_Peatland_Warming_Community.html","source_path":"kb/communities/SPRUCE_Peatland_Warming_Community.yaml","text_sha256":"8f405c1c09e76fff325d91645f7745b75e82f71c5d51ad0ba69c078b80fa7530","x":-4.0151801109313965,"y":-2.9973788261413574},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000251","label":"Subsurface Carboxydocella CO-Oxidation Aquifer Community","page":"communities/Subsurface_Carboxydocella_CO_Aquifer_Community.html","source_path":"kb/communities/Subsurface_Carboxydocella_CO_Aquifer_Community.yaml","text_sha256":"aa201a4a9a0e260c15823139a1b95d6d980f435838030fe55c921d758e95d7ef","x":-2.9535534381866455,"y":-3.2350423336029053},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000240","label":"Infant Gut Strain Persistence and Maternal Seeding Community","page":"communities/Infant_Gut_Strain_Persistence_Maternal_Community.html","source_path":"kb/communities/Infant_Gut_Strain_Persistence_Maternal_Community.yaml","text_sha256":"69ada16b99d71051db33e1ba53cdb2873d4c8f7784963e4c31f496bc782bc2fe","x":3.457515239715576,"y":3.5661487579345703},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000162","label":"Thalassiosira-Ruegeria Phycosphere Coculture","page":"communities/Thalassiosira_Ruegeria_Phycosphere_Coculture.html","source_path":"kb/communities/Thalassiosira_Ruegeria_Phycosphere_Coculture.yaml","text_sha256":"58d82a0f05604caf169784ed48e6e508e81fbb5d296486e2f4c7c8714fa7a9a4","x":-0.6132818460464478,"y":5.59945821762085},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000266","label":"Clostridium carboxidivorans-Clostridium kluyveri CO Chain-Elongation Coculture","page":"communities/Clostridium_Carboxidivorans_Kluyveri_CO_Chain_Elongation_Coculture.html","source_path":"kb/communities/Clostridium_Carboxidivorans_Kluyveri_CO_Chain_Elongation_Coculture.yaml","text_sha256":"8a93981ea60f6d1582ce4ed22917b327a0538e51e616deaf54ccda6c119b27e8","x":-1.8884721994400024,"y":2.389552354812622},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000350","label":"High-Ammonia Biogas 0B Butyrate-Oxidizing Enrichment","page":"communities/High_Ammonia_Biogas_0B_Butyrate_Oxidizing_Enrichment.html","source_path":"kb/communities/High_Ammonia_Biogas_0B_Butyrate_Oxidizing_Enrichment.yaml","text_sha256":"f3a053df91503cdfeb77e8f71788ea035d5f8527ec1e2c21b80548fd7092381e","x":-4.235561370849609,"y":0.754021942615509},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000202","label":"Clostridium ljungdahlii-Clostridium kluyveri Syngas Alcohol Coculture","page":"communities/Clostridium_Ljungdahlii_Kluyveri_Syngas_Alcohol_Coculture.html","source_path":"kb/communities/Clostridium_Ljungdahlii_Kluyveri_Syngas_Alcohol_Coculture.yaml","text_sha256":"d7c6e260da2271153a2b83c42ab8635f916f1ebadf74334aa869fbc9ad121ec5","x":-2.004319429397583,"y":2.382392406463623},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000158","label":"Bacteroides-Eubacterium Gnotobiotic Gut Model","page":"communities/Bacteroides_Eubacterium_Gnotobiotic_Gut_Model.html","source_path":"kb/communities/Bacteroides_Eubacterium_Gnotobiotic_Gut_Model.yaml","text_sha256":"30dc825ae57ac2fc4c62fb1f0ed57fc97aecb9f4cc24f72f7adad4cd7bbc38a2","x":2.976564645767212,"y":3.741856813430786},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000244","label":"Anammox Bioreactor DNRA Destabilization Community","page":"communities/Anammox_Bioreactor_DNRA_Destabilization_Community.html","source_path":"kb/communities/Anammox_Bioreactor_DNRA_Destabilization_Community.yaml","text_sha256":"fa1f8c01b97375d5085a2996f326873f25ac3c076fdec3eebd48115dc5ae696b","x":-1.1807197332382202,"y":-2.4674885272979736},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000178","label":"Model Lignocellulose Formaldehyde Cross-Feeding Community","page":"communities/Model_Lignocellulose_Formaldehyde_Crossfeeding_Community.html","source_path":"kb/communities/Model_Lignocellulose_Formaldehyde_Crossfeeding_Community.yaml","text_sha256":"642600ffcf3c767dc6629ad5bf9326d8f024bf6c8f0165c399dab7f35d5bb6db","x":0.0666825994849205,"y":1.4401861429214478},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000210","label":"Zymomonas-E. coli Exometabolomics-Designed Obligate Mutualism","page":"communities/Zymomonas_Ecoli_Exometabolomics_Obligate_Mutualism.html","source_path":"kb/communities/Zymomonas_Ecoli_Exometabolomics_Obligate_Mutualism.yaml","text_sha256":"daabed8e93b5d688aa026868cb8d96d41af076cadefb814712dbee5c2ede2a7c","x":0.38657069206237793,"y":3.861645221710205},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000282","label":"Thermophilic Lignocellulose-degrading Composting SynCom","page":"communities/Thermophilic_Lignocellulose_Composting_SynCom_Biosanitization.html","source_path":"kb/communities/Thermophilic_Lignocellulose_Composting_SynCom_Biosanitization.yaml","text_sha256":"3ca7cf653849f35a29fba9b66bab3f2c11277f0cbbf4504c2f84f2581f3204ff","x":3.048124074935913,"y":0.4863537549972534},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000348","label":"Sorghum SRC2v4 Root Colonization SynCom","page":"communities/Sorghum_SRC2v4_Root_Colonization_SynCom.html","source_path":"kb/communities/Sorghum_SRC2v4_Root_Colonization_SynCom.yaml","text_sha256":"2a5f64fe631293f02d210dd36aeb349c978100b50cad01b1194763efabf633c5","x":3.1896004676818848,"y":-2.4266421794891357},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000133","label":"OMM12 Gnotobiotic Mouse Gut Community","page":"communities/OMM12_Gnotobiotic_Mouse_Gut_Community.html","source_path":"kb/communities/OMM12_Gnotobiotic_Mouse_Gut_Community.yaml","text_sha256":"67e0d14e3ec23996299ced689eee3846cc4e9dc2bc56b2682db801a199c7c3d7","x":3.293034791946411,"y":3.4814159870147705},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000296","label":"Escherichia coli + Bifidobacterium bifidum Infant-gut Mutualistic Co-culture","page":"communities/Ecoli_Bifidobacterium_bifidum_Infant_gut_HMO_Mutualism_Coculture.html","source_path":"kb/communities/Ecoli_Bifidobacterium_bifidum_Infant_gut_HMO_Mutualism_Coculture.yaml","text_sha256":"ad40e5f4231946d4918a4212ec49695f27e5bccc442a13bd58e6d7d57a8d7539","x":2.8398938179016113,"y":3.5314433574676514},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000071","label":"Syntrophus Benzoate Degrader","page":"communities/Syntrophus_Benzoate_Degrader.html","source_path":"kb/communities/Syntrophus_Benzoate_Degrader.yaml","text_sha256":"014838683b6b1fe56100d3c6588699cc2725abaf8ab952c56d66399347a1ab72","x":-4.597818374633789,"y":1.1940251588821411},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000094","label":"Arabidopsis Coumarin Root SynCom","page":"communities/Arabidopsis_Coumarin_Root_SynCom.html","source_path":"kb/communities/Arabidopsis_Coumarin_Root_SynCom.yaml","text_sha256":"73ff9d5aaeefa58718a7614ac3b06e0f244c418a11df38124aa38fcdaef85ad8","x":4.161531448364258,"y":-2.5142998695373535},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000009","label":"BioModels MODEL2204300001 Kefir Community Model","page":"communities/BioModels_MODEL2204300001_Kefir_Community_Model.html","source_path":"kb/communities/BioModels_MODEL2204300001_Kefir_Community_Model.yaml","text_sha256":"97d18f5c78a98347aeeb9622b21b612829166176b1484c94cd0043a65d28815e","x":1.8470717668533325,"y":4.669951915740967},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000315","label":"Mesorhizobium TaiHu-Synechococcus PCC 7002 Vitamin B12 Synthetic Consortium","page":"communities/Mesorhizobium_Synechococcus_B12_Synthetic_Consortium.html","source_path":"kb/communities/Mesorhizobium_Synechococcus_B12_Synthetic_Consortium.yaml","text_sha256":"b61d6e6613310cc35c284d3d029a2d205bef0c520a128ae12cf96757d00440f5","x":-1.0979630947113037,"y":5.4691948890686035},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000239","label":"Thiocyanate-Degrading Afipia and Thiobacillus Bioreactor Community","page":"communities/Thiocyanate_Afipia_Thiobacillus_Bioreactor_Community.html","source_path":"kb/communities/Thiocyanate_Afipia_Thiobacillus_Bioreactor_Community.yaml","text_sha256":"db32794bf39eae900a09ff0f0abb5ae58d3a74ebc9a5dd1866c5c029495ead43","x":-0.8260172009468079,"y":-1.8381035327911377},{"adapter_version":"communitymech-semantic-v1","category":"METAL_REDUCTION","identifier":"CommunityMech:000268","label":"Rhodopseudomonas-Geobacter Magnetite Redox Coculture","page":"communities/Rhodopseudomonas_Geobacter_Magnetite_Redox_Coculture.html","source_path":"kb/communities/Rhodopseudomonas_Geobacter_Magnetite_Redox_Coculture.yaml","text_sha256":"ff8eb02beff5f52b739f73c05e38b78d443d0e928c8323be256883e749533708","x":-3.121076822280884,"y":-1.1685371398925781},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000005","label":"Bayan Obo REE Tailings Consortium","page":"communities/Bayan_Obo_REE_Tailings_Consortium.html","source_path":"kb/communities/Bayan_Obo_REE_Tailings_Consortium.yaml","text_sha256":"0acb111b168fa6902e555c1582690f3a5986459821fe30e35f26617e0b7c35f7","x":-3.785235643386841,"y":-5.975985527038574},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000344","label":"Klebsiella-Arthrobacter KZ Phenanthrene-Cadmium SynCom","page":"communities/Klebsiella_Arthrobacter_KZ_Phenanthrene_Cadmium_SynCom.html","source_path":"kb/communities/Klebsiella_Arthrobacter_KZ_Phenanthrene_Cadmium_SynCom.yaml","text_sha256":"507ae5f7b39c7cb653b8032a97ed2b9c5d74b1fb9c63c82db42f9b3a1f31ca8d","x":0.45059046149253845,"y":-1.0571359395980835},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000207","label":"Synechococcus-Azotobacter Photoproduction Mutualism","page":"communities/Synechococcus_Azotobacter_Photoproduction_Mutualism.html","source_path":"kb/communities/Synechococcus_Azotobacter_Photoproduction_Mutualism.yaml","text_sha256":"5d1e476f7569fa0222b08670932305871772251048178e5a0ed2b7068190305d","x":-1.9450185298919678,"y":5.861614227294922},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000252","label":"Crystal Geyser CO2-Rich Aquifer Autotrophic CPR Lysolipid Community","page":"communities/Crystal_Geyser_CO2_Aquifer_CPR_Lipid_Community.html","source_path":"kb/communities/Crystal_Geyser_CO2_Aquifer_CPR_Lipid_Community.yaml","text_sha256":"bcb7c6b6aaf6a8fc9bed2240075c194565e87f8b685da8fff44e373807993688","x":-2.749391555786133,"y":-3.503636121749878},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000351","label":"MUC2 Human Gut Commensal Defined Consortium","page":"communities/MUC2_Human_Gut_Commensal_Defined_Consortium.html","source_path":"kb/communities/MUC2_Human_Gut_Commensal_Defined_Consortium.yaml","text_sha256":"dee352c06c04572f5a495ce560b0e46469d2f4e19720605b6e5619b9f9bf8faf","x":2.334261655807495,"y":3.2062840461730957},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000108","label":"Medicago Nodule Biofertilizer SynCom","page":"communities/Medicago_Nodule_Biofertilizer_SynCom.html","source_path":"kb/communities/Medicago_Nodule_Biofertilizer_SynCom.yaml","text_sha256":"393a68af62125c5fb54d9bc2ad44886de1b2fb8415ac9af35696a543a39d9d57","x":4.030205726623535,"y":-2.356149911880493},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000199","label":"Dehalococcoides-Desulfovibrio Lactate-Fed TCE Dechlorination Coculture","page":"communities/Dehalococcoides_Desulfovibrio_Lactate_TCE_Syntrophy.html","source_path":"kb/communities/Dehalococcoides_Desulfovibrio_Lactate_TCE_Syntrophy.yaml","text_sha256":"2d9da7bb6507422a28816efe6ae8e34f7f77ffa212d7189ac6911f70dee7045e","x":-1.9176974296569824,"y":-0.24581316113471985},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000310","label":"Moss-Microbe Complex Regolith Biofertilizer","page":"communities/Moss_Microbe_Complex_Regolith_Biofertilizer.html","source_path":"kb/communities/Moss_Microbe_Complex_Regolith_Biofertilizer.yaml","text_sha256":"4f1b433a1704ada9e7962cf5376b03314557321d6a0e6e4f496caa1c531e3e24","x":-3.371643543243408,"y":-7.315645694732666},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000106","label":"Tobacco Chemotactic Biocontrol SynCom","page":"communities/Tobacco_Chemotactic_Biocontrol_SynCom.html","source_path":"kb/communities/Tobacco_Chemotactic_Biocontrol_SynCom.yaml","text_sha256":"7bba00461530df3c159393eb0a359c7350ce7705be5c7b0b628d2d82569f5f16","x":5.018680095672607,"y":-1.6807719469070435},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000345","label":"Pichia-Lactiplantibacillus CCMA Plant Beverage Coculture","page":"communities/Pichia_Lactiplantibacillus_CCMA_Plant_Beverage_Coculture.html","source_path":"kb/communities/Pichia_Lactiplantibacillus_CCMA_Plant_Beverage_Coculture.yaml","text_sha256":"90330af67ec162f11e25ef35639368c81934295e263146c2eff595126d551a79","x":0.5441087484359741,"y":2.52799129486084},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000339","label":"Space Habitat Seven-Member Stress-Tolerance SynCom","page":"communities/Space_Habitat_SevenMember_Stress_Tolerance_SynCom.html","source_path":"kb/communities/Space_Habitat_SevenMember_Stress_Tolerance_SynCom.yaml","text_sha256":"c316246fb1d2da58432ca34adfc58377fcbe1027c5b8da81ad6e607e5cdadee8","x":3.669246196746826,"y":1.3051815032958984},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000124","label":"Honeybee Core-20 Defined Microbiota","page":"communities/Honeybee_Core20_Defined_Microbiota.html","source_path":"kb/communities/Honeybee_Core20_Defined_Microbiota.yaml","text_sha256":"6fdce04448b3a330e9d18de84d5248585b1860b4e278a7feca6d2e0573d84706","x":3.510442018508911,"y":3.2784082889556885},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000195","label":"Coniochaeta-Sphingobacterium-Citrobacter Wheat Straw Consortium","page":"communities/Coniochaeta_Sphingobacterium_Citrobacter_Wheat_Straw_Consortium.html","source_path":"kb/communities/Coniochaeta_Sphingobacterium_Citrobacter_Wheat_Straw_Consortium.yaml","text_sha256":"4616901642545e91fb479067c9d3fd92010aae307f4e0263ce6e3bf90bc42c4b","x":-0.040698084980249405,"y":1.3813892602920532},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000149","label":"Synthetic Lichen Synechococcus-Rhodotorula Coculture","page":"communities/Synthetic_Lichen_Synechococcus_Rhodotorula_Coculture.html","source_path":"kb/communities/Synthetic_Lichen_Synechococcus_Rhodotorula_Coculture.yaml","text_sha256":"59e81e862817b46ffff9b76052cd85faae2d1d3f8dd47d036d9c0be8df0e0848","x":-1.7843332290649414,"y":5.968220233917236},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000324","label":"Pseudomonas-Bacillus Waxy Oil Biodegradation Consortium","page":"communities/Pseudomonas_Bacillus_Waxy_Oil_Biodegradation_Consortium.html","source_path":"kb/communities/Pseudomonas_Bacillus_Waxy_Oil_Biodegradation_Consortium.yaml","text_sha256":"b79636a33dc244660c4a518e0968f2a8777fbf3c112545d515a736c418de04a8","x":-0.01239005010575056,"y":-0.6348085999488831},{"adapter_version":"communitymech-semantic-v1","category":"METAL_REDUCTION","identifier":"CommunityMech:000262","label":"Alaska Tundra Permafrost Iron-Redox Community","page":"communities/Alaska_Tundra_Permafrost_Iron_Redox_Community.html","source_path":"kb/communities/Alaska_Tundra_Permafrost_Iron_Redox_Community.yaml","text_sha256":"4ff0770a2b7353d8a43e80d59176f311f359a433be8e3820c19a29cf7b29b9a4","x":-3.759805679321289,"y":-2.904301881790161},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000052","label":"Pelotomaculum-Methanothermobacter Syntrophic Consortium","page":"communities/Pelotomaculum_Methanothermobacter_Syntrophy.html","source_path":"kb/communities/Pelotomaculum_Methanothermobacter_Syntrophy.yaml","text_sha256":"67b1a1c3526f65373edad53306332a5d9c9dd14f5f008f1b6ca7d99cd2bc7ecb","x":-4.785126209259033,"y":1.0205832719802856},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000223","label":"Infant Gut DNA Phageome Succession Community","page":"communities/Infant_Gut_DNA_Phage_Succession_Community.html","source_path":"kb/communities/Infant_Gut_DNA_Phage_Succession_Community.yaml","text_sha256":"5559828451ff6315cb734dfa6430e67a03cdc0e2d03485535e4a708cf0695616","x":3.4681482315063477,"y":3.5578994750976562},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000104","label":"Pepper Growth Rhizosphere SynCom","page":"communities/Pepper_Growth_Rhizosphere_SynCom.html","source_path":"kb/communities/Pepper_Growth_Rhizosphere_SynCom.yaml","text_sha256":"cf8931f77425eec84df9a2a6481f577655e5d0707b15c47aebfdb25f5aea1f82","x":5.118863582611084,"y":-1.925755500793457},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000019","label":"Copper Biomining Heap Leach Consortium","page":"communities/Copper_Biomining_Heap_Leach.html","source_path":"kb/communities/Copper_Biomining_Heap_Leach.yaml","text_sha256":"acc3077195ef0a7fc5ea0cd02ed655552bc437dedf92e595fdd486d8b2d01ee3","x":-4.0857253074646,"y":-5.617560386657715},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000367","label":"Mediterranean AM Fungal Six-Species SynCom","page":"communities/Mediterranean_AM_Fungal_SixSpecies_SynCom.html","source_path":"kb/communities/Mediterranean_AM_Fungal_SixSpecies_SynCom.yaml","text_sha256":"505981ac6de55902cb4ba8d4fb5cb9c9c007987ac705da19204c7a05b6d0065b","x":2.941084861755371,"y":-2.637756586074829},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000340","label":"Pelagerythrobacter-Salinicola PES Pyrene-Degradation SynCom","page":"communities/Pelagerythrobacter_Salinicola_PES_Pyrene_Degradation_SynCom.html","source_path":"kb/communities/Pelagerythrobacter_Salinicola_PES_Pyrene_Degradation_SynCom.yaml","text_sha256":"27bc055a9dfcf825b58778936037de861e8d5cf045f355faf55d11d9e5ce39bd","x":0.01948748715221882,"y":-0.7151609659194946},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000357","label":"E. coli GL10-XL12 D-Lactate Mixed-Sugar SynCom","page":"communities/Ecoli_GL10_XL12_D_Lactate_Mixed_Sugar_SynCom.html","source_path":"kb/communities/Ecoli_GL10_XL12_D_Lactate_Mixed_Sugar_SynCom.yaml","text_sha256":"edbad66348c1501aa94c6d957cfa0bd9bee78d210bb04283a84bb594f88d32b7","x":0.5875663161277771,"y":2.7558789253234863},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000218","label":"Horonobe and Mizunami Underground Research Laboratory Subsurface Microbiome","page":"communities/Horonobe_Mizunami_URL_Subsurface_Microbiome.html","source_path":"kb/communities/Horonobe_Mizunami_URL_Subsurface_Microbiome.yaml","text_sha256":"f0daa3cb288486dd3f2e1990d2a135d5b252c86bbf3901de1630ac007c7ad549","x":-2.743284225463867,"y":-3.8085718154907227},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000248","label":"Candida parapsilosis Hospitalized Infant Gut Microbiome Community","page":"communities/Candida_Parapsilosis_Hospitalized_Infant_Microbiome.html","source_path":"kb/communities/Candida_Parapsilosis_Hospitalized_Infant_Microbiome.yaml","text_sha256":"338a714302bc27abd5ec1a7a8d832febe931040088dc21300b3f4ecd3cc690e9","x":3.2402687072753906,"y":3.8178300857543945},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000353","label":"Hualgayoc Acidic Sulfate-Reducing AMD Consortium","page":"communities/Hualgayoc_Acidic_Sulfate_Reducing_AMD_Consortium.html","source_path":"kb/communities/Hualgayoc_Acidic_Sulfate_Reducing_AMD_Consortium.yaml","text_sha256":"cf1a351d52b4aafbf85ba16103eef2bed46c6f08b462eec44eeb17786ac0c2da","x":-3.8116183280944824,"y":-4.562318801879883},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000300","label":"Pleuromutilin-degrading Artificial Consortium (5-strain)","page":"communities/Pleuromutilin_Degrading_Artificial_Consortium_5_Strain.html","source_path":"kb/communities/Pleuromutilin_Degrading_Artificial_Consortium_5_Strain.yaml","text_sha256":"f5531987bf27a7ec6e786a93c33d8dc48936ffbaadba8f1fe85f01b16e0bff2f","x":0.4311549961566925,"y":-0.11282452195882797},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000062","label":"Salar de Atacama Lithium Brine Community","page":"communities/Salar_Atacama_Lithium_Brine_Community.html","source_path":"kb/communities/Salar_Atacama_Lithium_Brine_Community.yaml","text_sha256":"694229e964d9ec16bca865ecdec7011bd454cfdf50064f4e0f683939947fc097","x":-3.574040651321411,"y":-4.272478103637695},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000213","label":"Variovorax-Cryptococcus Vitamin Cross-Feeding Microcosm","page":"communities/Variovorax_Cryptococcus_Vitamin_Mutualism_Microcosm.html","source_path":"kb/communities/Variovorax_Cryptococcus_Vitamin_Mutualism_Microcosm.yaml","text_sha256":"d38643710e7c9bf5b12c2b4d59344123f03274245e2962ccfefd492f3fc63732","x":-0.08579102903604507,"y":5.148460388183594},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000271","label":"Propanotrophic Chlorinated Ethene Cometabolism Enrichment Cultures","page":"communities/Propanotrophic_Chlorinated_Ethene_Cometabolism_Enrichment.html","source_path":"kb/communities/Propanotrophic_Chlorinated_Ethene_Cometabolism_Enrichment.yaml","text_sha256":"d2e6a42501857b02ed0e08b0722e2dc189f75dfbb1fc6fcaad8084b0b3d26fbe","x":-1.419797658920288,"y":-0.8460599780082703},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000150","label":"Desulfovibrio-Methanosarcina Lactate Syntrophy","page":"communities/Desulfovibrio_Methanosarcina_Lactate_Syntrophy.html","source_path":"kb/communities/Desulfovibrio_Methanosarcina_Lactate_Syntrophy.yaml","text_sha256":"cb844f6862ebeeb978c2206a38e494365cc9b850cba70b31674ee664db0108ad","x":-3.8950483798980713,"y":1.1875497102737427},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000136","label":"Oak Ridge FRC Uranium-Nitrate Groundwater Community","page":"communities/Oak_Ridge_FRC_Uranium_Nitrate_Groundwater_Community.html","source_path":"kb/communities/Oak_Ridge_FRC_Uranium_Nitrate_Groundwater_Community.yaml","text_sha256":"3ad2c3ac7d5376cf4c861336c0e277f3191b597405ac5ae26d1f62a99e749be6","x":-2.5754446983337402,"y":-3.741626501083374},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000352","label":"GENIA Nine-Member Multi-Pollutant Bioremediation SynCom","page":"communities/GENIA_NineMember_MultiPollutant_Bioremediation_SynCom.html","source_path":"kb/communities/GENIA_NineMember_MultiPollutant_Bioremediation_SynCom.yaml","text_sha256":"343a7c8439ff159b1f1da16c3532c933f7d504a30c114427a3650317e430cbaa","x":2.495553731918335,"y":-0.9802331924438477},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000142","label":"Bacteroides-Methanobrevibacter Gnotobiotic Mouse Mutualism","page":"communities/Bacteroides_Methanobrevibacter_Gnotobiotic_Mouse_Mutualism.html","source_path":"kb/communities/Bacteroides_Methanobrevibacter_Gnotobiotic_Mouse_Mutualism.yaml","text_sha256":"dbf25e1c119718254996e3b3b2fd56db78ad7614a2e438cdd9811dc509aec4f5","x":2.721143960952759,"y":3.496242046356201},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000177","label":"Shewanella-Geobacter Three-Species Exoelectrogenic Biofilm Community","page":"communities/Shewanella_Geobacter_Exoelectrogenic_Biofilm_Community.html","source_path":"kb/communities/Shewanella_Geobacter_Exoelectrogenic_Biofilm_Community.yaml","text_sha256":"efb22822e1ed75a2d3ba56c325607dfe9a5f6fd1152d2213278a5619022ececc","x":-3.2696361541748047,"y":-0.8427521586418152},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000068","label":"Syntrophobacter-Methanobacterium Syntrophic Consortium","page":"communities/Syntrophobacter_Methanobacterium_Syntrophy.html","source_path":"kb/communities/Syntrophobacter_Methanobacterium_Syntrophy.yaml","text_sha256":"8c36b2523056f3deedaff83340d0ee6a881bf473bb216ee987c983714c6bf911","x":-4.655643463134766,"y":0.9671416878700256},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000059","label":"Richmond Mine AMD Biofilm","page":"communities/Richmond_Mine_AMD_Biofilm.html","source_path":"kb/communities/Richmond_Mine_AMD_Biofilm.yaml","text_sha256":"93c79d954cdfccfd6ceb7912f195eb741d5a0148b0005491c45a501107293d5f","x":-3.897205352783203,"y":-5.0306715965271},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000303","label":"BioRock ISS Basalt Biomining Consortium","page":"communities/BioRock_ISS_Basalt_Biomining_Consortium.html","source_path":"kb/communities/BioRock_ISS_Basalt_Biomining_Consortium.yaml","text_sha256":"b9abdea4de7c439f7d23cb2bf082f9b0d0f18e363f3a1230c0d548387513f34d","x":-3.6009531021118164,"y":-6.643798351287842},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000366","label":"Cultivated Meat Contaminant SynCom","page":"communities/Cultivated_Meat_Contaminant_SynCom.html","source_path":"kb/communities/Cultivated_Meat_Contaminant_SynCom.yaml","text_sha256":"c56997838ee350fe1935029c0f18b6797813412fce5c16de8e5a8f8b9ab918f7","x":3.4390549659729004,"y":0.9102683663368225},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000103","label":"Maize Drought Response SynCom","page":"communities/Maize_Drought_Response_SynCom.html","source_path":"kb/communities/Maize_Drought_Response_SynCom.yaml","text_sha256":"94d567fe1d7f04a3749884310563e891643630761b55983280b37557c5427b0c","x":4.171766757965088,"y":-2.256147623062134},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000259","label":"Thalassiosira-Marinobacter Marine Snow Coculture","page":"communities/Thalassiosira_Marinobacter_Marine_Snow_Coculture.html","source_path":"kb/communities/Thalassiosira_Marinobacter_Marine_Snow_Coculture.yaml","text_sha256":"6f113705f887b73d38816187fc5fd5b481180b4b78d4d2e9827d67fc4288e78d","x":-0.628815233707428,"y":5.82745361328125},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000032","label":"Geobacter-Methanosaeta DIET Community","page":"communities/Geobacter_Methanosaeta_DIET.html","source_path":"kb/communities/Geobacter_Methanosaeta_DIET.yaml","text_sha256":"da9185e7bd2dfd154e6da4161f70ddb71ae9593f77f00e3d5fbeb80a5514b013","x":-3.5572497844696045,"y":-0.532174289226532},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000057","label":"Rammelsberg Cobalt-Nickel Tailings Consortium","page":"communities/Rammelsberg_Cobalt_Nickel_Tailings.html","source_path":"kb/communities/Rammelsberg_Cobalt_Nickel_Tailings.yaml","text_sha256":"c0467a5f22a1b57dc59ea94962848ecfef67c0d30a798ac079939d293fdcb702","x":-3.9645962715148926,"y":-5.561802864074707},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000171","label":"Methylacidiphilum-Galdieria Thermoacidophilic Methane Coculture","page":"communities/Methylacidiphilum_Galdieria_Thermoacidophilic_Coculture.html","source_path":"kb/communities/Methylacidiphilum_Galdieria_Thermoacidophilic_Coculture.yaml","text_sha256":"924aedae62df5268541a22179dd8df0ad4c014f1c0aae10fb2df03af51757c70","x":-2.514552354812622,"y":3.84505033493042},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000358","label":"Bacillus A1-A3 Naphthalene Biofilm Consortium","page":"communities/Bacillus_A1_A3_Naphthalene_Biofilm_Consortium.html","source_path":"kb/communities/Bacillus_A1_A3_Naphthalene_Biofilm_Consortium.yaml","text_sha256":"ee7f08806d4d533e4102bedd6e38716283cce1c07dfe4bfb671a0d483f643c2f","x":0.12371133267879486,"y":-0.7904185056686401},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000014","label":"Chlamydomonas-Bacterial Hydrogen Production Consortium","page":"communities/Chlamydomonas_Bacterial_H2_Consortium.html","source_path":"kb/communities/Chlamydomonas_Bacterial_H2_Consortium.yaml","text_sha256":"27f63383e74e87a5b46368314c22fb896627febfdf7127a18c5057264f754e93","x":-1.3021148443222046,"y":5.250540733337402},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000160","label":"Drosophila Five-Species Gnotobiotic Gut Microbiota","page":"communities/Drosophila_FiveSpecies_Gnotobiotic_Gut_Microbiota.html","source_path":"kb/communities/Drosophila_FiveSpecies_Gnotobiotic_Gut_Microbiota.yaml","text_sha256":"16bcf1a8cc58a59e2c0c1c80bab2da84c95921e2035fb129ce7283266643eb1d","x":2.708746910095215,"y":3.6431069374084473},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000099","label":"Jala Maize PGPB SynCom","page":"communities/Jala_Maize_PGPB_SynCom.html","source_path":"kb/communities/Jala_Maize_PGPB_SynCom.yaml","text_sha256":"3d82f27a5b54253638573b075fa4f1b2746c621481fbb8323f640c281f1d49ca","x":4.150224685668945,"y":-1.8997735977172852},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000245","label":"Avena Rhizosphere and Detritusphere Niche-Differentiated Decomposer Guilds","page":"communities/Avena_Rhizosphere_Detritusphere_Niche_Succession.html","source_path":"kb/communities/Avena_Rhizosphere_Detritusphere_Niche_Succession.yaml","text_sha256":"2e0a31be80145dbe06d70b752c8b2fcc7b00f0b21d954cf753d5af1292a27001","x":1.8494696617126465,"y":-3.2216527462005615},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000288","label":"Shewanella oneidensis + Pseudomonas aeruginosa Fe0-dependent Electro-syntrophic Denitrifying Consortium","page":"communities/Shewanella_Pseudomonas_Fe0_Electrosyntrophic_Denitrifying_Consortium.html","source_path":"kb/communities/Shewanella_Pseudomonas_Fe0_Electrosyntrophic_Denitrifying_Consortium.yaml","text_sha256":"8aad2a8dfd666f28ad7d66d3122ec5ee925071a40fe84e1ac3aa4d08f6fca64b","x":-2.5917773246765137,"y":-0.5429364442825317},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000211","label":"Synechococcus-Shewanella D-Lactate Biophotovoltaic Consortium","page":"communities/Synechococcus_Shewanella_Dlactate_Biophotovoltaic_Consortium.html","source_path":"kb/communities/Synechococcus_Shewanella_Dlactate_Biophotovoltaic_Consortium.yaml","text_sha256":"2251bad4e789006f81900e665f312bf8a65652208fc62e5ce890a2106c1dbe57","x":-2.0787012577056885,"y":5.7538323402404785},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000166","label":"Deepwater Horizon Deep-Sea Oil Plume Succession","page":"communities/Deepwater_Horizon_Deep_Sea_Oil_Plume_Succession.html","source_path":"kb/communities/Deepwater_Horizon_Deep_Sea_Oil_Plume_Succession.yaml","text_sha256":"3da089aab0ff6c3599ced18e5223879712e8220814c3f232596f389ddfe7b6c7","x":-2.701596260070801,"y":-2.6101341247558594},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000265","label":"Cellulomonas-Rhodobacter Cellulose Photohydrogen Coculture","page":"communities/Cellulomonas_Rhodobacter_Cellulose_Photohydrogen_Coculture.html","source_path":"kb/communities/Cellulomonas_Rhodobacter_Cellulose_Photohydrogen_Coculture.yaml","text_sha256":"ba75ba840d3de70adf815730d11d51c518b5f5f788ef2abda4af131037880160","x":-1.7937979698181152,"y":1.7382313013076782},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000346","label":"Chicken BL6 Anti-Salmonella SynCom","page":"communities/Chicken_BL6_AntiSalmonella_SynCom.html","source_path":"kb/communities/Chicken_BL6_AntiSalmonella_SynCom.yaml","text_sha256":"f02cbfc430aad88eb01e9aa2211781e1c42d8928031b836be5f589c7a70eec60","x":3.541550636291504,"y":2.168591260910034},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000376","label":"Ginseng CL95 Rusty Root Rot Biocontrol SynCom","page":"communities/Ginseng_CL95_Rusty_Root_Rot_Biocontrol_SynCom.html","source_path":"kb/communities/Ginseng_CL95_Rusty_Root_Rot_Biocontrol_SynCom.yaml","text_sha256":"5e885596fcbeea01c2c216fe1753c441ac0eb1a861b861984f6b6c17c5171f4e","x":5.1110148429870605,"y":-1.3291481733322144},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000119","label":"Multiomics Corn Straw Degradation SynCom","page":"communities/Multiomics_Corn_Straw_Degradation_SynCom.html","source_path":"kb/communities/Multiomics_Corn_Straw_Degradation_SynCom.yaml","text_sha256":"ce814ce8c6a1a542553a78f1df27beaa4a8b7581973ec0002b6fa4c38af48e9a","x":1.3083605766296387,"y":0.9929082989692688},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000335","label":"Streptomyces A2-A5-A11-M7 Pesticide-Bioremediation Consortium","page":"communities/Streptomyces_A2_A5_A11_M7_Pesticide_Consortium.html","source_path":"kb/communities/Streptomyces_A2_A5_A11_M7_Pesticide_Consortium.yaml","text_sha256":"dd03ba51ae82e203eb89dc28f00d72b1599a30da3dd806eeda10abaee19abf85","x":0.2130987048149109,"y":-0.9192069172859192},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000323","label":"Clostridium cellulovorans-Beijerinckii AECC ABE Coculture","page":"communities/Clostridium_Cellulovorans_Beijerinckii_AECC_ABE_Coculture.html","source_path":"kb/communities/Clostridium_Cellulovorans_Beijerinckii_AECC_ABE_Coculture.yaml","text_sha256":"10bd7050fc4e82080b20ef84df149653d56622a76896913f592aab767da1cc9b","x":-1.6868579387664795,"y":2.3145651817321777},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000125","label":"SkinCom Synthetic Skin Community","page":"communities/SkinCom_Synthetic_Skin_Community.html","source_path":"kb/communities/SkinCom_Synthetic_Skin_Community.yaml","text_sha256":"81cc2ee327bc36b796715e0a077ef511f16df4b633ea2c11915822629d8b9aec","x":3.3739473819732666,"y":2.1844217777252197},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000320","label":"Aspergillus Indium LCD Recovery Platform","page":"isolates/Aspergillus_Indium_LED_Recovery.html","source_path":"data/isolates/Aspergillus_Indium_LED_Recovery.yaml","text_sha256":"ca948047b9dd14f8fb7c3278228f524a4f83439f96607fe03316ba70d4ec0bc0","x":-3.8206748962402344,"y":-6.213545322418213},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000295","label":"Parachlorella kessleri + Saccharomyces cerevisiae Mutualistic Co-culture","page":"communities/Parachlorella_Saccharomyces_Mutualistic_Coculture.html","source_path":"kb/communities/Parachlorella_Saccharomyces_Mutualistic_Coculture.yaml","text_sha256":"aacf28dbe3f9505208f5fc0da72ccd1bd003fb9ee64483f0bc9145cf881c89ec","x":-0.9410389065742493,"y":5.17526912689209},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000155","label":"Ostreococcus-Dinoroseobacter B-Vitamin Mutualism","page":"communities/Ostreococcus_Dinoroseobacter_BVitamin_Mutualism.html","source_path":"kb/communities/Ostreococcus_Dinoroseobacter_BVitamin_Mutualism.yaml","text_sha256":"841884aec6107e8fe29e54175c790840224ae2d9e9f64a45dc2bff943c4cd5cf","x":-0.7768973112106323,"y":5.563060283660889},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000023","label":"Desulfovibrio-Methanococcus Syntrophic Consortium","page":"communities/Desulfovibrio_Methanococcus_Syntrophy.html","source_path":"kb/communities/Desulfovibrio_Methanococcus_Syntrophy.yaml","text_sha256":"14342f966090a4209f5a1888b014d6e7ebfa4137b8d3a6a5cbb6831aeb4f8c17","x":-4.432833194732666,"y":0.999701738357544},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000069","label":"Syntrophobacter-Methanospirillum Syntrophic Consortium","page":"communities/Syntrophobacter_Methanospirillum_Syntrophy.html","source_path":"kb/communities/Syntrophobacter_Methanospirillum_Syntrophy.yaml","text_sha256":"3982b8581cc37695aae29c7784982a707c46c4a8642b626bc389184de4784ce4","x":-4.675378322601318,"y":1.0547746419906616},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000113","label":"Phylogenetically Diverse Denitrifying SynCom","page":"communities/Phylogenetically_Diverse_Denitrifying_SynCom.html","source_path":"kb/communities/Phylogenetically_Diverse_Denitrifying_SynCom.yaml","text_sha256":"ed656ea8891af2c30842fa47a0f746e8b817ba07ab6ecca017e303cfe790ac17","x":-0.9365326762199402,"y":-2.4682905673980713},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000256","label":"Prairie Pothole Wetland Sulfur-Carbon Virus-Host Community","page":"communities/Prairie_Pothole_Wetland_Sulfur_Carbon_Virus_Community.html","source_path":"kb/communities/Prairie_Pothole_Wetland_Sulfur_Carbon_Virus_Community.yaml","text_sha256":"212d2fd3b77b46d2423ca4d96871d38c2ed86c9744d93ad5dba71221a3ed4f79","x":-3.519014835357666,"y":-3.356289863586426},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000192","label":"Methylomicrobium-Chlorella Methane Sequestration Coculture","page":"communities/Methylomicrobium_Chlorella_Methane_Sequestration_Coculture.html","source_path":"kb/communities/Methylomicrobium_Chlorella_Methane_Sequestration_Coculture.yaml","text_sha256":"52bd4fe4250ac612e093f954a4aed512d583736342655947e465879a5536cf59","x":-2.289224624633789,"y":4.148324966430664},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000129","label":"Soybean Chlorophyll-Selected Biofertilizer SynCom","page":"communities/Soybean_Chlorophyll_Selected_Biofertilizer_SynCom.html","source_path":"kb/communities/Soybean_Chlorophyll_Selected_Biofertilizer_SynCom.yaml","text_sha256":"74019b5e375c0258a9d4a67cf92212b894e2e814135f605162c172eb025ff570","x":3.953120231628418,"y":-2.456279993057251},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000363","label":"Synechocystis-Pseudomonas Acetate-Butanol Coculture","page":"communities/Synechocystis_Pseudomonas_Acetate_Butanol_Coculture.html","source_path":"kb/communities/Synechocystis_Pseudomonas_Acetate_Butanol_Coculture.yaml","text_sha256":"7f8faa5b760f351b178ace74e7e9304009c456e84740783ef8719f47a77f0636","x":-2.0132033824920654,"y":5.861827850341797},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000373","label":"Bacillus G12-Y4-X25 Tobacco Biocontrol SynCom","page":"communities/Bacillus_G12_Y4_X25_Tobacco_Biocontrol_SynCom.html","source_path":"kb/communities/Bacillus_G12_Y4_X25_Tobacco_Biocontrol_SynCom.yaml","text_sha256":"7f2605dc4920d45d0583baff25393a6396f7bcb2921e01f86df0358edceb4a20","x":5.063169479370117,"y":-1.2986890077590942},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000165","label":"Saccharomyces-Chlamydomonas Fungal-Algal Mutualism","page":"communities/Saccharomyces_Chlamydomonas_Fungal_Algal_Mutualism.html","source_path":"kb/communities/Saccharomyces_Chlamydomonas_Fungal_Algal_Mutualism.yaml","text_sha256":"c4802ed8f9dd78039252350e6660012a1df1568f2961291f43cbbcca56678410","x":-0.9581685066223145,"y":5.496689796447754},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000074","label":"Tinto River Iron Cycling Community","page":"communities/Tinto_River_Iron_Cycling_Community.html","source_path":"kb/communities/Tinto_River_Iron_Cycling_Community.yaml","text_sha256":"bc3d0c7d13019a4d887ca400d88a9a154409029c8ee7e8eb1dd42eed46450d8b","x":-3.9562671184539795,"y":-5.104090213775635},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000285","label":"SynCom + Chlorella sorokiniana Biogas-slurry Coupling System","page":"communities/SynCom_Chlorella_sorokiniana_Biogas_Slurry_Coupling_System.html","source_path":"kb/communities/SynCom_Chlorella_sorokiniana_Biogas_Slurry_Coupling_System.yaml","text_sha256":"0ad1889a012a36b63b607f7a228faf1b2f5d481678da1232c907c3101fb5f6b1","x":2.9855329990386963,"y":0.6227956414222717},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000275","label":"Butyrivibrio fibrisolvens + Selenomonas ruminantium + Ruminococcus albus Lignocellulolytic Rumen Consortium","page":"communities/Butyrivibrio_Selenomonas_Ruminococcus_Lignocellulolytic_Rumen_Consortium.html","source_path":"kb/communities/Butyrivibrio_Selenomonas_Ruminococcus_Lignocellulolytic_Rumen_Consortium.yaml","text_sha256":"d64aa4667e59388aa05f7bb3c15735fa730f55ea0375e1bd29714964cc1051f9","x":-0.2436143308877945,"y":1.5125125646591187},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000219","label":"Asgard Archaea Wetland Soil Methanogenesis-Substrate Community","page":"communities/Asgard_Wetland_Soil_Methanogenesis_Substrate_Community.html","source_path":"kb/communities/Asgard_Wetland_Soil_Methanogenesis_Substrate_Community.yaml","text_sha256":"460e4da34bea57baf5e8346c7032013b96d5e6bd4a7f61bddbd10e36fa60a498","x":-4.016145706176758,"y":-3.2364742755889893},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000194","label":"High-Solids Switchgrass Methanogenic Microbiome","page":"communities/High_Solids_Switchgrass_Methanogenic_Microbiome.html","source_path":"kb/communities/High_Solids_Switchgrass_Methanogenic_Microbiome.yaml","text_sha256":"86d77b5f02c6d17cddaf9add1efb533181c31f0806f792de3b040fee3469ef63","x":-1.252918004989624,"y":1.5176129341125488},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000011","label":"BioModels MODEL2310020001 Mouse Metaorganism Model","page":"communities/BioModels_MODEL2310020001_Mouse_Metaorganism_Model.html","source_path":"kb/communities/BioModels_MODEL2310020001_Mouse_Metaorganism_Model.yaml","text_sha256":"f0f13b3203c4cd98583bab8d17b253b668d68c379eb925e3313c7c4702776578","x":2.302501678466797,"y":4.447290897369385},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000087","label":"LBNL Switchgrass Soil SynCom16","page":"communities/LBNL_Switchgrass_Soil_SynCom16.html","source_path":"kb/communities/LBNL_Switchgrass_Soil_SynCom16.yaml","text_sha256":"024ad1306f01464815c5e8f7ca48e5d48cf2cd2712087162008d7db0c07125c7","x":3.3172028064727783,"y":-2.1421093940734863},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000086","label":"Model Soil Consortium-2 (MSC-2)","page":"communities/MSC2_Model_Soil_Consortium.html","source_path":"kb/communities/MSC2_Model_Soil_Consortium.yaml","text_sha256":"0e1d86dd9ed07a1c6e54d8d547219caefca9e73b3855639ffae8a5acd675c093","x":0.6076474785804749,"y":0.7197339534759521},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000089","label":"Cellulose-to-Methane Quad-Culture SynCom","page":"communities/Cellulose_Methane_Quad_Culture_SynCom.html","source_path":"kb/communities/Cellulose_Methane_Quad_Culture_SynCom.yaml","text_sha256":"8eca354ca53b2aad368c4bf6ada10a71cd8cf317f07cda7026b3f498d98a8263","x":-2.1934213638305664,"y":1.465627670288086},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000292","label":"Pseudomonas-Rahnella native rhizosphere SynCom for Artemisia argyi phytoremediation","page":"communities/SynCom_Pseudomonas_Rahnella_Artemisia_Phytoremediation.html","source_path":"kb/communities/SynCom_Pseudomonas_Rahnella_Artemisia_Phytoremediation.yaml","text_sha256":"794cb84cdec93a462077095bec78c1b0935efc4a85311a6acdda34803c1180c5","x":4.118293762207031,"y":-2.340355157852173},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000063","label":"Sorghum SRC1 Subset Community","page":"communities/Sorghum_SRC1_Subset.html","source_path":"kb/communities/Sorghum_SRC1_Subset.yaml","text_sha256":"11af740c3a212b7a25612e58dc5d1b95009fb224f33b78ff1997f98252996aea","x":2.9294216632843018,"y":-2.627791404724121},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000056","label":"Pseudo-nitzschia-Sulfitobacter Marine Association","page":"communities/Pseudonitzschia_Sulfitobacter_Association.html","source_path":"kb/communities/Pseudonitzschia_Sulfitobacter_Association.yaml","text_sha256":"407b212ecbcdb363108dc66276c38707df867805d9c6800494567f092a71f522","x":-0.5235821008682251,"y":5.660520076751709},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000040","label":"Lotus Lj-SC3 Synthetic Community","page":"communities/Lotus_LjSC3.html","source_path":"kb/communities/Lotus_LjSC3.yaml","text_sha256":"a1fb120a5e4fa06cbcba5d4d395a1a86ba632b172ac8a9889bff20ab60169f5b","x":3.2597713470458984,"y":-2.483100414276123},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000132","label":"KB-1 Chlorinated Ethene Dechlorinating Consortium","page":"communities/KB1_Chlorinated_Ethene_Dechlorinating_Consortium.html","source_path":"kb/communities/KB1_Chlorinated_Ethene_Dechlorinating_Consortium.yaml","text_sha256":"c2bc069a2d45587c0aa69ef088a7648e9b592ae52107cd75a077a6067b5f8211","x":-1.1367708444595337,"y":-0.7541654109954834},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000127","label":"SynComBac10 Chicken Intestinal SynCom","page":"communities/SynComBac10_Chicken_Intestinal_SynCom.html","source_path":"kb/communities/SynComBac10_Chicken_Intestinal_SynCom.yaml","text_sha256":"a2a895fdb11c3a5b7178259f7deecdb8891e807cd9326376753c1625afac42ef","x":3.717249870300293,"y":2.017282485961914},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000065","label":"Synechococcus-Bacillus Synthetic Photosynthetic Consortium","page":"communities/Synechococcus_Bacillus_SPC.html","source_path":"kb/communities/Synechococcus_Bacillus_SPC.yaml","text_sha256":"9eeebd6bf622808f997fb18d7ffebb85351df1cec8d53741b219144aa1591b77","x":-2.081233501434326,"y":6.010765075683594},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000036","label":"Ion-Adsorption REE Indigenous Community","page":"communities/Ion_Adsorption_REE_Indigenous_Community.html","source_path":"kb/communities/Ion_Adsorption_REE_Indigenous_Community.yaml","text_sha256":"12c08a4165875dc591413f54de34e51b1ba6d3e61ee022543ea5d5f54244d555","x":-3.1287131309509277,"y":-5.198551177978516},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000013","label":"BioModels MODEL2407300002 Sponge Holobiont Network","page":"communities/BioModels_MODEL2407300002_Sponge_Holobiont_Network.html","source_path":"kb/communities/BioModels_MODEL2407300002_Sponge_Holobiont_Network.yaml","text_sha256":"06de3e196a7de7e1e71bb11efdd87808d8e8860c4d1a455be6889d70e4c4d7f9","x":1.3135020732879639,"y":4.971480369567871},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000225","label":"Brachypodium Young Root Rhizosphere EcoFAB Community","page":"communities/Brachypodium_Young_Root_Rhizosphere_EcoFAB_Community.html","source_path":"kb/communities/Brachypodium_Young_Root_Rhizosphere_EcoFAB_Community.yaml","text_sha256":"f50dabbed261248232b9cee46ee61a8c8847ad382c5a85a7d92a54a03a4ce77c","x":2.6237621307373047,"y":-2.9677460193634033},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000329","label":"Sedimenting Arabinose-Glucose Saccharomyces Coculture","page":"communities/Sedimenting_Arabinose_Glucose_Saccharomyces_Coculture.html","source_path":"kb/communities/Sedimenting_Arabinose_Glucose_Saccharomyces_Coculture.yaml","text_sha256":"fc720953074e586c397d1c0e84cbdfcf46afb77e2dc382e197e861bf4d148064","x":0.5633422136306763,"y":2.6774075031280518},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000156","label":"Neocallimastix-Methanobrevibacter Xylanolytic Coculture","page":"communities/Neocallimastix_Methanobrevibacter_Xylan_Coculture.html","source_path":"kb/communities/Neocallimastix_Methanobrevibacter_Xylan_Coculture.yaml","text_sha256":"bf2e0a6f1d0f084405c76c72ce75c5e3285ab94ea57bce37f4da45cbb3429ee9","x":-2.3057103157043457,"y":1.4475923776626587},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000025","label":"EcoFAB 2.0 Root Microbiome Ring Trial SynCom17","page":"communities/EcoFAB_Ring_Trial_SynCom17.html","source_path":"kb/communities/EcoFAB_Ring_Trial_SynCom17.yaml","text_sha256":"d47741572ba43886d975fb55f8f4fd223b9bc54145e5e00400cdd7f1819a6f6a","x":3.3370273113250732,"y":-1.8894466161727905},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000272","label":"SynCom Y Agrobacterium-Bacillus Biofilm Biocontrol Co-culture","page":"communities/SynCom_Y_Agrobacterium_Bacillus_Biofilm_Biocontrol_Coculture.html","source_path":"kb/communities/SynCom_Y_Agrobacterium_Bacillus_Biofilm_Biocontrol_Coculture.yaml","text_sha256":"2cd8eea82eefe29e3c509606fb841cc028b208a3846fb4a7a8fbc4e3bd6592f4","x":4.778739929199219,"y":-1.425041913986206},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000336","label":"Clostridium acetobutylicum-Clostridium ljungdahlii Syntrophic Fusion Coculture","page":"communities/Clostridium_Acetobutylicum_Ljungdahlii_Fusion_Coculture.html","source_path":"kb/communities/Clostridium_Acetobutylicum_Ljungdahlii_Fusion_Coculture.yaml","text_sha256":"90159749552afa4cb40093b7734971f9ffed3f9b7e243d8cf1e9c21d058d7d1f","x":-2.583004951477051,"y":2.2144694328308105},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000079","label":"THOR Rhizosphere Model Community","page":"communities/THOR_Rhizosphere_Model_Community.html","source_path":"kb/communities/THOR_Rhizosphere_Model_Community.yaml","text_sha256":"23a46bbb433f8291fbded50410603f30b74777140bd8af2b4cf423ef214b1a0e","x":2.0567541122436523,"y":-3.100395441055298},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000122","label":"LBNL Human Gut Interaction SynCom","page":"communities/LBNL_Human_Gut_Interaction_SynCom.html","source_path":"kb/communities/LBNL_Human_Gut_Interaction_SynCom.yaml","text_sha256":"e21a8bc0178af9fa8a3e5c75b87755779a0092d512bc7421cdd07f848fb32728","x":3.377258062362671,"y":2.724881410598755},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000280","label":"Pinus armandii Endophytic Biocontrol SynCom","page":"communities/Pinus_armandii_Endophytic_Biocontrol_SynCom.html","source_path":"kb/communities/Pinus_armandii_Endophytic_Biocontrol_SynCom.yaml","text_sha256":"6185a476d5fcdc756510a8ac24b18f7650ee0576821d91671f0661ff688afbbd","x":4.680151462554932,"y":-1.3155442476272583},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000016","label":"Chlorella-Rhizobium Bioflocculation","page":"communities/Chlorella_Rhizobium_Bioflocculation.html","source_path":"kb/communities/Chlorella_Rhizobium_Bioflocculation.yaml","text_sha256":"253aad135083472771a167d6248ee79d3d2e90059133c7c6343da582377cf2c1","x":-1.6466079950332642,"y":4.781821250915527},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000163","label":"PET Artificial Four-Species Degradation Consortium","page":"communities/PET_Artificial_FourSpecies_Degradation_Consortium.html","source_path":"kb/communities/PET_Artificial_FourSpecies_Degradation_Consortium.yaml","text_sha256":"6c551fea29367c27dd01dd211d3b5663479d64499fff7c36497ee243cb47678d","x":0.06349872052669525,"y":-0.20265255868434906},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000076","label":"Wheat Synthetic Consortium C1","page":"communities/Wheat_Consortium_C1.html","source_path":"kb/communities/Wheat_Consortium_C1.yaml","text_sha256":"7991b61c668231e3d90c643124da0ac18448f3f5a17387c0ff08bbc3b6f26252","x":4.851639270782471,"y":-1.769600749015808},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000080","label":"SIHUMIx Human Intestinal Model Community","page":"communities/SIHUMIx_Human_Intestinal_Model_Community.html","source_path":"kb/communities/SIHUMIx_Human_Intestinal_Model_Community.yaml","text_sha256":"e4c68e2b38e0b82319bb20a583481906caf7a850e56aeb62219923843b2d9cb3","x":3.2817108631134033,"y":3.2037060260772705},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000264","label":"Clostridium cellulovorans-Rhodopseudomonas palustris Cellulose Biohydrogen Coculture","page":"communities/Clostridium_Cellulovorans_Rhodopseudomonas_Cellulose_Biohydrogen_Coculture.html","source_path":"kb/communities/Clostridium_Cellulovorans_Rhodopseudomonas_Cellulose_Biohydrogen_Coculture.yaml","text_sha256":"474df1293a509576548f1941327b53218abff129113ea82875f7dcfb7e9fc31c","x":-1.6953978538513184,"y":1.907236099243164},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000342","label":"Nitratireductor-Gordonia Z123 LDPE-Degradation SynCom","page":"communities/Nitratireductor_Gordonia_Z123_LDPE_Degradation_SynCom.html","source_path":"kb/communities/Nitratireductor_Gordonia_Z123_LDPE_Degradation_SynCom.yaml","text_sha256":"74060bdac362587df00698ef05fd1b8feadb1f74c05f652b91be79ab98ec6319","x":0.010486718267202377,"y":-0.779150664806366},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000276","label":"ANME/SRB Anaerobic Methanotrophic Syntrophic Consortia","page":"communities/ANME_SRB_Anaerobic_Methanotrophic_Syntrophic_Consortia.html","source_path":"kb/communities/ANME_SRB_Anaerobic_Methanotrophic_Syntrophic_Consortia.yaml","text_sha256":"3c2fe841f9dd315e2e017e442b210cfc7dc4a316614812b7bd66c77ef956e36b","x":-4.231417179107666,"y":-0.7358452081680298},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000001","label":"AMD Acidophile Heterotroph Network","page":"communities/AMD_Acidophile_Heterotroph_Network.html","source_path":"kb/communities/AMD_Acidophile_Heterotroph_Network.yaml","text_sha256":"8d724772cf4734be75348c0705ebbe398de13e47b3a9e3ff77444146e111f971","x":-3.764120578765869,"y":-4.97160530090332},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000298","label":"Shewanella-Acetogen Electrosynthetic Consortia for CO2-to-Acetate","page":"communities/Electrosynthetic_Consortia_Shewanella_Clostridium_Acetobacterium_Acetate.html","source_path":"kb/communities/Electrosynthetic_Consortia_Shewanella_Clostridium_Acetobacterium_Acetate.yaml","text_sha256":"e5ffa56178aac84da344167a2885bbc43dcfa8c3c1248cf1d7aa559d92ebfe9e","x":-3.1497318744659424,"y":-0.2224043607711792},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000082","label":"Defined Multispecies Enamel Caries Model","page":"communities/Defined_Multispecies_Enamel_Caries_Model.html","source_path":"kb/communities/Defined_Multispecies_Enamel_Caries_Model.yaml","text_sha256":"c100c344a712576fe06c67f0942957d7599c2f4b92bc945c9fb143049ec27c6e","x":2.4420154094696045,"y":5.3841118812561035},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000193","label":"Clostridium-Caldicellulosiruptor Minimal Medium Coculture","page":"communities/Clostridium_Caldicellulosiruptor_Minimal_Medium_Coculture.html","source_path":"kb/communities/Clostridium_Caldicellulosiruptor_Minimal_Medium_Coculture.yaml","text_sha256":"fca6964ac498312925b9a0e063ef9f7179e02b35a4bfb553413b421056355375","x":-1.6571670770645142,"y":1.9343771934509277},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000354","label":"Yarrowia lipolytica Division-of-Labor Lipid Consortium","page":"communities/Yarrowia_lipolytica_Division_of_Labor_Lipid_Consortium.html","source_path":"kb/communities/Yarrowia_lipolytica_Division_of_Labor_Lipid_Consortium.yaml","text_sha256":"4b826bfd12e500eeabff37751334c580ecc9e0bfdce1d9c60b2d367cdc202870","x":0.13262242078781128,"y":2.0253546237945557},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000044","label":"Mercury SFA East Fork Poplar Creek Sediment Community","page":"communities/Mercury_SFA_EFPC_Sediment_Community.html","source_path":"kb/communities/Mercury_SFA_EFPC_Sediment_Community.yaml","text_sha256":"ebfe013246c5fd37d20ba745089367d5be504a63333c68152727aa6a5cf73a4b","x":-2.8029911518096924,"y":-3.368298053741455},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000326","label":"Staphylococcus-Candida Context-Dependent Biofilm Coculture","page":"communities/Staphylococcus_Candida_Context_Dependent_Biofilm_Coculture.html","source_path":"kb/communities/Staphylococcus_Candida_Context_Dependent_Biofilm_Coculture.yaml","text_sha256":"6d043c03ce62652189a77028fc877ce4280ee0c39c3a2efd74ab25e654493d7b","x":2.3154971599578857,"y":5.019847869873047},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000347","label":"Bacillus siamensis-vallismortis HT Masson Pine SynCom","page":"communities/Bacillus_siamensis_vallismortis_HT_Masson_Pine_SynCom.html","source_path":"kb/communities/Bacillus_siamensis_vallismortis_HT_Masson_Pine_SynCom.yaml","text_sha256":"75fb2e6b8cd4f7dc23621367ce71e3d46bd5435865a0753051d85a89c7fdb51e","x":5.103806495666504,"y":-1.5002412796020508},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000311","label":"Legume-Rhizobia Mars Simulant Symbiosis","page":"communities/Legume_Rhizobia_Mars_Simulant_Symbiosis.html","source_path":"kb/communities/Legume_Rhizobia_Mars_Simulant_Symbiosis.yaml","text_sha256":"98cba31c12655a76da4e6d034e05f8982bdb92392ec53f6059da8f97b2af5556","x":-3.2932209968566895,"y":-7.453795909881592},{"adapter_version":"communitymech-semantic-v1","category":"METAL_REDUCTION","identifier":"CommunityMech:000017","label":"Chromium Sulfur Oxidation Enrichment","page":"communities/Chromium_Sulfur_Reduction_Enrichment.html","source_path":"kb/communities/Chromium_Sulfur_Reduction_Enrichment.yaml","text_sha256":"8a67dfcb12d99412fe115965ac5ee8f26d3b4cd72a9092926afd5d0fe293d788","x":-3.0278122425079346,"y":-1.3671060800552368},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000334","label":"Bosea-Pseudomonas Dimethachlon-Degradation Consortium","page":"communities/Bosea_Pseudomonas_Dimethachlon_Degradation_Consortium.html","source_path":"kb/communities/Bosea_Pseudomonas_Dimethachlon_Degradation_Consortium.yaml","text_sha256":"bdc72ae6e2cceca95fae46e7effddd8d936e40b144495dd58da6343b0141426e","x":-0.06300873309373856,"y":-0.6687812209129333},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000234","label":"Angelarchaeales Thermoplasmata CuMMO Soil and Sediment Community","page":"communities/Angelarchaeales_Thermoplasmata_CuMMO_Soil_Sediment_Community.html","source_path":"kb/communities/Angelarchaeales_Thermoplasmata_CuMMO_Soil_Sediment_Community.yaml","text_sha256":"40a492ab5d3c443e3d9b33001dece2bad37e95618c4b533902cd7cdbdf055c1d","x":-2.755842924118042,"y":-3.9422478675842285},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000058","label":"Rice-Duckweed Bacillus Biocontrol SynCom","page":"communities/Rice_Duckweed_Bacillus_SynCom.html","source_path":"kb/communities/Rice_Duckweed_Bacillus_SynCom.yaml","text_sha256":"a718845c7d76c6852c621349b577afedd3e8fda051a6d232c7e295c53c7ab757","x":4.808252334594727,"y":-1.5733025074005127},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000188","label":"Trichococcus-Syntrophomonas-Methanospirillum Butyrate Coculture","page":"communities/Trichococcus_Syntrophomonas_Methanospirillum_Butyrate_Coculture.html","source_path":"kb/communities/Trichococcus_Syntrophomonas_Methanospirillum_Butyrate_Coculture.yaml","text_sha256":"24123821b06a1740fb9a969989e259fec962bbf8c3693728f793106e9851c00d","x":-4.424880027770996,"y":1.1763719320297241},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000167","label":"Synechococcus-Pseudomonas Phototrophic PHA and DNT Coculture","page":"communities/Synechococcus_Pseudomonas_PhotoPHA_DNT_Coculture.html","source_path":"kb/communities/Synechococcus_Pseudomonas_PhotoPHA_DNT_Coculture.yaml","text_sha256":"b36548b3d9ed14c1def1e830a6bf499dbd0c1ac56ab5dbc84185d3e695c3b3e4","x":-2.009533405303955,"y":5.789278507232666},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000135","label":"SPRUCE Peatland Methane-Cycling Microbial Community","page":"communities/SPRUCE_Peatland_Methane_Cycling_Community.html","source_path":"kb/communities/SPRUCE_Peatland_Methane_Cycling_Community.yaml","text_sha256":"5e054fa7f4ceac07e9967ad4c0b18739e6e020e300015a6d79390969a06e4d66","x":-4.15395975112915,"y":-2.838934898376465},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000247","label":"Soil CPR Bacteria and Nanoarchaea Rare-Biosphere Community","page":"communities/Soil_CPR_Nanoarchaea_Rare_Biosphere_Community.html","source_path":"kb/communities/Soil_CPR_Nanoarchaea_Rare_Biosphere_Community.yaml","text_sha256":"2595faa2e836976a0002499083ef87a44f145cf257af88fd201e6bf08be63bc3","x":-0.3763359487056732,"y":-3.4482569694519043},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000330","label":"Poultry-Wastewater Three-Strain Electroactive Consortium","page":"communities/Poultry_Wastewater_ThreeStrain_Electroactive_Consortium.html","source_path":"kb/communities/Poultry_Wastewater_ThreeStrain_Electroactive_Consortium.yaml","text_sha256":"e9019a0fb76653fa70917faf8b2022fcf5730db05bee8e612b2c3c657b02d782","x":-2.014423370361328,"y":-1.2810828685760498},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000243","label":"Ngawha Geothermal Acidic Springs Mercury Cycling Community","page":"communities/Ngawha_Geothermal_Mercury_Cycling_Community.html","source_path":"kb/communities/Ngawha_Geothermal_Mercury_Cycling_Community.yaml","text_sha256":"59b2273432388e385da2038a503682421ec2623932fd0af389f2d96de8bb1a39","x":-3.11093807220459,"y":-3.857106924057007},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000221","label":"Soil Corrinoid Reservoir Microbial Community","page":"communities/Soil_Corrinoid_B12_Reservoir_Community.html","source_path":"kb/communities/Soil_Corrinoid_B12_Reservoir_Community.yaml","text_sha256":"822a5f414e0e54317fbdac1b60abfa062284acd4e07c45985fb47405c2007255","x":1.1671042442321777,"y":-3.195244073867798},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000317","label":"Human Gut Four-Member Proteome-Complementarity Consortium","page":"communities/Human_Gut_FourMember_Proteome_Complementarity_Consortium.html","source_path":"kb/communities/Human_Gut_FourMember_Proteome_Complementarity_Consortium.yaml","text_sha256":"63824860373dc6865bd41a01d660995a5c18b09053a32a8a7e884aa81049adde","x":2.708721399307251,"y":2.9416818618774414},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000090","label":"Populus Salt-Tolerant Rhizosphere SynComs","page":"communities/Populus_Salt_Tolerant_SynComs.html","source_path":"kb/communities/Populus_Salt_Tolerant_SynComs.yaml","text_sha256":"a3ddc314a98503374795177b7a8185a19dd8556a3f5ba8bd7b596e27ae35e222","x":4.59560489654541,"y":-2.7172205448150635},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000277","label":"Five-member bacterial-fungal composting SynCom for lignocellulose degradation","page":"communities/Composting_SynCom_Lignocellulose_Degradation_Humus.html","source_path":"kb/communities/Composting_SynCom_Lignocellulose_Degradation_Humus.yaml","text_sha256":"44fe296ee25bffb631b3e90dcaf46a75c5ef858efef3a68753c67a8d23cb483a","x":2.9333393573760986,"y":0.22478938102722168},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000051","label":"Panzhihua Vanadium Titanium Tailings Community","page":"communities/Panzhihua_Vanadium_Titanium_Tailings.html","source_path":"kb/communities/Panzhihua_Vanadium_Titanium_Tailings.yaml","text_sha256":"5d2e9100e5ced6e35c3f71baa053b8c2ac80ca5c73eea1d6227c54b8d5eb320d","x":-3.733257293701172,"y":-5.458905220031738},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000064","label":"Soybean N-Fixation Simplified SynCom","page":"communities/Soybean_N_Fixation_sfSynCom.html","source_path":"kb/communities/Soybean_N_Fixation_sfSynCom.yaml","text_sha256":"1decfa2280f7b884ca5e05fc65cfd747139cedcb8d13241a4949a3da1876f268","x":3.439673662185669,"y":-2.3692336082458496},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000147","label":"Trichodesmium-Alteromonas Marine Consortium","page":"communities/Trichodesmium_Alteromonas_Marine_Consortium.html","source_path":"kb/communities/Trichodesmium_Alteromonas_Marine_Consortium.yaml","text_sha256":"59d8c071bba6f8a66081f2901465ea856d315828ff1c7a5526065896dade00a9","x":-0.9480049014091492,"y":5.561702251434326},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000022","label":"Jeff Dangl's SynComm 35","page":"communities/Dangl_SynComm_35.html","source_path":"kb/communities/Dangl_SynComm_35.yaml","text_sha256":"1ec01d5c7eef275688087be66c596ecbec51dbc243916694f2b75e1c773aa192","x":3.963113307952881,"y":-2.1482415199279785},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000370","label":"Bacillus-Pseudomonas Galveston PET Consortium","page":"communities/Bacillus_Pseudomonas_Galveston_PET_Consortium.html","source_path":"kb/communities/Bacillus_Pseudomonas_Galveston_PET_Consortium.yaml","text_sha256":"7926cec43643cca09c2cb1c453b9a9503a80318c8abd564ba68d38fd0afbde5e","x":0.03732338547706604,"y":-0.6374204754829407},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000258","label":"Coastal Forested Wetland Seawater-Ion Microcosm Community","page":"communities/Coastal_Forested_Wetland_Seawater_Ion_Microcosm_Community.html","source_path":"kb/communities/Coastal_Forested_Wetland_Seawater_Ion_Microcosm_Community.yaml","text_sha256":"4f068d6aaeec4678e43036c9f07a79f87ff548748cca13e6ac66c3586282719c","x":-3.5943238735198975,"y":-3.273081064224243},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000091","label":"GLBRC Exometabolite Transwell SynCom System","page":"communities/GLBRC_Exometabolite_Transwell_SynCom.html","source_path":"kb/communities/GLBRC_Exometabolite_Transwell_SynCom.yaml","text_sha256":"169667da6b9761206ef7c3ba0cd6a85e25f46e990db9e646de54fc77a3ef9592","x":2.9088616371154785,"y":-0.6522002816200256},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000180","label":"Clostridium-Thermoanaerobacterium JN4-GD17 Cellulosic Biofuel Coculture","page":"communities/Clostridium_Thermoanaerobacterium_JN4_GD17_Cellulosic_Biofuel_Coculture.html","source_path":"kb/communities/Clostridium_Thermoanaerobacterium_JN4_GD17_Cellulosic_Biofuel_Coculture.yaml","text_sha256":"6a82a29bf4920fd123461962ef0fa9b234fd85403c6775645c4fcf9d29179dde","x":-1.3482341766357422,"y":2.101593255996704},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000164","label":"Yogurt Two-Species Starter Culture","page":"communities/Yogurt_TwoSpecies_Starter_Culture.html","source_path":"kb/communities/Yogurt_TwoSpecies_Starter_Culture.yaml","text_sha256":"37d78d5c111c21391e9650cb23c0a2465da57055f2c9f3293551e56e084fe3c3","x":1.9751824140548706,"y":4.006580352783203},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000092","label":"Rhodopseudomonas-E. coli Cross-Feeding Coculture","page":"communities/Rhodopseudomonas_Ecoli_CrossFeeding_Coculture.html","source_path":"kb/communities/Rhodopseudomonas_Ecoli_CrossFeeding_Coculture.yaml","text_sha256":"8f49f42aff21bdf7dfbce9fd665c3ae71f76e1eaed53e2770c3adb5e51db3288","x":-1.5187326669692993,"y":0.34601739048957825},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000070","label":"Syntrophomonas-Methanospirillum Syntrophic Consortium","page":"communities/Syntrophomonas_Methanospirillum_Syntrophy.html","source_path":"kb/communities/Syntrophomonas_Methanospirillum_Syntrophy.yaml","text_sha256":"db5cf1e36ef4e4fcf091d93802cd0edf819d5568a9d2e95f07ce26cbe948fa57","x":-4.759310245513916,"y":1.1111434698104858},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000066","label":"Synechococcus-E.coli Synthetic Photosynthetic Consortium","page":"communities/Synechococcus_Ecoli_SPC.html","source_path":"kb/communities/Synechococcus_Ecoli_SPC.yaml","text_sha256":"2e58527fd455c33b5bd2f5d8f6cd25880cdd6ad5f2c59559a32859bd26d4dc22","x":-2.0475051403045654,"y":5.98954963684082},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000309","label":"Mars Regolith Cyanobacteria/Microalga Biofertilizer Panel","page":"communities/Mars_Regolith_Cyanobacteria_Biofertilizer_Panel.html","source_path":"kb/communities/Mars_Regolith_Cyanobacteria_Biofertilizer_Panel.yaml","text_sha256":"5ff524dfea1c0679b3085297e41db6b97fbd86523ddb9e198df14f8d1582ac98","x":-3.4322621822357178,"y":-7.343360424041748},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000235","label":"Drought-Induced Rhizosphere Iron-Enriched Actinobacteria Community","page":"communities/Drought_Rhizosphere_Iron_Actinobacteria_Community.html","source_path":"kb/communities/Drought_Rhizosphere_Iron_Actinobacteria_Community.yaml","text_sha256":"c95088aeab1237901bdab93b1210c8266b7cd2e768bdefa4f864369e1404b050","x":2.3632824420928955,"y":-3.1070556640625},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000308","label":"Mars Meteorite EETA79001 Microbial Growth Panel","page":"communities/Mars_Meteorite_EETA79001_Growth_Panel.html","source_path":"kb/communities/Mars_Meteorite_EETA79001_Growth_Panel.yaml","text_sha256":"e5ea77f5c5e0f07306b4d263c001a30b20f83307d9a087ab009af73a395a511f","x":-3.4841907024383545,"y":-6.99834680557251},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000075","label":"Trichoderma Lactate Platform for SCFA Production","page":"communities/Trichoderma_Lactate_Platform.html","source_path":"kb/communities/Trichoderma_Lactate_Platform.yaml","text_sha256":"5378ff2c06481fdc83bda87599dcadc7c24712d65a7690abaab82c647a8f5c08","x":-0.575118899345398,"y":1.86744225025177},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000331","label":"Pseudomonas-Paracoccus Bifenthrin-Degrading Consortium","page":"communities/Pseudomonas_Paracoccus_Bifenthrin_Degradation_Consortium.html","source_path":"kb/communities/Pseudomonas_Paracoccus_Bifenthrin_Degradation_Consortium.yaml","text_sha256":"27cd1e9dba521e37fc1f8d54d7ab43da894b1d08341f58ca08d5dbffa24880cc","x":0.13352975249290466,"y":-0.496842622756958},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000293","label":"Crucian Carp Gut Disease-resistance SynCom","page":"communities/Crucian_Carp_Gut_Disease_Resistance_SynCom.html","source_path":"kb/communities/Crucian_Carp_Gut_Disease_Resistance_SynCom.yaml","text_sha256":"f30ecd00df9fa44175c14ae7102bed87f36ee2c06b40b695713931bf4c08d40b","x":3.733933210372925,"y":1.7854450941085815},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000107","label":"Tomato Oxylipin-Protective SynCom3","page":"communities/Tomato_Oxylipin_SynCom3.html","source_path":"kb/communities/Tomato_Oxylipin_SynCom3.yaml","text_sha256":"6febc92ed0db35692ca6ee5b1a9991b269b0af65aa1eeba0b06cd0d7684a7a34","x":5.11041259765625,"y":-1.8060718774795532},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000154","label":"Kombucha KMC-IMBG1 Fermentation Community","page":"communities/Kombucha_KMC_IMBG1_Fermentation_Community.html","source_path":"kb/communities/Kombucha_KMC_IMBG1_Fermentation_Community.yaml","text_sha256":"8a8b6a4278dbad32daf771f42381ddfb39c40c0d06cf32ae8c8c6db7b8e533ae","x":1.613957166671753,"y":2.66776442527771},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000097","label":"Banana Fusarium Wilt Biocontrol SynCom1.2","page":"communities/Banana_Fusarium_Biocontrol_SynCom12.html","source_path":"kb/communities/Banana_Fusarium_Biocontrol_SynCom12.yaml","text_sha256":"4d92b37946feebfe2f08d4f525b0004f764138ddff7b669c6361a89d6ecade92","x":4.996493339538574,"y":-1.5876225233078003},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000187","label":"Syntrophus-Methanospirillum Gentianae Benzoate Coculture","page":"communities/Syntrophus_Methanospirillum_Gentianae_Benzoate_Coculture.html","source_path":"kb/communities/Syntrophus_Methanospirillum_Gentianae_Benzoate_Coculture.yaml","text_sha256":"c96aa3154f02b951474f533a8058c41b3cdf07d0f3aacef2059772751f53136e","x":-4.449263095855713,"y":1.135298728942871},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000045","label":"Mixed Gallium LED Recovery Consortium","page":"communities/Mixed_Gallium_LED_Recovery_Consortium.html","source_path":"kb/communities/Mixed_Gallium_LED_Recovery_Consortium.yaml","text_sha256":"d83d05e94f8c4c2d24d49c28695e83b8512649817532bda2a75ee333468a630e","x":-3.9381823539733887,"y":-5.859334945678711},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000257","label":"MUCC Freshwater Wetland Methane-Cycling Network Community","page":"communities/MUCC_Freshwater_Wetland_Methane_Network_Community.html","source_path":"kb/communities/MUCC_Freshwater_Wetland_Methane_Network_Community.yaml","text_sha256":"ba05242fb054e97778742b6d0d284ea48fab9fbd3e80713fda10f4d9ddf6372e","x":-4.006744384765625,"y":-2.9861743450164795},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000123","label":"hCom2 Complex Gut Microbiome","page":"communities/hCom2_Complex_Gut_Microbiome.html","source_path":"kb/communities/hCom2_Complex_Gut_Microbiome.yaml","text_sha256":"135498f461889798bef9830dc41ec83086736908634d3a4e6a4937fb0bf2a0f5","x":3.490417242050171,"y":3.193545341491699},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000179","label":"Caldibacillus-Clostridium Aerotolerant Cellulose Coculture","page":"communities/Caldibacillus_Clostridium_Aerotolerant_Cellulose_Coculture.html","source_path":"kb/communities/Caldibacillus_Clostridium_Aerotolerant_Cellulose_Coculture.yaml","text_sha256":"eb842668353c5cf2349dc3550e3d8327ba8995401bdb97e826da2b1d1214a4e1","x":-1.4571236371994019,"y":2.209721088409424},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000328","label":"Waste-Sludge Electro-Fermentation Biofilm-Suspension Community","page":"communities/Waste_Sludge_Electrofermentation_Biofilm_Suspension_Community.html","source_path":"kb/communities/Waste_Sludge_Electrofermentation_Biofilm_Suspension_Community.yaml","text_sha256":"3fbc12646370f067aece2fdff1f983e4103e5b7bab78646479da5bf0aedeedbd","x":-3.0373828411102295,"y":-1.1412514448165894},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000291","label":"Pseudomonas stutzeri + Rhodococcus Naphthalene-degrading Biochar-bridged Engineered Consortium","page":"communities/Pseudomonas_stutzeri_Rhodococcus_Naphthalene_Biochar_Engineered_Consortium.html","source_path":"kb/communities/Pseudomonas_stutzeri_Rhodococcus_Naphthalene_Biochar_Engineered_Consortium.yaml","text_sha256":"0330755b933f484ecf129b0e88e4d30424087a0f157ad26cdd99cc33b6353e47","x":-0.8598461747169495,"y":-0.7264251708984375},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000157","label":"Microcoleus-Massilia Cyanosphere Urea Mutualism","page":"communities/Microcoleus_Massilia_Cyanosphere_Urea_Mutualism.html","source_path":"kb/communities/Microcoleus_Massilia_Cyanosphere_Urea_Mutualism.yaml","text_sha256":"6888347796e0498b1333ea128c0fa8976e853f9e46a48ecbd5eaa8390762a7fe","x":0.17761418223381042,"y":5.3429436683654785},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000027","label":"Ferroplasma-Leptospirillum Iron-Cycling Syntrophy","page":"communities/Ferroplasma_Leptospirillum_Syntrophy.html","source_path":"kb/communities/Ferroplasma_Leptospirillum_Syntrophy.yaml","text_sha256":"b01844267ac9fc5dd2f04b7457884dd830ada5d88acab2b29b5b8243ed38b685","x":-4.101283073425293,"y":-5.182791709899902},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000369","label":"Cyantraniliprole Fahmy Consortium T4","page":"communities/Cyantraniliprole_Fahmy_Consortium_T4.html","source_path":"kb/communities/Cyantraniliprole_Fahmy_Consortium_T4.yaml","text_sha256":"7a621fdbe73729c7ee4c22fefd5d010891f63296f14394c10e3438c1f2bf2b09","x":0.12701721489429474,"y":-0.6068823933601379},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000120","label":"Bacillus-Bradyrhizobium Straw Humification SynCom","page":"communities/Bacillus_Bradyrhizobium_Straw_Humification_SynCom.html","source_path":"kb/communities/Bacillus_Bradyrhizobium_Straw_Humification_SynCom.yaml","text_sha256":"8c0539977e8aec43a05201bf35bdb94d801dab31d6a74e9450297c868fb9dedb","x":3.3035778999328613,"y":-0.1272662729024887},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000046","label":"Naica Deep Subsurface Thermophilic Community","page":"communities/Naica_Deep_Subsurface_Thermophilic.html","source_path":"kb/communities/Naica_Deep_Subsurface_Thermophilic.yaml","text_sha256":"0cba1cd21681cb836977189e1eef46fd64a18c07d8e5384cdcbf4de5793304db","x":-3.419222354888916,"y":-3.680198907852173},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000138","label":"Hanford 300 Area Unconfined Aquifer Community","page":"communities/Hanford_300_Area_Unconfined_Aquifer_Community.html","source_path":"kb/communities/Hanford_300_Area_Unconfined_Aquifer_Community.yaml","text_sha256":"6c871e53dfb21a247f5460425f6574f40d5588c7b1d5bd30a088e7828d3a6044","x":-2.681903600692749,"y":-3.4565136432647705},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000143","label":"Emiliania huxleyi-Phaeobacter inhibens Dynamic Interaction","page":"communities/Emiliania_Phaeobacter_Dynamic_Interaction.html","source_path":"kb/communities/Emiliania_Phaeobacter_Dynamic_Interaction.yaml","text_sha256":"861d784a980f9a5aa4fe2dcb6a894033852d4e9acb31df83b7ae340fbc05ea7a","x":-0.708371102809906,"y":5.639191150665283},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000139","label":"Aalborg East Full-Scale EBPR Activated Sludge Community","page":"communities/Aalborg_East_Full_Scale_EBPR_Community.html","source_path":"kb/communities/Aalborg_East_Full_Scale_EBPR_Community.yaml","text_sha256":"faf6e7479a3a62a069143b90f6b744aec58f435b0562689a1a2c8c3c5385e222","x":-1.5926748514175415,"y":-2.559718370437622},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000020","label":"Coscinodiscus Synthetic Community","page":"communities/Coscinodiscus_Synthetic_Community.html","source_path":"kb/communities/Coscinodiscus_Synthetic_Community.yaml","text_sha256":"7e66060daa83ca777450bac85dd0b8f4356212d06451a79879733bbb3e570572","x":-0.8158887028694153,"y":5.916906356811523},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000007","label":"BioModels MODEL1806250004 Sharpshooter Sulcia-Baumannia Symbiosis","page":"communities/BioModels_MODEL1806250004_Sharpshooter_Sulcia_Baumannia.html","source_path":"kb/communities/BioModels_MODEL1806250004_Sharpshooter_Sulcia_Baumannia.yaml","text_sha256":"2ee34defe6d1a553d4e1f1972f9da021fcc0eb974ead606445917c8b731db128","x":1.4935436248779297,"y":5.008599281311035},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000327","label":"Methane-Fed MFC Electrogenesis and Nitrogen-Fixation Consortium","page":"communities/Methane_MFC_Electrogenesis_Nitrogen_Fixation_Consortium.html","source_path":"kb/communities/Methane_MFC_Electrogenesis_Nitrogen_Fixation_Consortium.yaml","text_sha256":"1bf7224f82696657391fa8bc8174e3928c9438e3e6b17cb37a794361b570a0c9","x":-3.5734050273895264,"y":-0.36164531111717224},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000371","label":"Rhodococcus-Pseudomonas Plastic Pyrolysis Oil Waste Consortium","page":"communities/Rhodococcus_Pseudomonas_PPOW_Consortium.html","source_path":"kb/communities/Rhodococcus_Pseudomonas_PPOW_Consortium.yaml","text_sha256":"572011eaf0473097bf4c1b7715e42e9217ed29d6228b7d356cd3784dbe2b7db1","x":-0.2362421452999115,"y":-0.611154317855835},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000305","label":"BioAsteroid ISS Chondrite Biomining Consortium","page":"communities/BioAsteroid_ISS_Chondrite_Biomining_Consortium.html","source_path":"kb/communities/BioAsteroid_ISS_Chondrite_Biomining_Consortium.yaml","text_sha256":"b8e5d8c89e007d035f11c5cf09be7533d1f039b93ce3216877c4b2f819223778","x":-3.591200351715088,"y":-6.806961536407471},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000217","label":"Cyprus Copper Sulphide Bioleaching Consortium","page":"communities/Cyprus_Copper_Sulphide_Bioleaching_Consortium.html","source_path":"kb/communities/Cyprus_Copper_Sulphide_Bioleaching_Consortium.yaml","text_sha256":"c12287d7ae230d9314e0f39423e66a636c6943345856ba2ac9ddea1c19b797e6","x":-4.10214376449585,"y":-5.768865585327148},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000175","label":"Clostridium cellulolyticum-Geobacter sulfurreducens Cellulose MFC Coculture","page":"communities/Clostridium_Cellulolyticum_Geobacter_Cellulose_MFC_Coculture.html","source_path":"kb/communities/Clostridium_Cellulolyticum_Geobacter_Cellulose_MFC_Coculture.yaml","text_sha256":"1e1ed6d21a6888ecd6b4498100fce9bcb6d2eff0233c03c5704c54f1f530056b","x":-2.3328120708465576,"y":1.0520073175430298},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000372","label":"Pseudomonas-Klebsiella-Alcaligenes Fe2+ Nitrogen-Removal SynCom","page":"communities/Pseudomonas_Klebsiella_Alcaligenes_FeII_Nitrogen_Removal_SynCom.html","source_path":"kb/communities/Pseudomonas_Klebsiella_Alcaligenes_FeII_Nitrogen_Removal_SynCom.yaml","text_sha256":"0cfe62805254ba07b193ee01711bc378251af50c25ebf6f66d6951d8794b66a9","x":-1.01242995262146,"y":-2.2954294681549072},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000290","label":"Phosphitivorax-Methanoculleus Lithosyntrophic Phosphite-Oxidizing Methanogenic Culture","page":"communities/Phosphitivorax_Methanoculleus_Lithosyntrophy_Phosphite_Coculture.html","source_path":"kb/communities/Phosphitivorax_Methanoculleus_Lithosyntrophy_Phosphite_Coculture.yaml","text_sha256":"1db1add23f6cb8074fa77ec05532eb8dd4f43395f08080c8b85d08377a86aef1","x":-5.0016326904296875,"y":0.8211683034896851},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000109","label":"Rice Acid Soil Bioinoculant SynCom","page":"communities/Rice_Acid_Soil_Bioinoculant_SynCom.html","source_path":"kb/communities/Rice_Acid_Soil_Bioinoculant_SynCom.yaml","text_sha256":"457d57760279ebd8cd9d3927e0f8144c8113a2f7367520fef58df1c7ca31e0b3","x":4.34357213973999,"y":-2.4835593700408936},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000102","label":"Peanut Seed Bacterial CS SynCom","page":"communities/Peanut_Seed_Bacterial_CS_SynCom.html","source_path":"kb/communities/Peanut_Seed_Bacterial_CS_SynCom.yaml","text_sha256":"61134180237845a78e2771bf34fed05b05cb20e2b8230165df1c62474b15b988","x":4.980342864990234,"y":-1.5437393188476562},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000270","label":"Trichoderma-Streptomyces Filamentous Cellulose Coculture","page":"communities/Trichoderma_Streptomyces_Filamentous_Cellulose_Coculture.html","source_path":"kb/communities/Trichoderma_Streptomyces_Filamentous_Cellulose_Coculture.yaml","text_sha256":"3afd42c8b11dc865add070cda0190c22ed1041251feb87551d2c4043b2f34270","x":-0.9458903670310974,"y":2.159039258956909},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000216","label":"PSY Transgenic Rice Rhizosphere Methane-Mitigating Community","page":"communities/PSY_Transgenic_Rice_Rhizosphere_Methane_Community.html","source_path":"kb/communities/PSY_Transgenic_Rice_Rhizosphere_Methane_Community.yaml","text_sha256":"040343e537d0a48f47ddb3e68d89be3e506c33df3b6f6b8759104c76581875e7","x":2.75589656829834,"y":-3.109100818634033},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000190","label":"Pelotomaculum-Methanocella Propionate RNA-Seq Coculture","page":"communities/Pelotomaculum_Methanocella_Propionate_RNASeq_Coculture.html","source_path":"kb/communities/Pelotomaculum_Methanocella_Propionate_RNASeq_Coculture.yaml","text_sha256":"d1fa118e8461557da402470babf251622e0295a02ae04e5047bde38f570d8f40","x":-4.693282604217529,"y":1.0520857572555542},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000349","label":"Bothnian Bay GAC-Dependent CIET-SAO Consortium","page":"communities/Bothnian_Bay_GAC_Dependent_CIET_SAO_Consortium.html","source_path":"kb/communities/Bothnian_Bay_GAC_Dependent_CIET_SAO_Consortium.yaml","text_sha256":"8d1db53ad360b932799caba8d4b970dd4d8a7cfc3713700b5cb80dd803239613","x":-3.940835952758789,"y":-0.5427630543708801},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000196","label":"Clostridium phytofermentans-E. coli Cellobiose Biofilm Consortium","page":"communities/Clostridium_Phytofermentans_Ecoli_Cellobiose_Biofilm_Consortium.html","source_path":"kb/communities/Clostridium_Phytofermentans_Ecoli_Cellobiose_Biofilm_Consortium.yaml","text_sha256":"19b3f50a41079d3a47e5322232f6e87a046eaab0011489485ccb3223791a2ba5","x":-0.8291029334068298,"y":2.2068238258361816},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000378","label":"Soy Sauce Temporal Seven-Species SynCom","page":"communities/Soy_Sauce_Temporal_SevenSpecies_SynCom.html","source_path":"kb/communities/Soy_Sauce_Temporal_SevenSpecies_SynCom.yaml","text_sha256":"31fd205fd2797f5761ca2ed66e1bc9ada1a5e806b7c324fa84ef19d66eb51fc0","x":2.7564918994903564,"y":1.7080233097076416},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000274","label":"Multi-stage Anaerobic-Digestion SynCom-YSJ and SynCom-J","page":"communities/Multi_stage_Anaerobic_Digestion_SynCom_YSJ_and_SynCom_J.html","source_path":"kb/communities/Multi_stage_Anaerobic_Digestion_SynCom_YSJ_and_SynCom_J.yaml","text_sha256":"76588b3a142fb64c6a21690cea33ba461cff1a748e0b0cc95b01badbd8c9c473","x":2.8520567417144775,"y":1.3210304975509644},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000203","label":"Shewanella-Streptococcus Starch-Fueled Microbial Fuel Cell Coculture","page":"communities/Shewanella_Streptococcus_Starch_Microbial_Fuel_Cell.html","source_path":"kb/communities/Shewanella_Streptococcus_Starch_Microbial_Fuel_Cell.yaml","text_sha256":"4eb1da14883d7adcc8d90b8988b4e45feca3585e3697689ee39b6029c75cd857","x":-2.739518880844116,"y":-0.1009209156036377},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000254","label":"Stordalen Mire Methylotrophic Methanogenesis Community","page":"communities/Stordalen_Mire_Methylotrophic_Methanogenesis_Community.html","source_path":"kb/communities/Stordalen_Mire_Methylotrophic_Methanogenesis_Community.yaml","text_sha256":"0af8484b3a8eb625dd43346e08193079885e6f2616a0421db466e13d6cb8b431","x":-4.311368942260742,"y":-2.888979434967041},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000186","label":"Thermotoga-Methanocaldococcus Hyperthermophilic Syntrophy","page":"communities/Thermotoga_Methanocaldococcus_Hyperthermophilic_Syntrophy.html","source_path":"kb/communities/Thermotoga_Methanocaldococcus_Hyperthermophilic_Syntrophy.yaml","text_sha256":"ff4a1fdfa8c45325a48a2609ac79329456229a7e2a71c1c4d83f076835f74d95","x":-4.284730434417725,"y":1.1672531366348267},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000368","label":"Arabidopsis Bacillus Biocontrol SynCom150","page":"communities/Arabidopsis_Bacillus_Biocontrol_SynCom150.html","source_path":"kb/communities/Arabidopsis_Bacillus_Biocontrol_SynCom150.yaml","text_sha256":"8b48b8c64e3f57178f60b6c7bbf8f56d36e1314f3c80fbbfcbc8f913eb2c59e0","x":4.627889156341553,"y":-1.408437728881836},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000312","label":"Suillus clintonianus-Bacillus altitudinis Thiamine Cross-Feeding SynCom","page":"communities/Suillus_Bacillus_Thiamine_Ectomycorrhizal_SynCom.html","source_path":"kb/communities/Suillus_Bacillus_Thiamine_Ectomycorrhizal_SynCom.yaml","text_sha256":"9ccd1f325f95ff41b1f4767c7cbad5ab055a16f8ca5803a0e11e568edee5fc22","x":0.3533945083618164,"y":5.2755255699157715},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000201","label":"Geobacter-Pseudomonas Formate-Fumarate Electroactive Coculture","page":"communities/Geobacter_Pseudomonas_Formate_Fumarate_Electroactive_Coculture.html","source_path":"kb/communities/Geobacter_Pseudomonas_Formate_Fumarate_Electroactive_Coculture.yaml","text_sha256":"649b0f771f240c575026f156c5b3fe63ab829a70d57fba0b18a1e3565e897f3f","x":-3.4152019023895264,"y":-0.6499712467193604},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000115","label":"Aerobic Denitrification Quorum-Quenching SynCom","page":"communities/Aerobic_Denitrification_QQ_SynCom.html","source_path":"kb/communities/Aerobic_Denitrification_QQ_SynCom.yaml","text_sha256":"7254185aeafb26d245ee9e4572a3b37901d370e3c9d038914b1a03cf8f3a2803","x":-1.1003257036209106,"y":-2.2768259048461914},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000362","label":"Sphingobium-Nitrososphaera Phenanthrene-Carbon SynCom","page":"communities/Sphingobium_Nitrososphaera_Phenanthrene_Carbon_SynCom.html","source_path":"kb/communities/Sphingobium_Nitrososphaera_Phenanthrene_Carbon_SynCom.yaml","text_sha256":"e5dacff3d1643a66d7ba14c96ee8fb0978fe22f38cbab361b9550889b42a2f73","x":3.483179807662964,"y":-1.307934284210205},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000008","label":"BioModels MODEL1806250005 Cicada Sulcia-Hodgkinia Symbiosis","page":"communities/BioModels_MODEL1806250005_Cicada_Sulcia_Hodgkinia.html","source_path":"kb/communities/BioModels_MODEL1806250005_Cicada_Sulcia_Hodgkinia.yaml","text_sha256":"c345d03a68790d3e8703cbad7e49a2f54c8ce17e9c54167f46be60ef2c0d7fcc","x":1.348326563835144,"y":4.94379186630249},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000055","label":"Polaromonas Vanadium Reduction Community","page":"communities/Polaromonas_Vanadium_Reduction_Community.html","source_path":"kb/communities/Polaromonas_Vanadium_Reduction_Community.yaml","text_sha256":"1772251093fa0591e14abf11dbb4548bea14211debd31040057c094d65f44354","x":-3.6813440322875977,"y":-4.756480693817139},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000098","label":"Watermelon Rhizosphere Fusarium-Protective SynCom8","page":"communities/Watermelon_Rhizosphere_Fusarium_SynCom8.html","source_path":"kb/communities/Watermelon_Rhizosphere_Fusarium_SynCom8.yaml","text_sha256":"c5a2cb1e1b08daef4db9bc36700651a62163a590b24b109c9bb59a4a23ac284f","x":5.019539833068848,"y":-1.9306188821792603},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000095","label":"Garlic Rhizosphere Pseudomonas SynCom6","page":"communities/Garlic_Pseudomonas_SynCom6.html","source_path":"kb/communities/Garlic_Pseudomonas_SynCom6.yaml","text_sha256":"652b5fc52b2fd1e7746f78f44d1b296094f36e40bf3c163d82a1976dc7214181","x":4.677220344543457,"y":-2.4951729774475098},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000145","label":"Cable Bacteria beneath Photosynthetic Biofilm Sediment Community","page":"communities/Cable_Bacteria_Photosynthetic_Biofilm_Sediment.html","source_path":"kb/communities/Cable_Bacteria_Photosynthetic_Biofilm_Sediment.yaml","text_sha256":"48268501c5b65b2fb35b417687cb003266682f565b804de9a50ff22bedf13791","x":-3.861647367477417,"y":-1.7458840608596802},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000325","label":"Euglena-Chlorella Microalgal Biorefinery Coculture","page":"communities/Euglena_Chlorella_Microalgal_Biorefinery_Coculture.html","source_path":"kb/communities/Euglena_Chlorella_Microalgal_Biorefinery_Coculture.yaml","text_sha256":"38650bcc22effdce6e7692708e487c9e4aeeb451b6ef9306fb24538186235f9d","x":-1.1788386106491089,"y":5.341737270355225},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000077","label":"Wheat Synthetic Consortium C6","page":"communities/Wheat_Consortium_C6.html","source_path":"kb/communities/Wheat_Consortium_C6.yaml","text_sha256":"10420158e3a2b85205d4ee1bf8e1d5b0d6f20b83b244ca0203f2821135b95937","x":4.354160785675049,"y":-2.027540922164917},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000004","label":"Australian Lead Zinc Polymetallic Tailings Consortium","page":"communities/Australian_Lead_Zinc_Polymetallic.html","source_path":"kb/communities/Australian_Lead_Zinc_Polymetallic.yaml","text_sha256":"c2239df1da100991c56ad158825d8ebd3fd6add2c1d024a467f822ad80819dda","x":-3.9291694164276123,"y":-5.445849895477295},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000111","label":"Miscanthus REE Tailings Nitrogen SynCom10","page":"communities/Miscanthus_REE_Tailings_Nitrogen_SynCom10.html","source_path":"kb/communities/Miscanthus_REE_Tailings_Nitrogen_SynCom10.yaml","text_sha256":"91d4136d43696838890aa263bae4cb9b49397ac72db1ecd11e0eb86f700117c5","x":2.8449907302856445,"y":-1.2247005701065063},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000307","label":"Anabaena / MGS-1 Anaerobic-Digestion Methanogen Consortium","page":"communities/Anabaena_MGS1_Anaerobic_Digestion_Methanogen_Consortium.html","source_path":"kb/communities/Anabaena_MGS1_Anaerobic_Digestion_Methanogen_Consortium.yaml","text_sha256":"1d7c873ab238738f848c4e62536f309946152a8376fb16813fb730787fd08684","x":-3.362839460372925,"y":-6.959606647491455},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000279","label":"Shewanella oneidensis MR-1 - Rhodopseudomonas palustris Electro-syntrophic Co-culture","page":"communities/Shewanella_oneidensis_Rhodopseudomonas_palustris_Electrosyntrophic_Coculture.html","source_path":"kb/communities/Shewanella_oneidensis_Rhodopseudomonas_palustris_Electrosyntrophic_Coculture.yaml","text_sha256":"0415b6270790d5a20e64561da327b0f038c4e4528effcfe15e8dd73e1ebad87e","x":-2.4866840839385986,"y":-0.3492859899997711},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000038","label":"KBase ORT Workflow Community Model","page":"communities/KBase_ORT_Workflow_Community_Model.html","source_path":"kb/communities/KBase_ORT_Workflow_Community_Model.yaml","text_sha256":"7ae05272e5f1849768e340d62f8685f367bc034bc9c4eb33952f14f06a57d292","x":-1.3158756494522095,"y":-2.7177374362945557},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000233","label":"East River Hillslope Riparian Transect Microbial Community","page":"communities/East_River_Hillslope_Riparian_Transect_Community.html","source_path":"kb/communities/East_River_Hillslope_Riparian_Transect_Community.yaml","text_sha256":"4e740dfc11574f72d498799eaa635462a12d0e52ef2c7c9403c8a58e8557fb2d","x":-2.9187417030334473,"y":-3.410473346710205},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000034","label":"Iberian Pit Lake Stratified Community","page":"communities/Iberian_Pit_Lake_Stratified_Community.html","source_path":"kb/communities/Iberian_Pit_Lake_Stratified_Community.yaml","text_sha256":"f5ba3bb03c5bed5d07edbe65920e68acce25a5f1975e46b35c69844491fdecff","x":-3.7707083225250244,"y":-4.1617889404296875},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000242","label":"Groundwater Elusimicrobia Diverse Metabolisms Community","page":"communities/Groundwater_Elusimicrobia_Diverse_Metabolisms.html","source_path":"kb/communities/Groundwater_Elusimicrobia_Diverse_Metabolisms.yaml","text_sha256":"6e7ca6ff35683f29b533e6adc56c9a48cada86a4ad1a04099781da2793ff800a","x":-2.5375869274139404,"y":-3.460263729095459},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000377","label":"Apple Fire Blight A+N+P SynCom","page":"communities/Apple_Fire_Blight_ANP_SynCom.html","source_path":"kb/communities/Apple_Fire_Blight_ANP_SynCom.yaml","text_sha256":"cd05d26ae97bf2459df539d8aa24f22f0281f5baf3d5d86e04eee5b1da7d3222","x":4.494614124298096,"y":-1.0384254455566406},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000061","label":"SF356 Thermophilic Cellulose-Degrading Community","page":"communities/SF356_Cellulose_Degrader.html","source_path":"kb/communities/SF356_Cellulose_Degrader.yaml","text_sha256":"2cffbfcd09ba5671f85dc87be3e8ab0fad4bb6dd7dc4faad318ff972ac91e3c5","x":-1.2555031776428223,"y":1.6976526975631714},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000284","label":"Black Soldier Fly Larvae Gut SynCom (Bacillus + Lactobacillus + Issatchenkia)","page":"communities/BSFL_Gut_SynCom_Bacillus_Lactobacillus_Issatchenkia.html","source_path":"kb/communities/BSFL_Gut_SynCom_Bacillus_Lactobacillus_Issatchenkia.yaml","text_sha256":"f9b66d5e2dd6efbd6326c7e8a2bb140b96c2ba64420fe3b5f96ef27304555286","x":3.429788827896118,"y":1.063599944114685},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000356","label":"Jiangshui LAB Directed Fermentation SynCom","page":"communities/Jiangshui_LAB_Directed_Fermentation_SynCom.html","source_path":"kb/communities/Jiangshui_LAB_Directed_Fermentation_SynCom.yaml","text_sha256":"01d466777a4d248c9e065e03c0264ef93e5a8aca43ff25190f1b181edb931e20","x":3.4013922214508057,"y":0.8610829710960388},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000338","label":"Caragana korshinskii Cross-Kingdom Forage Bio-Valorization SynCom","page":"communities/Caragana_Korshinskii_CrossKingdom_Forage_SynCom.html","source_path":"kb/communities/Caragana_Korshinskii_CrossKingdom_Forage_SynCom.yaml","text_sha256":"8acb2ccb76c1f863f61bff504557fc611d15ed48abfb4d2b69a743f5093abf19","x":2.4839961528778076,"y":0.8957006931304932},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000224","label":"Grassland Soil Wet-Up Virus-Host Community","page":"communities/Grassland_Soil_WetUp_Virus_Host_Community.html","source_path":"kb/communities/Grassland_Soil_WetUp_Virus_Host_Community.yaml","text_sha256":"b2c6a34a31d6d4ca786719b820adf62d6897b2963692873a815d1da1cdbf06f3","x":0.9897266030311584,"y":-3.447410821914673},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000006","label":"BioModels MODEL1806250003 Spittlebug Sulcia-Sodalis Symbiosis","page":"communities/BioModels_MODEL1806250003_Spittlebug_Sulcia_Sodalis.html","source_path":"kb/communities/BioModels_MODEL1806250003_Spittlebug_Sulcia_Sodalis.yaml","text_sha256":"85fa1bbe6add0d0591d36eb04b16c7b9403fbdf8ec221aeaa4df292f01d05182","x":1.1443381309509277,"y":5.1001482009887695},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000021","label":"DVM Tri-culture","page":"communities/DVM_Triculture.html","source_path":"kb/communities/DVM_Triculture.yaml","text_sha256":"b735eb0babe5ac62b8ae7017980fb23e423ae3eaedc8c1b8753750de31b6568e","x":-3.2618627548217773,"y":1.2423691749572754},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000214","label":"Model Cyanobacterial Consortia Core Microbiome","page":"communities/Model_Cyanobacterial_Consortia_Core_Microbiome.html","source_path":"kb/communities/Model_Cyanobacterial_Consortia_Core_Microbiome.yaml","text_sha256":"2039779a0ad1cca56fa3a0c4fd8ebe69c33dbf2be6c9d7b7e33022a123939e5f","x":-1.0997679233551025,"y":5.419238567352295},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000286","label":"Dual Bacillus coagulans + Pseudomonas putida Lactic-acid Co-culture","page":"communities/Dual_Bacillus_coagulans_Pseudomonas_putida_Lactic_Acid_Coculture.html","source_path":"kb/communities/Dual_Bacillus_coagulans_Pseudomonas_putida_Lactic_Acid_Coculture.yaml","text_sha256":"611632229b422c7d503b26684bce20890892c51772ed43bc3c2591aa13b01e4d","x":0.32249385118484497,"y":1.8509604930877686},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000299","label":"Ensifer YF2 + Sphingobacterium Y2 Polyethylene-degrading Consortium","page":"communities/Ensifer_YF2_Sphingobacterium_Y2_Polyethylene_Degrading_Consortium.html","source_path":"kb/communities/Ensifer_YF2_Sphingobacterium_Y2_Polyethylene_Degrading_Consortium.yaml","text_sha256":"57649717b9facc1655e0e8b5d9851f51dc80c56f17a4633dac45a327fbe0af5e","x":0.15291336178779602,"y":0.1493217796087265},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000361","label":"RH1 Glyphosate Streptomyces Consortium","page":"communities/RH1_Glyphosate_Streptomyces_Consortium.html","source_path":"kb/communities/RH1_Glyphosate_Streptomyces_Consortium.yaml","text_sha256":"c3488d4fbd9e1daa655a2e4d366dc9c9af7322c429bd2daf7209842b51a6af6a","x":0.23808063566684723,"y":-0.6495811343193054},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000072","label":"TYQ1 Nematode Biocontrol SynCom","page":"communities/TYQ1_Nematode_Biocontrol_SynCom.html","source_path":"kb/communities/TYQ1_Nematode_Biocontrol_SynCom.yaml","text_sha256":"449ccabf9055c3216aa863584516788065f2efe3004c8b43966c7b5b8ce032a2","x":3.4889862537384033,"y":-2.4034905433654785},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000189","label":"Syntrophomonas-Methanococcus Butyrate Growth Coordination Coculture","page":"communities/Syntrophomonas_Methanococcus_Butyrate_Growth_Coordination_Coculture.html","source_path":"kb/communities/Syntrophomonas_Methanococcus_Butyrate_Growth_Coordination_Coculture.yaml","text_sha256":"38a8fdfdf7afe7074e05dd3c412c85cd190d6bb73f20fd52f3f496722447e6ee","x":-4.389737129211426,"y":1.1245968341827393},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000015","label":"Chlamydomonas-Methylobacterium Mutualistic Consortium","page":"communities/Chlamydomonas_Methylobacterium_Mutualism.html","source_path":"kb/communities/Chlamydomonas_Methylobacterium_Mutualism.yaml","text_sha256":"c9ac43a28c754c347a65495fc0acd456855e9e7493bedfeab4390fbdfcdb2cfe","x":-1.0773333311080933,"y":5.382490158081055},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000183","label":"Dehalococcoides-Syntrophomonas TCE Dechlorination Coculture","page":"communities/Dehalococcoides_Syntrophomonas_TCE_Dechlorination_Coculture.html","source_path":"kb/communities/Dehalococcoides_Syntrophomonas_TCE_Dechlorination_Coculture.yaml","text_sha256":"09a3a7cc2e9521dddcf78f896e3d5b0a2f45dd2938cf5f58207a71263ebba84f","x":-2.2580690383911133,"y":-0.2714608907699585},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000096","label":"Desert-Derived Tomato Salt Stress SynCom5","page":"communities/Desert_Tomato_Salt_Stress_SynCom5.html","source_path":"kb/communities/Desert_Tomato_Salt_Stress_SynCom5.yaml","text_sha256":"d90f6b0c586804c2cc97bafb899415290a92bd50806162d0bee57019f80a2f18","x":4.834463119506836,"y":-2.1985297203063965},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000227","label":"Mediterranean Grassland qSIP Rainfall-Gradient Community","page":"communities/Mediterranean_Grassland_qSIP_Rainfall_Community.html","source_path":"kb/communities/Mediterranean_Grassland_qSIP_Rainfall_Community.yaml","text_sha256":"f993e66e1fe1786ff03ff32a579566310df703dfa4ec9c4751d99108e9f632da","x":1.5645631551742554,"y":-3.2563602924346924},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000130","label":"Synthetic Periphyton Freshwater Biofilm","page":"communities/Synthetic_Periphyton_Freshwater_Biofilm.html","source_path":"kb/communities/Synthetic_Periphyton_Freshwater_Biofilm.yaml","text_sha256":"6985136d42439914e6d0d72b31a7239d987b1f3caba83096a908d8b911fc54f5","x":0.998306930065155,"y":5.7290568351745605},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000294","label":"Corynebacterium glutamicum + Shewanella oneidensis Succinic-acid Co-culture","page":"communities/Corynebacterium_glutamicum_Shewanella_oneidensis_Succinic_Acid_Coculture.html","source_path":"kb/communities/Corynebacterium_glutamicum_Shewanella_oneidensis_Succinic_Acid_Coculture.yaml","text_sha256":"01f6cb22d5473d55c4e288b32bd39e7c7c92fa3687a96403ee887994f5cff48f","x":-2.880687952041626,"y":0.23151834309101105},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000117","label":"Urine Nitrification Synthetic Microbial Community","page":"communities/Urine_Nitrification_SynCom.html","source_path":"kb/communities/Urine_Nitrification_SynCom.yaml","text_sha256":"4fcd874c4ac7a6b21caae1c645509a6d6b1fa95bda813f98c905174f925fbb8b","x":-0.9691106677055359,"y":-2.2511980533599854},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000220","label":"Bifidobacterium-Ruminococcus Infant HMO Cross-Feeding Coculture","page":"communities/Bifidobacterium_Ruminococcus_Infant_HMO_CrossFeeding.html","source_path":"kb/communities/Bifidobacterium_Ruminococcus_Infant_HMO_CrossFeeding.yaml","text_sha256":"263cad44c8f85189ccc2e97ab190bb540da4798635c62fe4ecbbb8c2a39c998e","x":2.885499954223633,"y":3.626985788345337},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000182","label":"Thermacetogenium-Methanothermobacter Acetate Oxidation Coculture","page":"communities/Thermacetogenium_Methanothermobacter_Acetate_Oxidation_Coculture.html","source_path":"kb/communities/Thermacetogenium_Methanothermobacter_Acetate_Oxidation_Coculture.yaml","text_sha256":"0a593c312c37bed20972d2161ae4e91e81aceb6bc93237fe221dac7009c38083","x":-4.14941930770874,"y":1.4450867176055908},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000237","label":"Episymbiotic CPR Bacteria and DPANN Archaea Groundwater Community","page":"communities/Episymbiotic_CPR_DPANN_Groundwater_Community.html","source_path":"kb/communities/Episymbiotic_CPR_DPANN_Groundwater_Community.yaml","text_sha256":"4f6cccba713e5c64a0d59131299386adcd83889c4f95dd02cc5a2796617b7f6a","x":-2.479248523712158,"y":-3.451772928237915},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000029","label":"GLBRC Ultra-Filtered Milk Permeate Fermentation Community","page":"communities/GLBRC_UFMP_Fermentation_Community.html","source_path":"kb/communities/GLBRC_UFMP_Fermentation_Community.yaml","text_sha256":"4f0d3044e93ec812bc4a77f8fab4f2f1f74923ee5b9ba266075978de831a1a9c","x":1.1817338466644287,"y":2.7898130416870117},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000134","label":"ANME-SRB Marine Methane Seep Consortium","page":"communities/ANME_SRB_Marine_Methane_Seep_Consortium.html","source_path":"kb/communities/ANME_SRB_Marine_Methane_Seep_Consortium.yaml","text_sha256":"d650b4e410721fbc52733efdc7e40e818a5478e73f0d1f173e16adea43cf8130","x":-4.072662830352783,"y":-1.6337060928344727},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000131","label":"Prochlorococcus-Alteromonas Helper Coculture","page":"communities/Prochlorococcus_Alteromonas_Helper_Coculture.html","source_path":"kb/communities/Prochlorococcus_Alteromonas_Helper_Coculture.yaml","text_sha256":"192834da8f8ecf5391d03b588d6111d6230f5319c85829ce08989b6f182b82dd","x":-1.3964345455169678,"y":5.285477161407471},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000297","label":"DIET-based Simplified Lignocellulose-to-Methane Consortia (DIETsimp)","page":"communities/DIETsimp_Lignocellulose_to_Methane_DIET_Consortia.html","source_path":"kb/communities/DIETsimp_Lignocellulose_to_Methane_DIET_Consortia.yaml","text_sha256":"0e4cc2b7d32d6c1226853a83431732886284b646edbcba271e281d372be5c764","x":-3.089473247528076,"y":0.270374596118927},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000359","label":"PPHET Hybrid Photosynthetic PHB Microbiome","page":"communities/PPHET_Hybrid_Photosynthetic_PHB_Microbiome.html","source_path":"kb/communities/PPHET_Hybrid_Photosynthetic_PHB_Microbiome.yaml","text_sha256":"50ed0161a0cab4e8e25175321f00360b291e22b0c5a405d7144946dafcefc490","x":-1.823862075805664,"y":5.322712421417236},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000153","label":"Cheese Rind In Situ-In Vitro Model Community","page":"communities/Cheese_Rind_InSitu_InVitro_Model_Community.html","source_path":"kb/communities/Cheese_Rind_InSitu_InVitro_Model_Community.yaml","text_sha256":"e7b2642144eb0b26852f7625061ca86833fbd4fe88828a14ab94afcde9fdf3d6","x":2.5420210361480713,"y":4.738116264343262},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000333","label":"Clostridium-E. coli-Nitratidesulfovibrio Minority-Mediator Consortium","page":"communities/Clostridium_Ecoli_Nitratidesulfovibrio_Minority_Mediator_Consortium.html","source_path":"kb/communities/Clostridium_Ecoli_Nitratidesulfovibrio_Minority_Mediator_Consortium.yaml","text_sha256":"a80981e45461ecb217066127bcbf1f5cad03b9b5abf866bb6e79273f3597573c","x":0.6879491806030273,"y":2.563094139099121},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000355","label":"Bacillus-Saccharomyces Daqu Spatial-Cooperation SynCom","page":"communities/Bacillus_Saccharomyces_Daqu_Spatial_Cooperation_SynCom.html","source_path":"kb/communities/Bacillus_Saccharomyces_Daqu_Spatial_Cooperation_SynCom.yaml","text_sha256":"5321f95739ae18f6ac18fc3320fb957e5b22afde2fd916434ff8437518e12498","x":1.0826585292816162,"y":2.0179858207702637},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000137","label":"East River Floodplain Core Microbiome","page":"communities/East_River_Floodplain_Core_Microbiome.html","source_path":"kb/communities/East_River_Floodplain_Core_Microbiome.yaml","text_sha256":"d45d658d91d5fb99bca98e36989bf7b1c1e9e18b47792a7295a2369418fdd65a","x":-3.5742249488830566,"y":-3.105034351348877},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000146","label":"Anammox Granule Metabolic Interaction Community","page":"communities/Anammox_Granule_Metabolic_Interaction_Community.html","source_path":"kb/communities/Anammox_Granule_Metabolic_Interaction_Community.yaml","text_sha256":"9ba1d1b00187798a79a42befd6f30e5a5bfb8401bdf9d5d46c3ebc4f455435dd","x":-1.4380992650985718,"y":-2.46596360206604},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000073","label":"Thermophilic Pyrite Quorum Sensing Consortium","page":"communities/Thermophilic_Pyrite_QS_Consortium.html","source_path":"kb/communities/Thermophilic_Pyrite_QS_Consortium.yaml","text_sha256":"bbfd98195f86f2565b29b67c5b489cedf6c34cb22da9cf0ab74810e5e1c3ffa2","x":-4.104835510253906,"y":-5.509669303894043},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000316","label":"Eucalyptus Nursery Five-Strain Bacterial Inoculant Consortium","page":"communities/Eucalyptus_Nursery_FiveStrain_Inoculant_SynCom.html","source_path":"kb/communities/Eucalyptus_Nursery_FiveStrain_Inoculant_SynCom.yaml","text_sha256":"32412095d46e09442e2b4ebb86cefc962b476a326f3c275b8c8477f2c0da475e","x":3.105376720428467,"y":-2.695136070251465},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000278","label":"SynCom BsBv Cigar Tobacco Leaf Fermentation","page":"communities/SynCom_BsBv_Cigar_Tobacco_Leaf_Fermentation.html","source_path":"kb/communities/SynCom_BsBv_Cigar_Tobacco_Leaf_Fermentation.yaml","text_sha256":"e058e925a4967fe769dce915d2a311cfd6899f0c190d8214ff6dd07f19b527d8","x":3.8989038467407227,"y":0.14796464145183563},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000084","label":"Streptococcus mutans - Selenomonas sputigena ECC Pathobiont Model","page":"communities/SMutans_SSputigena_ECC_Pathobiont.html","source_path":"kb/communities/SMutans_SSputigena_ECC_Pathobiont.yaml","text_sha256":"3730ef94dc2443bcf31de3c28482362c8a47063c7ee7c429d8edb5fead70c178","x":2.436523675918579,"y":5.083737850189209},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000321","label":"BioModels MODEL2204300002 Kefir Rothia Model","page":"isolates/BioModels_MODEL2204300002_Kefir_Rothia_Model.html","source_path":"data/isolates/BioModels_MODEL2204300002_Kefir_Rothia_Model.yaml","text_sha256":"857802b9924ff80a1d8b4be2f03c9a1197dcb3be45eff0698036ac988d2a467c","x":1.5753692388534546,"y":4.756189346313477},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000140","label":"Saanich Inlet Oxygen Minimum Zone Redox-Gradient Community","page":"communities/Saanich_Inlet_OMZ_Redox_Gradient_Community.html","source_path":"kb/communities/Saanich_Inlet_OMZ_Redox_Gradient_Community.yaml","text_sha256":"1ac3fba76103dadf343bc88f80e8700ffcf2b3814a86e1af58e69c004f98a1d4","x":-3.5108394622802734,"y":-2.581112861633301},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000105","label":"Pepper Phytophthora-Resistance SynCom5","page":"communities/Pepper_Phytophthora_SynCom5.html","source_path":"kb/communities/Pepper_Phytophthora_SynCom5.yaml","text_sha256":"aafbdff645437805ae3717f6a233783a6dbe895ae700b30e63ca6216ce282547","x":5.128303527832031,"y":-1.8556197881698608},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000152","label":"Industrial Milk-Line Four-Species Model Biofilm","page":"communities/Industrial_Milk_Line_FourSpecies_Model_Biofilm.html","source_path":"kb/communities/Industrial_Milk_Line_FourSpecies_Model_Biofilm.yaml","text_sha256":"dd20a79e44b2d327bf9023118aed68c16ec630806f369d521442f82c1660515b","x":2.2848873138427734,"y":5.276205539703369},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000101","label":"Maize Benzoxazinoid-Metabolizing SynComs","page":"communities/Maize_Benzoxazinoid_Metabolizing_SynComs.html","source_path":"kb/communities/Maize_Benzoxazinoid_Metabolizing_SynComs.yaml","text_sha256":"99716a46f8c6fe37102b9450904f7ff282db7ef04694c359229ce6f4d8af3188","x":3.1058528423309326,"y":-1.1148014068603516},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000204","label":"Methylocystis-Rhodococcus Methane VFA PHBV Coculture","page":"communities/Methylocystis_Rhodococcus_Methane_VFA_PHBV_Coculture.html","source_path":"kb/communities/Methylocystis_Rhodococcus_Methane_VFA_PHBV_Coculture.yaml","text_sha256":"d2a62ed115de1b3860a34102abc9968c9090d042c87eee942932120dc8cacad6","x":-2.3266329765319824,"y":2.8992042541503906},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000085","label":"Streptococcus mutans - Veillonella parvula Adult Severe Caries Model","page":"communities/SMutans_VParvula_ASC_Biofilm.html","source_path":"kb/communities/SMutans_VParvula_ASC_Biofilm.yaml","text_sha256":"8d9cc2b2cd8af3cb54cb6cd91be836f66e44b70000936739943a7c1f9e038ebe","x":2.4638659954071045,"y":5.074481964111328},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000030","label":"Gulf of Mexico Oil-Degrading Consortium","page":"communities/GOM_Oil_Degrading_Consortium.html","source_path":"kb/communities/GOM_Oil_Degrading_Consortium.yaml","text_sha256":"f199460225718a8b9fb14b7b292d2037b1221d6a2457b9ea690c205601cc4b13","x":0.05428749695420265,"y":-0.8278330564498901},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000249","label":"San Francisco Bay Area Sewage SARS-CoV-2 Metagenomic Surveillance Community","page":"communities/Bay_Area_Sewage_SARS_CoV2_Surveillance_Community.html","source_path":"kb/communities/Bay_Area_Sewage_SARS_CoV2_Surveillance_Community.yaml","text_sha256":"e2f597851586841f556c0c3439fc0b6acd27805f023de006fd4727f5d2334037","x":-1.7129367589950562,"y":-3.7402594089508057},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000118","label":"Wheat Straw Biogas Pretreatment SynCom","page":"communities/Wheat_Straw_Biogas_Pretreatment_SynCom.html","source_path":"kb/communities/Wheat_Straw_Biogas_Pretreatment_SynCom.yaml","text_sha256":"20b28ae9249e459943a9bfacccae13fddc6928d01c981bbce25689e2c057a151","x":1.4777268171310425,"y":1.2738049030303955},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000250","label":"Soil Biosynthetic Gene Cluster Phylum-Depth-Vegetation Community","page":"communities/Soil_BGC_Phylum_Depth_Vegetation_Community.html","source_path":"kb/communities/Soil_BGC_Phylum_Depth_Vegetation_Community.yaml","text_sha256":"6f3493a03960b02c933cc95b1523863761504c978f4a145982eaf64e41520a92","x":1.0380140542984009,"y":-3.2313146591186523},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000128","label":"CRC Fusobacterium Control SynCom","page":"communities/CRC_Fusobacterium_Control_SynCom.html","source_path":"kb/communities/CRC_Fusobacterium_Control_SynCom.yaml","text_sha256":"c7c7fc7a6eb234a457aa0d4513125f4385d146f7000348f267e1a89ada8133d7","x":3.49351167678833,"y":1.8990213871002197},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000322","label":"Methylobacterium REE E-waste Platform","page":"isolates/Methylobacterium_REE_Ewaste_Platform.html","source_path":"data/isolates/Methylobacterium_REE_Ewaste_Platform.yaml","text_sha256":"e47c6a28e13d4040947fc4a687e229a0a5fe840948cdd79d95f00b967d5e51f3","x":-3.706988573074341,"y":-6.288360118865967},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000184","label":"Dehalococcoides-Pelobacter Acetylene TCE Coculture","page":"communities/Dehalococcoides_Pelobacter_Acetylene_TCE_Coculture.html","source_path":"kb/communities/Dehalococcoides_Pelobacter_Acetylene_TCE_Coculture.yaml","text_sha256":"decd74860744051d88b8a39b4aa5cd47bbdcbd0d0bd0ac9af7f62eb793bd4571","x":-1.6215240955352783,"y":-0.4734886586666107},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000048","label":"Okeke-Lu Cellulolytic-Xylanolytic Consortium","page":"communities/Okeke_Lu_Cellulolytic_Consortium.html","source_path":"kb/communities/Okeke_Lu_Cellulolytic_Consortium.yaml","text_sha256":"a915e94b4ed68aa280dad33491845b3c02825a3e6b82ff0308558ef4c15fe71d","x":-0.242939755320549,"y":1.4790233373641968},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000078","label":"m-CAFEs Brachypodium Reduced Complexity Consortia","page":"communities/mCAFEs_Brachypodium_RCC.html","source_path":"kb/communities/mCAFEs_Brachypodium_RCC.yaml","text_sha256":"f2f7ba58821511e7e73d6f026c78b48ba869c01c45a743be21544405746a8d34","x":2.401459217071533,"y":-2.9372143745422363},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000035","label":"Industrial Bioleaching Reactor Consortium","page":"communities/Industrial_Bioreactor_Consortium.html","source_path":"kb/communities/Industrial_Bioreactor_Consortium.yaml","text_sha256":"90eabfc919808f9b85598ff6905d020b5a2a68d2399153a7e84c243c9625a1f6","x":-4.025850296020508,"y":-5.860608100891113},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000191","label":"Chlorella-Azospirillum Synthetic Mutualism","page":"communities/Chlorella_Azospirillum_Synthetic_Mutualism.html","source_path":"kb/communities/Chlorella_Azospirillum_Synthetic_Mutualism.yaml","text_sha256":"3d75c9809528a7f5dce34c5f329c3c39b80b03b95b6d3ed88d09e182b77411f4","x":-0.7654247879981995,"y":5.358490467071533},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000043","label":"Maize Root Simplified Bacterial Community","page":"communities/Maize_Root_Simplified_Community.html","source_path":"kb/communities/Maize_Root_Simplified_Community.yaml","text_sha256":"6a27f83fa748d62983ea3348acf3767c1321cb2a69550bc2c3db5aa2e9db2fad","x":3.2957589626312256,"y":-2.3174855709075928},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000255","label":"Wetland Oxygen-Sulfate Greenhouse Gas Microcosm Community","page":"communities/Wetland_Oxygen_Sulfate_GHG_Microcosm_Community.html","source_path":"kb/communities/Wetland_Oxygen_Sulfate_GHG_Microcosm_Community.yaml","text_sha256":"56a01e920ce4a0ecced5acfe2f34904c540fc920f13edab9e8aea43deffa1314","x":-3.947331190109253,"y":-2.904677391052246},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000273","label":"Chromobacterium Gold Biocyanidation Platform","page":"isolates/Chromobacterium_Gold_Biocyanidation.html","source_path":"data/isolates/Chromobacterium_Gold_Biocyanidation.yaml","text_sha256":"0c72f24fce82950cdd6f7f4e4f9f613ad6f9ed63a577272f66e82d4b29b77756","x":-3.6154723167419434,"y":-6.627386093139648},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000281","label":"Infant-gut Prebiotic-response SynCom","page":"communities/Infant_Gut_Prebiotic_Response_SynCom.html","source_path":"kb/communities/Infant_Gut_Prebiotic_Response_SynCom.yaml","text_sha256":"4015210c5ab14f0388ec8ae3f094d48f4eb8bc3818b28071237208fa1330c4eb","x":3.377851724624634,"y":2.699673652648926},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000037","label":"KBase Models for Zahmeeth Original PLOS","page":"communities/KBase_Models_for_Zahmeeth_Original_PLOS.html","source_path":"kb/communities/KBase_Models_for_Zahmeeth_Original_PLOS.yaml","text_sha256":"14598acdddb66746d3c75a9fe2016c1f6baa2bb88c140eafb294e69d1e9d22db","x":1.636893391609192,"y":4.779601573944092},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000337","label":"Tropidoatractus magnetotacticus Magnetotactic Ciliate Tripartite Syntrophy","page":"communities/Tropidoatractus_Magnetotacticus_Tripartite_Syntrophy.html","source_path":"kb/communities/Tropidoatractus_Magnetotacticus_Tripartite_Syntrophy.yaml","text_sha256":"36a4085471edd8a7ad822f5317588b034a084456a3bf602afd04b7b4d677dc83","x":-4.35278844833374,"y":-1.2435243129730225},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000026","label":"E-waste Bioleaching Consortium","page":"communities/Ewaste_Bioleaching_Consortium.html","source_path":"kb/communities/Ewaste_Bioleaching_Consortium.yaml","text_sha256":"bb24e23c98e04d2f5540299850cc52160b7422f6239b93e4049e44be24c40fcc","x":-3.957258701324463,"y":-5.83111047744751},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000042","label":"MSC-1 Dominant Core","page":"communities/MSC1_Dominant_Core.html","source_path":"kb/communities/MSC1_Dominant_Core.yaml","text_sha256":"0252095d0eb3ad7e592091e6ceb377c183eeec9f58b3ad962c6c8f3fb37ed6a0","x":0.8254767060279846,"y":-2.614091396331787},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000024","label":"ENIGMA Denitrifying SynCom","page":"communities/ENIGMA_Denitrifying_SynCom.html","source_path":"kb/communities/ENIGMA_Denitrifying_SynCom.yaml","text_sha256":"2c50268820096417b82f947a90b8e6ddf2318f5d9f71e552ff872131ebfcf933","x":-0.8264681100845337,"y":-2.515094757080078},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000365","label":"Baijiu Pit Mud Hexanoic Acid SynCom G4","page":"communities/Baijiu_Pit_Mud_Hexanoic_Acid_SynCom_G4.html","source_path":"kb/communities/Baijiu_Pit_Mud_Hexanoic_Acid_SynCom_G4.yaml","text_sha256":"5ad3ffa0da232fdc2e84979681fc106fdfc615ff3736a00f8bee332fa364b2f5","x":2.9250879287719727,"y":0.47103220224380493},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000100","label":"Teosinte-Derived Maize Biofertilizer SynCom7","page":"communities/Teosinte_Maize_Biofertilizer_SynCom7.html","source_path":"kb/communities/Teosinte_Maize_Biofertilizer_SynCom7.yaml","text_sha256":"ac541a50b5271c1683bd8b2f82a4fe3a82555660a6304fcb12c6a54a852908b0","x":4.618795394897461,"y":-2.006741523742676},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000200","label":"Dehalococcoides-Desulfovibrio-Pelosinus Corrinoid Triculture","page":"communities/Dehalococcoides_Desulfovibrio_Pelosinus_Corrinoid_Triculture.html","source_path":"kb/communities/Dehalococcoides_Desulfovibrio_Pelosinus_Corrinoid_Triculture.yaml","text_sha256":"30cdd72b22d5da54784057a06e4f7baba8a26d11e8ea9335f4e437766e772fb4","x":-1.9548580646514893,"y":-0.19592873752117157},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000159","label":"CeMbio Caenorhabditis elegans Microbiome","page":"communities/CeMbio_Caenorhabditis_Elegans_Microbiome.html","source_path":"kb/communities/CeMbio_Caenorhabditis_Elegans_Microbiome.yaml","text_sha256":"df568df982c63db15dcc2d216f8a590e9efe7a71d900de1e09287bd0c200cafc","x":3.5066094398498535,"y":3.523559331893921},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000141","label":"Chlorochromatium aggregatum Phototrophic Consortium","page":"communities/Chlorochromatium_Aggregatum_Phototrophic_Consortium.html","source_path":"kb/communities/Chlorochromatium_Aggregatum_Phototrophic_Consortium.yaml","text_sha256":"052409c0f68867e4f7bf8112c45c17f3b6c5fb747ff892f6d0cb5710aac2e21c","x":-1.5419610738754272,"y":5.123783111572266},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000215","label":"California Grassland Precipitation Legacy Soil Community","page":"communities/California_Grassland_Precipitation_Legacy_Soil_Community.html","source_path":"kb/communities/California_Grassland_Precipitation_Legacy_Soil_Community.yaml","text_sha256":"0f30217cfe2c233c0cf67c8ea89c5b506083a63abad158514c727be2945442fe","x":0.7228723168373108,"y":-3.3976497650146484},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000151","label":"Engineered Gut Amino Acid Cross-Feeding Consortium","page":"communities/Engineered_Gut_Amino_Acid_CrossFeeding_Consortium.html","source_path":"kb/communities/Engineered_Gut_Amino_Acid_CrossFeeding_Consortium.yaml","text_sha256":"1de6f4e82c0da25b7b5f6fd8e3f2fdcfae04c814022ab75d844623a19634876a","x":2.566854953765869,"y":3.210235357284546},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000185","label":"Caldicellulosiruptor Two-Species Hydrogen Coculture","page":"communities/Caldicellulosiruptor_TwoSpecies_Hydrogen_Coculture.html","source_path":"kb/communities/Caldicellulosiruptor_TwoSpecies_Hydrogen_Coculture.yaml","text_sha256":"c397412b475a4d6ab4f5fedbcd2ba5f4c2e044317f29ae51f3f127fcce17d226","x":-1.718294382095337,"y":2.172290086746216},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000304","label":"Lunar and Martian Simulant PGPB Lettuce SynCom","page":"communities/Lunar_Martian_Simulant_PGPB_Lettuce_SynCom.html","source_path":"kb/communities/Lunar_Martian_Simulant_PGPB_Lettuce_SynCom.yaml","text_sha256":"22ab2e22f9a2256c511b9b9192f25c4be6a5a4f514b1803369a361996cb4604e","x":-3.4382903575897217,"y":-7.2675065994262695},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000222","label":"Sulfide Spring Autotrophic CPR-Hosting Biofilm","page":"communities/Sulfide_Spring_Autotrophic_CPR_Biofilm.html","source_path":"kb/communities/Sulfide_Spring_Autotrophic_CPR_Biofilm.yaml","text_sha256":"84a3ac94d9f995ec43245c86760c75894dccfa780eb0eb6747f2c1797e04b910","x":-3.3391470909118652,"y":-3.641453266143799},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000269","label":"Chlorella-Ecoli Mixotrophic Biofuel Precursor Coculture","page":"communities/Chlorella_Ecoli_Mixotrophic_Biofuel_Coculture.html","source_path":"kb/communities/Chlorella_Ecoli_Mixotrophic_Biofuel_Coculture.yaml","text_sha256":"4ab59d9f3417b8871f029b78b40ff5605b7a1929259a0d1f5bc610ab3f22884a","x":-1.264540195465088,"y":4.716289043426514},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000081","label":"Early Dental Biofilm Five-Species Model","page":"communities/Early_Dental_Biofilm_FiveSpecies.html","source_path":"kb/communities/Early_Dental_Biofilm_FiveSpecies.yaml","text_sha256":"554f23c91d45e94ec433cc3b5c470120f94232df1bc1d1dd41034b5fa9f3a4e8","x":2.4018189907073975,"y":5.210973262786865},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000287","label":"Electrostimulated Mixotrophic VFA-producing Enrichment Consortium","page":"communities/Electrostimulated_Mixotrophic_VFA_Producing_Enrichment_Consortium.html","source_path":"kb/communities/Electrostimulated_Mixotrophic_VFA_Producing_Enrichment_Consortium.yaml","text_sha256":"00b54f31a0330c71a07dadd0acfe4b07b85d69fe126299130926418aa335add6","x":-3.27608323097229,"y":-0.6373180150985718},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000364","label":"Sclerotinia Sclerotia 12-Strain Biocontrol SynCom","page":"communities/Sclerotinia_Sclerotia_12Strain_Biocontrol_SynCom.html","source_path":"kb/communities/Sclerotinia_Sclerotia_12Strain_Biocontrol_SynCom.yaml","text_sha256":"423f0ee4295770d0514ca4d8bbd20c5b3383e6b771c159e5319b1bc40646e2b1","x":4.457443714141846,"y":-0.805803656578064},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000144","label":"Altered Schaedler Flora Gnotobiotic Mouse Community","page":"communities/Altered_Schaedler_Flora_Gnotobiotic_Mouse_Community.html","source_path":"kb/communities/Altered_Schaedler_Flora_Gnotobiotic_Mouse_Community.yaml","text_sha256":"4a6cbe77a2414c506a82317b388200e84bfc6ac6953e1bc165faf7886cecb4cc","x":2.951843738555908,"y":3.810020685195923},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000375","label":"Maize SC2 Root-Rot Biocontrol SynCom","page":"communities/Maize_SC2_RootRot_Biocontrol_SynCom.html","source_path":"kb/communities/Maize_SC2_RootRot_Biocontrol_SynCom.yaml","text_sha256":"790b8fc15467416c1d711d7668a9bc00114327f1150b178029819d5a4b75cb16","x":4.386301040649414,"y":-1.842079520225525},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000093","label":"Arabidopsis Phyllosphere SynCom7","page":"communities/Arabidopsis_Phyllosphere_SynCom7.html","source_path":"kb/communities/Arabidopsis_Phyllosphere_SynCom7.yaml","text_sha256":"e840a0a707dd66ab9afe2b93379a37a858b7165966766eda104412ac6e723d2a","x":4.232011795043945,"y":-2.396761655807495},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000236","label":"Avena Rhizosphere Cross-Kingdom 13C-SIP Community","page":"communities/Avena_Rhizosphere_CrossKingdom_SIP_Community.html","source_path":"kb/communities/Avena_Rhizosphere_CrossKingdom_SIP_Community.yaml","text_sha256":"b4759837163b346d86d445eab04d05d1b72cb1f58eea1deeafaf7308693d3fad","x":1.9628806114196777,"y":-3.3750650882720947},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000263","label":"Saccharomyces-Acinetobacter Lignocellulose Hydrolysate Detoxification Coculture","page":"communities/Saccharomyces_Acinetobacter_Lignocellulose_Detox_Coculture.html","source_path":"kb/communities/Saccharomyces_Acinetobacter_Lignocellulose_Detox_Coculture.yaml","text_sha256":"aaf8b0d4fe27a144176fdff88b67f3dac2bac80a066a03f7ba90e5922e56c85c","x":-0.015718502923846245,"y":2.0424392223358154},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000197","label":"Methylocaldum-Cupriavidus Methane Acetate Cross-Feeding Coculture","page":"communities/Methylocaldum_Cupriavidus_Methane_Acetate_Crossfeeding_Coculture.html","source_path":"kb/communities/Methylocaldum_Cupriavidus_Methane_Acetate_Crossfeeding_Coculture.yaml","text_sha256":"c5f136484d814a33f94a5429fc7fef9682651ddad3a1c0efec0bc66a112e9d0f","x":-2.882148504257202,"y":2.895678758621216},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000012","label":"BioModels MODEL2405300001 Infant Gut HMO SynCom","page":"communities/BioModels_MODEL2405300001_Infant_Gut_HMO_SynCom.html","source_path":"kb/communities/BioModels_MODEL2405300001_Infant_Gut_HMO_SynCom.yaml","text_sha256":"456f73316251e55ef04b1db493332d41134546937fb4809fe64ffa7ef6777c7e","x":2.582770586013794,"y":4.039132595062256},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000176","label":"ORNL Clostridium-Desulfovibrio-Geobacter Trophic Model Community","page":"communities/ORNL_Clostridium_Desulfovibrio_Geobacter_Trophic_Model.html","source_path":"kb/communities/ORNL_Clostridium_Desulfovibrio_Geobacter_Trophic_Model.yaml","text_sha256":"3200c829efc23e8857e697cdc20dc30af1fd275308bd57c99d8d55e667c1059e","x":-2.3075997829437256,"y":0.4073981046676636},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000289","label":"Pseudomonas putida Pp-TE + Rhodococcus sp. RDK17 Terephthalic-acid Consortium","page":"communities/Pseudomonas_putida_PpTE_Rhodococcus_RDK17_Terephthalic_Acid_Consortium.html","source_path":"kb/communities/Pseudomonas_putida_PpTE_Rhodococcus_RDK17_Terephthalic_Acid_Consortium.yaml","text_sha256":"99ac61ae2b37da1270964a3ea86fa1d5f96885aef41a5caefe1feaeb7e951909","x":-0.12319472432136536,"y":-0.22636571526527405},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000126","label":"N-Cycle Bioflocculation Model Consortium","page":"communities/NCycle_Bioflocculation_Model_Consortium.html","source_path":"kb/communities/NCycle_Bioflocculation_Model_Consortium.yaml","text_sha256":"8c0c708e32508861793df933b30b6c1716a87a6077cbee567d88d87bb80df118","x":-1.322421908378601,"y":-2.358081102371216},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000306","label":"Lunar Regolith Simulant Phosphorus-Solubilizing Bacteria for Nicotiana benthamiana","page":"communities/Lunar_Simulant_Phosphate_Solubilizing_Bacteria_Nicotiana.html","source_path":"kb/communities/Lunar_Simulant_Phosphate_Solubilizing_Bacteria_Nicotiana.yaml","text_sha256":"0f7d440b39e05ec304ac01716db500d68854e57cb03bc9128afee58f4c7bc83d","x":-3.4186928272247314,"y":-7.276150226593018},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000318","label":"Bifidobacterium breve-Trichomonas vaginalis Vaginal Co-culture","page":"communities/Bifidobacterium_Trichomonas_Vaginal_Coculture.html","source_path":"kb/communities/Bifidobacterium_Trichomonas_Vaginal_Coculture.yaml","text_sha256":"037265609456a50de02d02d596ed5b36eea44070efe52d76715fba42f9bc0899","x":2.92924427986145,"y":3.5738306045532227},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000028","label":"GLBRC Populus Variovorax SynCom28","page":"communities/GLBRC_Populus_Variovorax_SynCom28.html","source_path":"kb/communities/GLBRC_Populus_Variovorax_SynCom28.yaml","text_sha256":"7883652605addf6a9b8ac5e69eee55002adf967f64ec741f53017159c4765da1","x":2.6867096424102783,"y":-2.6041109561920166},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000374","label":"Achromobacter-Enterobacter SL8-SL12 Cadmium Immobilization Coculture","page":"communities/Achromobacter_Enterobacter_SL8_SL12_Cadmium_Immobilization_Coculture.html","source_path":"kb/communities/Achromobacter_Enterobacter_SL8_SL12_Cadmium_Immobilization_Coculture.yaml","text_sha256":"8025f36043872167edfec079da3adfca06cfad4a27625711e0f2b7eb8e49cf90","x":-1.807790994644165,"y":-2.248044729232788},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000173","label":"Acetobacterium woodii-Clostridium drakei CO2 Electrolysis Coculture","page":"communities/Acetobacterium_Clostridium_CO2_Electrolysis_Coculture.html","source_path":"kb/communities/Acetobacterium_Clostridium_CO2_Electrolysis_Coculture.yaml","text_sha256":"d2a5886afb025c6989551c81e9e3ec17c617d03aeb96fa0351273b6e71513c58","x":-2.4402096271514893,"y":2.2676687240600586},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000314","label":"SynCom ARC Peanut Aflatoxin-Control and Nodulation-Coupling Community","page":"communities/SynCom_ARC_Peanut_Aflatoxin_Nodulation.html","source_path":"kb/communities/SynCom_ARC_Peanut_Aflatoxin_Nodulation.yaml","text_sha256":"f8b8758ffbcb2d5ff126c1067c626f0afaa74ab78eb611d458c6144cd126a16f","x":5.06695556640625,"y":-1.2149674892425537},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000360","label":"Wolffia Mankai Endosphere Cobamide Guild","page":"communities/Wolffia_Mankai_Endosphere_Cobamide_Guild.html","source_path":"kb/communities/Wolffia_Mankai_Endosphere_Cobamide_Guild.yaml","text_sha256":"dcd8a6ef1420a2033186b8629ff9a6b731d2d8259aa568092dfc163a2a419371","x":1.4535413980484009,"y":-2.6705260276794434},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000041","label":"MAMC-M48 Lignocellulose-Degrading Consortium","page":"communities/MAMC_M48_Lignocellulose.html","source_path":"kb/communities/MAMC_M48_Lignocellulose.yaml","text_sha256":"b8b73685597a4a98645ec63f2d53e62193ad31c1f4c5eab461a08e265053431b","x":0.09893161058425903,"y":0.89271080493927},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000114","label":"Shewanella Denitrifying Richness SynComs","page":"communities/Shewanella_Denitrifying_Richness_SynComs.html","source_path":"kb/communities/Shewanella_Denitrifying_Richness_SynComs.yaml","text_sha256":"3edce51ff9ec3098cb62d4ab6c42b1274580c9d4ea4a052a3adc23c3eade1007","x":-0.9915839433670044,"y":-2.0393049716949463},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000010","label":"BioModels MODEL2209060002 D pigrum - S aureus Community","page":"communities/BioModels_MODEL2209060002_DPigrum_SAureus_Community.html","source_path":"kb/communities/BioModels_MODEL2209060002_DPigrum_SAureus_Community.yaml","text_sha256":"5ae0f4193fdf0e1fbcbae22a9fce0c278cc3066ab8115e18530b065b5ecbb0e7","x":2.0774335861206055,"y":4.992537975311279},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000031","label":"Geobacter-Clostridium Interspecies Electron Transfer Coculture","page":"communities/Geobacter_Clostridium_Interspecies_Electron_Transfer_Coculture.html","source_path":"kb/communities/Geobacter_Clostridium_Interspecies_Electron_Transfer_Coculture.yaml","text_sha256":"b5526d482b7411684b28e5e528172e2157554140785bd433e55d4da2720fe436","x":-3.263092041015625,"y":-0.6166970133781433},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000067","label":"Synechococcus-Saccharomyces Synthetic Photosynthetic Consortium","page":"communities/Synechococcus_Saccharomyces_SPC.html","source_path":"kb/communities/Synechococcus_Saccharomyces_SPC.yaml","text_sha256":"678f377f1b8769dffae48b3750be38d5c0211815fc3f5a4ee4d6489ffa354cb5","x":-1.999376654624939,"y":5.98422908782959},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000260","label":"Mushroom Spring Hot-Spring Phototrophic Mat Community","page":"communities/Mushroom_Spring_Hot_Spring_Phototrophic_Mat_Community.html","source_path":"kb/communities/Mushroom_Spring_Hot_Spring_Phototrophic_Mat_Community.yaml","text_sha256":"c76524abcc4ca71e8330c1869c5aa1f0288bfe17d3dd46d04c9a2680f5aeee5f","x":-3.897305965423584,"y":-3.472539186477661},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000161","label":"Pseudomonas-Pedobacter Social Spreading Coculture","page":"communities/Pseudomonas_Pedobacter_Social_Spreading_Coculture.html","source_path":"kb/communities/Pseudomonas_Pedobacter_Social_Spreading_Coculture.yaml","text_sha256":"d114e4c15b40fd11e0acd44b892c1337bf04c976361d50eb138381b5bdfc8769","x":2.5409657955169678,"y":4.529335975646973},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000172","label":"Clostridium autoethanogenum-Clostridium kluyveri Syngas Coculture","page":"communities/Clostridium_Autoethanogenum_Kluyveri_Syngas_Coculture.html","source_path":"kb/communities/Clostridium_Autoethanogenum_Kluyveri_Syngas_Coculture.yaml","text_sha256":"f5338a853f140e61b094c2c08909c5ce42edccbd4879c88624673ed0cb32e5b9","x":-2.3052315711975098,"y":2.539637327194214},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000205","label":"Trichoderma-E. coli Cellulosic Isobutanol Coculture","page":"communities/Trichoderma_Ecoli_Cellulosic_Isobutanol_Coculture.html","source_path":"kb/communities/Trichoderma_Ecoli_Cellulosic_Isobutanol_Coculture.yaml","text_sha256":"1efda448d74d9c95131ce5095e4bfeac8a5fee187214b90bbf910ea6c512cd44","x":-0.23416543006896973,"y":2.1174697875976562},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000110","label":"Rice Phosphorus Uptake Intercropping SynCom4","page":"communities/Rice_P_Uptake_Intercropping_SynCom4.html","source_path":"kb/communities/Rice_P_Uptake_Intercropping_SynCom4.yaml","text_sha256":"b810c5d837288f7a7345a0f6a9c35d14dbe9f671677281d44aa1b90a6bd0f9c1","x":4.271810054779053,"y":-2.2848312854766846},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000267","label":"Sphingobium-Rhodococcus Lignin-Dimer Valorization Coculture","page":"communities/Sphingobium_Rhodococcus_Lignin_Dimer_Valorization_Coculture.html","source_path":"kb/communities/Sphingobium_Rhodococcus_Lignin_Dimer_Valorization_Coculture.yaml","text_sha256":"780b402cfe51f63c6b849d9ae6293be51bac87d234e95982abc602a94d6af6a7","x":-0.5609908103942871,"y":1.2783502340316772},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000226","label":"Lac Pavin Permanently Stratified Lake Community","page":"communities/Lac_Pavin_Stratified_Lake_Community.html","source_path":"kb/communities/Lac_Pavin_Stratified_Lake_Community.yaml","text_sha256":"e7f9d81b93a812dfe6c313c4504a995890484a560bb807baca7311eacab07e08","x":-3.3220911026000977,"y":-2.9958901405334473},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000054","label":"Phormidium Alkaline Consortium","page":"communities/Phormidium_Alkaline_Consortium.html","source_path":"kb/communities/Phormidium_Alkaline_Consortium.yaml","text_sha256":"f2ae6d8b014a9e78cdb5753e8c0d003ed1abd20352188162d031524a4cfeace5","x":-1.7940700054168701,"y":5.421578884124756},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000088","label":"LBNL Brachypodium Drought SynCom15","page":"communities/LBNL_Brachypodium_Drought_SynCom15.html","source_path":"kb/communities/LBNL_Brachypodium_Drought_SynCom15.yaml","text_sha256":"2087eca7e0a3dd51245d6ab72deec6626808de59c9870b3ecc272bbad76060d2","x":3.456050395965576,"y":-2.66764497756958},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000049","label":"PGM Spent Catalyst Bioleaching Consortium","page":"communities/PGM_Spent_Catalyst_Bioleaching.html","source_path":"kb/communities/PGM_Spent_Catalyst_Bioleaching.yaml","text_sha256":"a58dc125340a17901069d0802adbb49dd78f7cd5514fc4c4a52c83b5001d7b81","x":-4.122527122497559,"y":-5.796470642089844},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000241","label":"Rifle Aquifer Bioanode Extracellular Electron Transfer Community","page":"communities/Rifle_Aquifer_Bioanode_EET_Community.html","source_path":"kb/communities/Rifle_Aquifer_Bioanode_EET_Community.yaml","text_sha256":"8edd6fe61881f1be9a2e877ed602e93fd96169cb14efdc7e6c82453bc44dd7b1","x":-2.997509479522705,"y":-2.3991923332214355},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000018","label":"Cinnamate β-Oxidation Consortium","page":"communities/Cinnamate_Degradation_Consortium.html","source_path":"kb/communities/Cinnamate_Degradation_Consortium.yaml","text_sha256":"3bd608fc41ce995d05aaddcdc2164b33701e2a268ade75f69203d77a05b927cc","x":-4.675424575805664,"y":0.921583354473114},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000060","label":"Rifle Uranium-Reducing Community","page":"communities/Rifle_Uranium_Reducing_Community.html","source_path":"kb/communities/Rifle_Uranium_Reducing_Community.yaml","text_sha256":"05d39925552f20a5ff0315d508e1d0b8b6e1bec0a20f96c3fc35c6806924ca4e","x":-2.7276358604431152,"y":-3.664438247680664},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000170","label":"Methylotuvimicrobium-Synechococcus Gas Feedstock Coculture","page":"communities/Methylotuvimicrobium_Synechococcus_Gas_Feedstock_Coculture.html","source_path":"kb/communities/Methylotuvimicrobium_Synechococcus_Gas_Feedstock_Coculture.yaml","text_sha256":"04ce0cbe529a13475a91b5ade1e08cd26c7930c3627077c374acc9c6c38282dc","x":-2.251159191131592,"y":4.660420894622803},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000083","label":"Streptococcus mutans - Candida albicans ECC Biofilm Model","page":"communities/SMutans_CAlbicans_ECC_Biofilm.html","source_path":"kb/communities/SMutans_CAlbicans_ECC_Biofilm.yaml","text_sha256":"36f5d2727dcaa5aedcea302e3f29deb3133f9a4c0d05f43945285c5dfcc7703d","x":2.5666861534118652,"y":5.199058532714844},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000208","label":"Clostridium Thermocellum-Saccharoperbutylacetonicum Cellulosic Butanol Coculture","page":"communities/Clostridium_Thermocellum_Saccharoperbutylacetonicum_Cellulosic_Butanol_Coculture.html","source_path":"kb/communities/Clostridium_Thermocellum_Saccharoperbutylacetonicum_Cellulosic_Butanol_Coculture.yaml","text_sha256":"93ad4d795d00680f792371f6ecd6a57d3e22759b604e5130361b3e5df160ea01","x":-1.3385446071624756,"y":2.3130698204040527},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000050","label":"PMI Variovorax Thermotolerance Collection","page":"communities/PMI_Variovorax_Thermotolerance_Collection.html","source_path":"kb/communities/PMI_Variovorax_Thermotolerance_Collection.yaml","text_sha256":"3f0f958dba81069657a1c6885d9c4f82eab74fd478622b41fe2aea5c01d37124","x":3.8950090408325195,"y":-2.6218783855438232},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000206","label":"Clostridium-Saccharomyces Cellulose Ethanol Coculture","page":"communities/Clostridium_Saccharomyces_Cellulose_Ethanol_Coculture.html","source_path":"kb/communities/Clostridium_Saccharomyces_Cellulose_Ethanol_Coculture.yaml","text_sha256":"0f58e434ca0d6c03e468de47e9e6d0edd0279f05957162211b523f980515a5bc","x":-1.1212124824523926,"y":2.317575216293335},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000209","label":"Dehalococcoides-Methanosarcina DMB-Guided Cobalamin Coculture","page":"communities/Dehalococcoides_Methanosarcina_DMB_Cobalamin_Coculture.html","source_path":"kb/communities/Dehalococcoides_Methanosarcina_DMB_Cobalamin_Coculture.yaml","text_sha256":"20e34c5a5c69d87bed4917b6c0803b3f452d0cc1783c3562dc3ce4e5dc3f364b","x":-1.8732410669326782,"y":-0.23843298852443695},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000039","label":"KBase Synthetic Bacterial Community in R2A Medium","page":"communities/KBase_Synthetic_Bacterial_Community_R2A.html","source_path":"kb/communities/KBase_Synthetic_Bacterial_Community_R2A.yaml","text_sha256":"7e6d9b69d86ea84c62a4746c75d3d8fd408b48a3b41673cd11b76ecc16bccb2b","x":2.339444160461426,"y":-1.8471851348876953},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000341","label":"Priestia-Pseudomonas Rice Arsenic-Stress SynCom","page":"communities/Priestia_Pseudomonas_Rice_Arsenic_Stress_SynCom.html","source_path":"kb/communities/Priestia_Pseudomonas_Rice_Arsenic_Stress_SynCom.yaml","text_sha256":"6ef9b4045bde9a6b21d22fe7d8e99fa35915615c2536dba179fa8fe2669440fd","x":4.365429401397705,"y":-2.3438289165496826},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000168","label":"Clostridium-Thermoanaerobacter Cellulosic Bioethanol Coculture","page":"communities/Clostridium_Thermoanaerobacter_Cellulosic_Bioethanol_Coculture.html","source_path":"kb/communities/Clostridium_Thermoanaerobacter_Cellulosic_Bioethanol_Coculture.yaml","text_sha256":"c1f266369fc18d7bf634d428bfde9663a17b1ea30908ff8282413c51cfee7d54","x":-1.5423380136489868,"y":2.2620410919189453},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000053","label":"Phenol Carboxylation Consortium","page":"communities/Phenol_Carboxylation_Consortium.html","source_path":"kb/communities/Phenol_Carboxylation_Consortium.yaml","text_sha256":"889365a4328498620b92820369c568f1e1e9c4a95dc8883c55d350aa5c6f6069","x":-4.4496893882751465,"y":1.2652981281280518},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000246","label":"South Bay Salt Pond Methane Restoration Microbial Community","page":"communities/South_Bay_Salt_Pond_Methane_Restoration_Community.html","source_path":"kb/communities/South_Bay_Salt_Pond_Methane_Restoration_Community.yaml","text_sha256":"8b288d3e2b57c39c87f737033c061739428eed6bd23444b482cd56f257a44233","x":-4.037392616271973,"y":-2.9343554973602295},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000343","label":"Komagataella-E. coli Co-inducible Biosynthesis Coculture","page":"communities/Komagataella_Ecoli_Coinducible_Biosynthesis_Coculture.html","source_path":"kb/communities/Komagataella_Ecoli_Coinducible_Biosynthesis_Coculture.yaml","text_sha256":"c4624d99950936c9282a96670c4f1043cf98b59752ba03fd90aa42c51184bc1a","x":0.3466097116470337,"y":2.83628511428833},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000148","label":"Buchnera-Serratia Cinara cedri Endosymbiont Consortium","page":"communities/Buchnera_Serratia_Cinara_Cedri_Endosymbiont_Consortium.html","source_path":"kb/communities/Buchnera_Serratia_Cinara_Cedri_Endosymbiont_Consortium.yaml","text_sha256":"dfdfca5f38e83f25adb110340fc328770d2d37497697a2647f0a49f9adb96db8","x":0.42514878511428833,"y":5.06350564956665},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000332","label":"Kefir Flavor Lentilactobacillus-Kluyveromyces Coculture","page":"communities/Kefir_Flavor_Lentilactobacillus_Kluyveromyces_Coculture.html","source_path":"kb/communities/Kefir_Flavor_Lentilactobacillus_Kluyveromyces_Coculture.yaml","text_sha256":"e5a5f79d1a22ec4b976135708223c7e39cbb9589374fe683ee39d918791e08f6","x":0.9586912393569946,"y":2.8440585136413574},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000033","label":"Geobacter-Methanosarcina DIET Community","page":"communities/Geobacter_Methanosarcina_DIET.html","source_path":"kb/communities/Geobacter_Methanosarcina_DIET.yaml","text_sha256":"2fc6c5c49f7e847d340a17d394941ea43bc93bc7d1b8b661478e1f4623de0b53","x":-3.5622122287750244,"y":-0.6226912140846252},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000047","label":"ORNL PMI Populus PD10 SynCom","page":"communities/ORNL_PMI_Populus_PD10_SynCom.html","source_path":"kb/communities/ORNL_PMI_Populus_PD10_SynCom.yaml","text_sha256":"7c10d8bca8e6093e4f2aff4153da2865ff8811ca8207d95257ea78b8c3d66015","x":3.4963433742523193,"y":-2.35148024559021},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000112","label":"Tribromophenol Anaerobic Bioremediation SynCom","page":"communities/Tribromophenol_Anaerobic_Bioremediation_SynCom.html","source_path":"kb/communities/Tribromophenol_Anaerobic_Bioremediation_SynCom.yaml","text_sha256":"5522e4d8257bc55226aa95114416f032cb24faeeec29013c4512ac3259c71dda","x":-2.157504081726074,"y":-0.008533160202205181},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000261","label":"Lake Washington Methane-Oxygen Methylotroph Community","page":"communities/Lake_Washington_Methane_Oxygen_Methylotroph_Community.html","source_path":"kb/communities/Lake_Washington_Methane_Oxygen_Methylotroph_Community.yaml","text_sha256":"17ed6d56e533e28ddc4af0a307385ae58dd6930f71b61bc319d9b3d159edf737","x":-3.734405040740967,"y":-2.728146553039551},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000301","label":"Dehalococcoides mccartyi CWV2 Dechlorinating Consortium","page":"communities/Dehalococcoides_mccartyi_CWV2_Dechlorinating_Consortium.html","source_path":"kb/communities/Dehalococcoides_mccartyi_CWV2_Dechlorinating_Consortium.yaml","text_sha256":"7dd60eaebf302bd36d3636755b7494fb83241d388fe28eb9ef2da6327ad3338b","x":-1.8295767307281494,"y":-0.925062894821167},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000198","label":"Synechococcus-Halomonas Light-Driven PHB Coculture","page":"communities/Synechococcus_Halomonas_Light_Driven_PHB_Coculture.html","source_path":"kb/communities/Synechococcus_Halomonas_Light_Driven_PHB_Coculture.yaml","text_sha256":"39159234e16c185af49322b38ae3c8eab40553cff57b87060bf4be3fa4cc48e6","x":-1.9927095174789429,"y":5.834944725036621}] diff --git a/data/text_map/current.json b/data/text_map/current.json new file mode 100644 index 000000000..674a46811 --- /dev/null +++ b/data/text_map/current.json @@ -0,0 +1 @@ +{"bundle":"87d6340fedc2bed70566164552a00f66a992271b5fc029e3761241c1734e93bc","manifest_sha256":"c2e08f67b70e16f6bc8fcef098fe22cab6cec29fc0c40aad42974b50da0c783e"} diff --git a/docs/TEXT_MAP_INPUTS.md b/docs/TEXT_MAP_INPUTS.md index 10b87829c..aa21b5757 100644 --- a/docs/TEXT_MAP_INPUTS.md +++ b/docs/TEXT_MAP_INPUTS.md @@ -20,3 +20,27 @@ This repository publishes the contents of `docs/`, so the bundle is staged at Isolate detail pages are published in `docs/isolates/` by `just gen-html`; the community browser and graph population remain communities only. + + +## Publish the common semantic view + +`conf/text_map.yaml` is explicitly disabled until a reviewed full-input bundle +exists at `data/text_map/current.json` and the canonical CLAW runtime is vendored +at `scripts/embedding_pipeline.py`. Enablement requires the pinned fleet BGE +model, revision, dimension and 512-token window, actual PaCMAP, valid checksums, +and fresh complete adapter inputs. Missing or stale enabled inputs fail loudly. + +`just stage-text-map` validates and stages the three public files at +`docs/text-map/` without inference. It binds the exact immutable generation +approved by preflight, refusing pointer changes or manifest substitution before +publication. The Pages workflow performs the same validation before uploading +`docs/`; a standalone stage does not regenerate existing browser pages. + +The shared text map complements the existing domain graph views. Record URLs +are relative to `docs/`, so the shared map's `../` link prefix resolves to the +existing browser/detail routes. No legacy graph vector or model artifact is +relabeled as BGE. + +After enabling the map, run `just gen-html` to regenerate the landing/browser +links and per-record pages. Its renderer preflights the full bundle before +writing pages; normal checks use the same path. diff --git a/docs/browser.html b/docs/browser.html index 7d58a0ccb..88ffde9eb 100644 --- a/docs/browser.html +++ b/docs/browser.html @@ -495,6 +495,7 @@
← Home +

Semantic text map

CommunityMech

Microbial Community Knowledge Base

@@ -597,7 +598,7 @@

Metal Relevance

diff --git a/docs/index.html b/docs/index.html index 9fe2d3f60..f328b2278 100644 --- a/docs/index.html +++ b/docs/index.html @@ -76,10 +76,11 @@

CommunityMech

Microbial community knowledge base — curated, evidence-backed interaction networks.

+

Semantic text map

@@ -90,7 +91,7 @@

Record browser

Faceted browser of microbial communities — filter by category, ecological state, metals, and rare-earth elements.

- +

Embedding browser

Interactive PaCMAP of community embedding space from taxonomic composition.

diff --git a/docs/text-map/index.html b/docs/text-map/index.html new file mode 100644 index 000000000..c9b1e390b --- /dev/null +++ b/docs/text-map/index.html @@ -0,0 +1,41 @@ + + +communitymech semantic text map + +

communitymech semantic text map

Showing 372 of 372 input records. +PaCMAP positions summarize similarity between record descriptions.

+ +

Select a point to open its record.

+ +

    +

    Map provenance and coverage

    + + \ No newline at end of file diff --git a/docs/text-map/manifest.json b/docs/text-map/manifest.json new file mode 100644 index 000000000..d4757c8b4 --- /dev/null +++ b/docs/text-map/manifest.json @@ -0,0 +1 @@ +{"coverage":{"displayed":372,"eligible":372,"maximum":50000,"omitted":0,"selection":"bottom-k-sha256(seed,identifier)","total":372},"encoder":{"dimension":1024,"dtype":"float32-le","format_version":1,"inference_device":"mps:0","library_versions":{"numpy":"2.3.5","sentence-transformers":"6.0.0","tokenizers":"0.23.2","torch":"2.14.0","transformers":"5.17.0"},"max_seq_length":512,"model":"BAAI/bge-large-en-v1.5","normalized":true,"pooling":"sentence-transformers-model","query_instruction":null,"revision":"d4aa6901d3a41ba39fb536a557fa166f842b0e09","truncation":"tail","weight_dtype":"torch.float32"},"encoder_profile_sha256":"3346a4c533aeac55dfcf54b6c4f3fb74e22f3ad4682c53f5215b539ac5ba0627","files":{"index.html":"ff21002c80d803d28295b946e8a3cbe6706083c4ece6c49371cfa63a2cae9978","points.json":"30c98b2a63ac00e49705058581acf699b85ab3a7b912a33aef3336c9330a9b62"},"format_version":1,"generated_at_utc":"2026-09-15T01:15:56.769129+00:00","inputs":{"adapter_version":"communitymech-semantic-v1","categories":{"AMD":7,"BIOMINING":13,"BIOREMEDIATION":53,"BIOTECHNOLOGY":64,"CARBON_SEQUESTRATION":12,"DIET":7,"EXTREME_ENVIRONMENT":15,"LIGNOCELLULOSE":31,"METAL_REDUCTION":3,"METHANOGENESIS":14,"ORAL":5,"OTHER":38,"PHYTOPLANKTON":14,"RHIZOSPHERE":64,"SYNTROPHY":32},"corpus_sha256":"ca0b9e902e0e62b04efd56d339e743a2290737890961e6f146770a522f32bf92","count":372,"input_sha256":"ac00a842989e6d6debb8bac51c41632f855f93bd8d3ec58d6f88d72cd8ff523b","records_sha256":"6ecf47bdd7b6b3fdd523d83c6788348284bcbb6c6d517d0d5350e4cc7c1e9dd1"},"projection":{"FP_ratio":2.0,"MN_ratio":0.5,"apply_pca":true,"dimensions":2,"distance":"euclidean","effective_pairs":{"further":30,"mid_near":8,"neighbors":15},"implementation":"pacmap.PaCMAP","initialization":"pca","iterations":[100,100,250],"knn_backend":"faiss","learning_rate":1.0,"library_versions":{"faiss-cpu":"1.15.0","numba":"0.63.1","numpy":"2.3.5","pacmap":"0.9.1","scikit-learn":"1.8.0"},"method":"pacmap","neighbors":15,"requested_neighbors":15,"seed":42},"representation":"semantic-text","source_vectors":{"dtype":"float32-le","order":"points.json","sha256":"393f2b6037fca355d4cf7609fb134170e40118d8cc183c8157abba14846c334a","shape":[372,1024],"storage":"local-profile-bound-cache"}} diff --git a/docs/text-map/points.json b/docs/text-map/points.json new file mode 100644 index 000000000..81bece12c --- /dev/null +++ b/docs/text-map/points.json @@ -0,0 +1 @@ +[{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000253","label":"Premature Infant Gut Escherichia In-Situ Physiological-Condition Community","page":"communities/Premature_Infant_Gut_Escherichia_Diametric_Ratio_Community.html","source_path":"kb/communities/Premature_Infant_Gut_Escherichia_Diametric_Ratio_Community.yaml","text_sha256":"67205c25d3f4d1ed9fc4ceaceda915c5d9e30d3fa443c244d0434f28b01218d7","x":3.2307217121124268,"y":3.371659755706787},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000181","label":"Pseudomonas-Rhodococcus Chloronitrobenzene Coculture","page":"communities/Pseudomonas_Rhodococcus_Chloronitrobenzene_Coculture.html","source_path":"kb/communities/Pseudomonas_Rhodococcus_Chloronitrobenzene_Coculture.yaml","text_sha256":"da78170c9066bedd392987d83cadefaa13688bddb593c5060ae787db04575da0","x":-0.6078157424926758,"y":-0.48021653294563293},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000238","label":"Acetylene-Fueled Trichloroethene Dechlorination Groundwater Enrichment","page":"communities/Acetylene_Fueled_TCE_Dechlorination_Groundwater_Enrichment.html","source_path":"kb/communities/Acetylene_Fueled_TCE_Dechlorination_Groundwater_Enrichment.yaml","text_sha256":"d41977e75e3e07b84497035cb5110cc454c24592b390e7b2dc54d06b49fb78ec","x":-1.9608172178268433,"y":-1.3322618007659912},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000283","label":"Sesame-flavor Baijiu Fuqu SynCom (13-genus)","page":"communities/SynCom_Sesame_Flavor_Baijiu_Fuqu_13Genus.html","source_path":"kb/communities/SynCom_Sesame_Flavor_Baijiu_Fuqu_13Genus.yaml","text_sha256":"39996efb04ee9ee66173d1c46e19a8066a10815e6cc437e9df4d864477ae8dc4","x":2.9754321575164795,"y":0.8567348122596741},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000174","label":"Clostridium cellulovorans-Methanosarcina barkeri Cellulose Methane Coculture","page":"communities/Clostridium_Cellulovorans_Methanosarcina_Cellulose_Methane_Coculture.html","source_path":"kb/communities/Clostridium_Cellulovorans_Methanosarcina_Cellulose_Methane_Coculture.yaml","text_sha256":"71d4ac19aa9dcb05b870a19ca32fbe2938935b01a2046a3396b0b34bb37766cf","x":-2.175126314163208,"y":1.9358447790145874},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000302","label":"SynCom MetG2 Rhizobacteria Sugarcane Stress Resilience","page":"communities/SynCom_MetG2_Rhizobacteria_Sugarcane_Stress_Resilience.html","source_path":"kb/communities/SynCom_MetG2_Rhizobacteria_Sugarcane_Stress_Resilience.yaml","text_sha256":"b5d97fa90a128e64006f6799ef58106b80a64a78a24457c191b7d20cb29e63a1","x":4.068554878234863,"y":-2.5681259632110596},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000169","label":"Methylocaldum-Methyloceanibacter Methane Cross-Feeding Coculture","page":"communities/Methylocaldum_Methyloceanibacter_Methane_Crossfeeding_Coculture.html","source_path":"kb/communities/Methylocaldum_Methyloceanibacter_Methane_Crossfeeding_Coculture.yaml","text_sha256":"6ce03369bea38101c0b97778938d42253de2c660ab873389d203b23e69f9c750","x":-3.331669330596924,"y":2.5319433212280273},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000121","label":"Methane Oxidation-Cr(VI) Reduction SynCom","page":"communities/Methane_Oxidation_CrVI_Reduction_SynCom.html","source_path":"kb/communities/Methane_Oxidation_CrVI_Reduction_SynCom.yaml","text_sha256":"dd57711476dd0625d34c721f17adb84f7d82cb6cdd18d7d0682a153b6d59bd10","x":-2.6406538486480713,"y":2.756192207336426},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000002","label":"AMD Nitrososphaerota Archaeal Community","page":"communities/AMD_Nitrososphaerota_Archaeal.html","source_path":"kb/communities/AMD_Nitrososphaerota_Archaeal.yaml","text_sha256":"0266d839420377de9eb37ce08a6d9dbfdb9ac90b4a32be489d267c7aa7de9f16","x":-3.63478684425354,"y":-4.350777626037598},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000313","label":"Chlorella fusca CHK0059 Keystone-Taxa Antifungal SynCom","page":"communities/Chlorella_Keystone_Taxa_Antifungal_SynCom.html","source_path":"kb/communities/Chlorella_Keystone_Taxa_Antifungal_SynCom.yaml","text_sha256":"e907346f4566c3c9b63a260e3a204cfb6bc40f63f8593d4dff16b90015a029d6","x":3.533454656600952,"y":-0.9772730469703674},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000116","label":"Aerobic Denitrification Disturbance-Stable SynCom","page":"communities/Aerobic_Denitrification_Disturbance_SynCom.html","source_path":"kb/communities/Aerobic_Denitrification_Disturbance_SynCom.yaml","text_sha256":"4429fce85132bd50dbb5a35d3bb739b1194e4f583fae5c9734f1d2b09f3ac2d8","x":-0.8535351157188416,"y":-2.381023406982422},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000003","label":"At-RSPHERE SynCom","page":"communities/At_RSPHERE_SynCom.html","source_path":"kb/communities/At_RSPHERE_SynCom.yaml","text_sha256":"f8f2c5ae7b4c27c001f44aa0708eeb8e2bc9b1b8f57924ea983c38b328fd2eb9","x":3.5365118980407715,"y":-2.551745891571045},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000319","label":"SPRUCE Peatland Warming Microbial Community","page":"communities/SPRUCE_Peatland_Warming_Community.html","source_path":"kb/communities/SPRUCE_Peatland_Warming_Community.yaml","text_sha256":"8f405c1c09e76fff325d91645f7745b75e82f71c5d51ad0ba69c078b80fa7530","x":-4.0151801109313965,"y":-2.9973788261413574},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000251","label":"Subsurface Carboxydocella CO-Oxidation Aquifer Community","page":"communities/Subsurface_Carboxydocella_CO_Aquifer_Community.html","source_path":"kb/communities/Subsurface_Carboxydocella_CO_Aquifer_Community.yaml","text_sha256":"aa201a4a9a0e260c15823139a1b95d6d980f435838030fe55c921d758e95d7ef","x":-2.9535534381866455,"y":-3.2350423336029053},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000240","label":"Infant Gut Strain Persistence and Maternal Seeding Community","page":"communities/Infant_Gut_Strain_Persistence_Maternal_Community.html","source_path":"kb/communities/Infant_Gut_Strain_Persistence_Maternal_Community.yaml","text_sha256":"69ada16b99d71051db33e1ba53cdb2873d4c8f7784963e4c31f496bc782bc2fe","x":3.457515239715576,"y":3.5661487579345703},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000162","label":"Thalassiosira-Ruegeria Phycosphere Coculture","page":"communities/Thalassiosira_Ruegeria_Phycosphere_Coculture.html","source_path":"kb/communities/Thalassiosira_Ruegeria_Phycosphere_Coculture.yaml","text_sha256":"58d82a0f05604caf169784ed48e6e508e81fbb5d296486e2f4c7c8714fa7a9a4","x":-0.6132818460464478,"y":5.59945821762085},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000266","label":"Clostridium carboxidivorans-Clostridium kluyveri CO Chain-Elongation Coculture","page":"communities/Clostridium_Carboxidivorans_Kluyveri_CO_Chain_Elongation_Coculture.html","source_path":"kb/communities/Clostridium_Carboxidivorans_Kluyveri_CO_Chain_Elongation_Coculture.yaml","text_sha256":"8a93981ea60f6d1582ce4ed22917b327a0538e51e616deaf54ccda6c119b27e8","x":-1.8884721994400024,"y":2.389552354812622},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000350","label":"High-Ammonia Biogas 0B Butyrate-Oxidizing Enrichment","page":"communities/High_Ammonia_Biogas_0B_Butyrate_Oxidizing_Enrichment.html","source_path":"kb/communities/High_Ammonia_Biogas_0B_Butyrate_Oxidizing_Enrichment.yaml","text_sha256":"f3a053df91503cdfeb77e8f71788ea035d5f8527ec1e2c21b80548fd7092381e","x":-4.235561370849609,"y":0.754021942615509},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000202","label":"Clostridium ljungdahlii-Clostridium kluyveri Syngas Alcohol Coculture","page":"communities/Clostridium_Ljungdahlii_Kluyveri_Syngas_Alcohol_Coculture.html","source_path":"kb/communities/Clostridium_Ljungdahlii_Kluyveri_Syngas_Alcohol_Coculture.yaml","text_sha256":"d7c6e260da2271153a2b83c42ab8635f916f1ebadf74334aa869fbc9ad121ec5","x":-2.004319429397583,"y":2.382392406463623},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000158","label":"Bacteroides-Eubacterium Gnotobiotic Gut Model","page":"communities/Bacteroides_Eubacterium_Gnotobiotic_Gut_Model.html","source_path":"kb/communities/Bacteroides_Eubacterium_Gnotobiotic_Gut_Model.yaml","text_sha256":"30dc825ae57ac2fc4c62fb1f0ed57fc97aecb9f4cc24f72f7adad4cd7bbc38a2","x":2.976564645767212,"y":3.741856813430786},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000244","label":"Anammox Bioreactor DNRA Destabilization Community","page":"communities/Anammox_Bioreactor_DNRA_Destabilization_Community.html","source_path":"kb/communities/Anammox_Bioreactor_DNRA_Destabilization_Community.yaml","text_sha256":"fa1f8c01b97375d5085a2996f326873f25ac3c076fdec3eebd48115dc5ae696b","x":-1.1807197332382202,"y":-2.4674885272979736},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000178","label":"Model Lignocellulose Formaldehyde Cross-Feeding Community","page":"communities/Model_Lignocellulose_Formaldehyde_Crossfeeding_Community.html","source_path":"kb/communities/Model_Lignocellulose_Formaldehyde_Crossfeeding_Community.yaml","text_sha256":"642600ffcf3c767dc6629ad5bf9326d8f024bf6c8f0165c399dab7f35d5bb6db","x":0.0666825994849205,"y":1.4401861429214478},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000210","label":"Zymomonas-E. coli Exometabolomics-Designed Obligate Mutualism","page":"communities/Zymomonas_Ecoli_Exometabolomics_Obligate_Mutualism.html","source_path":"kb/communities/Zymomonas_Ecoli_Exometabolomics_Obligate_Mutualism.yaml","text_sha256":"daabed8e93b5d688aa026868cb8d96d41af076cadefb814712dbee5c2ede2a7c","x":0.38657069206237793,"y":3.861645221710205},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000282","label":"Thermophilic Lignocellulose-degrading Composting SynCom","page":"communities/Thermophilic_Lignocellulose_Composting_SynCom_Biosanitization.html","source_path":"kb/communities/Thermophilic_Lignocellulose_Composting_SynCom_Biosanitization.yaml","text_sha256":"3ca7cf653849f35a29fba9b66bab3f2c11277f0cbbf4504c2f84f2581f3204ff","x":3.048124074935913,"y":0.4863537549972534},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000348","label":"Sorghum SRC2v4 Root Colonization SynCom","page":"communities/Sorghum_SRC2v4_Root_Colonization_SynCom.html","source_path":"kb/communities/Sorghum_SRC2v4_Root_Colonization_SynCom.yaml","text_sha256":"2a5f64fe631293f02d210dd36aeb349c978100b50cad01b1194763efabf633c5","x":3.1896004676818848,"y":-2.4266421794891357},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000133","label":"OMM12 Gnotobiotic Mouse Gut Community","page":"communities/OMM12_Gnotobiotic_Mouse_Gut_Community.html","source_path":"kb/communities/OMM12_Gnotobiotic_Mouse_Gut_Community.yaml","text_sha256":"67e0d14e3ec23996299ced689eee3846cc4e9dc2bc56b2682db801a199c7c3d7","x":3.293034791946411,"y":3.4814159870147705},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000296","label":"Escherichia coli + Bifidobacterium bifidum Infant-gut Mutualistic Co-culture","page":"communities/Ecoli_Bifidobacterium_bifidum_Infant_gut_HMO_Mutualism_Coculture.html","source_path":"kb/communities/Ecoli_Bifidobacterium_bifidum_Infant_gut_HMO_Mutualism_Coculture.yaml","text_sha256":"ad40e5f4231946d4918a4212ec49695f27e5bccc442a13bd58e6d7d57a8d7539","x":2.8398938179016113,"y":3.5314433574676514},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000071","label":"Syntrophus Benzoate Degrader","page":"communities/Syntrophus_Benzoate_Degrader.html","source_path":"kb/communities/Syntrophus_Benzoate_Degrader.yaml","text_sha256":"014838683b6b1fe56100d3c6588699cc2725abaf8ab952c56d66399347a1ab72","x":-4.597818374633789,"y":1.1940251588821411},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000094","label":"Arabidopsis Coumarin Root SynCom","page":"communities/Arabidopsis_Coumarin_Root_SynCom.html","source_path":"kb/communities/Arabidopsis_Coumarin_Root_SynCom.yaml","text_sha256":"73ff9d5aaeefa58718a7614ac3b06e0f244c418a11df38124aa38fcdaef85ad8","x":4.161531448364258,"y":-2.5142998695373535},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000009","label":"BioModels MODEL2204300001 Kefir Community Model","page":"communities/BioModels_MODEL2204300001_Kefir_Community_Model.html","source_path":"kb/communities/BioModels_MODEL2204300001_Kefir_Community_Model.yaml","text_sha256":"97d18f5c78a98347aeeb9622b21b612829166176b1484c94cd0043a65d28815e","x":1.8470717668533325,"y":4.669951915740967},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000315","label":"Mesorhizobium TaiHu-Synechococcus PCC 7002 Vitamin B12 Synthetic Consortium","page":"communities/Mesorhizobium_Synechococcus_B12_Synthetic_Consortium.html","source_path":"kb/communities/Mesorhizobium_Synechococcus_B12_Synthetic_Consortium.yaml","text_sha256":"b61d6e6613310cc35c284d3d029a2d205bef0c520a128ae12cf96757d00440f5","x":-1.0979630947113037,"y":5.4691948890686035},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000239","label":"Thiocyanate-Degrading Afipia and Thiobacillus Bioreactor Community","page":"communities/Thiocyanate_Afipia_Thiobacillus_Bioreactor_Community.html","source_path":"kb/communities/Thiocyanate_Afipia_Thiobacillus_Bioreactor_Community.yaml","text_sha256":"db32794bf39eae900a09ff0f0abb5ae58d3a74ebc9a5dd1866c5c029495ead43","x":-0.8260172009468079,"y":-1.8381035327911377},{"adapter_version":"communitymech-semantic-v1","category":"METAL_REDUCTION","identifier":"CommunityMech:000268","label":"Rhodopseudomonas-Geobacter Magnetite Redox Coculture","page":"communities/Rhodopseudomonas_Geobacter_Magnetite_Redox_Coculture.html","source_path":"kb/communities/Rhodopseudomonas_Geobacter_Magnetite_Redox_Coculture.yaml","text_sha256":"ff8eb02beff5f52b739f73c05e38b78d443d0e928c8323be256883e749533708","x":-3.121076822280884,"y":-1.1685371398925781},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000005","label":"Bayan Obo REE Tailings Consortium","page":"communities/Bayan_Obo_REE_Tailings_Consortium.html","source_path":"kb/communities/Bayan_Obo_REE_Tailings_Consortium.yaml","text_sha256":"0acb111b168fa6902e555c1582690f3a5986459821fe30e35f26617e0b7c35f7","x":-3.785235643386841,"y":-5.975985527038574},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000344","label":"Klebsiella-Arthrobacter KZ Phenanthrene-Cadmium SynCom","page":"communities/Klebsiella_Arthrobacter_KZ_Phenanthrene_Cadmium_SynCom.html","source_path":"kb/communities/Klebsiella_Arthrobacter_KZ_Phenanthrene_Cadmium_SynCom.yaml","text_sha256":"507ae5f7b39c7cb653b8032a97ed2b9c5d74b1fb9c63c82db42f9b3a1f31ca8d","x":0.45059046149253845,"y":-1.0571359395980835},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000207","label":"Synechococcus-Azotobacter Photoproduction Mutualism","page":"communities/Synechococcus_Azotobacter_Photoproduction_Mutualism.html","source_path":"kb/communities/Synechococcus_Azotobacter_Photoproduction_Mutualism.yaml","text_sha256":"5d1e476f7569fa0222b08670932305871772251048178e5a0ed2b7068190305d","x":-1.9450185298919678,"y":5.861614227294922},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000252","label":"Crystal Geyser CO2-Rich Aquifer Autotrophic CPR Lysolipid Community","page":"communities/Crystal_Geyser_CO2_Aquifer_CPR_Lipid_Community.html","source_path":"kb/communities/Crystal_Geyser_CO2_Aquifer_CPR_Lipid_Community.yaml","text_sha256":"bcb7c6b6aaf6a8fc9bed2240075c194565e87f8b685da8fff44e373807993688","x":-2.749391555786133,"y":-3.503636121749878},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000351","label":"MUC2 Human Gut Commensal Defined Consortium","page":"communities/MUC2_Human_Gut_Commensal_Defined_Consortium.html","source_path":"kb/communities/MUC2_Human_Gut_Commensal_Defined_Consortium.yaml","text_sha256":"dee352c06c04572f5a495ce560b0e46469d2f4e19720605b6e5619b9f9bf8faf","x":2.334261655807495,"y":3.2062840461730957},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000108","label":"Medicago Nodule Biofertilizer SynCom","page":"communities/Medicago_Nodule_Biofertilizer_SynCom.html","source_path":"kb/communities/Medicago_Nodule_Biofertilizer_SynCom.yaml","text_sha256":"393a68af62125c5fb54d9bc2ad44886de1b2fb8415ac9af35696a543a39d9d57","x":4.030205726623535,"y":-2.356149911880493},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000199","label":"Dehalococcoides-Desulfovibrio Lactate-Fed TCE Dechlorination Coculture","page":"communities/Dehalococcoides_Desulfovibrio_Lactate_TCE_Syntrophy.html","source_path":"kb/communities/Dehalococcoides_Desulfovibrio_Lactate_TCE_Syntrophy.yaml","text_sha256":"2d9da7bb6507422a28816efe6ae8e34f7f77ffa212d7189ac6911f70dee7045e","x":-1.9176974296569824,"y":-0.24581316113471985},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000310","label":"Moss-Microbe Complex Regolith Biofertilizer","page":"communities/Moss_Microbe_Complex_Regolith_Biofertilizer.html","source_path":"kb/communities/Moss_Microbe_Complex_Regolith_Biofertilizer.yaml","text_sha256":"4f1b433a1704ada9e7962cf5376b03314557321d6a0e6e4f496caa1c531e3e24","x":-3.371643543243408,"y":-7.315645694732666},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000106","label":"Tobacco Chemotactic Biocontrol SynCom","page":"communities/Tobacco_Chemotactic_Biocontrol_SynCom.html","source_path":"kb/communities/Tobacco_Chemotactic_Biocontrol_SynCom.yaml","text_sha256":"7bba00461530df3c159393eb0a359c7350ce7705be5c7b0b628d2d82569f5f16","x":5.018680095672607,"y":-1.6807719469070435},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000345","label":"Pichia-Lactiplantibacillus CCMA Plant Beverage Coculture","page":"communities/Pichia_Lactiplantibacillus_CCMA_Plant_Beverage_Coculture.html","source_path":"kb/communities/Pichia_Lactiplantibacillus_CCMA_Plant_Beverage_Coculture.yaml","text_sha256":"90330af67ec162f11e25ef35639368c81934295e263146c2eff595126d551a79","x":0.5441087484359741,"y":2.52799129486084},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000339","label":"Space Habitat Seven-Member Stress-Tolerance SynCom","page":"communities/Space_Habitat_SevenMember_Stress_Tolerance_SynCom.html","source_path":"kb/communities/Space_Habitat_SevenMember_Stress_Tolerance_SynCom.yaml","text_sha256":"c316246fb1d2da58432ca34adfc58377fcbe1027c5b8da81ad6e607e5cdadee8","x":3.669246196746826,"y":1.3051815032958984},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000124","label":"Honeybee Core-20 Defined Microbiota","page":"communities/Honeybee_Core20_Defined_Microbiota.html","source_path":"kb/communities/Honeybee_Core20_Defined_Microbiota.yaml","text_sha256":"6fdce04448b3a330e9d18de84d5248585b1860b4e278a7feca6d2e0573d84706","x":3.510442018508911,"y":3.2784082889556885},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000195","label":"Coniochaeta-Sphingobacterium-Citrobacter Wheat Straw Consortium","page":"communities/Coniochaeta_Sphingobacterium_Citrobacter_Wheat_Straw_Consortium.html","source_path":"kb/communities/Coniochaeta_Sphingobacterium_Citrobacter_Wheat_Straw_Consortium.yaml","text_sha256":"4616901642545e91fb479067c9d3fd92010aae307f4e0263ce6e3bf90bc42c4b","x":-0.040698084980249405,"y":1.3813892602920532},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000149","label":"Synthetic Lichen Synechococcus-Rhodotorula Coculture","page":"communities/Synthetic_Lichen_Synechococcus_Rhodotorula_Coculture.html","source_path":"kb/communities/Synthetic_Lichen_Synechococcus_Rhodotorula_Coculture.yaml","text_sha256":"59e81e862817b46ffff9b76052cd85faae2d1d3f8dd47d036d9c0be8df0e0848","x":-1.7843332290649414,"y":5.968220233917236},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000324","label":"Pseudomonas-Bacillus Waxy Oil Biodegradation Consortium","page":"communities/Pseudomonas_Bacillus_Waxy_Oil_Biodegradation_Consortium.html","source_path":"kb/communities/Pseudomonas_Bacillus_Waxy_Oil_Biodegradation_Consortium.yaml","text_sha256":"b79636a33dc244660c4a518e0968f2a8777fbf3c112545d515a736c418de04a8","x":-0.01239005010575056,"y":-0.6348085999488831},{"adapter_version":"communitymech-semantic-v1","category":"METAL_REDUCTION","identifier":"CommunityMech:000262","label":"Alaska Tundra Permafrost Iron-Redox Community","page":"communities/Alaska_Tundra_Permafrost_Iron_Redox_Community.html","source_path":"kb/communities/Alaska_Tundra_Permafrost_Iron_Redox_Community.yaml","text_sha256":"4ff0770a2b7353d8a43e80d59176f311f359a433be8e3820c19a29cf7b29b9a4","x":-3.759805679321289,"y":-2.904301881790161},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000052","label":"Pelotomaculum-Methanothermobacter Syntrophic Consortium","page":"communities/Pelotomaculum_Methanothermobacter_Syntrophy.html","source_path":"kb/communities/Pelotomaculum_Methanothermobacter_Syntrophy.yaml","text_sha256":"67b1a1c3526f65373edad53306332a5d9c9dd14f5f008f1b6ca7d99cd2bc7ecb","x":-4.785126209259033,"y":1.0205832719802856},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000223","label":"Infant Gut DNA Phageome Succession Community","page":"communities/Infant_Gut_DNA_Phage_Succession_Community.html","source_path":"kb/communities/Infant_Gut_DNA_Phage_Succession_Community.yaml","text_sha256":"5559828451ff6315cb734dfa6430e67a03cdc0e2d03485535e4a708cf0695616","x":3.4681482315063477,"y":3.5578994750976562},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000104","label":"Pepper Growth Rhizosphere SynCom","page":"communities/Pepper_Growth_Rhizosphere_SynCom.html","source_path":"kb/communities/Pepper_Growth_Rhizosphere_SynCom.yaml","text_sha256":"cf8931f77425eec84df9a2a6481f577655e5d0707b15c47aebfdb25f5aea1f82","x":5.118863582611084,"y":-1.925755500793457},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000019","label":"Copper Biomining Heap Leach Consortium","page":"communities/Copper_Biomining_Heap_Leach.html","source_path":"kb/communities/Copper_Biomining_Heap_Leach.yaml","text_sha256":"acc3077195ef0a7fc5ea0cd02ed655552bc437dedf92e595fdd486d8b2d01ee3","x":-4.0857253074646,"y":-5.617560386657715},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000367","label":"Mediterranean AM Fungal Six-Species SynCom","page":"communities/Mediterranean_AM_Fungal_SixSpecies_SynCom.html","source_path":"kb/communities/Mediterranean_AM_Fungal_SixSpecies_SynCom.yaml","text_sha256":"505981ac6de55902cb4ba8d4fb5cb9c9c007987ac705da19204c7a05b6d0065b","x":2.941084861755371,"y":-2.637756586074829},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000340","label":"Pelagerythrobacter-Salinicola PES Pyrene-Degradation SynCom","page":"communities/Pelagerythrobacter_Salinicola_PES_Pyrene_Degradation_SynCom.html","source_path":"kb/communities/Pelagerythrobacter_Salinicola_PES_Pyrene_Degradation_SynCom.yaml","text_sha256":"27bc055a9dfcf825b58778936037de861e8d5cf045f355faf55d11d9e5ce39bd","x":0.01948748715221882,"y":-0.7151609659194946},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000357","label":"E. coli GL10-XL12 D-Lactate Mixed-Sugar SynCom","page":"communities/Ecoli_GL10_XL12_D_Lactate_Mixed_Sugar_SynCom.html","source_path":"kb/communities/Ecoli_GL10_XL12_D_Lactate_Mixed_Sugar_SynCom.yaml","text_sha256":"edbad66348c1501aa94c6d957cfa0bd9bee78d210bb04283a84bb594f88d32b7","x":0.5875663161277771,"y":2.7558789253234863},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000218","label":"Horonobe and Mizunami Underground Research Laboratory Subsurface Microbiome","page":"communities/Horonobe_Mizunami_URL_Subsurface_Microbiome.html","source_path":"kb/communities/Horonobe_Mizunami_URL_Subsurface_Microbiome.yaml","text_sha256":"f0daa3cb288486dd3f2e1990d2a135d5b252c86bbf3901de1630ac007c7ad549","x":-2.743284225463867,"y":-3.8085718154907227},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000248","label":"Candida parapsilosis Hospitalized Infant Gut Microbiome Community","page":"communities/Candida_Parapsilosis_Hospitalized_Infant_Microbiome.html","source_path":"kb/communities/Candida_Parapsilosis_Hospitalized_Infant_Microbiome.yaml","text_sha256":"338a714302bc27abd5ec1a7a8d832febe931040088dc21300b3f4ecd3cc690e9","x":3.2402687072753906,"y":3.8178300857543945},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000353","label":"Hualgayoc Acidic Sulfate-Reducing AMD Consortium","page":"communities/Hualgayoc_Acidic_Sulfate_Reducing_AMD_Consortium.html","source_path":"kb/communities/Hualgayoc_Acidic_Sulfate_Reducing_AMD_Consortium.yaml","text_sha256":"cf1a351d52b4aafbf85ba16103eef2bed46c6f08b462eec44eeb17786ac0c2da","x":-3.8116183280944824,"y":-4.562318801879883},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000300","label":"Pleuromutilin-degrading Artificial Consortium (5-strain)","page":"communities/Pleuromutilin_Degrading_Artificial_Consortium_5_Strain.html","source_path":"kb/communities/Pleuromutilin_Degrading_Artificial_Consortium_5_Strain.yaml","text_sha256":"f5531987bf27a7ec6e786a93c33d8dc48936ffbaadba8f1fe85f01b16e0bff2f","x":0.4311549961566925,"y":-0.11282452195882797},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000062","label":"Salar de Atacama Lithium Brine Community","page":"communities/Salar_Atacama_Lithium_Brine_Community.html","source_path":"kb/communities/Salar_Atacama_Lithium_Brine_Community.yaml","text_sha256":"694229e964d9ec16bca865ecdec7011bd454cfdf50064f4e0f683939947fc097","x":-3.574040651321411,"y":-4.272478103637695},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000213","label":"Variovorax-Cryptococcus Vitamin Cross-Feeding Microcosm","page":"communities/Variovorax_Cryptococcus_Vitamin_Mutualism_Microcosm.html","source_path":"kb/communities/Variovorax_Cryptococcus_Vitamin_Mutualism_Microcosm.yaml","text_sha256":"d38643710e7c9bf5b12c2b4d59344123f03274245e2962ccfefd492f3fc63732","x":-0.08579102903604507,"y":5.148460388183594},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000271","label":"Propanotrophic Chlorinated Ethene Cometabolism Enrichment Cultures","page":"communities/Propanotrophic_Chlorinated_Ethene_Cometabolism_Enrichment.html","source_path":"kb/communities/Propanotrophic_Chlorinated_Ethene_Cometabolism_Enrichment.yaml","text_sha256":"d2e6a42501857b02ed0e08b0722e2dc189f75dfbb1fc6fcaad8084b0b3d26fbe","x":-1.419797658920288,"y":-0.8460599780082703},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000150","label":"Desulfovibrio-Methanosarcina Lactate Syntrophy","page":"communities/Desulfovibrio_Methanosarcina_Lactate_Syntrophy.html","source_path":"kb/communities/Desulfovibrio_Methanosarcina_Lactate_Syntrophy.yaml","text_sha256":"cb844f6862ebeeb978c2206a38e494365cc9b850cba70b31674ee664db0108ad","x":-3.8950483798980713,"y":1.1875497102737427},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000136","label":"Oak Ridge FRC Uranium-Nitrate Groundwater Community","page":"communities/Oak_Ridge_FRC_Uranium_Nitrate_Groundwater_Community.html","source_path":"kb/communities/Oak_Ridge_FRC_Uranium_Nitrate_Groundwater_Community.yaml","text_sha256":"3ad2c3ac7d5376cf4c861336c0e277f3191b597405ac5ae26d1f62a99e749be6","x":-2.5754446983337402,"y":-3.741626501083374},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000352","label":"GENIA Nine-Member Multi-Pollutant Bioremediation SynCom","page":"communities/GENIA_NineMember_MultiPollutant_Bioremediation_SynCom.html","source_path":"kb/communities/GENIA_NineMember_MultiPollutant_Bioremediation_SynCom.yaml","text_sha256":"343a7c8439ff159b1f1da16c3532c933f7d504a30c114427a3650317e430cbaa","x":2.495553731918335,"y":-0.9802331924438477},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000142","label":"Bacteroides-Methanobrevibacter Gnotobiotic Mouse Mutualism","page":"communities/Bacteroides_Methanobrevibacter_Gnotobiotic_Mouse_Mutualism.html","source_path":"kb/communities/Bacteroides_Methanobrevibacter_Gnotobiotic_Mouse_Mutualism.yaml","text_sha256":"dbf25e1c119718254996e3b3b2fd56db78ad7614a2e438cdd9811dc509aec4f5","x":2.721143960952759,"y":3.496242046356201},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000177","label":"Shewanella-Geobacter Three-Species Exoelectrogenic Biofilm Community","page":"communities/Shewanella_Geobacter_Exoelectrogenic_Biofilm_Community.html","source_path":"kb/communities/Shewanella_Geobacter_Exoelectrogenic_Biofilm_Community.yaml","text_sha256":"efb22822e1ed75a2d3ba56c325607dfe9a5f6fd1152d2213278a5619022ececc","x":-3.2696361541748047,"y":-0.8427521586418152},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000068","label":"Syntrophobacter-Methanobacterium Syntrophic Consortium","page":"communities/Syntrophobacter_Methanobacterium_Syntrophy.html","source_path":"kb/communities/Syntrophobacter_Methanobacterium_Syntrophy.yaml","text_sha256":"8c36b2523056f3deedaff83340d0ee6a881bf473bb216ee987c983714c6bf911","x":-4.655643463134766,"y":0.9671416878700256},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000059","label":"Richmond Mine AMD Biofilm","page":"communities/Richmond_Mine_AMD_Biofilm.html","source_path":"kb/communities/Richmond_Mine_AMD_Biofilm.yaml","text_sha256":"93c79d954cdfccfd6ceb7912f195eb741d5a0148b0005491c45a501107293d5f","x":-3.897205352783203,"y":-5.0306715965271},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000303","label":"BioRock ISS Basalt Biomining Consortium","page":"communities/BioRock_ISS_Basalt_Biomining_Consortium.html","source_path":"kb/communities/BioRock_ISS_Basalt_Biomining_Consortium.yaml","text_sha256":"b9abdea4de7c439f7d23cb2bf082f9b0d0f18e363f3a1230c0d548387513f34d","x":-3.6009531021118164,"y":-6.643798351287842},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000366","label":"Cultivated Meat Contaminant SynCom","page":"communities/Cultivated_Meat_Contaminant_SynCom.html","source_path":"kb/communities/Cultivated_Meat_Contaminant_SynCom.yaml","text_sha256":"c56997838ee350fe1935029c0f18b6797813412fce5c16de8e5a8f8b9ab918f7","x":3.4390549659729004,"y":0.9102683663368225},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000103","label":"Maize Drought Response SynCom","page":"communities/Maize_Drought_Response_SynCom.html","source_path":"kb/communities/Maize_Drought_Response_SynCom.yaml","text_sha256":"94d567fe1d7f04a3749884310563e891643630761b55983280b37557c5427b0c","x":4.171766757965088,"y":-2.256147623062134},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000259","label":"Thalassiosira-Marinobacter Marine Snow Coculture","page":"communities/Thalassiosira_Marinobacter_Marine_Snow_Coculture.html","source_path":"kb/communities/Thalassiosira_Marinobacter_Marine_Snow_Coculture.yaml","text_sha256":"6f113705f887b73d38816187fc5fd5b481180b4b78d4d2e9827d67fc4288e78d","x":-0.628815233707428,"y":5.82745361328125},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000032","label":"Geobacter-Methanosaeta DIET Community","page":"communities/Geobacter_Methanosaeta_DIET.html","source_path":"kb/communities/Geobacter_Methanosaeta_DIET.yaml","text_sha256":"da9185e7bd2dfd154e6da4161f70ddb71ae9593f77f00e3d5fbeb80a5514b013","x":-3.5572497844696045,"y":-0.532174289226532},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000057","label":"Rammelsberg Cobalt-Nickel Tailings Consortium","page":"communities/Rammelsberg_Cobalt_Nickel_Tailings.html","source_path":"kb/communities/Rammelsberg_Cobalt_Nickel_Tailings.yaml","text_sha256":"c0467a5f22a1b57dc59ea94962848ecfef67c0d30a798ac079939d293fdcb702","x":-3.9645962715148926,"y":-5.561802864074707},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000171","label":"Methylacidiphilum-Galdieria Thermoacidophilic Methane Coculture","page":"communities/Methylacidiphilum_Galdieria_Thermoacidophilic_Coculture.html","source_path":"kb/communities/Methylacidiphilum_Galdieria_Thermoacidophilic_Coculture.yaml","text_sha256":"924aedae62df5268541a22179dd8df0ad4c014f1c0aae10fb2df03af51757c70","x":-2.514552354812622,"y":3.84505033493042},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000358","label":"Bacillus A1-A3 Naphthalene Biofilm Consortium","page":"communities/Bacillus_A1_A3_Naphthalene_Biofilm_Consortium.html","source_path":"kb/communities/Bacillus_A1_A3_Naphthalene_Biofilm_Consortium.yaml","text_sha256":"ee7f08806d4d533e4102bedd6e38716283cce1c07dfe4bfb671a0d483f643c2f","x":0.12371133267879486,"y":-0.7904185056686401},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000014","label":"Chlamydomonas-Bacterial Hydrogen Production Consortium","page":"communities/Chlamydomonas_Bacterial_H2_Consortium.html","source_path":"kb/communities/Chlamydomonas_Bacterial_H2_Consortium.yaml","text_sha256":"27f63383e74e87a5b46368314c22fb896627febfdf7127a18c5057264f754e93","x":-1.3021148443222046,"y":5.250540733337402},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000160","label":"Drosophila Five-Species Gnotobiotic Gut Microbiota","page":"communities/Drosophila_FiveSpecies_Gnotobiotic_Gut_Microbiota.html","source_path":"kb/communities/Drosophila_FiveSpecies_Gnotobiotic_Gut_Microbiota.yaml","text_sha256":"16bcf1a8cc58a59e2c0c1c80bab2da84c95921e2035fb129ce7283266643eb1d","x":2.708746910095215,"y":3.6431069374084473},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000099","label":"Jala Maize PGPB SynCom","page":"communities/Jala_Maize_PGPB_SynCom.html","source_path":"kb/communities/Jala_Maize_PGPB_SynCom.yaml","text_sha256":"3d82f27a5b54253638573b075fa4f1b2746c621481fbb8323f640c281f1d49ca","x":4.150224685668945,"y":-1.8997735977172852},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000245","label":"Avena Rhizosphere and Detritusphere Niche-Differentiated Decomposer Guilds","page":"communities/Avena_Rhizosphere_Detritusphere_Niche_Succession.html","source_path":"kb/communities/Avena_Rhizosphere_Detritusphere_Niche_Succession.yaml","text_sha256":"2e0a31be80145dbe06d70b752c8b2fcc7b00f0b21d954cf753d5af1292a27001","x":1.8494696617126465,"y":-3.2216527462005615},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000288","label":"Shewanella oneidensis + Pseudomonas aeruginosa Fe0-dependent Electro-syntrophic Denitrifying Consortium","page":"communities/Shewanella_Pseudomonas_Fe0_Electrosyntrophic_Denitrifying_Consortium.html","source_path":"kb/communities/Shewanella_Pseudomonas_Fe0_Electrosyntrophic_Denitrifying_Consortium.yaml","text_sha256":"8aad2a8dfd666f28ad7d66d3122ec5ee925071a40fe84e1ac3aa4d08f6fca64b","x":-2.5917773246765137,"y":-0.5429364442825317},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000211","label":"Synechococcus-Shewanella D-Lactate Biophotovoltaic Consortium","page":"communities/Synechococcus_Shewanella_Dlactate_Biophotovoltaic_Consortium.html","source_path":"kb/communities/Synechococcus_Shewanella_Dlactate_Biophotovoltaic_Consortium.yaml","text_sha256":"2251bad4e789006f81900e665f312bf8a65652208fc62e5ce890a2106c1dbe57","x":-2.0787012577056885,"y":5.7538323402404785},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000166","label":"Deepwater Horizon Deep-Sea Oil Plume Succession","page":"communities/Deepwater_Horizon_Deep_Sea_Oil_Plume_Succession.html","source_path":"kb/communities/Deepwater_Horizon_Deep_Sea_Oil_Plume_Succession.yaml","text_sha256":"3da089aab0ff6c3599ced18e5223879712e8220814c3f232596f389ddfe7b6c7","x":-2.701596260070801,"y":-2.6101341247558594},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000265","label":"Cellulomonas-Rhodobacter Cellulose Photohydrogen Coculture","page":"communities/Cellulomonas_Rhodobacter_Cellulose_Photohydrogen_Coculture.html","source_path":"kb/communities/Cellulomonas_Rhodobacter_Cellulose_Photohydrogen_Coculture.yaml","text_sha256":"ba75ba840d3de70adf815730d11d51c518b5f5f788ef2abda4af131037880160","x":-1.7937979698181152,"y":1.7382313013076782},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000346","label":"Chicken BL6 Anti-Salmonella SynCom","page":"communities/Chicken_BL6_AntiSalmonella_SynCom.html","source_path":"kb/communities/Chicken_BL6_AntiSalmonella_SynCom.yaml","text_sha256":"f02cbfc430aad88eb01e9aa2211781e1c42d8928031b836be5f589c7a70eec60","x":3.541550636291504,"y":2.168591260910034},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000376","label":"Ginseng CL95 Rusty Root Rot Biocontrol SynCom","page":"communities/Ginseng_CL95_Rusty_Root_Rot_Biocontrol_SynCom.html","source_path":"kb/communities/Ginseng_CL95_Rusty_Root_Rot_Biocontrol_SynCom.yaml","text_sha256":"5e885596fcbeea01c2c216fe1753c441ac0eb1a861b861984f6b6c17c5171f4e","x":5.1110148429870605,"y":-1.3291481733322144},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000119","label":"Multiomics Corn Straw Degradation SynCom","page":"communities/Multiomics_Corn_Straw_Degradation_SynCom.html","source_path":"kb/communities/Multiomics_Corn_Straw_Degradation_SynCom.yaml","text_sha256":"ce814ce8c6a1a542553a78f1df27beaa4a8b7581973ec0002b6fa4c38af48e9a","x":1.3083605766296387,"y":0.9929082989692688},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000335","label":"Streptomyces A2-A5-A11-M7 Pesticide-Bioremediation Consortium","page":"communities/Streptomyces_A2_A5_A11_M7_Pesticide_Consortium.html","source_path":"kb/communities/Streptomyces_A2_A5_A11_M7_Pesticide_Consortium.yaml","text_sha256":"dd03ba51ae82e203eb89dc28f00d72b1599a30da3dd806eeda10abaee19abf85","x":0.2130987048149109,"y":-0.9192069172859192},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000323","label":"Clostridium cellulovorans-Beijerinckii AECC ABE Coculture","page":"communities/Clostridium_Cellulovorans_Beijerinckii_AECC_ABE_Coculture.html","source_path":"kb/communities/Clostridium_Cellulovorans_Beijerinckii_AECC_ABE_Coculture.yaml","text_sha256":"10bd7050fc4e82080b20ef84df149653d56622a76896913f592aab767da1cc9b","x":-1.6868579387664795,"y":2.3145651817321777},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000125","label":"SkinCom Synthetic Skin Community","page":"communities/SkinCom_Synthetic_Skin_Community.html","source_path":"kb/communities/SkinCom_Synthetic_Skin_Community.yaml","text_sha256":"81cc2ee327bc36b796715e0a077ef511f16df4b633ea2c11915822629d8b9aec","x":3.3739473819732666,"y":2.1844217777252197},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000320","label":"Aspergillus Indium LCD Recovery Platform","page":"isolates/Aspergillus_Indium_LED_Recovery.html","source_path":"data/isolates/Aspergillus_Indium_LED_Recovery.yaml","text_sha256":"ca948047b9dd14f8fb7c3278228f524a4f83439f96607fe03316ba70d4ec0bc0","x":-3.8206748962402344,"y":-6.213545322418213},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000295","label":"Parachlorella kessleri + Saccharomyces cerevisiae Mutualistic Co-culture","page":"communities/Parachlorella_Saccharomyces_Mutualistic_Coculture.html","source_path":"kb/communities/Parachlorella_Saccharomyces_Mutualistic_Coculture.yaml","text_sha256":"aacf28dbe3f9505208f5fc0da72ccd1bd003fb9ee64483f0bc9145cf881c89ec","x":-0.9410389065742493,"y":5.17526912689209},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000155","label":"Ostreococcus-Dinoroseobacter B-Vitamin Mutualism","page":"communities/Ostreococcus_Dinoroseobacter_BVitamin_Mutualism.html","source_path":"kb/communities/Ostreococcus_Dinoroseobacter_BVitamin_Mutualism.yaml","text_sha256":"841884aec6107e8fe29e54175c790840224ae2d9e9f64a45dc2bff943c4cd5cf","x":-0.7768973112106323,"y":5.563060283660889},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000023","label":"Desulfovibrio-Methanococcus Syntrophic Consortium","page":"communities/Desulfovibrio_Methanococcus_Syntrophy.html","source_path":"kb/communities/Desulfovibrio_Methanococcus_Syntrophy.yaml","text_sha256":"14342f966090a4209f5a1888b014d6e7ebfa4137b8d3a6a5cbb6831aeb4f8c17","x":-4.432833194732666,"y":0.999701738357544},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000069","label":"Syntrophobacter-Methanospirillum Syntrophic Consortium","page":"communities/Syntrophobacter_Methanospirillum_Syntrophy.html","source_path":"kb/communities/Syntrophobacter_Methanospirillum_Syntrophy.yaml","text_sha256":"3982b8581cc37695aae29c7784982a707c46c4a8642b626bc389184de4784ce4","x":-4.675378322601318,"y":1.0547746419906616},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000113","label":"Phylogenetically Diverse Denitrifying SynCom","page":"communities/Phylogenetically_Diverse_Denitrifying_SynCom.html","source_path":"kb/communities/Phylogenetically_Diverse_Denitrifying_SynCom.yaml","text_sha256":"ed656ea8891af2c30842fa47a0f746e8b817ba07ab6ecca017e303cfe790ac17","x":-0.9365326762199402,"y":-2.4682905673980713},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000256","label":"Prairie Pothole Wetland Sulfur-Carbon Virus-Host Community","page":"communities/Prairie_Pothole_Wetland_Sulfur_Carbon_Virus_Community.html","source_path":"kb/communities/Prairie_Pothole_Wetland_Sulfur_Carbon_Virus_Community.yaml","text_sha256":"212d2fd3b77b46d2423ca4d96871d38c2ed86c9744d93ad5dba71221a3ed4f79","x":-3.519014835357666,"y":-3.356289863586426},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000192","label":"Methylomicrobium-Chlorella Methane Sequestration Coculture","page":"communities/Methylomicrobium_Chlorella_Methane_Sequestration_Coculture.html","source_path":"kb/communities/Methylomicrobium_Chlorella_Methane_Sequestration_Coculture.yaml","text_sha256":"52bd4fe4250ac612e093f954a4aed512d583736342655947e465879a5536cf59","x":-2.289224624633789,"y":4.148324966430664},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000129","label":"Soybean Chlorophyll-Selected Biofertilizer SynCom","page":"communities/Soybean_Chlorophyll_Selected_Biofertilizer_SynCom.html","source_path":"kb/communities/Soybean_Chlorophyll_Selected_Biofertilizer_SynCom.yaml","text_sha256":"74019b5e375c0258a9d4a67cf92212b894e2e814135f605162c172eb025ff570","x":3.953120231628418,"y":-2.456279993057251},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000363","label":"Synechocystis-Pseudomonas Acetate-Butanol Coculture","page":"communities/Synechocystis_Pseudomonas_Acetate_Butanol_Coculture.html","source_path":"kb/communities/Synechocystis_Pseudomonas_Acetate_Butanol_Coculture.yaml","text_sha256":"7f8faa5b760f351b178ace74e7e9304009c456e84740783ef8719f47a77f0636","x":-2.0132033824920654,"y":5.861827850341797},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000373","label":"Bacillus G12-Y4-X25 Tobacco Biocontrol SynCom","page":"communities/Bacillus_G12_Y4_X25_Tobacco_Biocontrol_SynCom.html","source_path":"kb/communities/Bacillus_G12_Y4_X25_Tobacco_Biocontrol_SynCom.yaml","text_sha256":"7f2605dc4920d45d0583baff25393a6396f7bcb2921e01f86df0358edceb4a20","x":5.063169479370117,"y":-1.2986890077590942},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000165","label":"Saccharomyces-Chlamydomonas Fungal-Algal Mutualism","page":"communities/Saccharomyces_Chlamydomonas_Fungal_Algal_Mutualism.html","source_path":"kb/communities/Saccharomyces_Chlamydomonas_Fungal_Algal_Mutualism.yaml","text_sha256":"c4802ed8f9dd78039252350e6660012a1df1568f2961291f43cbbcca56678410","x":-0.9581685066223145,"y":5.496689796447754},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000074","label":"Tinto River Iron Cycling Community","page":"communities/Tinto_River_Iron_Cycling_Community.html","source_path":"kb/communities/Tinto_River_Iron_Cycling_Community.yaml","text_sha256":"bc3d0c7d13019a4d887ca400d88a9a154409029c8ee7e8eb1dd42eed46450d8b","x":-3.9562671184539795,"y":-5.104090213775635},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000285","label":"SynCom + Chlorella sorokiniana Biogas-slurry Coupling System","page":"communities/SynCom_Chlorella_sorokiniana_Biogas_Slurry_Coupling_System.html","source_path":"kb/communities/SynCom_Chlorella_sorokiniana_Biogas_Slurry_Coupling_System.yaml","text_sha256":"0ad1889a012a36b63b607f7a228faf1b2f5d481678da1232c907c3101fb5f6b1","x":2.9855329990386963,"y":0.6227956414222717},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000275","label":"Butyrivibrio fibrisolvens + Selenomonas ruminantium + Ruminococcus albus Lignocellulolytic Rumen Consortium","page":"communities/Butyrivibrio_Selenomonas_Ruminococcus_Lignocellulolytic_Rumen_Consortium.html","source_path":"kb/communities/Butyrivibrio_Selenomonas_Ruminococcus_Lignocellulolytic_Rumen_Consortium.yaml","text_sha256":"d64aa4667e59388aa05f7bb3c15735fa730f55ea0375e1bd29714964cc1051f9","x":-0.2436143308877945,"y":1.5125125646591187},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000219","label":"Asgard Archaea Wetland Soil Methanogenesis-Substrate Community","page":"communities/Asgard_Wetland_Soil_Methanogenesis_Substrate_Community.html","source_path":"kb/communities/Asgard_Wetland_Soil_Methanogenesis_Substrate_Community.yaml","text_sha256":"460e4da34bea57baf5e8346c7032013b96d5e6bd4a7f61bddbd10e36fa60a498","x":-4.016145706176758,"y":-3.2364742755889893},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000194","label":"High-Solids Switchgrass Methanogenic Microbiome","page":"communities/High_Solids_Switchgrass_Methanogenic_Microbiome.html","source_path":"kb/communities/High_Solids_Switchgrass_Methanogenic_Microbiome.yaml","text_sha256":"86d77b5f02c6d17cddaf9add1efb533181c31f0806f792de3b040fee3469ef63","x":-1.252918004989624,"y":1.5176129341125488},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000011","label":"BioModels MODEL2310020001 Mouse Metaorganism Model","page":"communities/BioModels_MODEL2310020001_Mouse_Metaorganism_Model.html","source_path":"kb/communities/BioModels_MODEL2310020001_Mouse_Metaorganism_Model.yaml","text_sha256":"f0f13b3203c4cd98583bab8d17b253b668d68c379eb925e3313c7c4702776578","x":2.302501678466797,"y":4.447290897369385},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000087","label":"LBNL Switchgrass Soil SynCom16","page":"communities/LBNL_Switchgrass_Soil_SynCom16.html","source_path":"kb/communities/LBNL_Switchgrass_Soil_SynCom16.yaml","text_sha256":"024ad1306f01464815c5e8f7ca48e5d48cf2cd2712087162008d7db0c07125c7","x":3.3172028064727783,"y":-2.1421093940734863},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000086","label":"Model Soil Consortium-2 (MSC-2)","page":"communities/MSC2_Model_Soil_Consortium.html","source_path":"kb/communities/MSC2_Model_Soil_Consortium.yaml","text_sha256":"0e1d86dd9ed07a1c6e54d8d547219caefca9e73b3855639ffae8a5acd675c093","x":0.6076474785804749,"y":0.7197339534759521},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000089","label":"Cellulose-to-Methane Quad-Culture SynCom","page":"communities/Cellulose_Methane_Quad_Culture_SynCom.html","source_path":"kb/communities/Cellulose_Methane_Quad_Culture_SynCom.yaml","text_sha256":"8eca354ca53b2aad368c4bf6ada10a71cd8cf317f07cda7026b3f498d98a8263","x":-2.1934213638305664,"y":1.465627670288086},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000292","label":"Pseudomonas-Rahnella native rhizosphere SynCom for Artemisia argyi phytoremediation","page":"communities/SynCom_Pseudomonas_Rahnella_Artemisia_Phytoremediation.html","source_path":"kb/communities/SynCom_Pseudomonas_Rahnella_Artemisia_Phytoremediation.yaml","text_sha256":"794cb84cdec93a462077095bec78c1b0935efc4a85311a6acdda34803c1180c5","x":4.118293762207031,"y":-2.340355157852173},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000063","label":"Sorghum SRC1 Subset Community","page":"communities/Sorghum_SRC1_Subset.html","source_path":"kb/communities/Sorghum_SRC1_Subset.yaml","text_sha256":"11af740c3a212b7a25612e58dc5d1b95009fb224f33b78ff1997f98252996aea","x":2.9294216632843018,"y":-2.627791404724121},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000056","label":"Pseudo-nitzschia-Sulfitobacter Marine Association","page":"communities/Pseudonitzschia_Sulfitobacter_Association.html","source_path":"kb/communities/Pseudonitzschia_Sulfitobacter_Association.yaml","text_sha256":"407b212ecbcdb363108dc66276c38707df867805d9c6800494567f092a71f522","x":-0.5235821008682251,"y":5.660520076751709},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000040","label":"Lotus Lj-SC3 Synthetic Community","page":"communities/Lotus_LjSC3.html","source_path":"kb/communities/Lotus_LjSC3.yaml","text_sha256":"a1fb120a5e4fa06cbcba5d4d395a1a86ba632b172ac8a9889bff20ab60169f5b","x":3.2597713470458984,"y":-2.483100414276123},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000132","label":"KB-1 Chlorinated Ethene Dechlorinating Consortium","page":"communities/KB1_Chlorinated_Ethene_Dechlorinating_Consortium.html","source_path":"kb/communities/KB1_Chlorinated_Ethene_Dechlorinating_Consortium.yaml","text_sha256":"c2bc069a2d45587c0aa69ef088a7648e9b592ae52107cd75a077a6067b5f8211","x":-1.1367708444595337,"y":-0.7541654109954834},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000127","label":"SynComBac10 Chicken Intestinal SynCom","page":"communities/SynComBac10_Chicken_Intestinal_SynCom.html","source_path":"kb/communities/SynComBac10_Chicken_Intestinal_SynCom.yaml","text_sha256":"a2a895fdb11c3a5b7178259f7deecdb8891e807cd9326376753c1625afac42ef","x":3.717249870300293,"y":2.017282485961914},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000065","label":"Synechococcus-Bacillus Synthetic Photosynthetic Consortium","page":"communities/Synechococcus_Bacillus_SPC.html","source_path":"kb/communities/Synechococcus_Bacillus_SPC.yaml","text_sha256":"9eeebd6bf622808f997fb18d7ffebb85351df1cec8d53741b219144aa1591b77","x":-2.081233501434326,"y":6.010765075683594},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000036","label":"Ion-Adsorption REE Indigenous Community","page":"communities/Ion_Adsorption_REE_Indigenous_Community.html","source_path":"kb/communities/Ion_Adsorption_REE_Indigenous_Community.yaml","text_sha256":"12c08a4165875dc591413f54de34e51b1ba6d3e61ee022543ea5d5f54244d555","x":-3.1287131309509277,"y":-5.198551177978516},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000013","label":"BioModels MODEL2407300002 Sponge Holobiont Network","page":"communities/BioModels_MODEL2407300002_Sponge_Holobiont_Network.html","source_path":"kb/communities/BioModels_MODEL2407300002_Sponge_Holobiont_Network.yaml","text_sha256":"06de3e196a7de7e1e71bb11efdd87808d8e8860c4d1a455be6889d70e4c4d7f9","x":1.3135020732879639,"y":4.971480369567871},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000225","label":"Brachypodium Young Root Rhizosphere EcoFAB Community","page":"communities/Brachypodium_Young_Root_Rhizosphere_EcoFAB_Community.html","source_path":"kb/communities/Brachypodium_Young_Root_Rhizosphere_EcoFAB_Community.yaml","text_sha256":"f50dabbed261248232b9cee46ee61a8c8847ad382c5a85a7d92a54a03a4ce77c","x":2.6237621307373047,"y":-2.9677460193634033},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000329","label":"Sedimenting Arabinose-Glucose Saccharomyces Coculture","page":"communities/Sedimenting_Arabinose_Glucose_Saccharomyces_Coculture.html","source_path":"kb/communities/Sedimenting_Arabinose_Glucose_Saccharomyces_Coculture.yaml","text_sha256":"fc720953074e586c397d1c0e84cbdfcf46afb77e2dc382e197e861bf4d148064","x":0.5633422136306763,"y":2.6774075031280518},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000156","label":"Neocallimastix-Methanobrevibacter Xylanolytic Coculture","page":"communities/Neocallimastix_Methanobrevibacter_Xylan_Coculture.html","source_path":"kb/communities/Neocallimastix_Methanobrevibacter_Xylan_Coculture.yaml","text_sha256":"bf2e0a6f1d0f084405c76c72ce75c5e3285ab94ea57bce37f4da45cbb3429ee9","x":-2.3057103157043457,"y":1.4475923776626587},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000025","label":"EcoFAB 2.0 Root Microbiome Ring Trial SynCom17","page":"communities/EcoFAB_Ring_Trial_SynCom17.html","source_path":"kb/communities/EcoFAB_Ring_Trial_SynCom17.yaml","text_sha256":"d47741572ba43886d975fb55f8f4fd223b9bc54145e5e00400cdd7f1819a6f6a","x":3.3370273113250732,"y":-1.8894466161727905},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000272","label":"SynCom Y Agrobacterium-Bacillus Biofilm Biocontrol Co-culture","page":"communities/SynCom_Y_Agrobacterium_Bacillus_Biofilm_Biocontrol_Coculture.html","source_path":"kb/communities/SynCom_Y_Agrobacterium_Bacillus_Biofilm_Biocontrol_Coculture.yaml","text_sha256":"2cd8eea82eefe29e3c509606fb841cc028b208a3846fb4a7a8fbc4e3bd6592f4","x":4.778739929199219,"y":-1.425041913986206},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000336","label":"Clostridium acetobutylicum-Clostridium ljungdahlii Syntrophic Fusion Coculture","page":"communities/Clostridium_Acetobutylicum_Ljungdahlii_Fusion_Coculture.html","source_path":"kb/communities/Clostridium_Acetobutylicum_Ljungdahlii_Fusion_Coculture.yaml","text_sha256":"90159749552afa4cb40093b7734971f9ffed3f9b7e243d8cf1e9c21d058d7d1f","x":-2.583004951477051,"y":2.2144694328308105},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000079","label":"THOR Rhizosphere Model Community","page":"communities/THOR_Rhizosphere_Model_Community.html","source_path":"kb/communities/THOR_Rhizosphere_Model_Community.yaml","text_sha256":"23a46bbb433f8291fbded50410603f30b74777140bd8af2b4cf423ef214b1a0e","x":2.0567541122436523,"y":-3.100395441055298},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000122","label":"LBNL Human Gut Interaction SynCom","page":"communities/LBNL_Human_Gut_Interaction_SynCom.html","source_path":"kb/communities/LBNL_Human_Gut_Interaction_SynCom.yaml","text_sha256":"e21a8bc0178af9fa8a3e5c75b87755779a0092d512bc7421cdd07f848fb32728","x":3.377258062362671,"y":2.724881410598755},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000280","label":"Pinus armandii Endophytic Biocontrol SynCom","page":"communities/Pinus_armandii_Endophytic_Biocontrol_SynCom.html","source_path":"kb/communities/Pinus_armandii_Endophytic_Biocontrol_SynCom.yaml","text_sha256":"6185a476d5fcdc756510a8ac24b18f7650ee0576821d91671f0661ff688afbbd","x":4.680151462554932,"y":-1.3155442476272583},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000016","label":"Chlorella-Rhizobium Bioflocculation","page":"communities/Chlorella_Rhizobium_Bioflocculation.html","source_path":"kb/communities/Chlorella_Rhizobium_Bioflocculation.yaml","text_sha256":"253aad135083472771a167d6248ee79d3d2e90059133c7c6343da582377cf2c1","x":-1.6466079950332642,"y":4.781821250915527},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000163","label":"PET Artificial Four-Species Degradation Consortium","page":"communities/PET_Artificial_FourSpecies_Degradation_Consortium.html","source_path":"kb/communities/PET_Artificial_FourSpecies_Degradation_Consortium.yaml","text_sha256":"6c551fea29367c27dd01dd211d3b5663479d64499fff7c36497ee243cb47678d","x":0.06349872052669525,"y":-0.20265255868434906},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000076","label":"Wheat Synthetic Consortium C1","page":"communities/Wheat_Consortium_C1.html","source_path":"kb/communities/Wheat_Consortium_C1.yaml","text_sha256":"7991b61c668231e3d90c643124da0ac18448f3f5a17387c0ff08bbc3b6f26252","x":4.851639270782471,"y":-1.769600749015808},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000080","label":"SIHUMIx Human Intestinal Model Community","page":"communities/SIHUMIx_Human_Intestinal_Model_Community.html","source_path":"kb/communities/SIHUMIx_Human_Intestinal_Model_Community.yaml","text_sha256":"e4c68e2b38e0b82319bb20a583481906caf7a850e56aeb62219923843b2d9cb3","x":3.2817108631134033,"y":3.2037060260772705},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000264","label":"Clostridium cellulovorans-Rhodopseudomonas palustris Cellulose Biohydrogen Coculture","page":"communities/Clostridium_Cellulovorans_Rhodopseudomonas_Cellulose_Biohydrogen_Coculture.html","source_path":"kb/communities/Clostridium_Cellulovorans_Rhodopseudomonas_Cellulose_Biohydrogen_Coculture.yaml","text_sha256":"474df1293a509576548f1941327b53218abff129113ea82875f7dcfb7e9fc31c","x":-1.6953978538513184,"y":1.907236099243164},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000342","label":"Nitratireductor-Gordonia Z123 LDPE-Degradation SynCom","page":"communities/Nitratireductor_Gordonia_Z123_LDPE_Degradation_SynCom.html","source_path":"kb/communities/Nitratireductor_Gordonia_Z123_LDPE_Degradation_SynCom.yaml","text_sha256":"74060bdac362587df00698ef05fd1b8feadb1f74c05f652b91be79ab98ec6319","x":0.010486718267202377,"y":-0.779150664806366},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000276","label":"ANME/SRB Anaerobic Methanotrophic Syntrophic Consortia","page":"communities/ANME_SRB_Anaerobic_Methanotrophic_Syntrophic_Consortia.html","source_path":"kb/communities/ANME_SRB_Anaerobic_Methanotrophic_Syntrophic_Consortia.yaml","text_sha256":"3c2fe841f9dd315e2e017e442b210cfc7dc4a316614812b7bd66c77ef956e36b","x":-4.231417179107666,"y":-0.7358452081680298},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000001","label":"AMD Acidophile Heterotroph Network","page":"communities/AMD_Acidophile_Heterotroph_Network.html","source_path":"kb/communities/AMD_Acidophile_Heterotroph_Network.yaml","text_sha256":"8d724772cf4734be75348c0705ebbe398de13e47b3a9e3ff77444146e111f971","x":-3.764120578765869,"y":-4.97160530090332},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000298","label":"Shewanella-Acetogen Electrosynthetic Consortia for CO2-to-Acetate","page":"communities/Electrosynthetic_Consortia_Shewanella_Clostridium_Acetobacterium_Acetate.html","source_path":"kb/communities/Electrosynthetic_Consortia_Shewanella_Clostridium_Acetobacterium_Acetate.yaml","text_sha256":"e5ffa56178aac84da344167a2885bbc43dcfa8c3c1248cf1d7aa559d92ebfe9e","x":-3.1497318744659424,"y":-0.2224043607711792},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000082","label":"Defined Multispecies Enamel Caries Model","page":"communities/Defined_Multispecies_Enamel_Caries_Model.html","source_path":"kb/communities/Defined_Multispecies_Enamel_Caries_Model.yaml","text_sha256":"c100c344a712576fe06c67f0942957d7599c2f4b92bc945c9fb143049ec27c6e","x":2.4420154094696045,"y":5.3841118812561035},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000193","label":"Clostridium-Caldicellulosiruptor Minimal Medium Coculture","page":"communities/Clostridium_Caldicellulosiruptor_Minimal_Medium_Coculture.html","source_path":"kb/communities/Clostridium_Caldicellulosiruptor_Minimal_Medium_Coculture.yaml","text_sha256":"fca6964ac498312925b9a0e063ef9f7179e02b35a4bfb553413b421056355375","x":-1.6571670770645142,"y":1.9343771934509277},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000354","label":"Yarrowia lipolytica Division-of-Labor Lipid Consortium","page":"communities/Yarrowia_lipolytica_Division_of_Labor_Lipid_Consortium.html","source_path":"kb/communities/Yarrowia_lipolytica_Division_of_Labor_Lipid_Consortium.yaml","text_sha256":"4b826bfd12e500eeabff37751334c580ecc9e0bfdce1d9c60b2d367cdc202870","x":0.13262242078781128,"y":2.0253546237945557},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000044","label":"Mercury SFA East Fork Poplar Creek Sediment Community","page":"communities/Mercury_SFA_EFPC_Sediment_Community.html","source_path":"kb/communities/Mercury_SFA_EFPC_Sediment_Community.yaml","text_sha256":"ebfe013246c5fd37d20ba745089367d5be504a63333c68152727aa6a5cf73a4b","x":-2.8029911518096924,"y":-3.368298053741455},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000326","label":"Staphylococcus-Candida Context-Dependent Biofilm Coculture","page":"communities/Staphylococcus_Candida_Context_Dependent_Biofilm_Coculture.html","source_path":"kb/communities/Staphylococcus_Candida_Context_Dependent_Biofilm_Coculture.yaml","text_sha256":"6d043c03ce62652189a77028fc877ce4280ee0c39c3a2efd74ab25e654493d7b","x":2.3154971599578857,"y":5.019847869873047},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000347","label":"Bacillus siamensis-vallismortis HT Masson Pine SynCom","page":"communities/Bacillus_siamensis_vallismortis_HT_Masson_Pine_SynCom.html","source_path":"kb/communities/Bacillus_siamensis_vallismortis_HT_Masson_Pine_SynCom.yaml","text_sha256":"75fb2e6b8cd4f7dc23621367ce71e3d46bd5435865a0753051d85a89c7fdb51e","x":5.103806495666504,"y":-1.5002412796020508},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000311","label":"Legume-Rhizobia Mars Simulant Symbiosis","page":"communities/Legume_Rhizobia_Mars_Simulant_Symbiosis.html","source_path":"kb/communities/Legume_Rhizobia_Mars_Simulant_Symbiosis.yaml","text_sha256":"98cba31c12655a76da4e6d034e05f8982bdb92392ec53f6059da8f97b2af5556","x":-3.2932209968566895,"y":-7.453795909881592},{"adapter_version":"communitymech-semantic-v1","category":"METAL_REDUCTION","identifier":"CommunityMech:000017","label":"Chromium Sulfur Oxidation Enrichment","page":"communities/Chromium_Sulfur_Reduction_Enrichment.html","source_path":"kb/communities/Chromium_Sulfur_Reduction_Enrichment.yaml","text_sha256":"8a67dfcb12d99412fe115965ac5ee8f26d3b4cd72a9092926afd5d0fe293d788","x":-3.0278122425079346,"y":-1.3671060800552368},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000334","label":"Bosea-Pseudomonas Dimethachlon-Degradation Consortium","page":"communities/Bosea_Pseudomonas_Dimethachlon_Degradation_Consortium.html","source_path":"kb/communities/Bosea_Pseudomonas_Dimethachlon_Degradation_Consortium.yaml","text_sha256":"bdc72ae6e2cceca95fae46e7effddd8d936e40b144495dd58da6343b0141426e","x":-0.06300873309373856,"y":-0.6687812209129333},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000234","label":"Angelarchaeales Thermoplasmata CuMMO Soil and Sediment Community","page":"communities/Angelarchaeales_Thermoplasmata_CuMMO_Soil_Sediment_Community.html","source_path":"kb/communities/Angelarchaeales_Thermoplasmata_CuMMO_Soil_Sediment_Community.yaml","text_sha256":"40a492ab5d3c443e3d9b33001dece2bad37e95618c4b533902cd7cdbdf055c1d","x":-2.755842924118042,"y":-3.9422478675842285},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000058","label":"Rice-Duckweed Bacillus Biocontrol SynCom","page":"communities/Rice_Duckweed_Bacillus_SynCom.html","source_path":"kb/communities/Rice_Duckweed_Bacillus_SynCom.yaml","text_sha256":"a718845c7d76c6852c621349b577afedd3e8fda051a6d232c7e295c53c7ab757","x":4.808252334594727,"y":-1.5733025074005127},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000188","label":"Trichococcus-Syntrophomonas-Methanospirillum Butyrate Coculture","page":"communities/Trichococcus_Syntrophomonas_Methanospirillum_Butyrate_Coculture.html","source_path":"kb/communities/Trichococcus_Syntrophomonas_Methanospirillum_Butyrate_Coculture.yaml","text_sha256":"24123821b06a1740fb9a969989e259fec962bbf8c3693728f793106e9851c00d","x":-4.424880027770996,"y":1.1763719320297241},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000167","label":"Synechococcus-Pseudomonas Phototrophic PHA and DNT Coculture","page":"communities/Synechococcus_Pseudomonas_PhotoPHA_DNT_Coculture.html","source_path":"kb/communities/Synechococcus_Pseudomonas_PhotoPHA_DNT_Coculture.yaml","text_sha256":"b36548b3d9ed14c1def1e830a6bf499dbd0c1ac56ab5dbc84185d3e695c3b3e4","x":-2.009533405303955,"y":5.789278507232666},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000135","label":"SPRUCE Peatland Methane-Cycling Microbial Community","page":"communities/SPRUCE_Peatland_Methane_Cycling_Community.html","source_path":"kb/communities/SPRUCE_Peatland_Methane_Cycling_Community.yaml","text_sha256":"5e054fa7f4ceac07e9967ad4c0b18739e6e020e300015a6d79390969a06e4d66","x":-4.15395975112915,"y":-2.838934898376465},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000247","label":"Soil CPR Bacteria and Nanoarchaea Rare-Biosphere Community","page":"communities/Soil_CPR_Nanoarchaea_Rare_Biosphere_Community.html","source_path":"kb/communities/Soil_CPR_Nanoarchaea_Rare_Biosphere_Community.yaml","text_sha256":"2595faa2e836976a0002499083ef87a44f145cf257af88fd201e6bf08be63bc3","x":-0.3763359487056732,"y":-3.4482569694519043},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000330","label":"Poultry-Wastewater Three-Strain Electroactive Consortium","page":"communities/Poultry_Wastewater_ThreeStrain_Electroactive_Consortium.html","source_path":"kb/communities/Poultry_Wastewater_ThreeStrain_Electroactive_Consortium.yaml","text_sha256":"e9019a0fb76653fa70917faf8b2022fcf5730db05bee8e612b2c3c657b02d782","x":-2.014423370361328,"y":-1.2810828685760498},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000243","label":"Ngawha Geothermal Acidic Springs Mercury Cycling Community","page":"communities/Ngawha_Geothermal_Mercury_Cycling_Community.html","source_path":"kb/communities/Ngawha_Geothermal_Mercury_Cycling_Community.yaml","text_sha256":"59b2273432388e385da2038a503682421ec2623932fd0af389f2d96de8bb1a39","x":-3.11093807220459,"y":-3.857106924057007},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000221","label":"Soil Corrinoid Reservoir Microbial Community","page":"communities/Soil_Corrinoid_B12_Reservoir_Community.html","source_path":"kb/communities/Soil_Corrinoid_B12_Reservoir_Community.yaml","text_sha256":"822a5f414e0e54317fbdac1b60abfa062284acd4e07c45985fb47405c2007255","x":1.1671042442321777,"y":-3.195244073867798},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000317","label":"Human Gut Four-Member Proteome-Complementarity Consortium","page":"communities/Human_Gut_FourMember_Proteome_Complementarity_Consortium.html","source_path":"kb/communities/Human_Gut_FourMember_Proteome_Complementarity_Consortium.yaml","text_sha256":"63824860373dc6865bd41a01d660995a5c18b09053a32a8a7e884aa81049adde","x":2.708721399307251,"y":2.9416818618774414},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000090","label":"Populus Salt-Tolerant Rhizosphere SynComs","page":"communities/Populus_Salt_Tolerant_SynComs.html","source_path":"kb/communities/Populus_Salt_Tolerant_SynComs.yaml","text_sha256":"a3ddc314a98503374795177b7a8185a19dd8556a3f5ba8bd7b596e27ae35e222","x":4.59560489654541,"y":-2.7172205448150635},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000277","label":"Five-member bacterial-fungal composting SynCom for lignocellulose degradation","page":"communities/Composting_SynCom_Lignocellulose_Degradation_Humus.html","source_path":"kb/communities/Composting_SynCom_Lignocellulose_Degradation_Humus.yaml","text_sha256":"44fe296ee25bffb631b3e90dcaf46a75c5ef858efef3a68753c67a8d23cb483a","x":2.9333393573760986,"y":0.22478938102722168},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000051","label":"Panzhihua Vanadium Titanium Tailings Community","page":"communities/Panzhihua_Vanadium_Titanium_Tailings.html","source_path":"kb/communities/Panzhihua_Vanadium_Titanium_Tailings.yaml","text_sha256":"5d2e9100e5ced6e35c3f71baa053b8c2ac80ca5c73eea1d6227c54b8d5eb320d","x":-3.733257293701172,"y":-5.458905220031738},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000064","label":"Soybean N-Fixation Simplified SynCom","page":"communities/Soybean_N_Fixation_sfSynCom.html","source_path":"kb/communities/Soybean_N_Fixation_sfSynCom.yaml","text_sha256":"1decfa2280f7b884ca5e05fc65cfd747139cedcb8d13241a4949a3da1876f268","x":3.439673662185669,"y":-2.3692336082458496},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000147","label":"Trichodesmium-Alteromonas Marine Consortium","page":"communities/Trichodesmium_Alteromonas_Marine_Consortium.html","source_path":"kb/communities/Trichodesmium_Alteromonas_Marine_Consortium.yaml","text_sha256":"59d8c071bba6f8a66081f2901465ea856d315828ff1c7a5526065896dade00a9","x":-0.9480049014091492,"y":5.561702251434326},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000022","label":"Jeff Dangl's SynComm 35","page":"communities/Dangl_SynComm_35.html","source_path":"kb/communities/Dangl_SynComm_35.yaml","text_sha256":"1ec01d5c7eef275688087be66c596ecbec51dbc243916694f2b75e1c773aa192","x":3.963113307952881,"y":-2.1482415199279785},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000370","label":"Bacillus-Pseudomonas Galveston PET Consortium","page":"communities/Bacillus_Pseudomonas_Galveston_PET_Consortium.html","source_path":"kb/communities/Bacillus_Pseudomonas_Galveston_PET_Consortium.yaml","text_sha256":"7926cec43643cca09c2cb1c453b9a9503a80318c8abd564ba68d38fd0afbde5e","x":0.03732338547706604,"y":-0.6374204754829407},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000258","label":"Coastal Forested Wetland Seawater-Ion Microcosm Community","page":"communities/Coastal_Forested_Wetland_Seawater_Ion_Microcosm_Community.html","source_path":"kb/communities/Coastal_Forested_Wetland_Seawater_Ion_Microcosm_Community.yaml","text_sha256":"4f068d6aaeec4678e43036c9f07a79f87ff548748cca13e6ac66c3586282719c","x":-3.5943238735198975,"y":-3.273081064224243},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000091","label":"GLBRC Exometabolite Transwell SynCom System","page":"communities/GLBRC_Exometabolite_Transwell_SynCom.html","source_path":"kb/communities/GLBRC_Exometabolite_Transwell_SynCom.yaml","text_sha256":"169667da6b9761206ef7c3ba0cd6a85e25f46e990db9e646de54fc77a3ef9592","x":2.9088616371154785,"y":-0.6522002816200256},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000180","label":"Clostridium-Thermoanaerobacterium JN4-GD17 Cellulosic Biofuel Coculture","page":"communities/Clostridium_Thermoanaerobacterium_JN4_GD17_Cellulosic_Biofuel_Coculture.html","source_path":"kb/communities/Clostridium_Thermoanaerobacterium_JN4_GD17_Cellulosic_Biofuel_Coculture.yaml","text_sha256":"6a82a29bf4920fd123461962ef0fa9b234fd85403c6775645c4fcf9d29179dde","x":-1.3482341766357422,"y":2.101593255996704},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000164","label":"Yogurt Two-Species Starter Culture","page":"communities/Yogurt_TwoSpecies_Starter_Culture.html","source_path":"kb/communities/Yogurt_TwoSpecies_Starter_Culture.yaml","text_sha256":"37d78d5c111c21391e9650cb23c0a2465da57055f2c9f3293551e56e084fe3c3","x":1.9751824140548706,"y":4.006580352783203},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000092","label":"Rhodopseudomonas-E. coli Cross-Feeding Coculture","page":"communities/Rhodopseudomonas_Ecoli_CrossFeeding_Coculture.html","source_path":"kb/communities/Rhodopseudomonas_Ecoli_CrossFeeding_Coculture.yaml","text_sha256":"8f49f42aff21bdf7dfbce9fd665c3ae71f76e1eaed53e2770c3adb5e51db3288","x":-1.5187326669692993,"y":0.34601739048957825},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000070","label":"Syntrophomonas-Methanospirillum Syntrophic Consortium","page":"communities/Syntrophomonas_Methanospirillum_Syntrophy.html","source_path":"kb/communities/Syntrophomonas_Methanospirillum_Syntrophy.yaml","text_sha256":"db5cf1e36ef4e4fcf091d93802cd0edf819d5568a9d2e95f07ce26cbe948fa57","x":-4.759310245513916,"y":1.1111434698104858},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000066","label":"Synechococcus-E.coli Synthetic Photosynthetic Consortium","page":"communities/Synechococcus_Ecoli_SPC.html","source_path":"kb/communities/Synechococcus_Ecoli_SPC.yaml","text_sha256":"2e58527fd455c33b5bd2f5d8f6cd25880cdd6ad5f2c59559a32859bd26d4dc22","x":-2.0475051403045654,"y":5.98954963684082},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000309","label":"Mars Regolith Cyanobacteria/Microalga Biofertilizer Panel","page":"communities/Mars_Regolith_Cyanobacteria_Biofertilizer_Panel.html","source_path":"kb/communities/Mars_Regolith_Cyanobacteria_Biofertilizer_Panel.yaml","text_sha256":"5ff524dfea1c0679b3085297e41db6b97fbd86523ddb9e198df14f8d1582ac98","x":-3.4322621822357178,"y":-7.343360424041748},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000235","label":"Drought-Induced Rhizosphere Iron-Enriched Actinobacteria Community","page":"communities/Drought_Rhizosphere_Iron_Actinobacteria_Community.html","source_path":"kb/communities/Drought_Rhizosphere_Iron_Actinobacteria_Community.yaml","text_sha256":"c95088aeab1237901bdab93b1210c8266b7cd2e768bdefa4f864369e1404b050","x":2.3632824420928955,"y":-3.1070556640625},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000308","label":"Mars Meteorite EETA79001 Microbial Growth Panel","page":"communities/Mars_Meteorite_EETA79001_Growth_Panel.html","source_path":"kb/communities/Mars_Meteorite_EETA79001_Growth_Panel.yaml","text_sha256":"e5ea77f5c5e0f07306b4d263c001a30b20f83307d9a087ab009af73a395a511f","x":-3.4841907024383545,"y":-6.99834680557251},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000075","label":"Trichoderma Lactate Platform for SCFA Production","page":"communities/Trichoderma_Lactate_Platform.html","source_path":"kb/communities/Trichoderma_Lactate_Platform.yaml","text_sha256":"5378ff2c06481fdc83bda87599dcadc7c24712d65a7690abaab82c647a8f5c08","x":-0.575118899345398,"y":1.86744225025177},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000331","label":"Pseudomonas-Paracoccus Bifenthrin-Degrading Consortium","page":"communities/Pseudomonas_Paracoccus_Bifenthrin_Degradation_Consortium.html","source_path":"kb/communities/Pseudomonas_Paracoccus_Bifenthrin_Degradation_Consortium.yaml","text_sha256":"27cd1e9dba521e37fc1f8d54d7ab43da894b1d08341f58ca08d5dbffa24880cc","x":0.13352975249290466,"y":-0.496842622756958},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000293","label":"Crucian Carp Gut Disease-resistance SynCom","page":"communities/Crucian_Carp_Gut_Disease_Resistance_SynCom.html","source_path":"kb/communities/Crucian_Carp_Gut_Disease_Resistance_SynCom.yaml","text_sha256":"f30ecd00df9fa44175c14ae7102bed87f36ee2c06b40b695713931bf4c08d40b","x":3.733933210372925,"y":1.7854450941085815},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000107","label":"Tomato Oxylipin-Protective SynCom3","page":"communities/Tomato_Oxylipin_SynCom3.html","source_path":"kb/communities/Tomato_Oxylipin_SynCom3.yaml","text_sha256":"6febc92ed0db35692ca6ee5b1a9991b269b0af65aa1eeba0b06cd0d7684a7a34","x":5.11041259765625,"y":-1.8060718774795532},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000154","label":"Kombucha KMC-IMBG1 Fermentation Community","page":"communities/Kombucha_KMC_IMBG1_Fermentation_Community.html","source_path":"kb/communities/Kombucha_KMC_IMBG1_Fermentation_Community.yaml","text_sha256":"8a8b6a4278dbad32daf771f42381ddfb39c40c0d06cf32ae8c8c6db7b8e533ae","x":1.613957166671753,"y":2.66776442527771},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000097","label":"Banana Fusarium Wilt Biocontrol SynCom1.2","page":"communities/Banana_Fusarium_Biocontrol_SynCom12.html","source_path":"kb/communities/Banana_Fusarium_Biocontrol_SynCom12.yaml","text_sha256":"4d92b37946feebfe2f08d4f525b0004f764138ddff7b669c6361a89d6ecade92","x":4.996493339538574,"y":-1.5876225233078003},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000187","label":"Syntrophus-Methanospirillum Gentianae Benzoate Coculture","page":"communities/Syntrophus_Methanospirillum_Gentianae_Benzoate_Coculture.html","source_path":"kb/communities/Syntrophus_Methanospirillum_Gentianae_Benzoate_Coculture.yaml","text_sha256":"c96aa3154f02b951474f533a8058c41b3cdf07d0f3aacef2059772751f53136e","x":-4.449263095855713,"y":1.135298728942871},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000045","label":"Mixed Gallium LED Recovery Consortium","page":"communities/Mixed_Gallium_LED_Recovery_Consortium.html","source_path":"kb/communities/Mixed_Gallium_LED_Recovery_Consortium.yaml","text_sha256":"d83d05e94f8c4c2d24d49c28695e83b8512649817532bda2a75ee333468a630e","x":-3.9381823539733887,"y":-5.859334945678711},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000257","label":"MUCC Freshwater Wetland Methane-Cycling Network Community","page":"communities/MUCC_Freshwater_Wetland_Methane_Network_Community.html","source_path":"kb/communities/MUCC_Freshwater_Wetland_Methane_Network_Community.yaml","text_sha256":"ba05242fb054e97778742b6d0d284ea48fab9fbd3e80713fda10f4d9ddf6372e","x":-4.006744384765625,"y":-2.9861743450164795},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000123","label":"hCom2 Complex Gut Microbiome","page":"communities/hCom2_Complex_Gut_Microbiome.html","source_path":"kb/communities/hCom2_Complex_Gut_Microbiome.yaml","text_sha256":"135498f461889798bef9830dc41ec83086736908634d3a4e6a4937fb0bf2a0f5","x":3.490417242050171,"y":3.193545341491699},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000179","label":"Caldibacillus-Clostridium Aerotolerant Cellulose Coculture","page":"communities/Caldibacillus_Clostridium_Aerotolerant_Cellulose_Coculture.html","source_path":"kb/communities/Caldibacillus_Clostridium_Aerotolerant_Cellulose_Coculture.yaml","text_sha256":"eb842668353c5cf2349dc3550e3d8327ba8995401bdb97e826da2b1d1214a4e1","x":-1.4571236371994019,"y":2.209721088409424},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000328","label":"Waste-Sludge Electro-Fermentation Biofilm-Suspension Community","page":"communities/Waste_Sludge_Electrofermentation_Biofilm_Suspension_Community.html","source_path":"kb/communities/Waste_Sludge_Electrofermentation_Biofilm_Suspension_Community.yaml","text_sha256":"3fbc12646370f067aece2fdff1f983e4103e5b7bab78646479da5bf0aedeedbd","x":-3.0373828411102295,"y":-1.1412514448165894},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000291","label":"Pseudomonas stutzeri + Rhodococcus Naphthalene-degrading Biochar-bridged Engineered Consortium","page":"communities/Pseudomonas_stutzeri_Rhodococcus_Naphthalene_Biochar_Engineered_Consortium.html","source_path":"kb/communities/Pseudomonas_stutzeri_Rhodococcus_Naphthalene_Biochar_Engineered_Consortium.yaml","text_sha256":"0330755b933f484ecf129b0e88e4d30424087a0f157ad26cdd99cc33b6353e47","x":-0.8598461747169495,"y":-0.7264251708984375},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000157","label":"Microcoleus-Massilia Cyanosphere Urea Mutualism","page":"communities/Microcoleus_Massilia_Cyanosphere_Urea_Mutualism.html","source_path":"kb/communities/Microcoleus_Massilia_Cyanosphere_Urea_Mutualism.yaml","text_sha256":"6888347796e0498b1333ea128c0fa8976e853f9e46a48ecbd5eaa8390762a7fe","x":0.17761418223381042,"y":5.3429436683654785},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000027","label":"Ferroplasma-Leptospirillum Iron-Cycling Syntrophy","page":"communities/Ferroplasma_Leptospirillum_Syntrophy.html","source_path":"kb/communities/Ferroplasma_Leptospirillum_Syntrophy.yaml","text_sha256":"b01844267ac9fc5dd2f04b7457884dd830ada5d88acab2b29b5b8243ed38b685","x":-4.101283073425293,"y":-5.182791709899902},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000369","label":"Cyantraniliprole Fahmy Consortium T4","page":"communities/Cyantraniliprole_Fahmy_Consortium_T4.html","source_path":"kb/communities/Cyantraniliprole_Fahmy_Consortium_T4.yaml","text_sha256":"7a621fdbe73729c7ee4c22fefd5d010891f63296f14394c10e3438c1f2bf2b09","x":0.12701721489429474,"y":-0.6068823933601379},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000120","label":"Bacillus-Bradyrhizobium Straw Humification SynCom","page":"communities/Bacillus_Bradyrhizobium_Straw_Humification_SynCom.html","source_path":"kb/communities/Bacillus_Bradyrhizobium_Straw_Humification_SynCom.yaml","text_sha256":"8c0539977e8aec43a05201bf35bdb94d801dab31d6a74e9450297c868fb9dedb","x":3.3035778999328613,"y":-0.1272662729024887},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000046","label":"Naica Deep Subsurface Thermophilic Community","page":"communities/Naica_Deep_Subsurface_Thermophilic.html","source_path":"kb/communities/Naica_Deep_Subsurface_Thermophilic.yaml","text_sha256":"0cba1cd21681cb836977189e1eef46fd64a18c07d8e5384cdcbf4de5793304db","x":-3.419222354888916,"y":-3.680198907852173},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000138","label":"Hanford 300 Area Unconfined Aquifer Community","page":"communities/Hanford_300_Area_Unconfined_Aquifer_Community.html","source_path":"kb/communities/Hanford_300_Area_Unconfined_Aquifer_Community.yaml","text_sha256":"6c871e53dfb21a247f5460425f6574f40d5588c7b1d5bd30a088e7828d3a6044","x":-2.681903600692749,"y":-3.4565136432647705},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000143","label":"Emiliania huxleyi-Phaeobacter inhibens Dynamic Interaction","page":"communities/Emiliania_Phaeobacter_Dynamic_Interaction.html","source_path":"kb/communities/Emiliania_Phaeobacter_Dynamic_Interaction.yaml","text_sha256":"861d784a980f9a5aa4fe2dcb6a894033852d4e9acb31df83b7ae340fbc05ea7a","x":-0.708371102809906,"y":5.639191150665283},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000139","label":"Aalborg East Full-Scale EBPR Activated Sludge Community","page":"communities/Aalborg_East_Full_Scale_EBPR_Community.html","source_path":"kb/communities/Aalborg_East_Full_Scale_EBPR_Community.yaml","text_sha256":"faf6e7479a3a62a069143b90f6b744aec58f435b0562689a1a2c8c3c5385e222","x":-1.5926748514175415,"y":-2.559718370437622},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000020","label":"Coscinodiscus Synthetic Community","page":"communities/Coscinodiscus_Synthetic_Community.html","source_path":"kb/communities/Coscinodiscus_Synthetic_Community.yaml","text_sha256":"7e66060daa83ca777450bac85dd0b8f4356212d06451a79879733bbb3e570572","x":-0.8158887028694153,"y":5.916906356811523},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000007","label":"BioModels MODEL1806250004 Sharpshooter Sulcia-Baumannia Symbiosis","page":"communities/BioModels_MODEL1806250004_Sharpshooter_Sulcia_Baumannia.html","source_path":"kb/communities/BioModels_MODEL1806250004_Sharpshooter_Sulcia_Baumannia.yaml","text_sha256":"2ee34defe6d1a553d4e1f1972f9da021fcc0eb974ead606445917c8b731db128","x":1.4935436248779297,"y":5.008599281311035},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000327","label":"Methane-Fed MFC Electrogenesis and Nitrogen-Fixation Consortium","page":"communities/Methane_MFC_Electrogenesis_Nitrogen_Fixation_Consortium.html","source_path":"kb/communities/Methane_MFC_Electrogenesis_Nitrogen_Fixation_Consortium.yaml","text_sha256":"1bf7224f82696657391fa8bc8174e3928c9438e3e6b17cb37a794361b570a0c9","x":-3.5734050273895264,"y":-0.36164531111717224},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000371","label":"Rhodococcus-Pseudomonas Plastic Pyrolysis Oil Waste Consortium","page":"communities/Rhodococcus_Pseudomonas_PPOW_Consortium.html","source_path":"kb/communities/Rhodococcus_Pseudomonas_PPOW_Consortium.yaml","text_sha256":"572011eaf0473097bf4c1b7715e42e9217ed29d6228b7d356cd3784dbe2b7db1","x":-0.2362421452999115,"y":-0.611154317855835},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000305","label":"BioAsteroid ISS Chondrite Biomining Consortium","page":"communities/BioAsteroid_ISS_Chondrite_Biomining_Consortium.html","source_path":"kb/communities/BioAsteroid_ISS_Chondrite_Biomining_Consortium.yaml","text_sha256":"b8e5d8c89e007d035f11c5cf09be7533d1f039b93ce3216877c4b2f819223778","x":-3.591200351715088,"y":-6.806961536407471},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000217","label":"Cyprus Copper Sulphide Bioleaching Consortium","page":"communities/Cyprus_Copper_Sulphide_Bioleaching_Consortium.html","source_path":"kb/communities/Cyprus_Copper_Sulphide_Bioleaching_Consortium.yaml","text_sha256":"c12287d7ae230d9314e0f39423e66a636c6943345856ba2ac9ddea1c19b797e6","x":-4.10214376449585,"y":-5.768865585327148},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000175","label":"Clostridium cellulolyticum-Geobacter sulfurreducens Cellulose MFC Coculture","page":"communities/Clostridium_Cellulolyticum_Geobacter_Cellulose_MFC_Coculture.html","source_path":"kb/communities/Clostridium_Cellulolyticum_Geobacter_Cellulose_MFC_Coculture.yaml","text_sha256":"1e1ed6d21a6888ecd6b4498100fce9bcb6d2eff0233c03c5704c54f1f530056b","x":-2.3328120708465576,"y":1.0520073175430298},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000372","label":"Pseudomonas-Klebsiella-Alcaligenes Fe2+ Nitrogen-Removal SynCom","page":"communities/Pseudomonas_Klebsiella_Alcaligenes_FeII_Nitrogen_Removal_SynCom.html","source_path":"kb/communities/Pseudomonas_Klebsiella_Alcaligenes_FeII_Nitrogen_Removal_SynCom.yaml","text_sha256":"0cfe62805254ba07b193ee01711bc378251af50c25ebf6f66d6951d8794b66a9","x":-1.01242995262146,"y":-2.2954294681549072},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000290","label":"Phosphitivorax-Methanoculleus Lithosyntrophic Phosphite-Oxidizing Methanogenic Culture","page":"communities/Phosphitivorax_Methanoculleus_Lithosyntrophy_Phosphite_Coculture.html","source_path":"kb/communities/Phosphitivorax_Methanoculleus_Lithosyntrophy_Phosphite_Coculture.yaml","text_sha256":"1db1add23f6cb8074fa77ec05532eb8dd4f43395f08080c8b85d08377a86aef1","x":-5.0016326904296875,"y":0.8211683034896851},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000109","label":"Rice Acid Soil Bioinoculant SynCom","page":"communities/Rice_Acid_Soil_Bioinoculant_SynCom.html","source_path":"kb/communities/Rice_Acid_Soil_Bioinoculant_SynCom.yaml","text_sha256":"457d57760279ebd8cd9d3927e0f8144c8113a2f7367520fef58df1c7ca31e0b3","x":4.34357213973999,"y":-2.4835593700408936},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000102","label":"Peanut Seed Bacterial CS SynCom","page":"communities/Peanut_Seed_Bacterial_CS_SynCom.html","source_path":"kb/communities/Peanut_Seed_Bacterial_CS_SynCom.yaml","text_sha256":"61134180237845a78e2771bf34fed05b05cb20e2b8230165df1c62474b15b988","x":4.980342864990234,"y":-1.5437393188476562},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000270","label":"Trichoderma-Streptomyces Filamentous Cellulose Coculture","page":"communities/Trichoderma_Streptomyces_Filamentous_Cellulose_Coculture.html","source_path":"kb/communities/Trichoderma_Streptomyces_Filamentous_Cellulose_Coculture.yaml","text_sha256":"3afd42c8b11dc865add070cda0190c22ed1041251feb87551d2c4043b2f34270","x":-0.9458903670310974,"y":2.159039258956909},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000216","label":"PSY Transgenic Rice Rhizosphere Methane-Mitigating Community","page":"communities/PSY_Transgenic_Rice_Rhizosphere_Methane_Community.html","source_path":"kb/communities/PSY_Transgenic_Rice_Rhizosphere_Methane_Community.yaml","text_sha256":"040343e537d0a48f47ddb3e68d89be3e506c33df3b6f6b8759104c76581875e7","x":2.75589656829834,"y":-3.109100818634033},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000190","label":"Pelotomaculum-Methanocella Propionate RNA-Seq Coculture","page":"communities/Pelotomaculum_Methanocella_Propionate_RNASeq_Coculture.html","source_path":"kb/communities/Pelotomaculum_Methanocella_Propionate_RNASeq_Coculture.yaml","text_sha256":"d1fa118e8461557da402470babf251622e0295a02ae04e5047bde38f570d8f40","x":-4.693282604217529,"y":1.0520857572555542},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000349","label":"Bothnian Bay GAC-Dependent CIET-SAO Consortium","page":"communities/Bothnian_Bay_GAC_Dependent_CIET_SAO_Consortium.html","source_path":"kb/communities/Bothnian_Bay_GAC_Dependent_CIET_SAO_Consortium.yaml","text_sha256":"8d1db53ad360b932799caba8d4b970dd4d8a7cfc3713700b5cb80dd803239613","x":-3.940835952758789,"y":-0.5427630543708801},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000196","label":"Clostridium phytofermentans-E. coli Cellobiose Biofilm Consortium","page":"communities/Clostridium_Phytofermentans_Ecoli_Cellobiose_Biofilm_Consortium.html","source_path":"kb/communities/Clostridium_Phytofermentans_Ecoli_Cellobiose_Biofilm_Consortium.yaml","text_sha256":"19b3f50a41079d3a47e5322232f6e87a046eaab0011489485ccb3223791a2ba5","x":-0.8291029334068298,"y":2.2068238258361816},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000378","label":"Soy Sauce Temporal Seven-Species SynCom","page":"communities/Soy_Sauce_Temporal_SevenSpecies_SynCom.html","source_path":"kb/communities/Soy_Sauce_Temporal_SevenSpecies_SynCom.yaml","text_sha256":"31fd205fd2797f5761ca2ed66e1bc9ada1a5e806b7c324fa84ef19d66eb51fc0","x":2.7564918994903564,"y":1.7080233097076416},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000274","label":"Multi-stage Anaerobic-Digestion SynCom-YSJ and SynCom-J","page":"communities/Multi_stage_Anaerobic_Digestion_SynCom_YSJ_and_SynCom_J.html","source_path":"kb/communities/Multi_stage_Anaerobic_Digestion_SynCom_YSJ_and_SynCom_J.yaml","text_sha256":"76588b3a142fb64c6a21690cea33ba461cff1a748e0b0cc95b01badbd8c9c473","x":2.8520567417144775,"y":1.3210304975509644},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000203","label":"Shewanella-Streptococcus Starch-Fueled Microbial Fuel Cell Coculture","page":"communities/Shewanella_Streptococcus_Starch_Microbial_Fuel_Cell.html","source_path":"kb/communities/Shewanella_Streptococcus_Starch_Microbial_Fuel_Cell.yaml","text_sha256":"4eb1da14883d7adcc8d90b8988b4e45feca3585e3697689ee39b6029c75cd857","x":-2.739518880844116,"y":-0.1009209156036377},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000254","label":"Stordalen Mire Methylotrophic Methanogenesis Community","page":"communities/Stordalen_Mire_Methylotrophic_Methanogenesis_Community.html","source_path":"kb/communities/Stordalen_Mire_Methylotrophic_Methanogenesis_Community.yaml","text_sha256":"0af8484b3a8eb625dd43346e08193079885e6f2616a0421db466e13d6cb8b431","x":-4.311368942260742,"y":-2.888979434967041},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000186","label":"Thermotoga-Methanocaldococcus Hyperthermophilic Syntrophy","page":"communities/Thermotoga_Methanocaldococcus_Hyperthermophilic_Syntrophy.html","source_path":"kb/communities/Thermotoga_Methanocaldococcus_Hyperthermophilic_Syntrophy.yaml","text_sha256":"ff4a1fdfa8c45325a48a2609ac79329456229a7e2a71c1c4d83f076835f74d95","x":-4.284730434417725,"y":1.1672531366348267},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000368","label":"Arabidopsis Bacillus Biocontrol SynCom150","page":"communities/Arabidopsis_Bacillus_Biocontrol_SynCom150.html","source_path":"kb/communities/Arabidopsis_Bacillus_Biocontrol_SynCom150.yaml","text_sha256":"8b48b8c64e3f57178f60b6c7bbf8f56d36e1314f3c80fbbfcbc8f913eb2c59e0","x":4.627889156341553,"y":-1.408437728881836},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000312","label":"Suillus clintonianus-Bacillus altitudinis Thiamine Cross-Feeding SynCom","page":"communities/Suillus_Bacillus_Thiamine_Ectomycorrhizal_SynCom.html","source_path":"kb/communities/Suillus_Bacillus_Thiamine_Ectomycorrhizal_SynCom.yaml","text_sha256":"9ccd1f325f95ff41b1f4767c7cbad5ab055a16f8ca5803a0e11e568edee5fc22","x":0.3533945083618164,"y":5.2755255699157715},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000201","label":"Geobacter-Pseudomonas Formate-Fumarate Electroactive Coculture","page":"communities/Geobacter_Pseudomonas_Formate_Fumarate_Electroactive_Coculture.html","source_path":"kb/communities/Geobacter_Pseudomonas_Formate_Fumarate_Electroactive_Coculture.yaml","text_sha256":"649b0f771f240c575026f156c5b3fe63ab829a70d57fba0b18a1e3565e897f3f","x":-3.4152019023895264,"y":-0.6499712467193604},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000115","label":"Aerobic Denitrification Quorum-Quenching SynCom","page":"communities/Aerobic_Denitrification_QQ_SynCom.html","source_path":"kb/communities/Aerobic_Denitrification_QQ_SynCom.yaml","text_sha256":"7254185aeafb26d245ee9e4572a3b37901d370e3c9d038914b1a03cf8f3a2803","x":-1.1003257036209106,"y":-2.2768259048461914},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000362","label":"Sphingobium-Nitrososphaera Phenanthrene-Carbon SynCom","page":"communities/Sphingobium_Nitrososphaera_Phenanthrene_Carbon_SynCom.html","source_path":"kb/communities/Sphingobium_Nitrososphaera_Phenanthrene_Carbon_SynCom.yaml","text_sha256":"e5dacff3d1643a66d7ba14c96ee8fb0978fe22f38cbab361b9550889b42a2f73","x":3.483179807662964,"y":-1.307934284210205},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000008","label":"BioModels MODEL1806250005 Cicada Sulcia-Hodgkinia Symbiosis","page":"communities/BioModels_MODEL1806250005_Cicada_Sulcia_Hodgkinia.html","source_path":"kb/communities/BioModels_MODEL1806250005_Cicada_Sulcia_Hodgkinia.yaml","text_sha256":"c345d03a68790d3e8703cbad7e49a2f54c8ce17e9c54167f46be60ef2c0d7fcc","x":1.348326563835144,"y":4.94379186630249},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000055","label":"Polaromonas Vanadium Reduction Community","page":"communities/Polaromonas_Vanadium_Reduction_Community.html","source_path":"kb/communities/Polaromonas_Vanadium_Reduction_Community.yaml","text_sha256":"1772251093fa0591e14abf11dbb4548bea14211debd31040057c094d65f44354","x":-3.6813440322875977,"y":-4.756480693817139},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000098","label":"Watermelon Rhizosphere Fusarium-Protective SynCom8","page":"communities/Watermelon_Rhizosphere_Fusarium_SynCom8.html","source_path":"kb/communities/Watermelon_Rhizosphere_Fusarium_SynCom8.yaml","text_sha256":"c5a2cb1e1b08daef4db9bc36700651a62163a590b24b109c9bb59a4a23ac284f","x":5.019539833068848,"y":-1.9306188821792603},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000095","label":"Garlic Rhizosphere Pseudomonas SynCom6","page":"communities/Garlic_Pseudomonas_SynCom6.html","source_path":"kb/communities/Garlic_Pseudomonas_SynCom6.yaml","text_sha256":"652b5fc52b2fd1e7746f78f44d1b296094f36e40bf3c163d82a1976dc7214181","x":4.677220344543457,"y":-2.4951729774475098},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000145","label":"Cable Bacteria beneath Photosynthetic Biofilm Sediment Community","page":"communities/Cable_Bacteria_Photosynthetic_Biofilm_Sediment.html","source_path":"kb/communities/Cable_Bacteria_Photosynthetic_Biofilm_Sediment.yaml","text_sha256":"48268501c5b65b2fb35b417687cb003266682f565b804de9a50ff22bedf13791","x":-3.861647367477417,"y":-1.7458840608596802},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000325","label":"Euglena-Chlorella Microalgal Biorefinery Coculture","page":"communities/Euglena_Chlorella_Microalgal_Biorefinery_Coculture.html","source_path":"kb/communities/Euglena_Chlorella_Microalgal_Biorefinery_Coculture.yaml","text_sha256":"38650bcc22effdce6e7692708e487c9e4aeeb451b6ef9306fb24538186235f9d","x":-1.1788386106491089,"y":5.341737270355225},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000077","label":"Wheat Synthetic Consortium C6","page":"communities/Wheat_Consortium_C6.html","source_path":"kb/communities/Wheat_Consortium_C6.yaml","text_sha256":"10420158e3a2b85205d4ee1bf8e1d5b0d6f20b83b244ca0203f2821135b95937","x":4.354160785675049,"y":-2.027540922164917},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000004","label":"Australian Lead Zinc Polymetallic Tailings Consortium","page":"communities/Australian_Lead_Zinc_Polymetallic.html","source_path":"kb/communities/Australian_Lead_Zinc_Polymetallic.yaml","text_sha256":"c2239df1da100991c56ad158825d8ebd3fd6add2c1d024a467f822ad80819dda","x":-3.9291694164276123,"y":-5.445849895477295},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000111","label":"Miscanthus REE Tailings Nitrogen SynCom10","page":"communities/Miscanthus_REE_Tailings_Nitrogen_SynCom10.html","source_path":"kb/communities/Miscanthus_REE_Tailings_Nitrogen_SynCom10.yaml","text_sha256":"91d4136d43696838890aa263bae4cb9b49397ac72db1ecd11e0eb86f700117c5","x":2.8449907302856445,"y":-1.2247005701065063},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000307","label":"Anabaena / MGS-1 Anaerobic-Digestion Methanogen Consortium","page":"communities/Anabaena_MGS1_Anaerobic_Digestion_Methanogen_Consortium.html","source_path":"kb/communities/Anabaena_MGS1_Anaerobic_Digestion_Methanogen_Consortium.yaml","text_sha256":"1d7c873ab238738f848c4e62536f309946152a8376fb16813fb730787fd08684","x":-3.362839460372925,"y":-6.959606647491455},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000279","label":"Shewanella oneidensis MR-1 - Rhodopseudomonas palustris Electro-syntrophic Co-culture","page":"communities/Shewanella_oneidensis_Rhodopseudomonas_palustris_Electrosyntrophic_Coculture.html","source_path":"kb/communities/Shewanella_oneidensis_Rhodopseudomonas_palustris_Electrosyntrophic_Coculture.yaml","text_sha256":"0415b6270790d5a20e64561da327b0f038c4e4528effcfe15e8dd73e1ebad87e","x":-2.4866840839385986,"y":-0.3492859899997711},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000038","label":"KBase ORT Workflow Community Model","page":"communities/KBase_ORT_Workflow_Community_Model.html","source_path":"kb/communities/KBase_ORT_Workflow_Community_Model.yaml","text_sha256":"7ae05272e5f1849768e340d62f8685f367bc034bc9c4eb33952f14f06a57d292","x":-1.3158756494522095,"y":-2.7177374362945557},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000233","label":"East River Hillslope Riparian Transect Microbial Community","page":"communities/East_River_Hillslope_Riparian_Transect_Community.html","source_path":"kb/communities/East_River_Hillslope_Riparian_Transect_Community.yaml","text_sha256":"4e740dfc11574f72d498799eaa635462a12d0e52ef2c7c9403c8a58e8557fb2d","x":-2.9187417030334473,"y":-3.410473346710205},{"adapter_version":"communitymech-semantic-v1","category":"AMD","identifier":"CommunityMech:000034","label":"Iberian Pit Lake Stratified Community","page":"communities/Iberian_Pit_Lake_Stratified_Community.html","source_path":"kb/communities/Iberian_Pit_Lake_Stratified_Community.yaml","text_sha256":"f5ba3bb03c5bed5d07edbe65920e68acce25a5f1975e46b35c69844491fdecff","x":-3.7707083225250244,"y":-4.1617889404296875},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000242","label":"Groundwater Elusimicrobia Diverse Metabolisms Community","page":"communities/Groundwater_Elusimicrobia_Diverse_Metabolisms.html","source_path":"kb/communities/Groundwater_Elusimicrobia_Diverse_Metabolisms.yaml","text_sha256":"6e7ca6ff35683f29b533e6adc56c9a48cada86a4ad1a04099781da2793ff800a","x":-2.5375869274139404,"y":-3.460263729095459},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000377","label":"Apple Fire Blight A+N+P SynCom","page":"communities/Apple_Fire_Blight_ANP_SynCom.html","source_path":"kb/communities/Apple_Fire_Blight_ANP_SynCom.yaml","text_sha256":"cd05d26ae97bf2459df539d8aa24f22f0281f5baf3d5d86e04eee5b1da7d3222","x":4.494614124298096,"y":-1.0384254455566406},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000061","label":"SF356 Thermophilic Cellulose-Degrading Community","page":"communities/SF356_Cellulose_Degrader.html","source_path":"kb/communities/SF356_Cellulose_Degrader.yaml","text_sha256":"2cffbfcd09ba5671f85dc87be3e8ab0fad4bb6dd7dc4faad318ff972ac91e3c5","x":-1.2555031776428223,"y":1.6976526975631714},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000284","label":"Black Soldier Fly Larvae Gut SynCom (Bacillus + Lactobacillus + Issatchenkia)","page":"communities/BSFL_Gut_SynCom_Bacillus_Lactobacillus_Issatchenkia.html","source_path":"kb/communities/BSFL_Gut_SynCom_Bacillus_Lactobacillus_Issatchenkia.yaml","text_sha256":"f9b66d5e2dd6efbd6326c7e8a2bb140b96c2ba64420fe3b5f96ef27304555286","x":3.429788827896118,"y":1.063599944114685},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000356","label":"Jiangshui LAB Directed Fermentation SynCom","page":"communities/Jiangshui_LAB_Directed_Fermentation_SynCom.html","source_path":"kb/communities/Jiangshui_LAB_Directed_Fermentation_SynCom.yaml","text_sha256":"01d466777a4d248c9e065e03c0264ef93e5a8aca43ff25190f1b181edb931e20","x":3.4013922214508057,"y":0.8610829710960388},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000338","label":"Caragana korshinskii Cross-Kingdom Forage Bio-Valorization SynCom","page":"communities/Caragana_Korshinskii_CrossKingdom_Forage_SynCom.html","source_path":"kb/communities/Caragana_Korshinskii_CrossKingdom_Forage_SynCom.yaml","text_sha256":"8acb2ccb76c1f863f61bff504557fc611d15ed48abfb4d2b69a743f5093abf19","x":2.4839961528778076,"y":0.8957006931304932},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000224","label":"Grassland Soil Wet-Up Virus-Host Community","page":"communities/Grassland_Soil_WetUp_Virus_Host_Community.html","source_path":"kb/communities/Grassland_Soil_WetUp_Virus_Host_Community.yaml","text_sha256":"b2c6a34a31d6d4ca786719b820adf62d6897b2963692873a815d1da1cdbf06f3","x":0.9897266030311584,"y":-3.447410821914673},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000006","label":"BioModels MODEL1806250003 Spittlebug Sulcia-Sodalis Symbiosis","page":"communities/BioModels_MODEL1806250003_Spittlebug_Sulcia_Sodalis.html","source_path":"kb/communities/BioModels_MODEL1806250003_Spittlebug_Sulcia_Sodalis.yaml","text_sha256":"85fa1bbe6add0d0591d36eb04b16c7b9403fbdf8ec221aeaa4df292f01d05182","x":1.1443381309509277,"y":5.1001482009887695},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000021","label":"DVM Tri-culture","page":"communities/DVM_Triculture.html","source_path":"kb/communities/DVM_Triculture.yaml","text_sha256":"b735eb0babe5ac62b8ae7017980fb23e423ae3eaedc8c1b8753750de31b6568e","x":-3.2618627548217773,"y":1.2423691749572754},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000214","label":"Model Cyanobacterial Consortia Core Microbiome","page":"communities/Model_Cyanobacterial_Consortia_Core_Microbiome.html","source_path":"kb/communities/Model_Cyanobacterial_Consortia_Core_Microbiome.yaml","text_sha256":"2039779a0ad1cca56fa3a0c4fd8ebe69c33dbf2be6c9d7b7e33022a123939e5f","x":-1.0997679233551025,"y":5.419238567352295},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000286","label":"Dual Bacillus coagulans + Pseudomonas putida Lactic-acid Co-culture","page":"communities/Dual_Bacillus_coagulans_Pseudomonas_putida_Lactic_Acid_Coculture.html","source_path":"kb/communities/Dual_Bacillus_coagulans_Pseudomonas_putida_Lactic_Acid_Coculture.yaml","text_sha256":"611632229b422c7d503b26684bce20890892c51772ed43bc3c2591aa13b01e4d","x":0.32249385118484497,"y":1.8509604930877686},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000299","label":"Ensifer YF2 + Sphingobacterium Y2 Polyethylene-degrading Consortium","page":"communities/Ensifer_YF2_Sphingobacterium_Y2_Polyethylene_Degrading_Consortium.html","source_path":"kb/communities/Ensifer_YF2_Sphingobacterium_Y2_Polyethylene_Degrading_Consortium.yaml","text_sha256":"57649717b9facc1655e0e8b5d9851f51dc80c56f17a4633dac45a327fbe0af5e","x":0.15291336178779602,"y":0.1493217796087265},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000361","label":"RH1 Glyphosate Streptomyces Consortium","page":"communities/RH1_Glyphosate_Streptomyces_Consortium.html","source_path":"kb/communities/RH1_Glyphosate_Streptomyces_Consortium.yaml","text_sha256":"c3488d4fbd9e1daa655a2e4d366dc9c9af7322c429bd2daf7209842b51a6af6a","x":0.23808063566684723,"y":-0.6495811343193054},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000072","label":"TYQ1 Nematode Biocontrol SynCom","page":"communities/TYQ1_Nematode_Biocontrol_SynCom.html","source_path":"kb/communities/TYQ1_Nematode_Biocontrol_SynCom.yaml","text_sha256":"449ccabf9055c3216aa863584516788065f2efe3004c8b43966c7b5b8ce032a2","x":3.4889862537384033,"y":-2.4034905433654785},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000189","label":"Syntrophomonas-Methanococcus Butyrate Growth Coordination Coculture","page":"communities/Syntrophomonas_Methanococcus_Butyrate_Growth_Coordination_Coculture.html","source_path":"kb/communities/Syntrophomonas_Methanococcus_Butyrate_Growth_Coordination_Coculture.yaml","text_sha256":"38a8fdfdf7afe7074e05dd3c412c85cd190d6bb73f20fd52f3f496722447e6ee","x":-4.389737129211426,"y":1.1245968341827393},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000015","label":"Chlamydomonas-Methylobacterium Mutualistic Consortium","page":"communities/Chlamydomonas_Methylobacterium_Mutualism.html","source_path":"kb/communities/Chlamydomonas_Methylobacterium_Mutualism.yaml","text_sha256":"c9ac43a28c754c347a65495fc0acd456855e9e7493bedfeab4390fbdfcdb2cfe","x":-1.0773333311080933,"y":5.382490158081055},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000183","label":"Dehalococcoides-Syntrophomonas TCE Dechlorination Coculture","page":"communities/Dehalococcoides_Syntrophomonas_TCE_Dechlorination_Coculture.html","source_path":"kb/communities/Dehalococcoides_Syntrophomonas_TCE_Dechlorination_Coculture.yaml","text_sha256":"09a3a7cc2e9521dddcf78f896e3d5b0a2f45dd2938cf5f58207a71263ebba84f","x":-2.2580690383911133,"y":-0.2714608907699585},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000096","label":"Desert-Derived Tomato Salt Stress SynCom5","page":"communities/Desert_Tomato_Salt_Stress_SynCom5.html","source_path":"kb/communities/Desert_Tomato_Salt_Stress_SynCom5.yaml","text_sha256":"d90f6b0c586804c2cc97bafb899415290a92bd50806162d0bee57019f80a2f18","x":4.834463119506836,"y":-2.1985297203063965},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000227","label":"Mediterranean Grassland qSIP Rainfall-Gradient Community","page":"communities/Mediterranean_Grassland_qSIP_Rainfall_Community.html","source_path":"kb/communities/Mediterranean_Grassland_qSIP_Rainfall_Community.yaml","text_sha256":"f993e66e1fe1786ff03ff32a579566310df703dfa4ec9c4751d99108e9f632da","x":1.5645631551742554,"y":-3.2563602924346924},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000130","label":"Synthetic Periphyton Freshwater Biofilm","page":"communities/Synthetic_Periphyton_Freshwater_Biofilm.html","source_path":"kb/communities/Synthetic_Periphyton_Freshwater_Biofilm.yaml","text_sha256":"6985136d42439914e6d0d72b31a7239d987b1f3caba83096a908d8b911fc54f5","x":0.998306930065155,"y":5.7290568351745605},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000294","label":"Corynebacterium glutamicum + Shewanella oneidensis Succinic-acid Co-culture","page":"communities/Corynebacterium_glutamicum_Shewanella_oneidensis_Succinic_Acid_Coculture.html","source_path":"kb/communities/Corynebacterium_glutamicum_Shewanella_oneidensis_Succinic_Acid_Coculture.yaml","text_sha256":"01f6cb22d5473d55c4e288b32bd39e7c7c92fa3687a96403ee887994f5cff48f","x":-2.880687952041626,"y":0.23151834309101105},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000117","label":"Urine Nitrification Synthetic Microbial Community","page":"communities/Urine_Nitrification_SynCom.html","source_path":"kb/communities/Urine_Nitrification_SynCom.yaml","text_sha256":"4fcd874c4ac7a6b21caae1c645509a6d6b1fa95bda813f98c905174f925fbb8b","x":-0.9691106677055359,"y":-2.2511980533599854},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000220","label":"Bifidobacterium-Ruminococcus Infant HMO Cross-Feeding Coculture","page":"communities/Bifidobacterium_Ruminococcus_Infant_HMO_CrossFeeding.html","source_path":"kb/communities/Bifidobacterium_Ruminococcus_Infant_HMO_CrossFeeding.yaml","text_sha256":"263cad44c8f85189ccc2e97ab190bb540da4798635c62fe4ecbbb8c2a39c998e","x":2.885499954223633,"y":3.626985788345337},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000182","label":"Thermacetogenium-Methanothermobacter Acetate Oxidation Coculture","page":"communities/Thermacetogenium_Methanothermobacter_Acetate_Oxidation_Coculture.html","source_path":"kb/communities/Thermacetogenium_Methanothermobacter_Acetate_Oxidation_Coculture.yaml","text_sha256":"0a593c312c37bed20972d2161ae4e91e81aceb6bc93237fe221dac7009c38083","x":-4.14941930770874,"y":1.4450867176055908},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000237","label":"Episymbiotic CPR Bacteria and DPANN Archaea Groundwater Community","page":"communities/Episymbiotic_CPR_DPANN_Groundwater_Community.html","source_path":"kb/communities/Episymbiotic_CPR_DPANN_Groundwater_Community.yaml","text_sha256":"4f6cccba713e5c64a0d59131299386adcd83889c4f95dd02cc5a2796617b7f6a","x":-2.479248523712158,"y":-3.451772928237915},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000029","label":"GLBRC Ultra-Filtered Milk Permeate Fermentation Community","page":"communities/GLBRC_UFMP_Fermentation_Community.html","source_path":"kb/communities/GLBRC_UFMP_Fermentation_Community.yaml","text_sha256":"4f0d3044e93ec812bc4a77f8fab4f2f1f74923ee5b9ba266075978de831a1a9c","x":1.1817338466644287,"y":2.7898130416870117},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000134","label":"ANME-SRB Marine Methane Seep Consortium","page":"communities/ANME_SRB_Marine_Methane_Seep_Consortium.html","source_path":"kb/communities/ANME_SRB_Marine_Methane_Seep_Consortium.yaml","text_sha256":"d650b4e410721fbc52733efdc7e40e818a5478e73f0d1f173e16adea43cf8130","x":-4.072662830352783,"y":-1.6337060928344727},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000131","label":"Prochlorococcus-Alteromonas Helper Coculture","page":"communities/Prochlorococcus_Alteromonas_Helper_Coculture.html","source_path":"kb/communities/Prochlorococcus_Alteromonas_Helper_Coculture.yaml","text_sha256":"192834da8f8ecf5391d03b588d6111d6230f5319c85829ce08989b6f182b82dd","x":-1.3964345455169678,"y":5.285477161407471},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000297","label":"DIET-based Simplified Lignocellulose-to-Methane Consortia (DIETsimp)","page":"communities/DIETsimp_Lignocellulose_to_Methane_DIET_Consortia.html","source_path":"kb/communities/DIETsimp_Lignocellulose_to_Methane_DIET_Consortia.yaml","text_sha256":"0e4cc2b7d32d6c1226853a83431732886284b646edbcba271e281d372be5c764","x":-3.089473247528076,"y":0.270374596118927},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000359","label":"PPHET Hybrid Photosynthetic PHB Microbiome","page":"communities/PPHET_Hybrid_Photosynthetic_PHB_Microbiome.html","source_path":"kb/communities/PPHET_Hybrid_Photosynthetic_PHB_Microbiome.yaml","text_sha256":"50ed0161a0cab4e8e25175321f00360b291e22b0c5a405d7144946dafcefc490","x":-1.823862075805664,"y":5.322712421417236},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000153","label":"Cheese Rind In Situ-In Vitro Model Community","page":"communities/Cheese_Rind_InSitu_InVitro_Model_Community.html","source_path":"kb/communities/Cheese_Rind_InSitu_InVitro_Model_Community.yaml","text_sha256":"e7b2642144eb0b26852f7625061ca86833fbd4fe88828a14ab94afcde9fdf3d6","x":2.5420210361480713,"y":4.738116264343262},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000333","label":"Clostridium-E. coli-Nitratidesulfovibrio Minority-Mediator Consortium","page":"communities/Clostridium_Ecoli_Nitratidesulfovibrio_Minority_Mediator_Consortium.html","source_path":"kb/communities/Clostridium_Ecoli_Nitratidesulfovibrio_Minority_Mediator_Consortium.yaml","text_sha256":"a80981e45461ecb217066127bcbf1f5cad03b9b5abf866bb6e79273f3597573c","x":0.6879491806030273,"y":2.563094139099121},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000355","label":"Bacillus-Saccharomyces Daqu Spatial-Cooperation SynCom","page":"communities/Bacillus_Saccharomyces_Daqu_Spatial_Cooperation_SynCom.html","source_path":"kb/communities/Bacillus_Saccharomyces_Daqu_Spatial_Cooperation_SynCom.yaml","text_sha256":"5321f95739ae18f6ac18fc3320fb957e5b22afde2fd916434ff8437518e12498","x":1.0826585292816162,"y":2.0179858207702637},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000137","label":"East River Floodplain Core Microbiome","page":"communities/East_River_Floodplain_Core_Microbiome.html","source_path":"kb/communities/East_River_Floodplain_Core_Microbiome.yaml","text_sha256":"d45d658d91d5fb99bca98e36989bf7b1c1e9e18b47792a7295a2369418fdd65a","x":-3.5742249488830566,"y":-3.105034351348877},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000146","label":"Anammox Granule Metabolic Interaction Community","page":"communities/Anammox_Granule_Metabolic_Interaction_Community.html","source_path":"kb/communities/Anammox_Granule_Metabolic_Interaction_Community.yaml","text_sha256":"9ba1d1b00187798a79a42befd6f30e5a5bfb8401bdf9d5d46c3ebc4f455435dd","x":-1.4380992650985718,"y":-2.46596360206604},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000073","label":"Thermophilic Pyrite Quorum Sensing Consortium","page":"communities/Thermophilic_Pyrite_QS_Consortium.html","source_path":"kb/communities/Thermophilic_Pyrite_QS_Consortium.yaml","text_sha256":"bbfd98195f86f2565b29b67c5b489cedf6c34cb22da9cf0ab74810e5e1c3ffa2","x":-4.104835510253906,"y":-5.509669303894043},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000316","label":"Eucalyptus Nursery Five-Strain Bacterial Inoculant Consortium","page":"communities/Eucalyptus_Nursery_FiveStrain_Inoculant_SynCom.html","source_path":"kb/communities/Eucalyptus_Nursery_FiveStrain_Inoculant_SynCom.yaml","text_sha256":"32412095d46e09442e2b4ebb86cefc962b476a326f3c275b8c8477f2c0da475e","x":3.105376720428467,"y":-2.695136070251465},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000278","label":"SynCom BsBv Cigar Tobacco Leaf Fermentation","page":"communities/SynCom_BsBv_Cigar_Tobacco_Leaf_Fermentation.html","source_path":"kb/communities/SynCom_BsBv_Cigar_Tobacco_Leaf_Fermentation.yaml","text_sha256":"e058e925a4967fe769dce915d2a311cfd6899f0c190d8214ff6dd07f19b527d8","x":3.8989038467407227,"y":0.14796464145183563},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000084","label":"Streptococcus mutans - Selenomonas sputigena ECC Pathobiont Model","page":"communities/SMutans_SSputigena_ECC_Pathobiont.html","source_path":"kb/communities/SMutans_SSputigena_ECC_Pathobiont.yaml","text_sha256":"3730ef94dc2443bcf31de3c28482362c8a47063c7ee7c429d8edb5fead70c178","x":2.436523675918579,"y":5.083737850189209},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000321","label":"BioModels MODEL2204300002 Kefir Rothia Model","page":"isolates/BioModels_MODEL2204300002_Kefir_Rothia_Model.html","source_path":"data/isolates/BioModels_MODEL2204300002_Kefir_Rothia_Model.yaml","text_sha256":"857802b9924ff80a1d8b4be2f03c9a1197dcb3be45eff0698036ac988d2a467c","x":1.5753692388534546,"y":4.756189346313477},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000140","label":"Saanich Inlet Oxygen Minimum Zone Redox-Gradient Community","page":"communities/Saanich_Inlet_OMZ_Redox_Gradient_Community.html","source_path":"kb/communities/Saanich_Inlet_OMZ_Redox_Gradient_Community.yaml","text_sha256":"1ac3fba76103dadf343bc88f80e8700ffcf2b3814a86e1af58e69c004f98a1d4","x":-3.5108394622802734,"y":-2.581112861633301},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000105","label":"Pepper Phytophthora-Resistance SynCom5","page":"communities/Pepper_Phytophthora_SynCom5.html","source_path":"kb/communities/Pepper_Phytophthora_SynCom5.yaml","text_sha256":"aafbdff645437805ae3717f6a233783a6dbe895ae700b30e63ca6216ce282547","x":5.128303527832031,"y":-1.8556197881698608},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000152","label":"Industrial Milk-Line Four-Species Model Biofilm","page":"communities/Industrial_Milk_Line_FourSpecies_Model_Biofilm.html","source_path":"kb/communities/Industrial_Milk_Line_FourSpecies_Model_Biofilm.yaml","text_sha256":"dd20a79e44b2d327bf9023118aed68c16ec630806f369d521442f82c1660515b","x":2.2848873138427734,"y":5.276205539703369},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000101","label":"Maize Benzoxazinoid-Metabolizing SynComs","page":"communities/Maize_Benzoxazinoid_Metabolizing_SynComs.html","source_path":"kb/communities/Maize_Benzoxazinoid_Metabolizing_SynComs.yaml","text_sha256":"99716a46f8c6fe37102b9450904f7ff282db7ef04694c359229ce6f4d8af3188","x":3.1058528423309326,"y":-1.1148014068603516},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000204","label":"Methylocystis-Rhodococcus Methane VFA PHBV Coculture","page":"communities/Methylocystis_Rhodococcus_Methane_VFA_PHBV_Coculture.html","source_path":"kb/communities/Methylocystis_Rhodococcus_Methane_VFA_PHBV_Coculture.yaml","text_sha256":"d2a62ed115de1b3860a34102abc9968c9090d042c87eee942932120dc8cacad6","x":-2.3266329765319824,"y":2.8992042541503906},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000085","label":"Streptococcus mutans - Veillonella parvula Adult Severe Caries Model","page":"communities/SMutans_VParvula_ASC_Biofilm.html","source_path":"kb/communities/SMutans_VParvula_ASC_Biofilm.yaml","text_sha256":"8d9cc2b2cd8af3cb54cb6cd91be836f66e44b70000936739943a7c1f9e038ebe","x":2.4638659954071045,"y":5.074481964111328},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000030","label":"Gulf of Mexico Oil-Degrading Consortium","page":"communities/GOM_Oil_Degrading_Consortium.html","source_path":"kb/communities/GOM_Oil_Degrading_Consortium.yaml","text_sha256":"f199460225718a8b9fb14b7b292d2037b1221d6a2457b9ea690c205601cc4b13","x":0.05428749695420265,"y":-0.8278330564498901},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000249","label":"San Francisco Bay Area Sewage SARS-CoV-2 Metagenomic Surveillance Community","page":"communities/Bay_Area_Sewage_SARS_CoV2_Surveillance_Community.html","source_path":"kb/communities/Bay_Area_Sewage_SARS_CoV2_Surveillance_Community.yaml","text_sha256":"e2f597851586841f556c0c3439fc0b6acd27805f023de006fd4727f5d2334037","x":-1.7129367589950562,"y":-3.7402594089508057},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000118","label":"Wheat Straw Biogas Pretreatment SynCom","page":"communities/Wheat_Straw_Biogas_Pretreatment_SynCom.html","source_path":"kb/communities/Wheat_Straw_Biogas_Pretreatment_SynCom.yaml","text_sha256":"20b28ae9249e459943a9bfacccae13fddc6928d01c981bbce25689e2c057a151","x":1.4777268171310425,"y":1.2738049030303955},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000250","label":"Soil Biosynthetic Gene Cluster Phylum-Depth-Vegetation Community","page":"communities/Soil_BGC_Phylum_Depth_Vegetation_Community.html","source_path":"kb/communities/Soil_BGC_Phylum_Depth_Vegetation_Community.yaml","text_sha256":"6f3493a03960b02c933cc95b1523863761504c978f4a145982eaf64e41520a92","x":1.0380140542984009,"y":-3.2313146591186523},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000128","label":"CRC Fusobacterium Control SynCom","page":"communities/CRC_Fusobacterium_Control_SynCom.html","source_path":"kb/communities/CRC_Fusobacterium_Control_SynCom.yaml","text_sha256":"c7c7fc7a6eb234a457aa0d4513125f4385d146f7000348f267e1a89ada8133d7","x":3.49351167678833,"y":1.8990213871002197},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000322","label":"Methylobacterium REE E-waste Platform","page":"isolates/Methylobacterium_REE_Ewaste_Platform.html","source_path":"data/isolates/Methylobacterium_REE_Ewaste_Platform.yaml","text_sha256":"e47c6a28e13d4040947fc4a687e229a0a5fe840948cdd79d95f00b967d5e51f3","x":-3.706988573074341,"y":-6.288360118865967},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000184","label":"Dehalococcoides-Pelobacter Acetylene TCE Coculture","page":"communities/Dehalococcoides_Pelobacter_Acetylene_TCE_Coculture.html","source_path":"kb/communities/Dehalococcoides_Pelobacter_Acetylene_TCE_Coculture.yaml","text_sha256":"decd74860744051d88b8a39b4aa5cd47bbdcbd0d0bd0ac9af7f62eb793bd4571","x":-1.6215240955352783,"y":-0.4734886586666107},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000048","label":"Okeke-Lu Cellulolytic-Xylanolytic Consortium","page":"communities/Okeke_Lu_Cellulolytic_Consortium.html","source_path":"kb/communities/Okeke_Lu_Cellulolytic_Consortium.yaml","text_sha256":"a915e94b4ed68aa280dad33491845b3c02825a3e6b82ff0308558ef4c15fe71d","x":-0.242939755320549,"y":1.4790233373641968},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000078","label":"m-CAFEs Brachypodium Reduced Complexity Consortia","page":"communities/mCAFEs_Brachypodium_RCC.html","source_path":"kb/communities/mCAFEs_Brachypodium_RCC.yaml","text_sha256":"f2f7ba58821511e7e73d6f026c78b48ba869c01c45a743be21544405746a8d34","x":2.401459217071533,"y":-2.9372143745422363},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000035","label":"Industrial Bioleaching Reactor Consortium","page":"communities/Industrial_Bioreactor_Consortium.html","source_path":"kb/communities/Industrial_Bioreactor_Consortium.yaml","text_sha256":"90eabfc919808f9b85598ff6905d020b5a2a68d2399153a7e84c243c9625a1f6","x":-4.025850296020508,"y":-5.860608100891113},{"adapter_version":"communitymech-semantic-v1","category":"PHYTOPLANKTON","identifier":"CommunityMech:000191","label":"Chlorella-Azospirillum Synthetic Mutualism","page":"communities/Chlorella_Azospirillum_Synthetic_Mutualism.html","source_path":"kb/communities/Chlorella_Azospirillum_Synthetic_Mutualism.yaml","text_sha256":"3d75c9809528a7f5dce34c5f329c3c39b80b03b95b6d3ed88d09e182b77411f4","x":-0.7654247879981995,"y":5.358490467071533},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000043","label":"Maize Root Simplified Bacterial Community","page":"communities/Maize_Root_Simplified_Community.html","source_path":"kb/communities/Maize_Root_Simplified_Community.yaml","text_sha256":"6a27f83fa748d62983ea3348acf3767c1321cb2a69550bc2c3db5aa2e9db2fad","x":3.2957589626312256,"y":-2.3174855709075928},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000255","label":"Wetland Oxygen-Sulfate Greenhouse Gas Microcosm Community","page":"communities/Wetland_Oxygen_Sulfate_GHG_Microcosm_Community.html","source_path":"kb/communities/Wetland_Oxygen_Sulfate_GHG_Microcosm_Community.yaml","text_sha256":"56a01e920ce4a0ecced5acfe2f34904c540fc920f13edab9e8aea43deffa1314","x":-3.947331190109253,"y":-2.904677391052246},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000273","label":"Chromobacterium Gold Biocyanidation Platform","page":"isolates/Chromobacterium_Gold_Biocyanidation.html","source_path":"data/isolates/Chromobacterium_Gold_Biocyanidation.yaml","text_sha256":"0c72f24fce82950cdd6f7f4e4f9f613ad6f9ed63a577272f66e82d4b29b77756","x":-3.6154723167419434,"y":-6.627386093139648},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000281","label":"Infant-gut Prebiotic-response SynCom","page":"communities/Infant_Gut_Prebiotic_Response_SynCom.html","source_path":"kb/communities/Infant_Gut_Prebiotic_Response_SynCom.yaml","text_sha256":"4015210c5ab14f0388ec8ae3f094d48f4eb8bc3818b28071237208fa1330c4eb","x":3.377851724624634,"y":2.699673652648926},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000037","label":"KBase Models for Zahmeeth Original PLOS","page":"communities/KBase_Models_for_Zahmeeth_Original_PLOS.html","source_path":"kb/communities/KBase_Models_for_Zahmeeth_Original_PLOS.yaml","text_sha256":"14598acdddb66746d3c75a9fe2016c1f6baa2bb88c140eafb294e69d1e9d22db","x":1.636893391609192,"y":4.779601573944092},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000337","label":"Tropidoatractus magnetotacticus Magnetotactic Ciliate Tripartite Syntrophy","page":"communities/Tropidoatractus_Magnetotacticus_Tripartite_Syntrophy.html","source_path":"kb/communities/Tropidoatractus_Magnetotacticus_Tripartite_Syntrophy.yaml","text_sha256":"36a4085471edd8a7ad822f5317588b034a084456a3bf602afd04b7b4d677dc83","x":-4.35278844833374,"y":-1.2435243129730225},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000026","label":"E-waste Bioleaching Consortium","page":"communities/Ewaste_Bioleaching_Consortium.html","source_path":"kb/communities/Ewaste_Bioleaching_Consortium.yaml","text_sha256":"bb24e23c98e04d2f5540299850cc52160b7422f6239b93e4049e44be24c40fcc","x":-3.957258701324463,"y":-5.83111047744751},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000042","label":"MSC-1 Dominant Core","page":"communities/MSC1_Dominant_Core.html","source_path":"kb/communities/MSC1_Dominant_Core.yaml","text_sha256":"0252095d0eb3ad7e592091e6ceb377c183eeec9f58b3ad962c6c8f3fb37ed6a0","x":0.8254767060279846,"y":-2.614091396331787},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000024","label":"ENIGMA Denitrifying SynCom","page":"communities/ENIGMA_Denitrifying_SynCom.html","source_path":"kb/communities/ENIGMA_Denitrifying_SynCom.yaml","text_sha256":"2c50268820096417b82f947a90b8e6ddf2318f5d9f71e552ff872131ebfcf933","x":-0.8264681100845337,"y":-2.515094757080078},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000365","label":"Baijiu Pit Mud Hexanoic Acid SynCom G4","page":"communities/Baijiu_Pit_Mud_Hexanoic_Acid_SynCom_G4.html","source_path":"kb/communities/Baijiu_Pit_Mud_Hexanoic_Acid_SynCom_G4.yaml","text_sha256":"5ad3ffa0da232fdc2e84979681fc106fdfc615ff3736a00f8bee332fa364b2f5","x":2.9250879287719727,"y":0.47103220224380493},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000100","label":"Teosinte-Derived Maize Biofertilizer SynCom7","page":"communities/Teosinte_Maize_Biofertilizer_SynCom7.html","source_path":"kb/communities/Teosinte_Maize_Biofertilizer_SynCom7.yaml","text_sha256":"ac541a50b5271c1683bd8b2f82a4fe3a82555660a6304fcb12c6a54a852908b0","x":4.618795394897461,"y":-2.006741523742676},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000200","label":"Dehalococcoides-Desulfovibrio-Pelosinus Corrinoid Triculture","page":"communities/Dehalococcoides_Desulfovibrio_Pelosinus_Corrinoid_Triculture.html","source_path":"kb/communities/Dehalococcoides_Desulfovibrio_Pelosinus_Corrinoid_Triculture.yaml","text_sha256":"30cdd72b22d5da54784057a06e4f7baba8a26d11e8ea9335f4e437766e772fb4","x":-1.9548580646514893,"y":-0.19592873752117157},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000159","label":"CeMbio Caenorhabditis elegans Microbiome","page":"communities/CeMbio_Caenorhabditis_Elegans_Microbiome.html","source_path":"kb/communities/CeMbio_Caenorhabditis_Elegans_Microbiome.yaml","text_sha256":"df568df982c63db15dcc2d216f8a590e9efe7a71d900de1e09287bd0c200cafc","x":3.5066094398498535,"y":3.523559331893921},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000141","label":"Chlorochromatium aggregatum Phototrophic Consortium","page":"communities/Chlorochromatium_Aggregatum_Phototrophic_Consortium.html","source_path":"kb/communities/Chlorochromatium_Aggregatum_Phototrophic_Consortium.yaml","text_sha256":"052409c0f68867e4f7bf8112c45c17f3b6c5fb747ff892f6d0cb5710aac2e21c","x":-1.5419610738754272,"y":5.123783111572266},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000215","label":"California Grassland Precipitation Legacy Soil Community","page":"communities/California_Grassland_Precipitation_Legacy_Soil_Community.html","source_path":"kb/communities/California_Grassland_Precipitation_Legacy_Soil_Community.yaml","text_sha256":"0f30217cfe2c233c0cf67c8ea89c5b506083a63abad158514c727be2945442fe","x":0.7228723168373108,"y":-3.3976497650146484},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000151","label":"Engineered Gut Amino Acid Cross-Feeding Consortium","page":"communities/Engineered_Gut_Amino_Acid_CrossFeeding_Consortium.html","source_path":"kb/communities/Engineered_Gut_Amino_Acid_CrossFeeding_Consortium.yaml","text_sha256":"1de6f4e82c0da25b7b5f6fd8e3f2fdcfae04c814022ab75d844623a19634876a","x":2.566854953765869,"y":3.210235357284546},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000185","label":"Caldicellulosiruptor Two-Species Hydrogen Coculture","page":"communities/Caldicellulosiruptor_TwoSpecies_Hydrogen_Coculture.html","source_path":"kb/communities/Caldicellulosiruptor_TwoSpecies_Hydrogen_Coculture.yaml","text_sha256":"c397412b475a4d6ab4f5fedbcd2ba5f4c2e044317f29ae51f3f127fcce17d226","x":-1.718294382095337,"y":2.172290086746216},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000304","label":"Lunar and Martian Simulant PGPB Lettuce SynCom","page":"communities/Lunar_Martian_Simulant_PGPB_Lettuce_SynCom.html","source_path":"kb/communities/Lunar_Martian_Simulant_PGPB_Lettuce_SynCom.yaml","text_sha256":"22ab2e22f9a2256c511b9b9192f25c4be6a5a4f514b1803369a361996cb4604e","x":-3.4382903575897217,"y":-7.2675065994262695},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000222","label":"Sulfide Spring Autotrophic CPR-Hosting Biofilm","page":"communities/Sulfide_Spring_Autotrophic_CPR_Biofilm.html","source_path":"kb/communities/Sulfide_Spring_Autotrophic_CPR_Biofilm.yaml","text_sha256":"84a3ac94d9f995ec43245c86760c75894dccfa780eb0eb6747f2c1797e04b910","x":-3.3391470909118652,"y":-3.641453266143799},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000269","label":"Chlorella-Ecoli Mixotrophic Biofuel Precursor Coculture","page":"communities/Chlorella_Ecoli_Mixotrophic_Biofuel_Coculture.html","source_path":"kb/communities/Chlorella_Ecoli_Mixotrophic_Biofuel_Coculture.yaml","text_sha256":"4ab59d9f3417b8871f029b78b40ff5605b7a1929259a0d1f5bc610ab3f22884a","x":-1.264540195465088,"y":4.716289043426514},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000081","label":"Early Dental Biofilm Five-Species Model","page":"communities/Early_Dental_Biofilm_FiveSpecies.html","source_path":"kb/communities/Early_Dental_Biofilm_FiveSpecies.yaml","text_sha256":"554f23c91d45e94ec433cc3b5c470120f94232df1bc1d1dd41034b5fa9f3a4e8","x":2.4018189907073975,"y":5.210973262786865},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000287","label":"Electrostimulated Mixotrophic VFA-producing Enrichment Consortium","page":"communities/Electrostimulated_Mixotrophic_VFA_Producing_Enrichment_Consortium.html","source_path":"kb/communities/Electrostimulated_Mixotrophic_VFA_Producing_Enrichment_Consortium.yaml","text_sha256":"00b54f31a0330c71a07dadd0acfe4b07b85d69fe126299130926418aa335add6","x":-3.27608323097229,"y":-0.6373180150985718},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000364","label":"Sclerotinia Sclerotia 12-Strain Biocontrol SynCom","page":"communities/Sclerotinia_Sclerotia_12Strain_Biocontrol_SynCom.html","source_path":"kb/communities/Sclerotinia_Sclerotia_12Strain_Biocontrol_SynCom.yaml","text_sha256":"423f0ee4295770d0514ca4d8bbd20c5b3383e6b771c159e5319b1bc40646e2b1","x":4.457443714141846,"y":-0.805803656578064},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000144","label":"Altered Schaedler Flora Gnotobiotic Mouse Community","page":"communities/Altered_Schaedler_Flora_Gnotobiotic_Mouse_Community.html","source_path":"kb/communities/Altered_Schaedler_Flora_Gnotobiotic_Mouse_Community.yaml","text_sha256":"4a6cbe77a2414c506a82317b388200e84bfc6ac6953e1bc165faf7886cecb4cc","x":2.951843738555908,"y":3.810020685195923},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000375","label":"Maize SC2 Root-Rot Biocontrol SynCom","page":"communities/Maize_SC2_RootRot_Biocontrol_SynCom.html","source_path":"kb/communities/Maize_SC2_RootRot_Biocontrol_SynCom.yaml","text_sha256":"790b8fc15467416c1d711d7668a9bc00114327f1150b178029819d5a4b75cb16","x":4.386301040649414,"y":-1.842079520225525},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000093","label":"Arabidopsis Phyllosphere SynCom7","page":"communities/Arabidopsis_Phyllosphere_SynCom7.html","source_path":"kb/communities/Arabidopsis_Phyllosphere_SynCom7.yaml","text_sha256":"e840a0a707dd66ab9afe2b93379a37a858b7165966766eda104412ac6e723d2a","x":4.232011795043945,"y":-2.396761655807495},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000236","label":"Avena Rhizosphere Cross-Kingdom 13C-SIP Community","page":"communities/Avena_Rhizosphere_CrossKingdom_SIP_Community.html","source_path":"kb/communities/Avena_Rhizosphere_CrossKingdom_SIP_Community.yaml","text_sha256":"b4759837163b346d86d445eab04d05d1b72cb1f58eea1deeafaf7308693d3fad","x":1.9628806114196777,"y":-3.3750650882720947},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000263","label":"Saccharomyces-Acinetobacter Lignocellulose Hydrolysate Detoxification Coculture","page":"communities/Saccharomyces_Acinetobacter_Lignocellulose_Detox_Coculture.html","source_path":"kb/communities/Saccharomyces_Acinetobacter_Lignocellulose_Detox_Coculture.yaml","text_sha256":"aaf8b0d4fe27a144176fdff88b67f3dac2bac80a066a03f7ba90e5922e56c85c","x":-0.015718502923846245,"y":2.0424392223358154},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000197","label":"Methylocaldum-Cupriavidus Methane Acetate Cross-Feeding Coculture","page":"communities/Methylocaldum_Cupriavidus_Methane_Acetate_Crossfeeding_Coculture.html","source_path":"kb/communities/Methylocaldum_Cupriavidus_Methane_Acetate_Crossfeeding_Coculture.yaml","text_sha256":"c5f136484d814a33f94a5429fc7fef9682651ddad3a1c0efec0bc66a112e9d0f","x":-2.882148504257202,"y":2.895678758621216},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000012","label":"BioModels MODEL2405300001 Infant Gut HMO SynCom","page":"communities/BioModels_MODEL2405300001_Infant_Gut_HMO_SynCom.html","source_path":"kb/communities/BioModels_MODEL2405300001_Infant_Gut_HMO_SynCom.yaml","text_sha256":"456f73316251e55ef04b1db493332d41134546937fb4809fe64ffa7ef6777c7e","x":2.582770586013794,"y":4.039132595062256},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000176","label":"ORNL Clostridium-Desulfovibrio-Geobacter Trophic Model Community","page":"communities/ORNL_Clostridium_Desulfovibrio_Geobacter_Trophic_Model.html","source_path":"kb/communities/ORNL_Clostridium_Desulfovibrio_Geobacter_Trophic_Model.yaml","text_sha256":"3200c829efc23e8857e697cdc20dc30af1fd275308bd57c99d8d55e667c1059e","x":-2.3075997829437256,"y":0.4073981046676636},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000289","label":"Pseudomonas putida Pp-TE + Rhodococcus sp. RDK17 Terephthalic-acid Consortium","page":"communities/Pseudomonas_putida_PpTE_Rhodococcus_RDK17_Terephthalic_Acid_Consortium.html","source_path":"kb/communities/Pseudomonas_putida_PpTE_Rhodococcus_RDK17_Terephthalic_Acid_Consortium.yaml","text_sha256":"99ac61ae2b37da1270964a3ea86fa1d5f96885aef41a5caefe1feaeb7e951909","x":-0.12319472432136536,"y":-0.22636571526527405},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000126","label":"N-Cycle Bioflocculation Model Consortium","page":"communities/NCycle_Bioflocculation_Model_Consortium.html","source_path":"kb/communities/NCycle_Bioflocculation_Model_Consortium.yaml","text_sha256":"8c0c708e32508861793df933b30b6c1716a87a6077cbee567d88d87bb80df118","x":-1.322421908378601,"y":-2.358081102371216},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000306","label":"Lunar Regolith Simulant Phosphorus-Solubilizing Bacteria for Nicotiana benthamiana","page":"communities/Lunar_Simulant_Phosphate_Solubilizing_Bacteria_Nicotiana.html","source_path":"kb/communities/Lunar_Simulant_Phosphate_Solubilizing_Bacteria_Nicotiana.yaml","text_sha256":"0f7d440b39e05ec304ac01716db500d68854e57cb03bc9128afee58f4c7bc83d","x":-3.4186928272247314,"y":-7.276150226593018},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000318","label":"Bifidobacterium breve-Trichomonas vaginalis Vaginal Co-culture","page":"communities/Bifidobacterium_Trichomonas_Vaginal_Coculture.html","source_path":"kb/communities/Bifidobacterium_Trichomonas_Vaginal_Coculture.yaml","text_sha256":"037265609456a50de02d02d596ed5b36eea44070efe52d76715fba42f9bc0899","x":2.92924427986145,"y":3.5738306045532227},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000028","label":"GLBRC Populus Variovorax SynCom28","page":"communities/GLBRC_Populus_Variovorax_SynCom28.html","source_path":"kb/communities/GLBRC_Populus_Variovorax_SynCom28.yaml","text_sha256":"7883652605addf6a9b8ac5e69eee55002adf967f64ec741f53017159c4765da1","x":2.6867096424102783,"y":-2.6041109561920166},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000374","label":"Achromobacter-Enterobacter SL8-SL12 Cadmium Immobilization Coculture","page":"communities/Achromobacter_Enterobacter_SL8_SL12_Cadmium_Immobilization_Coculture.html","source_path":"kb/communities/Achromobacter_Enterobacter_SL8_SL12_Cadmium_Immobilization_Coculture.yaml","text_sha256":"8025f36043872167edfec079da3adfca06cfad4a27625711e0f2b7eb8e49cf90","x":-1.807790994644165,"y":-2.248044729232788},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000173","label":"Acetobacterium woodii-Clostridium drakei CO2 Electrolysis Coculture","page":"communities/Acetobacterium_Clostridium_CO2_Electrolysis_Coculture.html","source_path":"kb/communities/Acetobacterium_Clostridium_CO2_Electrolysis_Coculture.yaml","text_sha256":"d2a5886afb025c6989551c81e9e3ec17c617d03aeb96fa0351273b6e71513c58","x":-2.4402096271514893,"y":2.2676687240600586},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000314","label":"SynCom ARC Peanut Aflatoxin-Control and Nodulation-Coupling Community","page":"communities/SynCom_ARC_Peanut_Aflatoxin_Nodulation.html","source_path":"kb/communities/SynCom_ARC_Peanut_Aflatoxin_Nodulation.yaml","text_sha256":"f8b8758ffbcb2d5ff126c1067c626f0afaa74ab78eb611d458c6144cd126a16f","x":5.06695556640625,"y":-1.2149674892425537},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000360","label":"Wolffia Mankai Endosphere Cobamide Guild","page":"communities/Wolffia_Mankai_Endosphere_Cobamide_Guild.html","source_path":"kb/communities/Wolffia_Mankai_Endosphere_Cobamide_Guild.yaml","text_sha256":"dcd8a6ef1420a2033186b8629ff9a6b731d2d8259aa568092dfc163a2a419371","x":1.4535413980484009,"y":-2.6705260276794434},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000041","label":"MAMC-M48 Lignocellulose-Degrading Consortium","page":"communities/MAMC_M48_Lignocellulose.html","source_path":"kb/communities/MAMC_M48_Lignocellulose.yaml","text_sha256":"b8b73685597a4a98645ec63f2d53e62193ad31c1f4c5eab461a08e265053431b","x":0.09893161058425903,"y":0.89271080493927},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000114","label":"Shewanella Denitrifying Richness SynComs","page":"communities/Shewanella_Denitrifying_Richness_SynComs.html","source_path":"kb/communities/Shewanella_Denitrifying_Richness_SynComs.yaml","text_sha256":"3edce51ff9ec3098cb62d4ab6c42b1274580c9d4ea4a052a3adc23c3eade1007","x":-0.9915839433670044,"y":-2.0393049716949463},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000010","label":"BioModels MODEL2209060002 D pigrum - S aureus Community","page":"communities/BioModels_MODEL2209060002_DPigrum_SAureus_Community.html","source_path":"kb/communities/BioModels_MODEL2209060002_DPigrum_SAureus_Community.yaml","text_sha256":"5ae0f4193fdf0e1fbcbae22a9fce0c278cc3066ab8115e18530b065b5ecbb0e7","x":2.0774335861206055,"y":4.992537975311279},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000031","label":"Geobacter-Clostridium Interspecies Electron Transfer Coculture","page":"communities/Geobacter_Clostridium_Interspecies_Electron_Transfer_Coculture.html","source_path":"kb/communities/Geobacter_Clostridium_Interspecies_Electron_Transfer_Coculture.yaml","text_sha256":"b5526d482b7411684b28e5e528172e2157554140785bd433e55d4da2720fe436","x":-3.263092041015625,"y":-0.6166970133781433},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000067","label":"Synechococcus-Saccharomyces Synthetic Photosynthetic Consortium","page":"communities/Synechococcus_Saccharomyces_SPC.html","source_path":"kb/communities/Synechococcus_Saccharomyces_SPC.yaml","text_sha256":"678f377f1b8769dffae48b3750be38d5c0211815fc3f5a4ee4d6489ffa354cb5","x":-1.999376654624939,"y":5.98422908782959},{"adapter_version":"communitymech-semantic-v1","category":"EXTREME_ENVIRONMENT","identifier":"CommunityMech:000260","label":"Mushroom Spring Hot-Spring Phototrophic Mat Community","page":"communities/Mushroom_Spring_Hot_Spring_Phototrophic_Mat_Community.html","source_path":"kb/communities/Mushroom_Spring_Hot_Spring_Phototrophic_Mat_Community.yaml","text_sha256":"c76524abcc4ca71e8330c1869c5aa1f0288bfe17d3dd46d04c9a2680f5aeee5f","x":-3.897305965423584,"y":-3.472539186477661},{"adapter_version":"communitymech-semantic-v1","category":"OTHER","identifier":"CommunityMech:000161","label":"Pseudomonas-Pedobacter Social Spreading Coculture","page":"communities/Pseudomonas_Pedobacter_Social_Spreading_Coculture.html","source_path":"kb/communities/Pseudomonas_Pedobacter_Social_Spreading_Coculture.yaml","text_sha256":"d114e4c15b40fd11e0acd44b892c1337bf04c976361d50eb138381b5bdfc8769","x":2.5409657955169678,"y":4.529335975646973},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000172","label":"Clostridium autoethanogenum-Clostridium kluyveri Syngas Coculture","page":"communities/Clostridium_Autoethanogenum_Kluyveri_Syngas_Coculture.html","source_path":"kb/communities/Clostridium_Autoethanogenum_Kluyveri_Syngas_Coculture.yaml","text_sha256":"f5338a853f140e61b094c2c08909c5ce42edccbd4879c88624673ed0cb32e5b9","x":-2.3052315711975098,"y":2.539637327194214},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000205","label":"Trichoderma-E. coli Cellulosic Isobutanol Coculture","page":"communities/Trichoderma_Ecoli_Cellulosic_Isobutanol_Coculture.html","source_path":"kb/communities/Trichoderma_Ecoli_Cellulosic_Isobutanol_Coculture.yaml","text_sha256":"1efda448d74d9c95131ce5095e4bfeac8a5fee187214b90bbf910ea6c512cd44","x":-0.23416543006896973,"y":2.1174697875976562},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000110","label":"Rice Phosphorus Uptake Intercropping SynCom4","page":"communities/Rice_P_Uptake_Intercropping_SynCom4.html","source_path":"kb/communities/Rice_P_Uptake_Intercropping_SynCom4.yaml","text_sha256":"b810c5d837288f7a7345a0f6a9c35d14dbe9f671677281d44aa1b90a6bd0f9c1","x":4.271810054779053,"y":-2.2848312854766846},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000267","label":"Sphingobium-Rhodococcus Lignin-Dimer Valorization Coculture","page":"communities/Sphingobium_Rhodococcus_Lignin_Dimer_Valorization_Coculture.html","source_path":"kb/communities/Sphingobium_Rhodococcus_Lignin_Dimer_Valorization_Coculture.yaml","text_sha256":"780b402cfe51f63c6b849d9ae6293be51bac87d234e95982abc602a94d6af6a7","x":-0.5609908103942871,"y":1.2783502340316772},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000226","label":"Lac Pavin Permanently Stratified Lake Community","page":"communities/Lac_Pavin_Stratified_Lake_Community.html","source_path":"kb/communities/Lac_Pavin_Stratified_Lake_Community.yaml","text_sha256":"e7f9d81b93a812dfe6c313c4504a995890484a560bb807baca7311eacab07e08","x":-3.3220911026000977,"y":-2.9958901405334473},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000054","label":"Phormidium Alkaline Consortium","page":"communities/Phormidium_Alkaline_Consortium.html","source_path":"kb/communities/Phormidium_Alkaline_Consortium.yaml","text_sha256":"f2ae6d8b014a9e78cdb5753e8c0d003ed1abd20352188162d031524a4cfeace5","x":-1.7940700054168701,"y":5.421578884124756},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000088","label":"LBNL Brachypodium Drought SynCom15","page":"communities/LBNL_Brachypodium_Drought_SynCom15.html","source_path":"kb/communities/LBNL_Brachypodium_Drought_SynCom15.yaml","text_sha256":"2087eca7e0a3dd51245d6ab72deec6626808de59c9870b3ecc272bbad76060d2","x":3.456050395965576,"y":-2.66764497756958},{"adapter_version":"communitymech-semantic-v1","category":"BIOMINING","identifier":"CommunityMech:000049","label":"PGM Spent Catalyst Bioleaching Consortium","page":"communities/PGM_Spent_Catalyst_Bioleaching.html","source_path":"kb/communities/PGM_Spent_Catalyst_Bioleaching.yaml","text_sha256":"a58dc125340a17901069d0802adbb49dd78f7cd5514fc4c4a52c83b5001d7b81","x":-4.122527122497559,"y":-5.796470642089844},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000241","label":"Rifle Aquifer Bioanode Extracellular Electron Transfer Community","page":"communities/Rifle_Aquifer_Bioanode_EET_Community.html","source_path":"kb/communities/Rifle_Aquifer_Bioanode_EET_Community.yaml","text_sha256":"8edd6fe61881f1be9a2e877ed602e93fd96169cb14efdc7e6c82453bc44dd7b1","x":-2.997509479522705,"y":-2.3991923332214355},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000018","label":"Cinnamate β-Oxidation Consortium","page":"communities/Cinnamate_Degradation_Consortium.html","source_path":"kb/communities/Cinnamate_Degradation_Consortium.yaml","text_sha256":"3bd608fc41ce995d05aaddcdc2164b33701e2a268ade75f69203d77a05b927cc","x":-4.675424575805664,"y":0.921583354473114},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000060","label":"Rifle Uranium-Reducing Community","page":"communities/Rifle_Uranium_Reducing_Community.html","source_path":"kb/communities/Rifle_Uranium_Reducing_Community.yaml","text_sha256":"05d39925552f20a5ff0315d508e1d0b8b6e1bec0a20f96c3fc35c6806924ca4e","x":-2.7276358604431152,"y":-3.664438247680664},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000170","label":"Methylotuvimicrobium-Synechococcus Gas Feedstock Coculture","page":"communities/Methylotuvimicrobium_Synechococcus_Gas_Feedstock_Coculture.html","source_path":"kb/communities/Methylotuvimicrobium_Synechococcus_Gas_Feedstock_Coculture.yaml","text_sha256":"04ce0cbe529a13475a91b5ade1e08cd26c7930c3627077c374acc9c6c38282dc","x":-2.251159191131592,"y":4.660420894622803},{"adapter_version":"communitymech-semantic-v1","category":"ORAL","identifier":"CommunityMech:000083","label":"Streptococcus mutans - Candida albicans ECC Biofilm Model","page":"communities/SMutans_CAlbicans_ECC_Biofilm.html","source_path":"kb/communities/SMutans_CAlbicans_ECC_Biofilm.yaml","text_sha256":"36f5d2727dcaa5aedcea302e3f29deb3133f9a4c0d05f43945285c5dfcc7703d","x":2.5666861534118652,"y":5.199058532714844},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000208","label":"Clostridium Thermocellum-Saccharoperbutylacetonicum Cellulosic Butanol Coculture","page":"communities/Clostridium_Thermocellum_Saccharoperbutylacetonicum_Cellulosic_Butanol_Coculture.html","source_path":"kb/communities/Clostridium_Thermocellum_Saccharoperbutylacetonicum_Cellulosic_Butanol_Coculture.yaml","text_sha256":"93ad4d795d00680f792371f6ecd6a57d3e22759b604e5130361b3e5df160ea01","x":-1.3385446071624756,"y":2.3130698204040527},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000050","label":"PMI Variovorax Thermotolerance Collection","page":"communities/PMI_Variovorax_Thermotolerance_Collection.html","source_path":"kb/communities/PMI_Variovorax_Thermotolerance_Collection.yaml","text_sha256":"3f0f958dba81069657a1c6885d9c4f82eab74fd478622b41fe2aea5c01d37124","x":3.8950090408325195,"y":-2.6218783855438232},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000206","label":"Clostridium-Saccharomyces Cellulose Ethanol Coculture","page":"communities/Clostridium_Saccharomyces_Cellulose_Ethanol_Coculture.html","source_path":"kb/communities/Clostridium_Saccharomyces_Cellulose_Ethanol_Coculture.yaml","text_sha256":"0f58e434ca0d6c03e468de47e9e6d0edd0279f05957162211b523f980515a5bc","x":-1.1212124824523926,"y":2.317575216293335},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000209","label":"Dehalococcoides-Methanosarcina DMB-Guided Cobalamin Coculture","page":"communities/Dehalococcoides_Methanosarcina_DMB_Cobalamin_Coculture.html","source_path":"kb/communities/Dehalococcoides_Methanosarcina_DMB_Cobalamin_Coculture.yaml","text_sha256":"20e34c5a5c69d87bed4917b6c0803b3f452d0cc1783c3562dc3ce4e5dc3f364b","x":-1.8732410669326782,"y":-0.23843298852443695},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000039","label":"KBase Synthetic Bacterial Community in R2A Medium","page":"communities/KBase_Synthetic_Bacterial_Community_R2A.html","source_path":"kb/communities/KBase_Synthetic_Bacterial_Community_R2A.yaml","text_sha256":"7e6d9b69d86ea84c62a4746c75d3d8fd408b48a3b41673cd11b76ecc16bccb2b","x":2.339444160461426,"y":-1.8471851348876953},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000341","label":"Priestia-Pseudomonas Rice Arsenic-Stress SynCom","page":"communities/Priestia_Pseudomonas_Rice_Arsenic_Stress_SynCom.html","source_path":"kb/communities/Priestia_Pseudomonas_Rice_Arsenic_Stress_SynCom.yaml","text_sha256":"6ef9b4045bde9a6b21d22fe7d8e99fa35915615c2536dba179fa8fe2669440fd","x":4.365429401397705,"y":-2.3438289165496826},{"adapter_version":"communitymech-semantic-v1","category":"LIGNOCELLULOSE","identifier":"CommunityMech:000168","label":"Clostridium-Thermoanaerobacter Cellulosic Bioethanol Coculture","page":"communities/Clostridium_Thermoanaerobacter_Cellulosic_Bioethanol_Coculture.html","source_path":"kb/communities/Clostridium_Thermoanaerobacter_Cellulosic_Bioethanol_Coculture.yaml","text_sha256":"c1f266369fc18d7bf634d428bfde9663a17b1ea30908ff8282413c51cfee7d54","x":-1.5423380136489868,"y":2.2620410919189453},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000053","label":"Phenol Carboxylation Consortium","page":"communities/Phenol_Carboxylation_Consortium.html","source_path":"kb/communities/Phenol_Carboxylation_Consortium.yaml","text_sha256":"889365a4328498620b92820369c568f1e1e9c4a95dc8883c55d350aa5c6f6069","x":-4.4496893882751465,"y":1.2652981281280518},{"adapter_version":"communitymech-semantic-v1","category":"METHANOGENESIS","identifier":"CommunityMech:000246","label":"South Bay Salt Pond Methane Restoration Microbial Community","page":"communities/South_Bay_Salt_Pond_Methane_Restoration_Community.html","source_path":"kb/communities/South_Bay_Salt_Pond_Methane_Restoration_Community.yaml","text_sha256":"8b288d3e2b57c39c87f737033c061739428eed6bd23444b482cd56f257a44233","x":-4.037392616271973,"y":-2.9343554973602295},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000343","label":"Komagataella-E. coli Co-inducible Biosynthesis Coculture","page":"communities/Komagataella_Ecoli_Coinducible_Biosynthesis_Coculture.html","source_path":"kb/communities/Komagataella_Ecoli_Coinducible_Biosynthesis_Coculture.yaml","text_sha256":"c4624d99950936c9282a96670c4f1043cf98b59752ba03fd90aa42c51184bc1a","x":0.3466097116470337,"y":2.83628511428833},{"adapter_version":"communitymech-semantic-v1","category":"SYNTROPHY","identifier":"CommunityMech:000148","label":"Buchnera-Serratia Cinara cedri Endosymbiont Consortium","page":"communities/Buchnera_Serratia_Cinara_Cedri_Endosymbiont_Consortium.html","source_path":"kb/communities/Buchnera_Serratia_Cinara_Cedri_Endosymbiont_Consortium.yaml","text_sha256":"dfdfca5f38e83f25adb110340fc328770d2d37497697a2647f0a49f9adb96db8","x":0.42514878511428833,"y":5.06350564956665},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000332","label":"Kefir Flavor Lentilactobacillus-Kluyveromyces Coculture","page":"communities/Kefir_Flavor_Lentilactobacillus_Kluyveromyces_Coculture.html","source_path":"kb/communities/Kefir_Flavor_Lentilactobacillus_Kluyveromyces_Coculture.yaml","text_sha256":"e5a5f79d1a22ec4b976135708223c7e39cbb9589374fe683ee39d918791e08f6","x":0.9586912393569946,"y":2.8440585136413574},{"adapter_version":"communitymech-semantic-v1","category":"DIET","identifier":"CommunityMech:000033","label":"Geobacter-Methanosarcina DIET Community","page":"communities/Geobacter_Methanosarcina_DIET.html","source_path":"kb/communities/Geobacter_Methanosarcina_DIET.yaml","text_sha256":"2fc6c5c49f7e847d340a17d394941ea43bc93bc7d1b8b661478e1f4623de0b53","x":-3.5622122287750244,"y":-0.6226912140846252},{"adapter_version":"communitymech-semantic-v1","category":"RHIZOSPHERE","identifier":"CommunityMech:000047","label":"ORNL PMI Populus PD10 SynCom","page":"communities/ORNL_PMI_Populus_PD10_SynCom.html","source_path":"kb/communities/ORNL_PMI_Populus_PD10_SynCom.yaml","text_sha256":"7c10d8bca8e6093e4f2aff4153da2865ff8811ca8207d95257ea78b8c3d66015","x":3.4963433742523193,"y":-2.35148024559021},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000112","label":"Tribromophenol Anaerobic Bioremediation SynCom","page":"communities/Tribromophenol_Anaerobic_Bioremediation_SynCom.html","source_path":"kb/communities/Tribromophenol_Anaerobic_Bioremediation_SynCom.yaml","text_sha256":"5522e4d8257bc55226aa95114416f032cb24faeeec29013c4512ac3259c71dda","x":-2.157504081726074,"y":-0.008533160202205181},{"adapter_version":"communitymech-semantic-v1","category":"CARBON_SEQUESTRATION","identifier":"CommunityMech:000261","label":"Lake Washington Methane-Oxygen Methylotroph Community","page":"communities/Lake_Washington_Methane_Oxygen_Methylotroph_Community.html","source_path":"kb/communities/Lake_Washington_Methane_Oxygen_Methylotroph_Community.yaml","text_sha256":"17ed6d56e533e28ddc4af0a307385ae58dd6930f71b61bc319d9b3d159edf737","x":-3.734405040740967,"y":-2.728146553039551},{"adapter_version":"communitymech-semantic-v1","category":"BIOREMEDIATION","identifier":"CommunityMech:000301","label":"Dehalococcoides mccartyi CWV2 Dechlorinating Consortium","page":"communities/Dehalococcoides_mccartyi_CWV2_Dechlorinating_Consortium.html","source_path":"kb/communities/Dehalococcoides_mccartyi_CWV2_Dechlorinating_Consortium.yaml","text_sha256":"7dd60eaebf302bd36d3636755b7494fb83241d388fe28eb9ef2da6327ad3338b","x":-1.8295767307281494,"y":-0.925062894821167},{"adapter_version":"communitymech-semantic-v1","category":"BIOTECHNOLOGY","identifier":"CommunityMech:000198","label":"Synechococcus-Halomonas Light-Driven PHB Coculture","page":"communities/Synechococcus_Halomonas_Light_Driven_PHB_Coculture.html","source_path":"kb/communities/Synechococcus_Halomonas_Light_Driven_PHB_Coculture.yaml","text_sha256":"39159234e16c185af49322b38ae3c8eab40553cff57b87060bf4be3fa4cc48e6","x":-1.9927095174789429,"y":5.834944725036621}] diff --git a/justfile b/justfile index d4c2764d7..0631f7dc3 100644 --- a/justfile +++ b/justfile @@ -802,4 +802,8 @@ validate-history target="history": # Full canonical semantic text by default; --record/--limit are explicit canaries. text-map-inputs *args: - uv run python scripts/text_map_inputs.py {{args}} + uv run python scripts/text_map_inputs.py "$@" + +# Validate full inputs and stage the configured common map; no model inference. +stage-text-map *args: + uv run python scripts/stage_text_map.py "$@" diff --git a/scripts/embedding_pipeline.py b/scripts/embedding_pipeline.py new file mode 100644 index 000000000..1a97ec400 --- /dev/null +++ b/scripts/embedding_pipeline.py @@ -0,0 +1,685 @@ +#!/usr/bin/env python3 +"""Build provenance-bound semantic-text maps from a Mech's JSONL adapter. + +Inspection and verification use the standard library. Model inference and +projection are explicit operations with separately installed dependencies. +""" +from __future__ import annotations + +import argparse +import contextlib +import datetime as dt +import hashlib +import heapq +import importlib.metadata +import json +import math +import os +import re +import shutil +import sqlite3 +import struct +import sys +import tempfile +from pathlib import Path +from urllib.parse import unquote, urlsplit + +FORMAT_VERSION = 1 +MODEL = "BAAI/bge-large-en-v1.5" +MODEL_REVISION = "d4aa6901d3a41ba39fb536a557fa166f842b0e09" +MODEL_DIMENSION = 1024 +MAX_SEQ_LENGTH = 512 +REQUIRED_FIELDS = ( + "identifier", "label", "category", "page", "source_path", "text", + "text_sha256", "adapter_version", +) + + +class ContractError(ValueError): + """Malformed input or an unverified artifact; never a successful map.""" + + +def canonical(value: object) -> bytes: + return json.dumps(value, sort_keys=True, separators=(",", ":"), + ensure_ascii=False, allow_nan=False).encode("utf-8") + + +def digest_file(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as stream: + for chunk in iter(lambda: stream.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def framed_update(digest, *values: str) -> None: + for value in values: + encoded = value.encode("utf-8") + digest.update(struct.pack(">Q", len(encoded))) + digest.update(encoded) + + +def local_link(value: str) -> bool: + if not isinstance(value, str) or not value.strip(): + return False + parsed = urlsplit(value) + decoded = unquote(parsed.path) + return bool(value) and not ( + parsed.scheme or parsed.netloc or decoded.startswith("/") + or "\\" in decoded or ".." in decoded.split("/") + or any(ord(char) < 32 for char in unquote(value)) + ) + + +def records(path: Path, *, raw_digest=None): + """Read one adapter record at a time; no YAML or biological policy here.""" + with path.open("rb") as stream: + for number, line in enumerate(stream, 1): + if raw_digest is not None: + raw_digest.update(line) + try: + record = json.loads(line.decode("utf-8")) + except (ValueError, UnicodeError) as exc: + raise ContractError(f"invalid JSONL record at line {number}") from exc + if not isinstance(record, dict) or any( + not isinstance(record.get(key), str) or not record[key].strip() + for key in REQUIRED_FIELDS + ): + raise ContractError(f"line {number}: required fields must be nonempty strings") + if not local_link(record["page"]) or not local_link(record["source_path"]): + raise ContractError(f"line {number}: page and source paths must be local") + if record["text_sha256"] != hashlib.sha256(record["text"].encode()).hexdigest(): + raise ContractError(f"line {number}: text checksum mismatch") + yield record + + +def inspect_inputs(path: Path) -> dict: + """Validate full ordered inputs, using disk for duplicate detection.""" + content = hashlib.sha256() + display = hashlib.sha256() + raw = hashlib.sha256() + counts: dict[str, int] = {} + versions: set[str] = set() + count = 0 + with tempfile.TemporaryDirectory(prefix="embedding-inputs-") as tmp: + with sqlite3.connect(str(Path(tmp) / "ids.sqlite")) as db: + db.execute("CREATE TABLE ids (id TEXT PRIMARY KEY)") + for record in records(path, raw_digest=raw): + try: + db.execute("INSERT INTO ids VALUES (?)", (record["identifier"],)) + except sqlite3.IntegrityError as exc: + raise ContractError(f"duplicate identifier: {record['identifier']}") from exc + framed_update(content, record["identifier"], record["text"]) + framed_update(display, canonical(record).decode()) + counts[record["category"]] = counts.get(record["category"], 0) + 1 + versions.add(record["adapter_version"]) + count += 1 + if not count: + raise ContractError("adapter input contains no records") + if len(versions) != 1: + raise ContractError("adapter versions must agree within one input") + if digest_file(path) != raw.hexdigest(): + raise ContractError("adapter input changed while inspecting; rerun") + return {"count": count, "corpus_sha256": content.hexdigest(), + "records_sha256": display.hexdigest(), "input_sha256": raw.hexdigest(), + "categories": counts, "adapter_version": versions.pop()} + + +def encoder_profile(*, library_versions: dict | None = None, device: str = "cpu") -> dict: + return {"format_version": FORMAT_VERSION, "model": MODEL, + "revision": MODEL_REVISION, "dimension": MODEL_DIMENSION, + "normalized": True, "dtype": "float32-le", "max_seq_length": MAX_SEQ_LENGTH, + "pooling": "sentence-transformers-model", "truncation": "tail", + "inference_device": device, "weight_dtype": "torch.float32", + "query_instruction": None, "library_versions": library_versions or {}} + + +def validate_profile(profile: dict) -> None: + if not isinstance(profile, dict) or not re.fullmatch( + r"[0-9a-f]{40}", str(profile.get("revision", "")) + ): + raise ContractError("encoder profile must identify an immutable model revision") + if (type(profile.get("format_version")) is not int + or profile["format_version"] != FORMAT_VERSION + or not isinstance(profile.get("model"), str) or not profile["model"] + or type(profile.get("dimension")) is not int or profile["dimension"] < 2 + or profile.get("normalized") is not True or profile.get("dtype") != "float32-le" + or type(profile.get("max_seq_length")) is not int + or profile["max_seq_length"] < 1 + or profile.get("pooling") != "sentence-transformers-model" + or profile.get("truncation") != "tail" + or not re.fullmatch(r"cpu|mps(?::\d+)?|cuda(?::\d+)?", + str(profile.get("inference_device", ""))) + or profile.get("weight_dtype") != "torch.float32" + or "query_instruction" not in profile or profile["query_instruction"] is not None): + raise ContractError("invalid encoder profile") + validate_versions(profile.get("library_versions"), "encoder") + canonical(profile) + + +def validate_versions(value, context: str) -> None: + if (not isinstance(value, dict) or not value + or any(not isinstance(name, str) or not name.strip() + or not isinstance(version, str) or not version.strip() + for name, version in value.items())): + raise ContractError(f"{context} requires recorded software versions") + + +def profile_id(profile: dict) -> str: + validate_profile(profile) + return hashlib.sha256(canonical(profile)).hexdigest() + + +def vector_bytes(vector, dimension: int) -> bytes: + values = [float(value) for value in vector] + if len(values) != dimension or not all(math.isfinite(value) for value in values): + raise ContractError("vector dimension or finiteness check failed") + norm = math.sqrt(sum(value * value for value in values)) + if not 0.999 <= norm <= 1.001: + raise ContractError("embedding vector must have unit norm") + return struct.pack("<" + "f" * dimension, *values) + + +def unpack_vector(blob: bytes, dimension: int): + if len(blob) != dimension * 4: + raise ContractError("cached vector byte length does not match its dimension") + values = struct.unpack("<" + "f" * dimension, blob) + vector_bytes(values, dimension) + return values + + +@contextlib.contextmanager +def cache_connection(path: Path, *, writable: bool = False): + if writable: + path.parent.mkdir(parents=True, exist_ok=True) + connection = sqlite3.connect(path, timeout=30) + connection.execute("PRAGMA synchronous=FULL") + connection.execute("CREATE TABLE IF NOT EXISTS profiles (id TEXT PRIMARY KEY, json TEXT)") + connection.execute("""CREATE TABLE IF NOT EXISTS vectors ( + profile TEXT, identifier TEXT, text_sha256 TEXT, vector BLOB, vector_sha256 TEXT, + PRIMARY KEY (profile, identifier, text_sha256))""") + else: + connection = sqlite3.connect(path.resolve().as_uri() + "?mode=ro", uri=True) + try: + yield connection + finally: + connection.close() + + +def cached_vector(db, key: str, record: dict, dimension: int): + row = db.execute( + "SELECT vector, vector_sha256 FROM vectors " + "WHERE profile=? AND identifier=? AND text_sha256=?", + (key, record["identifier"], record["text_sha256"]), + ).fetchone() + if row is None: + return None + blob, checksum = row + if hashlib.sha256(blob).hexdigest() != checksum: + raise ContractError("cached vector checksum mismatch") + unpack_vector(blob, dimension) + return blob + + +def populate_cache(input_path: Path, cache_path: Path, profile: dict, encoder, + *, batch_size: int = 64) -> dict: + """Reuse exact records and atomically commit each verified encoded batch.""" + if batch_size < 1: + raise ContractError("batch size must be positive") + identity = inspect_inputs(input_path) + key = profile_id(profile) + encoded_count = reused = 0 + pending = [] + with cache_connection(cache_path, writable=True) as db: + previous = db.execute("SELECT json FROM profiles WHERE id=?", (key,)).fetchone() + if previous is not None and previous[0] != canonical(profile).decode(): + raise ContractError("cache profile metadata is inconsistent with its identity") + + def save_batch(): + nonlocal encoded_count + vectors = encoder([record["text"] for record in pending]) + if len(vectors) != len(pending): + raise ContractError("encoder returned the wrong number of vectors") + # Validate the WHOLE batch before starting its transaction. + blobs = [vector_bytes(vector, profile["dimension"]) for vector in vectors] + with db: + db.execute("INSERT OR IGNORE INTO profiles VALUES (?, ?)", + (key, canonical(profile).decode())) + for record, blob in zip(pending, blobs, strict=True): + db.execute("INSERT OR REPLACE INTO vectors VALUES (?, ?, ?, ?, ?)", + (key, record["identifier"], record["text_sha256"], blob, + hashlib.sha256(blob).hexdigest())) + encoded_count += len(pending) + pending.clear() + + for record in records(input_path): + if cached_vector(db, key, record, profile["dimension"]) is not None: + reused += 1 + else: + pending.append(record) + if len(pending) == batch_size: + save_batch() + if pending: + save_batch() + if digest_file(input_path) != identity["input_sha256"]: + raise ContractError("adapter input changed while embedding; rerun") + return {**identity, "profile_id": key, "encoded": encoded_count, "reused": reused} + + +def versions(names: tuple[str, ...]) -> dict[str, str]: + return {name: importlib.metadata.version(name) for name in names} + + +def local_encoder(device: str | None = None): + from sentence_transformers import SentenceTransformer + + model = SentenceTransformer(MODEL, revision=MODEL_REVISION, + trust_remote_code=False, device=device) + model.max_seq_length = MAX_SEQ_LENGTH + model.tokenizer.truncation_side = "right" + profile = encoder_profile(library_versions=versions( + ("sentence-transformers", "transformers", "tokenizers", "torch", "numpy") + ), device=str(model.device)) + if str(next(model.parameters()).dtype) != profile["weight_dtype"]: + raise ContractError("model weights must use the declared float32 precision") + if model.get_sentence_embedding_dimension() != MODEL_DIMENSION: + raise ContractError("model returned an unexpected embedding dimension") + + def encode(texts): + return model.encode(texts, batch_size=len(texts), normalize_embeddings=True, + convert_to_numpy=True, show_progress_bar=False) + + return profile, encode + + +def select_records(input_path: Path, maximum: int, seed: int) -> list[dict]: + if maximum < 3: + raise ContractError("map selection maximum must be at least three") + # Bottom-k hashes are deterministic, bounded and independent of input order. + def ranked(): + for record in records(input_path): + key = hashlib.sha256(canonical([seed, record["identifier"]])).digest() + yield key, record["identifier"], record + return [record for _, _, record in heapq.nsmallest(maximum, ranked())] + + +def atomic_json(path: Path, value: dict) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + descriptor, filename = tempfile.mkstemp(prefix="." + path.name + ".", dir=path.parent) + temporary = Path(filename) + try: + with os.fdopen(descriptor, "wb") as stream: + stream.write(canonical(value) + b"\n") + stream.flush() + os.fsync(stream.fileno()) + os.replace(temporary, path) + finally: + temporary.unlink(missing_ok=True) + + +def build_map(input_path: Path, cache_path: Path, output: Path, profile: dict, + *, maximum: int = 50000, seed: int = 42, neighbors: int = 15, + projector=None, projection_versions: dict | None = None, + title: str = "Semantic text map") -> dict: + import numpy as np + + inputs = inspect_inputs(input_path) + key = profile_id(profile) + selected = select_records(input_path, maximum, seed) + if len(selected) < 3: + raise ContractError("PaCMAP map requires at least three input records") + if neighbors < 1: + raise ContractError("neighbors must be positive") + neighbor_count = min(neighbors, len(selected) - 1) + matrix = np.empty((len(selected), profile["dimension"]), dtype=" dict: + if bundle.is_symlink() or (bundle / "manifest.json").is_symlink(): + raise ContractError("bundle and manifest must not be symbolic links") + manifest = json.loads((bundle / "manifest.json").read_text()) + if not isinstance(manifest, dict) or manifest.get("format_version") != FORMAT_VERSION: + raise ContractError("unsupported map bundle format") + if (manifest.get("representation") != "semantic-text" + or any(not isinstance(manifest.get(name), dict) for name in + ("encoder", "inputs", "files", "coverage", "projection", "source_vectors"))): + raise ContractError("invalid map bundle metadata") + if manifest.get("encoder_profile_sha256") != profile_id(manifest["encoder"]): + raise ContractError("encoder profile checksum mismatch") + expected = {"points.json", "index.html"} + if set(manifest.get("files", {})) != expected: + raise ContractError("bundle must contain exactly the required artifact checksums") + for filename, checksum in manifest["files"].items(): + path = bundle / filename + if path.is_symlink() or digest_file(path) != checksum: + raise ContractError(f"artifact checksum mismatch: {filename}") + if input_path is not None and inspect_inputs(input_path) != manifest["inputs"]: + raise ContractError("map is stale relative to current adapter input") + points = json.loads((bundle / "points.json").read_text()) + if not isinstance(points, list) or len(points) < 3: + raise ContractError("map points must contain at least three records") + coverage = manifest["coverage"] + projection = manifest["projection"] + if (projection.get("method") != "pacmap" or projection.get("dimensions") != 2 + or type(projection.get("seed")) is not int + or type(projection.get("neighbors")) is not int + or not 1 <= projection["neighbors"] < len(points) + or type(projection.get("requested_neighbors")) is not int + or projection["requested_neighbors"] < 1 + or projection.get("initialization") != "pca" + or projection.get("MN_ratio") != 0.5 or projection.get("FP_ratio") != 2.0 + or projection.get("distance") != "euclidean" + or projection.get("learning_rate") != 1.0 + or projection.get("iterations") != [100, 100, 250] + or projection.get("apply_pca") is not True + or projection.get("knn_backend") != "faiss"): + raise ContractError("invalid PaCMAP projection metadata") + validate_versions(projection.get("library_versions"), "projection") + if projection.get("implementation") == "pacmap.PaCMAP": + pairs = projection.get("effective_pairs") + if (not isinstance(pairs, dict) + or any(type(pairs.get(name)) is not int or not 0 <= pairs[name] < len(points) + for name in ("neighbors", "mid_near", "further")) + or pairs["neighbors"] != projection["neighbors"] or pairs["further"] < 1): + raise ContractError("invalid effective PaCMAP pair counts") + elif projection.get("implementation") != "injected-projector": + raise ContractError("unidentified projection implementation") + if (not isinstance(points, list) or len(points) < 3 + or any(type(coverage.get(name)) is not int for name in + ("displayed", "eligible", "total", "omitted", "maximum")) + or not 3 <= len(points) <= coverage["maximum"] + or coverage["omitted"] < 0 + or coverage.get("selection") != "bottom-k-sha256(seed,identifier)"): + raise ContractError("invalid map selection coverage") + source_vectors = manifest["source_vectors"] + if (source_vectors.get("shape") != [len(points), manifest["encoder"]["dimension"]] + or source_vectors.get("dtype") != "float32-le" + or source_vectors.get("order") != "points.json" + or source_vectors.get("storage") != "local-profile-bound-cache" + or not re.fullmatch(r"[0-9a-f]{64}", str(source_vectors.get("sha256", "")))): + raise ContractError("invalid source vector receipt") + for row in points: + if (not isinstance(row, dict) + or any(not isinstance(row.get(name), str) or not row[name].strip() + for name in REQUIRED_FIELDS if name != "text") + or not local_link(row["page"]) or not local_link(row["source_path"]) + or not re.fullmatch(r"[0-9a-f]{64}", row["text_sha256"]) + or not all(type(row.get(name)) in (int, float) and math.isfinite(row[name]) + for name in ("x", "y"))): + raise ContractError("invalid map coordinate or record metadata") + if (coverage["displayed"] != len(points) + or coverage["total"] != manifest["inputs"]["count"] + or coverage["eligible"] != coverage["total"] + or coverage["omitted"] != coverage["total"] - len(points) + or len({row["identifier"] for row in points}) != len(points)): + raise ContractError("map coverage or identifiers are inconsistent") + if input_path is not None: + selected = select_records(input_path, coverage["maximum"], projection["seed"]) + expected = [{key: row[key] for key in REQUIRED_FIELDS if key != "text"} + for row in selected] + observed = [{key: row[key] for key in REQUIRED_FIELDS if key != "text"} + for row in points] + if observed != expected: + raise ContractError("map records differ from the declared input selection") + if cache_path is not None: + digest = hashlib.sha256() + with cache_connection(cache_path) as db: + profile_row = db.execute("SELECT json FROM profiles WHERE id=?", + (manifest["encoder_profile_sha256"],)).fetchone() + if profile_row is None or profile_row[0] != canonical(manifest["encoder"]).decode(): + raise ContractError("cache does not contain the exact encoder profile") + for row in points: + blob = cached_vector(db, manifest["encoder_profile_sha256"], row, + manifest["encoder"]["dimension"]) + if blob is None: + raise ContractError("source vector is missing from the verified cache") + digest.update(blob) + if digest.hexdigest() != source_vectors["sha256"]: + raise ContractError("map source vector receipt differs from the cache") + return manifest + + +def current_bundle(output: Path) -> Path: + pointer = json.loads((output / "current.json").read_text()) + if not re.fullmatch(r"[0-9a-f]{64}", str(pointer.get("bundle", ""))): + raise ContractError("invalid current bundle identifier") + bundle = output / pointer["bundle"] + if bundle.is_symlink() or digest_file(bundle / "manifest.json") != pointer["manifest_sha256"]: + raise ContractError("active manifest checksum mismatch") + return bundle + + +def stage_map(output: Path, published_dir: Path, *, input_path: Path, + expected_bundle: str | None = None) -> dict: + """Stage a verified map into a site build, restoring old files on exceptions. + + The caller owns the repository/build lock. The site's later deployment is + its publication boundary; the two directory renames are not a live-server + transaction. An interrupted machine may leave a named recovery directory. + Policy-checking callers pass the generation name they approved at preflight; + both the selection and its content identity must still match before writes. + """ + source = current_bundle(output) + if expected_bundle is not None and source.name != expected_bundle: + raise ContractError("map generation changed after site preflight") + manifest = validate_bundle(source, input_path=input_path) + if hashlib.sha256(canonical(manifest)).hexdigest() != source.name: + raise ContractError("map manifest differs from its immutable generation identity") + if manifest["projection"]["implementation"] != "pacmap.PaCMAP": + raise ContractError("site publication requires the actual PaCMAP implementation") + if (published_dir.is_symlink() + or (published_dir.exists() and not published_dir.is_dir()) + or source.resolve().is_relative_to(published_dir.resolve()) + or published_dir.resolve().is_relative_to(output.resolve()) + or input_path.resolve().is_relative_to(published_dir.resolve())): + raise ContractError("unsafe map staging destination") + published_dir.parent.mkdir(parents=True, exist_ok=True) + temporary = Path(tempfile.mkdtemp(prefix=".text-map-stage-", dir=published_dir.parent)) + backup = None + try: + for name in ("index.html", "points.json", "manifest.json"): + shutil.copyfile(source / name, temporary / name) + copied = validate_bundle(temporary, input_path=input_path) + if copied != manifest: + raise ContractError("map source changed during site staging") + if published_dir.exists(): + backup = Path(tempfile.mkdtemp(prefix=".text-map-recovery-", dir=published_dir.parent)) + backup.rmdir() + os.rename(published_dir, backup) + try: + os.rename(temporary, published_dir) + except BaseException: + if backup is not None: + os.rename(backup, published_dir) + raise + if backup is not None: + shutil.rmtree(backup) + return manifest + finally: + if temporary.exists(): + shutil.rmtree(temporary) + + +def render_html(title: str, points: list[dict], total: int) -> str: + import html + + payload = canonical(points).decode().replace("<", "\\u003c").replace("&", "\\u0026") + # The site adapter publishes this directory at text-map/. Record pages are + # relative to the site root, one level above this self-contained page. + return f''' + +{html.escape(title)} + +

    {html.escape(title)}

    Showing {len(points):,} of {total:,} input records. +PaCMAP positions summarize similarity between record descriptions.

    + +

    Select a point to open its record.

    + +

      +

      Map provenance and coverage

      + +''' + + +def main(argv=None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + sub = parser.add_subparsers(dest="command", required=True) + inspect_parser = sub.add_parser("inspect") + inspect_parser.add_argument("--input", type=Path, required=True) + embed_parser = sub.add_parser("embed") + embed_parser.add_argument("--input", type=Path, required=True) + embed_parser.add_argument("--cache", type=Path, required=True) + embed_parser.add_argument("--profile-output", type=Path, required=True) + embed_parser.add_argument("--batch-size", type=int, default=64) + embed_parser.add_argument("--device", choices=("cpu", "mps", "cuda")) + project_parser = sub.add_parser("project") + for name in ("input", "cache", "profile", "output"): + project_parser.add_argument("--" + name, type=Path, required=True) + project_parser.add_argument("--max-points", type=int, default=50000) + project_parser.add_argument("--seed", type=int, default=42) + project_parser.add_argument("--neighbors", type=int, default=15) + project_parser.add_argument("--title", default="Semantic text map") + check_parser = sub.add_parser("check") + check_parser.add_argument("--output", type=Path, required=True) + check_parser.add_argument("--input", type=Path) + check_parser.add_argument("--cache", type=Path) + stage_parser = sub.add_parser("stage") + stage_parser.add_argument("--output", type=Path, required=True) + stage_parser.add_argument("--input", type=Path, required=True) + stage_parser.add_argument("--published-dir", type=Path, required=True) + stage_parser.add_argument("--expected-bundle") + args = parser.parse_args(argv) + try: + if args.command == "inspect": + result = inspect_inputs(args.input) + elif args.command == "embed": + inspect_inputs(args.input) # fail before loading model weights + profile, encoder = local_encoder(args.device) + result = populate_cache(args.input, args.cache, profile, encoder, + batch_size=args.batch_size) + atomic_json(args.profile_output, profile) + elif args.command == "project": + profile = json.loads(args.profile.read_text()) + result = build_map(args.input, args.cache, args.output, profile, + maximum=args.max_points, seed=args.seed, + neighbors=args.neighbors, title=args.title) + elif args.command == "check": + result = validate_bundle(current_bundle(args.output), input_path=args.input, + cache_path=args.cache) + else: + result = stage_map(args.output, args.published_dir, input_path=args.input, + expected_bundle=args.expected_bundle) + print(json.dumps(result, indent=2, allow_nan=False)) + return 0 + except (ContractError, OSError, ValueError, KeyError, sqlite3.Error, + importlib.metadata.PackageNotFoundError) as exc: + print(f"embedding-pipeline: {exc}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/stage_text_map.py b/scripts/stage_text_map.py new file mode 100644 index 000000000..f7e84802c --- /dev/null +++ b/scripts/stage_text_map.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +"""Stage the configured shared semantic map without model inference.""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) +from communitymech.text_map_publish import main # noqa: E402 + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/src/communitymech/render.py b/src/communitymech/render.py index 70da89dea..851b4cba7 100644 --- a/src/communitymech/render.py +++ b/src/communitymech/render.py @@ -10,7 +10,8 @@ import yaml from jinja2 import Environment, FileSystemLoader, select_autoescape -from communitymech.paths import DOCS +from communitymech.paths import DOCS, REPO_ROOT +from communitymech.text_map_site import prepare_text_map def _strip_trailing_whitespace(html: str) -> str: @@ -90,6 +91,19 @@ def render_all( self, communities_dir: Path = Path("kb/communities"), output_dir: Path | None = None, + ) -> list[str]: + """Preflight and stage the common map before any generated page changes.""" + output_dir = output_dir if output_dir is not None else DOCS / "communities" + with prepare_text_map(REPO_ROOT) as text_map: + if text_map is not None: + text_map.stage(output_dir.parent) + self.env.globals["text_map_enabled"] = text_map is not None + return self._render_all(communities_dir, output_dir) + + def _render_all( + self, + communities_dir: Path = Path("kb/communities"), + output_dir: Path | None = None, ) -> list[str]: """ Render all community YAML files to HTML. diff --git a/src/communitymech/templates/index.html b/src/communitymech/templates/index.html index effa33dca..e1415a2c9 100644 --- a/src/communitymech/templates/index.html +++ b/src/communitymech/templates/index.html @@ -495,6 +495,7 @@
      ← Home +{% if text_map_enabled %}

      Semantic text map

      {% endif %}

      CommunityMech

      Microbial Community Knowledge Base

      @@ -597,7 +598,7 @@

      Metal Relevance

      diff --git a/src/communitymech/templates/landing.html b/src/communitymech/templates/landing.html index bb340a9c9..09b3d3ea2 100644 --- a/src/communitymech/templates/landing.html +++ b/src/communitymech/templates/landing.html @@ -76,10 +76,11 @@

      CommunityMech

      Microbial community knowledge base — curated, evidence-backed interaction networks.

      +{% if text_map_enabled %}

      Semantic text map

      {% endif %}
      @@ -90,7 +91,7 @@

      Record browser

      Faceted browser of microbial communities — filter by category, ecological state, metals, and rare-earth elements.

      - +

      Embedding browser

      Interactive PaCMAP of community embedding space from taxonomic composition.

      diff --git a/src/communitymech/text_map_publish.py b/src/communitymech/text_map_publish.py new file mode 100644 index 000000000..0724f0b1f --- /dev/null +++ b/src/communitymech/text_map_publish.py @@ -0,0 +1,24 @@ +"""Validate and stage the configured semantic map before Pages deployment.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +from communitymech.text_map_site import prepare_text_map + + +def publish(root: Path) -> dict: + with prepare_text_map(root) as ready: + if ready is not None: + ready.stage(root / "docs") + return {"enabled": ready is not None} + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, default=Path(__file__).resolve().parents[2]) + args = parser.parse_args(argv) + print(json.dumps(publish(args.root.resolve()), sort_keys=True)) + return 0 diff --git a/src/communitymech/text_map_site.py b/src/communitymech/text_map_site.py new file mode 100644 index 000000000..5b35c7148 --- /dev/null +++ b/src/communitymech/text_map_site.py @@ -0,0 +1,92 @@ +"""Prepare a configured common text map before a site build can change files. + +All artifact validation and atomic publication belong to CLAW's shared runtime. +This adapter only supplies fresh full-corpus semantic inputs and site policy. +""" + +from __future__ import annotations + +import importlib.util +import tempfile +from collections.abc import Iterator +from contextlib import contextmanager +from dataclasses import dataclass +from pathlib import Path +from types import ModuleType + +import yaml + +from communitymech.text_map_inputs import export_inputs + + +@dataclass +class PreparedTextMap: + pipeline: ModuleType + source: Path + inputs: Path + expected_bundle: str + + def stage(self, site: Path) -> None: + self.pipeline.stage_map( + self.source, + site / "text-map", + input_path=self.inputs, + expected_bundle=self.expected_bundle, + ) + + +def load_pipeline(root: Path) -> ModuleType: + path = root / "scripts" / "embedding_pipeline.py" + if not path.is_file() or path.is_symlink(): + raise ValueError( + "enabled text map requires the CLAW-governed scripts/embedding_pipeline.py" + ) + spec = importlib.util.spec_from_file_location("communitymech_embedding_pipeline", path) + if spec is None or spec.loader is None: + raise ValueError("cannot load the CLAW embedding pipeline") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + if not callable(getattr(module, "stage_map", None)): + raise ValueError("CLAW embedding pipeline does not provide validated map staging") + return module + + +@contextmanager +def prepare_text_map(root: Path) -> Iterator[PreparedTextMap | None]: + config = root / "conf" / "text_map.yaml" + if config.is_symlink(): + raise ValueError("text map configuration must not be a symlink") + if not config.is_file(): + raise ValueError("text map enablement requires conf/text_map.yaml") + settings = yaml.safe_load(config.read_text(encoding="utf-8")) + if ( + not isinstance(settings, dict) + or set(settings) != {"enabled"} + or type(settings["enabled"]) is not bool + ): + raise ValueError("text map configuration must contain only an explicit enabled boolean") + if not settings["enabled"]: + yield None + return + source = root / "data" / "text_map" + if source.is_symlink() or not (source / "current.json").is_file(): + raise ValueError("enabled text map requires data/text_map/current.json") + pipeline = load_pipeline(root) + with tempfile.TemporaryDirectory(prefix="communitymech-text-map-") as directory: + inputs = Path(directory) / "inputs.jsonl" + receipt = export_inputs(root, inputs) + if receipt["scope"] != "full": + raise ValueError("site publication requires fresh full-corpus inputs") + bundle = pipeline.current_bundle(source) + manifest = pipeline.validate_bundle(bundle, input_path=inputs) + if manifest["projection"]["implementation"] != "pacmap.PaCMAP": + raise ValueError("site publication requires the actual PaCMAP implementation") + profile = manifest["encoder"] + if ( + profile["model"] != pipeline.MODEL + or profile["revision"] != pipeline.MODEL_REVISION + or profile["dimension"] != pipeline.MODEL_DIMENSION + or profile["max_seq_length"] != pipeline.MAX_SEQ_LENGTH + ): + raise ValueError("common semantic map requires the pinned fleet BGE encoder profile") + yield PreparedTextMap(pipeline, source, inputs, bundle.name) diff --git a/tests/test_text_map_recipes.py b/tests/test_text_map_recipes.py new file mode 100644 index 000000000..85f2b5635 --- /dev/null +++ b/tests/test_text_map_recipes.py @@ -0,0 +1,33 @@ +"""The actual just boundary must preserve quoted adapter/staging arguments.""" + +import json +import os +import shutil +import subprocess +from pathlib import Path + +import pytest + + +@pytest.mark.skipif(shutil.which("just") is None, reason="actual recipe boundary requires just") +@pytest.mark.parametrize( + "recipe,script,option", + [ + ("text-map-inputs", "text_map_inputs.py", "--output"), + ("stage-text-map", "stage_text_map.py", "--root"), + ], +) +def test_recipes_preserve_quoted_paths(tmp_path, monkeypatch, recipe, script, option): + capture = tmp_path / "arguments.json" + executable = tmp_path / "uv" + executable.write_text( + "#!/usr/bin/env python3\nimport json,os,sys\nfrom pathlib import Path\n" + 'Path(os.environ["TEXT_MAP_ARGV_CAPTURE"]).write_text(json.dumps(sys.argv[1:]))\n' + ) + executable.chmod(0o755) + monkeypatch.setenv("PATH", str(tmp_path) + os.pathsep + os.environ["PATH"]) + monkeypatch.setenv("TEXT_MAP_ARGV_CAPTURE", str(capture)) + value = str(tmp_path / "path with spaces" / "inputs.jsonl") + root = Path(__file__).resolve().parents[1] + subprocess.run(["just", recipe, option, value], cwd=root, check=True, capture_output=True) + assert json.loads(capture.read_text()) == ["run", "python", "scripts/" + script, option, value] diff --git a/tests/test_text_map_site.py b/tests/test_text_map_site.py new file mode 100644 index 000000000..48ffebb51 --- /dev/null +++ b/tests/test_text_map_site.py @@ -0,0 +1,259 @@ +"""Publication requires an explicit switch and current validated full inputs.""" + +from __future__ import annotations + +import json +from pathlib import Path +from types import SimpleNamespace + +import pytest + +from communitymech import text_map_site as site + + +def configure(root: Path, value="false"): + config = root / "conf" / "text_map.yaml" + config.parent.mkdir(parents=True, exist_ok=True) + config.write_text(f"enabled: {value}\n") + + +def fake_pipeline(): + calls = [] + profile = { + "model": "BAAI/bge-large-en-v1.5", + "revision": "d4aa6901d3a41ba39fb536a557fa166f842b0e09", + "dimension": 1024, + "max_seq_length": 512, + } + manifest = {"encoder": profile, "projection": {"implementation": "pacmap.PaCMAP"}} + + def validate(bundle, *, input_path): + assert json.loads(input_path.read_text()) == {"test": "fresh full inputs"} + calls.append(("validate", bundle, input_path)) + return manifest + + def stage(output, published_dir, *, input_path, expected_bundle): + assert json.loads(input_path.read_text()) == {"test": "fresh full inputs"} + calls.append(("stage", output, published_dir, expected_bundle)) + return manifest + + pipeline = SimpleNamespace( + MODEL=profile["model"], + MODEL_REVISION=profile["revision"], + MODEL_DIMENSION=1024, + MAX_SEQ_LENGTH=512, + current_bundle=lambda output: output / ("a" * 64), + validate_bundle=validate, + stage_map=stage, + ) + return pipeline, calls, manifest + + +def enable_fixture(root, monkeypatch): + configure(root, "true") + source = root / "data" / "text_map" + source.mkdir(parents=True) + (source / "current.json").write_text("{}") + pipeline, calls, manifest = fake_pipeline() + monkeypatch.setattr(site, "load_pipeline", lambda _root: pipeline) + + def export(actual_root, output, **kwargs): + assert actual_root == root + assert not kwargs, "publication cannot request a canary or limited input set" + output.write_text(json.dumps({"test": "fresh full inputs"})) + return {"scope": "full"} + + monkeypatch.setattr(site, "export_inputs", export) + return pipeline, calls, manifest + + +def test_disabled_map_requires_no_runtime_or_artifact(tmp_path, monkeypatch): + configure(tmp_path) + monkeypatch.setattr( + site, "load_pipeline", lambda _root: pytest.fail("disabled map loaded runtime") + ) + with site.prepare_text_map(tmp_path) as ready: + assert ready is None + + +def test_enabled_map_missing_bundle_fails(tmp_path): + configure(tmp_path, "true") + with pytest.raises(ValueError, match="current.json"), site.prepare_text_map(tmp_path): + pass + + +def test_enabled_map_missing_shared_runtime_fails(tmp_path): + configure(tmp_path, "true") + source = tmp_path / "data" / "text_map" + source.mkdir(parents=True) + (source / "current.json").write_text("{}") + with pytest.raises(ValueError, match="CLAW-governed"), site.prepare_text_map(tmp_path): + pass + + +@pytest.mark.parametrize("value", ["1", "'true'", "null", "[]"]) +def test_enablement_requires_an_actual_boolean(tmp_path, value): + configure(tmp_path, value) + with pytest.raises(ValueError, match="enabled boolean"), site.prepare_text_map(tmp_path): + pass + + +def test_enabled_map_uses_fresh_full_inputs_and_canonical_stage(tmp_path, monkeypatch): + _, calls, _ = enable_fixture(tmp_path, monkeypatch) + with site.prepare_text_map(tmp_path) as ready: + inputs = ready.inputs + ready.stage(tmp_path / "published") + assert calls[-1] == ( + "stage", + tmp_path / "data" / "text_map", + tmp_path / "published" / "text-map", + "a" * 64, + ) + assert not inputs.exists() + assert calls[0][0] == "validate" + + +def test_legacy_encoder_cannot_be_published_as_the_common_space(tmp_path, monkeypatch): + _, _, manifest = enable_fixture(tmp_path, monkeypatch) + manifest["encoder"] = {"model": "MiniLM", "revision": "0" * 40, "dimension": 384} + with pytest.raises(ValueError, match="pinned fleet BGE"), site.prepare_text_map(tmp_path): + pass + + +def test_injected_projector_cannot_reach_the_site_build(tmp_path, monkeypatch): + _, _, manifest = enable_fixture(tmp_path, monkeypatch) + manifest["projection"]["implementation"] = "injected-projector" + with pytest.raises(ValueError, match="actual PaCMAP"), site.prepare_text_map(tmp_path): + pass + + +def test_subset_receipt_cannot_reach_publication(tmp_path, monkeypatch): + enable_fixture(tmp_path, monkeypatch) + monkeypatch.setattr(site, "export_inputs", lambda _root, _output: {"scope": "subset"}) + with pytest.raises(ValueError, match="full-corpus"), site.prepare_text_map(tmp_path): + pass + + +def test_pointer_change_does_not_replace_the_preflight_generation(tmp_path, monkeypatch): + pipeline, _, _ = enable_fixture(tmp_path, monkeypatch) + published = tmp_path / "published" / "text-map" + published.mkdir(parents=True) + old = published / "index.html" + old.write_text("previously published map") + seen = [] + + def checked_stage(output, published_dir, *, input_path, expected_bundle): + seen.append(expected_bundle) + if pipeline.current_bundle(output).name != expected_bundle: + raise ValueError("current map differs from preflight generation") + (published_dir / "index.html").write_text("replacement map") + + monkeypatch.setattr(pipeline, "stage_map", checked_stage) + with site.prepare_text_map(tmp_path) as ready: + monkeypatch.setattr(pipeline, "current_bundle", lambda output: output / ("b" * 64)) + with pytest.raises(ValueError, match="preflight generation"): + ready.stage(tmp_path / "published") + assert seen == ["a" * 64] + assert old.read_text() == "previously published map" + + +def test_alternate_window_cannot_be_published_as_the_common_space(tmp_path, monkeypatch): + _, _, manifest = enable_fixture(tmp_path, monkeypatch) + manifest["encoder"]["max_seq_length"] = 256 + with pytest.raises(ValueError, match="pinned fleet BGE"), site.prepare_text_map(tmp_path): + pass + + +def test_pages_upload_is_preceded_by_the_actual_staging_command(): + import yaml + + root = Path(__file__).resolve().parents[1] + workflow = yaml.safe_load((root / ".github/workflows/generate-pages.yaml").read_text()) + steps = workflow["jobs"]["deploy"]["steps"] + stage = next( + index + for index, step in enumerate(steps) + if "python scripts/stage_text_map.py" in step.get("run", "") + ) + upload = next( + index + for index, step in enumerate(steps) + if step.get("uses", "").startswith("actions/upload-pages-artifact@") + ) + assert stage < upload + assert "|| true" not in steps[stage]["run"] + trigger = workflow["on"] if "on" in workflow else workflow[True] + paths = trigger["push"]["paths"] + assert "data/text_map/**" in paths + assert "conf/text_map.yaml" in paths + + +def test_renderer_preflight_preserves_prior_site(tmp_path, monkeypatch): + from communitymech import render + + configure(tmp_path, "true") + published = tmp_path / "docs" + published.mkdir() + old = published / "index.html" + old.write_text("previous site") + monkeypatch.setattr(render, "REPO_ROOT", tmp_path) + renderer = render.CommunityRenderer() + with pytest.raises(ValueError, match="current.json"): + renderer.render_all(tmp_path / "kb/communities", published / "communities") + assert old.read_text() == "previous site" + + +def test_real_renderer_stages_map_before_pages_and_retains_graph_navigation(tmp_path, monkeypatch): + import shutil + from contextlib import contextmanager + + from communitymech import render + from communitymech.paths import default_record_roots + + root = Path(__file__).resolve().parents[1] + records = [ + next(iter(sorted(record_root.glob("*.yaml")))) for record_root in default_record_roots() + ] + for record in records: + destination = tmp_path / record.relative_to(root) + destination.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(record, destination) + published = tmp_path / "docs" + + class Prepared: + def stage(self, site_root): + assert site_root == published + assert not (published / "index.html").exists() + target = site_root / "text-map" + target.mkdir(parents=True) + for name in ("index.html", "points.json", "manifest.json"): + (target / name).write_text("verified fixture " + name) + + @contextmanager + def ready(_root): + yield Prepared() + + monkeypatch.setattr(render, "prepare_text_map", ready) + renderer = render.CommunityRenderer() + assert renderer.render_all(tmp_path / "kb/communities", published / "communities") == [] + assert renderer.render_isolates(tmp_path / "data/isolates", published / "isolates") == [] + for name in ("index.html", "browser.html"): + text = (published / name).read_text() + assert 'href="text-map/"' in text + assert 'href="community_umap.html"' in text + for record in records: + section = "isolates" if record.parent.name == "isolates" else "communities" + assert (published / section / (record.stem + ".html")).exists() + for name in ("index.html", "points.json", "manifest.json"): + assert (published / "text-map" / name).read_text() == "verified fixture " + name + + +def test_navigation_requires_successful_staging(): + from communitymech import render + + renderer = render.CommunityRenderer() + for name in ("landing.html", "index.html"): + template = renderer.env.get_template(name) + context = {"communities": [], "num_communities": 0} + assert 'href="text-map/"' not in template.render(text_map_enabled=False, **context) + assert 'href="text-map/"' in template.render(text_map_enabled=True, **context) From d30cbd49431c08664b7e51a52b0ea376dcc380b5 Mon Sep 17 00:00:00 2001 From: "marcin p. joachimiak" <4625870+realmarcin@users.noreply.github.com> Date: Mon, 14 Sep 2026 19:08:52 -0700 Subject: [PATCH 05/11] chore: synchronize reviewed shared embedding runtime and governance pin --- conf/embedding-runtime/README.md | 47 ++ conf/embedding-runtime/pyproject.toml | 17 + conf/embedding-runtime/uv.lock | 915 ++++++++++++++++++++++++++ scripts/.vendored_canon_ref | 2 +- scripts/embedding_pipeline.py | 495 +++++++++----- 5 files changed, 1308 insertions(+), 168 deletions(-) create mode 100644 conf/embedding-runtime/README.md create mode 100644 conf/embedding-runtime/pyproject.toml create mode 100644 conf/embedding-runtime/uv.lock diff --git a/conf/embedding-runtime/README.md b/conf/embedding-runtime/README.md new file mode 100644 index 000000000..b5c9f2af2 --- /dev/null +++ b/conf/embedding-runtime/README.md @@ -0,0 +1,47 @@ +# Optional text-map runtime + +This governed Python 3.13 environment is for explicit local embedding and +PaCMAP builds. Normal tests, record validation and Pages rendering do not +install it. The lock pins numerical/model dependencies independently of a +Mech's curation environment; the encoder and map receipts record actual +installed library versions as well. + +From a Mech repository root, export current semantic input with its domain +adapter, inspect it, and then explicitly run inference and projection: + +```bash +uv run python scripts/text_map_inputs.py --output workspace/text-map-inputs.jsonl +uv run python scripts/embedding_pipeline.py inspect --input workspace/text-map-inputs.jsonl +uv run --locked --project conf/embedding-runtime python scripts/embedding_pipeline.py embed --input workspace/text-map-inputs.jsonl --cache workspace/text-map-vectors.sqlite --profile-output workspace/text-map-profile.json --device cpu +uv run --locked --project conf/embedding-runtime python scripts/embedding_pipeline.py project --input workspace/text-map-inputs.jsonl --cache workspace/text-map-vectors.sqlite --profile workspace/text-map-profile.json --output data/text_map +uv run python scripts/embedding_pipeline.py check --output data/text_map --input workspace/text-map-inputs.jsonl --cache workspace/text-map-vectors.sqlite +``` + +Run one small explicit `--limit` adapter canary first, with separate output and +cache paths. Verify its vector count, finite coordinates, source receipt, +rendered page and repeat-run cache reuse before a full build. A canary is not a +complete-corpus artifact and cannot satisfy an enabled site's full-input check. + +The default display limit is 50,000 records selected deterministically. All +input records must have a verified cache entry; the map reports omitted display +records. No all-pairs similarity matrix is allocated. + +Model weights are downloaded only by the explicit `embed` command. A cached +model can be used with `HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1`. There are no +provider API calls. Old unpinned vector caches are not assigned this profile. + +The existing site renderer stages a validated bundle at `text-map/` only after +the repository enables it in `conf/text_map.yaml`. Its normal Python environment +runs this verification without importing Torch, NumPy or PaCMAP. The build must +fail if an enabled map is absent, stale or invalid. Preflight checks the exact +BGE model/revision, 1024 dimensions and the fleet's 512-token window. The staging +call passes the approved generation name through `expected_bundle`, rejecting +a different pointer or altered generation before changing site files. +Site deployment remains the +publication boundary. A machine interruption during directory staging may +leave `.text-map-recovery-*` beside the destination; preserve it for recovery. + +The runtime has been exercised on macOS Apple Silicon. Platform-specific model +wheels may constrain where heavy builds run; the standard-library verifier is +independent of those wheels. Cross-platform reproducibility is not implied by +the lock or a fixed random seed. diff --git a/conf/embedding-runtime/pyproject.toml b/conf/embedding-runtime/pyproject.toml new file mode 100644 index 000000000..680529076 --- /dev/null +++ b/conf/embedding-runtime/pyproject.toml @@ -0,0 +1,17 @@ +[project] +name = "mech-embedding-runtime" +version = "1.0.0" +requires-python = ">=3.13,<3.14" +dependencies = [ + "sentence-transformers==6.0.0", + "transformers==5.17.0", + "torch==2.14.0", + "pacmap==0.9.1", + "numpy==2.3.5", + "numba==0.63.1", + "scikit-learn==1.8.0", + "PyYAML==6.0.3", +] + +[tool.uv] +package = false diff --git a/conf/embedding-runtime/uv.lock b/conf/embedding-runtime/uv.lock new file mode 100644 index 000000000..1e355a292 --- /dev/null +++ b/conf/embedding-runtime/uv.lock @@ -0,0 +1,915 @@ +version = 1 +revision = 1 +requires-python = "==3.13.*" + +[[package]] +name = "annotated-doc" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302 }, +] + +[[package]] +name = "anyio" +version = "4.15.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/d2/f4d173e22df740bc37b1db102b386ba719b66e95b0f0d751f556b387e6d2/anyio-4.15.1.tar.gz", hash = "sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94", size = 276966 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b8/4bd346e22b28902df4d651910f5242c28d84e4a5c2435ca5c3f797ed7e2e/anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101", size = 132079 }, +] + +[[package]] +name = "certifi" +version = "2026.7.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983 }, +] + +[[package]] +name = "click" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251 }, +] + +[[package]] +name = "cloudpickle" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/27/fb/576f067976d320f5f0114a8d9fa1215425441bb35627b1993e5afd8111e5/cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414", size = 22330 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a", size = 22228 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "cuda-bindings" +version = "13.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-pathfinder" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/cf/165b4d449f94956c2a60930cf5dfeb27132ead60a7e7f2c37819df1cba07/cuda_bindings-13.4.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b601c0cbf0dffb648f68e56a60b320738a20210293f33896a1964a6438cc65f1", size = 6313772 }, + { url = "https://files.pythonhosted.org/packages/d9/f9/cf021d1560541caa1f35f3e7e311d2678dbacb4fa6a4573b63470fe1ae00/cuda_bindings-13.4.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e2c357698588b06ebd65811ee2013b6650dd0a10d16d899924aabad0d606d76", size = 6924300 }, +] + +[[package]] +name = "cuda-pathfinder" +version = "1.8.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/e6/22df83f82f9bc26cb1c42265cf14d34d4908dba2a0f261bd7b28244acb00/cuda_pathfinder-1.8.1-py3-none-any.whl", hash = "sha256:ae0137ff9e56ea97499bcbf54f5f2778ec25f3266715ac86da192a795af982a8", size = 62552 }, +] + +[[package]] +name = "cuda-toolkit" +version = "13.0.3.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c7/a79086a62c98befcdb8349656c6f114e2db3b8b2422f6e25c97a7f2a9a3c/cuda_toolkit-13.0.3.0-py2.py3-none-any.whl", hash = "sha256:d693caaa261214ddd7dbb60d68e71cbed884e68c2be7509778f3051da0b91c3f", size = 2512 }, +] + +[package.optional-dependencies] +cublas = [ + { name = "nvidia-cublas", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-cuda-nvrtc", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cudart = [ + { name = "nvidia-cuda-runtime", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cufft = [ + { name = "nvidia-cufft", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cufile = [ + { name = "nvidia-cufile", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, +] +cupti = [ + { name = "nvidia-cuda-cupti", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +curand = [ + { name = "nvidia-curand", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cusolver = [ + { name = "nvidia-cublas", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-cusolver", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-cusparse", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +cusparse = [ + { name = "nvidia-cusparse", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +nvjitlink = [ + { name = "nvidia-nvjitlink", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +nvrtc = [ + { name = "nvidia-cuda-nvrtc", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] +nvtx = [ + { name = "nvidia-nvtx", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine == 'AMD64' and sys_platform == 'win32')" }, +] + +[[package]] +name = "faiss-cpu" +version = "1.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "packaging" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/68/20e91694ad9a8b2bb48af956899e52b645cb1501e7e2ec31cb733da4d4c5/faiss_cpu-1.15.0-cp310-abi3-macosx_14_0_arm64.whl", hash = "sha256:50ea471ef1f4f3580eda8ab0ec9727d4bf65fd71c444bf306ce7cdbba8a42b21", size = 4904897 }, + { url = "https://files.pythonhosted.org/packages/d2/cd/ef4cf498977c4a84af7a8920bc97ca49fc19060c8464c63fab58847b4692/faiss_cpu-1.15.0-cp310-abi3-macosx_15_0_x86_64.whl", hash = "sha256:dd383bb1ce06fabcff5785f998f253aa88f88dcbe1fe36c922417cd6666dd896", size = 7087977 }, + { url = "https://files.pythonhosted.org/packages/94/c8/88b072bf55714405d0d7e11c12349510f15a69ae56033b1cd894fb2be7d6/faiss_cpu-1.15.0-cp310-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d0a2d5d33fe023e263d0d355a837f20db67578e3be27fc5f4012a273274abf6", size = 9835009 }, + { url = "https://files.pythonhosted.org/packages/c8/3b/8878dbfc78a0084bbd408b34827a58b530be98132fcf620b7e15f9191614/faiss_cpu-1.15.0-cp310-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec9b29aae29e428c085c2d49dbb02e4673cdea75db418d420f9e60e0b4184498", size = 18764625 }, + { url = "https://files.pythonhosted.org/packages/db/2a/654116e6ee2808562a6b2a11c396bdb46d45689e3bf7206ee99400589cab/faiss_cpu-1.15.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:30da3029952f0de69f16ce31946fd63fc3e292c867749bbcd2c0a0f09fd06f65", size = 11413863 }, + { url = "https://files.pythonhosted.org/packages/9d/8c/0a0f09659c1972aa83b9820cd3dd7f68f6678cfcfebde542e1c23d7d8663/faiss_cpu-1.15.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:88fbe1acac6978869063cb2f9477f85718da596a6e0a17751618f9c756bce255", size = 19470092 }, + { url = "https://files.pythonhosted.org/packages/96/74/4a70395a6e07036628a1bd0b3f709101a6aecfa6a746db13b6e7921cf291/faiss_cpu-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:22dddb013e764aad66dac6cd15b49c7598d60339e0591b73b5e081629419c21b", size = 16251914 }, +] + +[[package]] +name = "filelock" +version = "3.32.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/38/46/126b1831dca12060d4a8296bf9c4fe5c93c4f22197fa239cb0cc82042bba/filelock-3.32.6.tar.gz", hash = "sha256:a3f55a18af3652a94d8f47d6055df434f254ca1d02ef2524850c6d249ca2512c", size = 225172 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/06/4f138f618dbea66803291274f228f01daf29f306fe8b96bc30dab765df75/filelock-3.32.6-py3-none-any.whl", hash = "sha256:3f16ecd0117feae0dfc147e8c62eb5daeccd8bd800378c3ddf416de9b4feb6b1", size = 100189 }, +] + +[[package]] +name = "fsspec" +version = "2026.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/78/f34251dadb8f3921264a1d9b8946f5e542014ee2614b285261b4e40e6775/fsspec-2026.7.0.tar.gz", hash = "sha256:c803c40f4cf860b49dea58ee3e1c33cb9c790520e233537e1340049f89b82a88", size = 317040 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/3c/6a2bf344106328fd04963664a60b9bb6496fc25df8e962fcdc1367285fb9/fsspec-2026.7.0-py3-none-any.whl", hash = "sha256:b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279", size = 206583 }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, +] + +[[package]] +name = "hf-xet" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/ab/522a2ab67f27971a9d48ca666d4fca85ef7d5282d142e31fd087e27b1bbe/hf_xet-1.6.0.tar.gz", hash = "sha256:2e58454a340b3556dfa4972d5451aff4fba8dd42a236600ba1a1d2b1514f0fef", size = 920527 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/50/7afa2c9c787405864fc47a0d1bbc02c62e9101947ed43c1f43899fc7d91d/hf_xet-1.6.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:633dc0cd71d32da58ab8c03ad38e2fac452c15c2b0a2866ebf6ededfe0a5061d", size = 4071729 }, + { url = "https://files.pythonhosted.org/packages/4b/69/55b8dcf636142ae660fec1869fcac14c4da2e8412e14d6eee1523be77e9f/hf_xet-1.6.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:f0906082d9932ae0c0057fa194041c22b4e2cdb46b2592ef3b91f020d62a081a", size = 3876287 }, + { url = "https://files.pythonhosted.org/packages/67/4e/a28359bf1c1ecf11eba22123168c138698f7cb576ac678f5a2e16cd5da08/hf_xet-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d62671bb130879cef0ee4c9ebe47a14af6c66ec53e6d84dc15936e5ffdfac82f", size = 4464663 }, + { url = "https://files.pythonhosted.org/packages/9a/69/1f0cbc2fb22ae6082d094f743d1b8945a3f36f6089cb95f42b7ee348cda7/hf_xet-1.6.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0e6e21fa3cdfcdcd76748564bf593870a5e013f47d97cf10aed63aa222cff5b7", size = 4262538 }, + { url = "https://files.pythonhosted.org/packages/d1/3a/4f4f2301ade26e404462d3336fa11f7958d914cabbabdd6e03c3c5d5658c/hf_xet-1.6.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4fc74352a17015bd0ee90038bc9efe38db894cde45f268b6712b04fce8cd0acb", size = 4460520 }, + { url = "https://files.pythonhosted.org/packages/ab/5f/311725e2a905534dfee2dcb5b08414f249147f1f12252bfc2bd24caa075c/hf_xet-1.6.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4f71cba6129110c3374a33f919001ff130488fc23553698e34cc1c2a1198c", size = 4675937 }, + { url = "https://files.pythonhosted.org/packages/98/b7/8c59a66d15205024662f1d66968136f13893f96df1ddc5087e2e281fc95f/hf_xet-1.6.0-cp38-abi3-win_amd64.whl", hash = "sha256:fb4fadde1b2b70bf4c0c14a6dccbe7194b1c28947fefd5bbe3fed9d940676c3b", size = 4033128 }, + { url = "https://files.pythonhosted.org/packages/73/63/ca511b6f802f28cf3489b280fe77475bcca8de85e81a6299d7916b5b5555/hf_xet-1.6.0-cp38-abi3-win_arm64.whl", hash = "sha256:3dc3e35441ba395006af5aaacc40ef2e603c51ef46c3530b9156185f00935ea3", size = 3859359 }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, +] + +[[package]] +name = "huggingface-hub" +version = "1.31.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "httpx" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/f0/61159db90b5cd275d55516fe27920828e7d3be4053fdbdb27c3f70e5f1ef/huggingface_hub-1.31.0.tar.gz", hash = "sha256:f8e9e710a210613fa5d0f26bba6da05ef4aef9fba5a0f23f508f5ac4d08b6f90", size = 968039 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/7f/3f886a625043b77312b80da2f2bf00b5ecbf5a73061af1aa0259cd258c9d/huggingface_hub-1.31.0-py3-none-any.whl", hash = "sha256:9dbb6a503cbe2494ea666695207e7262d410659e09134059deb83e5480864667", size = 798313 }, +] + +[[package]] +name = "idna" +version = "3.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/f7/abb373e5757eaec4b922b92f97ec8d6d7e057cf06778247604fbc4e7c3f3/idna-3.19.tar.gz", hash = "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15", size = 215237 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/b0/0e52c878c53f245edd3a11020f20979b3f490f245af532c7cae3027754b5/idna-3.19-py3-none-any.whl", hash = "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4", size = 68550 }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, +] + +[[package]] +name = "joblib" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cloudpickle" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/1d/537ab090f302b838943a1b56497dd53059b9a9b46a074936470173a2e207/joblib-1.6.0.tar.gz", hash = "sha256:2ccc96785b12046c08fd6d55839c12857831b54a3c1673ffadd2f04bfc4eda03", size = 327903 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/53/84099323c2ec4be98d935f63c033ac4151ee83836ca1050ede3b3aadf155/joblib-1.6.0-py3-none-any.whl", hash = "sha256:3dbbf9f6e4b592a2357b854608e980fe6390d131d7a82f011a377ef2ebef7aba", size = 306115 }, +] + +[[package]] +name = "llvmlite" +version = "0.46.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/cd/08ae687ba099c7e3d21fe2ea536500563ef1943c5105bf6ab4ee3829f68e/llvmlite-0.46.0.tar.gz", hash = "sha256:227c9fd6d09dce2783c18b754b7cd9d9b3b3515210c46acc2d3c5badd9870ceb", size = 193456 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/ff/3eba7eb0aed4b6fca37125387cd417e8c458e750621fce56d2c541f67fa8/llvmlite-0.46.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:30b60892d034bc560e0ec6654737aaa74e5ca327bd8114d82136aa071d611172", size = 37232767 }, + { url = "https://files.pythonhosted.org/packages/0e/54/737755c0a91558364b9200702c3c9c15d70ed63f9b98a2c32f1c2aa1f3ba/llvmlite-0.46.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6cc19b051753368a9c9f31dc041299059ee91aceec81bd57b0e385e5d5bf1a54", size = 56275176 }, + { url = "https://files.pythonhosted.org/packages/e6/91/14f32e1d70905c1c0aa4e6609ab5d705c3183116ca02ac6df2091868413a/llvmlite-0.46.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bca185892908f9ede48c0acd547fe4dc1bafefb8a4967d47db6cf664f9332d12", size = 55128629 }, + { url = "https://files.pythonhosted.org/packages/4a/a7/d526ae86708cea531935ae777b6dbcabe7db52718e6401e0fb9c5edea80e/llvmlite-0.46.0-cp313-cp313-win_amd64.whl", hash = "sha256:67438fd30e12349ebb054d86a5a1a57fd5e87d264d2451bcfafbbbaa25b82a35", size = 38138941 }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687 }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622 }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029 }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374 }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980 }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990 }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784 }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588 }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041 }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543 }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113 }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911 }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658 }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066 }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639 }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569 }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284 }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801 }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769 }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642 }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612 }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200 }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973 }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +] + +[[package]] +name = "mech-embedding-runtime" +version = "1.0.0" +source = { virtual = "." } +dependencies = [ + { name = "numba" }, + { name = "numpy" }, + { name = "pacmap" }, + { name = "pyyaml" }, + { name = "scikit-learn" }, + { name = "sentence-transformers" }, + { name = "torch" }, + { name = "transformers" }, +] + +[package.metadata] +requires-dist = [ + { name = "numba", specifier = "==0.63.1" }, + { name = "numpy", specifier = "==2.3.5" }, + { name = "pacmap", specifier = "==0.9.1" }, + { name = "pyyaml", specifier = "==6.0.3" }, + { name = "scikit-learn", specifier = "==1.8.0" }, + { name = "sentence-transformers", specifier = "==6.0.0" }, + { name = "torch", specifier = "==2.14.0" }, + { name = "transformers", specifier = "==5.17.0" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 }, +] + +[[package]] +name = "networkx" +version = "3.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504 }, +] + +[[package]] +name = "numba" +version = "0.63.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llvmlite" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dc/60/0145d479b2209bd8fdae5f44201eceb8ce5a23e0ed54c71f57db24618665/numba-0.63.1.tar.gz", hash = "sha256:b320aa675d0e3b17b40364935ea52a7b1c670c9037c39cf92c49502a75902f4b", size = 2761666 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/f7/e19e6eff445bec52dde5bed1ebb162925a8e6f988164f1ae4b3475a73680/numba-0.63.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:0bd4fd820ef7442dcc07da184c3f54bb41d2bdb7b35bacf3448e73d081f730dc", size = 2680954 }, + { url = "https://files.pythonhosted.org/packages/e9/6c/1e222edba1e20e6b113912caa9b1665b5809433cbcb042dfd133c6f1fd38/numba-0.63.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:53de693abe4be3bd4dee38e1c55f01c55ff644a6a3696a3670589e6e4c39cde2", size = 3809736 }, + { url = "https://files.pythonhosted.org/packages/76/0a/590bad11a8b3feeac30a24d01198d46bdb76ad15c70d3a530691ce3cae58/numba-0.63.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:81227821a72a763c3d4ac290abbb4371d855b59fdf85d5af22a47c0e86bf8c7e", size = 3508854 }, + { url = "https://files.pythonhosted.org/packages/4e/f5/3800384a24eed1e4d524669cdbc0b9b8a628800bb1e90d7bd676e5f22581/numba-0.63.1-cp313-cp313-win_amd64.whl", hash = "sha256:eb227b07c2ac37b09432a9bda5142047a2d1055646e089d4a240a2643e508102", size = 2750228 }, +] + +[[package]] +name = "numpy" +version = "2.3.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251 }, + { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652 }, + { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172 }, + { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990 }, + { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902 }, + { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430 }, + { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551 }, + { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275 }, + { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637 }, + { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090 }, + { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710 }, + { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292 }, + { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897 }, + { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391 }, + { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275 }, + { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855 }, + { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359 }, + { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374 }, + { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587 }, + { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940 }, + { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341 }, + { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507 }, +] + +[[package]] +name = "nvidia-cublas" +version = "13.1.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cuda-nvrtc" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/a1/0bd24ee8c8d03adac032fd2909426a00c88f8c57961b1277ded97f91119f/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b7a210458267ac818974c53038fbec2e969d5c99f305ab15c72522fa9f001dd5", size = 542848918 }, + { url = "https://files.pythonhosted.org/packages/3b/cd/154ca20c38269e05eff77c1464e6c1da89f50a6390b565e9d82e06bc11e1/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:37936a16db8fe4ac1f065c2139360608a543a09275cb1a1af612e08cfa065436", size = 423138758 }, +] + +[[package]] +name = "nvidia-cuda-cupti" +version = "13.0.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/2a/80353b103fc20ce05ef51e928daed4b6015db4aaa9162ed0997090fe2250/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_aarch64.whl", hash = "sha256:796bd679890ee55fb14a94629b698b6db54bcfd833d391d5e94017dd9d7d3151", size = 10310827 }, + { url = "https://files.pythonhosted.org/packages/33/6d/737d164b4837a9bbd202f5ae3078975f0525a55730fe871d8ed4e3b952b0/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_x86_64.whl", hash = "sha256:4eb01c08e859bf924d222250d2e8f8b8ff6d3db4721288cf35d14252a4d933c8", size = 10715597 }, +] + +[[package]] +name = "nvidia-cuda-nvrtc" +version = "13.0.88" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/68/483a78f5e8f31b08fb1bb671559968c0ca3a065ac7acabfc7cee55214fd6/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:ad9b6d2ead2435f11cbb6868809d2adeeee302e9bb94bcf0539c7a40d80e8575", size = 90215200 }, + { url = "https://files.pythonhosted.org/packages/b7/dc/6bb80850e0b7edd6588d560758f17e0550893a1feaf436807d64d2da040f/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d27f20a0ca67a4bb34268a5e951033496c5b74870b868bacd046b1b8e0c3267b", size = 43015449 }, +] + +[[package]] +name = "nvidia-cuda-runtime" +version = "13.0.96" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/4f/17d7b9b8e285199c58ce28e31b5c5bbaa4d8271af06a89b6405258245de2/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ef9bcbe90493a2b9d810e43d249adb3d02e98dd30200d86607d8d02687c43f55", size = 2261060 }, + { url = "https://files.pythonhosted.org/packages/2e/24/d1558f3b68b1d26e706813b1d10aa1d785e4698c425af8db8edc3dced472/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f82250d7782aa23b6cfe765ecc7db554bd3c2870c43f3d1821f1d18aebf0548", size = 2243632 }, +] + +[[package]] +name = "nvidia-cudnn-cu13" +version = "9.24.0.43" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/30/7c257e3d5cb4fecb147b93895c66e29c93f8e76d74b45bb418ff0587c4ec/nvidia_cudnn_cu13-9.24.0.43-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:a6812a554a1ff0413e9c52b84c26c050380649ab9615f9c16bded368ce9f421f", size = 650976863 }, + { url = "https://files.pythonhosted.org/packages/5c/ba/791cffd048fe5b044e620df55267e3e95c0e6e07d50b41e377c03dfc910f/nvidia_cudnn_cu13-9.24.0.43-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:71f181cd810e90f9b6023b01186fe82d13d65f0ec098581ee201d39fad769e4b", size = 553099438 }, +] + +[[package]] +name = "nvidia-cufft" +version = "12.0.0.61" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554 }, + { url = "https://files.pythonhosted.org/packages/a8/2f/7b57e29836ea8714f81e9898409196f47d772d5ddedddf1592eadb8ab743/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c44f692dce8fd5ffd3e3df134b6cdb9c2f72d99cf40b62c32dde45eea9ddad3", size = 214085489 }, +] + +[[package]] +name = "nvidia-cufile" +version = "1.15.1.6" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/70/4f193de89a48b71714e74602ee14d04e4019ad36a5a9f20c425776e72cd6/nvidia_cufile-1.15.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08a3ecefae5a01c7f5117351c64f17c7c62efa5fffdbe24fc7d298da19cd0b44", size = 1223672 }, + { url = "https://files.pythonhosted.org/packages/ab/73/cc4a14c9813a8a0d509417cf5f4bdaba76e924d58beb9864f5a7baceefbf/nvidia_cufile-1.15.1.6-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:bdc0deedc61f548bddf7733bdc216456c2fdb101d020e1ab4b88d232d5e2f6d1", size = 1136992 }, +] + +[[package]] +name = "nvidia-curand" +version = "10.4.0.35" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/72/7c2ae24fb6b63a32e6ae5d241cc65263ea18d08802aaae087d9f013335a2/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:133df5a7509c3e292aaa2b477afd0194f06ce4ea24d714d616ff36439cee349a", size = 61962106 }, + { url = "https://files.pythonhosted.org/packages/a5/9f/be0a41ca4a4917abf5cb9ae0daff1a6060cc5de950aec0396de9f3b52bc5/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:1aee33a5da6e1db083fe2b90082def8915f30f3248d5896bcec36a579d941bfc", size = 59544258 }, +] + +[[package]] +name = "nvidia-cusolver" +version = "12.0.4.66" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas" }, + { name = "nvidia-cusparse" }, + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760 }, + { url = "https://files.pythonhosted.org/packages/5f/67/cba3777620cdacb99102da4042883709c41c709f4b6323c10781a9c3aa34/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:0a759da5dea5c0ea10fd307de75cdeb59e7ea4fcb8add0924859b944babf1112", size = 200941980 }, +] + +[[package]] +name = "nvidia-cusparse" +version = "12.6.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568 }, + { url = "https://files.pythonhosted.org/packages/fa/18/623c77619c31d62efd55302939756966f3ecc8d724a14dab2b75f1508850/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2b3c89c88d01ee0e477cb7f82ef60a11a4bcd57b6b87c33f789350b59759360b", size = 145942937 }, +] + +[[package]] +name = "nvidia-cusparselt-cu13" +version = "0.8.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/e1/cdc1797eadf82d3a9a575a19b33fdc871a97edbec42c00b5b5e914f4aff4/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:4dca476c50bf4780d46cd0bfbd82e2bc10a08e4fef7950917ce8d7578d22a23f", size = 221051344 }, + { url = "https://files.pythonhosted.org/packages/34/7d/2661f2fb3ac4302f3a246f5fc030213ac60c1fe0bce84f9783dbd831dbb7/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:786ce87568c303fadb5afcc7102d454cd3040d75f6f8626f5db460d1871f4dd0", size = 170148586 }, +] + +[[package]] +name = "nvidia-nccl-cu13" +version = "2.30.7" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/21/a73174c6157101bdf1ffc22b517f76ff0082613989dd9bc8f43e8034caac/nvidia_nccl_cu13-2.30.7-py3-none-manylinux_2_18_aarch64.whl", hash = "sha256:ca786ffa5a647c75d4d1f5cc72a6c4f537947e2ba8823d7c8aaf768e7a7b9f77", size = 215983881 }, + { url = "https://files.pythonhosted.org/packages/3f/34/c500f90c7ae641b8e0f98965b36b8a7ac79cc8b296e8d251fe3eb592ee54/nvidia_nccl_cu13-2.30.7-py3-none-manylinux_2_18_x86_64.whl", hash = "sha256:cefa7fdb9710efd0f39c5f1be1d61ff6fc9a996c451265bd7fbdcf9455ed4b50", size = 215965170 }, +] + +[[package]] +name = "nvidia-nvjitlink" +version = "13.4.52" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/c1/091f198d7f87e31d67fa9680eec8f8e4c6f889881f729b759db36ff01612/nvidia_nvjitlink-13.4.52-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:90401db7e5a580a5067a468b3086e0b65f3b96ab3c42524afd741efc8a0e150a", size = 42452221 }, + { url = "https://files.pythonhosted.org/packages/7e/a9/225ff51e80de170be880cb88e992193bc8134a51059cc0a3952f967f62c5/nvidia_nvjitlink-13.4.52-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3a589e3732140839349545efd0db67426523459b12e6952c3c73b6d55900f200", size = 40419746 }, +] + +[[package]] +name = "nvidia-nvshmem-cu13" +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/0f/05cc9c720236dcd2db9c1ab97fff629e96821be2e63103569da0c9b72f19/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dc2a197f38e5d0376ad52cd1a2a3617d3cdc150fd5966f4aee9bcebb1d68fe9", size = 60215947 }, + { url = "https://files.pythonhosted.org/packages/3c/35/a9bf80a609e74e3b000fef598933235c908fcefcef9026042b8e6dfde2a9/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:290f0a2ee94c9f3687a02502f3b9299a9f9fe826e6d0287ee18482e78d495b80", size = 60412546 }, +] + +[[package]] +name = "nvidia-nvtx" +version = "13.0.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/f3/d86c845465a2723ad7e1e5c36dcd75ddb82898b3f53be47ebd429fb2fa5d/nvidia_nvtx-13.0.85-py3-none-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4936d1d6780fbe68db454f5e72a42ff64d1fd6397df9f363ae786930fd5c1cd4", size = 148047 }, + { url = "https://files.pythonhosted.org/packages/a8/64/3708a90d1ebe202ffdeb7185f878a3c84d15c2b2c31858da2ce0583e2def/nvidia_nvtx-13.0.85-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb7780edb6b14107373c835bf8b72e7a178bac7367e23da7acb108f973f157a6", size = 148878 }, +] + +[[package]] +name = "packaging" +version = "26.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956 }, +] + +[[package]] +name = "pacmap" +version = "0.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "faiss-cpu" }, + { name = "numba" }, + { name = "numpy" }, + { name = "scikit-learn" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/88/5c/0b00087c7a7ee264e1e4ad6ddc6e38d9a55f29a05e17aa770d97dbdbaf77/pacmap-0.9.1.tar.gz", hash = "sha256:ec31ea3e316b9ad6294c5bc8a8e8b45a658b00d7f59799b960db16469095e35e", size = 24500 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/07/b58bb68a18b8b354bab18185dd5c3e903be94ab4e9861d179c6b9bc3333c/pacmap-0.9.1-py3-none-any.whl", hash = "sha256:c5448d6ae51ad66eeff4760dfc8091d496b7c2cf7dc19b5c2ea48f928d150417", size = 25312 }, +] + +[[package]] +name = "pygments" +version = "2.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669 }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252 }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081 }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159 }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626 }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613 }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115 }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427 }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090 }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246 }, +] + +[[package]] +name = "regex" +version = "2026.9.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/5c/f403115361de25809e8f785686ec7096e30fef73be9ae35aa51da4e80abb/regex-2026.9.10.tar.gz", hash = "sha256:1e321e2c84f0e52c457f5ea5944f796d6e8e09cb99738ea98dcc1bfe402a128d", size = 417072 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/90/d4452bf1ef7dbe406980e8b921a257024482203c1dafac535eae207611bc/regex-2026.9.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ef5a059ea1c6ee5d1c7e99a2484e628608d010921efe876c6f0e2029d2f35eca", size = 496408 }, + { url = "https://files.pythonhosted.org/packages/6a/35/c763c6424a0f99d021d46dc1f9065147bb5a40c2b2cdf28d2ebdbcd96508/regex-2026.9.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dce932f8e3ba936475ea3d0d8b59f7b050a9e206e994f53f8fd80299871e87da", size = 296931 }, + { url = "https://files.pythonhosted.org/packages/fa/68/241f88458b17c46ed2f80147a60a03b2ada7fb815c23b6bc76c298abb0a5/regex-2026.9.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d8c668af8f7bdb1d18739c27d30cd9f4b371495a883f75a002fb7a39d740fecd", size = 291741 }, + { url = "https://files.pythonhosted.org/packages/90/9e/974d6de404c63e2d09525f4ddb99874c7ab8e1f781ccbe0dd3e26fa6f6e5/regex-2026.9.10-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6aebdd9a946de328b3f6f61dbf48dd064a36eb6dddf96e34ae6651d37f6e9383", size = 800088 }, + { url = "https://files.pythonhosted.org/packages/9e/fd/3875b73f9e7ba3321dcaa02c19f650c05c61345328acf84599ac6f45ceed/regex-2026.9.10-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f2374c27deb189b282ec7e16106752c22ad39b056bbd8018960b1e4cc95d67a1", size = 871212 }, + { url = "https://files.pythonhosted.org/packages/c5/f5/2358e791c0e171194dd6a8b97b520579098a21397fb79dbe6b7edc9e3fa7/regex-2026.9.10-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e0dc78251154b66dc60211563fc115345da332eaa881e4e2523fb1edae3772f4", size = 919752 }, + { url = "https://files.pythonhosted.org/packages/20/3b/000c79c3f9c06b7542225a5d3a7f9a85405da7224b3b9af94a491d07abea/regex-2026.9.10-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bafa41b0dd63669e5c0f8adf3d24819efeb73c847f492eb011212eb352e69041", size = 804578 }, + { url = "https://files.pythonhosted.org/packages/30/6d/195eedb1de87f26639191e7487e41eb81e2ce255bc7563a64f3f5a95eb08/regex-2026.9.10-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ebb2ba68e4641a994061f70bf44ed448fba0b9b1d18c94ffb9efc1cca805b39b", size = 777345 }, + { url = "https://files.pythonhosted.org/packages/79/11/11fe2b313fcd92cb75c583648f2746031b9f4da9e9ed4241204a5e8b3721/regex-2026.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:048a89ee797db10160bd2bd519286577a6b43a100279bd4b7d8456a3d69c80a0", size = 790556 }, + { url = "https://files.pythonhosted.org/packages/7a/c0/07ec9b4c43b0e16d62454971a5ab3886eccb0bfa161300a02d801ab28620/regex-2026.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:79e9432995e14c749d34209413de5e621ec8e67789bf4f46dbfabea9d06a2406", size = 865572 }, + { url = "https://files.pythonhosted.org/packages/19/07/43bc9a9cf9fc8e37d2ba47980dfe4a6e151d2cf3ab969e0031e2a9b21484/regex-2026.9.10-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5847e22bbf959764d776937d791d034cc2d19b787e361c88d97e859e8dc68502", size = 767971 }, + { url = "https://files.pythonhosted.org/packages/9c/49/3b9286a3a94f3c89ed4ddbe74e72bdde21c1a5eadd520d5f4ed4a61936cb/regex-2026.9.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c103b3b14e011774af4fb7e4617ad4d72b9171905cd3b231a70a4efd76e477d7", size = 858835 }, + { url = "https://files.pythonhosted.org/packages/4a/9e/e5d27ce9fee8e3ef95f886c7b6ecec211efa4cfc18bd73bd5cf26cca4741/regex-2026.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6b34a778c695d24e77c140e3b4c95da69282e34f2f6b02b55656aa4a0379f643", size = 791793 }, + { url = "https://files.pythonhosted.org/packages/63/03/c28a6bebedc3e2d86ee27ec2de16f7ec0419dcd10e771d43dcc9c58a2e99/regex-2026.9.10-cp313-cp313-win32.whl", hash = "sha256:7abb38b8c40f3a235235a44da452c64b7b5c1d650ec6351027db0e090804f2e5", size = 267298 }, + { url = "https://files.pythonhosted.org/packages/cd/fd/5c85fa6cfb8e034080bda5a72fa0a4df2b7777a35eb7e73c2799c2adda7a/regex-2026.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:20e8bfb07ad79a282f8b95b56fe67f9750b1b7f775724e4ba1f23cb296115ce4", size = 277894 }, + { url = "https://files.pythonhosted.org/packages/c1/28/f5a25f6f65501675977fda35d9f61abb1468c4b87c0f73e536d8b21a60b8/regex-2026.9.10-cp313-cp313-win_arm64.whl", hash = "sha256:3bdeed3318a8eb2bbadc9c56347e0ff651639e934a47e168d05a3b12929fd0e7", size = 277436 }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654 }, +] + +[[package]] +name = "safetensors" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/06/f955dbbb1859e3bd23c8ac6141af5106e7ad5fedec4a3a6e3d60f94b7001/safetensors-0.8.0.tar.gz", hash = "sha256:fabaf3e0f18a6618d9b36560682562157f77c2b71fcffc7b432be2baed9d753d", size = 325846 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/a0/f718cda65b05407d228f97602cf60dca269c979867aa5beb25410de26cd3/safetensors-0.8.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c554f85858e05226d3c2828e32395e677434685d6d94594a41643361c5e837f0", size = 473568 }, + { url = "https://files.pythonhosted.org/packages/f5/b1/fa7c600e7dceae12e9606c7578cbc9ff1e1ed55844883ee5c92205e86226/safetensors-0.8.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:c80201d22cbf405b80647a60ada77bba06c8fba2da2743ba1e89cdcc39a81f25", size = 484562 }, + { url = "https://files.pythonhosted.org/packages/09/7d/65a7de0af421317bb36a067241e4235fff194eed60b961ed6d3f59a3fc60/safetensors-0.8.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a46e5ff292c356d6991e60942ba7f79817682d3a2cef0702136448cb9c4d235", size = 502844 }, + { url = "https://files.pythonhosted.org/packages/91/4f/3175c9d75634e0e0dda0082794193521035edd7c70a6f212bf33ca06ddf4/safetensors-0.8.0-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4124502b78f03534117c848f87a39b8f31e577b15eff423bf8bfb95f2a8c30d0", size = 511823 }, + { url = "https://files.pythonhosted.org/packages/20/87/846c289e7aa2299eff406335717cf43ce8777194ece8aad75772e0411615/safetensors-0.8.0-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc0a787ba8a35be368ee3574edfa2b1ad389eebd0a72e482ae275490e3f6c98", size = 633461 }, + { url = "https://files.pythonhosted.org/packages/76/22/8d64d9df2c45d5ded401df889d0ad90882804ca172d79ec4f0df8f727fe0/safetensors-0.8.0-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040070828e36dc8e122178bbbd5830ff9e97920affb84cbe0f46442497bed358", size = 545148 }, + { url = "https://files.pythonhosted.org/packages/28/50/f203ff3a3ddfe19308efc83c5a3a29ed02bf786732ec35e68bf9162f3365/safetensors-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6f3f93c9a0a7cc2788ee63fb763353d4bd2e89b0751bc78fcf7dda00bea774", size = 516040 }, + { url = "https://files.pythonhosted.org/packages/46/fb/cdaed17ceb2948784fd9c36b6fd3e951b608547cea81a48e8ee6f8cfdfcb/safetensors-0.8.0-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:fcdd41ec4628fee5799f807c73c353629130fbd942aa23d83c623dd6c9d52d78", size = 513832 }, + { url = "https://files.pythonhosted.org/packages/0d/49/1e15de264dcc3b77943d2d0c56a95809956883b1c2d6d585c792523f180b/safetensors-0.8.0-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e9f537aa183a38ace122d27303dcd986b26bd2a7591f9181d7f0c396f4677ca", size = 559930 }, + { url = "https://files.pythonhosted.org/packages/2a/43/bf38443278eab4b1be1fce2931e2b012ad9cb7df52ada751d0aab8f7659a/safetensors-0.8.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:87eec7ffed2b809f05a398a8becb7d013f19f7837cd15d9748580d6cf30dbaf4", size = 678670 }, + { url = "https://files.pythonhosted.org/packages/72/e3/68cd3fa5b48488e84add63e04cb12f3bc28ae4638c06d4508c6e88823d0e/safetensors-0.8.0-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:4a95ae2b05d7726d751da4ebf626a2ca782b706e101bd894c95bc2450b1cffcc", size = 786679 }, + { url = "https://files.pythonhosted.org/packages/29/4b/1c19c509d56e01f4fbb3d0a2e597450f6cc04d1d56cf52defb0a62dfd715/safetensors-0.8.0-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:3ae091f16662658bdc019a4ff6cb4c085bb7d725eb5978b183ffd265863b6d2d", size = 765683 }, + { url = "https://files.pythonhosted.org/packages/27/43/41c1621732edd934d868a00d1b891584c892a7b62a9aab82ea5a0a5623ee/safetensors-0.8.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8e080062fcde23be189565e1c3305d16751a218ecf9412c8601e64204eb6f846", size = 722361 }, + { url = "https://files.pythonhosted.org/packages/8e/3f/73ccf82579412b4a71c4ca673f10b5f1f888d7cf5af7fe24f27d30307be4/safetensors-0.8.0-cp310-abi3-win32.whl", hash = "sha256:2ddf52eac562eda224f99acfa7889d02968c1fd59a5b011ae7d8137c37e9c02d", size = 342401 }, + { url = "https://files.pythonhosted.org/packages/1b/6d/3fba214c1e5e0f69991677ec3bc17023f0421776975e1de0c682dca475e2/safetensors-0.8.0-cp310-abi3-win_amd64.whl", hash = "sha256:096ec1a98435df7beb08853bb5aa9081a84f23d0adc67ed1a0a10550f608373f", size = 355540 }, + { url = "https://files.pythonhosted.org/packages/8d/fc/7eedc3510d97878876e32774eebbeb61c43f148a96e915c84229a3e967aa/safetensors-0.8.0-cp310-abi3-win_arm64.whl", hash = "sha256:f7838e5135a406ad3e02efdcb8cf2e5397d368b0154537c4fec682dbc544d452", size = 340500 }, +] + +[[package]] +name = "scikit-learn" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/d4/40988bf3b8e34feec1d0e6a051446b1f66225f8529b9309becaeef62b6c4/scikit_learn-1.8.0.tar.gz", hash = "sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd", size = 7335585 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/aa/e22e0768512ce9255eba34775be2e85c2048da73da1193e841707f8f039c/scikit_learn-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0d6ae97234d5d7079dc0040990a6f7aeb97cb7fa7e8945f1999a429b23569e0a", size = 8513770 }, + { url = "https://files.pythonhosted.org/packages/58/37/31b83b2594105f61a381fc74ca19e8780ee923be2d496fcd8d2e1147bd99/scikit_learn-1.8.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:edec98c5e7c128328124a029bceb09eda2d526997780fef8d65e9a69eead963e", size = 8044458 }, + { url = "https://files.pythonhosted.org/packages/2d/5a/3f1caed8765f33eabb723596666da4ebbf43d11e96550fb18bdec42b467b/scikit_learn-1.8.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:74b66d8689d52ed04c271e1329f0c61635bcaf5b926db9b12d58914cdc01fe57", size = 8610341 }, + { url = "https://files.pythonhosted.org/packages/38/cf/06896db3f71c75902a8e9943b444a56e727418f6b4b4a90c98c934f51ed4/scikit_learn-1.8.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8fdf95767f989b0cfedb85f7ed8ca215d4be728031f56ff5a519ee1e3276dc2e", size = 8900022 }, + { url = "https://files.pythonhosted.org/packages/1c/f9/9b7563caf3ec8873e17a31401858efab6b39a882daf6c1bfa88879c0aa11/scikit_learn-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:2de443b9373b3b615aec1bb57f9baa6bb3a9bd093f1269ba95c17d870422b271", size = 7989409 }, + { url = "https://files.pythonhosted.org/packages/49/bd/1f4001503650e72c4f6009ac0c4413cb17d2d601cef6f71c0453da2732fc/scikit_learn-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:eddde82a035681427cbedded4e6eff5e57fa59216c2e3e90b10b19ab1d0a65c3", size = 7619760 }, + { url = "https://files.pythonhosted.org/packages/d2/7d/a630359fc9dcc95496588c8d8e3245cc8fd81980251079bc09c70d41d951/scikit_learn-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7cc267b6108f0a1499a734167282c00c4ebf61328566b55ef262d48e9849c735", size = 8826045 }, + { url = "https://files.pythonhosted.org/packages/cc/56/a0c86f6930cfcd1c7054a2bc417e26960bb88d32444fe7f71d5c2cfae891/scikit_learn-1.8.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:fe1c011a640a9f0791146011dfd3c7d9669785f9fed2b2a5f9e207536cf5c2fd", size = 8420324 }, + { url = "https://files.pythonhosted.org/packages/46/1e/05962ea1cebc1cf3876667ecb14c283ef755bf409993c5946ade3b77e303/scikit_learn-1.8.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72358cce49465d140cc4e7792015bb1f0296a9742d5622c67e31399b75468b9e", size = 8680651 }, + { url = "https://files.pythonhosted.org/packages/fe/56/a85473cd75f200c9759e3a5f0bcab2d116c92a8a02ee08ccd73b870f8bb4/scikit_learn-1.8.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:80832434a6cc114f5219211eec13dcbc16c2bac0e31ef64c6d346cde3cf054cb", size = 8925045 }, + { url = "https://files.pythonhosted.org/packages/cc/b7/64d8cfa896c64435ae57f4917a548d7ac7a44762ff9802f75a79b77cb633/scikit_learn-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ee787491dbfe082d9c3013f01f5991658b0f38aa8177e4cd4bf434c58f551702", size = 8507994 }, + { url = "https://files.pythonhosted.org/packages/5e/37/e192ea709551799379958b4c4771ec507347027bb7c942662c7fbeba31cb/scikit_learn-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde", size = 7869518 }, +] + +[[package]] +name = "scipy" +version = "1.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7e/74/66de6258867beb2ef08f35f9f2ac017a52cacd5081714d239ff1a442d458/scipy-1.18.1.tar.gz", hash = "sha256:52c4b7422442aba924d03ad4019852b08a92e64ea187b933135687bfe2747307", size = 30781235 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/55/4540ee0f9c42a9ad7109d0d1a8cc70de54c3572b01c6693a2b1c70e90ceb/scipy-1.18.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:3ab3523da44749156e1f68b464dc56af11ae4cbc5c739a49d05f32b982eca9f3", size = 31089958 }, + { url = "https://files.pythonhosted.org/packages/2a/f5/769f36d14922b8071a43e95d24d18b6bdafad10d7f5cf647867e1ac052bc/scipy-1.18.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e6fb6a55cc0ba97b59a1f288fb86dc6fce8bdfc0fffcbfd015e3a954bf2a2d93", size = 28715106 }, + { url = "https://files.pythonhosted.org/packages/9a/d7/21d890274f75ea37a8209d5519e72da3da90302e3b9fb8397a0918386a62/scipy-1.18.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ea324d9dd34c38bfb9bec8ca4d1b407db97dbb74029f566b8e322b1b6fe56fe6", size = 20456846 }, + { url = "https://files.pythonhosted.org/packages/ec/01/798430ecea2e78ec7c02663d5f71c007bb6abeca931080debd40d7fa55ea/scipy-1.18.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:75b00eb8fb802090aa903f4ea1c7f5a584779f967361e68b7e98e531cc2d7174", size = 23087986 }, + { url = "https://files.pythonhosted.org/packages/e6/5f/4634e9d35c68496e4e34cb6946eafab044458e6cedab42b40b6588e475b6/scipy-1.18.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d416b16cccfd70fbf62400e84d0bb2f4e6af519a45557f1692c749b37f14b315", size = 33998146 }, + { url = "https://files.pythonhosted.org/packages/41/48/6450ed9243315322bbc19ac57b9b70d66a20bf1d38d124c96bc4bf6af9ea/scipy-1.18.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fdaf5ea890a6183d0565f51a61799d67081bd5b1cf03c5f4b3fd3732108625c9", size = 35312578 }, + { url = "https://files.pythonhosted.org/packages/00/bd/bf5a4be6a3525676499f6dff307991739ff6fdcad1481b1aeb6745339f58/scipy-1.18.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c825cef2f49e46753726a7181a8e199804a912b29519ada542c6ebc654951899", size = 35612621 }, + { url = "https://files.pythonhosted.org/packages/bd/4e/3c45c33e00a77996c4b1cb707929f833ba7b1d522ee29f882512c330676d/scipy-1.18.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e3b417bf8c2c7c16e8f58ad91db17783ec911ac16e7b50eb6eab6e809b4f5b07", size = 37457323 }, + { url = "https://files.pythonhosted.org/packages/93/0e/e0348fbc0dbab65c114cf78957e7dfeb49f8e8b556b4d930cc12ff195e18/scipy-1.18.1-cp313-cp313-win_amd64.whl", hash = "sha256:559ed65f60c1af5a03f3912605a1b5114f522c7c32fb23c3376ae8f03219fe28", size = 36622841 }, + { url = "https://files.pythonhosted.org/packages/50/a8/6a77f5f267c555108f0a864b6db714363dab567a8266422a79a385f9232b/scipy-1.18.1-cp313-cp313-win_arm64.whl", hash = "sha256:cd479fc04dd9401e3b4f49e76518768ef99c4f517a98c284eb091fd725719adf", size = 24399315 }, +] + +[[package]] +name = "sentence-transformers" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "scikit-learn" }, + { name = "scipy" }, + { name = "tokenizers" }, + { name = "torch" }, + { name = "tqdm" }, + { name = "transformers" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/43/6b53e6a2098440ce21478742facbc058f1a66ba2cb80b24bdc64942e1e2c/sentence_transformers-6.0.0.tar.gz", hash = "sha256:9e8c2c24f3b1c7473cd5f519a3d3cff60daaeb95533b82d045ffb43ee5f2dac4", size = 575048 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/fe/9d19b01fe87945f9455c617bf5d33dfbf29fe06ab6580bc0bea06080c788/sentence_transformers-6.0.0-py3-none-any.whl", hash = "sha256:b974ac67523ea2a955afa87b1024129305472bd884367dcc969261cb086790e9", size = 739640 }, +] + +[[package]] +name = "setuptools" +version = "84.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/44/f5da03a8ef95d369145c5bb53050e7877c9f3d312e128605fd9504829143/setuptools-84.0.0.tar.gz", hash = "sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73", size = 1168449 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl", hash = "sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670", size = 818216 }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353 }, +] + +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638 }, +] + +[[package]] +name = "tokenizers" +version = "0.23.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/1e/bc6587c5ab643b2e17776cace9070a2ae73549c86bffac9934a600bf3c31/tokenizers-0.23.2.tar.gz", hash = "sha256:7f0f085686b9de0d0079e6f874ae053600db64c5d13049e0bbc0119926d25aac", size = 385745 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/ed/8a443528baa6fac8dfe8c3b75b038c63ac92bb539bcabe311e227c718173/tokenizers-0.23.2-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:85a9a357a3764aecc904ee76bdaf8cf1ad8e5a67a1b929a487c4a39b49ed0e90", size = 3148852 }, + { url = "https://files.pythonhosted.org/packages/67/49/22da045a91732384d3a3771816bf188dc5a1f702c32e635afa7c679c0bef/tokenizers-0.23.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:986670e43691469dcee610ea0f846f91a8f84e91fc6f7a48d4c064414c0ec2bf", size = 3101593 }, + { url = "https://files.pythonhosted.org/packages/2e/4d/8f569ed49372a3ed8e57099bd515055fd48d7c95912c4307cda6973c2168/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a37039b5dfc4af84eb3ef0a92f4307e28936c8f9adccba2629d36f652e9bf7a2", size = 3516830 }, + { url = "https://files.pythonhosted.org/packages/2a/de/e2f14c8919d5bf51874051d00d6c7b7e0e8bde6c6a2dbeddda7f642896ff/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b7e37ba198f24150f523e1242e83c4970de4a525480586be5dcc24d9add32c5", size = 3407975 }, + { url = "https://files.pythonhosted.org/packages/c5/bd/93c69152d02ef06ce47aed8b2bf4952dcf733c935a62791873932b2934d9/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43e4f2071e3cc8d5d86421c874aebc82659bb51a68bcdef5a0da75ee89511ccb", size = 3748165 }, + { url = "https://files.pythonhosted.org/packages/2d/b7/56b84b80bc96942bba8eb23751a9e8a1fce4faaf4390425e7083f721c98c/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:325fee2e0418a9dc6c9ecf736a5f5f0db7875183ace9549ae339da76f7a1fbb7", size = 4024165 }, + { url = "https://files.pythonhosted.org/packages/9b/8a/0175e216f005c2fe08238292663aa41e4c802b216e71047a69a0e9fc6fa3/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:950d7c9426fa72406a0ffeacdbc0bb9985f5db20eb8b263f29c79aaf83105703", size = 3591899 }, + { url = "https://files.pythonhosted.org/packages/2c/ca/ca6b93c7820df123b2662a9469e8facc826ccc94e98fdd0d615f6431e73a/tokenizers-0.23.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41c2f84d172449b4dadb9cdc508e3e364076613c35b16e76ecfe47a60d1e3305", size = 3386843 }, + { url = "https://files.pythonhosted.org/packages/e9/a4/4f9106d317b14a80aefea9f0e3a8d07ef25f856a7607eb7f5ab894281fcb/tokenizers-0.23.2-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:12f0835dc2ee694746a76adf7b1567d4346a4a502ebe93fb1f5f80ea49799b78", size = 3577314 }, + { url = "https://files.pythonhosted.org/packages/8d/6a/1552b70fb0d9ab074fd3fc961435d01364e79c9058481822c3af6e8d402c/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:eb2f9c8a24da020ea8c11a01a19c1c2547912d92121ae4a01cfbca46125dee40", size = 9967367 }, + { url = "https://files.pythonhosted.org/packages/06/01/3ccb3a956c7528b2507b8a9714155c4baf86af593039db6ea375dd0c96c3/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:f486f402f6f9abee5bb032553736813af0c710a86b2e0ca592634c55cea1f835", size = 9811886 }, + { url = "https://files.pythonhosted.org/packages/fa/73/7038e612d48bda1599457f712f6bd3854eae1a9dc9c13aa47f835349db48/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:bef235815a067b2648caf6dcc7a71091b0b0fff9ee8057f6451eb9335fae52ef", size = 10146224 }, + { url = "https://files.pythonhosted.org/packages/b5/d8/8e9e4e0b287a338d8f88976729628c9d22e8a54cfaf9777018a7f7cb58a0/tokenizers-0.23.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5c56bda1511921587789163e524d196ed8284174ac23abd7685d5ea8da6c4718", size = 10256304 }, + { url = "https://files.pythonhosted.org/packages/f3/1f/c79a01f671a49728ebb0b61f7ff9ea45663b66cab40bc0858e9859b25c16/tokenizers-0.23.2-cp310-abi3-win32.whl", hash = "sha256:debf978920d93ba9c219bd67cc4bbfaf912c9039e41e7a28b91ec15e3728c95a", size = 2592809 }, + { url = "https://files.pythonhosted.org/packages/db/f7/0a69ac6b82dbccf3f71add938a161c497952749294b8dd6dfe03a819dc40/tokenizers-0.23.2-cp310-abi3-win_amd64.whl", hash = "sha256:2e96f5699d5249c9c64aa8412e044f727aae3a4098cf830f9901ec1afc361cde", size = 2863236 }, + { url = "https://files.pythonhosted.org/packages/d7/b0/dee84cb44175be1b4c35bd2f770727494e78f0bb38e571a623ade94dbebb/tokenizers-0.23.2-cp310-abi3-win_arm64.whl", hash = "sha256:e49c394456dd9985787fec76132438ba3fb8911f857b1bf3d40119f9292d41aa", size = 2729352 }, +] + +[[package]] +name = "torch" +version = "2.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-bindings", marker = "sys_platform == 'linux'" }, + { name = "cuda-toolkit", extra = ["cublas", "cudart", "cufft", "cufile", "cupti", "curand", "cusolver", "cusparse", "nvjitlink", "nvrtc", "nvtx"], marker = "sys_platform == 'linux'" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cudnn-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu13", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu13", marker = "sys_platform == 'linux'" }, + { name = "setuptools" }, + { name = "sympy" }, + { name = "triton", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/40/0db773452c2a62b37761d3f418acf933d381f9e87077036fb57c2a386c37/torch-2.14.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:9d4b1022a5d9b71282ec67ad0d9e7235870096b8a246dc1c32d6ea1fc83dc998", size = 127311393 }, + { url = "https://files.pythonhosted.org/packages/13/36/537fd9da2adad49e7b2bb20741398625bee548493158274e87369a8eed56/torch-2.14.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:731b9ebdea402b8b1996d4c2ae613b16660e559b19e47bdc45d970568bc91c53", size = 454010525 }, + { url = "https://files.pythonhosted.org/packages/21/f1/39bd13b21f57d1982b7f3ddf663f01c7266e2957714880744eba9e8c8d11/torch-2.14.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:84bf384779a10c02fc3c6bdbab71a9cb66b0dd93c652d1ed5d6dfc0cb37e5962", size = 554619993 }, + { url = "https://files.pythonhosted.org/packages/89/a8/683d9c44737554b67ca76dd2db4f42258a0f014246cb511293e51e0154bd/torch-2.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:0e7cf18cb0d8bd666b6120932e29c7aef3502b61a08b44da4839580c539a7cdb", size = 124113865 }, +] + +[[package]] +name = "tqdm" +version = "4.70.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/ea/b2a5bd54b28a324dae8211928b2d730b6547500342c7e6c6dea08bd0a485/tqdm-4.70.1.tar.gz", hash = "sha256:cefd0eca11b2a37a3aee776544d4f4ae913f02688135b5556b8788dfa474afc4", size = 171846 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/03/921a3d3c75785aca9ebfbfcabfbc3a1be12e2ab5265deb026d55a5a3f83e/tqdm-4.70.1-py3-none-any.whl", hash = "sha256:c293e525e6fef9c20e8728fd4612df02a0aa31bb5fe91ecd93e123b1b7bffa73", size = 80199 }, +] + +[[package]] +name = "transformers" +version = "5.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "regex" }, + { name = "safetensors" }, + { name = "tokenizers" }, + { name = "tqdm" }, + { name = "typer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/9e/750649904a065007a838981785b2bd8d9ff26154c6c341ac67d0b7f82c68/transformers-5.17.0.tar.gz", hash = "sha256:a153be279169b55b92d8000bf4af294aed684503d091cca7804da2dd8a9de000", size = 9817878 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/d0/c502b60d684adbd98a8dc7d5bb866842772b816ac4354e4608be240041ae/transformers-5.17.0-py3-none-any.whl", hash = "sha256:78ec1ce21579b38dfb83950a0658cd119f87212a2fcfdff478096ce9d6c03801", size = 12295140 }, +] + +[[package]] +name = "triton" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/4d/4c564374bcdadb166fccbf3e45aee0d4a473f88d341761bd2fefe3b8e8c1/triton-3.8.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7004666652f500ed854a86988e4b3d69d247188b5d2092b5df1e44f4a954099", size = 226476793 }, + { url = "https://files.pythonhosted.org/packages/b0/b6/3394d5548404c1cabd1dadadd28d0b3f9478db1dff8180da53bb3f0a1e19/triton-3.8.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f0497218e26b7d79773ad9c2a3fa3b539ee69f587a13fac2e552b1d322a8015", size = 247975122 }, +] + +[[package]] +name = "typer" +version = "0.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/f7/57713ba479fd405eb76de31404b2c744c289e336b2d999511ebf51e496f7/typer-0.27.2.tar.gz", hash = "sha256:269b7eb9d3c202ca84b4bc9618cb04ebb43d3d4d1e567e4c768607232c05f945", size = 204045 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/bf/205d0004930ede8f542fb58f601526fccf4ae7626075ca1e6c4de5d3d652/typer-0.27.2-py3-none-any.whl", hash = "sha256:b3a5fc4342d5fc8fda8fc3010b1cf117e9249aab7fae800c2eff62fd3842d97d", size = 123130 }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571 }, +] diff --git a/scripts/.vendored_canon_ref b/scripts/.vendored_canon_ref index c6a87246d..6aa11e956 100644 --- a/scripts/.vendored_canon_ref +++ b/scripts/.vendored_canon_ref @@ -1 +1 @@ -c8b8f89ecf29574d7e24f6c65cfd925aefbdd007 +dbac7ddc8f1351493b90c6dc8850319769fdf620 diff --git a/scripts/embedding_pipeline.py b/scripts/embedding_pipeline.py index 1a97ec400..de15231f1 100644 --- a/scripts/embedding_pipeline.py +++ b/scripts/embedding_pipeline.py @@ -4,6 +4,7 @@ Inspection and verification use the standard library. Model inference and projection are explicit operations with separately installed dependencies. """ + from __future__ import annotations import argparse @@ -30,8 +31,14 @@ MODEL_DIMENSION = 1024 MAX_SEQ_LENGTH = 512 REQUIRED_FIELDS = ( - "identifier", "label", "category", "page", "source_path", "text", - "text_sha256", "adapter_version", + "identifier", + "label", + "category", + "page", + "source_path", + "text", + "text_sha256", + "adapter_version", ) @@ -40,8 +47,9 @@ class ContractError(ValueError): def canonical(value: object) -> bytes: - return json.dumps(value, sort_keys=True, separators=(",", ":"), - ensure_ascii=False, allow_nan=False).encode("utf-8") + return json.dumps( + value, sort_keys=True, separators=(",", ":"), ensure_ascii=False, allow_nan=False + ).encode("utf-8") def digest_file(path: Path) -> str: @@ -65,8 +73,11 @@ def local_link(value: str) -> bool: parsed = urlsplit(value) decoded = unquote(parsed.path) return bool(value) and not ( - parsed.scheme or parsed.netloc or decoded.startswith("/") - or "\\" in decoded or ".." in decoded.split("/") + parsed.scheme + or parsed.netloc + or decoded.startswith("/") + or "\\" in decoded + or ".." in decoded.split("/") or any(ord(char) < 32 for char in unquote(value)) ) @@ -101,37 +112,53 @@ def inspect_inputs(path: Path) -> dict: counts: dict[str, int] = {} versions: set[str] = set() count = 0 - with tempfile.TemporaryDirectory(prefix="embedding-inputs-") as tmp: - with sqlite3.connect(str(Path(tmp) / "ids.sqlite")) as db: - db.execute("CREATE TABLE ids (id TEXT PRIMARY KEY)") - for record in records(path, raw_digest=raw): - try: - db.execute("INSERT INTO ids VALUES (?)", (record["identifier"],)) - except sqlite3.IntegrityError as exc: - raise ContractError(f"duplicate identifier: {record['identifier']}") from exc - framed_update(content, record["identifier"], record["text"]) - framed_update(display, canonical(record).decode()) - counts[record["category"]] = counts.get(record["category"], 0) + 1 - versions.add(record["adapter_version"]) - count += 1 + with ( + tempfile.TemporaryDirectory(prefix="embedding-inputs-") as tmp, + sqlite3.connect(str(Path(tmp) / "ids.sqlite")) as db, + ): + db.execute("CREATE TABLE ids (id TEXT PRIMARY KEY)") + for record in records(path, raw_digest=raw): + try: + db.execute("INSERT INTO ids VALUES (?)", (record["identifier"],)) + except sqlite3.IntegrityError as exc: + raise ContractError(f"duplicate identifier: {record['identifier']}") from exc + framed_update(content, record["identifier"], record["text"]) + framed_update(display, canonical(record).decode()) + counts[record["category"]] = counts.get(record["category"], 0) + 1 + versions.add(record["adapter_version"]) + count += 1 if not count: raise ContractError("adapter input contains no records") if len(versions) != 1: raise ContractError("adapter versions must agree within one input") if digest_file(path) != raw.hexdigest(): raise ContractError("adapter input changed while inspecting; rerun") - return {"count": count, "corpus_sha256": content.hexdigest(), - "records_sha256": display.hexdigest(), "input_sha256": raw.hexdigest(), - "categories": counts, "adapter_version": versions.pop()} + return { + "count": count, + "corpus_sha256": content.hexdigest(), + "records_sha256": display.hexdigest(), + "input_sha256": raw.hexdigest(), + "categories": counts, + "adapter_version": versions.pop(), + } def encoder_profile(*, library_versions: dict | None = None, device: str = "cpu") -> dict: - return {"format_version": FORMAT_VERSION, "model": MODEL, - "revision": MODEL_REVISION, "dimension": MODEL_DIMENSION, - "normalized": True, "dtype": "float32-le", "max_seq_length": MAX_SEQ_LENGTH, - "pooling": "sentence-transformers-model", "truncation": "tail", - "inference_device": device, "weight_dtype": "torch.float32", - "query_instruction": None, "library_versions": library_versions or {}} + return { + "format_version": FORMAT_VERSION, + "model": MODEL, + "revision": MODEL_REVISION, + "dimension": MODEL_DIMENSION, + "normalized": True, + "dtype": "float32-le", + "max_seq_length": MAX_SEQ_LENGTH, + "pooling": "sentence-transformers-model", + "truncation": "tail", + "inference_device": device, + "weight_dtype": "torch.float32", + "query_instruction": None, + "library_versions": library_versions or {}, + } def validate_profile(profile: dict) -> None: @@ -139,29 +166,43 @@ def validate_profile(profile: dict) -> None: r"[0-9a-f]{40}", str(profile.get("revision", "")) ): raise ContractError("encoder profile must identify an immutable model revision") - if (type(profile.get("format_version")) is not int - or profile["format_version"] != FORMAT_VERSION - or not isinstance(profile.get("model"), str) or not profile["model"] - or type(profile.get("dimension")) is not int or profile["dimension"] < 2 - or profile.get("normalized") is not True or profile.get("dtype") != "float32-le" - or type(profile.get("max_seq_length")) is not int - or profile["max_seq_length"] < 1 - or profile.get("pooling") != "sentence-transformers-model" - or profile.get("truncation") != "tail" - or not re.fullmatch(r"cpu|mps(?::\d+)?|cuda(?::\d+)?", - str(profile.get("inference_device", ""))) - or profile.get("weight_dtype") != "torch.float32" - or "query_instruction" not in profile or profile["query_instruction"] is not None): + if ( + type(profile.get("format_version")) is not int + or profile["format_version"] != FORMAT_VERSION + or not isinstance(profile.get("model"), str) + or not profile["model"] + or type(profile.get("dimension")) is not int + or profile["dimension"] < 2 + or profile.get("normalized") is not True + or profile.get("dtype") != "float32-le" + or type(profile.get("max_seq_length")) is not int + or profile["max_seq_length"] < 1 + or profile.get("pooling") != "sentence-transformers-model" + or profile.get("truncation") != "tail" + or not re.fullmatch( + r"cpu|mps(?::\d+)?|cuda(?::\d+)?", str(profile.get("inference_device", "")) + ) + or profile.get("weight_dtype") != "torch.float32" + or "query_instruction" not in profile + or profile["query_instruction"] is not None + ): raise ContractError("invalid encoder profile") validate_versions(profile.get("library_versions"), "encoder") canonical(profile) def validate_versions(value, context: str) -> None: - if (not isinstance(value, dict) or not value - or any(not isinstance(name, str) or not name.strip() - or not isinstance(version, str) or not version.strip() - for name, version in value.items())): + if ( + not isinstance(value, dict) + or not value + or any( + not isinstance(name, str) + or not name.strip() + or not isinstance(version, str) + or not version.strip() + for name, version in value.items() + ) + ): raise ContractError(f"{context} requires recorded software versions") @@ -221,8 +262,9 @@ def cached_vector(db, key: str, record: dict, dimension: int): return blob -def populate_cache(input_path: Path, cache_path: Path, profile: dict, encoder, - *, batch_size: int = 64) -> dict: +def populate_cache( + input_path: Path, cache_path: Path, profile: dict, encoder, *, batch_size: int = 64 +) -> dict: """Reuse exact records and atomically commit each verified encoded batch.""" if batch_size < 1: raise ContractError("batch size must be positive") @@ -243,12 +285,21 @@ def save_batch(): # Validate the WHOLE batch before starting its transaction. blobs = [vector_bytes(vector, profile["dimension"]) for vector in vectors] with db: - db.execute("INSERT OR IGNORE INTO profiles VALUES (?, ?)", - (key, canonical(profile).decode())) + db.execute( + "INSERT OR IGNORE INTO profiles VALUES (?, ?)", + (key, canonical(profile).decode()), + ) for record, blob in zip(pending, blobs, strict=True): - db.execute("INSERT OR REPLACE INTO vectors VALUES (?, ?, ?, ?, ?)", - (key, record["identifier"], record["text_sha256"], blob, - hashlib.sha256(blob).hexdigest())) + db.execute( + "INSERT OR REPLACE INTO vectors VALUES (?, ?, ?, ?, ?)", + ( + key, + record["identifier"], + record["text_sha256"], + blob, + hashlib.sha256(blob).hexdigest(), + ), + ) encoded_count += len(pending) pending.clear() @@ -273,21 +324,30 @@ def versions(names: tuple[str, ...]) -> dict[str, str]: def local_encoder(device: str | None = None): from sentence_transformers import SentenceTransformer - model = SentenceTransformer(MODEL, revision=MODEL_REVISION, - trust_remote_code=False, device=device) + model = SentenceTransformer( + MODEL, revision=MODEL_REVISION, trust_remote_code=False, device=device + ) model.max_seq_length = MAX_SEQ_LENGTH model.tokenizer.truncation_side = "right" - profile = encoder_profile(library_versions=versions( - ("sentence-transformers", "transformers", "tokenizers", "torch", "numpy") - ), device=str(model.device)) + profile = encoder_profile( + library_versions=versions( + ("sentence-transformers", "transformers", "tokenizers", "torch", "numpy") + ), + device=str(model.device), + ) if str(next(model.parameters()).dtype) != profile["weight_dtype"]: raise ContractError("model weights must use the declared float32 precision") if model.get_sentence_embedding_dimension() != MODEL_DIMENSION: raise ContractError("model returned an unexpected embedding dimension") def encode(texts): - return model.encode(texts, batch_size=len(texts), normalize_embeddings=True, - convert_to_numpy=True, show_progress_bar=False) + return model.encode( + texts, + batch_size=len(texts), + normalize_embeddings=True, + convert_to_numpy=True, + show_progress_bar=False, + ) return profile, encode @@ -295,11 +355,13 @@ def encode(texts): def select_records(input_path: Path, maximum: int, seed: int) -> list[dict]: if maximum < 3: raise ContractError("map selection maximum must be at least three") + # Bottom-k hashes are deterministic, bounded and independent of input order. def ranked(): for record in records(input_path): key = hashlib.sha256(canonical([seed, record["identifier"]])).digest() yield key, record["identifier"], record + return [record for _, _, record in heapq.nsmallest(maximum, ranked())] @@ -317,10 +379,19 @@ def atomic_json(path: Path, value: dict) -> None: temporary.unlink(missing_ok=True) -def build_map(input_path: Path, cache_path: Path, output: Path, profile: dict, - *, maximum: int = 50000, seed: int = 42, neighbors: int = 15, - projector=None, projection_versions: dict | None = None, - title: str = "Semantic text map") -> dict: +def build_map( + input_path: Path, + cache_path: Path, + output: Path, + profile: dict, + *, + maximum: int = 50000, + seed: int = 42, + neighbors: int = 15, + projector=None, + projection_versions: dict | None = None, + title: str = "Semantic text map", +) -> dict: import numpy as np inputs = inspect_inputs(input_path) @@ -347,17 +418,29 @@ def build_map(input_path: Path, cache_path: Path, output: Path, profile: dict, projection_details = {"implementation": "injected-projector", "effective_pairs": None} if projector is None: import pacmap + projection_versions = versions(("pacmap", "numpy", "numba", "scikit-learn", "faiss-cpu")) - reducer = pacmap.PaCMAP(n_components=2, n_neighbors=neighbor_count, - MN_ratio=0.5, FP_ratio=2.0, random_state=seed, - distance="euclidean", lr=1.0, num_iters=(100, 100, 250), - apply_pca=True, knn_backend="faiss") + reducer = pacmap.PaCMAP( + n_components=2, + n_neighbors=neighbor_count, + MN_ratio=0.5, + FP_ratio=2.0, + random_state=seed, + distance="euclidean", + lr=1.0, + num_iters=(100, 100, 250), + apply_pca=True, + knn_backend="faiss", + ) coordinates = reducer.fit_transform(matrix, init="pca") neighbor_count = int(reducer.n_neighbors) projection_details = { "implementation": "pacmap.PaCMAP", - "effective_pairs": {"neighbors": neighbor_count, - "mid_near": int(reducer.n_MN), "further": int(reducer.n_FP)}, + "effective_pairs": { + "neighbors": neighbor_count, + "mid_near": int(reducer.n_MN), + "further": int(reducer.n_FP), + }, } else: coordinates = projector(matrix, seed=seed, neighbors=neighbor_count) @@ -371,54 +454,82 @@ def build_map(input_path: Path, cache_path: Path, output: Path, profile: dict, try: map_rows = [] for record, xy in zip(selected, coordinates, strict=True): - map_rows.append({name: record[name] for name in REQUIRED_FIELDS if name != "text"} - | {"x": float(xy[0]), "y": float(xy[1])}) + map_rows.append( + {name: record[name] for name in REQUIRED_FIELDS if name != "text"} + | {"x": float(xy[0]), "y": float(xy[1])} + ) (stage / "points.json").write_bytes(canonical(map_rows) + b"\n") - (stage / "index.html").write_text(render_html(title, map_rows, inputs["count"]), - encoding="utf-8") + (stage / "index.html").write_text( + render_html(title, map_rows, inputs["count"]), encoding="utf-8" + ) manifest = { - "format_version": FORMAT_VERSION, "representation": "semantic-text", + "format_version": FORMAT_VERSION, + "representation": "semantic-text", "generated_at_utc": dt.datetime.now(dt.timezone.utc).isoformat(), - "encoder": profile, "encoder_profile_sha256": key, "inputs": inputs, - "projection": {"method": "pacmap", "dimensions": 2, "seed": seed, - "requested_neighbors": neighbors, "neighbors": neighbor_count, - "MN_ratio": 0.5, "FP_ratio": 2.0, "distance": "euclidean", - "learning_rate": 1.0, "iterations": [100, 100, 250], - "apply_pca": True, "knn_backend": "faiss", - "initialization": "pca", "library_versions": projection_versions or {}, - **projection_details}, - "coverage": {"total": inputs["count"], "eligible": inputs["count"], - "displayed": len(selected), "omitted": inputs["count"] - len(selected), - "selection": "bottom-k-sha256(seed,identifier)", "maximum": maximum}, - "source_vectors": {"sha256": vector_checksum, - "shape": list(matrix.shape), "dtype": "float32-le", - "order": "points.json", "storage": "local-profile-bound-cache"}, - "files": {name: digest_file(stage / name) - for name in ("points.json", "index.html")}, + "encoder": profile, + "encoder_profile_sha256": key, + "inputs": inputs, + "projection": { + "method": "pacmap", + "dimensions": 2, + "seed": seed, + "requested_neighbors": neighbors, + "neighbors": neighbor_count, + "MN_ratio": 0.5, + "FP_ratio": 2.0, + "distance": "euclidean", + "learning_rate": 1.0, + "iterations": [100, 100, 250], + "apply_pca": True, + "knn_backend": "faiss", + "initialization": "pca", + "library_versions": projection_versions or {}, + **projection_details, + }, + "coverage": { + "total": inputs["count"], + "eligible": inputs["count"], + "displayed": len(selected), + "omitted": inputs["count"] - len(selected), + "selection": "bottom-k-sha256(seed,identifier)", + "maximum": maximum, + }, + "source_vectors": { + "sha256": vector_checksum, + "shape": list(matrix.shape), + "dtype": "float32-le", + "order": "points.json", + "storage": "local-profile-bound-cache", + }, + "files": {name: digest_file(stage / name) for name in ("points.json", "index.html")}, } (stage / "manifest.json").write_bytes(canonical(manifest) + b"\n") validate_bundle(stage, input_path=input_path) bundle = hashlib.sha256(canonical(manifest)).hexdigest() destination = output / bundle os.rename(stage, destination) - atomic_json(output / "current.json", {"bundle": bundle, - "manifest_sha256": digest_file(destination / "manifest.json")}) + atomic_json( + output / "current.json", + {"bundle": bundle, "manifest_sha256": digest_file(destination / "manifest.json")}, + ) return {"bundle": str(destination), "coverage": manifest["coverage"]} finally: if stage.exists(): shutil.rmtree(stage) -def validate_bundle(bundle: Path, *, input_path: Path | None = None, - cache_path: Path | None = None) -> dict: +def validate_bundle( + bundle: Path, *, input_path: Path | None = None, cache_path: Path | None = None +) -> dict: if bundle.is_symlink() or (bundle / "manifest.json").is_symlink(): raise ContractError("bundle and manifest must not be symbolic links") manifest = json.loads((bundle / "manifest.json").read_text()) if not isinstance(manifest, dict) or manifest.get("format_version") != FORMAT_VERSION: raise ContractError("unsupported map bundle format") - if (manifest.get("representation") != "semantic-text" - or any(not isinstance(manifest.get(name), dict) for name in - ("encoder", "inputs", "files", "coverage", "projection", "source_vectors"))): + if manifest.get("representation") != "semantic-text" or any( + not isinstance(manifest.get(name), dict) + for name in ("encoder", "inputs", "files", "coverage", "projection", "source_vectors") + ): raise ContractError("invalid map bundle metadata") if manifest.get("encoder_profile_sha256") != profile_id(manifest["encoder"]): raise ContractError("encoder profile checksum mismatch") @@ -436,77 +547,103 @@ def validate_bundle(bundle: Path, *, input_path: Path | None = None, raise ContractError("map points must contain at least three records") coverage = manifest["coverage"] projection = manifest["projection"] - if (projection.get("method") != "pacmap" or projection.get("dimensions") != 2 - or type(projection.get("seed")) is not int - or type(projection.get("neighbors")) is not int - or not 1 <= projection["neighbors"] < len(points) - or type(projection.get("requested_neighbors")) is not int - or projection["requested_neighbors"] < 1 - or projection.get("initialization") != "pca" - or projection.get("MN_ratio") != 0.5 or projection.get("FP_ratio") != 2.0 - or projection.get("distance") != "euclidean" - or projection.get("learning_rate") != 1.0 - or projection.get("iterations") != [100, 100, 250] - or projection.get("apply_pca") is not True - or projection.get("knn_backend") != "faiss"): + if ( + projection.get("method") != "pacmap" + or projection.get("dimensions") != 2 + or type(projection.get("seed")) is not int + or type(projection.get("neighbors")) is not int + or not 1 <= projection["neighbors"] < len(points) + or type(projection.get("requested_neighbors")) is not int + or projection["requested_neighbors"] < 1 + or projection.get("initialization") != "pca" + or projection.get("MN_ratio") != 0.5 + or projection.get("FP_ratio") != 2.0 + or projection.get("distance") != "euclidean" + or projection.get("learning_rate") != 1.0 + or projection.get("iterations") != [100, 100, 250] + or projection.get("apply_pca") is not True + or projection.get("knn_backend") != "faiss" + ): raise ContractError("invalid PaCMAP projection metadata") validate_versions(projection.get("library_versions"), "projection") if projection.get("implementation") == "pacmap.PaCMAP": pairs = projection.get("effective_pairs") - if (not isinstance(pairs, dict) - or any(type(pairs.get(name)) is not int or not 0 <= pairs[name] < len(points) - for name in ("neighbors", "mid_near", "further")) - or pairs["neighbors"] != projection["neighbors"] or pairs["further"] < 1): + if ( + not isinstance(pairs, dict) + or any( + type(pairs.get(name)) is not int or not 0 <= pairs[name] < len(points) + for name in ("neighbors", "mid_near", "further") + ) + or pairs["neighbors"] != projection["neighbors"] + or pairs["further"] < 1 + ): raise ContractError("invalid effective PaCMAP pair counts") elif projection.get("implementation") != "injected-projector": raise ContractError("unidentified projection implementation") - if (not isinstance(points, list) or len(points) < 3 - or any(type(coverage.get(name)) is not int for name in - ("displayed", "eligible", "total", "omitted", "maximum")) - or not 3 <= len(points) <= coverage["maximum"] - or coverage["omitted"] < 0 - or coverage.get("selection") != "bottom-k-sha256(seed,identifier)"): + if ( + not isinstance(points, list) + or len(points) < 3 + or any( + type(coverage.get(name)) is not int + for name in ("displayed", "eligible", "total", "omitted", "maximum") + ) + or not 3 <= len(points) <= coverage["maximum"] + or coverage["omitted"] < 0 + or coverage.get("selection") != "bottom-k-sha256(seed,identifier)" + ): raise ContractError("invalid map selection coverage") source_vectors = manifest["source_vectors"] - if (source_vectors.get("shape") != [len(points), manifest["encoder"]["dimension"]] - or source_vectors.get("dtype") != "float32-le" - or source_vectors.get("order") != "points.json" - or source_vectors.get("storage") != "local-profile-bound-cache" - or not re.fullmatch(r"[0-9a-f]{64}", str(source_vectors.get("sha256", "")))): + if ( + source_vectors.get("shape") != [len(points), manifest["encoder"]["dimension"]] + or source_vectors.get("dtype") != "float32-le" + or source_vectors.get("order") != "points.json" + or source_vectors.get("storage") != "local-profile-bound-cache" + or not re.fullmatch(r"[0-9a-f]{64}", str(source_vectors.get("sha256", ""))) + ): raise ContractError("invalid source vector receipt") for row in points: - if (not isinstance(row, dict) - or any(not isinstance(row.get(name), str) or not row[name].strip() - for name in REQUIRED_FIELDS if name != "text") - or not local_link(row["page"]) or not local_link(row["source_path"]) - or not re.fullmatch(r"[0-9a-f]{64}", row["text_sha256"]) - or not all(type(row.get(name)) in (int, float) and math.isfinite(row[name]) - for name in ("x", "y"))): + if ( + not isinstance(row, dict) + or any( + not isinstance(row.get(name), str) or not row[name].strip() + for name in REQUIRED_FIELDS + if name != "text" + ) + or not local_link(row["page"]) + or not local_link(row["source_path"]) + or not re.fullmatch(r"[0-9a-f]{64}", row["text_sha256"]) + or not all( + type(row.get(name)) in (int, float) and math.isfinite(row[name]) + for name in ("x", "y") + ) + ): raise ContractError("invalid map coordinate or record metadata") - if (coverage["displayed"] != len(points) - or coverage["total"] != manifest["inputs"]["count"] - or coverage["eligible"] != coverage["total"] - or coverage["omitted"] != coverage["total"] - len(points) - or len({row["identifier"] for row in points}) != len(points)): + if ( + coverage["displayed"] != len(points) + or coverage["total"] != manifest["inputs"]["count"] + or coverage["eligible"] != coverage["total"] + or coverage["omitted"] != coverage["total"] - len(points) + or len({row["identifier"] for row in points}) != len(points) + ): raise ContractError("map coverage or identifiers are inconsistent") if input_path is not None: selected = select_records(input_path, coverage["maximum"], projection["seed"]) - expected = [{key: row[key] for key in REQUIRED_FIELDS if key != "text"} - for row in selected] - observed = [{key: row[key] for key in REQUIRED_FIELDS if key != "text"} - for row in points] + expected = [{key: row[key] for key in REQUIRED_FIELDS if key != "text"} for row in selected] + observed = [{key: row[key] for key in REQUIRED_FIELDS if key != "text"} for row in points] if observed != expected: raise ContractError("map records differ from the declared input selection") if cache_path is not None: digest = hashlib.sha256() with cache_connection(cache_path) as db: - profile_row = db.execute("SELECT json FROM profiles WHERE id=?", - (manifest["encoder_profile_sha256"],)).fetchone() + profile_row = db.execute( + "SELECT json FROM profiles WHERE id=?", (manifest["encoder_profile_sha256"],) + ).fetchone() if profile_row is None or profile_row[0] != canonical(manifest["encoder"]).decode(): raise ContractError("cache does not contain the exact encoder profile") for row in points: - blob = cached_vector(db, manifest["encoder_profile_sha256"], row, - manifest["encoder"]["dimension"]) + blob = cached_vector( + db, manifest["encoder_profile_sha256"], row, manifest["encoder"]["dimension"] + ) if blob is None: raise ContractError("source vector is missing from the verified cache") digest.update(blob) @@ -525,8 +662,9 @@ def current_bundle(output: Path) -> Path: return bundle -def stage_map(output: Path, published_dir: Path, *, input_path: Path, - expected_bundle: str | None = None) -> dict: +def stage_map( + output: Path, published_dir: Path, *, input_path: Path, expected_bundle: str | None = None +) -> dict: """Stage a verified map into a site build, restoring old files on exceptions. The caller owns the repository/build lock. The site's later deployment is @@ -543,11 +681,13 @@ def stage_map(output: Path, published_dir: Path, *, input_path: Path, raise ContractError("map manifest differs from its immutable generation identity") if manifest["projection"]["implementation"] != "pacmap.PaCMAP": raise ContractError("site publication requires the actual PaCMAP implementation") - if (published_dir.is_symlink() - or (published_dir.exists() and not published_dir.is_dir()) - or source.resolve().is_relative_to(published_dir.resolve()) - or published_dir.resolve().is_relative_to(output.resolve()) - or input_path.resolve().is_relative_to(published_dir.resolve())): + if ( + published_dir.is_symlink() + or (published_dir.exists() and not published_dir.is_dir()) + or source.resolve().is_relative_to(published_dir.resolve()) + or published_dir.resolve().is_relative_to(output.resolve()) + or input_path.resolve().is_relative_to(published_dir.resolve()) + ): raise ContractError("unsafe map staging destination") published_dir.parent.mkdir(parents=True, exist_ok=True) temporary = Path(tempfile.mkdtemp(prefix=".text-map-stage-", dir=published_dir.parent)) @@ -582,7 +722,7 @@ def render_html(title: str, points: list[dict], total: int) -> str: payload = canonical(points).decode().replace("<", "\\u003c").replace("&", "\\u0026") # The site adapter publishes this directory at text-map/. Record pages are # relative to the site root, one level above this self-contained page. - return f''' + return f""" {html.escape(title)}