474 lines
123 KiB
HTML
474 lines
123 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>graphify - graphify-out/graph.html</title>
|
|
<script src="https://unpkg.com/vis-network@9.1.6/standalone/umd/vis-network.min.js"
|
|
integrity="sha384-Ux6phic9PEHJ38YtrijhkzyJ8yQlH8i/+buBR8s3mAZOJrP1gwyvAcIYl3GWtpX1"
|
|
crossorigin="anonymous"></script>
|
|
<style>
|
|
:root {
|
|
--bg: #0f0f1a; --panel: #1a1a2e; --border: #2a2a4e; --input-border: #3a3a5e;
|
|
--text: #e0e0e0; --text-2: #aaa; --text-3: #ccc; --muted: #555; --count: #666;
|
|
--neighbor-border: #333; --node-label: #ffffff;
|
|
}
|
|
[data-theme="light"] {
|
|
--bg: #ffffff; --panel: #f8f9fa; --border: #d9dee5; --input-border: #c3cad4;
|
|
--text: #222222; --text-2: #666666; --text-3: #333333; --muted: #888888; --count: #777777;
|
|
--neighbor-border: #ccc; --node-label: #222222;
|
|
}
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
body { background: var(--bg); color: var(--text); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; display: flex; height: 100vh; overflow: hidden; }
|
|
#graph { flex: 1; }
|
|
#sidebar { width: 280px; background: var(--panel); border-left: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; }
|
|
#search-wrap { padding: 12px; border-bottom: 1px solid var(--border); }
|
|
#search { width: 100%; background: var(--bg); border: 1px solid var(--input-border); color: var(--text); padding: 7px 10px; border-radius: 6px; font-size: 13px; outline: none; }
|
|
#search:focus { border-color: #4E79A7; }
|
|
#search-results { max-height: 140px; overflow-y: auto; padding: 4px 12px; border-bottom: 1px solid var(--border); display: none; }
|
|
.search-item { padding: 4px 6px; cursor: pointer; border-radius: 4px; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
.search-item:hover { background: var(--border); }
|
|
#info-panel { padding: 14px; border-bottom: 1px solid var(--border); min-height: 140px; }
|
|
#info-panel h3 { font-size: 13px; color: var(--text-2); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.05em; }
|
|
#info-content { font-size: 13px; color: var(--text-3); line-height: 1.6; }
|
|
#info-content .field { margin-bottom: 5px; }
|
|
#info-content .field b { color: var(--text); }
|
|
#info-content .empty { color: var(--muted); font-style: italic; }
|
|
.neighbor-link { display: block; padding: 2px 6px; margin: 2px 0; border-radius: 3px; cursor: pointer; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-left: 3px solid var(--neighbor-border); }
|
|
.neighbor-link:hover { background: var(--border); }
|
|
#neighbors-list { max-height: 160px; overflow-y: auto; margin-top: 4px; }
|
|
#legend-wrap { flex: 1; overflow-y: auto; padding: 12px; }
|
|
#legend-wrap h3 { font-size: 13px; color: var(--text-2); margin-bottom: 10px; text-transform: uppercase; letter-spacing: 0.05em; }
|
|
.legend-item { display: flex; align-items: center; gap: 8px; padding: 4px 0; cursor: pointer; border-radius: 4px; font-size: 12px; }
|
|
.legend-item:hover { background: var(--border); padding-left: 4px; }
|
|
.legend-item.dimmed { opacity: 0.35; }
|
|
.legend-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; }
|
|
.legend-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
.legend-count { color: var(--count); font-size: 11px; }
|
|
#stats { padding: 10px 14px; border-top: 1px solid var(--border); font-size: 11px; color: var(--muted); }
|
|
#legend-controls { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; padding: 4px 0; }
|
|
#legend-controls label { display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: 12px; color: var(--text-2); user-select: none; }
|
|
#legend-controls label:hover { color: var(--text); }
|
|
.legend-cb, #select-all-cb { appearance: none; -webkit-appearance: none; width: 14px; height: 14px; border: 1.5px solid var(--input-border); border-radius: 3px; background: var(--bg); cursor: pointer; position: relative; flex-shrink: 0; }
|
|
.legend-cb:checked, #select-all-cb:checked { background: #4E79A7; border-color: #4E79A7; }
|
|
.legend-cb:checked::after, #select-all-cb:checked::after { content: ''; position: absolute; left: 3.5px; top: 1px; width: 4px; height: 7px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
|
|
#select-all-cb:indeterminate { background: #4E79A7; border-color: #4E79A7; }
|
|
#select-all-cb:indeterminate::after { content: ''; position: absolute; left: 2px; top: 5px; width: 8px; height: 2px; background: #fff; border: none; transform: none; }
|
|
#theme-wrap { display: flex; gap: 4px; padding: 8px 12px; border-bottom: 1px solid var(--border); }
|
|
#theme-wrap button { flex: 1; background: var(--bg); color: var(--text-2); border: 1px solid var(--input-border); border-radius: 4px; padding: 3px 0; font-size: 11px; cursor: pointer; }
|
|
#theme-wrap button:hover { color: var(--text); }
|
|
#theme-wrap button[aria-pressed="true"] { background: #4E79A7; border-color: #4E79A7; color: #fff; }
|
|
</style>
|
|
<script id="graphify-theme-init">
|
|
// Apply the saved theme before first paint (#3894). No saved choice keeps the
|
|
// historical dark look; "system" follows prefers-color-scheme.
|
|
(function () {
|
|
var pref = null;
|
|
try { pref = localStorage.getItem('graphify-theme'); } catch (e) {}
|
|
var t = pref === 'light' ? 'light'
|
|
: pref === 'system' && window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches ? 'light'
|
|
: 'dark';
|
|
document.documentElement.setAttribute('data-theme', t);
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="graph"></div>
|
|
<div id="sidebar">
|
|
<div id="theme-wrap" role="group" aria-label="Theme">
|
|
<button type="button" data-theme-choice="light">Light</button>
|
|
<button type="button" data-theme-choice="dark">Dark</button>
|
|
<button type="button" data-theme-choice="system">System</button>
|
|
</div>
|
|
<div id="search-wrap">
|
|
<input id="search" type="text" placeholder="Search nodes..." autocomplete="off">
|
|
<div id="search-results"></div>
|
|
</div>
|
|
<div id="info-panel">
|
|
<h3>Node Info</h3>
|
|
<div id="info-content"><span class="empty">Click a node to inspect it</span></div>
|
|
</div>
|
|
<div id="legend-wrap">
|
|
<h3>Communities</h3>
|
|
<div id="legend-controls">
|
|
<label><input type="checkbox" id="select-all-cb" checked onchange="toggleAllCommunities(!this.checked)">Select All</label>
|
|
</div>
|
|
<div id="legend"></div>
|
|
</div>
|
|
<div id="stats">132 nodes · 189 edges · 17 communities</div>
|
|
</div>
|
|
<script>
|
|
const RAW_NODES = [{"id": "deploy", "label": "deploy.ps1", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "deploy.ps1", "community": 14, "community_name": "Deploy-Skript", "source_file": "deploy.ps1", "file_type": "code", "degree": 1}, {"id": "deploy_assert_ok", "label": "Assert-Ok()", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Assert-Ok()", "community": 14, "community_name": "Deploy-Skript", "source_file": "deploy.ps1", "file_type": "code", "degree": 1}, {"id": "assets_js_site", "label": "site.js", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "site.js", "community": 15, "community_name": "Spotify Loader (site.js)", "source_file": "assets/js/site.js", "file_type": "code", "degree": 0}, {"id": "epk_build", "label": "build.ps1", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "build.ps1", "community": 16, "community_name": "EPK PDF Build", "source_file": "epk/build.ps1", "file_type": "code", "degree": 0}, {"id": "gitea_workflows_deploy", "label": "deploy.yml", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "deploy.yml", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 3}, {"id": "gitea_workflows_deploy_container_image", "label": "image", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "image", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_deploy_container", "label": "container", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "container", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 2}, {"id": "gitea_workflows_deploy_deploy_env", "label": "env", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "env", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 4}, {"id": "gitea_workflows_deploy_deploy_runs_on", "label": "runs-on", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "runs-on", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_deploy_steps", "label": "steps", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "steps", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 4}, {"id": "gitea_workflows_deploy_env_http_proxy", "label": "http_proxy", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "http_proxy", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_env_https_proxy", "label": "https_proxy", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "https_proxy", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_env_no_proxy", "label": "no_proxy", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "no_proxy", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_jobs", "label": "jobs", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "jobs", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 2}, {"id": "gitea_workflows_deploy_jobs_deploy", "label": "deploy", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 17.9, "font": {"size": 12, "color": "#ffffff"}, "title": "deploy", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 5}, {"id": "gitea_workflows_deploy_name", "label": "name", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "name", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_on", "label": "on", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "on", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 2}, {"id": "gitea_workflows_deploy_on_push", "label": "push", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "push", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 2}, {"id": "gitea_workflows_deploy_push_branches", "label": "branches", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "branches", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_steps_name", "label": "name", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "name", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_steps_run", "label": "run", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "run", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "gitea_workflows_deploy_steps_uses", "label": "uses", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "uses", "community": 2, "community_name": "Gitea Deploy Workflow", "source_file": ".gitea/workflows/deploy.yml", "file_type": "code", "degree": 1}, {"id": "assets_css_main", "label": "Main Stylesheet (main.css)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Main Stylesheet (main.css)", "community": 0, "community_name": "Templates & Design", "source_file": "assets/css/main.css", "file_type": "code", "degree": 3}, {"id": "layouts_404", "label": "404 Page Template (Abgesoffen)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "404 Page Template (Abgesoffen)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/404.html", "file_type": "code", "degree": 1}, {"id": "layouts__default_band", "label": "Band Page Layout (members, group photo, crew)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Band Page Layout (members, group photo, crew)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/_default/band.html", "file_type": "code", "degree": 4}, {"id": "layouts__default_band_crew_section", "label": "Crew Section (photographer portrait / initials fallback)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Crew Section (photographer portrait / initials fallback)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/_default/band.html", "file_type": "code", "degree": 2}, {"id": "layouts__default_baseof", "label": "Base Template (baseof.html)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 28.9, "font": {"size": 12, "color": "#ffffff"}, "title": "Base Template (baseof.html)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/_default/baseof.html", "file_type": "code", "degree": 12}, {"id": "layouts__default_baseof_seo_meta", "label": "SEO / Open Graph Meta Tags", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "SEO / Open Graph Meta Tags", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/_default/baseof.html", "file_type": "code", "degree": 3}, {"id": "layouts__default_list", "label": "Default List Layout", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Default List Layout", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/_default/list.html", "file_type": "code", "degree": 1}, {"id": "layouts__default_single", "label": "Default Single Layout (legal prose)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Default Single Layout (legal prose)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/_default/single.html", "file_type": "code", "degree": 1}, {"id": "layouts_index", "label": "Homepage Template (hero, intro, live, booking)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Homepage Template (hero, intro, live, booking)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/index.html", "file_type": "code", "degree": 4}, {"id": "layouts_music_list", "label": "Music Page Layout (featured album, discography)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 21.1, "font": {"size": 12, "color": "#ffffff"}, "title": "Music Page Layout (featured album, discography)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/music/list.html", "file_type": "code", "degree": 7}, {"id": "layouts_partials_footer", "label": "Footer Partial (contact, social, photographer credit)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Footer Partial (contact, social, photographer credit)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/footer.html", "file_type": "code", "degree": 2}, {"id": "layouts_partials_header", "label": "Header Partial (logo, main nav with aria-current)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Header Partial (logo, main nav with aria-current)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/header.html", "file_type": "code", "degree": 1}, {"id": "layouts_partials_img", "label": "Responsive Image Partial (WebP srcset)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Responsive Image Partial (WebP srcset)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/img.html", "file_type": "code", "degree": 4}, {"id": "layouts_partials_releases", "label": "Releases Partial (parse cover filenames)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Releases Partial (parse cover filenames)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/releases.html", "file_type": "code", "degree": 3}, {"id": "layouts_partials_schema", "label": "JSON-LD Schema Partial", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 19.5, "font": {"size": 12, "color": "#ffffff"}, "title": "JSON-LD Schema Partial", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/schema.html", "file_type": "code", "degree": 6}, {"id": "layouts_partials_show_card", "label": "Show Card Partial (flyer / TBA poster)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Show Card Partial (flyer / TBA poster)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/show-card.html", "file_type": "code", "degree": 4}, {"id": "layouts_partials_spotify", "label": "Spotify Consent Embed Partial (click-to-load)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Spotify Consent Embed Partial (click-to-load)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/spotify.html", "file_type": "code", "degree": 2}, {"id": "layouts_robots", "label": "robots.txt Template", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "robots.txt Template", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/robots.txt", "file_type": "code", "degree": 1}, {"id": "layouts_shows_list", "label": "Shows List Layout (upcoming + archive by year)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 17.9, "font": {"size": 12, "color": "#ffffff"}, "title": "Shows List Layout (upcoming + archive by year)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/shows/list.html", "file_type": "code", "degree": 5}, {"id": "layouts_shows_single", "label": "Show Single Redirect (noindex, redirect to /shows/)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Show Single Redirect (noindex, redirect to /shows/)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/shows/single.html", "file_type": "code", "degree": 1}, {"id": "assets_css_main_album_vinyl", "label": "Album Sleeve Vinyl Slide-Out Effect", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Album Sleeve Vinyl Slide-Out Effect", "community": 0, "community_name": "Templates & Design", "source_file": "assets/css/main.css", "file_type": "concept", "degree": 1}, {"id": "assets_css_main_design_tokens", "label": "Design Tokens (--deep, --bolt, --red, fonts, --slant)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Design Tokens (--deep, --bolt, --red, fonts, --slant)", "community": 0, "community_name": "Templates & Design", "source_file": "assets/css/main.css", "file_type": "concept", "degree": 2}, {"id": "assets_css_main_flyer_wall", "label": "Flyer Wall (tilted posters with gaffa tape)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Flyer Wall (tilted posters with gaffa tape)", "community": 0, "community_name": "Templates & Design", "source_file": "assets/css/main.css", "file_type": "concept", "degree": 2}, {"id": "layouts_partials_releases_filename_convention", "label": "Release Filename Convention JJJJMMTT_Kind_Name.jpg", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Release Filename Convention JJJJMMTT_Kind_Name.jpg", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/releases.html", "file_type": "concept", "degree": 1}, {"id": "layouts_partials_schema_musicevent", "label": "MusicEvent JSON-LD (upcoming non-TBA shows)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "MusicEvent JSON-LD (upcoming non-TBA shows)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/schema.html", "file_type": "concept", "degree": 3}, {"id": "layouts_partials_schema_musicgroup", "label": "MusicGroup JSON-LD (band, members, albums)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "MusicGroup JSON-LD (band, members, albums)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/schema.html", "file_type": "concept", "degree": 3}, {"id": "site_params", "label": "site.Params (email, spotify, instagram, youtube, photographer)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 21.1, "font": {"size": 12, "color": "#ffffff"}, "title": "site.Params (email, spotify, instagram, youtube, photographer)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/partials/footer.html", "file_type": "concept", "degree": 7}, {"id": "assets_css_main_slant", "label": "Bolt-Angle Slant Clip-Paths", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Bolt-Angle Slant Clip-Paths", "community": 0, "community_name": "Templates & Design", "source_file": "assets/css/main.css", "file_type": "rationale", "degree": 1}, {"id": "layouts_music_list_featured_release", "label": "Featured Release Selection (newest album, else newest release)", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Featured Release Selection (newest album, else newest release)", "community": 0, "community_name": "Templates & Design", "source_file": "layouts/music/list.html", "file_type": "rationale", "degree": 1}, {"id": "claude_epk_build_script", "label": "epk/build.ps1 (PDF build)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "epk/build.ps1 (PDF build)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "code", "degree": 1}, {"id": "epk_epk_band_music_page", "label": "EPK Page 3: Band & Musik (Members, Ocean Tales, 5 Singles)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 21.1, "font": {"size": 12, "color": "#ffffff"}, "title": "EPK Page 3: Band & Musik (Members, Ocean Tales, 5 Singles)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "epk/epk.html", "file_type": "code", "degree": 7}, {"id": "epk_epk_bio_page", "label": "EPK Page 2: Bio (Punk mit Haltung, Facts)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "EPK Page 2: Bio (Punk mit Haltung, Facts)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "epk/epk.html", "file_type": "code", "degree": 4}, {"id": "epk_epk_document", "label": "epk.html EPK Template", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 25.8, "font": {"size": 12, "color": "#ffffff"}, "title": "epk.html EPK Template", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "epk/epk.html", "file_type": "code", "degree": 10}, {"id": "hugo_config", "label": "hugo.toml Site Config", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "hugo.toml Site Config", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "hugo.toml", "file_type": "code", "degree": 4}, {"id": "hugo_menu_main", "label": "Main Menu (Home, Band, Shows, Musik)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Main Menu (Home, Band, Shows, Musik)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "hugo.toml", "file_type": "code", "degree": 4}, {"id": "hugo_module_mounts", "label": "Module Mounts (static/img and releases as assets for WebP)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Module Mounts (static/img and releases as assets for WebP)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "hugo.toml", "file_type": "code", "degree": 2}, {"id": "hugo_params", "label": "[params] links, email, Spotify/Instagram/YouTube", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 19.5, "font": {"size": 12, "color": "#ffffff"}, "title": "[params] links, email, Spotify/Instagram/YouTube", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "hugo.toml", "file_type": "code", "degree": 6}, {"id": "hugo_params_photographer", "label": "[params.photographer] Lukas Ittenbach (shot__itt)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "[params.photographer] Lukas Ittenbach (shot__itt)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "hugo.toml", "file_type": "code", "degree": 3}, {"id": "claude_deepwater_survival", "label": "Deepwater Survival (Punkrock-Band aus Trier)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Deepwater Survival (Punkrock-Band aus Trier)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "concept", "degree": 3}, {"id": "claude_epk", "label": "EPK (Electronic Press Kit, 4 A4 pages)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "EPK (Electronic Press Kit, 4 A4 pages)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "concept", "degree": 1}, {"id": "claude_hugo_website", "label": "Hugo Website (deutsch, deploy.ps1)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Hugo Website (deutsch, deploy.ps1)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "concept", "degree": 2}, {"id": "content__index_band_bio", "label": "Band Bio Text (Identit\u00e4t, Zugeh\u00f6rigkeit, Abschied, Neuanfang)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Band Bio Text (Identit\u00e4t, Zugeh\u00f6rigkeit, Abschied, Neuanfang)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "content/_index.md", "file_type": "concept", "degree": 4}, {"id": "content__index_ocean_tales", "label": "Ocean Tales (Deb\u00fctalbum 2025)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 17.9, "font": {"size": 12, "color": "#ffffff"}, "title": "Ocean Tales (Deb\u00fctalbum 2025)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "content/_index.md", "file_type": "concept", "degree": 5}, {"id": "content__index_singles", "label": "Singles: Chirus, Let It Go, Addiction, My Own Home", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 17.9, "font": {"size": 12, "color": "#ffffff"}, "title": "Singles: Chirus, Let It Go, Addiction, My Own Home", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "content/_index.md", "file_type": "concept", "degree": 5}, {"id": "content_about_crew_lukas_ittenbach", "label": "Crew: Lukas Ittenbach (Video und Fotografie)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Crew: Lukas Ittenbach (Video und Fotografie)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "content/about.md", "file_type": "concept", "degree": 2}, {"id": "content_about_members", "label": "Band Members (Olly, Lucas, Ahrens, Felix)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Band Members (Olly, Lucas, Ahrens, Felix)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "content/about.md", "file_type": "concept", "degree": 4}, {"id": "epk_epk_single_im_so_glad", "label": "Single: I'm So Glad (2023)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Single: I'm So Glad (2023)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "epk/epk.html", "file_type": "concept", "degree": 2}, {"id": "claude_project_guide", "label": "CLAUDE.md Project Guide (Website & EPK)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 21.1, "font": {"size": 12, "color": "#ffffff"}, "title": "CLAUDE.md Project Guide (Website & EPK)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "document", "degree": 7}, {"id": "content__index_home", "label": "Home Page Content (Punk mit Haltung)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Home Page Content (Punk mit Haltung)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "content/_index.md", "file_type": "document", "degree": 3}, {"id": "content_about_band_page", "label": "Band Page (about.md)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Band Page (about.md)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "content/about.md", "file_type": "document", "degree": 4}, {"id": "content_music__index_music_page", "label": "Music Page (Musik)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 17.9, "font": {"size": 12, "color": "#ffffff"}, "title": "Music Page (Musik)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "content/music/_index.md", "file_type": "document", "degree": 5}, {"id": "claude_fixed_a4_overflow", "label": "Fixed A4 Page with overflow:hidden (check PDF for clipping)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Fixed A4 Page with overflow:hidden (check PDF for clipping)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "rationale", "degree": 1}, {"id": "claude_no_invented_facts", "label": "No Invented Facts Policy (only band-confirmed claims)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "No Invented Facts Policy (only band-confirmed claims)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "rationale", "degree": 1}, {"id": "claude_photo_credit_rule", "label": "Photo Credit Rule (Lukas Ittenbach @shot__itt always credited)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Photo Credit Rule (Lukas Ittenbach @shot__itt always credited)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "rationale", "degree": 3}, {"id": "claude_release_cover_naming", "label": "Release Cover Naming Convention (JJJJMMTT_[Single|Album]_[Name].jpg)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Release Cover Naming Convention (JJJJMMTT_[Single|Album]_[Name].jpg)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "CLAUDE.md", "file_type": "rationale", "degree": 2}, {"id": "hugo_buildfuture", "label": "buildFuture = true (future-dated shows)", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "buildFuture = true (future-dated shows)", "community": 1, "community_name": "Band, EPK & Regeln", "source_file": "hugo.toml", "file_type": "rationale", "degree": 2}, {"id": "content_shows_2025_album_release_party_show", "label": "Album Release Party", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Album Release Party", "community": 10, "community_name": "Album Release Party", "source_file": "content/shows/2025_Album_Release_Party.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2025_album_release_party_rothaus_trier", "label": "Rothaus Trier", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Rothaus Trier", "community": 10, "community_name": "Album Release Party", "source_file": "content/shows/2025_Album_Release_Party.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2025_riez_kapellenkontest_show", "label": "Riez Kapellen-Contest", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Riez Kapellen-Contest", "community": 11, "community_name": "Riez Kapellen-Contest", "source_file": "content/shows/2025_Riez_Kapellenkontest.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2025_riez_kapellenkontest_riez_rockbar_bausendorf", "label": "Riez Rockbar, Bausendorf", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Riez Rockbar, Bausendorf", "community": 11, "community_name": "Riez Kapellen-Contest", "source_file": "content/shows/2025_Riez_Kapellenkontest.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2026_altstadtfest_trier_show", "label": "Altstadtfest Trier", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Altstadtfest Trier", "community": 12, "community_name": "Altstadtfest Trier", "source_file": "content/shows/2026_Altstadtfest_Trier.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2026_altstadtfest_trier_hauptmarkt_b\u00fchne", "label": "Hauptmarkt B\u00fchne", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Hauptmarkt B\u00fchne", "community": 12, "community_name": "Altstadtfest Trier", "source_file": "content/shows/2026_Altstadtfest_Trier.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2026_halloween_show", "label": "Halloween Rock", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Halloween Rock", "community": 13, "community_name": "Halloween Rock", "source_file": "content/shows/2026_Halloween.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2026_halloween_gutweiler", "label": "Gutweiler", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Gutweiler", "community": 13, "community_name": "Halloween Rock", "source_file": "content/shows/2026_Halloween.md", "file_type": "concept", "degree": 1}, {"id": "epk_epk_css_tokens", "label": "EPK CSS Tokens (:root --deep, --bolt, --red, fonts)", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "EPK CSS Tokens (:root --deep, --bolt, --red, fonts)", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "epk/epk.html", "file_type": "code", "degree": 2}, {"id": "claude_design_system", "label": "Design System (--deep, --bolt, --red; Big Shoulders Display + Archivo)", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Design System (--deep, --bolt, --red; Big Shoulders Display + Archivo)", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "CLAUDE.md", "file_type": "concept", "degree": 2}, {"id": "content_datenschutz_dsgvo_rights", "label": "DSGVO Betroffenenrechte und Rechtsgrundlagen", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "DSGVO Betroffenenrechte und Rechtsgrundlagen", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "content/Datenschutz.md", "file_type": "concept", "degree": 1}, {"id": "content_datenschutz_hosting_1blu", "label": "Externes Hosting bei 1blu GmbH", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Externes Hosting bei 1blu GmbH", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "content/Datenschutz.md", "file_type": "concept", "degree": 1}, {"id": "content_impressum_disclaimer", "label": "Disclaimer (Inhalte, externe Links, Urheberrecht, Nutzungsbedingungen)", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Disclaimer (Inhalte, externe Links, Urheberrecht, Nutzungsbedingungen)", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "content/Impressum.md", "file_type": "concept", "degree": 1}, {"id": "content_datenschutz_page", "label": "Datenschutzerkl\u00e4rung", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 17.9, "font": {"size": 12, "color": "#ffffff"}, "title": "Datenschutzerkl\u00e4rung", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "content/Datenschutz.md", "file_type": "document", "degree": 5}, {"id": "content_impressum_page", "label": "Impressum (Lucas Hahmann, Trier)", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Impressum (Lucas Hahmann, Trier)", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "content/Impressum.md", "file_type": "document", "degree": 2}, {"id": "content_datenschutz_local_fonts", "label": "Lokal gehostete Schriftarten (keine Google-Verbindung)", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Lokal gehostete Schriftarten (keine Google-Verbindung)", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "content/Datenschutz.md", "file_type": "rationale", "degree": 2}, {"id": "content_datenschutz_spotify_click_to_load", "label": "Spotify Player Click-to-Load (no data before consent)", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Spotify Player Click-to-Load (no data before consent)", "community": 3, "community_name": "Datenschutz & Impressum", "source_file": "content/Datenschutz.md", "file_type": "rationale", "degree": 2}, {"id": "content_shows_2023_moselrock_show", "label": "Moselrock", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Moselrock", "community": 4, "community_name": "Show-Schema & Mosel-Gigs", "source_file": "content/shows/2023_Moselrock.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2025_bullenhitze_show", "label": "Bullenhitze", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Bullenhitze", "community": 4, "community_name": "Show-Schema & Mosel-Gigs", "source_file": "content/shows/2025_Bullenhitze.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2026_highway_to_kell_show", "label": "Highway to Kell", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Highway to Kell", "community": 4, "community_name": "Show-Schema & Mosel-Gigs", "source_file": "content/shows/2026_Highway_to_Kell.md", "file_type": "document", "degree": 3}, {"id": "archetypes_default_archetype", "label": "Default Content Archetype (draft, date, title from filename)", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Default Content Archetype (draft, date, title from filename)", "community": 4, "community_name": "Show-Schema & Mosel-Gigs", "source_file": "archetypes/default.md", "file_type": "code", "degree": 1}, {"id": "content_shows_2023_moselrock_wasserliesch", "label": "Wasserliesch", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Wasserliesch", "community": 4, "community_name": "Show-Schema & Mosel-Gigs", "source_file": "content/shows/2023_Moselrock.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2025_bullenhitze_salmtal", "label": "Salmtal", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Salmtal", "community": 4, "community_name": "Show-Schema & Mosel-Gigs", "source_file": "content/shows/2025_Bullenhitze.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2026_highway_to_kell_kell", "label": "Kell", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Kell", "community": 4, "community_name": "Show-Schema & Mosel-Gigs", "source_file": "content/shows/2026_Highway_to_Kell.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2026_tefftival_show_front_matter_schema", "label": "Show Front Matter Schema (title, date, location, poster, tba)", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 40.0, "font": {"size": 12, "color": "#ffffff"}, "title": "Show Front Matter Schema (title, date, location, poster, tba)", "community": 4, "community_name": "Show-Schema & Mosel-Gigs", "source_file": "content/shows/2026_Tefftival.md", "file_type": "concept", "degree": 19}, {"id": "epk_epk_cover_page", "label": "EPK Page 1: Cover (Roh, laut und ehrlich; 15+ Shows)", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "EPK Page 1: Cover (Roh, laut und ehrlich; 15+ Shows)", "community": 5, "community_name": "Shows \u2194 EPK Sync", "source_file": "epk/epk.html", "file_type": "code", "degree": 3}, {"id": "epk_epk_live_contact_page", "label": "EPK Page 4: Live & Kontakt (N\u00e4chste/Bisherige Shows, Booking)", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 19.5, "font": {"size": 12, "color": "#ffffff"}, "title": "EPK Page 4: Live & Kontakt (N\u00e4chste/Bisherige Shows, Booking)", "community": 5, "community_name": "Shows \u2194 EPK Sync", "source_file": "epk/epk.html", "file_type": "code", "degree": 6}, {"id": "claude_seo_jsonld_sitemap", "label": "SEO: JSON-LD schema partial and custom sitemap", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "SEO: JSON-LD schema partial and custom sitemap", "community": 5, "community_name": "Shows \u2194 EPK Sync", "source_file": "CLAUDE.md", "file_type": "concept", "degree": 1}, {"id": "epk_epk_show_history", "label": "Show History 2022-2026 (15 shows, e.g. Tefftival Tufa, Moselrock, Altstadtfest)", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Show History 2022-2026 (15 shows, e.g. Tefftival Tufa, Moselrock, Altstadtfest)", "community": 5, "community_name": "Shows \u2194 EPK Sync", "source_file": "epk/epk.html", "file_type": "concept", "degree": 3}, {"id": "epk_epk_upcoming_shows", "label": "Upcoming Shows (31.10.2026 Halloween Rock Gutweiler; 23.12.2026 TBA)", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Upcoming Shows (31.10.2026 Halloween Rock Gutweiler; 23.12.2026 TBA)", "community": 5, "community_name": "Shows \u2194 EPK Sync", "source_file": "epk/epk.html", "file_type": "concept", "degree": 2}, {"id": "claude_epk_manual_sync", "label": "EPK Manual Sync Rule (keep epk.html in step with website)", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "EPK Manual Sync Rule (keep epk.html in step with website)", "community": 5, "community_name": "Shows \u2194 EPK Sync", "source_file": "CLAUDE.md", "file_type": "rationale", "degree": 2}, {"id": "claude_shows_content_model", "label": "Shows Content Model (one file per show, tba, city/address)", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Shows Content Model (one file per show, tba, city/address)", "community": 5, "community_name": "Shows \u2194 EPK Sync", "source_file": "CLAUDE.md", "file_type": "rationale", "degree": 4}, {"id": "content_shows_2022_jukufe_light_show", "label": "JUKUFE Light", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "JUKUFE Light", "community": 6, "community_name": "Pink Future & Skatehalle", "source_file": "content/shows/2022_Jukufe_light.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2023_pink_future_show", "label": "Pink Future 2023", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Pink Future 2023", "community": 6, "community_name": "Pink Future & Skatehalle", "source_file": "content/shows/2023_Pink_Future.md", "file_type": "document", "degree": 4}, {"id": "content_shows_2024_pink_future_show", "label": "Pink Future 2024", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Pink Future 2024", "community": 6, "community_name": "Pink Future & Skatehalle", "source_file": "content/shows/2024_Pink_Future.md", "file_type": "document", "degree": 4}, {"id": "content_shows_2022_jukufe_light_skatehalle_trier", "label": "Skatehalle Trier", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Skatehalle Trier", "community": 6, "community_name": "Pink Future & Skatehalle", "source_file": "content/shows/2022_Jukufe_light.md", "file_type": "concept", "degree": 2}, {"id": "content_shows_2023_pink_future_pink_future_series", "label": "Pink Future (recurring)", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Pink Future (recurring)", "community": 6, "community_name": "Pink Future & Skatehalle", "source_file": "content/shows/2023_Pink_Future.md", "file_type": "concept", "degree": 2}, {"id": "content_shows_2023_pink_future_skatehalle_trier_west", "label": "Skatehalle Trier West", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Skatehalle Trier West", "community": 6, "community_name": "Pink Future & Skatehalle", "source_file": "content/shows/2023_Pink_Future.md", "file_type": "concept", "degree": 2}, {"id": "content_shows_2024_pink_future_palastgarten_trier", "label": "Palastgarten Trier", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Palastgarten Trier", "community": 6, "community_name": "Pink Future & Skatehalle", "source_file": "content/shows/2024_Pink_Future.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2022_konz_wird_laut_show", "label": "Konz wird Laut", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Konz wird Laut", "community": 7, "community_name": "Trierer Umland-Shows", "source_file": "content/shows/2022_Konz_wird_laut.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2024_rock_fuer_ruanda_show", "label": "Rock f\u00fcr Ruanda", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Rock f\u00fcr Ruanda", "community": 7, "community_name": "Trierer Umland-Shows", "source_file": "content/shows/2024_Rock_fuer_Ruanda.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2026_luke_show", "label": "Lucky\u00b4s Luke", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Lucky\u00b4s Luke", "community": 7, "community_name": "Trierer Umland-Shows", "source_file": "content/shows/2026_Luke.md", "file_type": "document", "degree": 3}, {"id": "content_shows__index_shows", "label": "Shows Section Index", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 38.4, "font": {"size": 12, "color": "#ffffff"}, "title": "Shows Section Index", "community": 7, "community_name": "Trierer Umland-Shows", "source_file": "content/shows/_index.md", "file_type": "document", "degree": 18}, {"id": "content_shows_2022_konz_wird_laut_haus_der_jugend_konz", "label": "Haus der Jugend Konz", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Haus der Jugend Konz", "community": 7, "community_name": "Trierer Umland-Shows", "source_file": "content/shows/2022_Konz_wird_laut.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2024_rock_fuer_ruanda_butzweiler", "label": "Butzweiler", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Butzweiler", "community": 7, "community_name": "Trierer Umland-Shows", "source_file": "content/shows/2024_Rock_fuer_Ruanda.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2026_luke_trier", "label": "Trier", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Trier", "community": 7, "community_name": "Trierer Umland-Shows", "source_file": "content/shows/2026_Luke.md", "file_type": "concept", "degree": 1}, {"id": "content_shows_2022_rock_im_gehege_show", "label": "Rock im Gehege 2022", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Rock im Gehege 2022", "community": 8, "community_name": "Rock im Gehege", "source_file": "content/shows/2022_Rock_im_Gehege.md", "file_type": "document", "degree": 4}, {"id": "content_shows_2024_rock_im_gehege_show", "label": "Rock im Gehege 2024", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Rock im Gehege 2024", "community": 8, "community_name": "Rock im Gehege", "source_file": "content/shows/2024_Rock_im_Gehege.md", "file_type": "document", "degree": 4}, {"id": "content_shows_2022_rock_im_gehege_piesbach", "label": "Piesbach", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Piesbach", "community": 8, "community_name": "Rock im Gehege", "source_file": "content/shows/2022_Rock_im_Gehege.md", "file_type": "concept", "degree": 2}, {"id": "content_shows_2022_rock_im_gehege_rock_im_gehege_series", "label": "Rock im Gehege (recurring)", "color": {"background": "#9C755F", "border": "#9C755F", "highlight": {"background": "#ffffff", "border": "#9C755F"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Rock im Gehege (recurring)", "community": 8, "community_name": "Rock im Gehege", "source_file": "content/shows/2022_Rock_im_Gehege.md", "file_type": "concept", "degree": 2}, {"id": "content_shows_2022_tefftival_show", "label": "Tefftival 2022", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 16.3, "font": {"size": 12, "color": "#ffffff"}, "title": "Tefftival 2022", "community": 9, "community_name": "Tefftival", "source_file": "content/shows/2022_Tefftival.md", "file_type": "document", "degree": 4}, {"id": "content_shows_2026_tefftival_show", "label": "Tefftival 2026 (TBA)", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 14.7, "font": {"size": 12, "color": "#ffffff"}, "title": "Tefftival 2026 (TBA)", "community": 9, "community_name": "Tefftival", "source_file": "content/shows/2026_Tefftival.md", "file_type": "document", "degree": 3}, {"id": "content_shows_2022_tefftival_tefftival_series", "label": "Tefftival (recurring, Dec 23)", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 13.2, "font": {"size": 0, "color": "#ffffff"}, "title": "Tefftival (recurring, Dec 23)", "community": 9, "community_name": "Tefftival", "source_file": "content/shows/2022_Tefftival.md", "file_type": "concept", "degree": 2}, {"id": "content_shows_2022_tefftival_tufa", "label": "Tufa", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 11.6, "font": {"size": 0, "color": "#ffffff"}, "title": "Tufa", "community": 9, "community_name": "Tefftival", "source_file": "content/shows/2022_Tefftival.md", "file_type": "concept", "degree": 1}];
|
|
const RAW_EDGES = [{"from": "deploy", "to": "deploy_assert_ok", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy", "to": "gitea_workflows_deploy_name", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy", "to": "gitea_workflows_deploy_on", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy", "to": "gitea_workflows_deploy_jobs", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_deploy_container", "to": "gitea_workflows_deploy_container_image", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_jobs_deploy", "to": "gitea_workflows_deploy_deploy_container", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_deploy_env", "to": "gitea_workflows_deploy_env_http_proxy", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_deploy_env", "to": "gitea_workflows_deploy_env_https_proxy", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_deploy_env", "to": "gitea_workflows_deploy_env_no_proxy", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_jobs_deploy", "to": "gitea_workflows_deploy_deploy_env", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_jobs_deploy", "to": "gitea_workflows_deploy_deploy_runs_on", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_deploy_steps", "to": "gitea_workflows_deploy_steps_uses", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_deploy_steps", "to": "gitea_workflows_deploy_steps_name", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_deploy_steps", "to": "gitea_workflows_deploy_steps_run", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_jobs_deploy", "to": "gitea_workflows_deploy_deploy_steps", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_jobs", "to": "gitea_workflows_deploy_jobs_deploy", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_on", "to": "gitea_workflows_deploy_on_push", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "gitea_workflows_deploy_on_push", "to": "gitea_workflows_deploy_push_branches", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "assets_css_main_design_tokens", "to": "assets_css_main", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "assets_css_main_flyer_wall", "to": "assets_css_main", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts__default_baseof", "to": "assets_css_main", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_404", "to": "layouts__default_baseof", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts__default_band", "to": "layouts_partials_img", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts__default_band_crew_section", "to": "layouts__default_band", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts__default_band", "to": "layouts__default_baseof", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_partials_schema_musicgroup", "to": "layouts__default_band", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts__default_band_crew_section", "to": "site_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts__default_baseof", "to": "layouts_partials_schema", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts__default_baseof", "to": "layouts_partials_header", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts__default_baseof", "to": "layouts_partials_footer", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts__default_baseof_seo_meta", "to": "layouts__default_baseof", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts__default_list", "to": "layouts__default_baseof", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts__default_single", "to": "layouts__default_baseof", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_index", "to": "layouts__default_baseof", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_music_list", "to": "layouts__default_baseof", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_shows_list", "to": "layouts__default_baseof", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_robots", "to": "layouts__default_baseof_seo_meta", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts__default_baseof_seo_meta", "to": "layouts_partials_schema", "label": "semantically_similar_to", "title": "semantically_similar_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_index", "to": "layouts_partials_show_card", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_index", "to": "layouts_partials_img", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_index", "to": "site_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_music_list", "to": "layouts_partials_img", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_music_list", "to": "layouts_partials_releases", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_music_list", "to": "layouts_partials_spotify", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_music_list_featured_release", "to": "layouts_music_list", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_music_list", "to": "site_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "assets_css_main_album_vinyl", "to": "layouts_music_list", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_partials_footer", "to": "site_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_show_card", "to": "layouts_partials_img", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_schema", "to": "layouts_partials_releases", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_releases_filename_convention", "to": "layouts_partials_releases", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_schema_musicevent", "to": "layouts_partials_schema", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_schema_musicgroup", "to": "layouts_partials_schema", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_schema", "to": "site_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_shows_list", "to": "layouts_partials_show_card", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_show_card", "to": "assets_css_main_flyer_wall", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_partials_spotify", "to": "site_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_shows_list", "to": "site_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_schema_musicevent", "to": "layouts_shows_list", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "layouts_shows_single", "to": "layouts_shows_list", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "assets_css_main_slant", "to": "assets_css_main_design_tokens", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "layouts_partials_schema_musicevent", "to": "layouts_partials_schema_musicgroup", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_epk_build_script", "to": "epk_epk_document", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_band_music_page", "to": "content__index_ocean_tales", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_band_music_page", "to": "content__index_singles", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_band_music_page", "to": "epk_epk_single_im_so_glad", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_document", "to": "epk_epk_band_music_page", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_band_music_page", "to": "claude_release_cover_naming", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_about_members", "to": "epk_epk_band_music_page", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_music__index_music_page", "to": "epk_epk_band_music_page", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "epk_epk_document", "to": "epk_epk_bio_page", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_photo_credit_rule", "to": "epk_epk_bio_page", "label": "rationale_for", "title": "rationale_for [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content__index_band_bio", "to": "epk_epk_bio_page", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "epk_epk_bio_page", "to": "content_about_members", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "epk_epk_document", "to": "claude_deepwater_survival", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_fixed_a4_overflow", "to": "epk_epk_document", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_no_invented_facts", "to": "epk_epk_document", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_project_guide", "to": "epk_epk_document", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_document", "to": "epk_epk_css_tokens", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_document", "to": "epk_epk_cover_page", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_document", "to": "epk_epk_live_contact_page", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_config", "to": "hugo_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_config", "to": "hugo_menu_main", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_config", "to": "hugo_module_mounts", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_config", "to": "hugo_buildfuture", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_menu_main", "to": "content__index_home", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_menu_main", "to": "content_about_band_page", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_menu_main", "to": "content_music__index_music_page", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_release_cover_naming", "to": "hugo_module_mounts", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "claude_project_guide", "to": "hugo_params", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_params", "to": "content__index_ocean_tales", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "hugo_params", "to": "hugo_params_photographer", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_datenschutz_spotify_click_to_load", "to": "hugo_params", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "hugo_params", "to": "epk_epk_live_contact_page", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "hugo_params_photographer", "to": "claude_photo_credit_rule", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "hugo_params_photographer", "to": "content_about_crew_lukas_ittenbach", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "claude_hugo_website", "to": "claude_deepwater_survival", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_about_members", "to": "claude_deepwater_survival", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_project_guide", "to": "claude_epk", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_project_guide", "to": "claude_hugo_website", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content__index_band_bio", "to": "content__index_ocean_tales", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content__index_band_bio", "to": "content__index_singles", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content__index_home", "to": "content__index_band_bio", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content__index_singles", "to": "content__index_ocean_tales", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_music__index_music_page", "to": "content__index_ocean_tales", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_single_im_so_glad", "to": "content__index_singles", "label": "conceptually_related_to", "title": "conceptually_related_to [AMBIGUOUS]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "AMBIGUOUS"}, {"from": "content_music__index_music_page", "to": "content__index_singles", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_about_band_page", "to": "content_about_crew_lukas_ittenbach", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_about_band_page", "to": "content_about_members", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_project_guide", "to": "content__index_home", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_project_guide", "to": "content_about_band_page", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_project_guide", "to": "content_music__index_music_page", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_photo_credit_rule", "to": "epk_epk_live_contact_page", "label": "rationale_for", "title": "rationale_for [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "claude_shows_content_model", "to": "hugo_buildfuture", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2025_album_release_party_show", "to": "content_shows_2025_album_release_party_rothaus_trier", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2025_album_release_party_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2025_album_release_party_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2025_riez_kapellenkontest_show", "to": "content_shows_2025_riez_kapellenkontest_riez_rockbar_bausendorf", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2025_riez_kapellenkontest_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2025_riez_kapellenkontest_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2026_altstadtfest_trier_show", "to": "content_shows_2026_altstadtfest_trier_hauptmarkt_b\u00fchne", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2026_altstadtfest_trier_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2026_altstadtfest_trier_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2026_halloween_show", "to": "content_shows_2026_halloween_gutweiler", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2026_halloween_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2026_halloween_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "claude_design_system", "to": "epk_epk_css_tokens", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_datenschutz_local_fonts", "to": "claude_design_system", "label": "rationale_for", "title": "rationale_for [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_datenschutz_page", "to": "content_datenschutz_dsgvo_rights", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_datenschutz_page", "to": "content_datenschutz_hosting_1blu", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_impressum_page", "to": "content_impressum_disclaimer", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_datenschutz_page", "to": "content_datenschutz_local_fonts", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_datenschutz_page", "to": "content_datenschutz_spotify_click_to_load", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_impressum_page", "to": "content_datenschutz_page", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2023_moselrock_show", "to": "content_shows_2023_moselrock_wasserliesch", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2023_moselrock_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2023_moselrock_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2025_bullenhitze_show", "to": "content_shows_2025_bullenhitze_salmtal", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2025_bullenhitze_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2025_bullenhitze_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2026_highway_to_kell_show", "to": "content_shows_2026_highway_to_kell_kell", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2026_highway_to_kell_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2026_highway_to_kell_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "archetypes_default_archetype", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2026_tefftival_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows__index_shows", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2022_jukufe_light_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2022_konz_wird_laut_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2022_rock_im_gehege_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2022_tefftival_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2023_pink_future_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2024_pink_future_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2024_rock_fuer_ruanda_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2024_rock_im_gehege_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2026_luke_show", "to": "content_shows_2026_tefftival_show_front_matter_schema", "label": "implements", "title": "implements [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "claude_epk_manual_sync", "to": "epk_epk_cover_page", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_cover_page", "to": "epk_epk_show_history", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "claude_epk_manual_sync", "to": "epk_epk_live_contact_page", "label": "rationale_for", "title": "rationale_for [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_live_contact_page", "to": "epk_epk_upcoming_shows", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "epk_epk_live_contact_page", "to": "epk_epk_show_history", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_seo_jsonld_sitemap", "to": "claude_shows_content_model", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "claude_shows_content_model", "to": "epk_epk_show_history", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "claude_shows_content_model", "to": "epk_epk_upcoming_shows", "label": "shares_data_with", "title": "shares_data_with [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2022_jukufe_light_show", "to": "content_shows_2022_jukufe_light_skatehalle_trier", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows__index_shows", "to": "content_shows_2022_jukufe_light_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2023_pink_future_show", "to": "content_shows_2023_pink_future_pink_future_series", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2023_pink_future_show", "to": "content_shows_2023_pink_future_skatehalle_trier_west", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows__index_shows", "to": "content_shows_2023_pink_future_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2024_pink_future_show", "to": "content_shows_2023_pink_future_pink_future_series", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2024_pink_future_show", "to": "content_shows_2024_pink_future_palastgarten_trier", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows__index_shows", "to": "content_shows_2024_pink_future_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2023_pink_future_skatehalle_trier_west", "to": "content_shows_2022_jukufe_light_skatehalle_trier", "label": "semantically_similar_to", "title": "semantically_similar_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2022_konz_wird_laut_show", "to": "content_shows_2022_konz_wird_laut_haus_der_jugend_konz", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows__index_shows", "to": "content_shows_2022_konz_wird_laut_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2024_rock_fuer_ruanda_show", "to": "content_shows_2024_rock_fuer_ruanda_butzweiler", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows__index_shows", "to": "content_shows_2024_rock_fuer_ruanda_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2026_luke_show", "to": "content_shows_2026_luke_trier", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows__index_shows", "to": "content_shows_2026_luke_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2022_rock_im_gehege_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2022_tefftival_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2024_rock_im_gehege_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows__index_shows", "to": "content_shows_2026_tefftival_show", "label": "references", "title": "references [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}, {"from": "content_shows_2022_rock_im_gehege_show", "to": "content_shows_2022_rock_im_gehege_rock_im_gehege_series", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2022_rock_im_gehege_show", "to": "content_shows_2022_rock_im_gehege_piesbach", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2024_rock_im_gehege_show", "to": "content_shows_2022_rock_im_gehege_rock_im_gehege_series", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2024_rock_im_gehege_show", "to": "content_shows_2022_rock_im_gehege_piesbach", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2022_tefftival_show", "to": "content_shows_2022_tefftival_tefftival_series", "label": "conceptually_related_to", "title": "conceptually_related_to [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2022_tefftival_show", "to": "content_shows_2022_tefftival_tufa", "label": "references", "title": "references [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "content_shows_2026_tefftival_show", "to": "content_shows_2022_tefftival_tefftival_series", "label": "conceptually_related_to", "title": "conceptually_related_to [INFERRED]", "dashes": true, "width": 1, "color": {"opacity": 0.35}, "confidence": "INFERRED"}];
|
|
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Templates & Design", "count": 29}, {"cid": 1, "color": "#F28E2B", "label": "Band, EPK & Regeln", "count": 27}, {"cid": 2, "color": "#E15759", "label": "Gitea Deploy Workflow", "count": 18}, {"cid": 3, "color": "#76B7B2", "label": "Datenschutz & Impressum", "count": 9}, {"cid": 4, "color": "#59A14F", "label": "Show-Schema & Mosel-Gigs", "count": 8}, {"cid": 5, "color": "#EDC948", "label": "Shows \u2194 EPK Sync", "count": 7}, {"cid": 6, "color": "#B07AA1", "label": "Pink Future & Skatehalle", "count": 7}, {"cid": 7, "color": "#FF9DA7", "label": "Trierer Umland-Shows", "count": 7}, {"cid": 8, "color": "#9C755F", "label": "Rock im Gehege", "count": 4}, {"cid": 9, "color": "#BAB0AC", "label": "Tefftival", "count": 4}, {"cid": 10, "color": "#4E79A7", "label": "Album Release Party", "count": 2}, {"cid": 11, "color": "#F28E2B", "label": "Riez Kapellen-Contest", "count": 2}, {"cid": 12, "color": "#E15759", "label": "Altstadtfest Trier", "count": 2}, {"cid": 13, "color": "#76B7B2", "label": "Halloween Rock", "count": 2}, {"cid": 14, "color": "#59A14F", "label": "Deploy-Skript", "count": 2}, {"cid": 15, "color": "#EDC948", "label": "Spotify Loader (site.js)", "count": 1}, {"cid": 16, "color": "#B07AA1", "label": "EPK PDF Build", "count": 1}];
|
|
|
|
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
|
|
function esc(s) {
|
|
return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''');
|
|
}
|
|
|
|
// Build vis datasets
|
|
const nodesDS = new vis.DataSet(RAW_NODES.map((n, i) => ({
|
|
id: n.id, label: n.label, color: n.color, size: n.size,
|
|
font: n.font, title: n.title,
|
|
// Fermat/golden-angle spiral seed positions (#3699): spreading nodes out
|
|
// before physics runs keeps avoidOverlap from computing near-zero-distance
|
|
// repulsion that blows the BarnesHut recursion into a stack overflow on large
|
|
// graphs. `i` is the map index — physics still settles small graphs identically.
|
|
x: 30 * Math.sqrt(i) * Math.cos(i * 2.4),
|
|
y: 30 * Math.sqrt(i) * Math.sin(i * 2.4),
|
|
community: n.community, community_name: n.community_name,
|
|
source_file: n.source_file, file_type: n.file_type, degree: n.degree,
|
|
member_count: n.member_count,
|
|
})));
|
|
|
|
const edgesDS = new vis.DataSet(RAW_EDGES.map((e, i) => ({
|
|
id: i, from: e.from, to: e.to,
|
|
label: '',
|
|
title: e.title,
|
|
dashes: e.dashes,
|
|
width: e.width,
|
|
color: e.color,
|
|
arrows: { to: { enabled: true, scaleFactor: 0.5 } },
|
|
})));
|
|
|
|
const container = document.getElementById('graph');
|
|
const network = new vis.Network(container, { nodes: nodesDS, edges: edgesDS }, {
|
|
physics: {
|
|
enabled: true,
|
|
solver: 'forceAtlas2Based',
|
|
forceAtlas2Based: {
|
|
gravitationalConstant: -60,
|
|
centralGravity: 0.005,
|
|
springLength: 120,
|
|
springConstant: 0.08,
|
|
damping: 0.4,
|
|
avoidOverlap: 0.8,
|
|
},
|
|
stabilization: { iterations: 200, fit: true },
|
|
},
|
|
interaction: {
|
|
hover: true,
|
|
tooltipDelay: 100,
|
|
hideEdgesOnDrag: true,
|
|
navigationButtons: false,
|
|
keyboard: false,
|
|
},
|
|
nodes: { shape: 'dot', borderWidth: 1.5 },
|
|
edges: { smooth: { type: 'continuous', roundness: 0.2 }, selectionWidth: 3 },
|
|
});
|
|
|
|
// Theme toggle (#3894): Light / Dark / System, persisted in localStorage.
|
|
const THEME_KEY = 'graphify-theme';
|
|
const themeMQ = window.matchMedia ? window.matchMedia('(prefers-color-scheme: light)') : null;
|
|
let themeLabelColor = '#ffffff'; // matches the per-node font color set in Python
|
|
function themePref() {
|
|
let p = null;
|
|
try { p = localStorage.getItem(THEME_KEY); } catch (e) {}
|
|
return (p === 'light' || p === 'dark' || p === 'system') ? p : null;
|
|
}
|
|
function applyTheme(pref) {
|
|
const t = pref === 'light' ? 'light' : (pref === 'system' && themeMQ && themeMQ.matches) ? 'light' : 'dark';
|
|
const root = document.documentElement;
|
|
if (!root) return;
|
|
root.setAttribute('data-theme', t);
|
|
document.querySelectorAll('[data-theme-choice]').forEach(b => {
|
|
b.setAttribute('aria-pressed', String(b.dataset.themeChoice === (pref || 'dark')));
|
|
});
|
|
const labelColor = getComputedStyle(root).getPropertyValue('--node-label').trim();
|
|
if (labelColor && labelColor !== themeLabelColor) {
|
|
themeLabelColor = labelColor;
|
|
nodesDS.update(nodesDS.get().map(n => ({ id: n.id, font: Object.assign({}, n.font, { color: labelColor }) })));
|
|
}
|
|
}
|
|
document.querySelectorAll('[data-theme-choice]').forEach(b => {
|
|
b.addEventListener('click', () => {
|
|
const pref = b.dataset.themeChoice;
|
|
try { localStorage.setItem(THEME_KEY, pref); } catch (e) {}
|
|
applyTheme(pref);
|
|
});
|
|
});
|
|
if (themeMQ) {
|
|
const onSchemeChange = () => { if (themePref() === 'system') applyTheme('system'); };
|
|
if (themeMQ.addEventListener) themeMQ.addEventListener('change', onSchemeChange);
|
|
else if (themeMQ.addListener) themeMQ.addListener(onSchemeChange);
|
|
}
|
|
applyTheme(themePref());
|
|
|
|
network.once('stabilizationIterationsDone', () => {
|
|
network.setOptions({ physics: { enabled: false } });
|
|
});
|
|
|
|
function showInfo(nodeId) {
|
|
const n = nodesDS.get(nodeId);
|
|
if (!n) return;
|
|
const neighborIds = network.getConnectedNodes(nodeId);
|
|
const neighborItems = neighborIds.map(nid => {
|
|
const nb = nodesDS.get(nid);
|
|
const color = nb ? nb.color.background : '#555';
|
|
return `<span class="neighbor-link" style="border-left-color:${esc(color)}" data-nid="${esc(nid)}">${esc(nb ? nb.label : nid)}</span>`;
|
|
}).join('');
|
|
const isMetaNode = !n.file_type && !n.source_file;
|
|
let html = `<div class="field"><b>${esc(n.label)}</b></div>`;
|
|
if (!isMetaNode) {
|
|
html += `<div class="field">Type: ${esc(n.file_type || 'unknown')}</div>`;
|
|
}
|
|
html += `<div class="field">Community: ${esc(n.community_name || '')}</div>`;
|
|
if (!isMetaNode) {
|
|
html += `<div class="field">Source: ${esc(n.source_file || '-')}</div>`;
|
|
} else if (n.member_count !== undefined && n.member_count !== null) {
|
|
html += `<div class="field">Members: ${esc(n.member_count)}</div>`;
|
|
}
|
|
html += `<div class="field">Degree: ${n.degree}</div>`;
|
|
if (neighborIds.length) {
|
|
html += `<div class="field" style="margin-top:8px;color:var(--text-2);font-size:11px">Neighbors (${neighborIds.length})</div><div id="neighbors-list">${neighborItems}</div>`;
|
|
}
|
|
document.getElementById('info-content').innerHTML = html;
|
|
}
|
|
|
|
function focusNode(nodeId) {
|
|
network.focus(nodeId, { scale: 1.4, animation: true });
|
|
network.selectNodes([nodeId]);
|
|
showInfo(nodeId);
|
|
}
|
|
|
|
// Neighbor links use a data attribute + one delegated listener rather than an
|
|
// inline onclick. A node id/label sourced from a document or a scraped URL
|
|
// (graphify add) can contain a double-quote; dropping the stringified id
|
|
// unescaped into a quoted onclick both broke every link and allowed a hostile
|
|
// source to inject an event handler into the local report (stored XSS, #1838).
|
|
// esc() on data-nid keeps the value inside the attribute; the listener reads it
|
|
// back verbatim. Bound to document so it survives the innerHTML rebuild that
|
|
// recreates #neighbors-list on each showInfo().
|
|
document.addEventListener('click', e => {
|
|
const el = e.target.closest('.neighbor-link');
|
|
if (el && el.dataset.nid !== undefined) focusNode(el.dataset.nid);
|
|
});
|
|
|
|
// Sidebar tooltips reuse vis-network's .vis-tooltip style and 100ms tooltipDelay.
|
|
// Names get one only when CSS ellipsis truncates them (the full text is still in
|
|
// the DOM); counts always get one, to say what the number is. Text is set with
|
|
// textContent only (labels are untrusted). Delegated on document so rows rebuilt
|
|
// later (search results, showInfo()) are covered.
|
|
const sidebarTip = document.createElement('div');
|
|
sidebarTip.className = 'vis-tooltip';
|
|
sidebarTip.style.cssText = 'white-space: normal; max-width: 360px; overflow-wrap: break-word;';
|
|
document.body.appendChild(sidebarTip);
|
|
let sidebarTipTimer = null;
|
|
let sidebarTipEl = null; // element whose text the tooltip shows
|
|
let sidebarTipZone = null; // element the pointer must leave to hide it
|
|
function hideSidebarTip() {
|
|
clearTimeout(sidebarTipTimer);
|
|
sidebarTip.style.visibility = 'hidden';
|
|
sidebarTip.textContent = '';
|
|
sidebarTipEl = sidebarTipZone = null;
|
|
}
|
|
document.addEventListener('mouseover', e => {
|
|
const zone = e.target.closest && e.target.closest('.legend-count, .legend-item, .search-item, .neighbor-link');
|
|
// Anywhere on a legend row except its count (dot, checkbox, gaps, padding)
|
|
// stands for the row's name, so moving within the row never re-triggers it.
|
|
const el = zone && zone.classList.contains('legend-item') ? zone.querySelector('.legend-label') : zone;
|
|
if (!el || el === sidebarTipEl) return;
|
|
hideSidebarTip();
|
|
const isCount = el.classList.contains('legend-count');
|
|
if (!isCount && el.scrollWidth <= el.clientWidth) return;
|
|
const text = isCount ? `${el.textContent} ${el.textContent === '1' ? 'node' : 'nodes'}` : el.textContent;
|
|
sidebarTipEl = el;
|
|
sidebarTipZone = zone;
|
|
const x = e.clientX, y = e.clientY;
|
|
sidebarTipTimer = setTimeout(() => {
|
|
sidebarTip.textContent = text;
|
|
sidebarTip.style.left = sidebarTip.style.top = '0px'; // measure at full max-width
|
|
sidebarTip.style.visibility = 'visible';
|
|
const w = sidebarTip.offsetWidth, h = sidebarTip.offsetHeight;
|
|
sidebarTip.style.left = Math.max(4, Math.min(x + 12, window.innerWidth - w - 4)) + 'px';
|
|
sidebarTip.style.top = (y + 16 + h > window.innerHeight ? Math.max(4, y - h - 8) : y + 16) + 'px';
|
|
}, 100);
|
|
});
|
|
document.addEventListener('mouseout', e => {
|
|
if (sidebarTipZone && !sidebarTipZone.contains(e.relatedTarget)) hideSidebarTip();
|
|
});
|
|
// A click rebuilds or hides the row (showInfo(), search pick) without a mouseout.
|
|
document.addEventListener('mousedown', hideSidebarTip);
|
|
|
|
// Track hovered node — hover detection is more reliable than click params
|
|
let hoveredNodeId = null;
|
|
network.on('hoverNode', params => {
|
|
hoveredNodeId = params.node;
|
|
container.style.cursor = 'pointer';
|
|
});
|
|
network.on('blurNode', () => {
|
|
hoveredNodeId = null;
|
|
container.style.cursor = 'default';
|
|
});
|
|
container.addEventListener('click', () => {
|
|
if (hoveredNodeId !== null) {
|
|
showInfo(hoveredNodeId);
|
|
network.selectNodes([hoveredNodeId]);
|
|
}
|
|
});
|
|
network.on('click', params => {
|
|
if (params.nodes.length > 0) {
|
|
showInfo(params.nodes[0]);
|
|
} else if (hoveredNodeId === null) {
|
|
document.getElementById('info-content').innerHTML = '<span class="empty">Click a node to inspect it</span>';
|
|
}
|
|
});
|
|
|
|
const searchInput = document.getElementById('search');
|
|
const searchResults = document.getElementById('search-results');
|
|
searchInput.addEventListener('input', () => {
|
|
const q = searchInput.value.toLowerCase().trim();
|
|
searchResults.innerHTML = '';
|
|
if (!q) { searchResults.style.display = 'none'; return; }
|
|
const matches = RAW_NODES.filter(n => n.label.toLowerCase().includes(q)).slice(0, 20);
|
|
if (!matches.length) { searchResults.style.display = 'none'; return; }
|
|
searchResults.style.display = 'block';
|
|
matches.forEach(n => {
|
|
const el = document.createElement('div');
|
|
el.className = 'search-item';
|
|
el.textContent = n.label;
|
|
el.style.borderLeft = `3px solid ${n.color.background}`;
|
|
el.style.paddingLeft = '8px';
|
|
el.onclick = () => {
|
|
network.focus(n.id, { scale: 1.5, animation: true });
|
|
network.selectNodes([n.id]);
|
|
showInfo(n.id);
|
|
searchResults.style.display = 'none';
|
|
searchInput.value = '';
|
|
};
|
|
searchResults.appendChild(el);
|
|
});
|
|
});
|
|
document.addEventListener('click', e => {
|
|
if (!searchResults.contains(e.target) && e.target !== searchInput)
|
|
searchResults.style.display = 'none';
|
|
});
|
|
|
|
const hiddenCommunities = new Set();
|
|
|
|
const selectAllCb = document.getElementById('select-all-cb');
|
|
|
|
function updateSelectAllState() {
|
|
const total = LEGEND.length;
|
|
const hidden = hiddenCommunities.size;
|
|
selectAllCb.checked = hidden === 0;
|
|
selectAllCb.indeterminate = hidden > 0 && hidden < total;
|
|
}
|
|
|
|
function toggleAllCommunities(hide) {
|
|
document.querySelectorAll('.legend-item').forEach(item => {
|
|
hide ? item.classList.add('dimmed') : item.classList.remove('dimmed');
|
|
});
|
|
document.querySelectorAll('.legend-cb').forEach(cb => {
|
|
cb.checked = !hide;
|
|
});
|
|
LEGEND.forEach(c => {
|
|
if (hide) hiddenCommunities.add(c.cid); else hiddenCommunities.delete(c.cid);
|
|
});
|
|
const updates = RAW_NODES.map(n => ({ id: n.id, hidden: hide }));
|
|
nodesDS.update(updates);
|
|
updateSelectAllState();
|
|
}
|
|
|
|
const legendEl = document.getElementById('legend');
|
|
LEGEND.forEach(c => {
|
|
const item = document.createElement('div');
|
|
item.className = 'legend-item';
|
|
const cb = document.createElement('input');
|
|
cb.type = 'checkbox';
|
|
cb.className = 'legend-cb';
|
|
cb.checked = true;
|
|
cb.addEventListener('change', (e) => {
|
|
e.stopPropagation();
|
|
if (cb.checked) {
|
|
hiddenCommunities.delete(c.cid);
|
|
item.classList.remove('dimmed');
|
|
} else {
|
|
hiddenCommunities.add(c.cid);
|
|
item.classList.add('dimmed');
|
|
}
|
|
const updates = RAW_NODES
|
|
.filter(n => n.community === c.cid)
|
|
.map(n => ({ id: n.id, hidden: !cb.checked }));
|
|
nodesDS.update(updates);
|
|
updateSelectAllState();
|
|
});
|
|
item.innerHTML = `<div class="legend-dot" style="background:${c.color}"></div>
|
|
<span class="legend-label">${c.label}</span>
|
|
<span class="legend-count">${c.count}</span>`;
|
|
item.prepend(cb);
|
|
item.onclick = (e) => {
|
|
if (e.target === cb) return;
|
|
cb.checked = !cb.checked;
|
|
cb.dispatchEvent(new Event('change'));
|
|
};
|
|
legendEl.appendChild(item);
|
|
});
|
|
</script>
|
|
<script>
|
|
// Render hyperedges as shaded regions
|
|
const hyperedges = [{"id": "epk_four_page_layout", "label": "EPK four A4 pages", "nodes": ["epk_epk_cover_page", "epk_epk_bio_page", "epk_epk_band_music_page", "epk_epk_live_contact_page"], "relation": "form", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "epk/epk.html"}, {"id": "release_data_pipeline", "label": "Release cover filename parsing feeding music page and album schema", "nodes": ["layouts_partials_releases", "layouts_partials_releases_filename_convention", "layouts_music_list", "layouts_partials_schema_musicgroup"], "relation": "form", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "layouts/partials/releases.html"}, {"id": "privacy_by_design_choices", "label": "Privacy-conscious site choices (local fonts, click-to-load Spotify, DSGVO)", "nodes": ["content_datenschutz_local_fonts", "content_datenschutz_spotify_click_to_load", "content_datenschutz_dsgvo_rights", "content_datenschutz_hosting_1blu"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "content/Datenschutz.md"}, {"id": "seo_layer", "label": "SEO layer (meta tags, JSON-LD, robots, show redirects)", "nodes": ["layouts__default_baseof_seo_meta", "layouts_partials_schema", "layouts_robots", "layouts_shows_single"], "relation": "form", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "layouts/_default/baseof.html"}, {"id": "trier_city_shows", "label": "Shows in the city of Trier", "nodes": ["content_shows_2022_jukufe_light_show", "content_shows_2023_pink_future_show", "content_shows_2024_pink_future_show", "content_shows_2025_album_release_party_show", "content_shows_2026_altstadtfest_trier_show", "content_shows_2026_luke_show"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "content/shows/_index.md"}, {"id": "upcoming_shows_2026", "label": "Upcoming shows after 2026-10-30 (EPK 'N\u00e4chste Shows')", "nodes": ["content_shows_2026_halloween_show", "content_shows_2026_tefftival_show", "content_shows__index_shows"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "content/shows/_index.md"}, {"id": "epk_website_manual_sync_flow", "label": "Website content manually mirrored into EPK", "nodes": ["claude_epk_manual_sync", "content__index_band_bio", "content_about_members", "content_music__index_music_page", "epk_epk_document"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "CLAUDE.md"}, {"id": "show_rendering_flow", "label": "Show listing rendering (home, shows page, card, JSON-LD events)", "nodes": ["layouts_index", "layouts_shows_list", "layouts_partials_show_card", "layouts_partials_schema_musicevent"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "layouts/shows/list.html"}];
|
|
// afterDrawing passes ctx already transformed to network coordinate space.
|
|
// Draw node positions raw — no manual pan/zoom/DPR math needed.
|
|
|
|
// Andrew's monotone chain. Returns the hull in counter-clockwise order, which
|
|
// is what the perimeter must be traced in. Collinear and duplicate points
|
|
// collapse to the extremes, so degenerate member sets render as a segment
|
|
// rather than a zero-area crossed path.
|
|
function convexHull(pts) {
|
|
const p = pts.slice().sort((a, b) => (a.x - b.x) || (a.y - b.y));
|
|
if (p.length < 3) return p;
|
|
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
|
const build = seq => {
|
|
const out = [];
|
|
for (const q of seq) {
|
|
while (out.length >= 2 && cross(out[out.length - 2], out[out.length - 1], q) <= 0) out.pop();
|
|
out.push(q);
|
|
}
|
|
out.pop();
|
|
return out;
|
|
};
|
|
const hull = build(p).concat(build(p.slice().reverse()));
|
|
return hull.length >= 3 ? hull : p;
|
|
}
|
|
network.on('afterDrawing', function(ctx) {
|
|
hyperedges.forEach(h => {
|
|
const positions = h.nodes
|
|
.map(nid => network.getPositions([nid])[nid])
|
|
.filter(p => p !== undefined);
|
|
if (positions.length < 2) return;
|
|
ctx.save();
|
|
ctx.globalAlpha = 0.12;
|
|
ctx.fillStyle = '#6366f1';
|
|
ctx.strokeStyle = '#6366f1';
|
|
ctx.lineWidth = 2;
|
|
ctx.beginPath();
|
|
// Centroid and expanded hull in network coordinates.
|
|
// The perimeter must follow hull order, not h.nodes order: tracing the
|
|
// raw member order self-intersects whenever the layout does not happen
|
|
// to place members in angular order, filling as crossed wedges.
|
|
const cx = positions.reduce((s, p) => s + p.x, 0) / positions.length;
|
|
const cy = positions.reduce((s, p) => s + p.y, 0) / positions.length;
|
|
const hull = convexHull(positions);
|
|
const expanded = hull.map(p => ({
|
|
x: cx + (p.x - cx) * 1.15,
|
|
y: cy + (p.y - cy) * 1.15
|
|
}));
|
|
ctx.moveTo(expanded[0].x, expanded[0].y);
|
|
expanded.slice(1).forEach(p => ctx.lineTo(p.x, p.y));
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
ctx.globalAlpha = 0.4;
|
|
ctx.stroke();
|
|
// Label
|
|
ctx.globalAlpha = 0.8;
|
|
ctx.fillStyle = '#4f46e5';
|
|
ctx.font = 'bold 11px sans-serif';
|
|
ctx.textAlign = 'center';
|
|
ctx.fillText(h.label, cx, cy - 5);
|
|
ctx.restore();
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |