Skip to content

Commit a5623f2

Browse files
deploy: 1e9d99f
1 parent dcca7c0 commit a5623f2

6 files changed

Lines changed: 370 additions & 970 deletions

File tree

.doctrees/environment.pickle

31 Bytes
Binary file not shown.

_modules/index.html

Lines changed: 74 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -281,179 +281,13 @@ <h1>All modules for which code is available</h1>
281281
import elkLayouts from "https://cdn.jsdelivr.net/npm/@mermaid-js/layout-elk@0.2.0/dist/mermaid-layout-elk.esm.min.mjs"
282282

283283

284-
285-
import zenumlLayouts from "https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-zenuml@0.2.2/dist/mermaid-zenuml.esm.min.mjs"
286-
287-
288284
const initStyles = () => {
289285
const defaultStyle = document.createElement('style');
290-
defaultStyle.textContent = `pre.mermaid {
291-
/* Same as .mermaid-container > pre */
292-
display: block;
293-
width: 100%;
294-
}
295-
296-
pre.mermaid > svg {
297-
/* Same as .mermaid-container > pre > svg */
298-
height: 500px;
299-
width: 100%;
300-
max-width: 100% !important;
301-
}`;
286+
defaultStyle.textContent = "pre.mermaid {\n /* Same as .mermaid-container > pre */\n display: block;\n width: 100%;\n}\n\npre.mermaid > svg {\n /* Same as .mermaid-container > pre > svg */\n height: 500px;\n width: 100%;\n max-width: 100% !important;\n}";
302287
document.head.appendChild(defaultStyle);
303288

304289
const fullscreenStyle = document.createElement('style');
305-
fullscreenStyle.textContent = `.mermaid-container {
306-
display: flex;
307-
flex-direction: row;
308-
width: 100%;
309-
}
310-
311-
.mermaid-container > pre {
312-
display: block;
313-
width: 100%;
314-
}
315-
316-
.mermaid-container > pre > svg {
317-
height: 500px;
318-
width: 100%;
319-
max-width: 100% !important;
320-
}
321-
322-
.mermaid-fullscreen-btn {
323-
width: 28px;
324-
height: 28px;
325-
background: rgba(255, 255, 255, 0.95);
326-
border: 1px solid rgba(0, 0, 0, 0.3);
327-
border-radius: 4px;
328-
cursor: pointer;
329-
display: flex;
330-
align-items: center;
331-
justify-content: center;
332-
transition: all 0.2s;
333-
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
334-
font-size: 14px;
335-
line-height: 1;
336-
padding: 0;
337-
color: #333;
338-
}
339-
340-
.mermaid-fullscreen-btn:hover {
341-
opacity: 100% !important;
342-
background: rgba(255, 255, 255, 1);
343-
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
344-
transform: scale(1.1);
345-
}
346-
347-
.mermaid-fullscreen-btn.dark-theme {
348-
background: rgba(50, 50, 50, 0.95);
349-
border: 1px solid rgba(255, 255, 255, 0.3);
350-
color: #e0e0e0;
351-
}
352-
353-
.mermaid-fullscreen-btn.dark-theme:hover {
354-
background: rgba(60, 60, 60, 1);
355-
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
356-
}
357-
358-
.mermaid-fullscreen-modal {
359-
display: none;
360-
position: fixed !important;
361-
top: 0 !important;
362-
left: 0 !important;
363-
width: 95vw;
364-
height: 100vh;
365-
background: rgba(255, 255, 255, 0.98);
366-
z-index: 9999;
367-
padding: 20px;
368-
overflow: auto;
369-
}
370-
371-
.mermaid-fullscreen-modal.dark-theme {
372-
background: rgba(0, 0, 0, 0.98);
373-
}
374-
375-
.mermaid-fullscreen-modal.active {
376-
display: flex;
377-
align-items: center;
378-
justify-content: center;
379-
}
380-
381-
.mermaid-container-fullscreen {
382-
position: relative;
383-
width: 95vw;
384-
height: 90vh;
385-
max-width: 95vw;
386-
max-height: 90vh;
387-
background: white;
388-
border-radius: 8px;
389-
padding: 20px;
390-
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
391-
overflow: auto;
392-
display: flex;
393-
align-items: center;
394-
justify-content: center;
395-
}
396-
397-
.mermaid-container-fullscreen.dark-theme {
398-
background: #1a1a1a;
399-
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
400-
}
401-
402-
.mermaid-container-fullscreen pre.mermaid {
403-
width: 100%;
404-
height: 100%;
405-
display: flex;
406-
align-items: center;
407-
justify-content: center;
408-
}
409-
410-
.mermaid-container-fullscreen .mermaid svg {
411-
height: 100% !important;
412-
width: 100% !important;
413-
cursor: grab;
414-
}
415-
416-
.mermaid-fullscreen-close {
417-
position: fixed !important;
418-
top: 20px !important;
419-
right: 20px !important;
420-
width: 40px;
421-
height: 40px;
422-
background: rgba(255, 255, 255, 0.95);
423-
border: 1px solid rgba(0, 0, 0, 0.2);
424-
border-radius: 50%;
425-
cursor: pointer;
426-
z-index: 10000;
427-
display: flex;
428-
align-items: center;
429-
justify-content: center;
430-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
431-
transition: all 0.2s;
432-
font-size: 24px;
433-
line-height: 1;
434-
color: #333;
435-
}
436-
437-
.mermaid-fullscreen-close:hover {
438-
background: white;
439-
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
440-
transform: scale(1.1);
441-
}
442-
443-
.mermaid-fullscreen-close.dark-theme {
444-
background: rgba(50, 50, 50, 0.95);
445-
border: 1px solid rgba(255, 255, 255, 0.2);
446-
color: #e0e0e0;
447-
}
448-
449-
.mermaid-fullscreen-close.dark-theme:hover {
450-
background: rgba(60, 60, 60, 1);
451-
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
452-
}
453-
454-
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
455-
display: none !important;
456-
}`;
290+
fullscreenStyle.textContent = ".mermaid-container {\n position: relative;\n display: flex;\n flex-direction: row;\n width: 100%;\n}\n\n.mermaid-container > pre {\n display: block;\n width: 100%;\n}\n\n.mermaid-container > pre > svg {\n height: 500px;\n width: 100%;\n max-width: 100% !important;\n}\n\n.mermaid-fullscreen-btn {\n position: absolute;\n width: 28px;\n height: 28px;\n background: rgba(255, 255, 255, 0.95);\n border: 1px solid rgba(0, 0, 0, 0.3);\n border-radius: 4px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n font-size: 14px;\n line-height: 1;\n padding: 0;\n color: #333;\n}\n\n.mermaid-fullscreen-btn:hover {\n opacity: 100% !important;\n background: rgba(255, 255, 255, 1);\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);\n transform: scale(1.1);\n}\n\n.mermaid-fullscreen-btn.dark-theme {\n background: rgba(50, 50, 50, 0.95);\n border: 1px solid rgba(255, 255, 255, 0.3);\n color: #e0e0e0;\n}\n\n.mermaid-fullscreen-btn.dark-theme:hover {\n background: rgba(60, 60, 60, 1);\n box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);\n}\n\n.mermaid-fullscreen-modal {\n display: none;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n width: 95vw;\n height: 100vh;\n background: rgba(255, 255, 255, 0.98);\n z-index: 9999;\n padding: 20px;\n overflow: auto;\n}\n\n.mermaid-fullscreen-modal.dark-theme {\n background: rgba(0, 0, 0, 0.98);\n}\n\n.mermaid-fullscreen-modal.active {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.mermaid-container-fullscreen {\n position: relative;\n width: 95vw;\n height: 90vh;\n max-width: 95vw;\n max-height: 90vh;\n background: white;\n border-radius: 8px;\n padding: 20px;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);\n overflow: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.mermaid-container-fullscreen.dark-theme {\n background: #1a1a1a;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);\n}\n\n.mermaid-container-fullscreen pre.mermaid {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.mermaid-container-fullscreen .mermaid svg {\n height: 100% !important;\n width: 100% !important;\n cursor: grab;\n}\n\n.mermaid-fullscreen-close {\n position: fixed !important;\n top: 20px !important;\n right: 20px !important;\n width: 40px;\n height: 40px;\n background: rgba(255, 255, 255, 0.95);\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 50%;\n cursor: pointer;\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n transition: all 0.2s;\n font-size: 24px;\n line-height: 1;\n color: #333;\n}\n\n.mermaid-fullscreen-close:hover {\n background: white;\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);\n transform: scale(1.1);\n}\n\n.mermaid-fullscreen-close.dark-theme {\n background: rgba(50, 50, 50, 0.95);\n border: 1px solid rgba(255, 255, 255, 0.2);\n color: #e0e0e0;\n}\n\n.mermaid-fullscreen-close.dark-theme:hover {\n background: rgba(60, 60, 60, 1);\n box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);\n}\n\n.mermaid-fullscreen-modal .mermaid-fullscreen-btn {\n display: none !important;\n}";
457291
document.head.appendChild(fullscreenStyle);
458292
}
459293

