-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexplore.html
More file actions
102 lines (97 loc) · 5.26 KB
/
Copy pathexplore.html
File metadata and controls
102 lines (97 loc) · 5.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Tree of Knowledge — Interactive Primer</title>
<meta
name="description"
content="The whole Interactive Primer tree of knowledge as one interactive graph — every concept and how they build on each other. Drag to rearrange, click a node to open the lesson."
/>
<link rel="icon" href="/images/icons/favicon.ico" sizes="any" />
<link rel="icon" type="image/png" sizes="32x32" href="/images/icons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/images/icons/favicon-16x16.png" />
<link rel="apple-touch-icon" href="/images/icons/apple-touch-icon.png" />
<link rel="apple-touch-startup-image" href="/images/banner-portrait.jpg" />
<link rel="manifest" href="/site.webmanifest" />
<meta name="theme-color" content="#f8f4ec" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="InteractivePrimer.com" />
<link rel="canonical" href="https://interactiveprimer.com/explore" />
<!-- Shared synchronous pre-paint: theme + locale, before the stylesheet (built from src/prepaint.ts). -->
<script src="/dist/prepaint.js"></script>
<link rel="stylesheet" href="/dist/assets/stix.css" />
<link rel="stylesheet" href="/css/primer.css" />
<!-- Cookieless visitor analytics (Cloudflare Web Analytics) — no cookie banner needed. -->
<script src="/dist/analytics.js" defer></script>
<!-- KaTeX glyph CSS for the math titles the tree map typesets (<primer-math> in a <foreignObject>).
The framework JS + deps come from the built app bundle, imported below via the asset manifest. -->
<link rel="stylesheet" href="/dist/assets/katex.min.css" />
<style>
html, body { height: 100%; }
body { margin: 0; background: var(--primer-bg, #fff); }
/* The graph fills the whole viewport; the search box (top-left) and hamburger (top-right)
float over it. */
#cg-host { position: fixed; inset: 0; }
/* Loading / error text, centred over the otherwise-empty canvas. */
.cg-loading {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
margin: 0; text-align: center; padding: 1.1rem;
font-family: var(--primer-font-ui, sans-serif); color: var(--primer-ink-soft, #667);
}
</style>
</head>
<body>
<a class="skip-link" href="#main">Skip to main content</a>
<main id="main" tabindex="-1">
<h1 class="sr-only">Tree of Knowledge — every concept and how they build on each other</h1>
<div id="cg-host"><p class="cg-loading" role="status" aria-live="polite">Loading the tree…</p></div>
</main>
<script type="module">
// Framework from the built app bundle (hashed URL via the asset manifest) — no import map.
const { app } = await (await fetch("/dist/asset-manifest.json")).json();
const { initTheme, initLocale, getLocale, loadGraph, mountConceptGraph, runProgressMigration, offline } =
await import(app);
offline.registerServiceWorker();
initTheme();
initLocale();
document.body.appendChild(document.createElement("primer-menu"));
// An optional ?id=<concept> centres the map on that concept (the fixed/bold node) instead
// of root — e.g. the "Explore" item in a lesson's pathway links here. Kept in the URL as
// shareable view state (unlike ?lang=, which is stripped).
const focusId = new URLSearchParams(location.search).get("id") || undefined;
const host = /** @type {HTMLElement} */ (document.getElementById("cg-host"));
loadGraph()
.then(async ({ byId }) => {
// Re-key any confidence scores stranded by a moved concept before the graph paints node
// colours from them (runs once; uses the same memoized graph).
await runProgressMigration();
host.replaceChildren();
// A nicer browser-tab title when focused on a specific concept.
const focused = focusId && byId.get(focusId);
if (focused) {
const title = focused.titles?.[getLocale()] ?? focused.title ?? focusId;
document.title = `${title} — Tree of Knowledge`;
}
let handle = mountConceptGraph(host, { byId, locale: getLocale(), focusId });
// Entering or leaving a course re-scopes the graph (members + ancestors only, members
// tinted). Rebuild in place so an "Exit course" from the menu reflows the whole tree.
document.addEventListener("course-change", () => {
handle.destroy();
host.replaceChildren();
handle = mountConceptGraph(host, { byId, locale: getLocale(), focusId });
});
})
.catch((err) => {
host.replaceChildren();
const p = document.createElement("p");
p.className = "cg-loading";
p.textContent = "Couldn't load the tree. Run `npm run graph`, then reload.";
host.appendChild(p);
console.error("concept graph:", err);
});
</script>
</body>
</html>