living-documentation 7.14.0 → 7.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/frontend/admin.html +91 -0
- package/dist/src/frontend/config.js +10 -0
- package/dist/src/frontend/documents.js +76 -0
- package/dist/src/frontend/i18n/en.json +10 -0
- package/dist/src/frontend/i18n/fr.json +10 -0
- package/dist/src/frontend/index.html +86 -0
- package/dist/src/frontend/sidebar.js +74 -0
- package/dist/src/frontend/state.js +3 -0
- package/dist/src/lib/config.d.ts +3 -0
- package/dist/src/lib/config.d.ts.map +1 -1
- package/dist/src/lib/config.js +3 -0
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/routes/config.d.ts.map +1 -1
- package/dist/src/routes/config.js +13 -0
- package/dist/src/routes/config.js.map +1 -1
- package/package.json +1 -1
|
@@ -274,6 +274,73 @@
|
|
|
274
274
|
info on each node — useful for diagnosing snap-to-grid issues.
|
|
275
275
|
</p>
|
|
276
276
|
</div>
|
|
277
|
+
<div class="px-5 py-4">
|
|
278
|
+
<label class="flex items-center gap-3 cursor-pointer">
|
|
279
|
+
<input
|
|
280
|
+
id="field-exclusive-folder"
|
|
281
|
+
name="exclusiveFolderExpansion"
|
|
282
|
+
type="checkbox"
|
|
283
|
+
class="w-4 h-4 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500"
|
|
284
|
+
/>
|
|
285
|
+
<span
|
|
286
|
+
class="text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
287
|
+
data-i18n="admin.appearance.exclusive_folder_label">Exclusive folder expansion in sidebar</span
|
|
288
|
+
>
|
|
289
|
+
</label>
|
|
290
|
+
<p
|
|
291
|
+
class="mt-1 text-xs text-gray-400 dark:text-gray-500 ml-7"
|
|
292
|
+
data-i18n="admin.appearance.exclusive_folder_hint"
|
|
293
|
+
>
|
|
294
|
+
When enabled, opening a folder in the sidebar automatically
|
|
295
|
+
closes any other open folder at the same level (and its
|
|
296
|
+
children).
|
|
297
|
+
</p>
|
|
298
|
+
</div>
|
|
299
|
+
<div class="px-5 py-4">
|
|
300
|
+
<label class="flex items-center gap-3 cursor-pointer">
|
|
301
|
+
<input
|
|
302
|
+
id="field-exclusive-category"
|
|
303
|
+
name="exclusiveCategoryExpansion"
|
|
304
|
+
type="checkbox"
|
|
305
|
+
class="w-4 h-4 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500"
|
|
306
|
+
/>
|
|
307
|
+
<span
|
|
308
|
+
class="text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
309
|
+
data-i18n="admin.appearance.exclusive_category_label">Exclusive category expansion in sidebar</span
|
|
310
|
+
>
|
|
311
|
+
</label>
|
|
312
|
+
<p
|
|
313
|
+
class="mt-1 text-xs text-gray-400 dark:text-gray-500 ml-7"
|
|
314
|
+
data-i18n="admin.appearance.exclusive_category_hint"
|
|
315
|
+
>
|
|
316
|
+
When enabled, opening a category automatically closes any
|
|
317
|
+
other open category under the same parent folder.
|
|
318
|
+
</p>
|
|
319
|
+
</div>
|
|
320
|
+
<div class="px-5 py-4 space-y-1.5">
|
|
321
|
+
<label
|
|
322
|
+
class="block text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
323
|
+
for="field-code-max-height"
|
|
324
|
+
data-i18n="admin.appearance.code_max_height_label"
|
|
325
|
+
>Code block max height (px)</label
|
|
326
|
+
>
|
|
327
|
+
<input
|
|
328
|
+
id="field-code-max-height"
|
|
329
|
+
name="codeBlockMaxHeight"
|
|
330
|
+
type="number"
|
|
331
|
+
min="0"
|
|
332
|
+
max="5000"
|
|
333
|
+
step="10"
|
|
334
|
+
class="w-full px-3 py-2 text-sm rounded-lg border border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
335
|
+
placeholder="400"
|
|
336
|
+
/>
|
|
337
|
+
<p
|
|
338
|
+
class="text-xs text-gray-400 dark:text-gray-500"
|
|
339
|
+
data-i18n="admin.appearance.code_max_height_hint"
|
|
340
|
+
>
|
|
341
|
+
Longer code blocks get a collapse/expand button. Set to 0 to disable.
|
|
342
|
+
</p>
|
|
343
|
+
</div>
|
|
277
344
|
<div class="px-5 py-4 space-y-1.5">
|
|
278
345
|
<label
|
|
279
346
|
class="block text-sm font-medium text-gray-700 dark:text-gray-300"
|
|
@@ -526,6 +593,14 @@
|
|
|
526
593
|
cfg.filenamePattern || "";
|
|
527
594
|
document.getElementById("field-debug").checked =
|
|
528
595
|
!!cfg.showDiagramDebug;
|
|
596
|
+
document.getElementById("field-exclusive-folder").checked =
|
|
597
|
+
!!cfg.exclusiveFolderExpansion;
|
|
598
|
+
document.getElementById("field-exclusive-category").checked =
|
|
599
|
+
!!cfg.exclusiveCategoryExpansion;
|
|
600
|
+
document.getElementById("field-code-max-height").value =
|
|
601
|
+
typeof cfg.codeBlockMaxHeight === "number"
|
|
602
|
+
? cfg.codeBlockMaxHeight
|
|
603
|
+
: 400;
|
|
529
604
|
document.getElementById("field-blocked-extensions").value =
|
|
530
605
|
(cfg.blockedFileExtensions || []).join(" ");
|
|
531
606
|
updatePreview(cfg.filenamePattern);
|
|
@@ -568,6 +643,22 @@
|
|
|
568
643
|
language: document.getElementById("field-language").value,
|
|
569
644
|
filenamePattern,
|
|
570
645
|
showDiagramDebug: document.getElementById("field-debug").checked,
|
|
646
|
+
exclusiveFolderExpansion: document.getElementById(
|
|
647
|
+
"field-exclusive-folder",
|
|
648
|
+
).checked,
|
|
649
|
+
exclusiveCategoryExpansion: document.getElementById(
|
|
650
|
+
"field-exclusive-category",
|
|
651
|
+
).checked,
|
|
652
|
+
codeBlockMaxHeight: Math.max(
|
|
653
|
+
0,
|
|
654
|
+
Math.min(
|
|
655
|
+
5000,
|
|
656
|
+
parseInt(
|
|
657
|
+
document.getElementById("field-code-max-height").value,
|
|
658
|
+
10,
|
|
659
|
+
) || 0,
|
|
660
|
+
),
|
|
661
|
+
),
|
|
571
662
|
diagramNodePalette: [...nodePalette],
|
|
572
663
|
diagramEdgePalette: [...edgePalette],
|
|
573
664
|
sourceRoot: sourceRootRaw === "" ? null : sourceRootRaw,
|
|
@@ -12,6 +12,16 @@ async function loadConfig() {
|
|
|
12
12
|
document.getElementById("welcome-pattern").textContent =
|
|
13
13
|
cfg.filenamePattern + ".md";
|
|
14
14
|
}
|
|
15
|
+
exclusiveFolderExpansion = !!cfg.exclusiveFolderExpansion;
|
|
16
|
+
exclusiveCategoryExpansion = !!cfg.exclusiveCategoryExpansion;
|
|
17
|
+
codeBlockMaxHeight =
|
|
18
|
+
typeof cfg.codeBlockMaxHeight === "number" ? cfg.codeBlockMaxHeight : 400;
|
|
19
|
+
if (codeBlockMaxHeight > 0) {
|
|
20
|
+
document.documentElement.style.setProperty(
|
|
21
|
+
"--ld-code-max-h",
|
|
22
|
+
codeBlockMaxHeight + "px",
|
|
23
|
+
);
|
|
24
|
+
}
|
|
15
25
|
} catch {
|
|
16
26
|
await window.initI18n('en');
|
|
17
27
|
/* non-fatal */
|
|
@@ -27,6 +27,9 @@ function _wireDocContent(html) {
|
|
|
27
27
|
hljs.highlightElement(block);
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
+
_decorateCodeBlocksWithCopy(contentEl);
|
|
31
|
+
_decorateCollapsibleCodeBlocks(contentEl);
|
|
32
|
+
|
|
30
33
|
contentEl.querySelectorAll("a[href]").forEach((a) => {
|
|
31
34
|
const href = a.getAttribute("href");
|
|
32
35
|
const m = href && href.match(/[?&]doc=([^&#]+)/);
|
|
@@ -85,6 +88,79 @@ function refreshSearchInCurrentDoc() {
|
|
|
85
88
|
|
|
86
89
|
window.refreshSearchInCurrentDoc = refreshSearchInCurrentDoc;
|
|
87
90
|
|
|
91
|
+
function _decorateCodeBlocksWithCopy(contentEl) {
|
|
92
|
+
const copyLabel =
|
|
93
|
+
(typeof window.t === "function" && window.t("doc.code_copy")) || "Copy";
|
|
94
|
+
const copiedLabel =
|
|
95
|
+
(typeof window.t === "function" && window.t("doc.code_copied")) ||
|
|
96
|
+
"Copied!";
|
|
97
|
+
contentEl.querySelectorAll("pre").forEach((pre) => {
|
|
98
|
+
const code = pre.querySelector("code");
|
|
99
|
+
if (!code) return;
|
|
100
|
+
if (pre.querySelector(".ld-code-copy")) return;
|
|
101
|
+
const btn = document.createElement("button");
|
|
102
|
+
btn.type = "button";
|
|
103
|
+
btn.className = "ld-code-copy";
|
|
104
|
+
btn.title = copyLabel;
|
|
105
|
+
btn.setAttribute("aria-label", copyLabel);
|
|
106
|
+
btn.innerHTML =
|
|
107
|
+
'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="5" width="8" height="9" rx="1.5"/><path d="M3 11V3a1 1 0 0 1 1-1h7"/></svg>';
|
|
108
|
+
btn.addEventListener("click", async (e) => {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
e.stopPropagation();
|
|
111
|
+
const text = code.innerText;
|
|
112
|
+
try {
|
|
113
|
+
await navigator.clipboard.writeText(text);
|
|
114
|
+
} catch {
|
|
115
|
+
const ta = document.createElement("textarea");
|
|
116
|
+
ta.value = text;
|
|
117
|
+
ta.style.position = "fixed";
|
|
118
|
+
ta.style.opacity = "0";
|
|
119
|
+
document.body.appendChild(ta);
|
|
120
|
+
ta.select();
|
|
121
|
+
try {
|
|
122
|
+
document.execCommand("copy");
|
|
123
|
+
} catch {
|
|
124
|
+
/* ignore */
|
|
125
|
+
}
|
|
126
|
+
document.body.removeChild(ta);
|
|
127
|
+
}
|
|
128
|
+
btn.classList.add("ld-copied");
|
|
129
|
+
btn.title = copiedLabel;
|
|
130
|
+
btn.innerHTML =
|
|
131
|
+
'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5 6.5 12 13 4.5"/></svg>';
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
btn.classList.remove("ld-copied");
|
|
134
|
+
btn.title = copyLabel;
|
|
135
|
+
btn.innerHTML =
|
|
136
|
+
'<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="5" width="8" height="9" rx="1.5"/><path d="M3 11V3a1 1 0 0 1 1-1h7"/></svg>';
|
|
137
|
+
}, 1500);
|
|
138
|
+
});
|
|
139
|
+
pre.appendChild(btn);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function _decorateCollapsibleCodeBlocks(contentEl) {
|
|
144
|
+
if (typeof codeBlockMaxHeight !== "number" || codeBlockMaxHeight <= 0) return;
|
|
145
|
+
const more = (typeof window.t === "function" && window.t("doc.code_show_more")) || "▾ Show more";
|
|
146
|
+
const less = (typeof window.t === "function" && window.t("doc.code_show_less")) || "▴ Show less";
|
|
147
|
+
contentEl.querySelectorAll("pre").forEach((pre) => {
|
|
148
|
+
if (!pre.querySelector("code")) return;
|
|
149
|
+
if (pre.scrollHeight <= codeBlockMaxHeight + 8) return;
|
|
150
|
+
pre.classList.add("ld-collapsible");
|
|
151
|
+
const btn = document.createElement("button");
|
|
152
|
+
btn.type = "button";
|
|
153
|
+
btn.className = "ld-code-toggle";
|
|
154
|
+
btn.textContent = more;
|
|
155
|
+
btn.addEventListener("click", (e) => {
|
|
156
|
+
e.preventDefault();
|
|
157
|
+
const expanded = pre.classList.toggle("ld-expanded");
|
|
158
|
+
btn.textContent = expanded ? less : more;
|
|
159
|
+
});
|
|
160
|
+
pre.appendChild(btn);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
88
164
|
async function loadDocuments() {
|
|
89
165
|
try {
|
|
90
166
|
[allDocs] = await Promise.all([
|
|
@@ -92,6 +92,10 @@
|
|
|
92
92
|
"doc.saving": "Saving…",
|
|
93
93
|
"doc.failed_to_load": "Failed to load document: ",
|
|
94
94
|
"doc.copied": "✓ Copied!",
|
|
95
|
+
"doc.code_show_more": "▾ Show more",
|
|
96
|
+
"doc.code_show_less": "▴ Show less",
|
|
97
|
+
"doc.code_copy": "Copy",
|
|
98
|
+
"doc.code_copied": "Copied!",
|
|
95
99
|
|
|
96
100
|
"metadata.button": "Metadata",
|
|
97
101
|
"metadata.button_title": "Manage source-file metadata",
|
|
@@ -316,6 +320,12 @@
|
|
|
316
320
|
"admin.appearance.language_hint": "Interface language for all pages.",
|
|
317
321
|
"admin.appearance.debug_label": "Show debug button in diagram editor",
|
|
318
322
|
"admin.appearance.debug_hint": "Displays a Debug button that overlays raw position and size info on each node — useful for diagnosing snap-to-grid issues.",
|
|
323
|
+
"admin.appearance.exclusive_folder_label": "Exclusive folder expansion in sidebar",
|
|
324
|
+
"admin.appearance.exclusive_folder_hint": "When enabled, opening a folder in the sidebar automatically closes any other open folder at the same level (and its children).",
|
|
325
|
+
"admin.appearance.exclusive_category_label": "Exclusive category expansion in sidebar",
|
|
326
|
+
"admin.appearance.exclusive_category_hint": "When enabled, opening a category automatically closes any other open category under the same parent folder.",
|
|
327
|
+
"admin.appearance.code_max_height_label": "Code block max height (px)",
|
|
328
|
+
"admin.appearance.code_max_height_hint": "Longer code blocks get a collapse/expand button. Set to 0 to disable.",
|
|
319
329
|
|
|
320
330
|
"admin.pattern.label": "Filename Pattern",
|
|
321
331
|
"admin.pattern.hint": "Parsed for date, category, and title.",
|
|
@@ -92,6 +92,10 @@
|
|
|
92
92
|
"doc.saving": "Enregistrement…",
|
|
93
93
|
"doc.failed_to_load": "Impossible de charger le document : ",
|
|
94
94
|
"doc.copied": "✓ Copié !",
|
|
95
|
+
"doc.code_show_more": "▾ Afficher plus",
|
|
96
|
+
"doc.code_show_less": "▴ Réduire",
|
|
97
|
+
"doc.code_copy": "Copier",
|
|
98
|
+
"doc.code_copied": "Copié !",
|
|
95
99
|
|
|
96
100
|
"metadata.button": "Métadonnées",
|
|
97
101
|
"metadata.button_title": "Gérer les métadonnées des fichiers source",
|
|
@@ -316,6 +320,12 @@
|
|
|
316
320
|
"admin.appearance.language_hint": "Langue de l'interface pour toutes les pages.",
|
|
317
321
|
"admin.appearance.debug_label": "Afficher le bouton debug dans l'éditeur de diagrammes",
|
|
318
322
|
"admin.appearance.debug_hint": "Affiche un bouton Debug qui superpose les informations brutes de position et de taille sur chaque nœud — utile pour diagnostiquer les problèmes de grille.",
|
|
323
|
+
"admin.appearance.exclusive_folder_label": "Ouverture exclusive des dossiers dans la barre latérale",
|
|
324
|
+
"admin.appearance.exclusive_folder_hint": "Si activé, l'ouverture d'un dossier dans la barre latérale referme automatiquement tout autre dossier ouvert au même niveau (ainsi que ses enfants).",
|
|
325
|
+
"admin.appearance.exclusive_category_label": "Ouverture exclusive des catégories dans la barre latérale",
|
|
326
|
+
"admin.appearance.exclusive_category_hint": "Si activé, l'ouverture d'une catégorie referme automatiquement toute autre catégorie ouverte sous le même dossier parent.",
|
|
327
|
+
"admin.appearance.code_max_height_label": "Hauteur max des blocs de code (px)",
|
|
328
|
+
"admin.appearance.code_max_height_hint": "Les blocs plus longs reçoivent un bouton « Afficher plus / Réduire ». Mettre 0 pour désactiver.",
|
|
319
329
|
|
|
320
330
|
"admin.pattern.label": "Modèle de nom de fichier",
|
|
321
331
|
"admin.pattern.hint": "Analysé pour extraire la date, la catégorie et le titre.",
|
|
@@ -81,6 +81,92 @@
|
|
|
81
81
|
max-height: 9999px;
|
|
82
82
|
opacity: 1;
|
|
83
83
|
}
|
|
84
|
+
.category-docs.no-transition {
|
|
85
|
+
transition: none !important;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Code block decorations (copy + collapse) */
|
|
89
|
+
.prose pre {
|
|
90
|
+
position: relative;
|
|
91
|
+
}
|
|
92
|
+
.ld-code-copy {
|
|
93
|
+
position: absolute;
|
|
94
|
+
top: 0.4rem;
|
|
95
|
+
right: 0.5rem;
|
|
96
|
+
z-index: 2;
|
|
97
|
+
width: 28px;
|
|
98
|
+
height: 28px;
|
|
99
|
+
display: inline-flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: center;
|
|
102
|
+
border-radius: 0.375rem;
|
|
103
|
+
background: rgba(255, 255, 255, 0.08);
|
|
104
|
+
color: #d1d5db;
|
|
105
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
106
|
+
cursor: pointer;
|
|
107
|
+
opacity: 0;
|
|
108
|
+
transition:
|
|
109
|
+
opacity 0.15s ease,
|
|
110
|
+
background 0.15s ease;
|
|
111
|
+
font-size: 0.8rem;
|
|
112
|
+
line-height: 1;
|
|
113
|
+
}
|
|
114
|
+
.prose pre:hover .ld-code-copy,
|
|
115
|
+
.ld-code-copy:focus-visible,
|
|
116
|
+
.ld-code-copy.ld-copied {
|
|
117
|
+
opacity: 1;
|
|
118
|
+
}
|
|
119
|
+
.ld-code-copy:hover {
|
|
120
|
+
background: rgba(255, 255, 255, 0.2);
|
|
121
|
+
}
|
|
122
|
+
.ld-code-copy.ld-copied {
|
|
123
|
+
background: rgba(34, 197, 94, 0.25);
|
|
124
|
+
color: #86efac;
|
|
125
|
+
border-color: rgba(34, 197, 94, 0.4);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Collapsible code blocks (set via --ld-code-max-h from .living-doc.json) */
|
|
129
|
+
pre.ld-collapsible {
|
|
130
|
+
max-height: var(--ld-code-max-h, 400px);
|
|
131
|
+
overflow: hidden;
|
|
132
|
+
position: relative;
|
|
133
|
+
}
|
|
134
|
+
pre.ld-collapsible.ld-expanded {
|
|
135
|
+
max-height: none;
|
|
136
|
+
overflow: auto;
|
|
137
|
+
}
|
|
138
|
+
pre.ld-collapsible:not(.ld-expanded)::after {
|
|
139
|
+
content: "";
|
|
140
|
+
position: absolute;
|
|
141
|
+
left: 0;
|
|
142
|
+
right: 0;
|
|
143
|
+
bottom: 0;
|
|
144
|
+
height: 64px;
|
|
145
|
+
pointer-events: none;
|
|
146
|
+
background: linear-gradient(
|
|
147
|
+
to bottom,
|
|
148
|
+
rgba(40, 44, 52, 0) 0%,
|
|
149
|
+
rgba(40, 44, 52, 0.85) 100%
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
.ld-code-toggle {
|
|
153
|
+
position: absolute;
|
|
154
|
+
right: 0.5rem;
|
|
155
|
+
bottom: 0.4rem;
|
|
156
|
+
z-index: 1;
|
|
157
|
+
padding: 0.15rem 0.6rem;
|
|
158
|
+
border-radius: 0.375rem;
|
|
159
|
+
background: rgba(255, 255, 255, 0.12);
|
|
160
|
+
color: #e5e7eb;
|
|
161
|
+
font-size: 0.75rem;
|
|
162
|
+
font-weight: 500;
|
|
163
|
+
border: 1px solid rgba(255, 255, 255, 0.18);
|
|
164
|
+
cursor: pointer;
|
|
165
|
+
transition: background 0.15s ease;
|
|
166
|
+
}
|
|
167
|
+
.ld-code-toggle:hover {
|
|
168
|
+
background: rgba(255, 255, 255, 0.22);
|
|
169
|
+
}
|
|
84
170
|
|
|
85
171
|
/* Color swatch selection ring */
|
|
86
172
|
.color-swatch-btn.selected-swatch,
|
|
@@ -202,6 +202,57 @@ function renderDocItem(doc) {
|
|
|
202
202
|
</button>`;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
function setInstantCollapse(el) {
|
|
206
|
+
el.classList.add("no-transition");
|
|
207
|
+
el.classList.add("collapsed");
|
|
208
|
+
el.classList.remove("expanded");
|
|
209
|
+
// Force reflow so the collapsed state is committed while transitions are off
|
|
210
|
+
void el.offsetHeight;
|
|
211
|
+
requestAnimationFrame(() => el.classList.remove("no-transition"));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function collapseCategoryByKey(key, instant = false) {
|
|
215
|
+
const parts = key.split("|");
|
|
216
|
+
const catNodeId =
|
|
217
|
+
"cat-" + parts.map((p) => p.replace(/\W/g, "-")).join("-");
|
|
218
|
+
const el = document.getElementById(catNodeId);
|
|
219
|
+
const arrow = document.getElementById("arrow-" + catNodeId);
|
|
220
|
+
if (el) {
|
|
221
|
+
if (instant) setInstantCollapse(el);
|
|
222
|
+
else {
|
|
223
|
+
el.classList.add("collapsed");
|
|
224
|
+
el.classList.remove("expanded");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (arrow) arrow.style.transform = "";
|
|
228
|
+
expandedCategories.delete(key);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function collapseFolderAndDescendants(pathKey, instant = false) {
|
|
232
|
+
const parts = pathKey.split("|");
|
|
233
|
+
const nodeId =
|
|
234
|
+
"folder-" + parts.map((p) => p.replace(/\W/g, "-")).join("-");
|
|
235
|
+
const el = document.getElementById(nodeId);
|
|
236
|
+
const arrow = document.getElementById("arrow-" + nodeId);
|
|
237
|
+
if (el) {
|
|
238
|
+
if (instant) setInstantCollapse(el);
|
|
239
|
+
else {
|
|
240
|
+
el.classList.add("collapsed");
|
|
241
|
+
el.classList.remove("expanded");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (arrow) arrow.style.transform = "";
|
|
245
|
+
expandedFolders.delete(pathKey);
|
|
246
|
+
|
|
247
|
+
const prefix = pathKey + "|";
|
|
248
|
+
for (const key of [...expandedFolders]) {
|
|
249
|
+
if (key.startsWith(prefix)) collapseFolderAndDescendants(key, instant);
|
|
250
|
+
}
|
|
251
|
+
for (const key of [...expandedCategories]) {
|
|
252
|
+
if (key.startsWith(prefix)) collapseCategoryByKey(key, instant);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
205
256
|
function toggleCategory(key) {
|
|
206
257
|
const parts = key.split("|");
|
|
207
258
|
const catNodeId =
|
|
@@ -210,6 +261,17 @@ function toggleCategory(key) {
|
|
|
210
261
|
const arrow = document.getElementById("arrow-" + catNodeId);
|
|
211
262
|
if (!el) return;
|
|
212
263
|
const expanding = el.classList.contains("collapsed");
|
|
264
|
+
|
|
265
|
+
if (expanding && exclusiveCategoryExpansion) {
|
|
266
|
+
const parentPath = parts.slice(0, -1).join("|");
|
|
267
|
+
for (const otherKey of [...expandedCategories]) {
|
|
268
|
+
if (otherKey === key) continue;
|
|
269
|
+
const otherParts = otherKey.split("|");
|
|
270
|
+
const otherParent = otherParts.slice(0, -1).join("|");
|
|
271
|
+
if (otherParent === parentPath) collapseCategoryByKey(otherKey, true);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
213
275
|
el.classList.toggle("collapsed", !expanding);
|
|
214
276
|
el.classList.toggle("expanded", expanding);
|
|
215
277
|
if (arrow) arrow.style.transform = expanding ? "rotate(90deg)" : "";
|
|
@@ -225,6 +287,18 @@ function toggleFolder(pathKey) {
|
|
|
225
287
|
const arrow = document.getElementById("arrow-" + nodeId);
|
|
226
288
|
if (!el) return;
|
|
227
289
|
const expanding = el.classList.contains("collapsed");
|
|
290
|
+
|
|
291
|
+
if (expanding && exclusiveFolderExpansion) {
|
|
292
|
+
const parentPath = parts.slice(0, -1).join("|");
|
|
293
|
+
for (const otherKey of [...expandedFolders]) {
|
|
294
|
+
if (otherKey === pathKey) continue;
|
|
295
|
+
const otherParts = otherKey.split("|");
|
|
296
|
+
const otherParent = otherParts.slice(0, -1).join("|");
|
|
297
|
+
if (otherParent === parentPath)
|
|
298
|
+
collapseFolderAndDescendants(otherKey, true);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
228
302
|
el.classList.toggle("collapsed", !expanding);
|
|
229
303
|
el.classList.toggle("expanded", expanding);
|
|
230
304
|
if (arrow) arrow.style.transform = expanding ? "rotate(90deg)" : "";
|
package/dist/src/lib/config.d.ts
CHANGED
|
@@ -11,6 +11,9 @@ export interface LivingDocConfig {
|
|
|
11
11
|
diagramEdgePalette: string[] | null;
|
|
12
12
|
sourceRoot: string | null;
|
|
13
13
|
blockedFileExtensions: string[];
|
|
14
|
+
exclusiveFolderExpansion: boolean;
|
|
15
|
+
exclusiveCategoryExpansion: boolean;
|
|
16
|
+
codeBlockMaxHeight: number;
|
|
14
17
|
}
|
|
15
18
|
export declare function getConfigPath(docsPath: string): string;
|
|
16
19
|
export declare function readConfig(docsPath: string): LivingDocConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACnC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qBAAqB,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACnC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,wBAAwB,EAAE,OAAO,CAAC;IAClC,0BAA0B,EAAE,OAAO,CAAC;IACpC,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAiED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAY5D;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,GAC9B,eAAe,CAMjB"}
|
package/dist/src/lib/config.js
CHANGED
|
@@ -62,6 +62,9 @@ const DEFAULTS = {
|
|
|
62
62
|
diagramEdgePalette: DEFAULT_DIAGRAM_EDGE_PALETTE,
|
|
63
63
|
sourceRoot: null,
|
|
64
64
|
blockedFileExtensions: DEFAULT_BLOCKED_FILE_EXTENSIONS,
|
|
65
|
+
exclusiveFolderExpansion: false,
|
|
66
|
+
exclusiveCategoryExpansion: false,
|
|
67
|
+
codeBlockMaxHeight: 400,
|
|
65
68
|
};
|
|
66
69
|
function getConfigPath(docsPath) {
|
|
67
70
|
return path_1.default.join(docsPath, CONFIG_FILENAME);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":";;;;;AAoFA,sCAEC;AAED,gCAYC;AAED,kCASC;AA/GD,4CAAoB;AACpB,gDAAwB;AAoBxB,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C,mGAAmG;AACnG,yFAAyF;AACzF,MAAM,4BAA4B,GAAG;IACnC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,WAAW;CACvB,CAAC;AAEF,MAAM,4BAA4B,GAAG;IACnC,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC;AAEF,MAAM,+BAA+B,GAAG;IACtC,KAAK;IACL,IAAI;IACJ,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;AAEF,MAAM,QAAQ,GAAoB;IAChC,UAAU,EAAE,GAAG;IACf,eAAe,EAAE,mCAAmC;IACpD,KAAK,EAAE,sBAAsB;IAC7B,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,IAAI;IACd,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,EAAE;IACd,gBAAgB,EAAE,KAAK;IACvB,kBAAkB,EAAE,4BAA4B;IAChD,kBAAkB,EAAE,4BAA4B;IAChD,UAAU,EAAE,IAAI;IAChB,qBAAqB,EAAE,+BAA+B;IACtD,wBAAwB,EAAE,KAAK;IAC/B,0BAA0B,EAAE,KAAK;IACjC,kBAAkB,EAAE,GAAG;CACxB,CAAC;AAEF,SAAgB,aAAa,CAAC,QAAgB;IAC5C,OAAO,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;AAC9C,CAAC;AAED,SAAgB,UAAU,CAAC,QAAgB;IACzC,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,IAAI,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA6B,CAAC;YAC3D,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;IACrC,CAAC;IACD,OAAO,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC;AAED,SAAgB,WAAW,CACzB,QAAgB,EAChB,KAA+B;IAE/B,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,OAAO,GAAoB,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;IAC1D,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAIpD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAIpD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiHrD"}
|
|
@@ -33,6 +33,9 @@ function configRouter(docsPath) {
|
|
|
33
33
|
'diagramEdgePalette',
|
|
34
34
|
'sourceRoot',
|
|
35
35
|
'blockedFileExtensions',
|
|
36
|
+
'exclusiveFolderExpansion',
|
|
37
|
+
'exclusiveCategoryExpansion',
|
|
38
|
+
'codeBlockMaxHeight',
|
|
36
39
|
];
|
|
37
40
|
const safe = {};
|
|
38
41
|
for (const key of allowed) {
|
|
@@ -93,6 +96,16 @@ function configRouter(docsPath) {
|
|
|
93
96
|
return res.status(400).json({ error: 'blockedFileExtensions must be an array of strings' });
|
|
94
97
|
}
|
|
95
98
|
}
|
|
99
|
+
// codeBlockMaxHeight: non-negative integer pixels (0 disables); clamped to [0, 5000]
|
|
100
|
+
if ('codeBlockMaxHeight' in patch) {
|
|
101
|
+
const v = patch.codeBlockMaxHeight;
|
|
102
|
+
if (typeof v === 'number' && Number.isFinite(v) && v >= 0) {
|
|
103
|
+
safe.codeBlockMaxHeight = Math.min(5000, Math.round(v));
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return res.status(400).json({ error: 'codeBlockMaxHeight must be a non-negative number' });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
96
109
|
// extraFiles: only absolute .md paths
|
|
97
110
|
if ('extraFiles' in patch && Array.isArray(patch.extraFiles)) {
|
|
98
111
|
safe.extraFiles = patch.extraFiles.filter((f) => typeof f === 'string' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/routes/config.ts"],"names":[],"mappings":";;;;;AAIA,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/routes/config.ts"],"names":[],"mappings":";;;;;AAIA,oCAiHC;AArHD,qCAAoD;AACpD,gDAAwB;AACxB,0CAAyE;AAEzE,SAAgB,YAAY,CAAC,QAAgB;IAC3C,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;IAExB,kBAAkB;IAClB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QAC/C,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,kBAAkB;IAClB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QAC9C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,GAAG,CAAC,IAAgC,CAAC;YACnD,6DAA6D;YAC7D,MAAM,OAAO,GAA8B;gBACzC,OAAO;gBACP,iBAAiB;gBACjB,OAAO;gBACP,UAAU;gBACV,kBAAkB;gBAClB,oBAAoB;gBACpB,oBAAoB;gBACpB,YAAY;gBACZ,uBAAuB;gBACvB,0BAA0B;gBAC1B,4BAA4B;gBAC5B,oBAAoB;aACrB,CAAC;YACF,MAAM,IAAI,GAA6B,EAAE,CAAC;YAC1C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;oBAChB,IAAgC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;YACD,uDAAuD;YACvD,IAAI,iBAAiB,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;gBAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;gBAC7D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACrC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC,CAAC;gBACpF,CAAC;gBACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sDAAsD,EAAE,CAAC,CAAC;gBACjG,CAAC;YACH,CAAC;YACD,8BAA8B;YAC9B,IAAI,UAAU,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAkB,CAAC,EAAE,CAAC;gBAC1E,OAAQ,IAAgC,CAAC,QAAQ,CAAC;YACpD,CAAC;YACD,oEAAoE;YACpE,IAAI,oBAAoB,IAAI,KAAK,EAAE,CAAC;gBAClC,MAAM,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC;gBACnC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,EAAE,CAAC;oBAC9E,IAAI,CAAC,kBAAkB,GAAG,CAAoB,CAAC;gBACjD,CAAC;YACH,CAAC;YACD,IAAI,oBAAoB,IAAI,KAAK,EAAE,CAAC;gBAClC,MAAM,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC;gBACnC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,EAAE,CAAC;oBAC9E,IAAI,CAAC,kBAAkB,GAAG,CAAoB,CAAC;gBACjD,CAAC;YACH,CAAC;YACD,0DAA0D;YAC1D,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;gBAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;gBAC3B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;oBAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACzB,CAAC;qBAAM,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,cAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvD,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6CAA6C,EAAE,CAAC,CAAC;gBACxF,CAAC;YACH,CAAC;YACD,qFAAqF;YACrF,IAAI,uBAAuB,IAAI,KAAK,EAAE,CAAC;gBACrC,MAAM,CAAC,GAAG,KAAK,CAAC,qBAAqB,CAAC;gBACtC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrB,IAAI,CAAC,qBAAqB,GAAI,CAAe;yBAC1C,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;yBACjD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;yBACtD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1C,CAAC;qBAAM,CAAC;oBACN,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mDAAmD,EAAE,CAAC,CAAC;gBAC9F,CAAC;YACH,CAAC;YACD,qFAAqF;YACrF,IAAI,oBAAoB,IAAI,KAAK,EAAE,CAAC;gBAClC,MAAM,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC;gBACnC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1D,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1D,CAAC;qBAAM,CAAC;oBACN,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC,CAAC;gBAC7F,CAAC;YACH,CAAC;YACD,sCAAsC;YACtC,IAAI,YAAY,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7D,IAAI,CAAC,UAAU,GAAI,KAAK,CAAC,UAAwB,CAAC,MAAM,CACtD,CAAC,CAAC,EAAe,EAAE,CACjB,OAAO,CAAC,KAAK,QAAQ;oBACrB,cAAI,CAAC,UAAU,CAAC,CAAC,CAAC;oBAClB,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAClC,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,IAAA,oBAAW,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|