@@ -500,6 +334,13 @@ <h1>All modules for which code is available</h1>
500334
let previousScrollOffset = [window.scrollX, window.scrollY];
501335
let _lazyObserver = null;
502336
let _renderQueue = Promise.resolve();
337+
let closeModal = () => {};
338+
339+
document.addEventListener('keydown', (e) => {
340+
if (e.key === 'Escape' && modal?.classList.contains('active')) {
341+
closeModal();
342+
}
343+
});
503344

504345
// Apply d3 zoom to each SVG. Idempotent: an SVG already wrapped is skipped,
505346
// so this is safe to call both for the initial batch and for diagrams that
@@ -596,8 +437,10 @@ <h1>All modules for which code is available</h1>
596437
el.removeAttribute('data-mermaid-deferred');
597438
// Apply zoom to the now-rendered diagram, matching
598439
// the decoration visible diagrams receive.
599-
if ("True" === "True") {
600-
addZoomToSvgs(d3.selectAll(".mermaid svg"));
440+
if (true) {
441+
addZoomToSvgs(d3.selectAll(".mermaid").select(function() {
442+
return this.querySelector("svg");
443+
}));
601444
}
602445
} catch (e) {
603446
console.error("Mermaid deferred rendering failed:", e);
@@ -618,10 +461,12 @@ <h1>All modules for which code is available</h1>
618461
const mermaids_active = document.querySelectorAll(".mermaid:not([data-mermaid-deferred]):not([data-mermaid-render-failed])");
619462
const mermaids_processed = document.querySelectorAll(".mermaid:not([data-mermaid-deferred]):not([data-mermaid-render-failed])[data-processed='true']");
620463

621-
if ("True" === "True") {
464+
if (true) {
622465
const mermaids_to_add_zoom = -1 === -1 ? mermaids_active.length : -1;
623466
if(mermaids_to_add_zoom > 0) {
624-
var svgs = d3.selectAll(".mermaid svg");
467+
var svgs = d3.selectAll(".mermaid").select(function() {
468+
return this.querySelector("svg");
469+
});
625470
// Wait until every active (visible) diagram has rendered. Deferred
626471
// diagrams are excluded, so a fixed d3_node_count that counts a
627472
// hidden diagram no longer loops forever waiting for its SVG.
@@ -638,7 +483,7 @@ <h1>All modules for which code is available</h1>
638483
}
639484

640485
// Stop here if not adding fullscreen capability
641-
if ("True" !== "True") return;
486+
if (!true) return;
642487

643488
if (modal !== null ) {
644489
// Destroy existing modal
@@ -661,7 +506,7 @@ <h1>All modules for which code is available</h1>
661506
modalContent = modal.querySelector('.mermaid-container-fullscreen');
662507
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
663508

664-
const closeModal = () => {
509+
closeModal = () => {
665510
modal.classList.remove('active');
666511
modalContent.innerHTML = '';
667512
document.body.style.overflow = ''
@@ -672,12 +517,6 @@ <h1>All modules for which code is available</h1>
672517
modal.addEventListener('click', (e) => {
673518
if (e.target === modal) closeModal();
674519
});
675-
document.addEventListener('keydown', (e) => {
676-
if (e.key === 'Escape' && modal.classList.contains('active')) {
677-
closeModal();
678-
}
679-
});
680-
681520
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
682521
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
683522
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
@@ -697,8 +536,8 @@ <h1>All modules for which code is available</h1>
697536
const fullscreenBtn = document.createElement('button');
698537
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
699538
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
700-
fullscreenBtn.textContent = '⛶';
701-
fullscreenBtn.style.opacity = '50%';
539+
fullscreenBtn.textContent = "\u26f6";
540+
fullscreenBtn.style.opacity = "50%";
702541

703542
// Calculate dynamic position based on diagram's margin and padding
704543
const diagramStyle = window.getComputedStyle(mermaidDiv);
@@ -710,7 +549,7 @@ <h1>All modules for which code is available</h1>
710549
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
711550

712551
fullscreenBtn.addEventListener('click', () => {
713-
previousScrollOffset = [window.scroll, window.scrollY];
552+
previousScrollOffset = [window.scrollX, window.scrollY];
714553
const clone = mermaidDiv.cloneNode(true);
715554
modalContent.innerHTML = '';
716555
modalContent.appendChild(clone);
@@ -722,9 +561,9 @@ <h1>All modules for which code is available</h1>
722561
svg.style.width = '100%';
723562
svg.style.height = 'auto';
724563
svg.style.maxWidth = '100%';
725-
svg.style.sdisplay = 'block';
564+
svg.style.display = 'block';
726565

727-
if ("True" === "True") {
566+
if (true) {
728567
setTimeout(() => {
729568
const g = svg.querySelector('g');
730569
if (g) {
@@ -747,9 +586,27 @@ <h1>All modules for which code is available</h1>
747586
});
748587
};
749588

589+
590+
// Resolves once the lazily-loaded zenuml plugin has registered (or immediately
591+
// when the page has no zenuml diagram). `load` awaits this before rendering.
592+
let zenumlReady = Promise.resolve();
593+
const pageHasZenuml = () => [...document.querySelectorAll(".mermaid")].some((el) => {
594+
const code = el.getAttribute("data-original-code") || el.textContent || "";
595+
const diagram = code
596+
.replace(/^\s*---\s*\n[^]*?\n---\s*/, "")
597+
.replace(/^\s*%%\{[^]*?\}%%\s*/, "");
598+
return /^\s*zenuml\b/i.test(diagram);
599+
});
600+
601+
750602
const load = async () => {
751603
initStyles();
752604

605+
606+
// Wait for the zenuml plugin (loaded lazily below) to finish registering
607+
// before rendering, so zenuml diagrams are recognised.
608+
await zenumlReady;
609+
753610
await runMermaid(true);
754611

755612
const reRunIfThemeChanges = async () => {
@@ -758,10 +615,8 @@ <h1>All modules for which code is available</h1>
758615
darkTheme = newDarkTheme;
759616
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
760617
await mermaid.initialize(
761-
{...JSON.parse(
762-
`{"startOnLoad": false}`
763-
),
764-
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
618+
{...{"startOnLoad": false},
619+
...{ darkMode: darkTheme, theme: darkTheme ? "dark" : "default" },
765620
}
766621
);
767622
await runMermaid(true);
@@ -785,15 +640,40 @@ <h1>All modules for which code is available</h1>
785640

786641

787642

788-
mermaid.registerExternalDiagrams([zenumlLayouts]);
643+
// Only load and register the zenuml plugin when the page actually contains a
644+
// zenuml diagram. This avoids fetching the (large) zenuml bundle on every page,
645+
// and avoids its side effects where they are not needed. The import is kept off
646+
// the module's top level (no top-level await) so the "load" listener below is
647+
// still registered synchronously; `load` awaits `zenumlReady` before rendering.
648+
if (pageHasZenuml()) {
649+
// The zenuml bundle injects a stylesheet that declares generic design tokens
650+
// (--background, --border, --white, ...) on :root, clobbering identically-named
651+
// tokens in the host theme (sphinxawesome, shibuya, ...) and causing a flash of
652+
// restyled page content. Confine those declarations to the zenuml diagram
653+
// subtree so they no longer leak onto the host page.
654+
const descopeZenumlStyle = (node) => {
655+
if (!node || node.tagName !== "STYLE" || node.hasAttribute("data-zenuml-descoped")) return;
656+
const css = node.textContent || "";
657+
if (!css.includes("--occurance-border")) return; // zenuml stylesheet signature
658+
node.setAttribute("data-zenuml-descoped", "true");
659+
node.textContent = css.replace(/:root\b/g, ".zenuml");
660+
};
661+
new MutationObserver((records) => {
662+
for (const rec of records) {
663+
for (const node of rec.addedNodes) descopeZenumlStyle(node);
664+
}
665+
}).observe(document.head, { childList: true });
666+
667+
zenumlReady = import("https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-zenuml@0.2.2/dist/mermaid-zenuml.esm.min.mjs").then(({ default: zenumlLayouts }) => {
668+
mermaid.registerExternalDiagrams([zenumlLayouts]);
669+
});
670+
}
789671

790672

791673
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
792674
mermaid.initialize(
793-
{...JSON.parse(
794-
`{"startOnLoad": false}`
795-
),
796-
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
675+
{...{"startOnLoad": false},
676+
...{ darkMode: darkTheme, theme: darkTheme ? "dark" : "default" },
797677
}
798678
);
799679

0 commit comments

Comments
 (0)