mirror of
https://github.com/tt-a1i/archify.git
synced 2026-09-28 15:04:37 +08:00
Lifecycle diagrams generated from real repositories looked tangled: lower bands used a column grid offset from the main rail, fixed 36px gaps could not hold reciprocal transitions or labels, the implied rail doubled authored main transitions, and the runtime source badge sat on the lifecycle sigil. Schema v2 renders one row per lane on a shared column grid with a dedicated orthogonal router, adaptive gaps, and vertical row headers. Start and final states get UML marks explained by the legend, decision no longer shares the failure color, and label layout reserves the source badge. Schema v1 keeps its exact state geometry. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1436 lines
163 KiB
HTML
1436 lines
163 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" data-theme="dark" data-preset="[VISUAL PRESET]">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="generator" content="archify 2.17.0-dev.1">
|
|
<meta name="archify-reader-contract" content="declared-wide-v1">
|
|
<title>[PROJECT NAME] Architecture Diagram</title>
|
|
<script>
|
|
// Resolve the theme before first paint so light-preference users don't
|
|
// see a dark flash. The toolbar script below re-applies with UI state.
|
|
(function () {
|
|
try {
|
|
var theme = null;
|
|
try {
|
|
var param = new URLSearchParams(window.location.search).get('theme');
|
|
if (param === 'light' || param === 'dark') theme = param;
|
|
if (new URLSearchParams(window.location.search).get('embed') === '1') {
|
|
document.documentElement.setAttribute('data-embed', 'true');
|
|
}
|
|
if (new URLSearchParams(window.location.search).get('present') === '1') {
|
|
document.documentElement.setAttribute('data-present', 'true');
|
|
}
|
|
} catch (_) {}
|
|
if (!theme) {
|
|
try { theme = localStorage.getItem('archify-theme'); } catch (_) {}
|
|
}
|
|
if (theme !== 'light' && theme !== 'dark') {
|
|
theme = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
|
}
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
} catch (_) {}
|
|
})();
|
|
</script>
|
|
<style id="archify-fonts">
|
|
/*
|
|
JetBrains Mono variable WOFF2 subsets from Google Fonts service revision v24.
|
|
These fixed bytes are shared by the viewer and its SVG/raster exports.
|
|
No local() source: an installed copy must not override the bundled font.
|
|
Uncovered characters (including CJK) still use the system fallback stack.
|
|
Upstream: https://github.com/JetBrains/JetBrainsMono
|
|
|
|
cyrillic-ext 1664 bytes sha256 9343de2ca5d9549f792e7962375af8efb0f320c7643bfd36c884b5a30e5c396f
|
|
cyrillic 8892 bytes sha256 4995a9a43ac659ec32fcd8b463755cd6a07b31a6e6b3894a6a153b661cf490e2
|
|
greek 6800 bytes sha256 49c3da6c9a2b279b0f1f860f5cfb1f5dc38d88a5c7be9c9b1837bbc4e3db6111
|
|
vietnamese 5872 bytes sha256 d44eb1936043a56038eb02dd70b243f379bef65783f94ec12f277550720411f1
|
|
latin-ext 11596 bytes sha256 9c38cb2d0d2d93c1ee6e21fa78db76f13ea7e15e15cc64214c7ca89b6aaa35c4
|
|
latin 31340 bytes sha256 2c32b9b3ee358c119e210f6f5195f9bd34894d78a785ff2e95d60e718e400af4
|
|
|
|
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
|
|
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
This license is copied below, and is also available with a FAQ at:
|
|
https://openfontlicense.org
|
|
|
|
|
|
-----------------------------------------------------------
|
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
-----------------------------------------------------------
|
|
|
|
PREAMBLE
|
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
development of collaborative font projects, to support the font creation
|
|
efforts of academic and linguistic communities, and to provide a free and
|
|
open framework in which fonts may be shared and improved in partnership
|
|
with others.
|
|
|
|
The OFL allows the licensed fonts to be used, studied, modified and
|
|
redistributed freely as long as they are not sold by themselves. The
|
|
fonts, including any derivative works, can be bundled, embedded,
|
|
redistributed and/or sold with any software provided that any reserved
|
|
names are not used by derivative works. The fonts and derivatives,
|
|
however, cannot be released under any other type of license. The
|
|
requirement for fonts to remain under this license does not apply
|
|
to any document created using the fonts or their derivatives.
|
|
|
|
DEFINITIONS
|
|
"Font Software" refers to the set of files released by the Copyright
|
|
Holder(s) under this license and clearly marked as such. This may
|
|
include source files, build scripts and documentation.
|
|
|
|
"Reserved Font Name" refers to any names specified as such after the
|
|
copyright statement(s).
|
|
|
|
"Original Version" refers to the collection of Font Software components as
|
|
distributed by the Copyright Holder(s).
|
|
|
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
or substituting -- in part or in whole -- any of the components of the
|
|
Original Version, by changing formats or by porting the Font Software to a
|
|
new environment.
|
|
|
|
"Author" refers to any designer, engineer, programmer, technical
|
|
writer or other person who contributed to the Font Software.
|
|
|
|
PERMISSION & CONDITIONS
|
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
redistribute, and sell modified and unmodified copies of the Font
|
|
Software, subject to the following conditions:
|
|
|
|
1) Neither the Font Software nor any of its individual components,
|
|
in Original or Modified Versions, may be sold by itself.
|
|
|
|
2) Original or Modified Versions of the Font Software may be bundled,
|
|
redistributed and/or sold with any software, provided that each copy
|
|
contains the above copyright notice and this license. These can be
|
|
included either as stand-alone text files, human-readable headers or
|
|
in the appropriate machine-readable metadata fields within text or
|
|
binary files as long as those fields can be easily viewed by the user.
|
|
|
|
3) No Modified Version of the Font Software may use the Reserved Font
|
|
Name(s) unless explicit written permission is granted by the corresponding
|
|
Copyright Holder. This restriction only applies to the primary font name as
|
|
presented to the users.
|
|
|
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
Software shall not be used to promote, endorse or advertise any
|
|
Modified Version, except to acknowledge the contribution(s) of the
|
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
permission.
|
|
|
|
5) The Font Software, modified or unmodified, in part or in whole,
|
|
must be distributed entirely under this license, and must not be
|
|
distributed under any other license. The requirement for fonts to
|
|
remain under this license does not apply to any document created
|
|
using the Font Software.
|
|
|
|
TERMINATION
|
|
This license becomes null and void if any of the above conditions are
|
|
not met.
|
|
|
|
DISCLAIMER
|
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
*/
|
|
/* cyrillic-ext */
|
|
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400 800; font-display: swap;
|
|
src: url(data:font/woff2;base64,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) format('woff2');
|
|
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
|
|
/* cyrillic */
|
|
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400 800; font-display: swap;
|
|
src: url(data:font/woff2;base64,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) format('woff2');
|
|
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
|
|
/* greek */
|
|
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400 800; font-display: swap;
|
|
src: url(data:font/woff2;base64,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) format('woff2');
|
|
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; }
|
|
/* vietnamese */
|
|
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400 800; font-display: swap;
|
|
src: url(data:font/woff2;base64,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) format('woff2');
|
|
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; }
|
|
/* latin-ext */
|
|
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400 800; font-display: swap;
|
|
src: url(data:font/woff2;base64,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) format('woff2');
|
|
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
|
|
/* latin */
|
|
@font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400 800; font-display: swap;
|
|
src: url(data:font/woff2;base64,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) format('woff2');
|
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
|
|
</style>
|
|
<style>
|
|
/* ARCHIFY:VIEWER_CSS */
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Toolbar: theme, live visual style, trace motion, presentation stage, and export.
|
|
Motion appears only for trace-enabled artifacts and has no shortcut;
|
|
Keyboard: T toggles theme, S cycles style, F toggles the stage, E opens export. -->
|
|
<div class="toolbar" role="toolbar" aria-label="{{i18n:viewer.toolbar.actions}}">
|
|
<div class="toolbar-group">
|
|
<button id="btn-theme" type="button"
|
|
title="{{i18n:viewer.theme.toggle.title}}"
|
|
aria-label="{{i18n:viewer.theme.toggle}}"
|
|
aria-pressed="false">
|
|
<span id="theme-icon" class="toolbar-icon" aria-hidden="true"></span>
|
|
<span id="theme-label">{{i18n:viewer.theme.dark}}</span>
|
|
</button>
|
|
<div class="preset-wrap">
|
|
<button id="btn-preset" type="button"
|
|
title="{{i18n:viewer.preset.choose.title}}"
|
|
aria-label="{{i18n:viewer.preset.choose}}"
|
|
aria-haspopup="menu"
|
|
aria-expanded="false"
|
|
aria-controls="preset-menu"
|
|
aria-keyshortcuts="S">
|
|
<span class="preset-control-mark" aria-hidden="true"></span>
|
|
<span id="preset-label">{{i18n:viewer.preset.style}}</span>
|
|
<span class="toolbar-icon toolbar-chevron" aria-hidden="true"></span>
|
|
</button>
|
|
<div class="preset-menu" id="preset-menu" role="menu" aria-label="{{i18n:viewer.preset.menu}}">
|
|
<div class="preset-menu-heading" role="presentation"><span>{{i18n:viewer.preset.identity}}</span><span class="preset-menu-shortcut"><kbd>S</kbd>{{i18n:viewer.preset.cycles}}</span></div>
|
|
<button class="preset-option" data-preset-value="classic" type="button" role="menuitemradio" aria-checked="false" tabindex="-1">
|
|
<span class="preset-option-swatch classic" aria-hidden="true"></span>
|
|
<span class="preset-option-copy"><strong>{{i18n:viewer.preset.classic}}</strong><small>{{i18n:viewer.preset.classic.hint}}</small></span>
|
|
<span class="preset-option-check" aria-hidden="true"></span>
|
|
</button>
|
|
<button class="preset-option" data-preset-value="signal-flow" type="button" role="menuitemradio" aria-checked="false" tabindex="-1">
|
|
<span class="preset-option-swatch signal-flow" aria-hidden="true"></span>
|
|
<span class="preset-option-copy"><strong>{{i18n:viewer.preset.flow}}</strong><small>{{i18n:viewer.preset.flow.hint}}</small></span>
|
|
<span class="preset-option-check" aria-hidden="true"></span>
|
|
</button>
|
|
<button class="preset-option" data-preset-value="blueprint" type="button" role="menuitemradio" aria-checked="false" tabindex="-1">
|
|
<span class="preset-option-swatch blueprint" aria-hidden="true"></span>
|
|
<span class="preset-option-copy"><strong>{{i18n:viewer.preset.blueprint}}</strong><small>{{i18n:viewer.preset.blueprint.hint}}</small></span>
|
|
<span class="preset-option-check" aria-hidden="true"></span>
|
|
</button>
|
|
<button class="preset-option" data-preset-value="editorial" type="button" role="menuitemradio" aria-checked="false" tabindex="-1">
|
|
<span class="preset-option-swatch editorial" aria-hidden="true"></span>
|
|
<span class="preset-option-copy"><strong>{{i18n:viewer.preset.editorial}}</strong><small>{{i18n:viewer.preset.editorial.hint}}</small></span>
|
|
<span class="preset-option-check" aria-hidden="true"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<button id="btn-motion" type="button" hidden
|
|
title="{{i18n:viewer.motion.pause}}"
|
|
aria-label="{{i18n:viewer.motion.pause}}"
|
|
aria-pressed="true">
|
|
<span class="motion-control-dot" aria-hidden="true"></span>
|
|
<span id="motion-label">{{i18n:viewer.motion.live}}</span>
|
|
</button>
|
|
<button id="btn-present" type="button"
|
|
title="{{i18n:viewer.present.enter.title}}"
|
|
aria-label="{{i18n:viewer.present.enter}}"
|
|
aria-pressed="false">
|
|
<span id="present-icon" class="toolbar-icon" aria-hidden="true"></span>
|
|
<span id="present-label">{{i18n:viewer.present.present}}</span>
|
|
</button>
|
|
</div>
|
|
<div class="export-wrap">
|
|
<button id="btn-export" type="button"
|
|
title="{{i18n:viewer.export.button.title}}"
|
|
aria-label="{{i18n:viewer.export.diagram}}"
|
|
aria-haspopup="menu"
|
|
aria-expanded="false"
|
|
aria-controls="export-menu">
|
|
{{i18n:viewer.export.button}} <span class="toolbar-icon toolbar-chevron" aria-hidden="true"></span>
|
|
</button>
|
|
<div class="export-menu" id="export-menu" role="menu" aria-label="{{i18n:viewer.export.menu}}">
|
|
<div class="export-menu-header" role="presentation">
|
|
<div><strong>{{i18n:viewer.export.diagram}}</strong><span>{{i18n:viewer.export.subtitle}}</span></div>
|
|
<kbd>E</kbd>
|
|
</div>
|
|
<div class="export-menu-section" role="group" aria-label="{{i18n:viewer.export.share}}">
|
|
<span class="export-menu-heading" aria-hidden="true">{{i18n:viewer.export.share}}</span>
|
|
<button data-action="route-share-card" type="button" role="menuitem" tabindex="-1" hidden disabled><span class="export-item-copy"><strong>{{i18n:viewer.export.routeShareCard}}</strong><small class="hint">1200×630 PNG</small></span></button>
|
|
<button data-action="reach-share-card" type="button" role="menuitem" tabindex="-1" hidden disabled><span class="export-item-copy"><strong>{{i18n:viewer.export.reachShareCard}}</strong><small class="hint">1200×630 PNG</small></span></button>
|
|
<button data-action="copy" type="button" role="menuitem" tabindex="-1"><span class="export-item-copy"><strong>{{i18n:viewer.export.copyDiagram}}</strong><small class="hint">{{i18n:viewer.export.clipboardPng}}</small></span></button>
|
|
</div>
|
|
<div class="export-menu-section" role="group" aria-label="{{i18n:viewer.export.raster}}">
|
|
<span class="export-menu-heading" aria-hidden="true">{{i18n:viewer.export.image}}</span>
|
|
<button data-format="png" type="button" role="menuitem" tabindex="-1"><span class="export-item-copy"><strong>PNG</strong><small class="hint">{{i18n:viewer.export.lossless}}</small></span></button>
|
|
<button data-format="jpeg" type="button" role="menuitem" tabindex="-1"><span class="export-item-copy"><strong>JPEG</strong><small class="hint">{{i18n:viewer.export.compact}}</small></span></button>
|
|
<button data-format="webp" type="button" role="menuitem" tabindex="-1"><span class="export-item-copy"><strong>WebP</strong><small class="hint">{{i18n:viewer.export.modern}}</small></span></button>
|
|
</div>
|
|
<div class="export-menu-section" role="group" aria-label="{{i18n:viewer.export.vectorMotion}}">
|
|
<span class="export-menu-heading" aria-hidden="true">{{i18n:viewer.export.vectorMotion.heading}}</span>
|
|
<button data-format="svg" type="button" role="menuitem" tabindex="-1"><span class="export-item-copy"><strong>{{i18n:viewer.export.svg.auto}}</strong><small class="hint">{{i18n:viewer.export.svg.auto.hint}}</small></span></button>
|
|
<button data-format="svg-light" type="button" role="menuitem" tabindex="-1"><span class="export-item-copy"><strong>{{i18n:viewer.export.svg.light}}</strong><small class="hint">{{i18n:viewer.export.svg.light.hint}}</small></span></button>
|
|
<button data-format="svg-dark" type="button" role="menuitem" tabindex="-1"><span class="export-item-copy"><strong>{{i18n:viewer.export.svg.dark}}</strong><small class="hint">{{i18n:viewer.export.svg.dark.hint}}</small></span></button>
|
|
<button data-format="webm" type="button" role="menuitem" tabindex="-1"><span class="export-item-copy"><strong>WebM</strong><small class="hint">{{i18n:viewer.export.motion6s}}</small></span></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container">
|
|
<!-- Header -->
|
|
<div class="header">
|
|
<div class="header-row"
|
|
data-preset-badge-signal-flow="{{i18n:viewer.preset.badge.signalFlow}}"
|
|
data-preset-badge-blueprint="{{i18n:viewer.preset.badge.blueprint}}"
|
|
data-preset-badge-editorial="{{i18n:viewer.preset.badge.editorial}}">
|
|
<div class="pulse-dot"></div>
|
|
<h1>[PROJECT NAME] Architecture</h1>
|
|
</div>
|
|
<p class="subtitle">[Subtitle description]</p>
|
|
</div>
|
|
|
|
<!-- ARCHIFY:SOURCE_EVIDENCE_DATA -->
|
|
<!-- ARCHIFY:I18N_DATA -->
|
|
<!-- Main Diagram -->
|
|
<div class="diagram-container" data-detail-level="read"
|
|
data-preset-badge-editorial-plate="{{i18n:viewer.preset.badge.editorialPlate}}">
|
|
<!-- ARCHIFY:SVG_SLOT_START -->
|
|
<svg viewBox="0 0 1000 680" role="img" aria-label="[PROJECT NAME] architecture diagram">
|
|
<!-- Definitions -->
|
|
<defs>
|
|
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" class="m-default" />
|
|
</marker>
|
|
<marker id="arrowhead-emphasis" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" class="m-emphasis" />
|
|
</marker>
|
|
<marker id="arrowhead-security" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" class="m-security" />
|
|
</marker>
|
|
<marker id="arrowhead-dashed" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" class="m-dashed" />
|
|
</marker>
|
|
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
<path d="M 40 0 L 0 0 0 40" class="c-grid" stroke-width="0.5"/>
|
|
</pattern>
|
|
</defs>
|
|
|
|
<!-- Background Grid -->
|
|
<rect width="100%" height="100%" fill="url(#grid)" />
|
|
|
|
<!-- =================================================================
|
|
COMPONENT EXAMPLES — use CSS classes, not inline fill/stroke
|
|
(so theme toggle works). Each box pattern:
|
|
1. opaque mask rect (.c-mask) to hide arrows underneath
|
|
2. styled rect (.c-<type>) with 1.5px stroke
|
|
3. text (.t-primary / .t-muted)
|
|
================================================================= -->
|
|
|
|
<!-- External/Generic Component -->
|
|
<rect x="30" y="280" width="100" height="50" rx="6" class="c-mask"/>
|
|
<rect x="30" y="280" width="100" height="50" rx="6" class="c-external" stroke-width="1.5"/>
|
|
<text x="80" y="300" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">Users</text>
|
|
<text x="80" y="316" class="t-muted" font-size="9" text-anchor="middle">Browser/Mobile</text>
|
|
|
|
<!-- Security Component -->
|
|
<rect x="30" y="80" width="100" height="60" rx="6" class="c-mask"/>
|
|
<rect x="30" y="80" width="100" height="60" rx="6" class="c-security" stroke-width="1.5"/>
|
|
<text x="80" y="105" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">Auth Provider</text>
|
|
<text x="80" y="121" class="t-muted" font-size="9" text-anchor="middle">OAuth 2.0</text>
|
|
|
|
<!-- Region/Cloud Boundary -->
|
|
<rect x="160" y="40" width="820" height="620" rx="12" class="c-region" stroke-width="1"/>
|
|
<text x="172" y="58" class="t-cloud" font-size="10" font-weight="600">AWS Region: us-west-2</text>
|
|
|
|
<!-- AWS/Cloud Service -->
|
|
<rect x="200" y="280" width="110" height="50" rx="6" class="c-mask"/>
|
|
<rect x="200" y="280" width="110" height="50" rx="6" class="c-cloud" stroke-width="1.5"/>
|
|
<text x="255" y="300" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">CloudFront</text>
|
|
<text x="255" y="316" class="t-muted" font-size="9" text-anchor="middle">CDN</text>
|
|
|
|
<!-- Multi-line AWS Component (S3 Buckets example) -->
|
|
<rect x="200" y="380" width="110" height="100" rx="6" class="c-mask"/>
|
|
<rect x="200" y="380" width="110" height="100" rx="6" class="c-cloud" stroke-width="1.5"/>
|
|
<text x="255" y="400" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">S3 Buckets</text>
|
|
<text x="255" y="420" class="t-muted" font-size="8" text-anchor="middle">• bucket-one</text>
|
|
<text x="255" y="434" class="t-muted" font-size="8" text-anchor="middle">• bucket-two</text>
|
|
<text x="255" y="448" class="t-muted" font-size="8" text-anchor="middle">• bucket-three</text>
|
|
<text x="255" y="466" class="t-cloud" font-size="7" text-anchor="middle">OAI Protected</text>
|
|
|
|
<!-- Security Group (dashed boundary). NOTE: extra vertical headroom
|
|
so the sg-name label has ~12px breathing room above the inner
|
|
component. Pattern: boundary y = inner.y - 30, h = inner.h + 50. -->
|
|
<rect x="350" y="250" width="120" height="100" rx="8" class="c-security-group" stroke-width="1"/>
|
|
<text x="358" y="268" class="t-security" font-size="8">sg-name :port</text>
|
|
|
|
<!-- Component inside security group -->
|
|
<rect x="360" y="280" width="100" height="50" rx="6" class="c-mask"/>
|
|
<rect x="360" y="280" width="100" height="50" rx="6" class="c-cloud" stroke-width="1.5"/>
|
|
<text x="410" y="300" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">Load Balancer</text>
|
|
<text x="410" y="316" class="t-muted" font-size="9" text-anchor="middle">HTTPS :443</text>
|
|
|
|
<!-- Backend Component -->
|
|
<rect x="510" y="280" width="110" height="50" rx="6" class="c-mask"/>
|
|
<rect x="510" y="280" width="110" height="50" rx="6" class="c-backend" stroke-width="1.5"/>
|
|
<text x="565" y="300" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">API Server</text>
|
|
<text x="565" y="316" class="t-muted" font-size="9" text-anchor="middle">FastAPI :8000</text>
|
|
|
|
<!-- Database Component -->
|
|
<rect x="700" y="280" width="120" height="50" rx="6" class="c-mask"/>
|
|
<rect x="700" y="280" width="120" height="50" rx="6" class="c-database" stroke-width="1.5"/>
|
|
<text x="760" y="300" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">Database</text>
|
|
<text x="760" y="316" class="t-muted" font-size="9" text-anchor="middle">PostgreSQL</text>
|
|
|
|
<!-- Frontend Component -->
|
|
<rect x="200" y="520" width="200" height="110" rx="8" class="c-mask"/>
|
|
<rect x="200" y="520" width="200" height="110" rx="8" class="c-frontend" stroke-width="1.5"/>
|
|
<text x="300" y="545" class="t-primary" font-size="12" font-weight="600" text-anchor="middle">Frontend</text>
|
|
<text x="300" y="565" class="t-muted" font-size="9" text-anchor="middle">React + TypeScript</text>
|
|
<text x="300" y="580" class="t-muted" font-size="9" text-anchor="middle">Additional detail</text>
|
|
<text x="300" y="595" class="t-muted" font-size="9" text-anchor="middle">More info</text>
|
|
<text x="300" y="615" class="t-frontend" font-size="8" text-anchor="middle">domain.example.com</text>
|
|
|
|
<!-- =================================================================
|
|
ARROW EXAMPLES (use .a-* classes and stroke-width on the line)
|
|
================================================================= -->
|
|
|
|
<!-- Standard arrow with label -->
|
|
<line x1="130" y1="305" x2="198" y2="305" class="a-default" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<text x="164" y="299" class="t-muted" font-size="9" text-anchor="middle">HTTPS</text>
|
|
|
|
<!-- Simple arrow (no label) -->
|
|
<line x1="310" y1="305" x2="358" y2="305" class="a-default" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
|
|
<!-- Vertical arrow -->
|
|
<line x1="255" y1="330" x2="255" y2="378" class="a-default" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<text x="270" y="358" class="t-muted" font-size="9">OAI</text>
|
|
|
|
<!-- Straight arrows between services -->
|
|
<line x1="460" y1="305" x2="508" y2="305" class="a-default" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="620" y1="305" x2="698" y2="305" class="a-default" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<text x="655" y="299" class="t-muted" font-size="9">TLS</text>
|
|
|
|
<!-- Curved dashed path for auth/security flow -->
|
|
<path d="M 80 140 L 80 200 Q 80 220 100 220 L 200 220 Q 220 220 220 240 L 220 278"
|
|
class="a-security" stroke-width="1.5"/>
|
|
<text x="150" y="210" class="t-security" font-size="8">JWT + PKCE</text>
|
|
|
|
<!-- =================================================================
|
|
LEGEND
|
|
================================================================= -->
|
|
<text x="720" y="70" class="t-primary" font-size="10" font-weight="600">Legend</text>
|
|
|
|
<rect x="720" y="82" width="16" height="10" rx="2" class="c-frontend" stroke-width="1"/>
|
|
<text x="742" y="90" class="t-muted" font-size="8">Frontend</text>
|
|
|
|
<rect x="720" y="98" width="16" height="10" rx="2" class="c-backend" stroke-width="1"/>
|
|
<text x="742" y="106" class="t-muted" font-size="8">Backend</text>
|
|
|
|
<rect x="720" y="114" width="16" height="10" rx="2" class="c-cloud" stroke-width="1"/>
|
|
<text x="742" y="122" class="t-muted" font-size="8">Cloud Service</text>
|
|
|
|
<rect x="720" y="130" width="16" height="10" rx="2" class="c-database" stroke-width="1"/>
|
|
<text x="742" y="138" class="t-muted" font-size="8">Database</text>
|
|
|
|
<rect x="720" y="146" width="16" height="10" rx="2" class="c-security" stroke-width="1"/>
|
|
<text x="742" y="154" class="t-muted" font-size="8">Security</text>
|
|
|
|
<line x1="720" y1="168" x2="736" y2="168" class="a-security" stroke-width="1"/>
|
|
<text x="742" y="171" class="t-muted" font-size="8">Auth Flow</text>
|
|
|
|
<rect x="720" y="178" width="16" height="10" rx="2" class="c-security-group" stroke-width="1"/>
|
|
<text x="742" y="186" class="t-muted" font-size="8">Security Group</text>
|
|
</svg>
|
|
<!-- ARCHIFY:SVG_SLOT_END -->
|
|
<p class="intent-trace-status no-print" id="intent-trace-status" role="status" aria-live="polite" aria-atomic="true"></p>
|
|
<div class="diagram-guide no-print" id="diagram-guide" hidden role="dialog" aria-modal="false" aria-labelledby="diagram-guide-title">
|
|
<div class="diagram-guide-head">
|
|
<span>
|
|
<span class="diagram-guide-eyebrow">{{i18n:viewer.guide.eyebrow}}</span>
|
|
<strong class="diagram-guide-title" id="diagram-guide-title">{{i18n:viewer.guide.title}}</strong>
|
|
</span>
|
|
<button class="diagram-guide-close" id="diagram-guide-close" type="button" aria-label="{{i18n:viewer.guide.close}}">×</button>
|
|
</div>
|
|
<p class="diagram-guide-stats" id="diagram-guide-stats">{{i18n:viewer.guide.inspecting}}</p>
|
|
<div class="diagram-guide-actions" id="diagram-guide-actions" role="group" aria-label="{{i18n:viewer.guide.actions}}">
|
|
<button class="diagram-guide-action" type="button" data-guide-action="find" aria-label="{{i18n:viewer.guide.find}}">
|
|
<span class="diagram-guide-index" aria-hidden="true">01</span>
|
|
<span class="diagram-guide-action-copy"><strong>{{i18n:viewer.guide.find}}</strong><small>{{i18n:viewer.guide.find.hint}}</small></span>
|
|
<kbd aria-hidden="true">/</kbd>
|
|
</button>
|
|
<button class="diagram-guide-action" type="button" data-guide-action="route" aria-label="{{i18n:viewer.guide.route.aria}}">
|
|
<span class="diagram-guide-index" aria-hidden="true">02</span>
|
|
<span class="diagram-guide-action-copy"><strong>{{i18n:viewer.guide.route}}</strong><small>{{i18n:viewer.guide.route.hint}}</small></span>
|
|
<kbd aria-hidden="true">R</kbd>
|
|
</button>
|
|
<button class="diagram-guide-action" type="button" data-guide-action="map" aria-label="{{i18n:viewer.guide.map}}">
|
|
<span class="diagram-guide-index" aria-hidden="true">03</span>
|
|
<span class="diagram-guide-action-copy"><strong>{{i18n:viewer.guide.map}}</strong><small>{{i18n:viewer.guide.map.hint}}</small></span>
|
|
<kbd aria-hidden="true">M</kbd>
|
|
</button>
|
|
<button class="diagram-guide-action" type="button" data-guide-action="lens" aria-label="{{i18n:viewer.guide.lens}}">
|
|
<span class="diagram-guide-index" aria-hidden="true">04</span>
|
|
<span class="diagram-guide-action-copy"><strong>{{i18n:viewer.guide.lens}}</strong><small>{{i18n:viewer.guide.lens.hint}}</small></span>
|
|
<kbd aria-hidden="true">L</kbd>
|
|
</button>
|
|
<button class="diagram-guide-action" type="button" data-guide-action="present" aria-label="{{i18n:viewer.present.enter}}">
|
|
<span class="diagram-guide-index" aria-hidden="true">05</span>
|
|
<span class="diagram-guide-action-copy"><strong>{{i18n:viewer.guide.present}}</strong><small>{{i18n:viewer.guide.present.hint}}</small></span>
|
|
<kbd aria-hidden="true">F</kbd>
|
|
</button>
|
|
</div>
|
|
<div class="diagram-guide-shortcuts" aria-label="{{i18n:viewer.guide.shortcuts}}">
|
|
<span><kbd>E</kbd> {{i18n:viewer.guide.shortcut.export}}</span><span><kbd>T</kbd> {{i18n:viewer.guide.shortcut.theme}}</span><span><kbd>S</kbd> {{i18n:viewer.guide.shortcut.style}}</span><span><kbd>0</kbd> {{i18n:viewer.guide.shortcut.reset}}</span><span><kbd>+</kbd> {{i18n:viewer.guide.shortcut.zoomIn}}</span><span><kbd>-</kbd> {{i18n:viewer.guide.shortcut.zoomOut}}</span><span><kbd>Esc</kbd> {{i18n:viewer.guide.shortcut.close}}</span>
|
|
</div>
|
|
<p class="diagram-guide-feedback" id="diagram-guide-feedback" aria-live="polite"></p>
|
|
</div>
|
|
<div class="node-finder no-print" id="node-finder" hidden role="dialog" aria-modal="false" aria-labelledby="node-finder-title">
|
|
<div class="node-finder-head">
|
|
<strong id="node-finder-title">{{i18n:viewer.finder.title}}</strong>
|
|
<button class="node-finder-close" id="node-finder-close" type="button" aria-label="{{i18n:viewer.finder.close}}">×</button>
|
|
</div>
|
|
<div class="node-finder-search">
|
|
<span aria-hidden="true">⌕</span>
|
|
<input class="node-finder-input" id="node-finder-input" type="search" autocomplete="off" spellcheck="false" placeholder="{{i18n:viewer.finder.placeholder}}" aria-label="{{i18n:viewer.finder.search}}" aria-describedby="node-finder-status">
|
|
<kbd aria-hidden="true">/</kbd>
|
|
</div>
|
|
<div class="node-finder-results" id="node-finder-results" role="group" aria-label="{{i18n:viewer.finder.results}}"></div>
|
|
<p class="node-finder-empty" id="node-finder-empty" hidden>{{i18n:viewer.finder.empty}}</p>
|
|
<p class="node-finder-status" id="node-finder-status" aria-live="polite"></p>
|
|
</div>
|
|
<div class="focus-chip relationship-lens no-print" id="focus-chip" hidden role="region" aria-labelledby="relationship-lens-title">
|
|
<div class="relationship-lens-head">
|
|
<button class="relationship-lens-drag-handle" id="btn-focus-move" type="button" data-focus-drag-handle aria-label="{{i18n:viewer.passport.move}}" title="{{i18n:viewer.passport.move}}"></button>
|
|
<div class="relationship-lens-copy">
|
|
<span class="relationship-lens-eyebrow">{{i18n:viewer.passport.eyebrow}}</span>
|
|
<strong class="relationship-lens-title" id="relationship-lens-title"><span id="focus-label"></span></strong>
|
|
<span class="semantic-passport-detail" id="focus-detail" hidden></span>
|
|
<div class="semantic-passport-meta" id="focus-passport-meta" aria-label="{{i18n:viewer.passport.metadata}}">
|
|
<span id="focus-kind" data-passport="kind"></span>
|
|
<span id="focus-context" data-passport="context" hidden></span>
|
|
<span id="focus-tag" data-passport="tag" hidden></span>
|
|
<span id="focus-brand" data-passport="brand" hidden></span>
|
|
<code id="focus-id" data-passport="id"></code>
|
|
</div>
|
|
<div class="semantic-passport-evidence" id="focus-evidence" hidden aria-label="{{i18n:viewer.passport.evidence}}">
|
|
<div class="semantic-passport-evidence-head">
|
|
<span class="semantic-passport-evidence-status">{{i18n:viewer.passport.verified}}</span>
|
|
<a class="semantic-passport-repository" id="focus-repository" target="_blank" rel="noopener noreferrer" referrerpolicy="no-referrer"></a>
|
|
</div>
|
|
<div class="semantic-passport-evidence-links" id="focus-evidence-links"></div>
|
|
</div>
|
|
<span class="relationship-lens-summary" id="focus-summary" aria-live="polite"></span>
|
|
<div class="semantic-passport-reach" id="focus-reach" hidden>
|
|
<span class="semantic-passport-reach-label">{{i18n:viewer.passport.reach}}</span>
|
|
<div class="semantic-passport-reach-actions" role="group" aria-label="{{i18n:viewer.passport.reach.trace}}">
|
|
<button id="btn-reach-upstream" type="button" aria-label="{{i18n:viewer.passport.upstream.trace}}" aria-pressed="false">
|
|
<span>{{i18n:viewer.passport.upstream}}</span><strong id="focus-reach-upstream-count">0</strong>
|
|
</button>
|
|
<button id="btn-reach-downstream" type="button" aria-label="{{i18n:viewer.passport.downstream.trace}}" aria-pressed="false">
|
|
<span>{{i18n:viewer.passport.downstream}}</span><strong id="focus-reach-downstream-count">0</strong>
|
|
</button>
|
|
</div>
|
|
<small class="semantic-passport-reach-status" id="focus-reach-status" hidden aria-live="polite"></small>
|
|
</div>
|
|
</div>
|
|
<div class="relationship-lens-actions">
|
|
<button id="btn-focus-clear" type="button" aria-label="{{i18n:viewer.passport.close}}" title="{{i18n:viewer.common.close}}">×</button>
|
|
<button id="btn-focus-copy" type="button" aria-label="{{i18n:viewer.passport.copy.focus}}">{{i18n:viewer.passport.copy}}</button>
|
|
<button id="btn-focus-relations" type="button" aria-label="{{i18n:viewer.passport.relations.show}}" aria-expanded="false" aria-controls="relationship-lens-list">{{i18n:viewer.passport.relations}}</button>
|
|
</div>
|
|
</div>
|
|
<div class="relationship-lens-list" id="relationship-lens-list" aria-label="{{i18n:viewer.passport.relations.list}}"></div>
|
|
</div>
|
|
<div class="route-probe no-print" id="route-probe" hidden role="region" aria-labelledby="route-probe-title" data-state="idle">
|
|
<div class="route-probe-head">
|
|
<span class="route-probe-copy">
|
|
<span class="route-probe-eyebrow">{{i18n:viewer.route.eyebrow}}</span>
|
|
<strong class="route-probe-title" id="route-probe-title">{{i18n:viewer.route.start}}</strong>
|
|
</span>
|
|
<span class="route-probe-actions">
|
|
<button class="route-probe-find" id="route-probe-find" type="button" aria-label="{{i18n:viewer.route.start.find.aria}}" data-node-finder-trigger>{{i18n:viewer.route.start.find}}</button>
|
|
<button class="route-probe-copy-link" id="route-probe-copy" type="button" aria-label="{{i18n:viewer.route.copy.aria}}" hidden>{{i18n:viewer.route.copy}}</button>
|
|
<button id="route-probe-clear" type="button" aria-label="{{i18n:viewer.route.clear.aria}}">{{i18n:viewer.route.clear}}</button>
|
|
</span>
|
|
</div>
|
|
<div class="route-probe-path" id="route-probe-path" aria-label="{{i18n:viewer.route.traced}}">
|
|
<span class="route-probe-placeholder">{{i18n:viewer.route.pickTwo}}</span>
|
|
</div>
|
|
<div class="route-journey-controls" id="route-journey-controls" hidden role="group" aria-label="{{i18n:viewer.route.controls}}" data-playing="false">
|
|
<button id="route-journey-prev" type="button" aria-label="{{i18n:viewer.route.previous}}" title="{{i18n:viewer.route.previous}}">←</button>
|
|
<button class="route-journey-play" id="route-journey-play" type="button" aria-label="{{i18n:viewer.route.play}}" aria-pressed="false" title="{{i18n:viewer.route.play}}">
|
|
<span id="route-journey-play-icon" aria-hidden="true">▶</span>
|
|
<span id="route-journey-play-label">{{i18n:viewer.route.journey}}</span>
|
|
</button>
|
|
<button id="route-journey-next" type="button" aria-label="{{i18n:viewer.route.next}}" title="{{i18n:viewer.route.next}}">→</button>
|
|
<button class="route-journey-overview" id="route-journey-overview" type="button" aria-label="{{i18n:viewer.route.overview.aria}}" title="{{i18n:viewer.route.overview.aria}}">{{i18n:viewer.route.overview}}</button>
|
|
</div>
|
|
<small class="route-probe-status" id="route-probe-status" aria-live="polite">{{i18n:viewer.route.instructions}}</small>
|
|
</div>
|
|
<div class="semantic-lens no-print" id="semantic-lens" hidden role="dialog" aria-modal="false" aria-labelledby="semantic-lens-title">
|
|
<div class="semantic-lens-head">
|
|
<span>
|
|
<span class="semantic-lens-eyebrow">{{i18n:viewer.lens.eyebrow}}</span>
|
|
<strong class="semantic-lens-title" id="semantic-lens-title">{{i18n:viewer.lens.title}}</strong>
|
|
</span>
|
|
<button class="semantic-lens-close" id="semantic-lens-close" type="button" aria-label="{{i18n:viewer.lens.close}}">×</button>
|
|
</div>
|
|
<p class="semantic-lens-instruction">{{i18n:viewer.lens.instruction}}</p>
|
|
<div class="semantic-lens-kinds" id="semantic-lens-kinds" role="group" aria-label="{{i18n:viewer.lens.kinds}}"></div>
|
|
<p class="semantic-lens-status" id="semantic-lens-status" aria-live="polite">{{i18n:viewer.lens.choose}}</p>
|
|
<div class="semantic-lens-actions">
|
|
<button id="semantic-lens-copy" type="button" aria-label="{{i18n:viewer.lens.copy}}" hidden>{{i18n:viewer.common.copyLink}}</button>
|
|
<button id="semantic-lens-clear" type="button" aria-label="{{i18n:viewer.lens.clear}}">{{i18n:viewer.common.clear}}</button>
|
|
</div>
|
|
</div>
|
|
<div class="overview-map no-print" id="overview-map" hidden role="region" aria-labelledby="overview-map-title">
|
|
<div class="overview-map-head">
|
|
<span class="overview-map-live" aria-hidden="true"></span>
|
|
<span class="overview-map-copy">
|
|
<strong id="overview-map-title">{{i18n:viewer.radar.title}}</strong>
|
|
<small id="overview-map-status" aria-live="polite">{{i18n:viewer.radar.building}}</small>
|
|
</span>
|
|
<button class="overview-map-expand" id="overview-map-expand" type="button" aria-label="{{i18n:viewer.radar.openFull}}">{{i18n:viewer.radar.open}}</button>
|
|
<button class="overview-map-close" id="overview-map-close" type="button" aria-label="{{i18n:viewer.radar.close}}">×</button>
|
|
</div>
|
|
<div class="overview-map-surface" id="overview-map-surface" tabindex="0" role="group" aria-label="{{i18n:viewer.radar.surface}}"></div>
|
|
<div class="overview-map-hint" aria-hidden="true"><span>{{i18n:viewer.radar.click}}</span><span>{{i18n:viewer.radar.drag}}</span></div>
|
|
</div>
|
|
<p class="overview-map-feedback no-print" id="overview-map-feedback" role="status" aria-live="polite" hidden>{{i18n:viewer.radar.space}}</p>
|
|
<button class="rail-reveal no-print" id="rail-reveal" type="button" hidden aria-controls="reader-rail" aria-expanded="false"><span class="rail-reveal-icon" aria-hidden="true"></span><span>{{i18n:viewer.rail.show}}</span></button>
|
|
<div class="diagram-nav no-print" role="toolbar" aria-label="{{i18n:viewer.nav.controls}}">
|
|
<button id="btn-route-probe" type="button" aria-label="{{i18n:viewer.nav.route}}" aria-pressed="false" aria-controls="route-probe" title="{{i18n:viewer.nav.route.title}}">{{i18n:viewer.nav.route.short}}</button>
|
|
<button id="btn-overview-map" type="button" aria-label="{{i18n:viewer.nav.radar}}" aria-expanded="false" aria-controls="overview-map" title="{{i18n:viewer.nav.radar.title}}">{{i18n:viewer.nav.radar.short}}</button>
|
|
<button id="btn-semantic-lens" type="button" aria-label="{{i18n:viewer.nav.lens}}" aria-haspopup="dialog" aria-expanded="false" aria-pressed="false" aria-controls="semantic-lens" title="{{i18n:viewer.nav.lens.title}}">{{i18n:viewer.nav.lens.short}}</button>
|
|
<button id="btn-node-finder" type="button" aria-label="{{i18n:viewer.nav.find}}" aria-haspopup="dialog" aria-expanded="false" aria-controls="node-finder" title="{{i18n:viewer.nav.find.title}}" data-node-finder-trigger><span class="diagram-nav-icon find" aria-hidden="true"></span></button>
|
|
<button id="btn-diagram-guide" type="button" hidden aria-label="{{i18n:viewer.nav.guide}}" aria-haspopup="dialog" aria-expanded="false" aria-controls="diagram-guide" title="{{i18n:viewer.nav.guide.title}}"><span class="diagram-nav-icon guide" aria-hidden="true"></span></button>
|
|
<button data-view="out" type="button" aria-label="{{i18n:viewer.nav.zoomOut}}" title="{{i18n:viewer.nav.zoomOut.title}}"><span class="diagram-nav-icon minus" aria-hidden="true"></span></button>
|
|
<button data-view="reset" type="button" aria-label="{{i18n:viewer.nav.reset}}" title="{{i18n:viewer.nav.reset.title}}"><span class="diagram-nav-detail" data-view-detail hidden>{{i18n:viewer.nav.read}}</span><span class="diagram-nav-percent" data-view-percent>100%</span></button>
|
|
<button data-view="in" type="button" aria-label="{{i18n:viewer.nav.zoomIn}}" title="{{i18n:viewer.nav.zoomIn.title}}"><span class="diagram-nav-icon plus" aria-hidden="true"></span></button>
|
|
</div>
|
|
</div>
|
|
|
|
<aside class="reader-rail" id="reader-rail">
|
|
<div class="rail-controls no-print" role="toolbar" aria-label="{{i18n:viewer.rail.controls}}">
|
|
<button class="rail-control" id="rail-placement" type="button" hidden aria-label="{{i18n:viewer.rail.bottom}}" title="{{i18n:viewer.rail.bottom}}" data-placement="right"><span class="rail-control-icon placement" aria-hidden="true"></span></button>
|
|
<button class="rail-control" id="rail-collapse" type="button" hidden aria-controls="reader-rail" aria-expanded="true" aria-label="{{i18n:viewer.rail.collapse}}" title="{{i18n:viewer.rail.collapse}}"><span class="rail-control-icon collapse" aria-hidden="true"></span></button>
|
|
</div>
|
|
<!-- ARCHIFY:CARDS_SLOT_START -->
|
|
<div class="cards">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot rose"></div>
|
|
<h3>Card Title 1</h3>
|
|
</div>
|
|
<ul>
|
|
<li>Item one</li>
|
|
<li>Item two</li>
|
|
<li>Item three</li>
|
|
<li>Item four</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot amber"></div>
|
|
<h3>Card Title 2</h3>
|
|
</div>
|
|
<ul>
|
|
<li>Item one</li>
|
|
<li>Item two</li>
|
|
<li>Item three</li>
|
|
<li>Item four</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot violet"></div>
|
|
<h3>Card Title 3</h3>
|
|
</div>
|
|
<ul>
|
|
<li>Item one</li>
|
|
<li>Item two</li>
|
|
<li>Item three</li>
|
|
<li>Item four</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<!-- ARCHIFY:CARDS_SLOT_END -->
|
|
<nav class="node-outline no-print" id="node-outline" hidden aria-labelledby="node-outline-title">
|
|
<div class="node-outline-head">
|
|
<strong id="node-outline-title">{{i18n:viewer.outline.title}}</strong>
|
|
<span class="node-outline-count" id="node-outline-count"></span>
|
|
</div>
|
|
<ol class="node-outline-list" id="node-outline-list"></ol>
|
|
</nav>
|
|
</aside>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
var Archify = {};
|
|
var archifyI18nData = (function () {
|
|
var node = document.getElementById('archify-i18n-data');
|
|
try { return JSON.parse(node ? node.textContent : '{}'); }
|
|
catch (_) { return { locale: 'en', messages: {} }; }
|
|
})();
|
|
Archify.locale = archifyI18nData.locale || 'en';
|
|
|
|
function viewerText(key, values) {
|
|
var messages = archifyI18nData.messages || {};
|
|
var template = Object.prototype.hasOwnProperty.call(messages, key) ? messages[key] : key;
|
|
return String(template).replace(/\{([a-zA-Z0-9_]+)\}/g, function (match, name) {
|
|
return values && Object.prototype.hasOwnProperty.call(values, name) ? String(values[name]) : match;
|
|
});
|
|
}
|
|
|
|
function viewerCount(key, count, values) {
|
|
var suffix = Number(count) === 1 ? '.one' : '.other';
|
|
var payload = Object.assign({}, values || {}, { count: count });
|
|
return viewerText(key + suffix, payload);
|
|
}
|
|
|
|
function viewerKindLabel(value) {
|
|
var normalized = String(value || 'node').toLowerCase();
|
|
var knownKey = 'viewer.kind.' + normalized;
|
|
var known = viewerText(knownKey);
|
|
if (known !== knownKey) return known;
|
|
return normalized
|
|
.replace(/messagebus/gi, 'message bus')
|
|
.replace(/[-_]+/g, ' ')
|
|
.replace(/\b\w/g, function (letter) { return letter.toUpperCase(); });
|
|
}
|
|
|
|
function hasDrawableGeometry(element) {
|
|
if (!element) return false;
|
|
var geometries = /^(path|line|polyline)$/i.test(element.tagName)
|
|
? [element]
|
|
: Array.prototype.slice.call(element.querySelectorAll('path, line, polyline'));
|
|
return geometries.some(function (geometry) {
|
|
var source = geometry.tagName.toLowerCase() === 'path'
|
|
? geometry.getAttribute('d')
|
|
: geometry.tagName.toLowerCase() === 'polyline'
|
|
? geometry.getAttribute('points')
|
|
: [geometry.getAttribute('x1'), geometry.getAttribute('y1'), geometry.getAttribute('x2'), geometry.getAttribute('y2')].join(' ');
|
|
if (!source || /(?:^|[^a-z])(?:nan|infinity)(?:[^a-z]|$)/i.test(source) || typeof geometry.getTotalLength !== 'function') return false;
|
|
try {
|
|
var length = Number(geometry.getTotalLength());
|
|
return Number.isFinite(length) && length > 0;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
|
|
/* ============================================================
|
|
Visual style try-on — one topology, four bundled presets.
|
|
The reader's choice is intentionally session-only: it updates the
|
|
live page and canonical SVG together, but never rewrites the source,
|
|
URL, or a later diagram's authored default.
|
|
============================================================ */
|
|
Archify.preset = (function () {
|
|
var PRESETS = ['classic', 'signal-flow', 'blueprint', 'editorial'];
|
|
var LABELS = {
|
|
classic: viewerText('viewer.preset.classic.short'),
|
|
'signal-flow': viewerText('viewer.preset.flow.short'),
|
|
blueprint: viewerText('viewer.preset.blueprint'),
|
|
editorial: viewerText('viewer.preset.editorial')
|
|
};
|
|
var html = document.documentElement;
|
|
var svg = document.querySelector('.diagram-container svg');
|
|
var btn = document.getElementById('btn-preset');
|
|
var label = document.getElementById('preset-label');
|
|
var menu = document.getElementById('preset-menu');
|
|
var options = function () {
|
|
return Array.prototype.slice.call(menu.querySelectorAll('[data-preset-value]'));
|
|
};
|
|
var authored = PRESETS.indexOf(html.getAttribute('data-preset')) >= 0
|
|
? html.getAttribute('data-preset')
|
|
: 'classic';
|
|
|
|
function current() {
|
|
var value = html.getAttribute('data-preset');
|
|
return PRESETS.indexOf(value) >= 0 ? value : authored;
|
|
}
|
|
function nextAfter(preset) {
|
|
return PRESETS[(PRESETS.indexOf(preset) + 1) % PRESETS.length];
|
|
}
|
|
function apply(preset) {
|
|
if (html.getAttribute('data-embed') === 'true') return false;
|
|
if (PRESETS.indexOf(preset) < 0) return false;
|
|
html.setAttribute('data-preset', preset);
|
|
svg.setAttribute('data-preset', preset);
|
|
btn.setAttribute('data-preset-option', preset);
|
|
label.textContent = LABELS[preset];
|
|
btn.setAttribute('aria-label', viewerText('viewer.preset.current', { style: LABELS[preset] }));
|
|
btn.title = viewerText('viewer.preset.choose.title');
|
|
options().forEach(function (option) {
|
|
var selected = option.getAttribute('data-preset-value') === preset;
|
|
option.setAttribute('aria-checked', String(selected));
|
|
});
|
|
return true;
|
|
}
|
|
function cycle() { return apply(nextAfter(current())); }
|
|
|
|
function isOpen() { return menu.classList.contains('open'); }
|
|
function open(focusLast) {
|
|
if (html.getAttribute('data-embed') === 'true') return false;
|
|
if (Archify.exportMenu && Archify.exportMenu.isOpen()) Archify.exportMenu.close(false);
|
|
menu.classList.add('open');
|
|
btn.setAttribute('aria-expanded', 'true');
|
|
var available = options();
|
|
var selected = available.find(function (option) { return option.getAttribute('aria-checked') === 'true'; });
|
|
var target = focusLast ? available[available.length - 1] : (selected || available[0]);
|
|
if (target) target.focus();
|
|
return true;
|
|
}
|
|
function close(focusTrigger) {
|
|
menu.classList.remove('open');
|
|
btn.setAttribute('aria-expanded', 'false');
|
|
if (focusTrigger) btn.focus();
|
|
return false;
|
|
}
|
|
|
|
apply(authored);
|
|
btn.addEventListener('click', function (e) {
|
|
e.stopPropagation();
|
|
if (isOpen()) close(false);
|
|
else open(false);
|
|
});
|
|
btn.addEventListener('keydown', function (e) {
|
|
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
|
|
e.preventDefault();
|
|
if (!isOpen()) open(e.key === 'ArrowUp');
|
|
}
|
|
});
|
|
document.addEventListener('click', function (e) {
|
|
if (!menu.contains(e.target) && e.target !== btn) close(false);
|
|
});
|
|
menu.addEventListener('click', function (e) {
|
|
var option = e.target.closest('[data-preset-value]');
|
|
if (!option || !menu.contains(option)) return;
|
|
if (apply(option.getAttribute('data-preset-value'))) close(true);
|
|
});
|
|
menu.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape') { e.preventDefault(); close(true); return; }
|
|
if (e.key === 'Tab') { close(false); return; }
|
|
var available = options();
|
|
var active = available.indexOf(document.activeElement);
|
|
switch (e.key) {
|
|
case 'ArrowDown':
|
|
e.preventDefault();
|
|
if (available.length) available[(active + 1 + available.length) % available.length].focus();
|
|
break;
|
|
case 'ArrowUp':
|
|
e.preventDefault();
|
|
if (available.length) available[(active - 1 + available.length) % available.length].focus();
|
|
break;
|
|
case 'Home':
|
|
e.preventDefault();
|
|
if (available[0]) available[0].focus();
|
|
break;
|
|
case 'End':
|
|
e.preventDefault();
|
|
if (available.length) available[available.length - 1].focus();
|
|
break;
|
|
}
|
|
});
|
|
return { cycle: cycle, apply: apply, current: current, authored: authored, open: open, close: close, isOpen: isOpen };
|
|
})();
|
|
|
|
/* ============================================================
|
|
Theme toggle — persists to localStorage, respects system pref
|
|
============================================================ */
|
|
|
|
Archify.theme = (function () {
|
|
var STORAGE_KEY = 'archify-theme';
|
|
var html = document.documentElement;
|
|
var btn = document.getElementById('btn-theme');
|
|
var label = document.getElementById('theme-label');
|
|
|
|
// localStorage can throw (blocked cookies, sandboxed iframes); the whole
|
|
// script element dies on an uncaught error, so guard every access.
|
|
function readStored() {
|
|
try { return localStorage.getItem(STORAGE_KEY); } catch (_) { return null; }
|
|
}
|
|
function writeStored(value) {
|
|
try { localStorage.setItem(STORAGE_KEY, value); } catch (_) {}
|
|
}
|
|
function urlOverride() {
|
|
// URL param wins (useful for deterministic screenshots / share links)
|
|
try {
|
|
var param = new URLSearchParams(window.location.search).get('theme');
|
|
if (param === 'light' || param === 'dark') return param;
|
|
} catch (_) {}
|
|
return null;
|
|
}
|
|
|
|
function resolveInitial() {
|
|
var fromUrl = urlOverride();
|
|
if (fromUrl) return fromUrl;
|
|
var saved = readStored();
|
|
if (saved === 'light' || saved === 'dark') return saved;
|
|
return window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
|
}
|
|
|
|
function apply(theme) {
|
|
html.setAttribute('data-theme', theme);
|
|
label.textContent = viewerText(theme === 'dark' ? 'viewer.theme.dark' : 'viewer.theme.light');
|
|
btn.setAttribute('aria-pressed', theme === 'light' ? 'true' : 'false');
|
|
}
|
|
|
|
function toggle() {
|
|
var next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
|
|
apply(next);
|
|
writeStored(next);
|
|
}
|
|
|
|
apply(resolveInitial());
|
|
btn.addEventListener('click', toggle);
|
|
|
|
// Follow live OS theme changes while the user has no explicit preference.
|
|
try {
|
|
var media = window.matchMedia('(prefers-color-scheme: light)');
|
|
var onChange = function (e) {
|
|
var saved = readStored();
|
|
if (urlOverride() || saved === 'light' || saved === 'dark') return;
|
|
apply(e.matches ? 'light' : 'dark');
|
|
};
|
|
if (media.addEventListener) media.addEventListener('change', onChange);
|
|
else if (media.addListener) media.addListener(onChange);
|
|
} catch (_) {}
|
|
|
|
return { toggle: toggle };
|
|
})();
|
|
|
|
/* ARCHIFY:EXPORT */
|
|
|
|
/* ARCHIFY:MOTION_GOVERNOR */
|
|
|
|
/* Verified repository evidence is emitted only after the renderer checks
|
|
the authored GitHub revision, source blobs, and optional line ranges
|
|
against the explicit --repo-root. It remains outside the SVG so every
|
|
canonical visual export stays free of repository paths. */
|
|
Archify.sourceEvidence = (function () {
|
|
var element = document.getElementById('archify-source-evidence-data');
|
|
var payload = null;
|
|
var svgNamespace = 'http://www.w3.org/2000/svg';
|
|
if (element) {
|
|
try {
|
|
var parsed = JSON.parse(element.textContent || 'null');
|
|
if (parsed && parsed.verified === true && parsed.repository && parsed.nodes) payload = parsed;
|
|
} catch (_) {}
|
|
}
|
|
function installBeacons() {
|
|
if (!payload) return 0;
|
|
var svg = document.querySelector('.diagram-container svg');
|
|
if (!svg) return 0;
|
|
var installed = 0;
|
|
Array.prototype.forEach.call(svg.querySelectorAll('[data-node-id]'), function (node) {
|
|
var id = node.getAttribute('data-node-id');
|
|
var sources = payload.nodes[id];
|
|
if (!Array.isArray(sources) || !sources.length || node.querySelector('[data-source-evidence-beacon]')) return;
|
|
var shape = node.querySelector('[data-animate="node"]') || node.querySelector('[class*="c-"]');
|
|
var box;
|
|
try { box = (shape || node).getBBox(); } catch (_) { return; }
|
|
if (!box || !Number.isFinite(box.x) || !Number.isFinite(box.y) || !Number.isFinite(box.width) || box.width < 36) return;
|
|
|
|
var count = sources.length;
|
|
var label = viewerCount('viewer.passport.beacon', count);
|
|
var beacon = document.createElementNS(svgNamespace, 'g');
|
|
beacon.classList.add('source-evidence-beacon');
|
|
beacon.setAttribute('data-source-evidence-beacon', '');
|
|
beacon.setAttribute('aria-hidden', 'true');
|
|
var brandOffset = node.hasAttribute('data-node-brand') ? 22 : 0;
|
|
var title = document.createElementNS(svgNamespace, 'title');
|
|
title.textContent = label;
|
|
var plate = document.createElementNS(svgNamespace, 'rect');
|
|
plate.setAttribute('height', '13');
|
|
plate.setAttribute('rx', '6.5');
|
|
var text = document.createElementNS(svgNamespace, 'text');
|
|
text.setAttribute('y', '9.4');
|
|
text.textContent = viewerText('viewer.passport.sourceMarker') + ' ' + count;
|
|
beacon.appendChild(title);
|
|
beacon.appendChild(plate);
|
|
beacon.appendChild(text);
|
|
node.appendChild(beacon);
|
|
|
|
// Measure the real glyph advance, then clamp the plate between 24
|
|
// and 36px; a still-wider label is squeezed with textLength so the
|
|
// badge never overlaps the neighbouring brand mark or sigil.
|
|
var textWidth = 16;
|
|
try {
|
|
var measured = text.getComputedTextLength();
|
|
if (Number.isFinite(measured) && measured > 0) textWidth = measured;
|
|
} catch (_) {}
|
|
var plateWidth = Math.min(36, Math.max(24, textWidth + 8));
|
|
if (textWidth > plateWidth - 8) {
|
|
text.setAttribute('textLength', String(plateWidth - 8));
|
|
text.setAttribute('lengthAdjust', 'spacingAndGlyphs');
|
|
}
|
|
plate.setAttribute('width', String(plateWidth));
|
|
text.setAttribute('x', String(plateWidth / 2));
|
|
beacon.setAttribute('transform', 'translate(' + (box.x + box.width - 6 - brandOffset - plateWidth) + ' ' + (box.y + 4.5) + ')');
|
|
|
|
var originalLabel = node.getAttribute('aria-label') || '';
|
|
node.setAttribute('data-source-evidence-count', String(count));
|
|
node.setAttribute('data-source-evidence-original-label', originalLabel);
|
|
node.setAttribute('aria-label', (originalLabel ? originalLabel + ', ' : '') + viewerCount('viewer.passport.sourceCount', count));
|
|
installed += 1;
|
|
});
|
|
return installed;
|
|
}
|
|
return {
|
|
available: function () { return Boolean(payload); },
|
|
repository: function () { return payload ? payload.repository : null; },
|
|
node: function (id) {
|
|
var sources = payload && payload.nodes ? payload.nodes[id] : null;
|
|
return Array.isArray(sources) ? sources.slice() : [];
|
|
},
|
|
installBeacons: installBeacons
|
|
};
|
|
})();
|
|
Archify.sourceEvidence.installBeacons();
|
|
|
|
/* ARCHIFY:FOCUS */
|
|
|
|
/* ARCHIFY:INTENT_TRACE */
|
|
|
|
/* ============================================================
|
|
Adaptive Reader Shell — one diagram across laptop and monitor.
|
|
The canonical SVG and viewBox never change. On ordinary desktop pages,
|
|
wide diagrams and measured intrinsic tall workflows receive enough outer width to use the available
|
|
height without pushing summary cards below the viewport. Mobile,
|
|
embed, presentation, print, and unmarked non-wide diagrams retain their own
|
|
established layout contracts.
|
|
============================================================ */
|
|
// Fixed script-private participants; the CLI sees only the joint wait below.
|
|
const archifyLayoutOwners = { reader: null, viewerChrome: null };
|
|
Archify.waitForStableLayout = function (options) {
|
|
options = options || {};
|
|
var maximumFrames = Math.max(1, Number(options.maximumFrames) || 240);
|
|
var fontsReady = document.fonts && document.fonts.ready
|
|
? document.fonts.ready.catch(function () {})
|
|
: Promise.resolve();
|
|
return fontsReady.then(function () {
|
|
if (typeof options.schedule === 'function') options.schedule();
|
|
return new Promise(function (resolve, reject) {
|
|
var previous = '';
|
|
var stableFrames = 0;
|
|
var sampledFrames = 0;
|
|
function sample() {
|
|
sampledFrames += 1;
|
|
if (typeof options.pending === 'function' && options.pending()) {
|
|
previous = '';
|
|
stableFrames = 0;
|
|
} else {
|
|
var current = typeof options.snapshot === 'function' ? options.snapshot() : '';
|
|
if (current === previous) stableFrames += 1;
|
|
else {
|
|
previous = current;
|
|
stableFrames = 0;
|
|
}
|
|
if (stableFrames >= 3) {
|
|
resolve({ stable: true, snapshot: current, sampledFrames: sampledFrames });
|
|
return;
|
|
}
|
|
}
|
|
if (sampledFrames >= maximumFrames) {
|
|
reject(new Error(options.timeoutMessage || 'Layout did not reach stable dimensions.'));
|
|
return;
|
|
}
|
|
requestAnimationFrame(sample);
|
|
}
|
|
requestAnimationFrame(sample);
|
|
});
|
|
});
|
|
};
|
|
|
|
/* ARCHIFY:READER_LAYOUT */
|
|
/* ARCHIFY:CHROME_LAYOUT */
|
|
Archify.layoutStability = {
|
|
whenStable: function () {
|
|
var reader = archifyLayoutOwners.reader;
|
|
var chrome = archifyLayoutOwners.viewerChrome;
|
|
if (!reader || !chrome) {
|
|
return Promise.reject(new Error('Joint layout owners are unavailable.'));
|
|
}
|
|
var observedFontsReady = document.fonts && document.fonts.ready;
|
|
var fontCyclePending = false;
|
|
var fontGeneration = 0;
|
|
function scheduleOwners() { reader.schedule(); chrome.schedule(); }
|
|
function fontsPending() {
|
|
var fonts = document.fonts;
|
|
var ready = fonts && fonts.ready;
|
|
if (ready && (ready !== observedFontsReady || (fonts.status === 'loading' && !fontCyclePending))) {
|
|
observedFontsReady = ready;
|
|
fontCyclePending = true;
|
|
var generation = ++fontGeneration;
|
|
ready.catch(function () {}).then(function () {
|
|
if (generation !== fontGeneration) return;
|
|
fontCyclePending = false;
|
|
scheduleOwners();
|
|
});
|
|
}
|
|
return fontCyclePending || Boolean(fonts && fonts.status === 'loading');
|
|
}
|
|
return Archify.waitForStableLayout({
|
|
maximumFrames: 960,
|
|
schedule: scheduleOwners,
|
|
pending: function () {
|
|
// Recapture readiness for font cycles that begin during sampling.
|
|
return fontsPending() || reader.pending() || chrome.pending();
|
|
},
|
|
snapshot: function () {
|
|
return JSON.stringify([
|
|
['reader', reader.snapshot()],
|
|
['viewerChrome', chrome.snapshot()]
|
|
]);
|
|
},
|
|
timeoutMessage: 'Joint reader and viewer chrome layout did not reach stable dimensions.'
|
|
});
|
|
}
|
|
};
|
|
/* ARCHIFY:CAMERA */
|
|
/* ARCHIFY:RADAR */
|
|
|
|
/* ============================================================
|
|
Presentation Stage — a shareable, viewport-filling live view.
|
|
It changes only HTML layout and URL state; SVG semantics and export
|
|
serialization remain untouched. Escape first clears an active
|
|
focus, then exits the stage.
|
|
============================================================ */
|
|
Archify.presentation = (function () {
|
|
var html = document.documentElement;
|
|
var btn = document.getElementById('btn-present');
|
|
var label = document.getElementById('present-label');
|
|
var previousScrollY = 0;
|
|
|
|
function active() { return html.getAttribute('data-present') === 'true'; }
|
|
|
|
function updateUrl(next) {
|
|
try {
|
|
var url = new URL(window.location.href);
|
|
if (next) url.searchParams.set('present', '1');
|
|
else url.searchParams.delete('present');
|
|
history.replaceState(null, '', url.pathname + url.search + url.hash);
|
|
} catch (_) {}
|
|
}
|
|
|
|
function render(next) {
|
|
btn.setAttribute('aria-pressed', next ? 'true' : 'false');
|
|
btn.setAttribute('aria-label', viewerText(next ? 'viewer.present.exit' : 'viewer.present.enter'));
|
|
btn.title = viewerText(next ? 'viewer.present.exit.title' : 'viewer.present.enter.title');
|
|
label.textContent = viewerText(next ? 'viewer.present.exit.label' : 'viewer.present.present');
|
|
}
|
|
|
|
function setActive(next, options) {
|
|
options = options || {};
|
|
next = Boolean(next);
|
|
if (next === active()) {
|
|
render(next);
|
|
return next;
|
|
}
|
|
if (next) {
|
|
if (Archify.semanticLens && typeof Archify.semanticLens.clearPreview === 'function') Archify.semanticLens.clearPreview();
|
|
previousScrollY = window.scrollY || 0;
|
|
html.setAttribute('data-present', 'true');
|
|
try { window.scrollTo(0, 0); } catch (_) {}
|
|
} else {
|
|
html.removeAttribute('data-present');
|
|
}
|
|
render(next);
|
|
if (options.updateUrl !== false) updateUrl(next);
|
|
requestAnimationFrame(function () {
|
|
if (Archify.view && typeof Archify.view.reset === 'function') {
|
|
Archify.view.reset({ automatic: true });
|
|
requestAnimationFrame(function () {
|
|
if (Archify.view && typeof Archify.view.sync === 'function') Archify.view.sync();
|
|
});
|
|
}
|
|
if (!next && previousScrollY) {
|
|
try { window.scrollTo(0, previousScrollY); } catch (_) {}
|
|
}
|
|
});
|
|
return next;
|
|
}
|
|
|
|
function toggle() { return setActive(!active()); }
|
|
|
|
render(active());
|
|
btn.addEventListener('click', toggle);
|
|
|
|
return {
|
|
enter: function () { return setActive(true); },
|
|
exit: function () { return setActive(false); },
|
|
toggle: toggle,
|
|
active: active
|
|
};
|
|
})();
|
|
|
|
/* ARCHIFY:NODE_FINDER */
|
|
|
|
/* ARCHIFY:NODE_OUTLINE */
|
|
|
|
/* ARCHIFY:ROUTE_PROBE */
|
|
|
|
/* ARCHIFY:SEMANTIC_LENS */
|
|
|
|
/* ============================================================
|
|
Diagram Guide — a factual command deck over existing interactions.
|
|
Counts come from compiled semantics; actions delegate to Finder, Route
|
|
Probe, Semantic Radar, Semantic Lens, Presentation, theme, export, and
|
|
camera without adding a second command implementation or SVG state.
|
|
============================================================ */
|
|
Archify.guide = (function () {
|
|
var html = document.documentElement;
|
|
var container = document.querySelector('.diagram-container');
|
|
var svg = container.querySelector(':scope > svg');
|
|
var trigger = document.getElementById('btn-diagram-guide');
|
|
var panel = document.getElementById('diagram-guide');
|
|
var closeBtn = document.getElementById('diagram-guide-close');
|
|
var stats = document.getElementById('diagram-guide-stats');
|
|
var actions = document.getElementById('diagram-guide-actions');
|
|
var feedback = document.getElementById('diagram-guide-feedback');
|
|
var routePanel = document.getElementById('route-probe');
|
|
var returnFocus = null;
|
|
|
|
function relationshipCount() {
|
|
var seen = {};
|
|
Array.prototype.forEach.call(svg.querySelectorAll('[data-edge-from][data-edge-to]'), function (edge) {
|
|
var key = edge.getAttribute('data-edge-key') || [
|
|
edge.getAttribute('data-edge-from'),
|
|
edge.getAttribute('data-edge-to'),
|
|
edge.getAttribute('data-edge-label') || ''
|
|
].join('\u0000');
|
|
seen[key] = true;
|
|
});
|
|
return Object.keys(seen).length;
|
|
}
|
|
function renderFacts() {
|
|
var nodes = svg.querySelectorAll('[data-node-id]').length;
|
|
var relationships = relationshipCount();
|
|
stats.textContent = viewerText('viewer.guide.facts', {
|
|
nodes: viewerCount('viewer.guide.fact.node', nodes),
|
|
relationships: viewerCount('viewer.guide.fact.relationship', relationships)
|
|
});
|
|
}
|
|
function actionButtons() {
|
|
return Array.prototype.slice.call(actions.querySelectorAll('.diagram-guide-action:not(:disabled)'));
|
|
}
|
|
function close(options) {
|
|
options = options || {};
|
|
panel.hidden = true;
|
|
html.removeAttribute('data-guide-open');
|
|
routePanel.removeAttribute('data-guide-open');
|
|
trigger.setAttribute('aria-expanded', 'false');
|
|
trigger.setAttribute('aria-label', viewerText('viewer.guide.open'));
|
|
feedback.textContent = '';
|
|
if (options.restoreFocus !== false) {
|
|
var target = trigger.hidden ? returnFocus : trigger;
|
|
if (target && typeof target.focus === 'function') target.focus();
|
|
}
|
|
return false;
|
|
}
|
|
function open() {
|
|
if (html.getAttribute('data-embed') === 'true') return false;
|
|
if (Archify.semanticLens && typeof Archify.semanticLens.clearPreview === 'function') Archify.semanticLens.clearPreview();
|
|
if (Archify.exportMenu && Archify.exportMenu.isOpen()) Archify.exportMenu.close(false);
|
|
if (Archify.finder && Archify.finder.isOpen()) Archify.finder.close({ restoreFocus: false });
|
|
if (Archify.radar && Archify.radar.isOpen()) Archify.radar.close({ restoreFocus: false });
|
|
if (Archify.semanticLens && Archify.semanticLens.isOpen()) Archify.semanticLens.close({ restoreFocus: false });
|
|
if (Archify.routeProbe && Archify.routeProbe.isJourneyPlaying && Archify.routeProbe.isJourneyPlaying()) {
|
|
Archify.routeProbe.pauseJourney({ preserveElapsed: true, reason: 'guide' });
|
|
}
|
|
returnFocus = document.activeElement;
|
|
renderFacts();
|
|
panel.hidden = false;
|
|
html.setAttribute('data-guide-open', 'true');
|
|
routePanel.setAttribute('data-guide-open', 'true');
|
|
trigger.setAttribute('aria-expanded', 'true');
|
|
trigger.setAttribute('aria-label', viewerText('viewer.guide.close'));
|
|
feedback.textContent = '';
|
|
requestAnimationFrame(function () {
|
|
var first = actionButtons()[0];
|
|
if (first) first.focus();
|
|
});
|
|
return true;
|
|
}
|
|
function toggle() { return panel.hidden ? open() : close(); }
|
|
function execute(action) {
|
|
feedback.textContent = '';
|
|
close({ restoreFocus: false });
|
|
if (action === 'find') return Archify.finder.open();
|
|
if (action === 'route') return Archify.routeProbe.begin({ focusNode: true });
|
|
if (action === 'map') return Archify.radar.open();
|
|
if (action === 'lens') return Archify.semanticLens.open();
|
|
if (action === 'present') return Archify.presentation.enter();
|
|
if (action === 'export') return Archify.exportMenu.open();
|
|
if (action === 'theme') return Archify.theme.toggle();
|
|
if (action === 'preset') return Archify.preset.cycle();
|
|
if (action === 'reset') return Archify.view.reset();
|
|
if (action === 'zoom-in') return Archify.view.zoomIn();
|
|
if (action === 'zoom-out') return Archify.view.zoomOut();
|
|
return false;
|
|
}
|
|
function actionForKey(key) {
|
|
return {
|
|
'/': 'find',
|
|
r: 'route',
|
|
m: 'map',
|
|
l: 'lens',
|
|
f: 'present',
|
|
e: 'export',
|
|
t: 'theme',
|
|
s: 'preset',
|
|
'0': 'reset',
|
|
'+': 'zoom-in',
|
|
'=': 'zoom-in',
|
|
'-': 'zoom-out'
|
|
}[key] || null;
|
|
}
|
|
|
|
trigger.addEventListener('click', toggle);
|
|
closeBtn.addEventListener('click', function () { close(); });
|
|
actions.addEventListener('click', function (event) {
|
|
var button = event.target.closest('[data-guide-action]');
|
|
if (!button || button.disabled) return;
|
|
event.stopPropagation();
|
|
execute(button.getAttribute('data-guide-action'));
|
|
});
|
|
panel.addEventListener('keydown', function (event) {
|
|
if (event.key === 'Escape' || event.key === '?') {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
close();
|
|
return;
|
|
}
|
|
var buttons = actionButtons();
|
|
var index = buttons.indexOf(document.activeElement);
|
|
var next = null;
|
|
if (index >= 0 && event.key === 'ArrowRight') next = (index + 1) % buttons.length;
|
|
else if (index >= 0 && event.key === 'ArrowDown') next = (index + 1) % buttons.length;
|
|
else if (index >= 0 && event.key === 'ArrowLeft') next = (index - 1 + buttons.length) % buttons.length;
|
|
else if (index >= 0 && event.key === 'ArrowUp') next = (index - 1 + buttons.length) % buttons.length;
|
|
else if (event.key === 'Home' && buttons.length) next = 0;
|
|
else if (event.key === 'End' && buttons.length) next = buttons.length - 1;
|
|
if (next !== null) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
buttons[next].focus();
|
|
return;
|
|
}
|
|
var action = actionForKey(event.key.length === 1 ? event.key.toLowerCase() : event.key);
|
|
if (!action) return;
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
execute(action);
|
|
});
|
|
document.addEventListener('click', function (event) {
|
|
if (!panel.hidden && !panel.contains(event.target) && event.target !== trigger) close({ restoreFocus: false });
|
|
});
|
|
|
|
renderFacts();
|
|
return {
|
|
open: open,
|
|
close: close,
|
|
toggle: toggle,
|
|
execute: execute,
|
|
isOpen: function () { return !panel.hidden; },
|
|
facts: function () {
|
|
return {
|
|
nodes: svg.querySelectorAll('[data-node-id]').length,
|
|
relationships: relationshipCount()
|
|
};
|
|
}
|
|
};
|
|
})();
|
|
|
|
/* ============================================================
|
|
Global keyboard shortcuts
|
|
? -> open Diagram Guide
|
|
T -> toggle theme
|
|
S -> cycle visual style
|
|
E -> open export menu
|
|
F -> toggle presentation stage
|
|
M -> toggle Semantic Radar
|
|
L -> toggle Semantic Lens
|
|
R -> start/clear Route Probe
|
|
/ -> open node finder or the active route endpoint picker
|
|
+ / - -> zoom, 0 -> reset view
|
|
Escape -> clear temporary trace/focus/view first, then exit presentation
|
|
Ignored when focus is inside an input/textarea/contenteditable.
|
|
============================================================ */
|
|
document.addEventListener('keydown', function (e) {
|
|
if (e.metaKey || e.ctrlKey || e.altKey) return;
|
|
if (e.defaultPrevented) return;
|
|
var t = e.target;
|
|
if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return;
|
|
if (Archify.preset && Archify.preset.isOpen() && e.key !== 'Escape' && e.key !== 's' && e.key !== 'S') {
|
|
Archify.preset.close(false);
|
|
}
|
|
if (e.key === '?') {
|
|
e.preventDefault();
|
|
Archify.guide.toggle();
|
|
} else if (e.key === '/') {
|
|
e.preventDefault();
|
|
Archify.finder.open();
|
|
} else if (e.key === 't' || e.key === 'T') {
|
|
e.preventDefault();
|
|
Archify.theme.toggle();
|
|
} else if (e.key === 's' || e.key === 'S') {
|
|
e.preventDefault();
|
|
Archify.preset.cycle();
|
|
} else if (e.key === 'e' || e.key === 'E') {
|
|
e.preventDefault();
|
|
if (!Archify.exportMenu.isOpen()) Archify.exportMenu.open();
|
|
} else if (e.key === 'f' || e.key === 'F') {
|
|
e.preventDefault();
|
|
Archify.presentation.toggle();
|
|
} else if (e.key === 'm' || e.key === 'M') {
|
|
e.preventDefault();
|
|
Archify.radar.toggle();
|
|
} else if (e.key === 'l' || e.key === 'L') {
|
|
e.preventDefault();
|
|
Archify.semanticLens.toggle();
|
|
} else if (e.key === 'r' || e.key === 'R') {
|
|
e.preventDefault();
|
|
Archify.routeProbe.toggle({ focusNode: true });
|
|
} else if (e.key === '+' || e.key === '=') {
|
|
e.preventDefault();
|
|
Archify.view.zoomIn();
|
|
} else if (e.key === '-') {
|
|
e.preventDefault();
|
|
Archify.view.zoomOut();
|
|
} else if (e.key === '0') {
|
|
e.preventDefault();
|
|
Archify.view.reset();
|
|
} else if (e.key === 'Escape' && Archify.preset.isOpen()) {
|
|
e.preventDefault();
|
|
Archify.preset.close(true);
|
|
} else if (e.key === 'Escape' && Archify.semanticLens.isOpen()) {
|
|
e.preventDefault();
|
|
Archify.semanticLens.close({ restoreFocus: true });
|
|
} else if (e.key === 'Escape' && Archify.semanticLens.active()) {
|
|
e.preventDefault();
|
|
Archify.semanticLens.clear({ preserveView: true });
|
|
} else if (e.key === 'Escape' && Archify.guide.isOpen()) {
|
|
e.preventDefault();
|
|
Archify.guide.close({ restoreFocus: true });
|
|
} else if (e.key === 'Escape' && Archify.radar.isOpen()) {
|
|
e.preventDefault();
|
|
Archify.radar.close({ restoreFocus: true });
|
|
} else if (e.key === 'Escape' && Archify.routeProbe.active()) {
|
|
e.preventDefault();
|
|
Archify.routeProbe.escape({ restoreFocus: true });
|
|
} else if (e.key === 'Escape' && Archify.intentTrace.active()) {
|
|
e.preventDefault();
|
|
Archify.intentTrace.clear();
|
|
} else if (e.key === 'Escape' && Archify.focus.active()) {
|
|
e.preventDefault();
|
|
Archify.focus.clear({ restoreFocus: true });
|
|
} else if (e.key === 'Escape' && Archify.presentation.active()) {
|
|
e.preventDefault();
|
|
Archify.presentation.exit();
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|