*/
+
+sdoc-toast {
+ pointer-events: initial;
+ text-align: center;
+ border-radius: var(--base-rhythm);
+ box-shadow: 0 8px 32px rgba(0,0,0,.3);
+ background: var(--color-bg-ui);
+ color: var(--color-fg-secondary-invert);
+}
+
+sdoc-toast:not(:empty) {
+ padding: .75rem 2rem;
+}
+
+sdoc-toast a,
+sdoc-toast a:link,
+sdoc-toast a:visited {
+ color: var(--color-bg-contrast);
+}
+
+sdoc-toast a:hover {
+ color: var(--color-fg-accent);
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/node.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/node.css
new file mode 100644
index 0000000..cf45ed3
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/node.css
@@ -0,0 +1,246 @@
+turbo-frame {
+ display: contents;
+}
+
+sdoc-node {
+ display: block;
+ position: relative;
+}
+
+/* sdoc-node[show-node-type-name] sdoc-node-content {
+ margin-top: calc(2 * var(--base-rhythm));
+} */
+
+sdoc-node[show-node-type-name]::before {
+ content: attr(show-node-type-name);
+ position: absolute;
+ top: calc(1 * var(--base-rhythm));
+ right: calc(4 * var(--base-rhythm));
+
+ font-size: 10px;
+ font-family: var(--code-font-family);
+ font-weight: 600;
+ line-height: 1;
+ text-transform: uppercase;
+
+ padding-top: calc(0.25 * var(--base-rhythm));
+ padding-bottom: calc(0.5 * var(--base-rhythm));
+ padding-left: calc(0.75 * var(--base-rhythm));
+ padding-right: calc(0.75 * var(--base-rhythm));
+ border-radius: 3px;
+ border: var(--requirement-border-width, 1px) solid var(--requirement-border-color, #bfbfbf);
+
+ color: var(--requirement-label-color);
+ background-color: var(--color-bg-contrast);
+}
+
+/* sdoc-node */
+
+sdoc-node {
+ background-color: var(--color-bg-contrast);
+ border-radius: 3px;
+
+ /* padding: calc(3 * var(--base-rhythm)) calc(4 * var(--base-rhythm)); */
+ padding-inline: calc(4 * var(--base-rhythm));
+ padding-block: calc(3 * var(--base-rhythm));
+}
+
+sdoc-node[node-role="root"] {
+ padding-top: calc(3 * var(--base-rhythm));
+}
+
+sdoc-node[node-style="readonly"][node-role="requirement"] {
+ background: none;
+ background-color: transparent;
+ outline: none;
+ padding-left: 0;
+ padding-right: 0;
+ padding-bottom: 0;
+ margin: 0;
+}
+
+sdoc-node[show-node-type-name][node-style="readonly"]::before {
+ right: 0;
+}
+
+sdoc-node[show-node-type-name][node-view="plain"]::before {
+ content: none;
+}
+
+/* editable_node */
+
+sdoc-node[node-style="card"][node-role="requirement"],
+[data-editable_node="on"] {
+ box-shadow: var(--base-elevation-0);
+ transition: box-shadow .5s;
+}
+
+sdoc-node[node-style="card"][node-role="requirement"]:hover,
+[data-editable_node="on"]:hover {
+ box-shadow: var(--base-elevation-node);
+ z-index: 10;
+}
+
+/* sdoc-node[node-style="card"] */
+
+sdoc-node[node-style="card"] {
+ background-color: var(--color-bg-contrast);
+ border-radius: 3px;
+ padding: 0;
+}
+
+sdoc-node[node-style="card"][node-role="text"],
+sdoc-node[node-style="card"][node-role="section"] {
+ background-color: var(--color-bg-contrast);
+ padding: calc(var(--base-rhythm)) calc(var(--base-rhythm)*2);
+}
+
+[data-role='current'] sdoc-node[node-style="card"] {
+ background-color: var(--color-bg-contrast);
+}
+
+[data-role='current'] [node-role="requirement"] {
+
+}
+
+[data-role='parents'] sdoc-node[node-style="card"],
+[data-role='children'] sdoc-node[node-style="card"] {
+ background-color: var(--color-bg-secondary);
+ width: var(--card-width);
+}
+
+sdoc-node[node-style="card"].highlighted {
+ background-color: var(--color-highlight);
+}
+
+[data-viewtype="traceability"] sdoc-node[node-style="card"] + sdoc-node[node-style="card"] {
+ margin-top: var(--base-padding);
+}
+
+[data-viewtype="deep_traceability"] sdoc-node[node-style="card"] {
+ /* width: var(--card-width); */
+ /* flex-grow: 1; */
+}
+
+[data-viewtype="requirements-coverage"] sdoc-node[node-style="card"] {
+ width: calc(var(--card-width)*0.75);
+ /* width: auto; */
+ font-size: .85em;
+ line-height: 1.4;
+}
+
+/* nouid */
+
+sdoc-node.nouid {
+ /* background-color: rgb(240, 220, 220); */
+}
+
+.nouid sdoc-node-title,
+.nouid .requirement__title {
+ color: #502222;
+}
+
+/* sdoc-node-controls */
+
+sdoc-node-controls[data-direction~="column"],
+sdoc-node-controls {
+ position: absolute;
+
+ display: flex;
+ justify-content: flex-start;
+
+ transition: .5s ease-out;
+ opacity: 0;
+
+ /* HACK: [sdoc-node outline hack] */
+ left: calc(100% + 1px);
+ top: -2px;
+
+ /* default: column to right */
+ bottom: 0;
+ right: unset;
+ width: calc(var(--base-rhythm)*4); /* determines the size of the buttons */
+ height: unset;
+
+ justify-content: flex-start;
+ flex-direction: column;
+}
+
+sdoc-node-controls[data-direction~="column"] {
+ flex-direction: column;
+ justify-content: flex-start;
+
+ left: 100%;
+ top: 0;
+ bottom: 0;
+ right: unset;
+ width: calc(var(--base-rhythm)*4); /* determines the size of the buttons */
+ height: unset;
+}
+
+sdoc-node-controls[data-direction~="row"] {
+ flex-direction: row;
+ justify-content: flex-end;
+
+ top: calc(100% - 4px);
+ left: 0;
+ right: 0;
+ bottom: unset;
+ height: calc(var(--base-rhythm)*4); /* determines the size of the buttons */
+ width: unset;
+}
+
+sdoc-main-placeholder + sdoc-node-controls {
+ opacity: 1;
+}
+
+sdoc-node-controls:hover,
+sdoc-node:hover sdoc-node-controls {
+ opacity: 1;
+}
+
+sdoc-node:hover sdoc-node-controls:hover {
+ opacity: 1;
+}
+
+sdoc-menu {
+ display: flex;
+ align-items: stretch;
+ /* default: */
+ flex-direction: column;
+}
+
+sdoc-menu-handler {
+ display: flex;
+ align-items: stretch;
+ /* default: */
+ flex-direction: column;
+}
+
+sdoc-menu, /* default: */
+sdoc-menu-handler, /* default: */
+sdoc-node-controls[data-direction~="column"] sdoc-menu,
+sdoc-node-controls[data-direction~="column"] sdoc-menu-handler {
+ flex-direction: column;
+}
+
+sdoc-node-controls[data-direction~="row"] sdoc-menu,
+sdoc-node-controls[data-direction~="row"] sdoc-menu-handler {
+ flex-direction: row;
+}
+
+/* math equation numbering support */
+div.math {
+ position: relative;
+ text-align: center;
+ padding-right: 3em; /* reserve space for eqno */
+ overflow: hidden; /* prevents scrollbars */
+}
+
+.math .eqno {
+ position: absolute;
+ right: 0;
+ top: 0;
+ font-size: 90%;
+ white-space: nowrap;
+}
\ No newline at end of file
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/node_content.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/node_content.css
new file mode 100644
index 0000000..f1c4845
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/node_content.css
@@ -0,0 +1,495 @@
+:root {
+ --requirement-container-limit: 500px;
+ --requirement-border-color: rgb(230, 230, 230); /* = var(--color-border) on white without opacity */
+ --requirement-border-width: 1px;
+ --requirement-border-radius: 4px;
+ --requirement-inner-borders-width: 1px;
+ --requirement-label-color: var(--color-fg-secondary, #808080);
+ --requirement-bg-dark-color: var(--color-bg-main, #F2F5F9);
+ --requirement-bg-light-color: var(--color-bg-contrast, #FFFFFF);
+}
+
+/* sdoc-node-content */
+
+sdoc-node-content {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr); /* issue#1370 https://css-tricks.com/preventing-a-grid-blowout/ */
+ place-items: stretch stretch;
+ place-content: stretch stretch;
+ gap: var(--requirement-inner-borders-width);
+
+ position: relative;
+ background-color: var(--color-bg-contrast); /* affects the color of the space between cells */
+ border:
+ var(--requirement-border-width, 1px)
+ solid
+ var(--requirement-border-color);
+
+ border-radius: var(--requirement-border-radius);
+
+
+ min-width: 300px;
+
+ /* and use overflow-wrap: break-word; in the field */
+ max-width: 100%;
+
+ /*
+ DEV: to show anchors (in the context) to the left of the node,
+ need to remove this:
+ overflow-x: auto;
+ */
+}
+
+/* Workaround for html2pdf4doc print bug:
+ (https://github.com/strictdoc-project/strictdoc/issues/2450#issuecomment-3299134769)
+ Disable background for elements that trigger header/footer overlap.
+ This hides the background of problematic split (not sliced) sections
+ to prevent them from covering header/footer areas during printing.
+ Real fix will be applied in html2pdf4doc in a future release. */
+@media print {
+ sdoc-node-content {
+ background: none;
+ background-color: transparent;
+ }
+}
+
+sdoc-node-title {
+ display: block;
+
+ font-size: 1.125em;
+ font-weight: 700;
+}
+
+sdoc-node-title:last-child {
+ margin-bottom: 0;
+}
+
+sdoc-node-title * {
+ /* affect H inside title, if applicable */
+ margin: 0;
+}
+
+[node-style="card"] sdoc-node-title {
+ font-size: 1em;
+}
+
+/* synonym to [node-view="inline"] */
+sdoc-node-content[node-view="simple"] sdoc-node-title {
+ padding-left: calc(var(--base-rhythm)*2);
+ padding-right: calc(var(--base-rhythm)*2);
+ padding-top: calc(var(--base-rhythm)*1);
+ padding-bottom: calc(var(--base-rhythm)*1);
+
+ word-break: break-word;
+ overflow-wrap: break-word;
+}
+
+/* sdoc-node-content[node-view="simple"] sdoc-node-title, */
+sdoc-node-content[node-view="table"] sdoc-node-title,
+sdoc-node-content[node-view="zebra"] sdoc-node-title {
+ padding-left: calc(var(--base-rhythm)*2);
+ padding-right: calc(var(--base-rhythm)*2);
+ padding-top: calc(var(--base-rhythm)*1);
+ padding-bottom: calc(var(--base-rhythm)*1);
+
+ border-top-right-radius: var(--requirement-border-radius);
+ border-top-left-radius: var(--requirement-border-radius);
+
+ background-color: var(--requirement-bg-dark-color);
+ /* border-bottom: */
+ outline: 1px solid var(--requirement-border-color);
+
+ word-break: break-word;
+ overflow-wrap: break-word;
+}
+
+sdoc-node-uid {
+ display: block;
+ padding-left: calc(var(--base-rhythm)*2);
+ padding-right: calc(var(--base-rhythm)*2);
+ padding-top: calc(var(--base-rhythm)*1);
+ padding-bottom: calc(var(--base-rhythm)*1);
+ font-size: var(--font-size-sm);
+ font-family: var(--code-font-family);
+ font-weight: 700;
+
+ text-transform: uppercase;
+ color: var(--requirement-label-color);
+
+ word-break: break-word;
+ overflow-wrap: break-word;
+}
+
+sdoc-node-field-label {
+ display: flex;
+ align-items:flex-start;
+
+ padding-left: calc(var(--base-rhythm)*2);
+ padding-right: calc(var(--base-rhythm)*2);
+ padding-top: calc(var(--base-rhythm)*1.75);
+ padding-bottom: calc(var(--base-rhythm)*1);
+
+ font-size: var(--font-size-sm);
+ font-family: var(--code-font-family);
+ font-weight: 500;
+ line-height: 1;
+ color: var(--requirement-label-color);
+
+ /* @mettta and @stanislaw are commenting this out because REQUIREMENT's field names
+ were split apart, even though there was enough screen width
+ word-break: break-word;
+ */
+ overflow-wrap: break-word;
+}
+
+sdoc-node-field {
+ display: block;
+ position: relative;
+
+ padding-left: calc(var(--base-rhythm)*2);
+ padding-right: calc(var(--base-rhythm)*2);
+ padding-top: calc(var(--base-rhythm)*1);
+ padding-bottom: calc(var(--base-rhythm)*1);
+
+ word-break: break-word;
+ overflow-wrap: break-word;
+}
+
+[data-viewtype="html2pdf"] sdoc-node-field-label {
+ word-break: normal;
+}
+
+/* for relations in requirement */
+sdoc-node-field > ol:first-child,
+sdoc-node-field > ul:first-child {
+ margin-top: 0;
+}
+sdoc-node-field > ol:last-child,
+sdoc-node-field > ul:last-child {
+ margin-bottom: 0;
+}
+
+/* node-view="plain" */
+
+sdoc-node-content[node-view="plain"] {
+ border: 0;
+ display: flex;
+ flex-direction: column;
+ gap: var(--base-padding);
+}
+
+sdoc-node-content[node-view="plain"] sdoc-node-field-label {
+ display: none;
+}
+
+sdoc-node-content[node-view="plain"] sdoc-node-field {
+ padding: 0;
+}
+
+/* node-view="table" */
+
+sdoc-node-content[node-view="table"] {
+ /* grid: */
+ grid-template-columns: minmax(80px, min-content) minmax(0, 1fr); /* issue#1370 https://css-tricks.com/preventing-a-grid-blowout/ */
+ /* border: */
+ background-color: var(--requirement-border-color);
+}
+
+sdoc-node-content[node-view="table"]
+ sdoc-node-title {
+ grid-column: 1 / 3;
+ }
+
+sdoc-node-content[node-view="table"]
+ sdoc-node-field-label {
+ grid-column: 1 / 2;
+ background-color: var(--requirement-bg-dark-color);
+ }
+
+sdoc-node-content[node-view="table"]
+ sdoc-node-field {
+ grid-column: 2 / 3;
+ background-color: var(--requirement-bg-light-color);
+ }
+
+sdoc-node:not([node-style="card"]) {
+ /* Making the node a container for the requirement: */
+ container: node / inline-size;
+ /*
+ HACK: [sdoc-node outline hack]
+ Buggy behavior for @container CSS feature:
+ after window resize, the 1px vertically space
+ appears randomly between nodes.
+ */
+ outline: 1px solid #fff;
+ margin: 1px 0;
+}
+
+/* calc(var(--card-width) + calc(var(--base-padding)*4)) */
+/* 300 + 16*4 = 364 */
+@container node (width < 400px) {
+ sdoc-node-content[node-view="table"] {
+ /* removes columns: */
+ grid-template-columns: minmax(0, 1fr); /* issue#1370 https://css-tricks.com/preventing-a-grid-blowout/ */
+ /* removes inner border: */
+ background-color: var(--requirement-bg-light-color);
+ }
+
+ sdoc-node-content[node-view="table"]
+ sdoc-node-title,
+ sdoc-node-content[node-view="table"]
+ sdoc-node-field-label,
+ sdoc-node-content[node-view="table"]
+ sdoc-node-field {
+ /* removes columns: */
+ grid-column: unset;
+ }
+}
+
+@supports not (container-type: inline-size) {
+ /* TODO test 888px */
+ @media (max-width: 888px) {
+ /* Do the same as if there was a container support */
+
+ sdoc-node-content[node-view="table"] {
+ /* removes columns: */
+ grid-template-columns: minmax(0, 1fr); /* issue#1370 https://css-tricks.com/preventing-a-grid-blowout/ */
+ /* removes inner border: */
+ background-color: var(--requirement-bg-light-color);
+ }
+
+ sdoc-node-content[node-view="table"]
+ sdoc-node-title,
+ sdoc-node-content[node-view="table"]
+ sdoc-node-field-label,
+ sdoc-node-content[node-view="table"]
+ sdoc-node-field {
+ /* removes columns: */
+ grid-column: unset;
+ }
+ }
+}
+
+/* node-view="zebra" */
+
+sdoc-node-content[node-view="zebra"] {
+ grid-template-columns: minmax(0, 1fr); /* issue#1370 https://css-tricks.com/preventing-a-grid-blowout/ */
+}
+
+sdoc-node-content[node-view="zebra"]
+ sdoc-node-field-label {
+ background-color: var(--requirement-bg-dark-color);
+ }
+
+sdoc-node-content[node-view="zebra"]
+ sdoc-node-field {
+ background-color: var(--requirement-bg-light-color);
+ }
+
+/* node-view="simple" */
+/* synonym to "inline" */
+
+sdoc-node-content[node-view="simple"] {
+ grid-template-columns: minmax(0, 1fr); /* issue#1370 https://css-tricks.com/preventing-a-grid-blowout/ */
+}
+
+sdoc-node-content[node-view="simple"]
+sdoc-node-field-label {
+ background-color: #fff;
+ padding-bottom: 0;
+}
+
+/* node-view="narrative" */
+
+sdoc-node-content[node-view="narrative"] {
+ display: flex;
+ flex-direction: column;
+ padding-top: var(--base-rhythm);
+ border-radius: 0;
+ border-left: none;
+ border-right: none;
+ border-bottom: none;
+}
+
+sdoc-node-content[node-view="narrative"] sdoc-node-title {
+ border: none;
+ outline: none;
+ background: none;
+ background-color: transparent;
+ padding: 0;
+ margin-bottom: var(--base-padding);
+ grid-column: 1 / -1;
+}
+
+sdoc-node-content[node-view="narrative"] sdoc-node-field {
+ padding: 0;
+}
+
+sdoc-node-content[node-view="narrative"] sdoc-node-field-label {
+ opacity: 0.8;
+ font-size: var(--font-size-sm);
+ line-height: calc(var(--font-size-sm) * 1.5);
+ padding: 0;
+}
+
+sdoc-node-content[node-view="narrative"] .node_fields_group-primary {
+ display: flex;
+ flex-direction: column;
+ padding-top: var(--base-padding);
+}
+
+sdoc-node-content[node-view="narrative"] .node_fields_group-primary sdoc-node-field {
+ margin-bottom: var(--base-padding);
+ color: var(--color-fg-contrast);
+}
+
+sdoc-node-content[node-view="narrative"] .node_fields_group-primary sdoc-node-field:last-child {
+ margin-bottom: 0;
+}
+
+sdoc-node-content[node-view="narrative"] .node_fields_group-secondary {
+ display: grid;
+ grid-template-columns: max-content 1fr;
+ gap: calc(.5 * var(--base-rhythm));
+}
+
+sdoc-node-content[node-view="narrative"] .node_fields_group-secondary sdoc-node-field {
+ font-size: var(--font-size-sm);
+ line-height: calc(var(--font-size-sm) * 1.5);
+ opacity: 0.6;
+}
+
+sdoc-node-content[node-view="narrative"] .requirement__parent-uid,
+sdoc-node-content[node-view="narrative"] .requirement__child-uid {
+ /*
+ affects UID in links;
+ make them lighter:
+ */
+ font-weight: normal;
+}
+
+/* section */
+
+sdoc-section,
+sdoc-section-title {
+ display: block;
+ margin: 0;
+}
+
+sdoc-section-title {
+ font-weight: 700;
+}
+
+sdoc-section-title {
+ margin-bottom: var(--base-padding);
+}
+
+sdoc-section-title:last-child {
+ margin-bottom: 0;
+}
+
+sdoc-section-title * {
+ margin: 0;
+
+ /* This rule, when the element starts the page when printed,
+ creates illegal margins,
+ which breaks the rhythm of HTML2PDF4DOC
+ and generates blank pages:
+ */
+ /* display: inline; */
+}
+
+/* TEXT node */
+
+sdoc-text,
+sdoc-section-text {
+ display: block;
+ margin: 0;
+}
+
+[node-style="card"] sdoc-text {
+ padding: var(--base-padding);
+}
+
+sdoc-section-text {
+ margin-top: var(--base-padding);
+}
+
+sdoc-section-text:first-child {
+ margin-top: 0;
+}
+
+/* meta */
+
+sdoc-meta {
+ display: grid;
+ grid-template-columns: minmax(min-content, max-content) minmax(min-content, 1fr);
+ place-items: stretch stretch;
+ place-content: stretch stretch;
+ position: relative;
+ border:
+ var(--requirement-border-width, 1px)
+ solid
+ var(--requirement-border-color);
+ border-radius: var(--requirement-border-radius);
+
+ font-size: var(--font-size-sm);
+ line-height: 24px; /* to keep the copy button from expanding out of the content line */
+ /* margin: var(--base-padding) 0; */
+ margin: 0;
+ padding: calc(var(--base-rhythm)*0.5);
+ row-gap: 2px;
+
+ width: fit-content;
+ max-width: 100%;
+ overflow-x: auto;
+}
+
+sdoc-meta-section,
+sdoc-meta-label,
+sdoc-meta-field {
+ display: flex;
+ align-items: flex-start;
+ padding: calc(var(--base-rhythm)*0.25) var(--base-rhythm);
+ background-color: var(--color-bg-contrast);
+}
+
+sdoc-meta-label {
+ grid-column: 1 / 2;
+ font-family: var(--code-font-family);
+ font-weight: 700;
+ text-transform: uppercase;
+ color: var(--requirement-label-color);
+ background-color: var(--color-bg-secondary);
+}
+
+sdoc-meta-field {
+ grid-column: 2 / 3;
+}
+
+sdoc-meta-section {
+ grid-column: 1 / -1;
+}
+
+/* PDF */
+/* There is no sdoc-node wrapper, so such neighbours and nesting is possible. */
+sdoc-text + sdoc-text,
+sdoc-text + sdoc-section,
+sdoc-text + sdoc-section-title,
+sdoc-section + sdoc-text,
+sdoc-section + sdoc-section,
+sdoc-section + sdoc-section sdoc-section-title {
+ margin-top: calc(var(--base-rhythm)*4);
+}
+
+/* requirement type tag */
+
+.requirement__type-tag {
+ /* font-size: var(--font-size-sm);
+ font-family: var(--code-font-family);
+ font-weight: 500;
+ line-height: 1;
+ text-transform: uppercase; */
+ color: var(--requirement-label-color);
+ white-space: nowrap;
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/pan_with_space.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/pan_with_space.js
new file mode 100644
index 0000000..2a04d2d
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/pan_with_space.js
@@ -0,0 +1,151 @@
+// This code in this file is a simplified version of the StackOverflow answer
+// taken from: https://stackoverflow.com/a/33948409/598057.
+
+const MOUSEMOVE_SPEED_FACTOR = 1;
+const KEYDOWN_SPEED_FACTOR = 20;
+const PWS_SELECTOR = "[js-pan_with_space]";
+
+function getPanElement() {
+ const element = document.querySelector(PWS_SELECTOR);
+ return element;
+}
+
+window.addEventListener('load', function () {
+ var state = {
+ spacePressed: false,
+ isDown: false,
+ startX: 0,
+ startY: 0
+ }
+
+ const element = getPanElement();
+ if (element) {
+ console.assert(!!element, "Expected a valid element.");
+
+ document.addEventListener("keydown", function (e) {
+ if (e.key === ' ' || e.key === 'Spacebar') {
+ // ' ' is standard, 'Spacebar' was used by IE9 and Firefox < 37
+
+ e.preventDefault();
+ e.stopPropagation();
+ state.spacePressed = true;
+ element.style.cursor = 'move';
+ element.style.scrollBehavior = 'auto';
+ return;
+ }
+
+ var moveFactor = KEYDOWN_SPEED_FACTOR;
+ if (e.altKey) {
+ moveFactor = KEYDOWN_SPEED_FACTOR * 10;
+ }
+
+ if (e.key === 'ArrowDown') {
+ e.preventDefault();
+ e.stopPropagation();
+ element.scrollTop = element.scrollTop + moveFactor;
+ }
+ else if (e.key === 'ArrowUp') {
+ e.preventDefault();
+ e.stopPropagation();
+ element.scrollTop = element.scrollTop - moveFactor;
+ }
+ else if (e.key === 'ArrowLeft') {
+ e.preventDefault();
+ e.stopPropagation();
+ element.scrollLeft = element.scrollLeft - moveFactor;
+ }
+ else if (e.key === 'ArrowRight') {
+ e.preventDefault();
+ e.stopPropagation();
+ element.scrollLeft = element.scrollLeft + moveFactor;
+ }
+ })
+
+ document.addEventListener("keyup", function (e) {
+ if (e.key === ' ' || e.key === 'Spacebar') {
+ // ' ' is standard, 'Spacebar' was used by IE9 and Firefox < 37
+ e.preventDefault();
+ e.stopPropagation();
+ state.spacePressed = false;
+ element.style.cursor = 'default';
+ element.style.scrollBehavior = '';
+ }
+ });
+
+ element.addEventListener("mousedown", function (e) {
+ if (!state.spacePressed) {
+ return;
+ }
+
+ // Tell the browser we're handling this event.
+ e.preventDefault();
+ e.stopPropagation();
+
+ // Calc the starting mouse X,Y for the drag.
+ state.startX = parseInt(e.clientX);
+ state.startY = parseInt(e.clientY);
+
+ var mouseX = parseInt(e.clientX);
+ var mouseY = parseInt(e.clientY);
+
+ state.isDown = true;
+ });
+
+ element.addEventListener("mouseup", function (e) {
+ if (!state.spacePressed) {
+ return;
+ }
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ state.isDown = false;
+ });
+
+ element.addEventListener("mousemove", function (e) {
+ if (!state.isDown) {
+ return;
+ }
+
+ if (!state.spacePressed) {
+ return;
+ }
+
+ e.preventDefault();
+ e.stopPropagation();
+
+ var mouseX = parseInt(e.clientX);
+ var mouseY = parseInt(e.clientY);
+
+ var dx = mouseX - state.startX;
+ var dy = mouseY - state.startY;
+
+ state.startX = mouseX;
+ state.startY = mouseY;
+
+ var speedupFactor = MOUSEMOVE_SPEED_FACTOR;
+ element.scrollTo(
+ element.scrollLeft - dx * speedupFactor, element.scrollTop - dy * speedupFactor
+ );
+ });
+
+ element.addEventListener("mouseleave", function (e) {
+ // Tell the browser we're handling this event.
+ e.preventDefault();
+ e.stopPropagation();
+
+ state.isDown = false;
+ });
+ }
+});
+
+// When a window is loaded, scroll to the central column of the DTR tree.
+// The central column is the one where the current document's requirements are
+// listed top-to-bottom.
+document.addEventListener("DOMContentLoaded", function(event) {
+ const element = getPanElement();
+ if (element) {
+ const firstNode = element.querySelector('.content_item[data-role="current"]');
+ firstNode && firstNode.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
+ }
+});
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_map.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_map.js
new file mode 100644
index 0000000..b6f8946
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_map.js
@@ -0,0 +1,1851 @@
+// map of the project for the stable_uri forwarder
+const projectMap = {
+ "strictdoc/docs/strictdoc_01_user_guide.html": [
+
+
+ {"MID":"c2d4542d5f1741c88dfcb4f68ad7dcbd","UID":"SDOC_UG","_LINK":"SDOC_UG" },
+
+ {"MID":"75a595ff028741d0bf9067bba8fb787a","_LINK":"1-Introduction" },
+
+ {"MID":"27023bf63c414fd998437961c77a0e2e","_LINK":"27023bf63c414fd998437961c77a0e2e" },
+
+ {"MID":"bcd0cf7c13cf4cf2ab176455aedc0c90","UID":"SDOC_UG_CONTACT","_LINK":"SDOC_UG_CONTACT" },
+
+ {"MID":"3ae6491057674be1abf057b7e0d9bf21","_LINK":"3ae6491057674be1abf057b7e0d9bf21" },
+
+ {"MID":"8e4ede8cdc70402b91a59026d31a7020","_LINK":"1.1.1-StrictDoc-office-hours" },
+
+ {"MID":"c46def916b6f4df692c95f47414feebb","_LINK":"c46def916b6f4df692c95f47414feebb" },
+
+ {"MID":"e0a00ca3085f444187050ce9576aa31b","_LINK":"2-Examples" },
+
+ {"MID":"2122186075e8455181178b01331101fa","UID":"SDOC_UG_HELLO_WORLD","_LINK":"SDOC_UG_HELLO_WORLD" },
+
+ {"MID":"ffbdb80fb21d48adbaeffb782d7994a2","_LINK":"ffbdb80fb21d48adbaeffb782d7994a2" },
+
+ {"MID":"83369fc77d584407b530b179a449479b","_LINK":"2.2-StrictDoc-Examples-repository" },
+
+ {"MID":"d6bde8e4055b42138d216b48692c8f26","_LINK":"d6bde8e4055b42138d216b48692c8f26" },
+
+ {"MID":"0a736f05ab154b2599988b63201d4f10","_LINK":"2.3-StrictDoc-Templates-repository" },
+
+ {"MID":"47c2088447d7452ba28962ee220ba63a","_LINK":"47c2088447d7452ba28962ee220ba63a" },
+
+ {"MID":"2b2e39c48cc740e5b8452d76881f667d","_LINK":"2.4-Other-examples" },
+
+ {"MID":"2eaa8bfe5a354fcbb704ea7fd94f3a0a","_LINK":"2eaa8bfe5a354fcbb704ea7fd94f3a0a" },
+
+ {"MID":"821b818006a14ed7aeb025d9ac8fe8b6","UID":"SDOC_UG_GETTING_STARTED","_LINK":"SDOC_UG_GETTING_STARTED" },
+
+ {"MID":"4e9f094a7b2949edb23c817c5e2276e4","_LINK":"3.1-Requirements" },
+
+ {"MID":"e7e4c2982d8e49deaa9b7413a09a4efa","_LINK":"e7e4c2982d8e49deaa9b7413a09a4efa" },
+
+ {"MID":"914da2bf10364a6fbd9fc7f48b96c6e5","_LINK":"3.2-Installing-StrictDoc-as-a-Pip-package-recommended-way" },
+
+ {"MID":"872a60c673854cfd909787f2379d88c7","_LINK":"872a60c673854cfd909787f2379d88c7" },
+
+ {"MID":"b3e2c50e2d7e46acbce7ea0c646776ca","_LINK":"3.3-Installing-nightly-StrictDoc-as-a-Pip-package" },
+
+ {"MID":"867f22a2767a434586d1ee4f7ee161fb","_LINK":"867f22a2767a434586d1ee4f7ee161fb" },
+
+ {"MID":"9e95ac9422f44aae92c0615176153815","_LINK":"3.4-Installing-StrictDoc-into-a-Docker-container" },
+
+ {"MID":"32e04944c2a14ead93248ff1ea37a68d","_LINK":"32e04944c2a14ead93248ff1ea37a68d" },
+
+ {"MID":"e441594df15841d38f717194b722f3de","_LINK":"3.5-Installing-StrictDoc-as-a-Snap-package-not-maintained" },
+
+ {"MID":"2adfe1bc6be542c3885ca4ea80b8d6e1","_LINK":"2adfe1bc6be542c3885ca4ea80b8d6e1" },
+
+ {"MID":"4af1193170a7416d81a799344dfc8ed6","_LINK":"3.6-Installing-StrictDoc-with-Nix" },
+
+ {"MID":"2045b5e37fc34a83b7457c43d816bf2c","_LINK":"2045b5e37fc34a83b7457c43d816bf2c" },
+
+ {"MID":"6cc72bf1a2a94999954e148a6bef374c","_LINK":"4-Running-StrictDoc" },
+
+ {"MID":"1685e4d63d9746b784b4a55f17b0de30","UID":"SECTION-UG-Static-HTML-export","_LINK":"SECTION-UG-Static-HTML-export" },
+
+ {"MID":"c092847abfa04295b63f943c951f24c8","_LINK":"c092847abfa04295b63f943c951f24c8" },
+
+ {"MID":"1a059d3ae7da45f8b53f3d74f3580980","UID":"SECTION-UG-Web-server","_LINK":"SECTION-UG-Web-server" },
+
+ {"MID":"1fc9f6f4f84d47439bf6aa3404227ca4","_LINK":"1fc9f6f4f84d47439bf6aa3404227ca4" },
+
+ {"MID":"9f7fcbdd8e564af8986349deb09745a5","_LINK":"4.3-Security-considerations" },
+
+ {"MID":"4fa89608f70e4a84a0e4b2930da28bbe","_LINK":"4fa89608f70e4a84a0e4b2930da28bbe" },
+
+ {"MID":"6d489d82b2e24bfeb2919be24262468f","UID":"SDOC_UG_IDE_SUPPORT","_LINK":"SDOC_UG_IDE_SUPPORT" },
+
+ {"MID":"aad57726976f4882982458de90d168c7","_LINK":"aad57726976f4882982458de90d168c7" },
+
+ {"MID":"24fb3436fa8c4b36929183eaac269376","UID":"SECTION-UG-SDoc-syntax","_LINK":"SECTION-UG-SDoc-syntax" },
+
+ {"MID":"556a4f61a4884f3088a743a0717f397f","_LINK":"556a4f61a4884f3088a743a0717f397f" },
+
+ {"MID":"43c9624d3c97433a97f8e8f39e2dd784","_LINK":"6.1-Document-structure" },
+
+ {"MID":"5419c0c9bfcc4922ac5aa79ddb333188","_LINK":"5419c0c9bfcc4922ac5aa79ddb333188" },
+
+ {"MID":"b4ceeb12bdf1448cb97b7974d4980189","UID":"SECTION-UG-DOCUMENT-ELEMENTS","_LINK":"SECTION-UG-DOCUMENT-ELEMENTS" },
+
+ {"MID":"db088d5977934056a851a24988e9266c","UID":"SECTION-UG-Document","_LINK":"SECTION-UG-Document" },
+
+ {"MID":"4b5c6f6fd70e44be8e5be10a38427e77","_LINK":"4b5c6f6fd70e44be8e5be10a38427e77" },
+
+ {"MID":"c75dc4ddd0c349e489817076877394a7","UID":"DOCUMENT_FIELD_OPTIONS","_LINK":"DOCUMENT_FIELD_OPTIONS" },
+
+ {"MID":"45f3cb9a3da54852a83670af72a4d21b","_LINK":"45f3cb9a3da54852a83670af72a4d21b" },
+
+ {"MID":"0f566e0d07bf4194adabc4fba2fdf919","_LINK":"6.2.1.1.1-ENABLE_MID" },
+
+ {"MID":"196b9e9d857548bebecc698903a593de","_LINK":"196b9e9d857548bebecc698903a593de" },
+
+ {"MID":"8cef59608d3942c88dc554f5531e2d8a","_LINK":"6.2.1.1.2-MARKUP" },
+
+ {"MID":"19f65eabcd1c4f28a0091133979b5b6e","_LINK":"19f65eabcd1c4f28a0091133979b5b6e" },
+
+ {"MID":"48c614864015426b8cb98d423201ad43","_LINK":"6.2.1.1.3-AUTO_LEVELS" },
+
+ {"MID":"915b35a9193348108e60968f9b60c1d0","_LINK":"915b35a9193348108e60968f9b60c1d0" },
+
+ {"MID":"8cde71c0f4d448c2a8939f9a81af7ac7","UID":"SECTION-UG-VIEW_STYLE","_LINK":"SECTION-UG-VIEW_STYLE" },
+
+ {"MID":"538a721c42824ad6b94a2f54780887ea","_LINK":"538a721c42824ad6b94a2f54780887ea" },
+
+ {"MID":"bdf01de0fc414b70a6a07118396b23b0","_LINK":"6.2.1.1.5-NODE_IN_TOC" },
+
+ {"MID":"e9e7522f3a094f5ea809f7bae93384d7","_LINK":"e9e7522f3a094f5ea809f7bae93384d7" },
+
+ {"MID":"726b6a1a2f854e82a7670cb8480b887e","_LINK":"6.2.1.2-Additional-Metadata" },
+
+ {"MID":"f86d45b7ad1a48ec919b43a695ca9126","_LINK":"f86d45b7ad1a48ec919b43a695ca9126" },
+
+ {"MID":"93085eee6a214a0a85aa94472f0a0a6c","UID":"SECTION-UG-Leaf-nodes","_LINK":"SECTION-UG-Leaf-nodes" },
+
+ {"MID":"23cbc84e92294aa0aeb0bb279d914480","_LINK":"6.2.2.1-TEXT" },
+
+ {"MID":"4474709783b74b1ca31fa754c712344e","_LINK":"4474709783b74b1ca31fa754c712344e" },
+
+ {"MID":"6426b56116ba428fbba395c79dc2eacc","_LINK":"6.2.2.2-REQUIREMENT" },
+
+ {"MID":"f221cd0c72f846b385ec2f0a9ddd15d5","_LINK":"f221cd0c72f846b385ec2f0a9ddd15d5" },
+
+ {"MID":"a1ad4861e5bc442baf38383b29c901a1","UID":"UG_COMPOSITE_NODE","_LINK":"UG_COMPOSITE_NODE" },
+
+ {"MID":"ce69fe89236a4bcfa104a640def4b64a","_LINK":"ce69fe89236a4bcfa104a640def4b64a" },
+
+ {"MID":"c8c15acf52a24c99922bdae6711f5120","UID":"ELEMENT_SECTION","_LINK":"ELEMENT_SECTION" },
+
+ {"MID":"14e5fea31b1c41bf8c743f18e51053e0","_LINK":"14e5fea31b1c41bf8c743f18e51053e0" },
+
+ {"MID":"9a571c9363ee4dc4a3cdc56abd2c57a7","_LINK":"6.2.3.1.1-Nesting-sections" },
+
+ {"MID":"fa700a9b975f493ba7ec2fd0a7b44bbe","_LINK":"fa700a9b975f493ba7ec2fd0a7b44bbe" },
+
+ {"MID":"0f52cfb294af480e806f0434d0a07757","_LINK":"6.2.3.1.2-Section-grammar-definition" },
+
+ {"MID":"7f2967ea1a41426ba15c0bdde2664920","_LINK":"7f2967ea1a41426ba15c0bdde2664920" },
+
+ {"MID":"324938c23b864864b4e8ff6a67b589a5","_LINK":"6.2.4-Reserved-fields" },
+
+ {"MID":"4d69fa95bd974d859973dbb34679a7c4","_LINK":"4d69fa95bd974d859973dbb34679a7c4" },
+
+ {"MID":"79b128720cd74a548d291e223b61c4bc","UID":"SECTION-UG-Machine-identifiers-MID","_LINK":"SECTION-UG-Machine-identifiers-MID" },
+
+ {"MID":"7fe2832d60014259a8d67a09f1db102a","_LINK":"7fe2832d60014259a8d67a09f1db102a" },
+
+ {"MID":"4afebe421fe341b8b609b1c24f47b708","_LINK":"6.2.4.1.1-Unique-vs-machine-identifiers-MID-vs-UID" },
+
+ {"MID":"a5a3d62d90f646aa8fac43795aa8fcbb","_LINK":"a5a3d62d90f646aa8fac43795aa8fcbb" },
+
+ {"MID":"6a7c6a10b0fc4db7a5b32abedc3bb31c","_LINK":"6.2.4.2-UID" },
+
+ {"MID":"2c3b050a2cd0444fb8948bb6adcb7085","_LINK":"2c3b050a2cd0444fb8948bb6adcb7085" },
+
+ {"MID":"f01eced244e842e28c0729d8458ac935","UID":"UG_NODE_WITHOUT_A_LEVEL","_LINK":"UG_NODE_WITHOUT_A_LEVEL" },
+
+ {"MID":"094425a33e8941d9a0016b4ed714c664","_LINK":"094425a33e8941d9a0016b4ed714c664" },
+
+ {"MID":"05c39a0bc4d9482ca4199c84b1981948","_LINK":"6.2.4.4-STATUS" },
+
+ {"MID":"448aa949724e4361a5b2f317c40c7492","_LINK":"6.2.4.5-TAGS" },
+
+ {"MID":"d7c2d72f849b413cb312d44813d25d5a","_LINK":"d7c2d72f849b413cb312d44813d25d5a" },
+
+ {"MID":"62480ac9dbdf4e4fb5c533abefa19997","_LINK":"6.2.4.6-TITLE" },
+
+ {"MID":"f5f9008f417e40aa8acd9da18ccd89d1","_LINK":"f5f9008f417e40aa8acd9da18ccd89d1" },
+
+ {"MID":"fb3b2d0bbf4c43abaa09b29b106346d4","_LINK":"6.2.4.7-STATEMENT" },
+
+ {"MID":"cea069906c2e4329bea0d97744984ba8","_LINK":"cea069906c2e4329bea0d97744984ba8" },
+
+ {"MID":"bf35d37584b34aabb5bf3b2e144beecb","_LINK":"6.2.4.8-RATIONALE" },
+
+ {"MID":"7e63bdbce418401da8eb5aa607fd8fc2","_LINK":"7e63bdbce418401da8eb5aa607fd8fc2" },
+
+ {"MID":"165b33aa61474a1db0ca0bd1f1279ba4","_LINK":"6.2.4.9-COMMENT" },
+
+ {"MID":"3928acde165b4505943154199ecd739a","_LINK":"3928acde165b4505943154199ecd739a" },
+
+ {"MID":"f10fd08172054423be7c00fcd16e61e9","UID":"SDOC_UG_REQUIREMENT_RELATIONS","_LINK":"SDOC_UG_REQUIREMENT_RELATIONS" },
+
+ {"MID":"c0c9c15d57e742ed80f12b8895f01de0","_LINK":"c0c9c15d57e742ed80f12b8895f01de0" },
+
+ {"MID":"c357b57be45a4871a6dfb877483de702","_LINK":"6.2.4.10.1-Relation-roles" },
+
+ {"MID":"a54f41576b2d40df92041862bef13600","_LINK":"a54f41576b2d40df92041862bef13600" },
+
+ {"MID":"57df0956302f4c728f6b35606320b660","UID":"UG_COMPOSABLE_DOCUMENTS","_LINK":"UG_COMPOSABLE_DOCUMENTS" },
+
+ {"MID":"6ed881a7cb8949cab3d1a1836846b716","_LINK":"6ed881a7cb8949cab3d1a1836846b716" },
+
+ {"MID":"952dd638d61c45ab950f271d53e56b2f","_LINK":"952dd638d61c45ab950f271d53e56b2f" },
+
+ {"MID":"0d29071c7f924ecdb11fc32da4ecc5e3","UID":"SECTION-UG-DOCUMENT-GRAMMAR","_LINK":"SECTION-UG-DOCUMENT-GRAMMAR" },
+
+ {"MID":"4c2244d6affb4653844f730e1de88266","_LINK":"4c2244d6affb4653844f730e1de88266" },
+
+ {"MID":"269600f411374fce975c3d7110ae74b6","_LINK":"6.3.1-Supported-field-types" },
+
+ {"MID":"a437c871dc3d46dba80460d5c8c22cf6","_LINK":"a437c871dc3d46dba80460d5c8c22cf6" },
+
+ {"MID":"3b9af7a4f6444664aa9e76343b477236","_LINK":"6.3.2-Grammar-element-properties" },
+
+ {"MID":"e1e5bda619f549188d8d7ae158aeaa44","_LINK":"6.3.2.1-IS_COMPOSITE" },
+
+ {"MID":"5396d4571b4c4204b093a44980a489ed","_LINK":"5396d4571b4c4204b093a44980a489ed" },
+
+ {"MID":"f2c8342dd6f5432c95ef6f80cf5e87ba","_LINK":"6.3.2.2-PREFIX" },
+
+ {"MID":"19d4dcbf0cd24f84996bcddb778e348c","_LINK":"19d4dcbf0cd24f84996bcddb778e348c" },
+
+ {"MID":"61df1b83c27e43909ad5640cf0d78962","UID":"SECTION-UG-VIEW_STYLE-2","_LINK":"SECTION-UG-VIEW_STYLE-2" },
+
+ {"MID":"4678706b4c864f459d1b478cd703fcc1","_LINK":"4678706b4c864f459d1b478cd703fcc1" },
+
+ {"MID":"04828fd96e2e42f3810af276d06859c1","UID":"SDOC_UG_GRAMMAR_RELATIONS","_LINK":"SDOC_UG_GRAMMAR_RELATIONS" },
+
+ {"MID":"012b0350547a48fc9ab3fbd6d9b5d502","_LINK":"012b0350547a48fc9ab3fbd6d9b5d502" },
+
+ {"MID":"16ce47f32874421986a5a843c5aeb2bf","UID":"SECTION-UG-Relation-roles","_LINK":"SECTION-UG-Relation-roles" },
+
+ {"MID":"01b8aa59963b42518d98c4e6b5e3259b","_LINK":"01b8aa59963b42518d98c4e6b5e3259b" },
+
+ {"MID":"ed4e4d30b3eb46ca976295aa27ede9e3","UID":"SDOC_UG_GRAMMAR_RELATIONS_PARENT_VS_CHILD","_LINK":"SDOC_UG_GRAMMAR_RELATIONS_PARENT_VS_CHILD" },
+
+ {"MID":"b119e614781044eab641e20eaec872e5","_LINK":"b119e614781044eab641e20eaec872e5" },
+
+ {"MID":"cd7d9c9b0efe443895d1b6eb44a3799b","_LINK":"6.3.4-IMPORT_FROM_FILE-Importing-grammar-from-file" },
+
+ {"MID":"df106206da0e446e87021fbf711fdb65","_LINK":"df106206da0e446e87021fbf711fdb65" },
+
+ {"MID":"d4292ad751ca407b8147e7204a934c4e","UID":"SDOC_UG_LINKS_AND_ANCHORS","_LINK":"SDOC_UG_LINKS_AND_ANCHORS" },
+
+ {"MID":"6ce1010a003146ec9e3e8d77ee89a082","_LINK":"6ce1010a003146ec9e3e8d77ee89a082" },
+
+ {"MID":"ac7ccc30e5bf489cb4929302c8ec21cf","_LINK":"6.4.1-Links" },
+
+ {"MID":"8b07c82f462348a58c3ab81be4db753d","_LINK":"8b07c82f462348a58c3ab81be4db753d" },
+
+ {"MID":"a1d9bb6b7df84b5eb6bf355542a5288a","_LINK":"6.4.2-Anchors" },
+
+ {"MID":"294d6a0e96424dc8a93d6502c43e8501","_LINK":"294d6a0e96424dc8a93d6502c43e8501" },
+
+ {"MID":"26b105a45eda470497148a7903ca731b","_LINK":"6.4.2.1-Anchor-example" },
+
+ {"MID":"ba71ef8f24b342178b28e87b7609b8d7","_LINK":"ba71ef8f24b342178b28e87b7609b8d7" },
+
+ {"MID":"ec9dcd4ad28a4852bc47723e667006df","_LINK":"6.5-Syntax-rules" },
+
+ {"MID":"926894ac8efc4e99943741691b3d4efe","UID":"SECTION-UG-Strict-rule-1","_LINK":"SECTION-UG-Strict-rule-1" },
+
+ {"MID":"2ebd1f2d3c8746a383d71232756c3bd3","_LINK":"2ebd1f2d3c8746a383d71232756c3bd3" },
+
+ {"MID":"1e465597f02842de92852be3a57f84cb","UID":"SECTION-UG-Strict-rule-2","_LINK":"SECTION-UG-Strict-rule-2" },
+
+ {"MID":"686eb01cf7db44c4bd1edd72ccb02ed0","_LINK":"686eb01cf7db44c4bd1edd72ccb02ed0" },
+
+ {"MID":"c741dd299b044fc9b72510256d48589e","UID":"SECTION-UG-Strict-rule-3","_LINK":"SECTION-UG-Strict-rule-3" },
+
+ {"MID":"c01ab5711463497498c91a968179d63c","_LINK":"c01ab5711463497498c91a968179d63c" },
+
+ {"MID":"31eb939aa5684f74b86be93ea7f14f7b","_LINK":"7-Markup" },
+
+ {"MID":"a3d675f38a1341548722239e994e55e1","_LINK":"a3d675f38a1341548722239e994e55e1" },
+
+ {"MID":"64d48546374e4bfd881733b0174fbebe","_LINK":"7.1-Images" },
+
+ {"MID":"e87ffdf6195c481cb39bc3d1ec29eca6","_LINK":"e87ffdf6195c481cb39bc3d1ec29eca6" },
+
+ {"MID":"83066d011cef4e8694aac5fbe90a357e","_LINK":"7.2-Mathjax-support" },
+
+ {"MID":"abdf406fe10847929dd7cb12a030456f","_LINK":"abdf406fe10847929dd7cb12a030456f" },
+
+ {"MID":"3e761d05262f44d29f48476c89ce3ca2","_LINK":"8-Export-formats" },
+
+ {"MID":"110260c57dbb47da87662686bc73d6e7","_LINK":"8.1-HTML-documentation-tree-by-StrictDoc" },
+
+ {"MID":"a6bfffddf89045a1a7ecf55c9681fe14","_LINK":"a6bfffddf89045a1a7ecf55c9681fe14" },
+
+ {"MID":"dcc6a2bc11424cf2b114b25a7f65530d","UID":"SECTION-UG-Inbound-Links","_LINK":"SECTION-UG-Inbound-Links" },
+
+ {"MID":"742831d32ca54791b53c1dbbbd070b55","_LINK":"742831d32ca54791b53c1dbbbd070b55" },
+
+ {"MID":"1b41e7c036cf4e3282fa3d4e687bf95d","_LINK":"8.1.2-Standalone-HTML-pages" },
+
+ {"MID":"5674bfd50f31420baf56625d79d1ebff","_LINK":"5674bfd50f31420baf56625d79d1ebff" },
+
+ {"MID":"f6091bab49714c1fa72c2fbca12c970b","UID":"SECTION-UG-HTML-export-via-Sphinx","_LINK":"SECTION-UG-HTML-export-via-Sphinx" },
+
+ {"MID":"bf8160f43703418db306785c48463123","_LINK":"bf8160f43703418db306785c48463123" },
+
+ {"MID":"c95a2b4c4fbd40fcbd92fe7f24c2cd91","UID":"SECTION-UG-PDF-export-via-Sphinx-LaTeX","_LINK":"SECTION-UG-PDF-export-via-Sphinx-LaTeX" },
+
+ {"MID":"58595abe6ff148afbb45e2b6adc25110","_LINK":"58595abe6ff148afbb45e2b6adc25110" },
+
+ {"MID":"e33a21323e2b48d692ed85cc56fd06e6","_LINK":"8.4-JSON" },
+
+ {"MID":"4d956edcd00846a98f59778dd7de9257","_LINK":"4d956edcd00846a98f59778dd7de9257" },
+
+ {"MID":"40050f96b9a64f57bbb0ad01f4d37264","_LINK":"9-Manage-project-tree" },
+
+ {"MID":"7f4b56d2a1104f539489bf7ddcdb1469","UID":"SECTION-UG-Automatic-assignment-of-requirements-UID","_LINK":"SECTION-UG-Automatic-assignment-of-requirements-UID" },
+
+ {"MID":"ed367ed0bc284d4d9318bf6c844c3e3e","_LINK":"ed367ed0bc284d4d9318bf6c844c3e3e" },
+
+ {"MID":"fa1cc31842144440a8ca310c7c0dedb2","UID":"SECTION-TRACEABILITY-REQS-TO-SOURCE-CODE","_LINK":"SECTION-TRACEABILITY-REQS-TO-SOURCE-CODE" },
+
+ {"MID":"4398b17f61ad4dd290e72d7888597f48","_LINK":"4398b17f61ad4dd290e72d7888597f48" },
+
+ {"MID":"845ff817ad9d483796b9dc6016bfc3c7","UID":"SECTION-UG-Language-aware-parsing-of-source-code","_LINK":"SECTION-UG-Language-aware-parsing-of-source-code" },
+
+ {"MID":"07bfe045a4934dd29d97fdb8ac567b7c","_LINK":"07bfe045a4934dd29d97fdb8ac567b7c" },
+
+ {"MID":"2cde4b7a4d42450c84c93989aeb4d53d","_LINK":"10.2-Linking-source-code-to-requirements" },
+
+ {"MID":"c787c538cc0a422fb2898b525ec1006d","_LINK":"c787c538cc0a422fb2898b525ec1006d" },
+
+ {"MID":"a72c5eceff5c446c968c0e23bda3d933","_LINK":"10.3-Linking-requirements-to-source-code" },
+
+ {"MID":"1c06fb7b90114633801d177459f482b5","_LINK":"1c06fb7b90114633801d177459f482b5" },
+
+ {"MID":"38599400293a4b31a7cb6cb748f3dfe5","UID":"SECTION-UG-File-relations-roles","_LINK":"SECTION-UG-File-relations-roles" },
+
+ {"MID":"4f477cb2e0ca42aaac814042f795b982","_LINK":"4f477cb2e0ca42aaac814042f795b982" },
+
+ {"MID":"c9da7df725564208971e7ee058ad8d73","UID":"SECTION-UG-Parsing-SDoc-source-nodes","_LINK":"SECTION-UG-Parsing-SDoc-source-nodes" },
+
+ {"MID":"72fe8c3f618042578850cfdf01868b6c","_LINK":"72fe8c3f618042578850cfdf01868b6c" },
+
+ {"MID":"31411ccbe80144868da8961ea2dd38bc","UID":"SECTION-UG-ReqIF-support","_LINK":"SECTION-UG-ReqIF-support" },
+
+ {"MID":"b510d9337e604bfda366f2ec605f4c88","_LINK":"b510d9337e604bfda366f2ec605f4c88" },
+
+ {"MID":"81f3e7ff2e584f789e0076d0ab560d45","_LINK":"11.1-Import-flow-ReqIF-SDoc" },
+
+ {"MID":"079ed6d7ec3f4040b59efce7ccd37267","_LINK":"079ed6d7ec3f4040b59efce7ccd37267" },
+
+ {"MID":"7d1678af20a84f5d8263061f36332773","_LINK":"11.2-Export-flow-SDoc-ReqIF" },
+
+ {"MID":"94641cac6b9748bfa2de8648ff197584","_LINK":"94641cac6b9748bfa2de8648ff197584" },
+
+ {"MID":"c87ecf181d564e44ad1981558bf2cab0","UID":"SECTION-UG-ReqIF-options","_LINK":"SECTION-UG-ReqIF-options" },
+
+ {"MID":"57dd1fb10ba64e2f8e0b75baf772b634","_LINK":"57dd1fb10ba64e2f8e0b75baf772b634" },
+
+ {"MID":"95643ee2edb84ad8b86f9cf2bb74aaae","UID":"SECTION-REQIF-DETAILS","_LINK":"SECTION-REQIF-DETAILS" },
+
+ {"MID":"edd5c3bf902e48deaee3248d12087a75","_LINK":"edd5c3bf902e48deaee3248d12087a75" },
+
+ {"MID":"5ad8e72bdcfb4ac1b942468af9180657","_LINK":"12-Excel-support" },
+
+ {"MID":"65c1657a8fb04179960fca4ece265b18","_LINK":"65c1657a8fb04179960fca4ece265b18" },
+
+ {"MID":"4a34ea5da82b4e469cf5a87178f69536","_LINK":"12.1-Import-flow-Excel-XLS-XLSX-SDoc" },
+
+ {"MID":"b01355b5a6d54409a0c7a684376a5278","_LINK":"b01355b5a6d54409a0c7a684376a5278" },
+
+ {"MID":"1cbdef9ee67b4392a3bdb64276e90e36","_LINK":"12.2-Export-flow-SDoc-Excel-XLSX" },
+
+ {"MID":"14161a9fa81d427f8a5a21367359339e","_LINK":"14161a9fa81d427f8a5a21367359339e" },
+
+ {"MID":"17a8adb92c8d4e7992e869355e73912d","_LINK":"13-Options" },
+
+ {"MID":"05f82bdf26f141738d2f511133633a2d","UID":"SDOC_UG_OPTIONS_PROJECT_LEVEL","_LINK":"SDOC_UG_OPTIONS_PROJECT_LEVEL" },
+
+ {"MID":"6449098df878484fbe8aed8a8b0e9a97","_LINK":"6449098df878484fbe8aed8a8b0e9a97" },
+
+ {"MID":"3671119d6a304d0b80c63f7e31faee88","_LINK":"13.1.1-Project-title" },
+
+ {"MID":"12501275599f4d7a954892e1a56778b9","_LINK":"12501275599f4d7a954892e1a56778b9" },
+
+ {"MID":"22741629bf054d6784faf541393e90d0","_LINK":"13.1.2-Path-to-assets" },
+
+ {"MID":"7d1102cda98c4ea18c6e646b73511097","_LINK":"7d1102cda98c4ea18c6e646b73511097" },
+
+ {"MID":"9fbabb0a6d0e46648f58ba7245776bd9","UID":"SECTION-UG-Path-to-cache-dir","_LINK":"SECTION-UG-Path-to-cache-dir" },
+
+ {"MID":"e94e9762cc0e4e1eafe57d0d9e03eb5b","_LINK":"e94e9762cc0e4e1eafe57d0d9e03eb5b" },
+
+ {"MID":"2c54380e174e42b6ba8eff74173ceb0f","_LINK":"13.1.4-Path-to-source-root" },
+
+ {"MID":"be42ecf5c8a84fc3bca0b73ea50647de","_LINK":"be42ecf5c8a84fc3bca0b73ea50647de" },
+
+ {"MID":"499fa0144cbd48c687ba0d5f9f7cb846","_LINK":"13.1.5-Path-to-custom-HTML2PDF-template" },
+
+ {"MID":"225dc4d22c084a67ae049fca1098bc1a","_LINK":"225dc4d22c084a67ae049fca1098bc1a" },
+
+ {"MID":"593a2abbdaa5470988103c70e87c4cfc","_LINK":"13.1.6-Include-exclude-document-paths" },
+
+ {"MID":"27e5981c451d4ad4938ab622e3cf0be2","_LINK":"27e5981c451d4ad4938ab622e3cf0be2" },
+
+ {"MID":"7284798d60a340c2a6369c651d1ee6be","_LINK":"13.1.7-Include-exclude-source-files-paths" },
+
+ {"MID":"3908f98fab5c47668ba752d0e93033ab","_LINK":"3908f98fab5c47668ba752d0e93033ab" },
+
+ {"MID":"b355fc6730d14eb1892ac6a25e47bf59","UID":"SDOC_UG_CONFIG_FEATURES","_LINK":"SDOC_UG_CONFIG_FEATURES" },
+
+ {"MID":"f43d8170c44b4d70ada2816fe71caf07","_LINK":"f43d8170c44b4d70ada2816fe71caf07" },
+
+ {"MID":"39f7752d17c848e4ae9acd53eaf8048b","_LINK":"13.1.8.1-Enable-all-features" },
+
+ {"MID":"d33880e1740d4d0892852cc8c425f66f","_LINK":"d33880e1740d4d0892852cc8c425f66f" },
+
+ {"MID":"35173b0d735a4d4f8c06256d1d4e1f89","_LINK":"13.1.8.2-Disable-all-features" },
+
+ {"MID":"9cf2ac683b7a4e939286146ef00631c1","_LINK":"9cf2ac683b7a4e939286146ef00631c1" },
+
+ {"MID":"fc0da01a4a114ddd888a90fd6a29e456","_LINK":"13.1.9-Server-configuration" },
+
+ {"MID":"c520cefdfe3e47ccb1a0ada95ee5c4f0","UID":"SECTION-UG-Host-and-port","_LINK":"SECTION-UG-Host-and-port" },
+
+ {"MID":"9943131c688c400b99e2db9ec4854480","_LINK":"9943131c688c400b99e2db9ec4854480" },
+
+ {"MID":"cc720b525adf46849f6117c18c97905e","_LINK":"13.2-Command-line-interface-options" },
+
+ {"MID":"d69f1fe42c754a34a5f360f47d4b4a5b","_LINK":"13.2.1-Project-title" },
+
+ {"MID":"81d8e1beb5904cb78dfde2712ff3f311","_LINK":"81d8e1beb5904cb78dfde2712ff3f311" },
+
+ {"MID":"6ea7b264c142461398e9c8711cfec8d3","_LINK":"13.2.2-Parallelization" },
+
+ {"MID":"f8ff07833ff942dfabdad2412350cd0c","_LINK":"f8ff07833ff942dfabdad2412350cd0c" },
+
+ {"MID":"8030a2ceb5014b9881529ef39d3c1fb7","_LINK":"14-Python-API" },
+
+ {"MID":"4504bffd6ced4aa78848ee9e03fdd4b7","_LINK":"4504bffd6ced4aa78848ee9e03fdd4b7" },
+
+ {"MID":"cb5115ac9a6d47a198ceac81c9d49b60","UID":"UG_PORTABILITY_CONSIDERATIONS","_LINK":"UG_PORTABILITY_CONSIDERATIONS" },
+
+ {"MID":"e15260727be84ce394386a4f95c627ae","_LINK":"e15260727be84ce394386a4f95c627ae" },
+
+ {"MID":"d49d64a25f654d0c9b39023e87e5fa19","_LINK":"16-Interoperability-with-other-tools" },
+
+ {"MID":"dc83f93c820944b6b04c0923a7ad7e69","UID":"SECTION-UG-Doxygen","_LINK":"SECTION-UG-Doxygen" },
+
+ {"MID":"a8664547ac7e41399d7d8d263869abc6","_LINK":"a8664547ac7e41399d7d8d263869abc6" },
+
+ {"MID":"1296f265cdd948d8a5c02fbfc1cc4065","_LINK":"16.2-Valispace" },
+
+ {"MID":"5fe39dedfa4640d2bd7127ff23b0e3de","_LINK":"5fe39dedfa4640d2bd7127ff23b0e3de" },
+
+ {"MID":"e3596b4fb0804ac28a8bb3d06bd81953","UID":"SDOC_UG_EXPERIMENTAL_FEATURES","_LINK":"SDOC_UG_EXPERIMENTAL_FEATURES" },
+
+ {"MID":"5b400736aec54789b2ed3ebcffcf961e","_LINK":"5b400736aec54789b2ed3ebcffcf961e" },
+
+ {"MID":"72fdb23051184714ab32e22859504a77","UID":"SECTION-UG-Search-and-filtering","_LINK":"SECTION-UG-Search-and-filtering" },
+
+ {"MID":"de584af947a445e5bcc782bab6a93baf","_LINK":"de584af947a445e5bcc782bab6a93baf" },
+
+ {"MID":"f2d766a310ef41959b0c6d581d042420","_LINK":"17.1.1-Query-engine" },
+
+ {"MID":"29ffc3e91d8045589b0837f647286128","_LINK":"29ffc3e91d8045589b0837f647286128" },
+
+ {"MID":"2da071ad45054d168a5ae2982266fb77","_LINK":"17.1.2-Filtering-content" },
+
+ {"MID":"d52d86750ad54ce1b3263ebb092451c0","_LINK":"d52d86750ad54ce1b3263ebb092451c0" },
+
+ {"MID":"241afbf6b7af40189eec8054d0d0201c","UID":"SECTION-UG-Project-statistics-screen","_LINK":"SECTION-UG-Project-statistics-screen" },
+
+ {"MID":"2fefc893de83432fa852886cc3a05fea","_LINK":"2fefc893de83432fa852886cc3a05fea" },
+
+ {"MID":"aa84a8c59a904c9dbb1052b1bff169bf","_LINK":"17.2.1-User-provided-custom-statistics-generator-experimental" },
+
+ {"MID":"7cf15de69efc46a5abe6b6fc786e4b71","_LINK":"7cf15de69efc46a5abe6b6fc786e4b71" },
+
+ {"MID":"aa7ebc36cd2947ac9aa293d6c76d8848","UID":"SECTION-UG-Diff-changelog-screen","_LINK":"SECTION-UG-Diff-changelog-screen" },
+
+ {"MID":"131a7392a33f4225a62539dd173a920b","_LINK":"131a7392a33f4225a62539dd173a920b" },
+
+ {"MID":"0a4573d025f14e61b84aad14349d42f4","UID":"SECTION-UG-HTML2PDF-document-generator","_LINK":"SECTION-UG-HTML2PDF-document-generator" },
+
+ {"MID":"6e610b9a381f4b5d9d26004dd286e001","_LINK":"6e610b9a381f4b5d9d26004dd286e001" },
+
+ {"MID":"61b3fa2fc31140ae95ae1a651cb18355","_LINK":"17.5-Mermaid-diagramming-and-charting-tool" },
+
+ {"MID":"6a4e4467a5c0451ea8291fd94309d525","_LINK":"6a4e4467a5c0451ea8291fd94309d525" },
+
+ {"MID":"74291dc6cfae47d2bae33066024f3807","_LINK":"17.6-Test-report-integration" },
+
+ {"MID":"07e78a4847554fbd87c44d7b11133f68","_LINK":"07e78a4847554fbd87c44d7b11133f68" },
+
+ {"MID":"e9c94abacb12425980aec8ed7ee752cb","_LINK":"17.6.1-JUnit-XML" },
+
+ {"MID":"eba63ebd45624139a8773cf42fe7d670","_LINK":"eba63ebd45624139a8773cf42fe7d670" },
+
+ {"MID":"06d9dbbeca204f5e8d0042e142b615bd","_LINK":"17.6.2-LLVM-Integrated-Tester-JUnit-XML-specifics" },
+
+ {"MID":"fab24f53f02f46e7a4cb49e333dfdc54","_LINK":"fab24f53f02f46e7a4cb49e333dfdc54" },
+
+ {"MID":"c7f5451905bf4fdb9a3a7dc97bb0e853","_LINK":"17.6.3-Robot-Framework-XML" },
+
+ {"MID":"6c3d98ca65cc40d585953237693ff2c6","_LINK":"6c3d98ca65cc40d585953237693ff2c6" },
+
+ {"MID":"66e608bfa6b8448598c0a732a27ddaad","_LINK":"17.7-Shadow-features" },
+
+ {"MID":"38fa0af0d01e479ba7f5be046bae02eb","_LINK":"38fa0af0d01e479ba7f5be046bae02eb" },
+
+ {"MID":"c3c6d6fe6e8140ca905d26dbbaae22b3","UID":"SDOC_UG_LIMIT","_LINK":"SDOC_UG_LIMIT" },
+
+ {"MID":"4fb2645146eb42c1be2152d480b61cfc","UID":"SDOC_UG_LIMIT_RST","_LINK":"SDOC_UG_LIMIT_RST" },
+
+ {"MID":"f7b039831f4e4c1ea19b45efe71c5365","_LINK":"f7b039831f4e4c1ea19b45efe71c5365" },
+
+ {"MID":"076c2ae8d627491a85ddcacc132a4bc5","UID":"SDOC_UG_LIMIT_WEB","_LINK":"SDOC_UG_LIMIT_WEB" },
+
+ {"MID":"911c454331634018b8de24186ae8e742","_LINK":"911c454331634018b8de24186ae8e742" },
+
+ {"MID":"2a49392c11d246ea8c69375764fc5362","_LINK":"18.2.1-Concurrent-use-of-web-user-interface" },
+
+ {"MID":"bdee3bde500a40878b70be44f113cf2c","_LINK":"bdee3bde500a40878b70be44f113cf2c" },
+
+ {"MID":"c5cfb2c7892f4137a3bc0c3136a55a89","_LINK":"19-Known-issues" },
+
+ {"MID":"9282f2d7218a4f2e967b6df45b0347ab","_LINK":"9282f2d7218a4f2e967b6df45b0347ab" },
+
+ {"MID":"7e4c91401d244149a1aa502d990f0052","UID":"SDOC_IMPL_2","_LINK":"SDOC_IMPL_2" },
+
+ {"MID":"ec83d51626ee4e0cbb75c500ee306b06","_LINK":"ec83d51626ee4e0cbb75c500ee306b06" },
+
+ {"MID":"b55c23b113d54802b5717f7a82a45bd2","_LINK":"20-Appendices" },
+
+ {"MID":"a72ae310493a42ba8ecdc7de2c42d4f2","UID":"SECTION-UG-FREETEXT-TEXT","_LINK":"SECTION-UG-FREETEXT-TEXT" },
+
+ {"MID":"2509cce7ee634c7a8878c5e1094b83f2","_LINK":"2509cce7ee634c7a8878c5e1094b83f2" },
+
+ {"MID":"bbe50de9a4d845a7aa91e32dd9335abe","_LINK":"20.1.1-How-to-migrate-from-FREETEXT-to-TEXT" },
+
+ {"MID":"5d2f033604824264b1cc05840997c6b8","_LINK":"5d2f033604824264b1cc05840997c6b8" },
+
+ {"MID":"2ed20461aeb4462b812432c08aa006be","UID":"SECTION-UG-NODE-MIGRATION","_LINK":"SECTION-UG-NODE-MIGRATION" },
+
+ {"MID":"9d55b69bf789487e814210da06fc4164","_LINK":"9d55b69bf789487e814210da06fc4164" },
+
+ {"MID":"6f15ef6876ba48598d5560aaf4664ec9","_LINK":"20.2.1-How-to-migrate-from-SECTION-to-SECTION" },
+
+ {"MID":"19fe5099aa034eddb960cc88953ace0e","_LINK":"19fe5099aa034eddb960cc88953ace0e" }, ],
+ "strictdoc/docs/strictdoc_02_feature_map.html": [
+
+
+ {"MID":"1696d73230f046d589d2d87dd29d48a9","UID":"SDOC_FEATURE_MAP","_LINK":"SDOC_FEATURE_MAP" },
+
+ {"MID":"f405431dc66e4d6786be020a62a4e5a3","_LINK":"f405431dc66e4d6786be020a62a4e5a3" },
+
+ {"MID":"01c07ca347a24181a92a5be6c8431094","UID":"SECTION-FM-SDoc-text-markup","_LINK":"SECTION-FM-SDoc-text-markup" },
+
+ {"MID":"dfd4d2d77c7247819e476f360ffff639","_LINK":"1.1-Definition" },
+
+ {"MID":"4c40803dd0f04af88fd722ba6b732270","UID":"SDOC-FEAT-1","_LINK":"SDOC-FEAT-1" },
+
+ {"MID":"3f422abd9abe4717a995ae4150df12e3","_LINK":"1.2-Use-case" },
+
+ {"MID":"8ea5b080819e47afa78bc346d671cf30","_LINK":"8ea5b080819e47afa78bc346d671cf30" },
+
+ {"MID":"fa7b37153def4eb4a6e9dcee079cba2a","_LINK":"1.3-Inspirations" },
+
+ {"MID":"104b6ff4623f4ac9a965aa789c4cf001","_LINK":"104b6ff4623f4ac9a965aa789c4cf001" },
+
+ {"MID":"87b1538be72a4ff7945b5bb95f856471","_LINK":"1.4-Screenshots" },
+
+ {"MID":"f48ae881c5134f77885202b019e124d4","_LINK":"f48ae881c5134f77885202b019e124d4" },
+
+ {"MID":"27bb9f0875d84d79bb882f6ca98ee1fa","_LINK":"2-HTML-export" },
+
+ {"MID":"4a0844b5938a488a89ac4b379fc7d956","_LINK":"2.1-Definition" },
+
+ {"MID":"8e6604c8b27b450cbd21c12dc8572291","UID":"SDOC-FEAT-2","_LINK":"SDOC-FEAT-2" },
+
+ {"MID":"4e46063e2031418298b55a1861179900","_LINK":"2.2-Screenshots" },
+
+ {"MID":"586f8745588b483b8e027021d90931ac","_LINK":"586f8745588b483b8e027021d90931ac" },
+
+ {"MID":"3ef4254efd8547a8adaf37e100f22724","_LINK":"3-Web-based-graphical-user-interface" },
+
+ {"MID":"bd3e1273cb244616956bddfc22c05638","_LINK":"3.1-Definition" },
+
+ {"MID":"2c1cde585d5944b5b7b5a0d5f72a98ed","UID":"SDOC-FEAT-3","_LINK":"SDOC-FEAT-3" },
+
+ {"MID":"6b5989db0e984c42b12440993c885987","_LINK":"3.2-Screenshots" },
+
+ {"MID":"28ce32fe182c45ce882b65c835620339","_LINK":"28ce32fe182c45ce882b65c835620339" },
+
+ {"MID":"5ac3e3c690494371bd9de04be5eae0b0","_LINK":"4-Traceability-between-requirements-and-source-code" },
+
+ {"MID":"538d26fae4644debbc8f244709b8be7b","_LINK":"4.1-Definition" },
+
+ {"MID":"e14eee106ea443e598378e55401914dc","UID":"SDOC-FEAT-4","_LINK":"SDOC-FEAT-4" },
+
+ {"MID":"ceec313d9ec040b9bcaaf64967ed6af8","_LINK":"4.2-Screenshots" },
+
+ {"MID":"363aae23cbb44f30aff42ef6a430ffdf","_LINK":"363aae23cbb44f30aff42ef6a430ffdf" },
+
+ {"MID":"a436d31c5f324eb0bb6b35f0a6ce598d","_LINK":"5-Document-grammar" },
+
+ {"MID":"f20223cddcb14e40b45f99045e2d3a3a","_LINK":"5.1-Definition" },
+
+ {"MID":"0bfcb6144dde487791d4f01164dd7e7c","UID":"SDOC-FEAT-5","_LINK":"SDOC-FEAT-5" },
+
+ {"MID":"f4763b00f9624cfd8b44f8e571f2aec6","_LINK":"5.2-Screenshots" },
+
+ {"MID":"3d3d3e2c1c974ed4a2382770225212d7","_LINK":"3d3d3e2c1c974ed4a2382770225212d7" },
+
+ {"MID":"5b511eac439c4e0a8aa2c60499be88d0","_LINK":"6-Composable-documents" },
+
+ {"MID":"ab4bc7b948154dbfbd4956d41cda8b75","_LINK":"6.1-Definition" },
+
+ {"MID":"e7b2d61545eb414f97345ecac25c52cc","UID":"SDOC-FEAT-6","_LINK":"SDOC-FEAT-6" },
+
+ {"MID":"dd4d9c0d593b46f8a0abfb3fd91356ae","_LINK":"7-Export-to-RST" },
+
+ {"MID":"ab0e4d27b6334b44bd4b46425842cdbe","_LINK":"7.1-Definition" },
+
+ {"MID":"dd686a557c3e4e50ba89538a74d39383","UID":"SDOC-FEAT-8","_LINK":"SDOC-FEAT-8" },
+
+ {"MID":"f0a7041347444f3a822129120faf0fcd","_LINK":"7.2-Screenshots" },
+
+ {"MID":"45be72764a73440b8abf313bb84420aa","_LINK":"45be72764a73440b8abf313bb84420aa" },
+
+ {"MID":"2e8e39a2198e4f8aa18a470a892e4d25","_LINK":"8-Export-to-PDF" },
+
+ {"MID":"381ebcd10ee241aaaa9fe3654870961c","_LINK":"8.1-Definition" },
+
+ {"MID":"5be4f35be2eb49faae7c33b5a2d83251","UID":"SDOC-FEAT-10","_LINK":"SDOC-FEAT-10" },
+
+ {"MID":"2d8b04efe57d4c0aa543ed974ace868e","_LINK":"8.2-Screenshots" },
+
+ {"MID":"15d6e791674c4c0ab54afb6a781f35c9","_LINK":"9-Query-engine-and-search-screen" },
+
+ {"MID":"91177d3444d9437e87032875ac8fcd7d","_LINK":"9.1-Definition" },
+
+ {"MID":"9c1e6cb601294891bcaae2b8c9042c59","UID":"SDOC-FEAT-7","_LINK":"SDOC-FEAT-7" },
+
+ {"MID":"631f1620053342c8a398a1a5d458f873","_LINK":"9.2-Screenshots" },
+
+ {"MID":"64afc2abdab847439c0c18420db7ba47","_LINK":"64afc2abdab847439c0c18420db7ba47" },
+
+ {"MID":"3475f60f31b5488aab981fd2b7b12d4c","_LINK":"10-Project-statistics" },
+
+ {"MID":"9bbcc02a46194852b9616ea4437ce976","_LINK":"10.1-Definition" },
+
+ {"MID":"2dd0b514a24f43a287a4096d0be0af58","UID":"SDOC-FEAT-11","_LINK":"SDOC-FEAT-11" },
+
+ {"MID":"7d215ba517fc4aee9dfb381279297cc7","_LINK":"10.2-Screenshots" },
+
+ {"MID":"bd5a4763e2ca4df497dbaeeff9ffbd71","_LINK":"bd5a4763e2ca4df497dbaeeff9ffbd71" },
+
+ {"MID":"0b3d7fad0ee643ef83617745c51e8e72","_LINK":"11-Documentation-diff-changelog" },
+
+ {"MID":"9cdf4d3af1014aea923f77b112e6b1e3","_LINK":"11.1-Definition" },
+
+ {"MID":"e9da42f8e39b438a8e8eada16b280706","UID":"SDOC-FEAT-12","_LINK":"SDOC-FEAT-12" },
+
+ {"MID":"c60c6fab5740469aa251bfa3a805f21f","_LINK":"11.2-Screenshots" },
+
+ {"MID":"1fad67b63724450bb63738cf7e29d051","_LINK":"1fad67b63724450bb63738cf7e29d051" },
+
+ {"MID":"f655f9a2bde044489233fa03d2891de1","_LINK":"12-ReqIF-support" },
+
+ {"MID":"1627a126e1184c5e9050206f2f1ab725","_LINK":"12.1-Definition" },
+
+ {"MID":"2845463f977d4b51ac788c2fc9cbd894","UID":"SDOC-FEAT-13","_LINK":"SDOC-FEAT-13" },
+
+ {"MID":"e1109c5b3b1c4068a0eace811684f0c0","_LINK":"13-Project-configuration" },
+
+ {"MID":"3c2a1a37e11c425184042d6dab3f050a","_LINK":"13.1-Definition" },
+
+ {"MID":"8fc72d79bfe940aba2cf041e263b92df","UID":"SDOC-FEAT-9","_LINK":"SDOC-FEAT-9" },
+
+ {"MID":"275658296e5342acab72102589096f15","_LINK":"13.2-Screenshots" },
+
+ {"MID":"100daefc4121415989324de1978d1f59","_LINK":"100daefc4121415989324de1978d1f59" }, ],
+ "strictdoc/docs/strictdoc_03_faq.html": [
+
+
+ {"MID":"a434bc71a7324efaaed7f5a58e56e544","UID":"SDOC_FAQ","_LINK":"SDOC_FAQ" },
+
+ {"MID":"5acdfccd5771492f95b70328bd599cf7","_LINK":"5acdfccd5771492f95b70328bd599cf7" },
+
+ {"MID":"e972c79015524961863e095280a81aab","_LINK":"1-What-is-StrictDoc" },
+
+ {"MID":"d8d92e4eb8254cbda8dcb37709a9df45","_LINK":"d8d92e4eb8254cbda8dcb37709a9df45" },
+
+ {"MID":"86827c92ec3a493d8a2382b75b5277a8","_LINK":"2-Resources-about-StrictDoc" },
+
+ {"MID":"f7083cf6a84e4b858b5e551f8c8a555a","_LINK":"2.1-Presentations" },
+
+ {"MID":"52342105083e4f80884959d4ca7f4dba","_LINK":"52342105083e4f80884959d4ca7f4dba" },
+
+ {"MID":"d22b63a405264a6a80d4ab3f9b2bf9c5","_LINK":"2.2-Blog-posts" },
+
+ {"MID":"b2f5aea77e504ee1b64a67be24bd3c58","_LINK":"b2f5aea77e504ee1b64a67be24bd3c58" },
+
+ {"MID":"d75bd4d35b4b425b90ec8667ffffe191","_LINK":"2.3-Screencasts-tutorials" },
+
+ {"MID":"9d23e77aa7f848cb8efca49f5cf41f77","_LINK":"9d23e77aa7f848cb8efca49f5cf41f77" },
+
+ {"MID":"74235945ec4a4116aecbc883ffba54b7","_LINK":"3-Which-web-server-is-recommended-for-StrictDoc-documentation" },
+
+ {"MID":"966a5c3babf84fc7a1454b2799d13470","_LINK":"966a5c3babf84fc7a1454b2799d13470" },
+
+ {"MID":"2e911dedb13348bf827f078bbbca44f4","_LINK":"4-Is-StrictDoc-compatible-with-Sphinx" },
+
+ {"MID":"ac35a712b4a84f4ab2b61feb15c1550d","_LINK":"ac35a712b4a84f4ab2b61feb15c1550d" },
+
+ {"MID":"235122d2c10748918c7c6ff736e39d18","UID":"SECTION-FAQ-How-did-the-SDoc-text-language-become-what-it-is","_LINK":"SECTION-FAQ-How-did-the-SDoc-text-language-become-what-it-is" },
+
+ {"MID":"b3561dd4f8e64f11a251c3471022aece","_LINK":"b3561dd4f8e64f11a251c3471022aece" },
+
+ {"MID":"1d4220cc9a5444a5bdbaee91c8c50670","_LINK":"6-How-StrictDoc-compares-to-other-tools" },
+
+ {"MID":"45093addf6ec4772a0289fd958ae61dc","_LINK":"45093addf6ec4772a0289fd958ae61dc" },
+
+ {"MID":"a4533ae81bfe446295242add9156198e","_LINK":"6.1-Doorstop" },
+
+ {"MID":"d0c305180d8747a1b70254eaf2c4f201","_LINK":"d0c305180d8747a1b70254eaf2c4f201" },
+
+ {"MID":"5012af516d18447caa3a2dbce97d3e4a","_LINK":"6.2-Sphinx" },
+
+ {"MID":"74b6be0dc2bb485987d8731348cdf5ce","_LINK":"74b6be0dc2bb485987d8731348cdf5ce" },
+
+ {"MID":"515bcae39d1f48eda0b72562871ab15a","_LINK":"6.3-Sphinx-Needs" },
+
+ {"MID":"602327a9b8654e1eab4bc265e172a63d","_LINK":"602327a9b8654e1eab4bc265e172a63d" },
+
+ {"MID":"4a77366154d74cf7ab34044bed1cd542","_LINK":"6.4-FRET" },
+
+ {"MID":"e3eb1be604c6499292339ecbe7620c60","_LINK":"e3eb1be604c6499292339ecbe7620c60" },
+
+ {"MID":"723731c256fc43dfb315a300f6429945","_LINK":"6.5-Other-tools" },
+
+ {"MID":"ad24dca8ed9c449ab76c1798f38eb37c","_LINK":"ad24dca8ed9c449ab76c1798f38eb37c" },
+
+ {"MID":"ff143a18e98144bd86e10e29616c187b","_LINK":"7-How-long-has-the-StrictDoc-project-been-around" },
+
+ {"MID":"47d60404cf574aebb8c83795589c4137","_LINK":"47d60404cf574aebb8c83795589c4137" },
+
+ {"MID":"6e5ed6bb36634220a0c583d21c96295f","_LINK":"8-Which-StrictDoc-statistics-are-available" },
+
+ {"MID":"730bfedff6b24c34a6d6331051fd76d3","_LINK":"730bfedff6b24c34a6d6331051fd76d3" }, ],
+ "strictdoc/docs/strictdoc_04_release_notes.html": [
+
+
+ {"MID":"4277890572a94f49bda9f32a80e43c06","_LINK":"None-Release-Notes" },
+
+ {"MID":"0dd2649ec4784c9480eac6f4aef3158b","_LINK":"0dd2649ec4784c9480eac6f4aef3158b" },
+
+ {"MID":"27d526d90cda48dfa5cbf17df88299ba","_LINK":"1-0-12-1-2025-09-18" },
+
+ {"MID":"7433a733b3794983b5e17169897c3732","_LINK":"7433a733b3794983b5e17169897c3732" },
+
+ {"MID":"f2a70deaf8164240951fca48510d7aa4","_LINK":"2-0-12-0-2025-09-17" },
+
+ {"MID":"a7e0cee58f054a50818f07a02bab7230","_LINK":"a7e0cee58f054a50818f07a02bab7230" },
+
+ {"MID":"721b576103a748c8a63d3147ec771b95","_LINK":"3-0-11-3-2025-09-07" },
+
+ {"MID":"e60129ab582946319616595111296e76","_LINK":"e60129ab582946319616595111296e76" },
+
+ {"MID":"4bd05b9073254db38322102f4bbc5096","_LINK":"4-0-11-2-2025-09-02" },
+
+ {"MID":"7776a30d522b4b5f9a6e405d20241566","_LINK":"7776a30d522b4b5f9a6e405d20241566" },
+
+ {"MID":"3e3043021e034cb69dfd9b62eecadbb3","_LINK":"5-0-11-1-2025-09-01" },
+
+ {"MID":"9a4bbed442b94d72859d70d31282efc1","_LINK":"9a4bbed442b94d72859d70d31282efc1" },
+
+ {"MID":"f53df5a2e9674373a8f52f1a01b5010d","_LINK":"6-0-11-0-2025-08-26" },
+
+ {"MID":"177963dca83748d89bfaeb01b3d663a8","_LINK":"177963dca83748d89bfaeb01b3d663a8" },
+
+ {"MID":"a5ab8dd5bc4045e99299eff729e430e6","_LINK":"7-0-10-1-2025-07-25" },
+
+ {"MID":"6d0bb97e7ef74fc1ae93cf2a91480e6a","_LINK":"6d0bb97e7ef74fc1ae93cf2a91480e6a" },
+
+ {"MID":"447ab1fa1d38453ab46e0002e6eb852d","_LINK":"8-0-10-0-2025-07-20" },
+
+ {"MID":"c536381cea6842f0b77c1aa5ac942ce0","_LINK":"c536381cea6842f0b77c1aa5ac942ce0" },
+
+ {"MID":"aa45a90bad3f4273ab46dade039ef4c6","_LINK":"9-0-9-4-2025-07-12" },
+
+ {"MID":"a25dd134646e462ca09e850481bccb2b","_LINK":"a25dd134646e462ca09e850481bccb2b" },
+
+ {"MID":"eca2ad204c8246a8b0f29a5eb8d7f799","_LINK":"10-0-9-3-2025-07-03" },
+
+ {"MID":"64706a3d4d9c4beda3597ffa9d92921a","_LINK":"64706a3d4d9c4beda3597ffa9d92921a" },
+
+ {"MID":"6665c867a01f49f59968ae83d2e928fe","_LINK":"11-0-9-2-2025-06-28" },
+
+ {"MID":"d56dfede85b84e07bd5ecddc82a576fc","_LINK":"d56dfede85b84e07bd5ecddc82a576fc" },
+
+ {"MID":"a5ab3ca7210f4c18a465e7686e71c15f","_LINK":"12-0-9-1-2025-06-14" },
+
+ {"MID":"fbf2c4dcf8154779b3ac914d9ff335c4","_LINK":"fbf2c4dcf8154779b3ac914d9ff335c4" },
+
+ {"MID":"71b0ec45b5644c5083085c83ef6be95e","_LINK":"13-0-9-0-2025-06-10" },
+
+ {"MID":"72d1a7e4b54d44e38778d87c74075dc8","_LINK":"72d1a7e4b54d44e38778d87c74075dc8" },
+
+ {"MID":"d64fb5003399496bbb18ffb6e05efaf4","_LINK":"14-0-8-0-2025-04-13" },
+
+ {"MID":"a7bd074d2dcd40a6af106e91720d90d3","_LINK":"a7bd074d2dcd40a6af106e91720d90d3" },
+
+ {"MID":"58b99c15df8445ce9832e24a17588e2c","_LINK":"15-0-7-0-2025-03-03" },
+
+ {"MID":"c5725f24fcd24d54929e155f6ad47b44","_LINK":"c5725f24fcd24d54929e155f6ad47b44" },
+
+ {"MID":"ff59e375101145b3bf12465ce2b5fc14","_LINK":"16-0-6-0-2025-02-16" },
+
+ {"MID":"3ddfc6462bec45b2ac69a1799293c7da","_LINK":"3ddfc6462bec45b2ac69a1799293c7da" },
+
+ {"MID":"d9e164994bb941ada8aecc73000bd51d","_LINK":"17-0-5-0-2025-01-06" },
+
+ {"MID":"d0d93f5eb37247079cc182e924dabd14","_LINK":"d0d93f5eb37247079cc182e924dabd14" },
+
+ {"MID":"e7df8274f42c4e01b02ad840e6b2569c","_LINK":"18-0-4-0-2024-12-25" },
+
+ {"MID":"f4e63483a11b442993c47b5d0574e89b","_LINK":"f4e63483a11b442993c47b5d0574e89b" },
+
+ {"MID":"591c1b85c6fb4453aee08e23cb9f257a","_LINK":"19-0-3-0-2024-11-21" },
+
+ {"MID":"b39a3b3d9f8640e380dad5a2fdb75d79","_LINK":"b39a3b3d9f8640e380dad5a2fdb75d79" },
+
+ {"MID":"f4cd860f07b1479ba1845bce3c749d68","_LINK":"20-0-2-1-2024-11-10" },
+
+ {"MID":"26043bba142a4e739dd206e229829202","_LINK":"26043bba142a4e739dd206e229829202" },
+
+ {"MID":"f76d863243b5410788e457b9c3bf1d2b","_LINK":"21-0-2-0-2024-11-04" },
+
+ {"MID":"611e8df13d464fd1b22e5026cf3ce531","_LINK":"611e8df13d464fd1b22e5026cf3ce531" },
+
+ {"MID":"83878b68483f4da2930bfb3712c08aa3","_LINK":"22-0-1-0-2024-11-01" },
+
+ {"MID":"e37e230c932448798bd9978d4f27f32c","_LINK":"e37e230c932448798bd9978d4f27f32c" },
+
+ {"MID":"771fb5350bf840e4b30485fe9e8d9452","_LINK":"23-0-0-60-2024-10-26" },
+
+ {"MID":"65daf4400b464021ba3cb7a06061e651","_LINK":"65daf4400b464021ba3cb7a06061e651" },
+
+ {"MID":"4538fe1994bc4730b7febe3dc624f704","_LINK":"24-0-0-59-2024-10-13" },
+
+ {"MID":"e9d5e3f8f6b04647afb95bae6b2f503a","_LINK":"e9d5e3f8f6b04647afb95bae6b2f503a" },
+
+ {"MID":"306a619f550f4be18db6dbb987df3248","_LINK":"25-0-0-58-2024-06-25" },
+
+ {"MID":"fd7f4d5b58e54f64aa43349684a675c4","_LINK":"fd7f4d5b58e54f64aa43349684a675c4" },
+
+ {"MID":"0795627e25e343f3b1b476b673a543ab","_LINK":"26-0-0-57-2024-06-23" },
+
+ {"MID":"f99185cb69cf47d4bc6e1bd404b67467","_LINK":"f99185cb69cf47d4bc6e1bd404b67467" },
+
+ {"MID":"cd994052a0354410a550858a1f25d426","_LINK":"27-0-0-56-2024-06-02" },
+
+ {"MID":"61f17be85ac442a0b70003825d671ced","_LINK":"61f17be85ac442a0b70003825d671ced" },
+
+ {"MID":"938f1a0fdcc94c5aaa87ddb18b880afe","_LINK":"28-0-0-55-2024-04-28" },
+
+ {"MID":"00abb07e55534a75a8cfd50d8cfc5732","_LINK":"00abb07e55534a75a8cfd50d8cfc5732" },
+
+ {"MID":"055ee004b28647629eead8165f198579","_LINK":"29-0-0-54-2024-04-17" },
+
+ {"MID":"e5bf489ac0684ea4b626574b5439c7dd","_LINK":"e5bf489ac0684ea4b626574b5439c7dd" },
+
+ {"MID":"87b7b54fa4024959bdcb42ded18f77f2","_LINK":"30-0-0-53-2024-04-01" },
+
+ {"MID":"2ac296f6326b4481beb7d67b95dbb23c","_LINK":"2ac296f6326b4481beb7d67b95dbb23c" },
+
+ {"MID":"36a70af62b3e4a5d8bf08d9345fda095","_LINK":"31-0-0-52-2024-03-25" },
+
+ {"MID":"72d6e38e89cc471b8d3f46ae5654e0e6","_LINK":"72d6e38e89cc471b8d3f46ae5654e0e6" },
+
+ {"MID":"6c72f8654ea1401ea2a6e4ab82cf76e4","_LINK":"32-0-0-51-2024-03-20" },
+
+ {"MID":"e81c4206bcb148979762ee3f2aa5c9ba","_LINK":"e81c4206bcb148979762ee3f2aa5c9ba" },
+
+ {"MID":"413952c14412434fb237c3e909101707","_LINK":"33-0-0-50-2024-03-19" },
+
+ {"MID":"a9d7c449d1a7400496504926c744e500","_LINK":"a9d7c449d1a7400496504926c744e500" },
+
+ {"MID":"3a03dd169ffb4fe0b64f48b365a77d2e","_LINK":"34-0-0-49-2024-03-11" },
+
+ {"MID":"0b8c8f40923744b089845afeb44223e9","_LINK":"0b8c8f40923744b089845afeb44223e9" },
+
+ {"MID":"a7ed1eaf155d4f588b27ba31ecc88d4d","_LINK":"35-0-0-48-2024-01-24" },
+
+ {"MID":"6cff333594d6430886053b59b265e806","_LINK":"6cff333594d6430886053b59b265e806" },
+
+ {"MID":"7a3620eecd1b4bd1a8eba7a373f14723","_LINK":"36-0-0-47-2023-11-20" },
+
+ {"MID":"c422af340d5b45c48bfe89130e1bba52","_LINK":"c422af340d5b45c48bfe89130e1bba52" }, ],
+ "strictdoc/docs/strictdoc_05_troubleshooting.html": [
+
+
+ {"MID":"5680165c90f44903b3b1dc1013b8cb59","UID":"SDOC_TROUBLESHOOTING","_LINK":"SDOC_TROUBLESHOOTING" },
+
+ {"MID":"7e3481d51ad14767b5c97132cad2e0a6","_LINK":"7e3481d51ad14767b5c97132cad2e0a6" },
+
+ {"MID":"17152ac7de9f4c138b85e2956091206f","_LINK":"1-Caching-issues" },
+
+ {"MID":"9a32ac13510d401cbc1a608259652c78","_LINK":"9a32ac13510d401cbc1a608259652c78" }, ],
+ "strictdoc/docs/strictdoc_10_contributing.html": [
+
+
+ {"MID":"1739e662499648d38c210a8aafbb3361","_LINK":"None-Contributing-to-StrictDoc" },
+
+ {"MID":"13fe652f160d4af69e869c28a155437d","_LINK":"13fe652f160d4af69e869c28a155437d" },
+
+ {"MID":"ec078ab0d7564738acd2961f72abb2c9","_LINK":"1-Contributor-checklist" },
+
+ {"MID":"ae0fc6d87b114137ab6da7c9b5647b62","_LINK":"ae0fc6d87b114137ab6da7c9b5647b62" },
+
+ {"MID":"8b40cc35f3524bc7b4e444321c080837","_LINK":"2-How-can-I-help" },
+
+ {"MID":"8e346888911649f2a3aaf49763aaef24","_LINK":"2.1-Spread-the-word" },
+
+ {"MID":"07462b02027a423a85ab68525b78ac67","_LINK":"07462b02027a423a85ab68525b78ac67" },
+
+ {"MID":"2696c7fda6d440f3a290f202bee08fe6","_LINK":"2.2-ReqIF-users" },
+
+ {"MID":"9cfbb025525f41c5a195be0e637dffee","_LINK":"9cfbb025525f41c5a195be0e637dffee" },
+
+ {"MID":"4e1edb97346c43af952c4e74f9defbe8","_LINK":"2.3-TeX-LaTeX-Sphinx-experts" },
+
+ {"MID":"75ed9362d86748269f62f5920514b7c2","_LINK":"75ed9362d86748269f62f5920514b7c2" }, ],
+ "strictdoc/docs/strictdoc_11_developer_guide.html": [
+
+
+ {"MID":"4f05169346ab4001b6ff19e8349e8fa7","_LINK":"None-Developer-Guide" },
+
+ {"MID":"f174b0cdec6b482daa2878c8cc0d02c3","_LINK":"f174b0cdec6b482daa2878c8cc0d02c3" },
+
+ {"MID":"c069e4c7b4d04dd09eb73f940e947bfd","UID":"DEVGUIDE_GETTING_STARTED","_LINK":"DEVGUIDE_GETTING_STARTED" },
+
+ {"MID":"7477d397d0ca493f8e47532455d44965","_LINK":"1.1-System-dependencies" },
+
+ {"MID":"df2e1de12c6b456898c48a36650813d4","_LINK":"df2e1de12c6b456898c48a36650813d4" },
+
+ {"MID":"b7a21564c30043acbf1733d9b47bd0bc","_LINK":"1.1.1-Windows-specific-Long-Path-support" },
+
+ {"MID":"8591cf6dece04244824c3ac2a8666ba3","_LINK":"8591cf6dece04244824c3ac2a8666ba3" },
+
+ {"MID":"89ec30b9f67c489da635be391b0b0e15","_LINK":"1.2-Installing-StrictDoc-from-GitHub-developer-mode" },
+
+ {"MID":"2407bb186b274a58b97b54b99ba6e86f","_LINK":"2407bb186b274a58b97b54b99ba6e86f" },
+
+ {"MID":"1814a8c25afc40cba6dca1696cae119b","_LINK":"1.2.1-Development-within-a-virtual-environment" },
+
+ {"MID":"a3e14b05452b48e2a0d8726fa00a7f00","_LINK":"a3e14b05452b48e2a0d8726fa00a7f00" },
+
+ {"MID":"90d5d79146e64660a71cd74ac23f6811","_LINK":"2-Invoke-for-development-tasks" },
+
+ {"MID":"452b3c24463446a497ed6b8fcdb31fef","_LINK":"452b3c24463446a497ed6b8fcdb31fef" },
+
+ {"MID":"e7ce6a2f13614974b43aba56f6ae7253","_LINK":"3-Main-Check-task" },
+
+ {"MID":"09258e99cabb4455904b0e2c6687d492","_LINK":"09258e99cabb4455904b0e2c6687d492" },
+
+ {"MID":"07d9a3c17be8475089844f5eb2cd8299","UID":"DEVGUIDE_PYTHON_CODE","_LINK":"DEVGUIDE_PYTHON_CODE" },
+
+ {"MID":"3012a69ef5d244d49fcb90c088d4523b","_LINK":"3012a69ef5d244d49fcb90c088d4523b" },
+
+ {"MID":"6e9707c99199464583f091056d1ae458","UID":"DEVGUIDE_GIT_WORKFLOW","_LINK":"DEVGUIDE_GIT_WORKFLOW" },
+
+ {"MID":"0e916453596b460b84a89f722354a825","_LINK":"0e916453596b460b84a89f722354a825" },
+
+ {"MID":"2420b2d7a4624bd99b0f8088dfa9abff","_LINK":"6-Frontend-development" },
+
+ {"MID":"d818aad87db54985b8933f98528808ab","_LINK":"d818aad87db54985b8933f98528808ab" },
+
+ {"MID":"73c717608cce4abca2c768f1dbfb705d","_LINK":"7-Running-End-to-End-Web-tests" },
+
+ {"MID":"da3cbcd69b0545988daeb0f42098830d","_LINK":"da3cbcd69b0545988daeb0f42098830d" },
+
+ {"MID":"240dc1426d994397ac1401834b4f0ef0","_LINK":"8-Running-integration-tests" },
+
+ {"MID":"4e307b3b950840bbbe455c1ae3238a6e","_LINK":"4e307b3b950840bbbe455c1ae3238a6e" },
+
+ {"MID":"7b4bf839b1c44b0d82001060596d8cbf","_LINK":"9-Documentation" },
+
+ {"MID":"d1f5fde86ebc4103bc4eb0334b1ec919","_LINK":"d1f5fde86ebc4103bc4eb0334b1ec919" },
+
+ {"MID":"a44e3b99323b4ac291f4b4d3948c3cc0","_LINK":"10-Conventions" },
+
+ {"MID":"49b7349a3bee478cbe81d8ef25f6245c","_LINK":"49b7349a3bee478cbe81d8ef25f6245c" }, ],
+ "strictdoc/docs/strictdoc_20_L1_Open_Requirements_Tool.html": [
+
+
+ {"MID":"b7bcca934cd148c3855beb4c85723bc5","_LINK":"None-Requirements-Tool-Specification-L1" },
+
+ {"MID":"c455f0297eb648c6aa9c6d239f043e0d","_LINK":"c455f0297eb648c6aa9c6d239f043e0d" },
+
+ {"MID":"668d18a7489043b38dd435933319e8e7","_LINK":"1-Summary-of-user-needs" },
+
+ {"MID":"7a94c3f55e32498187603400923bfae4","_LINK":"7a94c3f55e32498187603400923bfae4" },
+
+ {"MID":"1cbe275272994922a942fd088fa969d8","_LINK":"1.1-Free-and-open-source-tool" },
+
+ {"MID":"3ca29d12a7804f089f5b2aa955e4da59","_LINK":"3ca29d12a7804f089f5b2aa955e4da59" },
+
+ {"MID":"18136bcb9a5b4226a7a95d27dae49805","_LINK":"1.2-Document-types" },
+
+ {"MID":"14383453f84747d3abdce6b5dce50c7f","_LINK":"14383453f84747d3abdce6b5dce50c7f" },
+
+ {"MID":"973b586b8a89411ab4f083fd4c262cf5","UID":"SECTION-RTC-Appendix-A-Document-archetypes","_LINK":"SECTION-RTC-Appendix-A-Document-archetypes" },
+
+ {"MID":"4a847b9a58444e4a9be056db1f23272c","_LINK":"4a847b9a58444e4a9be056db1f23272c" },
+
+ {"MID":"52b6175f03d7495a9fa8dbffa36aeff4","UID":"SECTION-LRTS-Workflows","_LINK":"SECTION-LRTS-Workflows" },
+
+ {"MID":"c537b8fa5b54417eb9dff6478553f6d7","_LINK":"c537b8fa5b54417eb9dff6478553f6d7" },
+
+ {"MID":"08d547a3b04d485ca1f5a3a94a664ee1","_LINK":"1.4-Target-audience" },
+
+ {"MID":"847eaab505124e7797bd25c865f9d868","_LINK":"847eaab505124e7797bd25c865f9d868" },
+
+ {"MID":"f1ffdc7f78134d4b98f3c90e9be40cc7","UID":"SECTION-RTS-Documentation-management","_LINK":"SECTION-RTS-Documentation-management" },
+
+ {"MID":"0cacb010f5164118adce5dd8512c3e27","_LINK":"0cacb010f5164118adce5dd8512c3e27" },
+
+ {"MID":"72d0dd23dedd4907b4a8924debe7343b","UID":"SDOC-SSS-3","_LINK":"SDOC-SSS-3" },
+
+ {"MID":"9841bc9a56d740dd9e7988e52339618c","UID":"SDOC-SSS-91","_LINK":"SDOC-SSS-91" },
+
+ {"MID":"c4de5f1f46f343b6b4e8dc2a6121b0a2","UID":"SDOC-SSS-51","_LINK":"SDOC-SSS-51" },
+
+ {"MID":"5236f36f278140539e347bacea921118","UID":"SDOC-SSS-52","_LINK":"SDOC-SSS-52" },
+
+ {"MID":"8aeecdfa139341588d6ab8c0c3606a9b","UID":"SDOC-SSS-53","_LINK":"SDOC-SSS-53" },
+
+ {"MID":"d1883b65e17442c0a22987d4ad415cb6","UID":"SDOC-SSS-75","_LINK":"SDOC-SSS-75" },
+
+ {"MID":"b8d7b22fd8a6478a9a21ecaa60cf0028","UID":"SDOC-SSS-63","_LINK":"SDOC-SSS-63" },
+
+ {"MID":"3bb5252d75bc486b98e7606fb642bac0","UID":"SDOC-SSS-95","_LINK":"SDOC-SSS-95" },
+
+ {"MID":"fd227b9cfdc54d7db3134cdb925bde87","UID":"SECTION-RTS-Requirements-management","_LINK":"SECTION-RTS-Requirements-management" },
+
+ {"MID":"c1e2431cdf2141ca86931f29b9912ff7","_LINK":"c1e2431cdf2141ca86931f29b9912ff7" },
+
+ {"MID":"6e6f1464c47f4ced8e14c4153f40618b","UID":"SDOC-SSS-4","_LINK":"SDOC-SSS-4" },
+
+ {"MID":"db42ad4b504e48e0bf51b4d82529a888","UID":"SDOC-SSS-61","_LINK":"SDOC-SSS-61" },
+
+ {"MID":"a69bae43b3224dfc8439a88451a98395","UID":"SDOC-SSS-62","_LINK":"SDOC-SSS-62" },
+
+ {"MID":"5f89bdaa6cb74e2a8b9b030b6237b7ef","UID":"SDOC-SSS-64","_LINK":"SDOC-SSS-64" },
+
+ {"MID":"65575cc8a87e4d4480ccdf89d1fb6d67","UID":"SDOC-SSS-5","_LINK":"SDOC-SSS-5" },
+
+ {"MID":"06ab121d3c0f4d8c94652323b8f735c6","UID":"SDOC-SSS-70","_LINK":"SDOC-SSS-70" },
+
+ {"MID":"637c129a91804d8cbe2280c1af14836d","UID":"SDOC-SSS-6","_LINK":"SDOC-SSS-6" },
+
+ {"MID":"1ce495a5194044d4a7a3dd030f766c9f","UID":"SDOC-SSS-7","_LINK":"SDOC-SSS-7" },
+
+ {"MID":"44b9d75e50c84d6c8424cfb8a42a0771","UID":"SDOC-SSS-8","_LINK":"SDOC-SSS-8" },
+
+ {"MID":"387bd5ff0e4a4a97962661e9d7451f19","UID":"SDOC-SSS-71","_LINK":"SDOC-SSS-71" },
+
+ {"MID":"3348caaed8d44be0928cc6f3c7414094","UID":"SDOC-SSS-89","_LINK":"SDOC-SSS-89" },
+
+ {"MID":"3850f0b8c8294455bf7be9e2acddbd40","UID":"SDOC-SSS-47","_LINK":"SDOC-SSS-47" },
+
+ {"MID":"1216cb617c0f495a9c96471ef72bf80f","UID":"SDOC-SSS-57","_LINK":"SDOC-SSS-57" },
+
+ {"MID":"7c112f3a5885477084396fd26387a864","_LINK":"4-Tool-configurability" },
+
+ {"MID":"4550038552894ef69b85b281cff60c60","UID":"SDOC-SSS-92","_LINK":"SDOC-SSS-92" },
+
+ {"MID":"4550b38552894ef69b85b281cff60360","UID":"SDOC-SSS-93","_LINK":"SDOC-SSS-93" },
+
+ {"MID":"56dabce670be4691b35434bda6d6bb36","UID":"SECTION-SSSS-Performance","_LINK":"SECTION-SSSS-Performance" },
+
+ {"MID":"68e4b4b1ba78485f8620575ef9e1eaa2","_LINK":"68e4b4b1ba78485f8620575ef9e1eaa2" },
+
+ {"MID":"a0a95079e3c0438bb3ea9e5af7ddddc9","UID":"SDOC-SSS-13","_LINK":"SDOC-SSS-13" },
+
+ {"MID":"64b982c9299a4c8eb7031495e940a3f8","UID":"SDOC-SSS-14","_LINK":"SDOC-SSS-14" },
+
+ {"MID":"d1a483f3e321414b83bb4a39b1283293","_LINK":"6-Data-integrity" },
+
+ {"MID":"d1323d222a0040b2b6122c59b3c00f06","UID":"SDOC-SSS-94","_LINK":"SDOC-SSS-94" },
+
+ {"MID":"ec52fa5cc1714b07863eb7da9432be1d","UID":"SECTION-SSSS-Existing-workflows","_LINK":"SECTION-SSSS-Existing-workflows" },
+
+ {"MID":"33769a5f0ca94b99a4802adc81841037","_LINK":"33769a5f0ca94b99a4802adc81841037" },
+
+ {"MID":"831debedfa0e4e4c8434021569f96bad","UID":"SDOC-SSS-73","_LINK":"SDOC-SSS-73" },
+
+ {"MID":"5d412989005e4bc3b5dcfd94675615dc","UID":"SDOC-SSS-56","_LINK":"SDOC-SSS-56" },
+
+ {"MID":"5eb553abd3944bffbd003e37b3d1c5a5","UID":"SDOC-SSS-28","_LINK":"SDOC-SSS-28" },
+
+ {"MID":"06f0bb40f76142f4ba59d037aaedc9de","UID":"SDOC-SSS-48","_LINK":"SDOC-SSS-48" },
+
+ {"MID":"74ffae6279bc4e4095c03d6a247c3599","UID":"SDOC-SSS-29","_LINK":"SDOC-SSS-29" },
+
+ {"MID":"e0e6d1f883764719919238e4974dccef","UID":"SDOC-SSS-49","_LINK":"SDOC-SSS-49" },
+
+ {"MID":"ed4bd232bed84eda977263fa03e75b80","UID":"SDOC-SSS-74","_LINK":"SDOC-SSS-74" },
+
+ {"MID":"85d2f75b2f074f98ace5ceb5288c09b9","UID":"SECTION-RTC-Usability-installation-and-usage","_LINK":"SECTION-RTC-Usability-installation-and-usage" },
+
+ {"MID":"7e33387f373d427d9e1af522f1e5bbc5","UID":"SDOC-SSS-79","_LINK":"SDOC-SSS-79" },
+
+ {"MID":"57b01915e4624634909dbb40f5d56697","UID":"SDOC-SSS-80","_LINK":"SDOC-SSS-80" },
+
+ {"MID":"d3e66072363d4e7ea2e2f9691c094bb2","UID":"SDOC-SSS-81","_LINK":"SDOC-SSS-81" },
+
+ {"MID":"db495bc2f11f4f96ace60cdb0bef4d66","UID":"SDOC-SSS-82","_LINK":"SDOC-SSS-82" },
+
+ {"MID":"90562d92b9a7468ba42567bc72cb6ebf","UID":"SDOC-SSS-83","_LINK":"SDOC-SSS-83" },
+
+ {"MID":"4312ed066d19487eba18ec677430e60f","UID":"SDOC-SSS-84","_LINK":"SDOC-SSS-84" },
+
+ {"MID":"81858dda65844dcd9640fdd74badecee","UID":"SDOC-SSS-85","_LINK":"SDOC-SSS-85" },
+
+ {"MID":"ee96cc5f18e14f6894e2775c546240d8","UID":"SDOC-SSS-86","_LINK":"SDOC-SSS-86" },
+
+ {"MID":"f4b122c5081f4b218aa93a119e372a34","UID":"SDOC-SSS-87","_LINK":"SDOC-SSS-87" },
+
+ {"MID":"29fa83c59e714d0da8b36a9dc65b0c72","UID":"SECTION-SSSS-Implementation-suggestions","_LINK":"SECTION-SSSS-Implementation-suggestions" },
+
+ {"MID":"3db06eb066b4441290e06b08405da0a9","UID":"SDOC-SSS-30","_LINK":"SDOC-SSS-30" },
+
+ {"MID":"e718af582b0345c2b0ddb6e405cb6d9a","UID":"SDOC-SSS-31","_LINK":"SDOC-SSS-31" },
+
+ {"MID":"cd20e9613a65441a8862143ba6407f61","UID":"SDOC-SSS-32","_LINK":"SDOC-SSS-32" },
+
+ {"MID":"4475857729e5476cbbb409cc844048fd","UID":"SDOC-SSS-68","_LINK":"SDOC-SSS-68" },
+
+ {"MID":"5ac2f3010db84466bff854fc323e944c","UID":"SDOC-SSS-33","_LINK":"SDOC-SSS-33" },
+
+ {"MID":"b76fb774542849a182e2cdd89fdaab3c","UID":"SDOC-SSS-67","_LINK":"SDOC-SSS-67" },
+
+ {"MID":"871a7a66eb50436997fde692e90e93eb","UID":"SDOC-SSS-69","_LINK":"SDOC-SSS-69" },
+
+ {"MID":"0556a0b2773d4ee0b44b22773455a600","UID":"SDOC-SSS-90","_LINK":"SDOC-SSS-90" },
+
+ {"MID":"7bdea1a7cb9e4f6fbcf8497670f87278","UID":"SECTION-RTS-Text-based-requirements-language","_LINK":"SECTION-RTS-Text-based-requirements-language" },
+
+ {"MID":"dfe5a61ed10149bebcf69d9c5c3b1316","_LINK":"dfe5a61ed10149bebcf69d9c5c3b1316" },
+
+ {"MID":"f472e85f3398413795234a9298d4af3c","UID":"SDOC-SSS-88","_LINK":"SDOC-SSS-88" },
+
+ {"MID":"b13bc3dfa7324f238bc06a88baf5edb6","UID":"SDOC-SSS-55","_LINK":"SDOC-SSS-55" },
+
+ {"MID":"0b47da74f9ec45e6a77573185b95f327","UID":"SDOC-SSS-54","_LINK":"SDOC-SSS-54" },
+
+ {"MID":"13f3e7765b494237893c1585a7c9dfd0","UID":"SDOC-SSS-34","_LINK":"SDOC-SSS-34" },
+
+ {"MID":"8b1da9907bc847c989dc807b7dff2a05","UID":"SECTION-RTS-Requirements-and-source-code","_LINK":"SECTION-RTS-Requirements-and-source-code" },
+
+ {"MID":"4692362c77974fb8bcbeefdc248d0e89","UID":"SDOC-SSS-72","_LINK":"SDOC-SSS-72" },
+
+ {"MID":"cd9e353e07ae4d50b1aa08999854aa02","UID":"SECTION-RTS-Requirements-exchange-formats-export-import","_LINK":"SECTION-RTS-Requirements-exchange-formats-export-import" },
+
+ {"MID":"ecc76e0991e44d6282776365496193e6","_LINK":"ecc76e0991e44d6282776365496193e6" },
+
+ {"MID":"73e70548c2cf415f94adbf1066d5fe4b","UID":"SDOC-SSS-58","_LINK":"SDOC-SSS-58" },
+
+ {"MID":"c94de32c2c2e454d81c77724a4f29283","UID":"SDOC-SSS-59","_LINK":"SDOC-SSS-59" },
+
+ {"MID":"f7a600a238e34075ac6b65852492cc2f","UID":"SDOC-SSS-60","_LINK":"SDOC-SSS-60" },
+
+ {"MID":"efaa3e91045c4d49a70232f09a85ad35","UID":"SECTION-RTS-Requirements-collaboration","_LINK":"SECTION-RTS-Requirements-collaboration" },
+
+ {"MID":"f9d65df46ff24b0da6cb2bf011f0fc70","UID":"SDOC-SSS-65","_LINK":"SDOC-SSS-65" },
+
+ {"MID":"29d0374556494f38977ec3c928aa894d","UID":"SDOC-SSS-66","_LINK":"SDOC-SSS-66" },
+
+ {"MID":"f80a4b7ff03042849c3814c6cd5e5ca4","UID":"SECTION-SSSS-Development-process","_LINK":"SECTION-SSSS-Development-process" },
+
+ {"MID":"f16ea50f686e412f9c21d8096055bb47","UID":"SDOC-SSS-76","_LINK":"SDOC-SSS-76" },
+
+ {"MID":"0bebdf77108a499c87e5c0838204c39c","UID":"SDOC-SSS-50","_LINK":"SDOC-SSS-50" },
+
+ {"MID":"1a39a758930040029db320d8466806c1","UID":"SDOC-SSS-77","_LINK":"SDOC-SSS-77" },
+
+ {"MID":"8cb5ac6812924f4c8f4afd156b2f021c","UID":"SDOC-SSS-78","_LINK":"SDOC-SSS-78" },
+
+ {"MID":"e4cd429e9ec04deabfd1fb1381c39e38","UID":"SECTION-SSSS-Licensing-and-distribution","_LINK":"SECTION-SSSS-Licensing-and-distribution" },
+
+ {"MID":"92bf658bcddb4d2899b78c526fbddf38","_LINK":"92bf658bcddb4d2899b78c526fbddf38" },
+
+ {"MID":"2f30b94fdc074c8fa5858dfccc6202e8","UID":"SDOC-SSS-38","_LINK":"SDOC-SSS-38" },
+
+ {"MID":"27b640de8cae44a680b23429c981bee9","UID":"SDOC-SSS-39","_LINK":"SDOC-SSS-39" },
+
+ {"MID":"1338faad11204073a97212fa0fd11317","UID":"SDOC-SSS-40","_LINK":"SDOC-SSS-40" }, ],
+ "strictdoc/docs/strictdoc_21_L2_StrictDoc_Requirements.html": [
+
+
+ {"MID":"8a87daf19a7c487f89f396406a974509","_LINK":"None-StrictDoc-Requirements-Specification-L2" },
+
+ {"MID":"bd8a7931c1e04df9bf08d291488c67aa","_LINK":"1-SDoc-data-model" },
+
+ {"MID":"e8d5b55055254144b96d1ffeb587ec72","UID":"SDOC-SRS-18","_LINK":"SDOC-SRS-18" },
+
+ {"MID":"3b31cad22529476db01aca41caf39750","UID":"SDOC-SRS-26","_LINK":"SDOC-SRS-26" },
+
+ {"MID":"8e2ffffd33af4a969d5bb7ca40cb49a4","UID":"SDOC-SRS-100","_LINK":"SDOC-SRS-100" },
+
+ {"MID":"2d4020ba06d74571aef7aafe8604215b","UID":"SDOC-SRS-132","_LINK":"SDOC-SRS-132" },
+
+ {"MID":"f94419a390f2403daa3c4cd0e96f6cb6","UID":"SDOC-SRS-98","_LINK":"SDOC-SRS-98" },
+
+ {"MID":"435f856197d743c1b9b1dcbe91a22863","UID":"SDOC-SRS-110","_LINK":"SDOC-SRS-110" },
+
+ {"MID":"abcced8724d743c1b9b1dcbe91a22863","UID":"SDOC-SRS-151","_LINK":"SDOC-SRS-151" },
+
+ {"MID":"63821c507d584cf985f05904710b9779","UID":"SDOC-SRS-99","_LINK":"SDOC-SRS-99" },
+
+ {"MID":"899d2f68749b4be1a3124fe4d01de1aa","UID":"SDOC-SRS-135","_LINK":"SDOC-SRS-135" },
+
+ {"MID":"983653fc26214f46977dc792d65ae65f","UID":"SDOC-SRS-109","_LINK":"SDOC-SRS-109" },
+
+ {"MID":"fad4cf5dcf4d40518c7c9826fd6bd18a","UID":"SDOC-SRS-31","_LINK":"SDOC-SRS-31" },
+
+ {"MID":"9930894b08c44f5eba996c0a255e9e3f","UID":"SDOC-SRS-101","_LINK":"SDOC-SRS-101" },
+
+ {"MID":"fa090bc6976c4275aadbf522da6b920b","UID":"SDOC-SRS-149","_LINK":"SDOC-SRS-149" },
+
+ {"MID":"54132bc6976c4275aadbf522da6b920b","UID":"SDOC-SRS-150","_LINK":"SDOC-SRS-150" },
+
+ {"MID":"cbc7f72c6e0b4c858817bf17357105a5","_LINK":"2-SDoc-text-markup" },
+
+ {"MID":"27a6da48c65445539e536ee034921fb5","UID":"SDOC-SRS-20","_LINK":"SDOC-SRS-20" },
+
+ {"MID":"1f147feed60245378de2e099facd196d","UID":"SDOC-SRS-136","_LINK":"SDOC-SRS-136" },
+
+ {"MID":"f48a57c0cd764951a667127ce92fdb12","UID":"SDOC-SRS-127","_LINK":"SDOC-SRS-127" },
+
+ {"MID":"9df34a7ab79842d99ee68303f334d4eb","UID":"SDOC-SRS-104","_LINK":"SDOC-SRS-104" },
+
+ {"MID":"8dd6dd3979484dadbe71ac91aab50608","UID":"SDOC-SRS-105","_LINK":"SDOC-SRS-105" },
+
+ {"MID":"e5e3033c13f24fa083423230da7994f7","UID":"SDOC-SRS-19","_LINK":"SDOC-SRS-19" },
+
+ {"MID":"b97418ceccff438cb0457ed4bdf1be47","UID":"SDOC-SRS-93","_LINK":"SDOC-SRS-93" },
+
+ {"MID":"8924c29136944f65ac5efc8b6b90a07b","UID":"SDOC-SRS-21","_LINK":"SDOC-SRS-21" },
+
+ {"MID":"10d23bfbf4504c2e8c995ae89c500be4","UID":"SDOC-SRS-122","_LINK":"SDOC-SRS-122" },
+
+ {"MID":"5405c74a9eba4e9193007f01ea98bc85","UID":"SDOC-SRS-22","_LINK":"SDOC-SRS-22" },
+
+ {"MID":"f871dfc381354daf820cc1e2b94fdb05","UID":"SDOC-SRS-24","_LINK":"SDOC-SRS-24" },
+
+ {"MID":"b1b4f03d4e404a14be481626803fcfc2","UID":"SDOC-SRS-27","_LINK":"SDOC-SRS-27" },
+
+ {"MID":"39f117b79cfa4a8485c458280b3d36ce","UID":"SDOC-SRS-23","_LINK":"SDOC-SRS-23" },
+
+ {"MID":"98628e1db3ca4f52b7632674b69dd657","UID":"SDOC-SRS-25","_LINK":"SDOC-SRS-25" },
+
+ {"MID":"34b4abc6bb4649de9e56af31c229b0d1","UID":"SECTION-SRS-Graph-database","_LINK":"SECTION-SRS-Graph-database" },
+
+ {"MID":"2c8d7940a23c443f81a7eb373340894e","UID":"SDOC-SRS-28","_LINK":"SDOC-SRS-28" },
+
+ {"MID":"272b8933276d4cd48a78fcfa11899573","UID":"SDOC-SRS-29","_LINK":"SDOC-SRS-29" },
+
+ {"MID":"8330d61fd5b1438fa90f127f88903a0d","UID":"SDOC-SRS-30","_LINK":"SDOC-SRS-30" },
+
+ {"MID":"07a1e7bef11d4fcca86cd31ee5245d8d","UID":"SDOC-SRS-32","_LINK":"SDOC-SRS-32" },
+
+ {"MID":"2dad5f293bc442eaa98859c4b5eac0d5","UID":"SDOC-SRS-102","_LINK":"SDOC-SRS-102" },
+
+ {"MID":"4dce611287954289b1c2a6a15c413611","_LINK":"4-Documentation-tree" },
+
+ {"MID":"50b2d5d6eb1140f0a2b980203468a5f7","UID":"SDOC-SRS-115","_LINK":"SDOC-SRS-115" },
+
+ {"MID":"fcbf717009ce4cb2a8def7eb7b377654","UID":"SECTION-SRS-Web-HTML-frontend","_LINK":"SECTION-SRS-Web-HTML-frontend" },
+
+ {"MID":"a3603184d571449792f5cd752c978686","UID":"SECTION-SRS-General-export-requirements-2","_LINK":"SECTION-SRS-General-export-requirements-2" },
+
+ {"MID":"37f17fdd57ff47e9b7f4147adaeabde1","UID":"SDOC-SRS-49","_LINK":"SDOC-SRS-49" },
+
+ {"MID":"37399be2a8ac46889e3437209f9dffa9","UID":"SDOC-SRS-50","_LINK":"SDOC-SRS-50" },
+
+ {"MID":"f2fd90ad8a2946e7b085233a9c7a8a75","UID":"SDOC-SRS-51","_LINK":"SDOC-SRS-51" },
+
+ {"MID":"8811f0ef33de4365bc66a602a8c184f6","UID":"SDOC-SRS-48","_LINK":"SDOC-SRS-48" },
+
+ {"MID":"b99ebebdadb94fec968785429cef9002","UID":"SECTION-SRS-Screen-Project-tree","_LINK":"SECTION-SRS-Screen-Project-tree" },
+
+ {"MID":"100fa410f4b443e69c48738899cfb5bd","UID":"SDOC-SRS-53","_LINK":"SDOC-SRS-53" },
+
+ {"MID":"eb04abcfd64146f3b7be509afd1693f9","UID":"SDOC-SRS-107","_LINK":"SDOC-SRS-107" },
+
+ {"MID":"de7cda1156e043d7999933a2df630a30","UID":"SDOC-SRS-108","_LINK":"SDOC-SRS-108" },
+
+ {"MID":"185cfc2d1ed4429ebaf0689f70a8cb0a","UID":"SECTION-SRS-Screen-Document-DOC","_LINK":"SECTION-SRS-Screen-Document-DOC" },
+
+ {"MID":"9c962637ef7f45b6af6c83964b0a06d9","UID":"SDOC-SRS-54","_LINK":"SDOC-SRS-54" },
+
+ {"MID":"201187122be14ea48d69106d396c6790","UID":"SDOC-SRS-106","_LINK":"SDOC-SRS-106" },
+
+ {"MID":"13968ae160744e10ba8979eaee2f4f54","UID":"SDOC-SRS-55","_LINK":"SDOC-SRS-55" },
+
+ {"MID":"edc02a3a97704007b70b93102c76b278","UID":"SDOC-SRS-92","_LINK":"SDOC-SRS-92" },
+
+ {"MID":"197e00dd3b1d42309250c89de23ea51b","UID":"SDOC-SRS-56","_LINK":"SDOC-SRS-56" },
+
+ {"MID":"2706ac7ccb8148edb7b200a1b78c25d6","UID":"SDOC-SRS-57","_LINK":"SDOC-SRS-57" },
+
+ {"MID":"d64f7a0f6ba54672a62634304c54e2d4","UID":"SDOC-SRS-96","_LINK":"SDOC-SRS-96" },
+
+ {"MID":"956371b6a7824d0b91caa5603faeeae2","UID":"SDOC-SRS-120","_LINK":"SDOC-SRS-120" },
+
+ {"MID":"738b63b7f55b43eb99f5600bd65f5ba7","UID":"SDOC-SRS-59","_LINK":"SDOC-SRS-59" },
+
+ {"MID":"2b5d74dafd6d43f4bab4c05ed4da6f0d","UID":"SECTION-SRS-Screen-Table-TBL","_LINK":"SECTION-SRS-Screen-Table-TBL" },
+
+ {"MID":"e12b4c5b4f13444d99279ab445df5bcc","UID":"SDOC-SRS-62","_LINK":"SDOC-SRS-62" },
+
+ {"MID":"3c589969eb6a41c19b1dd246dabadbc8","UID":"SECTION-SRS-Screen-Traceability-TR","_LINK":"SECTION-SRS-Screen-Traceability-TR" },
+
+ {"MID":"35d4c1dd30814c2a80918a90081a88b7","UID":"SDOC-SRS-65","_LINK":"SDOC-SRS-65" },
+
+ {"MID":"9d337068b6a940b7a98d40697ea200a8","UID":"SECTION-SRS-Screen-Deep-traceability-DTR","_LINK":"SECTION-SRS-Screen-Deep-traceability-DTR" },
+
+ {"MID":"48bc17d898c94605b17d0267480f57ee","UID":"SDOC-SRS-66","_LINK":"SDOC-SRS-66" },
+
+ {"MID":"ddf15b3113a54107979752ec192e2ded","_LINK":"5.7-Screen-Project-statistics" },
+
+ {"MID":"19f7c2d35237423e950584a4a7aa95a7","UID":"SDOC-SRS-97","_LINK":"SDOC-SRS-97" },
+
+ {"MID":"7968fb7612f64504b5a430ccbffe80f1","UID":"SDOC-SRS-154","_LINK":"SDOC-SRS-154" },
+
+ {"MID":"d84e3a79b3e443cabe96d7c18ea5d322","_LINK":"5.8-Screen-Document-tree-map" },
+
+ {"MID":"1520fa85ed7a4f1aa80c49ed858f402f","UID":"SDOC-SRS-157","_LINK":"SDOC-SRS-157" },
+
+ {"MID":"14ad600308434e6baaeef02d3e90b720","_LINK":"5.9-Screen-Traceability-matrix" },
+
+ {"MID":"167f6fe66d7247a6bf628ed6c1949275","UID":"SDOC-SRS-112","_LINK":"SDOC-SRS-112" },
+
+ {"MID":"544f8ffed8604e63a269a3f953681163","_LINK":"5.10-Screen-Project-tree-diff" },
+
+ {"MID":"aef80cc1a3144564bf23bf3c2a1cfd7f","UID":"SDOC-SRS-111","_LINK":"SDOC-SRS-111" },
+
+ {"MID":"8380fb39beb04d1c9370733bcfafbc01","_LINK":"5.11-Content-search" },
+
+ {"MID":"3e85dd6bf05a4cecb8e070fd81aa333a","UID":"SDOC-SRS-155","_LINK":"SDOC-SRS-155" },
+
+ {"MID":"2d4dc6fc901f4b28aaf414fcfbdfabca","UID":"SECTION-SRS-Requirements-to-source-traceability","_LINK":"SECTION-SRS-Requirements-to-source-traceability" },
+
+ {"MID":"221b544dab2e4b96be124e1caf84a7c2","UID":"SDOC-SRS-33","_LINK":"SDOC-SRS-33" },
+
+ {"MID":"2f63252320d546d88462849b521f45ba","_LINK":"6.2-Language-aware-parsing-of-source-code" },
+
+ {"MID":"79a8080f6e41485f9835ccda067b34bc","UID":"SDOC-SRS-142","_LINK":"SDOC-SRS-142" },
+
+ {"MID":"85a8080f8441485f9111ccda063b34bc","UID":"SDOC-SRS-146","_LINK":"SDOC-SRS-146" },
+
+ {"MID":"3456080f1358485f9bacdcda063b34bc","UID":"SDOC-SRS-147","_LINK":"SDOC-SRS-147" },
+
+ {"MID":"9183080f1358485f9bacdcda0635109","UID":"SDOC-SRS-148","_LINK":"SDOC-SRS-148" },
+
+ {"MID":"bdeda4b89d82446281e2c7c2eae46708","UID":"SDOC-SRS-143","_LINK":"SDOC-SRS-143" },
+
+ {"MID":"aefeb5b89d82446281e2c7c2eae12345","UID":"SDOC-SRS-144","_LINK":"SDOC-SRS-144" },
+
+ {"MID":"5fedbaba39d24da79d074501198ff654","_LINK":"6.5-Forward-linking-from-requirements-to-source-code" },
+
+ {"MID":"21637d9bec434d32bb6b97ba5a4e70e6","UID":"SDOC-SRS-145","_LINK":"SDOC-SRS-145" },
+
+ {"MID":"9c1dd6cbabd44ac680985c403cf710a7","_LINK":"6.6-Source-code-markup-Relations" },
+
+ {"MID":"b9144222a7f3454da2989f494cd9647c","UID":"SDOC-SRS-34","_LINK":"SDOC-SRS-34" },
+
+ {"MID":"61c25cab106e4283b2c6d64bf1db96b2","UID":"SDOC-SRS-124","_LINK":"SDOC-SRS-124" },
+
+ {"MID":"61c23c1b106e4583b2c6d64bf1d296ba","UID":"SDOC-SRS-137","_LINK":"SDOC-SRS-137" },
+
+ {"MID":"86e23c1b106e4adeb2c6d64bf1d29aaa","UID":"SDOC-SRS-140","_LINK":"SDOC-SRS-140" },
+
+ {"MID":"82345cab106e4283b2c7774bf1db96b1","UID":"SDOC-SRS-139","_LINK":"SDOC-SRS-139" },
+
+ {"MID":"11c23c1b105e4583b2c6d64bf1d296cc","UID":"SDOC-SRS-138","_LINK":"SDOC-SRS-138" },
+
+ {"MID":"5ce2ea410dd94927807a258f482483a5","_LINK":"6.7-Source-code-markup-Nodes" },
+
+ {"MID":"f44df3c6a84f4b4e9201a61023446d9c","UID":"SDOC-SRS-141","_LINK":"SDOC-SRS-141" },
+
+ {"MID":"3aeb1eea0dba4041a9161a1a8d291999","UID":"SDOC-SRS-35","_LINK":"SDOC-SRS-35" },
+
+ {"MID":"56ecfb19152e45b09c0e55de2d1d5f05","UID":"SDOC-SRS-36","_LINK":"SDOC-SRS-36" },
+
+ {"MID":"1acdd6ddf9d24dbaa320230402152226","UID":"SECTION-SRS-Export-import-formats","_LINK":"SECTION-SRS-Export-import-formats" },
+
+ {"MID":"ce1d174a4d794250931a5ba519583be6","UID":"SECTION-SRS-RST","_LINK":"SECTION-SRS-RST" },
+
+ {"MID":"2aa615b9cf264e7aad826f4ff466e514","UID":"SDOC-SRS-70","_LINK":"SDOC-SRS-70" },
+
+ {"MID":"6faffbd1d4cc47ea88c08ef38966e5ec","UID":"SDOC-SRS-71","_LINK":"SDOC-SRS-71" },
+
+ {"MID":"a906dfb776334b8985f778f0fe1b79e4","UID":"SECTION-SRS-ReqIF","_LINK":"SECTION-SRS-ReqIF" },
+
+ {"MID":"2bf94015818e4770b2b1947b5fdbb969","UID":"SDOC-SRS-72","_LINK":"SDOC-SRS-72" },
+
+ {"MID":"bb52b698d7a544aca420d606e4e51356","UID":"SDOC-SRS-73","_LINK":"SDOC-SRS-73" },
+
+ {"MID":"0ffda51372b641f6ba460bf5ac8b3627","UID":"SECTION-SRS-Excel","_LINK":"SECTION-SRS-Excel" },
+
+ {"MID":"f7b587f66dda402dbd58768e2740742f","UID":"SDOC-SRS-74","_LINK":"SDOC-SRS-74" },
+
+ {"MID":"97b587f66dda402dbd58768e2740742f","UID":"SDOC-SRS-152","_LINK":"SDOC-SRS-152" },
+
+ {"MID":"5aa75848972249d5bec8a40812b99d86","UID":"SDOC-SRS-134","_LINK":"SDOC-SRS-134" },
+
+ {"MID":"53cfa6296eec45479544e6c5165d7fb9","UID":"SECTION-SRS-Command-line-interface","_LINK":"SECTION-SRS-Command-line-interface" },
+
+ {"MID":"63373c3875404f1c820add84ea057c73","_LINK":"8.1-General-CLI-requirements" },
+
+ {"MID":"598647eed3a446fe93e2c54b197f830e","UID":"SDOC-SRS-103","_LINK":"SDOC-SRS-103" },
+
+ {"MID":"7c6a0efe76b84dcd842ef371796e787e","UID":"SECTION-SRS-Command-Manage","_LINK":"SECTION-SRS-Command-Manage" },
+
+ {"MID":"bea76afe9bf241eaaf5984b54e00ff76","UID":"SECTION-SRS-Command-Auto-UID","_LINK":"SECTION-SRS-Command-Auto-UID" },
+
+ {"MID":"7daa1310876a421f8e39f8ac25b99c1d","UID":"SDOC-SRS-85","_LINK":"SDOC-SRS-85" },
+
+ {"MID":"a0ed7cdd06ec4f0ab6d3ba56cced8c7e","_LINK":"9-Python-API" },
+
+ {"MID":"a20c5b6a021f4dd5a5a5dda2880c1b87","UID":"SDOC-SRS-125","_LINK":"SDOC-SRS-125" },
+
+ {"MID":"590121ded2074757aa1720b4d8013426","_LINK":"10-Web-server" },
+
+ {"MID":"409f462f1f4645c8ad24980727a72521","UID":"SDOC-SRS-126","_LINK":"SDOC-SRS-126" },
+
+ {"MID":"44eb09d0e5b542d5984d234167e6f337","_LINK":"11-User-experience" },
+
+ {"MID":"821c01118a9643a188a4ecc5b0cec6a5","UID":"SECTION-SSRS-Strict-mode-by-default","_LINK":"SECTION-SSRS-Strict-mode-by-default" },
+
+ {"MID":"c4e9dce647654deeab8471d04573f8cb","UID":"SDOC-SRS-6","_LINK":"SDOC-SRS-6" },
+
+ {"MID":"40e7bd8aabdf4cb889e9d7b01b8729e6","UID":"SECTION-SRS-Configurability","_LINK":"SECTION-SRS-Configurability" },
+
+ {"MID":"da446e6d3c6d4b13badd4a47bdbcc5a3","UID":"SDOC-SRS-37","_LINK":"SDOC-SRS-37" },
+
+ {"MID":"a6e70c0619204a26b135d1e5fca45dd7","UID":"SDOC-SRS-39","_LINK":"SDOC-SRS-39" },
+
+ {"MID":"a8a17295d3e24601891c7d19d5ca67d9","UID":"SDOC-SRS-119","_LINK":"SDOC-SRS-119" },
+
+ {"MID":"bb14fb2c46f34cf1a82b417b57e95853","UID":"SECTION-SSRS-Performance","_LINK":"SECTION-SSRS-Performance" },
+
+ {"MID":"acd97ca6b9d2451da53168917d96705e","UID":"SDOC-SRS-1","_LINK":"SDOC-SRS-1" },
+
+ {"MID":"54602f6d120548c8bbd70d1d25113d53","UID":"SDOC-SRS-95","_LINK":"SDOC-SRS-95" },
+
+ {"MID":"6fec2f8c0baa4ddba95bee05ad03a785","UID":"SDOC-SRS-2","_LINK":"SDOC-SRS-2" },
+
+ {"MID":"5f2df631605543d18d57e09bc3791003","UID":"SDOC-SRS-3","_LINK":"SDOC-SRS-3" },
+
+ {"MID":"d0c4828ed8434613aae844481bbef1ca","UID":"SDOC-SRS-4","_LINK":"SDOC-SRS-4" },
+
+ {"MID":"4e014d3291ce460c993a0ff334eff4a7","UID":"SDOC-SRS-5","_LINK":"SDOC-SRS-5" },
+
+ {"MID":"de3a4de44f474784bf233ea7610eac6c","UID":"SECTION-SRS-Quality-requirements","_LINK":"SECTION-SRS-Quality-requirements" },
+
+ {"MID":"cbee3d3e8a9d440abaa58387c342602c","_LINK":"14.1-General-process" },
+
+ {"MID":"27319e3866b8423099774d8770950acd","UID":"SDOC-SRS-133","_LINK":"SDOC-SRS-133" },
+
+ {"MID":"47cec130eb3d4583825355f2635e7011","UID":"SECTION-SRS-Requirements-engineering","_LINK":"SECTION-SRS-Requirements-engineering" },
+
+ {"MID":"d0ab977bbb494cbf818c92a1cab1bef0","UID":"SDOC-SRS-128","_LINK":"SDOC-SRS-128" },
+
+ {"MID":"b3fff332c2e342ec9dd372ebd49cb64d","UID":"SDOC-SRS-91","_LINK":"SDOC-SRS-91" },
+
+ {"MID":"dfbaabc0529f4cc987358ae0563910e9","UID":"SECTION-SRS-Implementation-requirements","_LINK":"SECTION-SRS-Implementation-requirements" },
+
+ {"MID":"5eb734a4b8944531aa75f0b71ef22d52","UID":"SECTION-SRS-Programming-languages","_LINK":"SECTION-SRS-Programming-languages" },
+
+ {"MID":"4053ea6c8f6c4c29b89fea0e39912861","UID":"SDOC-SRS-8","_LINK":"SDOC-SRS-8" },
+
+ {"MID":"131af6457a9f43299306e6dc9fce65a7","UID":"SECTION-SRS-Cross-platform-availability","_LINK":"SECTION-SRS-Cross-platform-availability" },
+
+ {"MID":"ceee07bdc9bd42fc9a4d0e9b4bfc312f","UID":"SDOC-SRS-9","_LINK":"SDOC-SRS-9" },
+
+ {"MID":"f8c7586e1b324480ac0bd153e068350d","UID":"SDOC-SRS-10","_LINK":"SDOC-SRS-10" },
+
+ {"MID":"6af3dbb1e05244579622d3d2a26b5413","UID":"SDOC-SRS-11","_LINK":"SDOC-SRS-11" },
+
+ {"MID":"852396c217184ba98a0d26b92f36fd04","UID":"SECTION-SRS-Implementation-constraints","_LINK":"SECTION-SRS-Implementation-constraints" },
+
+ {"MID":"83d5c896004948b48c3597d58267dafa","UID":"SDOC-SRS-89","_LINK":"SDOC-SRS-89" },
+
+ {"MID":"b22bf982e73246a79a5ba4ae653d21e5","UID":"SDOC-SRS-14","_LINK":"SDOC-SRS-14" },
+
+ {"MID":"309e4108c1fa47e99d4331af642f3b81","UID":"SDOC-SRS-15","_LINK":"SDOC-SRS-15" },
+
+ {"MID":"b9cacb97a045418385c7f870b23ac063","UID":"SDOC-SRS-16","_LINK":"SDOC-SRS-16" },
+
+ {"MID":"70f05a744a0546909dc5b69de88ad41f","UID":"SDOC-SRS-87","_LINK":"SDOC-SRS-87" },
+
+ {"MID":"7d68821750a54cb5833b608cfc278f47","UID":"SDOC-SRS-88","_LINK":"SDOC-SRS-88" },
+
+ {"MID":"e4e5b9934e074cdb9567fa197db20a4a","UID":"SECTION-SRS-Coding-constraints","_LINK":"SECTION-SRS-Coding-constraints" },
+
+ {"MID":"61d96cd1d03e40c48187ee67ac0b65f6","UID":"SDOC-SRS-40","_LINK":"SDOC-SRS-40" },
+
+ {"MID":"72b5b0c925cf4ef49749b7e466675df1","UID":"SDOC-SRS-41","_LINK":"SDOC-SRS-41" },
+
+ {"MID":"61e87567580045378d970b327d218cac","UID":"SECTION-SRS-Linting","_LINK":"SECTION-SRS-Linting" },
+
+ {"MID":"6c0163c56ade49faa353ec06cbd676cd","UID":"SDOC-SRS-42","_LINK":"SDOC-SRS-42" },
+
+ {"MID":"3029f97a1276499dbbd5d7c71691908e","UID":"SECTION-SRS-Static-analysis","_LINK":"SECTION-SRS-Static-analysis" },
+
+ {"MID":"2cc9b494ca6248058b6bf63b6e2c1cfa","UID":"SDOC-SRS-43","_LINK":"SDOC-SRS-43" },
+
+ {"MID":"3aba8ca86d404ba9a063ce125489f35b","UID":"SECTION-SRS-Testing","_LINK":"SECTION-SRS-Testing" },
+
+ {"MID":"2731c64ab32146eeb4b8167df4a34540","UID":"SDOC-SRS-44","_LINK":"SDOC-SRS-44" },
+
+ {"MID":"70ef3986cfc4437bbb10288d3b55958c","UID":"SDOC-SRS-45","_LINK":"SDOC-SRS-45" },
+
+ {"MID":"a42c65f1a53b4c9bb50bc2a1ecb855cb","UID":"SDOC-SRS-46","_LINK":"SDOC-SRS-46" },
+
+ {"MID":"c90f35ab9a7f4c29a418557151878b9f","UID":"SDOC-SRS-47","_LINK":"SDOC-SRS-47" },
+
+ {"MID":"83bdb9731e78431cb48d584d279443b4","_LINK":"15-Code-hosting-and-distribution" },
+
+ {"MID":"dbd186fae9624fd6af8aeb55edfaa43b","UID":"SECTION-SRS-Code-hosting","_LINK":"SECTION-SRS-Code-hosting" },
+
+ {"MID":"b112c60bc2f34114ab1f3361a1a10a00","UID":"SDOC-SRS-12","_LINK":"SDOC-SRS-12" },
+
+ {"MID":"bd949cbbe07c4cb29492ea0c8e5c1eec","UID":"SDOC-SRS-118","_LINK":"SDOC-SRS-118" }, ],
+ "strictdoc/docs/strictdoc_24_development_plan.html": [
+
+
+ {"MID":"e776a9eb7ba0455eb589787028aa0529","_LINK":"None-Development-Plan" },
+
+ {"MID":"2ba509874f1744cf899643b58a6a2095","_LINK":"2ba509874f1744cf899643b58a6a2095" },
+
+ {"MID":"24b0bc5efe074a419b441900d30b2876","_LINK":"1-Project-goals" },
+
+ {"MID":"bdbd5aecefdc41bca1c88b9bce71d512","_LINK":"bdbd5aecefdc41bca1c88b9bce71d512" },
+
+ {"MID":"f1e3c17829fd4eebbd390fceaeb95619","UID":"SECTION-DP-Project-milestones","_LINK":"SECTION-DP-Project-milestones" },
+
+ {"MID":"fd9294fdd2b546de993f649767371394","_LINK":"fd9294fdd2b546de993f649767371394" },
+
+ {"MID":"bf9f3f05501140da8d35cde39493c72f","_LINK":"2.1-The-roadmap-diagram" },
+
+ {"MID":"53e101acb20e44e89de27f0f77c5f0cb","_LINK":"53e101acb20e44e89de27f0f77c5f0cb" },
+
+ {"MID":"625560c790a3492eaf45466b787602d7","_LINK":"3-Versioning" },
+
+ {"MID":"ae2a2af6e3f24f65845c6c37ea7da2e2","_LINK":"ae2a2af6e3f24f65845c6c37ea7da2e2" },
+
+ {"MID":"ef6bde37e1c54f49afdbd3c6785fd01c","_LINK":"4-Quality" },
+
+ {"MID":"14d0e79fcadc43f1a1cee2d66ae6b763","_LINK":"14d0e79fcadc43f1a1cee2d66ae6b763" },
+
+ {"MID":"bc49b1e28fff4386b3bf5788a6686a79","_LINK":"4.1-Linting-of-code" },
+
+ {"MID":"f6de78d4a95b4970ab55563e18472a92","_LINK":"f6de78d4a95b4970ab55563e18472a92" },
+
+ {"MID":"38ce17138405490b80e06037b40dc49d","_LINK":"4.2-Static-analysis" },
+
+ {"MID":"ad63541e341d4648ab59b4a0817a7e3c","_LINK":"ad63541e341d4648ab59b4a0817a7e3c" },
+
+ {"MID":"2834756354a7420499d0deecfe0ee9c4","_LINK":"4.3-Testing" },
+
+ {"MID":"ee541e7062704b3f919bcaac2bce2723","_LINK":"ee541e7062704b3f919bcaac2bce2723" },
+
+ {"MID":"2004550abd54486d9aa5f98282eef6e1","_LINK":"4.4-Traceability-between-StrictDoc-requirements-code-and-tests" },
+
+ {"MID":"f829d28d2e3d4bcaa38f44ffb1ac0373","_LINK":"f829d28d2e3d4bcaa38f44ffb1ac0373" },
+
+ {"MID":"30b874ab3eac4d429633537e1e89677f","_LINK":"4.5-Continuous-integration-CI" },
+
+ {"MID":"85e3915270f144c7a76ccfa0e088d93d","_LINK":"85e3915270f144c7a76ccfa0e088d93d" },
+
+ {"MID":"2ae3a8822a424a9e8ad6976c2476d109","_LINK":"5-Python-baseline" },
+
+ {"MID":"081ee6266bab4a3a80f290c95e055a25","_LINK":"081ee6266bab4a3a80f290c95e055a25" }, ],
+ "strictdoc/docs/strictdoc_25_design.html": [
+
+
+ {"MID":"8e68536f7d4047ada15d3a3043580c4a","UID":"SDOC_DD","_LINK":"SDOC_DD" },
+
+ {"MID":"2c006e9044074d239db4a45328633657","_LINK":"2c006e9044074d239db4a45328633657" },
+
+ {"MID":"a74f4e7328714765b5e051768ca8383d","_LINK":"1-Overview" },
+
+ {"MID":"23937f96ac8e437d81686071cc42d6bf","_LINK":"23937f96ac8e437d81686071cc42d6bf" },
+
+ {"MID":"f296843b2027457f851a159abafc97e3","_LINK":"2-Building-blocks" },
+
+ {"MID":"bae7db5591fe418a857af4fb02ad4fec","_LINK":"bae7db5591fe418a857af4fb02ad4fec" },
+
+ {"MID":"5328a6f4c8544f5e92a91279b5b2c0df","UID":"SECTION-DD-High-level-architecture","_LINK":"SECTION-DD-High-level-architecture" },
+
+ {"MID":"dcb6369b8d0949f0b06c9ee5b2188b12","_LINK":"dcb6369b8d0949f0b06c9ee5b2188b12" },
+
+ {"MID":"9b81ed50014c412bb617e90552e58879","_LINK":"4-StrictDoc-command-line-application" },
+
+ {"MID":"0e0fca629004496084dbe5e217874c36","_LINK":"0e0fca629004496084dbe5e217874c36" },
+
+ {"MID":"dbcfa8a98e4f4928b0b35938d57dd644","_LINK":"5-StrictDoc-web-application" },
+
+ {"MID":"f84c0efa27954e44a8b5c1dd3517f90f","_LINK":"f84c0efa27954e44a8b5c1dd3517f90f" },
+
+ {"MID":"dd2bd75fdffe49a1a0299b804538329c","_LINK":"5.1-The-HTML-Over-the-Wire-Hotwire-architecture" },
+
+ {"MID":"5577da2187294eb986ec84d9fe26bbdf","_LINK":"5577da2187294eb986ec84d9fe26bbdf" },
+
+ {"MID":"50f1db3236fa426ea5904974ee724939","_LINK":"6-Static-HTML-search" },
+
+ {"MID":"5fedd9aac1684adc8fe1f3b87557345d","UID":"SDOC-SRS-156","_LINK":"SDOC-SRS-156" },
+
+ {"MID":"108af17c077c48bea04557c9d325e924","_LINK":"7-Parsing-SDoc-files" },
+
+ {"MID":"8a926f0a67424a1eb5db73bb5abca0cd","_LINK":"8a926f0a67424a1eb5db73bb5abca0cd" },
+
+ {"MID":"4db723c7ae2c4350b2f184783cb638e7","UID":"SECTION-DD-Caching-artifacts","_LINK":"SECTION-DD-Caching-artifacts" },
+
+ {"MID":"d351d1bf6c2a48d88e9b9bdc50e029ff","_LINK":"d351d1bf6c2a48d88e9b9bdc50e029ff" },
+
+ {"MID":"4b904b71438c47fcac8aba14df2dd7c0","_LINK":"9-HTML-escaping" },
+
+ {"MID":"e8a03713c7f644698d9a72cc79b2a299","_LINK":"e8a03713c7f644698d9a72cc79b2a299" },
+
+ {"MID":"92e8709709614f0f9ccdf702799bf56c","_LINK":"10-ReqIF-interface" },
+
+ {"MID":"abe8709709614f0f9ccdf702799bf511","UID":"SDOC-SRS-153","_LINK":"SDOC-SRS-153" }, ],
+ "strictdoc/docs/strictdoc_28_Backlog.html": [
+
+
+ {"MID":"cabef7629dda4f2fb34255d01fea8d5f","_LINK":"None-StrictDoc-Backlog" },
+
+ {"MID":"35bc1e28ec724aefbcff864c89399877","_LINK":"35bc1e28ec724aefbcff864c89399877" },
+
+ {"MID":"d1e697dea73144c48a4b88d0d784a517","UID":"SECTION-SB-Open-source-requirements-tool-challenges","_LINK":"SECTION-SB-Open-source-requirements-tool-challenges" },
+
+ {"MID":"d65fe32e8ea444ceb99c174bfc06df7d","_LINK":"d65fe32e8ea444ceb99c174bfc06df7d" },
+
+ {"MID":"fc76b207c152433888a86a166f58a425","UID":"SDOC-SRS-13","_LINK":"SDOC-SRS-13" },
+
+ {"MID":"7614a9f4f7bd4b1c9899995ac3d1e6ad","UID":"SECTION-SB-Backlog","_LINK":"SECTION-SB-Backlog" },
+
+ {"MID":"e61e7224e27d41ceacad9bf6051bd6f0","UID":"SDOC-BACKLOG-6","_LINK":"SDOC-BACKLOG-6" },
+
+ {"MID":"07a9636655314912a996ecf5692ae3d5","UID":"SDOC-SRS-86","_LINK":"SDOC-SRS-86" },
+
+ {"MID":"0425151bf3944e0ebc1c5acabcb35905","UID":"SECTION-SRS-Screen-Project-home","_LINK":"SECTION-SRS-Screen-Project-home" },
+
+ {"MID":"0a158ddac310483489ef08f618ba8741","UID":"SDOC-SRS-52","_LINK":"SDOC-SRS-52" },
+
+ {"MID":"1d8a2c3cf8c24e1b92fe212ab7efacf2","_LINK":"2.4-Screen-Traceability-navigator" },
+
+ {"MID":"dbfe92e9ec3b44e9a3e1c9e89a0e9ef5","UID":"SDOC-SRS-113","_LINK":"SDOC-SRS-113" },
+
+ {"MID":"2654d541d5ce4cb6ad9fcfe2eaa9abb4","UID":"SECTION-SB-Formal-modeling","_LINK":"SECTION-SB-Formal-modeling" },
+
+ {"MID":"5958a5c0aad8486b84ad31bc014d4ad3","UID":"SDOC-RMC-27","_LINK":"SDOC-RMC-27" },
+
+ {"MID":"99e84f704c074cf28de51ce6fb183a66","UID":"SDOC-RMC-29","_LINK":"SDOC-RMC-29" },
+
+ {"MID":"44b30591f6674ede821324fe527babd9","UID":"SDOC-RMC-55","_LINK":"SDOC-RMC-55" },
+
+ {"MID":"045aee37b0a24b3cb62cabd8b614aaf7","UID":"SDOC-RMC-28","_LINK":"SDOC-RMC-28" },
+
+ {"MID":"7e0fd5af118b4f5d8ecbf0d8ef3841e6","UID":"SDOC-RMC-30","_LINK":"SDOC-RMC-30" },
+
+ {"MID":"061392f275b04c93b664faad9ed4f483","UID":"SECTION-SRS-LaTeX-export","_LINK":"SECTION-SRS-LaTeX-export" },
+
+ {"MID":"9ec7f471ccb243ea9d86cf2756403b8f","UID":"SDOC-SRS-76","_LINK":"SDOC-SRS-76" },
+
+ {"MID":"5a0304abcd8a44dab5d032dce6625a5d","UID":"SDOC-BACKLOG-1","_LINK":"SDOC-BACKLOG-1" },
+
+ {"MID":"162a3da4d9d74c15b5078c9859657ce3","UID":"SDOC-BACKLOG-2","_LINK":"SDOC-BACKLOG-2" },
+
+ {"MID":"06f16ede826749a389c8d7de9828e0eb","UID":"SDOC-BACKLOG-3","_LINK":"SDOC-BACKLOG-3" },
+
+ {"MID":"0e69828e1d914e20852aef7cfc4e87c4","UID":"SDOC-BACKLOG-9","_LINK":"SDOC-BACKLOG-9" },
+
+ {"MID":"34246811634c493dbc771ae4c8bc3b14","UID":"SDOC-BACKLOG-4","_LINK":"SDOC-BACKLOG-4" },
+
+ {"MID":"3f50a97bc70842dbabeea911f653ef90","UID":"SDOC-BACKLOG-7","_LINK":"SDOC-BACKLOG-7" },
+
+ {"MID":"72285f9b09de48a29fef8f85431e4a94","UID":"SDOC-BACKLOG-8","_LINK":"SDOC-BACKLOG-8" },
+
+ {"MID":"bdedcdd91c7f4efb8787b5a82cfec49b","UID":"SDOC-SRS-114","_LINK":"SDOC-SRS-114" },
+
+ {"MID":"478c38d2cca94107b18fe3dc5b8bfefd","_LINK":"2.15-Multi-user-workflow" },
+
+ {"MID":"f97dc050ddab4a08bf1689200118faaa","UID":"SDOC-SRS-123","_LINK":"SDOC-SRS-123" },
+
+ {"MID":"e5b2aff0c1db4b11a8c75c278813300b","UID":"SDOC-SRS-130","_LINK":"SDOC-SRS-130" },
+
+ {"MID":"440f0bc311b84421a7e8bea9dfd2448b","UID":"SDOC-SRS-131","_LINK":"SDOC-SRS-131" },
+
+ {"MID":"caecd704ed634d718deff07ba0db7fa6","UID":"SDOC-SRS-116","_LINK":"SDOC-SRS-116" },
+
+ {"MID":"b74a7a3209d247f6b357513b0cce5000","UID":"SDOC-SRS-121","_LINK":"SDOC-SRS-121" },
+
+ {"MID":"fa7fd8fd3a694d8e93953fd60e19fdde","UID":"SDOC-SRS-61","_LINK":"SDOC-SRS-61" },
+
+ {"MID":"7a06d1433e4c4b0eaf55ede14507eac9","UID":"SDOC-SRS-94","_LINK":"SDOC-SRS-94" },
+
+ {"MID":"45b8513623744776899abfbf99c95286","UID":"SDOC-SRS-58","_LINK":"SDOC-SRS-58" },
+
+ {"MID":"c02a65f2716f4a86b8f83e3a7b4cd31c","UID":"SDOC-SRS-60","_LINK":"SDOC-SRS-60" },
+
+ {"MID":"7aa5316dd056465e97044e221412290b","UID":"SDOC-SRS-63","_LINK":"SDOC-SRS-63" },
+
+ {"MID":"229378602d1847cb83c61ab3e97bb22b","UID":"SDOC-SRS-64","_LINK":"SDOC-SRS-64" },
+
+ {"MID":"b3472533d57145bc9790724efe56075c","_LINK":"2.24-Screen-Impact-analysis" },
+
+ {"MID":"f5feb38777064d9db939279d32f79130","UID":"SDOC-SRS-117","_LINK":"SDOC-SRS-117" },
+
+ {"MID":"a7c504087df04cedb5541d83ed988e9b","UID":"SDOC-SRS-75","_LINK":"SDOC-SRS-75" },
+
+ {"MID":"4a49c79a1bdd4d4aae5f62bc1d2a56d0","UID":"SECTION-SB-Backlog-Web-based-user-interface","_LINK":"SECTION-SB-Backlog-Web-based-user-interface" },
+
+ {"MID":"d10cddd846de4961bbb0bc8b8c6550d3","_LINK":"d10cddd846de4961bbb0bc8b8c6550d3" },
+
+ {"MID":"866a55f2e47b477ebcd52ea57da4f037","UID":"SECTION-SB-Backlog-Nice-to-have","_LINK":"SECTION-SB-Backlog-Nice-to-have" },
+
+ {"MID":"d02e104a518c4627ac918a33ad165c96","_LINK":"d02e104a518c4627ac918a33ad165c96" },
+
+ {"MID":"eb1fab2bbea541c8b00f70780326c9fc","UID":"SECTION-SB-Backlog-Technical-debt","_LINK":"SECTION-SB-Backlog-Technical-debt" },
+
+ {"MID":"85e94802132048d29ca73cf2096c6758","_LINK":"85e94802132048d29ca73cf2096c6758" },
+
+ {"MID":"6ef8c2ad683d46af948674727c7a52b4","UID":"SECTION-SB-Open-questions","_LINK":"SECTION-SB-Open-questions" },
+
+ {"MID":"717df91623014fb98ba34ab8173b94ab","UID":"SECTION-SB-One-or-many-input-sdoc-trees","_LINK":"SECTION-SB-One-or-many-input-sdoc-trees" },
+
+ {"MID":"b778a18ede89464c936be2b2af492e24","_LINK":"b778a18ede89464c936be2b2af492e24" }, ],
+ "strictdoc/docs/strictdoc_30_credits.html": [
+
+
+ {"MID":"d92baa6b8cf745a2ab6be86616b06277","_LINK":"None-Credits" },
+
+ {"MID":"18cf0af34c194590b3eb391c2ef94074","_LINK":"18cf0af34c194590b3eb391c2ef94074" },
+
+ {"MID":"c89b5ba9c6dc427497647b64048a2c98","_LINK":"1-Contributions-to-StrictDoc" },
+
+ {"MID":"e6de83e242bc4aea96622a2e7585f135","_LINK":"e6de83e242bc4aea96622a2e7585f135" },
+
+ {"MID":"4d59a5df65d547e685cb491937793f69","_LINK":"2-Open-source-software" },
+
+ {"MID":"4428ac9ec3504dda9f1e1e845ffb3c75","_LINK":"4428ac9ec3504dda9f1e1e845ffb3c75" },
+
+ {"MID":"2da7450f8b804a7a8494921486bd4d8e","_LINK":"3-Hosting-and-Continuous-Integration" },
+
+ {"MID":"5b702e6f9b714e458b059912ca8e196a","_LINK":"5b702e6f9b714e458b059912ca8e196a" },
+
+ {"MID":"43ccb6448b9d4b65a2c40df54d1707aa","_LINK":"4-Free-and-commercial-IDEs-by-JetBrains" },
+
+ {"MID":"b4729e592d104fe3818c8949615ffef9","_LINK":"b4729e592d104fe3818c8949615ffef9" }, ],
+ "strictdoc/docs_extra/DO178_requirements.html": [
+
+
+ {"MID":"b3727ea826c24d42a84e88983e7c1e24","_LINK":"None-Technical-Note-DO-178C-requirements-tool-requirements" },
+
+ {"MID":"fc77215d50134f17aa242b4df7310099","_LINK":"fc77215d50134f17aa242b4df7310099" },
+
+ {"MID":"6be4dbe02b4346df9849eaa6fe077e0e","UID":"SECTION-DR-Already-implemented-features","_LINK":"SECTION-DR-Already-implemented-features" },
+
+ {"MID":"af14393406e64ab6b2911eefa4358f33","UID":"DO178-1","_LINK":"DO178-1" },
+
+ {"MID":"0a19cae3756a4d2f9f0be9e57c44a8fa","UID":"DO178-2","_LINK":"DO178-2" },
+
+ {"MID":"dd075d6cd4fb4ad2b731a9b8068efade","UID":"DO178-14","_LINK":"DO178-14" },
+
+ {"MID":"03346e43cd0b43529cc3b958a00d8d35","UID":"DO178-3","_LINK":"DO178-3" },
+
+ {"MID":"4f0809d49292413eb621a47a8b405bc7","UID":"DO178-4","_LINK":"DO178-4" },
+
+ {"MID":"c74bba92cec34bf7b1046689c2dfc54c","UID":"DO178-5","_LINK":"DO178-5" },
+
+ {"MID":"8b73ce9efcc840b2be272d5aaef08e70","UID":"DO178-6","_LINK":"DO178-6" },
+
+ {"MID":"8c654ff659a94cceb0c7a52bc8ae4073","UID":"DO178-8","_LINK":"DO178-8" },
+
+ {"MID":"cfdb3867a4a64b3eb9405e998c11ae72","UID":"DO178-7","_LINK":"DO178-7" },
+
+ {"MID":"40d4a56263d0420691dbde5d7889895a","UID":"DO178-13","_LINK":"DO178-13" },
+
+ {"MID":"8bd26640450f448c8228464223c21373","UID":"DO178-9","_LINK":"DO178-9" },
+
+ {"MID":"09f3e3faa1b84aafb19f26e22ab06c95","UID":"SECTION-DR-Needs-discussion","_LINK":"SECTION-DR-Needs-discussion" },
+
+ {"MID":"db4336a8f119443cae6a70d74a0601da","UID":"DO178-19","_LINK":"DO178-19" },
+
+ {"MID":"7d18b7674050495c935dc4669dfb260e","UID":"DO178-15","_LINK":"DO178-15" },
+
+ {"MID":"b0c13e71074242ab91d6344514b82657","UID":"DO178-10","_LINK":"DO178-10" },
+
+ {"MID":"7e8a475859084e9d95eda3f2c1381ae7","UID":"DO178-11","_LINK":"DO178-11" },
+
+ {"MID":"23c11790799c4457804bcb9d6288931e","UID":"DO178-12","_LINK":"DO178-12" },
+
+ {"MID":"a1fb2f7cd7cd4c8eb33c3407a791fd88","UID":"DO178-16","_LINK":"DO178-16" },
+
+ {"MID":"756503f4934a4aed81dfe090b2538e2a","UID":"DO178-17","_LINK":"DO178-17" },
+
+ {"MID":"8120b4f6be4e4ecd83c0b69a3424e0be","UID":"DO178-18","_LINK":"DO178-18" }, ],
+ "strictdoc/docs_extra/Zephyr_requirements.html": [
+
+
+ {"MID":"2e7deb9808bb42879e7463b1d7ac9bba","_LINK":"None-Technical-Note-Zephyr-requirements-tool-requirements" },
+
+ {"MID":"68e87901205c4b0dbb6a0071479330b5","UID":"ZEP-1","_LINK":"ZEP-1" },
+
+ {"MID":"36415af620f645388af4dc51c2a19b97","UID":"ZEP-2","_LINK":"ZEP-2" },
+
+ {"MID":"7a9e26240f5c4fe29143cf3348ac3d3b","UID":"ZEP-3","_LINK":"ZEP-3" },
+
+ {"MID":"a5928d6204a84d02a3c367d6dbc54092","UID":"ZEP-4","_LINK":"ZEP-4" },
+
+ {"MID":"55bbe693d12d4e00956d41a837ef15ef","UID":"ZEP-5","_LINK":"ZEP-5" },
+
+ {"MID":"b58c387f3a2d4cf6a540e279dbe49e47","UID":"ZEP-6","_LINK":"ZEP-6" },
+
+ {"MID":"17a141add32f4d7696b5a74b6507b9aa","UID":"ZEP-7","_LINK":"ZEP-7" },
+
+ {"MID":"d0d258d8640443578c7ec508c014b50d","UID":"ZEP-8","_LINK":"ZEP-8" },
+
+ {"MID":"611546bf2409417e8844f93854d54268","UID":"ZEP-9","_LINK":"ZEP-9" },
+
+ {"MID":"f1f6da87da5c49d1b8c3441b14863975","UID":"ZEP-10","_LINK":"ZEP-10" },
+
+ {"MID":"55cbd9b658164414adb0c13b0446e3f7","UID":"ZEP-11","_LINK":"ZEP-11" },
+
+ {"MID":"a2930225168147808e6554a4da49aeb4","UID":"ZEP-12","_LINK":"ZEP-12" },
+
+ {"MID":"2614d6673a594da995df672e8943839e","UID":"ZEP-13","_LINK":"ZEP-13" },
+
+ {"MID":"a92a28ce3bcb4b3590f36e778a604ccb","UID":"ZEP-14","_LINK":"ZEP-14" },
+
+ {"MID":"b74919612283422a9e139418a20926c6","UID":"ZEP-15","_LINK":"ZEP-15" }, ],
+};
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_tree.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_tree.css
new file mode 100644
index 0000000..940d06b
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_tree.css
@@ -0,0 +1,218 @@
+
+/* tree */
+.project_tree {
+ position: relative;
+ /* width: -moz-fit-content;
+ width: fit-content; */
+ /* margin: 0 auto; */
+}
+
+.project_tree details>summary {
+ list-style: none;
+}
+
+.project_tree summary::-webkit-details-marker {
+ display: none
+}
+
+/* folder */
+
+.project_tree-folder {
+ border: var(--base-border);
+ border-radius: calc(0.5 * var(--base-rhythm));
+ overflow: hidden;
+ position: relative;
+ padding-left: var(--base-rhythm);
+ padding-right: var(--base-rhythm);
+ background: var(--color-bg-secondary);
+}
+
+.project_tree-folder[open] {
+ background: transparent;
+}
+
+.project_tree-folder.source {
+ padding-right: 0;
+ border-right: none;
+ border-bottom: none;
+}
+
+.project_tree-folder summary {
+ position: relative;
+ cursor: pointer;
+ user-select: none;
+}
+
+.project_tree-folder-title {
+ font-weight: bold;
+ display: flex;
+ column-gap: calc(0.5 * var(--base-rhythm));
+ font-size: 0.85rem;
+ line-height: 1.2;
+ color: #666;
+ padding: calc(0.5 * var(--base-rhythm));
+ position: relative;
+}
+
+.project_tree-folder-title::before,
+.project_tree-folder-title::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: -20px;
+ left: -20px;
+ bottom: 0;
+}
+
+.project_tree-folder-title::after {
+ background: var(--color-bg-secondary);
+}
+
+.project_tree-folder summary:hover > .project_tree-folder-title::before {
+ background: var(--color-bg-secondary);
+}
+
+.project_tree-folder summary:hover > .project_tree-folder-title,
+.project_tree-folder summary:hover::after {
+ color: var(--color-fg-accent);
+}
+
+/* .icon_collapse_expand is class inside SVG */
+.project_tree-folder-title .icon_collapse_expand {
+ margin-left: auto;
+}
+/* .collapsed and .expanded are classes inside SVG .icon_collapse */
+.project_tree-folder > summary .icon_collapse_expand .collapsed {
+ display: initial;
+}
+.project_tree-folder > summary .icon_collapse_expand .expanded {
+ display: none;
+}
+.project_tree-folder[open] > summary .icon_collapse_expand .expanded {
+ display: initial;
+}
+.project_tree-folder[open] > summary .icon_collapse_expand .collapsed {
+ display: none;
+}
+
+.project_tree-folder-content {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: var(--base-rhythm);
+ padding-top: var(--base-rhythm);
+ padding-bottom: var(--base-rhythm);
+}
+
+/* file */
+
+.project_tree-file {
+ display: flex;
+ column-gap: var(--base-rhythm);
+ padding: calc(0.5 * var(--base-rhythm));
+ border-radius: calc(0.5 * var(--base-rhythm));
+ transition: background .3s;
+ border: 1px solid rgba(255,255,255,0);
+}
+
+.project_tree-file:not([href]):hover {
+ border: 1px solid rgba(255,255,255,0.75);
+ background: rgba(0,0,0,0.01);
+}
+
+.project_tree-file[href]:hover {
+ background: rgba(255,255,255,0.5);
+}
+
+.project_tree-file[href]:hover .project_tree-file-icon,
+.project_tree-file[href]:hover .project_tree-file-title {
+ color: var(--color-fg-accent);
+}
+
+.project_tree-file-details {
+ display: block;
+}
+
+.project_tree-file-icon {
+ line-height: 0;
+}
+
+.project_tree-file-title {
+ font-size: 1em;
+ font-weight: 500;
+ line-height: 1.2;
+ transition: color .2s;
+}
+
+.project_tree-file-icon,
+.project_tree-file-title {
+ color: var(--color-fg-secondary);
+}
+
+.project_tree-file[href] .project_tree-file-icon,
+.project_tree-file[href] .project_tree-file-title {
+ color: var(--color-fg-main);
+}
+
+.project_tree-file-name {
+ font-size: 0.85rem;
+ line-height: 1.2;
+ color: var(--color-fg-secondary);
+ margin-top: 0.25rem;
+}
+
+.project_tree-file-aside {
+ margin-left: auto;
+}
+
+/* dashboard */
+
+.dashboard {
+ display: flex;
+ align-items: flex-start;
+ gap: var(--base-rhythm);
+}
+
+.dashboard-main {
+ flex-grow: 1;
+}
+
+.dashboard-aside {
+ width: 30%;
+ /* max-width: 300px; */
+ font-size: 0.75rem;
+ display: flex;
+ gap: var(--base-rhythm);
+ flex-direction: column;
+}
+
+.dashboard-block:empty {
+ display: none;
+}
+
+.dashboard-block {
+ border: var(--base-border);
+ border-radius: calc(0.5 * var(--base-rhythm));
+ overflow: hidden;
+ position: relative;
+ padding: var(--base-rhythm);
+}
+
+.dashboard-block-title {
+ font-weight: 600;
+ position: relative;
+ top: calc(-1 * var(--base-rhythm));
+ color: var(--color-fg-secondary);
+ padding: calc(0.5 * var(--base-rhythm)) 0;
+}
+
+.dashboard-block-title::after {
+ content: '';
+ position: absolute;
+ top: -20px;
+ left: -20px;
+ right: -20px;
+ bottom: 0;
+ background-color: rgba(0,0,0,0.025);
+ border-bottom: var(--base-border);
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_tree.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_tree.js
new file mode 100644
index 0000000..79a48c9
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/project_tree.js
@@ -0,0 +1,373 @@
+const FRAME_SELECTOR = '#frame_project_tree';
+const SWITCH_SELECTOR = '#project_tree_controls';
+const FRAGMENT_ATTR = 'included-document';
+const FRAGMENT_SELECTOR = `.project_tree-file[${FRAGMENT_ATTR}]`;
+const FILE_SELECTOR = `.project_tree-file`;
+const FOLDER_SELECTOR = `.project_tree-folder`;
+
+// This class Switch was taken
+// from strictdoc/export/html/_static/source-code-coverage.js
+// and improved a bit:
+class Switch {
+ constructor({
+ callback,
+ labelText,
+ checked,
+ componentClass,
+ colorOn,
+ colorOff,
+ size,
+ stroke,
+ units,
+ position,
+ topPosition,
+ leftPosition,
+ rightPosition,
+ bottomPosition,
+ dataTestID,
+ }) {
+ this.colorOn = colorOn || 'rgb(242, 100, 42)';
+ this.colorOff = colorOff || 'rgb(200, 200, 200)';
+ this.labelInitialText = labelText || '';
+ this.checked = (checked === false) ? false : true;
+
+ this.dataTestID = dataTestID || 'std-switch';
+ this.componentClass = componentClass || 'std-switch-scc';
+ this.size = size || 0.75;
+ this.stroke = stroke || 0.25;
+ this.units = units || 'rem';
+
+ this.topPosition = topPosition || 'unset',
+ this.leftPosition = leftPosition || 'unset',
+ this.rightPosition = rightPosition || 'unset',
+ this.bottomPosition = bottomPosition || 'unset',
+ this.position = position || 'static',
+
+ this.controlLabelTextSpan = document.createElement('span');
+ this.callback = callback;
+ }
+
+ create() {
+ const block = document.createElement('div');
+ block.classList.add(this.componentClass);
+ const label = document.createElement('label');
+ label.classList.add(`${this.componentClass}__label`);
+ const input = document.createElement('input');
+ input.classList.add(`${this.componentClass}__input`);
+ input.type = 'checkbox';
+ input.checked = this.checked;
+ const slider = document.createElement('span');
+ slider.classList.add(`${this.componentClass}__slider`);
+
+ label.append(input, slider, this.controlLabelTextSpan);
+ block.append(label);
+
+ this.insertStyle();
+ this.updateLabelText(this.labelInitialText);
+ input.addEventListener('change', () => this.callback(input.checked));
+
+ label.setAttribute('data-testid', this.dataTestID);
+
+ return block;
+ }
+
+ updateLabelText(text) {
+ this.controlLabelTextSpan.innerHTML = text;
+ }
+
+ insertStyle() {
+
+ const css = `
+ .${this.componentClass} {
+ display: inline-block;
+ line-height: 0;
+ position: ${this.position};
+ top: ${this.topPosition};
+ left: ${this.leftPosition};
+ right: ${this.rightPosition};
+ bottom: ${this.bottomPosition};
+ }
+ .${this.componentClass}__label {
+ display: inline-flex;
+ column-gap: 8px;
+ line-height: ${this.size * 1.6}${this.units};
+ line-height: 1.25;
+ align-items: flex-start;
+ justify-content: flex-start;
+ user-select: none;
+ cursor: pointer;
+ font-size: small;
+ }
+ .${this.componentClass}__input {
+ opacity: 0;
+ width: 0;
+ height: 0;
+ position: absolute;
+ }
+ .${this.componentClass}__slider {
+ position: relative;
+ cursor: pointer;
+ background-color: ${this.colorOff};
+ -webkit-transition: .4s;
+ transition: .4s;
+ display: inline-block;
+ width: ${this.size * 2 + this.stroke * 2}${this.units};
+ min-width: ${this.size * 2 + this.stroke * 2}${this.units};
+ height: ${this.size + this.stroke * 2}${this.units};
+ margin-right: ${this.size * 0.5}${this.units};
+ border-radius: ${this.size * 0.5 + this.stroke}${this.units};
+ }
+ .${this.componentClass}__slider::before {
+ position: absolute;
+ content: "";
+ height: ${this.size}${this.units};
+ width: ${this.size}${this.units};
+ left: ${this.stroke}${this.units};
+ bottom: ${this.stroke}${this.units};
+ background-color: white;
+ -webkit-transition: .4s;
+ transition: .4s;
+ border-radius: 50%;
+ }
+ input:checked + .${this.componentClass}__slider {
+ background-color: ${this.colorOn};
+ }
+ input:focus + .${this.componentClass}__slider {
+ box-shadow: 0 0 1px ${this.colorOn};
+ }
+ input:checked + .${this.componentClass}__slider::before {
+ -webkit-transform: translateX(${this.size}${this.units});
+ -ms-transform: translateX(${this.size}${this.units});
+ transform: translateX(${this.size}${this.units});
+ }
+ `;
+
+ const head = document.querySelector('head');
+ const style = document.createElement('style');
+ style.append(document.createTextNode(css));
+ style.setAttribute("data-slider-styles", '');
+ head.append(style);
+ }
+
+}
+
+class ProjectTree {
+ constructor({
+ mutatingFrame,
+ controlTarget
+ }) {
+ this.mutatingFrame = mutatingFrame;
+ this.controlTarget = controlTarget;
+ this.fragments = [];
+
+ this.control;
+ this.controlElement;
+
+ this.state = {
+ fragmentVisibility: {
+ _sessionStorageItemName: 'projectTreeFragmentVisibility',
+ initial: 'hide',
+ current: null,
+ }
+ };
+ }
+
+ init() {
+ // console.log('First time call.');
+
+ console.assert(this.mutatingFrame, `mutatingFrame not found on the page`);
+ this._addMutationObserver();
+
+ this._initStateAndStorage();
+
+ // * this.controlTarget may not be present on the page, for example, in the case of static export.
+ // console.assert(this.controlTarget, `controlTarget not found on the page`);
+
+ this._createControl();
+ this._addControl();
+
+ this.updateFragmentsAndControl();
+ }
+
+ getCurrentFragmentVisibilityBool() {
+ return (this.state.fragmentVisibility.current === 'show') ? true : false;
+ }
+
+ updateFragmentsAndControl() {
+ // Update list of fragment elements (files + folders) and toggle visibility
+ const fileFragments = this._getFileFragments();
+ const folderFragments = this._getFoldersWithOnlyFragments();
+
+ // Store both individual file fragments and folders that contain only fragments
+ this.fragments = [...fileFragments, ...folderFragments];
+
+ // Only show number of file fragments (folders are excluded from count)
+ this._updateControl(fileFragments.length);
+ this._updateFragmentsVisibility(this.getCurrentFragmentVisibilityBool());
+ }
+
+ _getFileFragments() {
+ // Find all file elements that are marked as included fragments
+ return [...this.mutatingFrame.querySelectorAll(FRAGMENT_SELECTOR)];
+ }
+
+ _getFoldersWithOnlyFragments() {
+ // Find folders that contain only fragment files and no other files
+ const folders = [...this.mutatingFrame.querySelectorAll(FOLDER_SELECTOR)];
+ return folders.filter(folder => {
+ // Consider only those folders if it contains only fragment files
+ const fragCount = folder.querySelectorAll(FRAGMENT_SELECTOR).length;
+ const fileCount = folder.querySelectorAll(FILE_SELECTOR).length;
+ return fragCount > 0 && fragCount === fileCount;
+ });
+ }
+
+ _getFragments() {
+ let fragments = [...this.mutatingFrame.querySelectorAll(FRAGMENT_SELECTOR)];
+ const folders = this._prepareFragmentsFolders(fragments);
+ return fragments.concat(folders);
+ }
+
+ _prepareFragmentsFolders(fragments) {
+ // Temporary solution.
+ // It is possible to optimize the search to reduce the number of runs.
+
+ const result = [];
+ // .project_tree-folder > .project_tree-folder-content > .project_tree-file === fragment
+ const folders = [...this.mutatingFrame.querySelectorAll(FOLDER_SELECTOR)];
+ folders.forEach(folder => {
+ const frag = folder.querySelectorAll(FRAGMENT_SELECTOR);
+ const file = folder.querySelectorAll(FILE_SELECTOR);
+ if (frag.length === file.length) {
+ result.push(folder);
+ }
+ });
+ return result
+ }
+
+ _updateFragmentsVisibility(bool) {
+ const display = bool ? '' : 'none';
+ this.fragments.forEach(element => {
+ element.style.display = display;
+ })
+ }
+
+ _updateControl(num) {
+ this.control.updateLabelText(`Show ${num} fragment${num > 1 ? 's' : ''} included in other documents in the Project document tree.`)
+
+ if (num) {
+ this._addControl();
+ } else {
+ this._removeControl();
+ }
+ }
+
+ toggleFragmentsVisibility(checked) {
+ this._updateFragmentsVisibility(checked);
+
+ if (checked) {
+ this._updateCurrentState('show', 'fragmentVisibility');
+ this._setSessionStorageItem('show', 'fragmentVisibility');
+ } else {
+ this._updateCurrentState('hide', 'fragmentVisibility');
+ this._setSessionStorageItem('hide', 'fragmentVisibility');
+ }
+ }
+
+ _initStateAndStorage(option = 'fragmentVisibility') {
+ const storage = this._getSessionStorageItem(option);
+
+ if (storage) {
+ this._updateCurrentState(storage);
+ } else {
+ this._updateCurrentState(this.state[option].initial);
+ this._setSessionStorageItem(this.state[option].initial);
+ }
+ }
+
+ _updateCurrentState(value, option = 'fragmentVisibility') {
+ this.state[option].current = value;
+ }
+
+ _setSessionStorageItem(nextState, option = 'fragmentVisibility') {
+ sessionStorage.setItem(this.state[option]._sessionStorageItemName, nextState);
+ }
+
+ _getSessionStorageItem(option = 'fragmentVisibility') {
+ const storage = sessionStorage.getItem(this.state[option]._sessionStorageItemName);
+ return storage;
+ }
+
+ _createControl() {
+ this.control = new Switch(
+ {
+ labelText: `Show fragments`, // * This text will be updated later.
+ dataTestID: 'show-hide-fragments-toggler',
+ size: 0.5,
+ stroke: 0.175,
+ // position: 'absolute',
+ // topPosition: '16px',
+ // leftPosition: 0,
+ // checked: false,
+ checked: this.getCurrentFragmentVisibilityBool(),
+ callback: (checked) => this.toggleFragmentsVisibility(checked),
+ }
+ );
+ this.controlElement = this.control.create();
+ }
+
+ _addControl() {
+ // * this.controlTarget may not be present on the page, for example, in the case of static export.
+ this.controlTarget && this.controlTarget.append(this.controlElement);
+ }
+
+ _removeControl() {
+ this.controlElement.remove();
+ }
+
+ _addMutationObserver() {
+ // console.log('Mutation observer added for', this.mutatingFrame);
+
+ new MutationObserver((mutationsList, observer) => {
+ for (let mutation of mutationsList) {
+ if (mutation.type === 'childList') {
+ // When re-rendering the frame content,
+ // the array of tracked elements should be updated
+ // and their visibility should be set according
+ // to the current settings available in the State.
+ this.updateFragmentsAndControl();
+ }
+ }
+ }).observe(
+ this.mutatingFrame,
+ {
+ childList: true,
+ // subtree: true
+ }
+ );
+ }
+}
+
+window.addEventListener("DOMContentLoaded", function(){
+
+ const controlTarget = document.querySelector(SWITCH_SELECTOR);
+ // * This element may not be present on the page, for example, in the case of static export.
+ // if (!controlTarget) {
+ // console.error(`Selector "${SWITCH_SELECTOR}" not found on the page`);
+ // return;
+ // }
+
+ const mutatingFrame = document.querySelector(FRAME_SELECTOR);
+ if (!mutatingFrame) {
+ console.error(`Selector "${FRAME_SELECTOR}" not found on the page`);
+ return;
+ }
+
+ const projectTree = new ProjectTree({
+ mutatingFrame,
+ controlTarget
+ });
+
+ projectTree.init();
+
+},false);
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/requirement-tree.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/requirement-tree.css
new file mode 100644
index 0000000..b0aa443
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/requirement-tree.css
@@ -0,0 +1,283 @@
+:root {
+ --requirement-tree-line-width: 1px;
+ --requirement-tree-line-color: var(--color-border);
+ --requirement-tree-margin: var(--tree-gap);
+ --requirement-tree-downward-margin: calc(var(--requirement-tree-margin)*.5);
+ --requirement-tree-downward-string-margin: calc(var(--requirement-tree-downward-margin)*0.25);
+ --requirement-tree-line: var(--requirement-tree-line-width) solid;
+ --requirement-tree-downward-line: var(--requirement-tree-line-color) var(--requirement-tree-line-width) solid;
+ --requirement-tree-arrow-size: calc(var(--requirement-tree-margin)/4);
+ /* var(--color-fg-contrast) */
+ /* var(--color-accent) */
+}
+
+/* requirement-tree */
+
+.requirement-tree {
+ position: relative;
+
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ box-sizing: border-box;
+
+ display: flex;
+ justify-content: flex-start;
+ flex-direction: column;
+ align-content: flex-start;
+
+ /* default aka right direction */
+ align-items: flex-start;
+ margin-left: var(--requirement-tree-margin);
+}
+
+.requirement-tree_right.requirement-tree {
+ align-items: flex-start;
+ margin-right: 0;
+ margin-left: var(--requirement-tree-margin);
+}
+
+.requirement-tree_left.requirement-tree {
+ align-items: flex-end;
+ margin-left: 0;
+ margin-right: var(--requirement-tree-margin);
+}
+
+.requirement-tree_branch {
+ position: relative;
+
+ display: flex;
+ justify-content: center;
+ align-items: flex-start;
+ align-content: stretch;
+ margin-bottom: var(--requirement-tree-margin);
+}
+
+.requirement-tree_left .requirement-tree_branch {
+ flex-direction: row-reverse;
+}
+
+.requirement-tree_branch:last-child {
+ margin-bottom: 0;
+}
+
+.requirement-tree_node {
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+
+ /* for width restrictions in deep trace */
+ max-width: var(--card-width);
+}
+
+[data-viewtype="requirements-coverage"] .requirement-tree_node {
+ width: calc(var(--card-width)*0.75);
+}
+
+ /* arrows */
+
+.requirement-tree_right.requirement-tree::before {
+ /* arrow from children, show only in right tree */
+ content: '';
+ position: absolute;
+ width: var(--requirement-tree-arrow-size);
+ height: var(--requirement-tree-arrow-size);
+ top: var(--requirement-tree-margin);
+ left: calc(var(--requirement-tree-margin)*(-1) - var(--requirement-tree-line-width)*0.5);
+ box-sizing: border-box;
+ border-top: var(--requirement-tree-line);
+ border-left: var(--requirement-tree-line);
+ transform-origin: top left;
+ transform: rotate(-45deg);
+ z-index: 2;
+}
+
+.requirement-tree_left .requirement-tree_node::before {
+ /* arrow to parents inside tree */
+ content: '';
+ position: absolute;
+ width: var(--requirement-tree-arrow-size);
+ height: var(--requirement-tree-arrow-size);
+ top: var(--requirement-tree-margin);
+ right: calc(var(--requirement-tree-arrow-size)*(-1));
+ box-sizing: border-box;
+ border-top: var(--requirement-tree-line);
+ border-left: var(--requirement-tree-line);
+ transform-origin: top left;
+ transform: rotate(-45deg);
+ z-index: 2;
+}
+
+/* corner connector to node */
+
+.requirement-tree_branch::before {
+ content: '';
+ position: absolute;
+ width: calc(var(--requirement-tree-margin)*0.5);
+ height: var(--requirement-tree-margin);
+ top: 0;
+ box-sizing: border-box;
+ /* default aka right direction */
+ border-bottom: var(--requirement-tree-line);
+ border-left: var(--requirement-tree-line);
+ left: calc(var(--requirement-tree-margin)*(-1)*0.5);
+}
+
+.requirement-tree_right .requirement-tree_branch::before {
+ right: unset;
+ left: calc(var(--requirement-tree-margin)*(-1)*0.5);
+ border: none;
+ border-bottom: var(--requirement-tree-line);
+ border-left: var(--requirement-tree-line);
+}
+
+.requirement-tree_left .requirement-tree_branch::before {
+ left: unset;
+ right: calc(var(--requirement-tree-margin)*(-1)*0.5);
+ border: none;
+ border-bottom: var(--requirement-tree-line);
+ border-right: var(--requirement-tree-line);
+}
+
+/* horizontal line to top node instead corner */
+
+.requirement-tree_branch:first-child::before {
+ width: var(--requirement-tree-margin);
+ border: none;
+ border-bottom: var(--requirement-tree-line);
+ /* default aka right direction */
+ right: unset;
+ left: calc(var(--requirement-tree-margin)*(-1));
+}
+
+.requirement-tree_right .requirement-tree_branch:first-child::before {
+ right: unset;
+ left: calc(var(--requirement-tree-margin)*(-1));
+}
+
+.requirement-tree_left .requirement-tree_branch:first-child::before {
+ left: unset;
+ right: calc(var(--requirement-tree-margin)*(-1));
+}
+
+/* vertical line */
+
+.requirement-tree_branch::after {
+ content: '';
+ position: absolute;
+ width: calc(var(--requirement-tree-margin)*0.5);
+ top: var(--requirement-tree-margin);
+ bottom: calc(var(--requirement-tree-margin)*(-1));
+ box-sizing: border-box;
+ /* default aka right direction */
+ border: none;
+ border-left: var(--requirement-tree-line);
+ left: calc(var(--requirement-tree-margin)*(-1)*0.5);
+}
+
+.requirement-tree_right .requirement-tree_branch::after {
+ border: none;
+ border-left: var(--requirement-tree-line);
+ right: unset;
+ left: calc(var(--requirement-tree-margin)*(-1)*0.5);
+}
+
+.requirement-tree_left .requirement-tree_branch::after {
+ border: none;
+ border-right: var(--requirement-tree-line);
+ left: unset;
+ right: calc(var(--requirement-tree-margin)*(-1)*0.5);
+}
+
+/* vertical line on last node is not showing */
+.requirement-tree_branch:last-child:after {
+ content: none;
+}
+
+/* downward */
+
+.requirement-tree_downward {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ margin-left: var(--requirement-tree-downward-margin);
+ box-sizing: border-box;
+
+ font-size: .75rem;
+ line-height: 1.2;
+}
+
+.requirement-tree_downward_node {
+ position: relative;
+ border-left: var(--requirement-tree-downward-line);
+}
+
+.requirement-tree_downward .requirement-tree_downward_node {
+ padding-top: calc(var(--requirement-tree-downward-margin)*0.5);
+}
+
+.requirement-tree_downward .requirement-tree_downward_node:first-child {
+ padding-top: var(--requirement-tree-downward-margin);
+}
+
+.requirement-tree_downward .requirement-tree_downward_node:last-child {
+ border-color: transparent;
+}
+
+.requirement-tree_downward .requirement-tree_downward_node::before {
+ position: absolute;
+ content: '';
+ width: var(--requirement-tree-downward-margin);
+ border-bottom: var(--requirement-tree-downward-line);
+ box-sizing: border-box;
+ top: 0;
+ left: calc(var(--requirement-tree-line-width)*(-1));
+ bottom: calc(100% - var(--requirement-tree-downward-margin)*0.5 - 0.75rem);
+}
+
+.requirement-tree_downward .requirement-tree_downward_node:last-child::before {
+ border-left: var(--requirement-tree-downward-line);
+}
+
+.requirement-tree_downward .requirement-tree_downward_node:first-child::before {
+ bottom: calc(100% - var(--requirement-tree-downward-margin)*1 - 0.75rem);
+}
+
+.requirement-tree_downward_node .requirement-tree_downward_item {
+ position: relative;
+ /* margin-left: calc(var(--requirement-tree-downward-margin) + var(--requirement-tree-downward-string-margin)); */
+ margin-left: calc(var(--requirement-tree-downward-margin) - 0.25rem);
+
+ border-radius: 4px;
+ overflow: clip;
+ border: 1px solid var(--requirement-tree-line-color);
+ background-color: var(--color-bg-main);
+
+ overflow-wrap: break-word;
+}
+
+.requirement-tree_downward_item span,
+.requirement-tree_downward_item a {
+ padding: 4px 6px;
+ display: inline-block;
+ width: 100%;
+ overflow-wrap: break-word;
+}
+
+.requirement-tree_downward_item a {
+ color: var(--color-accent);
+ text-decoration: none;
+}
+
+.requirement-tree_downward_item a:hover {
+ text-decoration: underline;
+}
+
+/* hover */
+
+/* .requirement-tree_node:hover + .requirement-tree::before,
+.requirement-tree_node:hover + .requirement-tree .requirement-tree::before,
+.requirement-tree_node:hover + .requirement-tree .requirement-tree_branch::before,
+.requirement-tree_node:hover + .requirement-tree .requirement-tree_branch::after {
+ border-width: 2px;
+} */
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/requirement__temporary.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/requirement__temporary.css
new file mode 100644
index 0000000..24122fe
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/requirement__temporary.css
@@ -0,0 +1,138 @@
+/* TODO: should be revised and then moved to a permanent location or removed */
+
+/* requirement__title */
+
+.requirement__title {
+ margin: 0;
+ line-height: 1.6;
+ font-weight: bold;
+}
+
+/* requirement: parent / child / file */
+
+ul.requirement__link {
+ font-size: .85rem;
+ line-height: 1.4;
+ list-style: none;
+ padding: 0;
+}
+
+[data-viewtype="source-file"] ul.requirement__link li {
+ margin-top: 0.5rem;
+}
+
+.requirement__link a,
+.requirement__link li > span {
+ display: inline-block;
+ position: relative;
+ margin-left: 1.5rem;
+ width: calc(100% - 1.5rem);
+ overflow-wrap: break-word;
+}
+
+.requirement__link a::before,
+.requirement__link li > span::before {
+ color: #808080;
+ position: absolute;
+ left: -1.5rem;
+}
+
+.requirement__link a:link,
+.requirement__link a:visited {
+ color: var(--color-fg-contrast);
+ text-decoration: none;
+}
+
+.requirement__link a:hover {
+ /* color: var(--color-fg-accent); */
+ text-decoration: underline;
+}
+
+/* .requirement__link a::before {
+ content: '\2014';
+} */
+
+a.requirement__link-file::before,
+.requirement__link-file::before {
+ content: '>';
+}
+
+a.requirement__link-parent::before {
+ content: '\2190';
+}
+
+a.requirement__link-child::before {
+ content: '\2192';
+}
+
+.requirement__link-external::before {
+ content: '\21D6';
+}
+
+.requirement__parent-uid,
+.requirement__child-uid {
+ position: relative;
+ font-weight: bold;
+}
+
+/* switch (injected by JS) */
+
+.std-switch {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+
+ user-select: none;
+ cursor: pointer;
+}
+
+.std-switch input {
+ opacity: 0;
+ width: 0;
+ height: 0;
+ position: absolute;
+}
+
+.std-switch_slider {
+
+ position: relative;
+ cursor: pointer;
+ background-color: #ccc;
+ -webkit-transition: .4s;
+ transition: .4s;
+
+ display: inline-block;
+ width: 44px;
+ height: 26px;
+ margin-right: 10px;
+
+ border-radius: 22px;
+}
+
+.std-switch_slider::before {
+ position: absolute;
+ content: "";
+ height: 18px;
+ width: 18px;
+ left: 4px;
+ bottom: 4px;
+ background-color: white;
+ -webkit-transition: .4s;
+ transition: .4s;
+
+ border-radius: 50%;
+}
+
+input:checked + .std-switch_slider {
+ background-color: rgb(100, 222, 50);
+}
+
+input:focus + .std-switch_slider {
+ box-shadow: 0 0 1px rgb(100, 222, 50);
+}
+
+input:checked + .std-switch_slider:before {
+ -webkit-transform: translateX(18px);
+ -ms-transform: translateX(18px);
+ transform: translateX(18px);
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/resizable_bar.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/resizable_bar.js
new file mode 100644
index 0000000..098482c
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/resizable_bar.js
@@ -0,0 +1,602 @@
+// Expected in element:
+// js-resizable_bar="name"
+// data-state="open|closed"
+// data-position="left|right"
+
+class ResizableBar {
+ constructor({
+ barAttribute,
+ barOpenMinWidth,
+ barOpenMaxWidthRatio,
+ // styles
+ barPadding,
+ barPaddingBottom,
+ barClosedWidth,
+ barHandlerWidth,
+ barColorMain,
+ barColorBackground,
+ barColorActive,
+ barColorBorder,
+ barColorScrollbarTrack,
+ barColorScrollbarThumb,
+ }) {
+ this.barAttribute = barAttribute || 'js-resizable_bar';
+ this.barOpenMaxWidthRatio = barOpenMaxWidthRatio || 0.2;
+ this.barOpenMinWidth = barOpenMinWidth || 77;
+ // styles
+ this.barPadding = barPadding || 'calc(var(--base-rhythm, 8px)*2)';
+ this.barPaddingBottom = barPaddingBottom || 'calc(var(--base-rhythm, 8px)*8)';
+ this.barClosedWidth = barClosedWidth || 12;
+ this.barHandlerWidth = barHandlerWidth || 8;
+ this.barColorMain = barColorMain || 'var(--color-fg-main, Black)';
+ this.barColorBackground = barColorBackground || 'var(--color-bg-main, White)';
+ this.barColorActive = barColorActive || 'var(--color-fg-accent, currentColor)';
+ this.barColorBorder = barColorBorder || 'var(--color-border, rgba(0,0,0,0.1))';
+ this.barColorScrollbarTrack = barColorScrollbarTrack || 'var(--scrollbarBG, transparent)';
+ this.barColorScrollbarThumb = barColorScrollbarThumb || 'var(--thumbBG, rgba(0,0,0,.05))';
+
+ // state
+ this.state = {
+ current: {
+ id: null,
+ direction: null, // 1||-1
+ pageX: null
+ }
+ };
+
+ this.initialState = 'open';
+ this.initialWidth = `${this.barOpenMaxWidthRatio * 100}vw`;
+ this.initialStyle = ``;
+
+ // subscribe
+ const _this = this;
+ this._mouseDownHandler = (e) => {_this._onMouseDown(e)};
+ this._mouseMoveHandler = (e) => {_this._onMouseMove(e)};
+ this._mouseUpHandler = (e) => {_this._onMouseUp(e)};
+ this._toggleHandler = (e) => {_this._toggle(e)};
+ }
+
+ init() {
+ this._insertInitialBarStyle();
+ this._insertInitialPreloaderStyle();
+ }
+
+ render() {
+ this._renderBars();
+ this._insertBarStyle();
+ this._insertPreloaderStyle();
+ }
+
+ // render
+
+ _renderBars() {
+ [...document.querySelectorAll(`[${this.barAttribute}]`)]
+ .forEach((bar) => {
+ const id = bar.getAttribute(this.barAttribute);
+ const position = bar.dataset.position;
+ const direction = (bar.dataset.position === 'left') ? 1 : -1;;
+ const state = this._sessionStorageGetItem(id, 'state') || this.initialState;
+ const width = this._sessionStorageGetItem(id, 'width');
+
+ // Read data from element and from Storage
+ // and set to State:
+ this._setState({
+ id: id,
+ element: bar,
+ position: position,
+ direction: direction,
+ state: state,
+ width: width,
+ });
+
+ // Update Bar with data from Storage:
+ this._updateBar(id);
+
+ // Wrap the bar content in the created scrolling element:
+ const wrapper = this._createScrollableWrapper(id);
+ [ ...bar.childNodes ].forEach(child => wrapper.appendChild(child));
+ bar.appendChild(wrapper);
+
+ // Add control elements:
+ bar.append(this._createHandler(id));
+
+ // Add testID:
+ this._addTestID(bar, id, 'bar');
+ });
+ }
+
+ _adjustWidth(width) {
+ let adjustedWidth = width;
+ const max = window.innerWidth * this.barOpenMaxWidthRatio;
+ if(width && width < this.barOpenMinWidth) {
+ adjustedWidth = this.barOpenMinWidth
+ }
+ if(width && width > max) {
+ adjustedWidth = null;
+ }
+ return adjustedWidth;
+ }
+
+ // session storage
+
+ _sessionStorageGet() {
+ return JSON.parse(sessionStorage.getItem('resizableBarStorage'))
+ }
+
+ _sessionStorageSet(obj) {
+ const string = JSON.stringify(obj);
+ sessionStorage.setItem('resizableBarStorage', string)
+ }
+
+ _sessionStorageGetItem(id, item) {
+ const storage = this._sessionStorageGet();
+ const value = (storage && storage[id]) ? storage[id][item] : null;
+ return value;
+ }
+
+ _sessionStorageSetItem(id, item, value) {
+ let storage = this._sessionStorageGet() || {};
+ storage = {
+ ...storage,
+ [id]: {
+ ...storage[id],
+ [item]: value,
+ },
+ };
+ this._sessionStorageSet(storage);
+ }
+
+ // state
+
+ _setState({
+ id,
+ element,
+ state,
+ position,
+ direction,
+ width,
+ }) {
+ this.state[id] = {
+ element: element,
+ state: state,
+ position: position,
+ direction: direction,
+ width: width,
+ };
+ }
+
+ _updateState({
+ id,
+ element,
+ state,
+ position,
+ direction,
+ width,
+ }) {
+ console.assert(id, '_updateState(): ID must be provided');
+ if (!this.state[id]) { this.state[id] = {} }
+ if (element) { this.state[id].element = element; }
+ if (state) { this.state[id].state = state; }
+ if (position) { this.state[id].position = position; }
+ if (direction) { this.state[id].direction = direction; }
+ if (width || width===null) { this.state[id].width = width; }
+ }
+
+ // current
+
+ _updateCurrent(e) {
+ if (e.type == "mousedown") {
+ // When we start a new resize, we update the currents:
+ this.state.current.id = e.target.dataset.content;
+ this.state.current.pageX = e.pageX;
+ this.state.current.startWidth = this.state[this.state.current.id].element.offsetWidth;
+ } else {
+ // e.type == "mouseup"
+ // At the end of the resize:
+ this.state.current.id = null;
+ this.state.current.pageX = null;
+ this.state.current.startWidth = null;
+ }
+ }
+
+ // elements
+
+ _addTestID(element, id, attr) {
+ element.dataset.testid = `${id}-${attr}`;
+ }
+
+ _updateBar(id) {
+ const barState = this.state[id];
+ const bar = this.state[id].element;
+ bar.dataset.position = barState.position;
+ bar.dataset.state = barState.state;
+ this._updateBarWidth(bar, barState.width);
+ }
+
+ _updateBarWidth(bar, width) {
+ // If there is no specific width, set the maximum.
+ // The style tag cannot be left empty to override the preloaded styles
+ // set for each bar with the width taken from the storage
+ // before the page is rendered.
+ bar.style.width = width ? `${width}px` : `${this.barOpenMaxWidthRatio * 100}vw`;
+ }
+
+ _createHandler(id) {
+ const handler = document.createElement('div');
+ handler.setAttribute(`${this.barAttribute}-handler`, '');
+ handler.dataset.content = id;
+ handler.style[this.state[id].position] = 'unset'; // 'left | right'
+
+ const border = document.createElement('div');
+ border.setAttribute(`${this.barAttribute}-border`, '');
+ border.dataset.content = id;
+ border.title = `Resize ${id}`;
+ border.addEventListener('mousedown', this._mouseDownHandler);
+
+ const button = document.createElement('div');
+ button.setAttribute(`${this.barAttribute}-button`, '');
+ button.dataset.content = id;
+ button.title = `Toggle ${id}`;
+ button.addEventListener('mousedown', this._toggleHandler);
+
+ // Add testIDs:
+ this._addTestID(border, id, 'handler-border');
+ this._addTestID(button, id, 'handler-button');
+
+ handler.append(border, button);
+ return handler;
+ }
+
+ _createScrollableWrapper(id, direction = 'y') {
+ const wrapper = document.createElement('div');
+ wrapper.setAttribute(`${this.barAttribute}-scroll`, direction);
+ wrapper.dataset.content = id;
+ return wrapper;
+ }
+
+ // event listeners
+
+ _onMouseDown(e) {
+ // Init resizing
+ if (e.button == 0) {
+ e.preventDefault();
+ this._updateCurrent(e);
+ window.addEventListener('mousemove', this._mouseMoveHandler);
+ window.addEventListener('mouseup', this._mouseUpHandler);
+ }
+ }
+
+ _onMouseMove(e) {
+ // Resizing
+ const currentId = this.state.current.id;
+ const currentX = this.state.current.pageX;
+ const currentStartWidth = this.state.current.startWidth;
+ const currentBar = this.state[currentId].element;
+
+ // todo: _onMouseUp() does not always stop execution of requestAnimationFrame,
+ // and after the correct width is calculated in _adjustWidth (20vw),
+ // the extreme width from this function can be set again (for ex.: 789px).
+ // requestAnimationFrame(() => {
+
+ // currentId exists if a resize has been initiated
+ if (currentId) {
+
+ // Resize
+ // * delta: the distance traveled by the mouse, starting from the initial point
+ const delta = e.pageX - currentX;
+ // * this.state[currentId].direction = 1 || -1
+ // * w: current bar width
+ this.state.current.width = currentStartWidth + this.state[currentId].direction * delta;
+
+ // Rendering the change in width of the bar:
+ // currentBar.style.width = w + 'px';
+ this._updateBarWidth(currentBar, this.state.current.width);
+
+ // Close/Open
+ if (this.state.current.width < this.barOpenMinWidth) {
+ if (this.state[currentId].state == 'open') {
+ this._close(currentId);
+ }
+ } else {
+ if (this.state[currentId].state == 'closed') {
+ this._open(currentId);
+ }
+ }
+ }
+
+ // })
+ }
+
+ _onMouseUp(e) {
+ // Clean up after work
+ window.removeEventListener('mousemove', this._mouseMoveHandler);
+ window.removeEventListener('mouseup', this._mouseUpHandler);
+
+ const currentWidth = this._adjustWidth(this.state.current.width);
+ this._updateState({ id: this.state.current.id, width: currentWidth });
+ this._sessionStorageSetItem(this.state.current.id, 'width', currentWidth); // WRITE DATA TO STORAGE
+ this._updateBar(this.state.current.id);
+ this._updateCurrent(e);
+ }
+
+ _toggle(e) {
+ if (e.button == 0) {
+ const id = e.target.dataset.content;
+ this.state[id].state = this.state[id].state === 'open'
+ ? 'closed'
+ : 'open';
+ this._sessionStorageSetItem(id, 'state', this.state[id].state);
+ this._updateBar(id);
+ }
+ }
+
+ _open(id) {
+ this.state[id].state = 'open';
+ this._sessionStorageSetItem(id, 'state', this.state[id].state);
+ this._updateBar(id);
+ }
+
+ _close(id) {
+ this.state[id].state = 'closed';
+ this._sessionStorageSetItem(id, 'state', this.state[id].state);
+ this._updateBar(id);
+ }
+
+ // styles
+
+ _insertStyle(css, attr) {
+ const style = document.createElement('style');
+ style.setAttribute(`${this.barAttribute}-${attr}`, '');
+ style.textContent = css;
+ document.head.append(style);
+ }
+
+ _insertInitialBarStyle() {
+ const storage = this._sessionStorageGet();
+
+ let initStyle = `[${this.barAttribute}]{width:${this.barOpenMaxWidthRatio * 100}vw}`;
+
+ // Add styles based on data from Storage:
+ for (let id in storage) {
+ const w = (storage[id].state == 'closed') ? this.barClosedWidth : storage[id].width;
+ // If w = null (this is possible if so in the storage),
+ // the base style will be in effect:
+ w && (initStyle += `[${this.barAttribute}="${id}"]{width:${w}px}`);
+ }
+
+ this._insertStyle(initStyle, 'initial-style')
+ }
+
+ _insertBarStyle() {
+ let barStyle = `
+[${this.barAttribute}] {
+ position: relative;
+ height: 100%;
+ max-width: ${this.barOpenMaxWidthRatio * 100}vw;
+}
+
+[${this.barAttribute}]:hover {
+ z-index: 22;
+}
+
+[${this.barAttribute}][data-state="open"] {
+ min-width: ${this.barOpenMinWidth}px;
+ pointer-events: auto;
+}
+[${this.barAttribute}][data-state="closed"] {
+ max-width: ${this.barClosedWidth}px;
+ min-width: ${this.barClosedWidth}px;
+ pointer-events: none;
+ transition: .5s;
+}
+
+[${this.barAttribute}][data-position="left"] {
+ border-left: none;
+}
+[${this.barAttribute}][data-position="right"] {
+ border-right: none;
+}
+
+[${this.barAttribute}-handler] {
+ pointer-events: auto;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 10;
+ width: ${this.barHandlerWidth}px;
+ color: ${this.barColorActive};
+}
+
+[${this.barAttribute}-border] {
+ pointer-events: auto;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ width: ${this.barHandlerWidth}px;
+ background: transparent;
+ transition: .3s;
+ cursor: col-resize;
+}
+
+[${this.barAttribute}][data-state="closed"] [${this.barAttribute}-border] {
+ cursor: e-resize;
+}
+
+[${this.barAttribute}-border]::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ width: 1px;
+ background: ${this.barColorBorder};
+ transition: .3s;
+}
+
+[${this.barAttribute}-border]::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ width: ${0.5 * this.barHandlerWidth}px;
+ background: transparent;
+ transition: .3s;
+}
+
+[${this.barAttribute}][data-position="left"] [${this.barAttribute}-border]::before {
+ right: 0;
+ left: unset;
+}
+[${this.barAttribute}][data-position="left"] [${this.barAttribute}-border]::after {
+ right: ${-0.25 * this.barHandlerWidth}px;
+ left: unset;
+}
+
+[${this.barAttribute}][data-position="right"] [${this.barAttribute}-border]::before {
+ right: unset;
+ left: 0;
+}
+[${this.barAttribute}][data-position="right"] [${this.barAttribute}-border]::after {
+ right: unset;
+ left: ${-0.25 * this.barHandlerWidth}px;
+}
+
+[${this.barAttribute}-border]:hover::after {
+ background: ${this.barColorActive};
+}
+
+[${this.barAttribute}-button] {
+ cursor: pointer;
+ position: absolute;
+ z-index: 2;
+ left: 0;
+ right: 0;
+ top: ${-1 * this.barHandlerWidth}px;
+ box-sizing: border-box;
+ width: ${2 * this.barHandlerWidth}px;
+ height: ${2 * this.barHandlerWidth}px;
+ font-size: ${1.5 * this.barHandlerWidth}px;
+ font-weight: bold;
+ border-radius: 50%;
+ border-width: 1px;
+ border-style: solid;
+ border-color: ${this.barColorBackground};
+ background: ${this.barColorBackground};
+ color: ${this.barColorActive};
+ transition: .3s;
+}
+
+[data-position="right"] [${this.barAttribute}-button] {
+ right: 0;
+ left: unset;
+}
+[data-position="left"] [${this.barAttribute}-button] {
+ left: 0;
+ right: unset;
+}
+
+[${this.barAttribute}-button]:hover {
+ color: ${this.barColorMain};
+ border-color: ${this.barColorMain};
+}
+
+/* ❮❯ */
+[${this.barAttribute}-button]::after {
+ content: '❮';
+ position: absolute;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ left: 0;
+ right: 0;
+ top: ${-1 * this.barHandlerWidth}px;
+ bottom: ${-1 * this.barHandlerWidth}px;
+}
+[${this.barAttribute}][data-state="open"] [${this.barAttribute}-button]::after,
+[${this.barAttribute}][data-state="open"][data-position="left"] [${this.barAttribute}-button]::after,
+[${this.barAttribute}][data-state="closed"][data-position="right"] [${this.barAttribute}-button]::after {
+ content: '❮';
+}
+[${this.barAttribute}][data-state="closed"] [${this.barAttribute}-button]::after,
+[${this.barAttribute}][data-state="closed"][data-position="left"] [${this.barAttribute}-button]::after,
+[${this.barAttribute}][data-state="open"][data-position="right"] [${this.barAttribute}-button]::after {
+ content: '❯';
+}
+
+[${this.barAttribute}-scroll] {
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ /*padding: ${this.barPadding};
+ padding-bottom: ${this.barPaddingBottom};*/
+ scrollbar-color: ${this.barColorScrollbarTrack} ${this.barColorScrollbarTrack};
+}
+[${this.barAttribute}-scroll='y'] {
+ overflow-x: hidden;
+ overflow-y: scroll;
+}
+[${this.barAttribute}-scroll]:hover {
+ scrollbar-color: ${this.barColorScrollbarThumb} ${this.barColorScrollbarTrack};
+}
+[${this.barAttribute}-scroll]::-webkit-scrollbar-thumb {
+ background-color: ${this.barColorScrollbarTrack};
+}
+[${this.barAttribute}-scroll]:hover::-webkit-scrollbar-thumb {
+ background-color: ${this.barColorScrollbarThumb}
+}
+
+[data-state="closed"] [${this.barAttribute}-scroll] {
+ display: none;
+}
+`;
+
+ this._insertStyle(barStyle, 'style');
+ }
+
+ _insertInitialPreloaderStyle() {
+ let style = `
+ aside {
+ /* for a pseudo preloader [js-resizable_bar]::after, affects: layout_tree,layout_toc */
+ position: relative;
+ }
+ [${this.barAttribute}]::after {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ content: '';
+ position: absolute;
+ left: 0; right: 0; top: 0; bottom: 0;
+ z-index: 2;
+ background-color: ${this.barColorBackground};
+ }
+ `;
+
+ this._insertStyle(style, 'initial-preloader-style');
+ }
+
+ _insertPreloaderStyle() {
+ let style = `
+ [${this.barAttribute}]::after {
+ opacity: 0;
+ transition: .3s;
+ pointer-events: none;
+ }
+ `;
+
+ this._insertStyle(style, 'preloader-style');
+ }
+}
+
+const resizableBar = new ResizableBar({});
+resizableBar.init();
+
+window.addEventListener("load", function () {
+ resizableBar.render();
+});
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_coverage_screen.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_coverage_screen.css
new file mode 100644
index 0000000..16df13a
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_coverage_screen.css
@@ -0,0 +1,283 @@
+.project_coverage {
+ width: 100%;
+ /* font-size: 0.875rem; */
+}
+
+.project_coverage thead {
+ position: sticky;
+ z-index: 1;
+ top: calc(-1 * var(--base-gap)); /* compensate .main top padding when scrolling */
+}
+
+.project_coverage thead th {
+ /* adding a background prevents the th-button background from working */
+ vertical-align: bottom;
+ border-bottom: var(--base-border);
+ font-size: 0.875em;
+}
+
+.project_coverage thead::before {
+ content: '';
+ position: absolute;
+ z-index: -1;
+ left: calc(-1 * var(--base-gap)); /* compensate .main padding to overlap content */
+ right: calc(-1 * var(--base-gap)); /* compensate .main padding to overlap content */
+ top: calc(-1 * var(--base-gap)); /* compensate .main padding to overlap content */
+ bottom: 0;
+ background: var(--color-bg-main);
+}
+
+.project_coverage th,
+.project_coverage td {
+ padding: calc(0.5 * var(--base-rhythm)) var(--base-rhythm);
+ border-right: var(--base-border);
+ position: relative;
+}
+
+.project_coverage td {
+ text-align: right;
+}
+
+.project_coverage th:last-child,
+.project_coverage td:last-child {
+ border-right: none;
+}
+
+.project_coverage tr:first-child th:first-child, /* tr compensate colspan */
+.project_coverage td:first-child {
+ width: auto;
+ text-align: left;
+}
+
+.project_coverage td:not(:first-child) {
+ width: 1px;
+ white-space: nowrap;
+}
+
+.project_coverage tr.project_coverage-file:hover {
+ background: rgba(255,255,255,0.3);
+}
+
+.project_coverage tr.project_coverage-folder td {
+ padding-right: 0;
+}
+
+.project_coverage-folder-title {
+ /* font-weight: bold; */
+ display: flex;
+ align-items: flex-end;
+ column-gap: calc(0.5 * var(--base-rhythm));
+ /* font-size: 0.75em; */
+ line-height: 1;
+ color: #999;
+ padding: calc(0.5 * var(--base-rhythm));
+ position: relative;
+ background: var(--color-bg-secondary);
+}
+
+.project_coverage-file-link {
+ display: flex;
+ /* column-gap: var(--base-rhythm); */
+ padding: calc(0.5 * var(--base-rhythm));
+ border-radius: calc(0.5 * var(--base-rhythm));
+ transition: background .3s;
+ border: 1px solid rgba(255,255,255,0);
+}
+
+.project_coverage-file-icon {}
+
+.project_coverage-file-title {
+ font-size: 1em;
+ font-weight: 500;
+ line-height: 1.2;
+ transition: color .2s;
+ display: flex;
+ column-gap: var(--base-rhythm);
+}
+
+.project_coverage-file-path {
+ font-size: 0.75em;
+ color: var(--color-fg-secondary);
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ display: none;
+}
+
+.project_coverage-file-details {
+ position: relative;
+ flex-grow: 1;
+}
+
+.project_coverage-file-link:not([href]):hover {
+ /* color: gray; */
+ /* all this file have no links -> they are red */
+}
+
+.project_coverage-file_uncovered .project_coverage-file-link,
+.project_coverage-file_uncovered .project_coverage-file-title {
+ color: var(--color-danger);
+ font-weight: 400 !important;
+}
+
+.project_coverage-file-link[href]:hover .project_coverage-file-icon,
+.project_coverage-file-link[href]:hover .project_coverage-file-title {
+ color: var(--color-fg-accent);
+}
+
+.project_coverage-file-link[href] .project_coverage-file-icon,
+.project_coverage-file-link[href] .project_coverage-file-title {
+ color: var(--color-fg-main);
+}
+
+/* cols */
+
+.project_coverage-col-line {
+ background-color: rgba(255, 155, 0, 0.05) !important;
+}
+
+.project_coverage-col-func {
+ background-color: rgba(175, 0, 255, 0.05) !important;
+}
+
+.sorted_col.project_coverage-col-line,
+th.project_coverage-col-line {
+ background-color: rgba(255, 155, 0, 0.15) !important;
+}
+
+.sorted_col.project_coverage-col-func,
+th.project_coverage-col-func {
+ background-color: rgba(175, 0, 255, 0.15) !important;
+}
+
+/* value_extended */
+
+.value_extended[data-ext]::after {
+content: attr(data-ext);
+margin-left: 2px;
+font-size: 0.85em;
+font-weight: 200;
+}
+
+/* project_coverage-sort_handler */
+
+.project_coverage-sort_handler {
+ cursor: pointer;
+}
+
+.project_coverage-sort_handler::after {
+ content: '○';
+ display: block;
+}
+
+.project_coverage-sort_handler::before {
+ content: '';
+ cursor: pointer;
+ position: absolute;
+ inset: 0;
+ z-index: -1;
+}
+
+.project_coverage-sort_handler:hover {
+ color: var(--color-blue);
+}
+
+.project_coverage-sort_handler:hover::before {
+ border: 3px solid white;
+}
+
+.project_coverage-sort_handler[sorted]::before {
+ border: 3px solid white;
+}
+
+/* ▿ ▵ △ ▽ ▾ ▴ */
+
+.project_coverage-sort_handler:hover::after {
+ /* the first act: desc */
+ content: '▽';
+}
+
+.project_coverage-sort_handler[sorted='asc']::after {
+ content: '▴';
+}
+
+.project_coverage-sort_handler[sorted='dsc']::after {
+ content: '▾';
+}
+
+.project_coverage-sort_handler[sorted='dsc']:hover::after {
+ content: '△';
+}
+
+.project_coverage-sort_handler[sorted='asc']:hover::after {
+ content: '▽';
+}
+
+/* sort_reset */
+
+.project_coverage-sort_reset {
+ display: flex;
+ flex-direction: column;
+ gap: var(--base-padding);
+}
+
+.project_coverage-sort_reset::after {
+ content: ' ';
+ display: block;
+}
+
+/* sorted sort_reset */
+
+.project_coverage.sorted .project_coverage-sort_reset {
+ cursor: pointer;
+}
+
+.project_coverage.sorted .project_coverage-sort_reset::after {
+ content: 'reset sorting';
+ font-weight: 400;
+ text-align: right;
+ color: var(--color-fg-accent);
+}
+
+.project_coverage.sorted .project_coverage-sort_reset::before {
+ content: '';
+ cursor: pointer;
+ position: absolute;
+ inset: 0;
+ z-index: -1;
+}
+
+.project_coverage.sorted .project_coverage-sort_reset:hover::before {
+ background-color: rgb(255 255 255 / 50%);
+}
+
+/* sorted mods */
+
+.project_coverage.sorted .project_coverage-folder,
+.project_coverage.sorted .project_coverage-file-indent {
+ display: none;
+}
+
+.project_coverage.sorted .project_coverage-file-path {
+ display: block;
+}
+
+.project_coverage.sorted .project_coverage-file-details {
+ position: relative;
+ flex-grow: 1;
+ padding: 0 0 var(--base-padding) 0;
+}
+
+/* color */
+
+.color-secondary {
+ color: var(--color-fg-secondary);
+}
+
+.color-uncovered {
+ color: var(--color-danger);
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_coverage_screen.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_coverage_screen.js
new file mode 100644
index 0000000..64fbc86
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_coverage_screen.js
@@ -0,0 +1,73 @@
+// @relation(SDOC-SRS-35, scope=file)
+
+document.addEventListener("DOMContentLoaded", () => {
+ const table = document.querySelector(".project_coverage");
+ const tbody = table.querySelector("tbody");
+ const originalRows = Array.from(tbody.rows);
+ let sortState = null;
+
+ const handlers = table.querySelectorAll(".project_coverage-sort_handler");
+ const colgroupCols = table.querySelectorAll("colgroup col");
+
+ handlers.forEach((handler) => {
+ handler.addEventListener("click", () => {
+
+ const dataId = handler.getAttribute("data-id");
+ // We expect:
+ // - Each .project_coverage-sort_handler has a unique data-id
+ // - Each | in sortable rows has matching data-id and data-value
+ // - contains matching the same data-id
+
+ console.assert(dataId, "Missing data-id on sort handler.");
+ if (!dataId) return;
+
+ const isSameColumn = sortState && sortState.id === dataId;
+ const asc = isSameColumn ? !sortState.asc : false;
+
+ const rows = Array.from(tbody.rows);
+ const validRows = rows.filter(row =>
+ row.classList.contains("project_coverage-file") &&
+ row.querySelector(`td[data-id="${dataId}"]`)
+ );
+ if (validRows.length === 0) return;
+
+ validRows.sort((a, b) => {
+ const aCell = a.querySelector(`td[data-id="${dataId}"]`);
+ const bCell = b.querySelector(`td[data-id="${dataId}"]`);
+ const aVal = parseFloat(aCell?.dataset.value || '0');
+ const bVal = parseFloat(bCell?.dataset.value || '0');
+ return asc ? aVal - bVal : bVal - aVal;
+ });
+
+ tbody.innerHTML = "";
+ validRows.forEach(row => tbody.appendChild(row));
+ table.classList.add("sorted");
+
+ handlers.forEach(h => h.removeAttribute("sorted"));
+ handler.setAttribute("sorted", asc ? "asc" : "dsc");
+
+ sortState = { id: dataId, asc };
+
+ // Highlight active
+ colgroupCols.forEach(col => col.classList.remove("sorted_col"));
+ const activeCol = table.querySelector(`colgroup col[data-id="${dataId}"]`);
+ if (activeCol) {
+ activeCol.classList.add("sorted_col");
+ } else {
+ console.warn(`No found for data-id="${dataId}"`);
+ }
+ });
+ });
+
+ const resetter = table.querySelector(".project_coverage-sort_reset");
+ if (resetter) {
+ resetter.addEventListener("click", () => {
+ tbody.innerHTML = "";
+ originalRows.forEach(row => tbody.appendChild(row));
+ table.classList.remove("sorted");
+ handlers.forEach(h => h.removeAttribute("sorted"));
+ colgroupCols.forEach(col => col.classList.remove("sorted_col"));
+ sortState = null;
+ });
+ }
+});
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_file_screen.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_file_screen.css
new file mode 100644
index 0000000..06a393a
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_file_screen.css
@@ -0,0 +1,410 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+
+[data-viewtype="source-file"] {
+ --source-line: 1px solid rgba(0, 0, 0, .05);
+}
+
+[data-viewtype="source-file"] .layout {
+ grid-template-columns:
+ fit-content(var(--base-gap))
+ minmax(222px, 22%) /* replaced: fit-content(20%) */
+ fit-content(20%)
+ minmax(0, 1fr)
+ fit-content(20%)
+ auto;
+ grid-template-areas:
+ "nav header header header header aside"
+ "nav tree bar_left main bar_right aside"
+ "nav footer footer footer footer aside";
+}
+
+/* left panel */
+
+.source-file__aside {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+
+/* left scrollable panel */
+
+.source-file__refer { /* wrapper */
+ position: relative;
+ height: 100%;
+ overflow-y: hidden;
+}
+
+.source-file__toc {
+ position: relative;
+ height: 100%;
+ overflow-y: scroll;
+ padding: calc(var(--base-padding)*2)
+ calc(var(--base-padding) / 2)
+ calc(var(--base-padding)*4)
+ calc(var(--base-padding) / 1);
+
+ font-size: var(--font-size-sm);
+
+ transition: margin-left .5s;
+ scrollbar-color: transparent var(--scrollbarBG);
+}
+
+.source-file__toc:hover {
+ scrollbar-color: var(--thumbBG) var(--scrollbarBG);
+}
+
+.source-file__toc::-webkit-scrollbar-thumb {
+ background-color: transparent;
+}
+
+.source-file__toc:hover::-webkit-scrollbar-thumb {
+ background-color: var(--thumbBG)
+}
+
+.source-file__toc-range {
+ background-color: var(--color-highlight-secondary);
+ border-radius: var(--base-rhythm);
+ margin-bottom: var(--tree-gap);
+}
+
+.source-file__toc-range-header {
+ padding: var(--base-rhythm);
+}
+
+.source-file__toc-range-node {
+ border-top: 2px solid var(--color-bg-main);
+}
+
+.source-file__toc-node {
+ border-top: 1px solid var(--color-border);
+ margin-bottom: 2rem;
+}
+
+/* SDOC-NODE in SOURCE */
+
+.source-file__requirement {
+ position: relative;
+ padding: var(--base-rhythm) 0;
+ transition: background-color 0.3s ease-in, border-color 0.3s ease-in;
+ font-size: var(--font-size-xsm);
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: 0.25rem;
+}
+
+.source-file__requirement-links {
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: 0.25rem;
+ margin-top: var(--base-rhythm);
+}
+
+.source-file__requirement-info {
+ word-break: break-word;
+}
+
+.source-file__requirement-uid {
+ display: block;
+ position: relative;
+ font-weight: bold;
+ word-break: break-word;
+}
+
+.source-file__requirement details {
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: 0.25rem;
+}
+
+.source-file__requirement summary {
+ list-style: none;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+ position: relative;
+ gap: var(--base-rhythm);
+ align-items: flex-start;
+}
+
+.source-file__requirement summary::-webkit-details-marker {
+ display: none;
+}
+
+.source-file__requirement summary::after {
+ content: "➕";
+ user-select: none;
+ padding: calc(var(--base-rhythm) / 2);
+ margin-left: auto;
+ transition: transform 0.2s;
+ font-size: 8px;
+ color: var(--color-link);
+}
+
+.source-file__requirement:hover summary::after {
+ color: var(--color-hover);
+}
+
+.source-file__requirement details[open] summary::after {
+ content: "➖";
+}
+
+.source-file__requirement-header {
+ display: flex;
+ gap: var(--base-rhythm);
+ align-items: flex-start; /* to push action icon to top */
+}
+
+/* requirement_file */
+
+[data-viewtype="source-file"] .requirement_file li {
+ position: relative;
+}
+
+[data-viewtype="source-file"] .requirement_file li > a,
+[data-viewtype="source-file"] .requirement_file li > span {
+ display: inline-block;
+ padding: .15rem .25rem .15rem 0;
+ line-height: 1;
+}
+
+[data-viewtype="source-file"] .current_file_pseudolink {
+ font-weight: bold;
+ color: #808080;
+}
+
+/* CODE */
+
+.source-file__source {
+ /* position: relative; */
+ position: absolute;
+ inset: 0px;
+ left: var(--tree-gap);
+ overflow: auto;
+
+ padding: var(--tree-gap) 0 calc(var(--tree-gap)*10);
+ transition: box-shadow 0.3s ease-in;
+}
+
+.source-file__source .sdoc-table_key_value {
+ /* font-size: var(--font-size-sm); */
+ font-size: 14px;
+ min-width: 100%;
+ margin-bottom: var(--tree-gap);
+}
+
+.source {
+ display: grid;
+ grid-template-columns:
+ minmax(min-content, max-content)
+ minmax(0, 1fr); /* issue#1370 https://css-tricks.com/preventing-a-grid-blowout/ */
+ gap: 0 0;
+ place-items: stretch stretch;
+ transition: transform 0.3s ease-in;
+ position: relative;
+
+ min-width: 100%;
+ width: max-content;
+
+ font-size: 14px;
+ z-index: 1;
+}
+
+.source_highlight {
+ position: absolute;
+ left: 0;
+ right: 0;
+ background-color: var(--color-highlight);
+ z-index: -1;
+ transition: height 0.3s ease-in, top 0.3s ease-in;
+}
+
+/* source__range */
+
+.source__range {
+ grid-column: 1 / -1;
+ display: contents;
+}
+
+.source__range-closer {
+ grid-column: 1 / -1;
+ /* margin-bottom: var(--tree-gap); */
+ margin-bottom: var(--base-padding);
+}
+
+.source__range-closer-label {
+ display: flex;
+ border-radius: 0 0 6px 6px;
+ column-gap: calc(var(--base-rhythm)* 1);
+ background-color: var(--color-highlight-secondary);
+ padding: var(--base-rhythm);
+}
+
+.source__range-closer-label .source__range-definition::before {
+ content: 'End of';
+ display: inline-block;
+ margin-right: 6px;
+}
+
+.focus .source__range:not(.active),
+.focus .source__range-closer:not(.active) {
+ display: none;
+}
+
+.source__range-cell {
+ background-color: var(--color-highlight-secondary);
+}
+
+.source__range-header {
+ grid-column: 1 / -1;
+ background-color: var(--color-highlight-secondary);
+ padding: var(--base-rhythm);
+ margin-top: var(--tree-gap);
+ border-top-left-radius: var(--base-rhythm);
+}
+
+.source__range-button {
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ justify-content: center;
+ height: 100%;
+}
+
+.source__range-banner {
+ padding: 0 1rem 1rem 0;
+}
+
+.source__range.collapsed .source__range-banner {
+ display: none;
+}
+
+ul.source__range-titles-list {
+ margin: var(--base-rhythm);
+ list-style-type: none;
+}
+
+.source__range.collapsed .source__range-titles-list {
+ display: block;
+}
+
+.source__range.expanded .source__range-titles-list {
+ display: none;
+}
+
+.source__range-title-icon {
+ cursor: help;
+}
+
+/* sdoc-node-content */
+
+.source__range-banner sdoc-node-content[node-view="table"] sdoc-node-field-label {
+ background-color: var(--requirement-bg-light-color);
+}
+
+/* source__range-handler */
+
+.source__range-handler {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ height: 100%;
+ color: var(--color-link);
+}
+
+.source__range-handler:hover {
+ color: var(--color-hover);
+}
+
+.source__range .source__range-handler .expanded,
+.source__range.expanded .source__range-handler .collapsed {
+ display: none;
+}
+
+.source__range .source__range-handler .collapsed,
+.source__range.expanded .source__range-handler .expanded {
+ display: unset;
+}
+
+/* source__line */
+
+.source__line {
+ grid-column: 1 / -1;
+ display: contents;
+}
+
+.source.coverage .source__line.covered > div {
+ background: rgba(75, 255, 0, 0.2);
+}
+
+.source__line.highlighted > div {
+ background: var(--color-highlight) !important;
+}
+
+/* line-number */
+
+.source__line-number {
+ grid-column: 1 / 2;
+ padding: 0.25rem 1rem 0.25rem 2rem;
+ text-align: right;
+ border-bottom: var(--source-line);
+ color: var(--color-fg-secondary);
+ background: var(--color-bg-contrast);
+ user-select: none;
+ position: relative;
+}
+
+/* line content */
+
+.source__line-content {
+ grid-column: 2 / 3;
+ padding: 0.25rem 1rem 0.25rem .5rem;
+ border-bottom: var(--source-line);
+ border-left: var(--source-line);
+ background: var(--color-bg-contrast);
+}
+
+/* pointers */
+
+.source__range-pointer {
+ display: inline-block;
+ padding-left: calc(var(--base-rhythm)* 1);
+ padding-right: calc(var(--base-rhythm)* 1);
+ border-radius: 6px;
+}
+
+.source__range-pointer.active {
+ background-color: var(--color-highlight) !important;
+ color: var(--color-fg-contrast) !important;
+}
+
+.focus .source__range-pointer.active {
+ outline: solid 3px yellow;
+}
+
+.source__range-pointer .source__range-pointer_description {
+ font-weight: normal;
+ word-break: break-word;
+}
+
+.source__range-definition {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ max-width: 100%;
+ min-width: 0;
+ display: inline-block;
+}
+
+/* Pygments */
+
+.highlight {
+ background: transparent !important;
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_file_screen.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_file_screen.js
new file mode 100644
index 0000000..8e47e20
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/source_file_screen.js
@@ -0,0 +1,642 @@
+// @relation(SDOC-SRS-36, scope=file)
+
+const __log = (topic, ...payload) => {
+ console.log(`%c ${topic} `, 'background:yellow;color:black',
+ ...payload
+ );
+}
+
+class SimpleTabs {
+ constructor(tabsContainer, tabContentSelector = "sdoc-tab-content") {
+ this.tabsContainer = tabsContainer;
+ this.tabContents = document.querySelectorAll(tabContentSelector);
+ this.tabs = tabsContainer.querySelectorAll("sdoc-tab");
+ this._init();
+ }
+
+ _init() {
+ this.tabs.forEach((tab) => {
+ tab.addEventListener("click", () => {
+ this.activateTab(tab.innerText.trim());
+ });
+ });
+
+ // Activate the tab marked as active, or the first one
+ const activeTab = [...this.tabs].find((t) => t.hasAttribute("active")) || this.tabs[0];
+ this.activateTab(activeTab.innerText.trim());
+ }
+
+ activateTab(tabName) {
+ this.tabs.forEach((tab) => {
+ if (tab.innerText.trim() === tabName) {
+ tab.setAttribute("active", "");
+ } else {
+ tab.removeAttribute("active");
+ }
+ });
+
+ this.tabContents.forEach((content) => {
+ if (content.id === tabName) {
+ content.setAttribute("active", "");
+ } else {
+ content.removeAttribute("active");
+ }
+ });
+ }
+}
+
+class Switch {
+ constructor({
+ callback,
+ labelText,
+ checked,
+ componentClass,
+ colorOn,
+ colorOff,
+ size,
+ stroke,
+ units,
+ alignRight,
+ }) {
+ this.colorOn = colorOn || 'rgb(100, 200, 50)';
+ this.colorOff = colorOff || 'rgb(200, 200, 200)';
+ this.labelText = labelText || '';
+ this.checked = checked || false; // todo: replace true/false with strings
+
+ this.componentClass = componentClass || 'std-switch-scc';
+ this.size = size || 0.75;
+ this.stroke = stroke || 0.25;
+ this.units = units || 'rem';
+ this.alignRight = alignRight || true;
+
+ this.callback = callback;
+ }
+
+ create() {
+ const block = document.createElement('div');
+ block.classList.add(this.componentClass);
+ const label = document.createElement('label');
+ label.classList.add(`${this.componentClass}__label`);
+ const input = document.createElement('input');
+ input.classList.add(`${this.componentClass}__input`);
+ input.type = 'checkbox';
+ input.checked = this.checked;
+ const slider = document.createElement('span');
+ slider.classList.add(`${this.componentClass}__slider`);
+ const text = document.createElement('span');
+ text.innerHTML = this.labelText;
+
+ input.addEventListener('change', () => this.callback(input.checked));
+
+ label.append(input, slider, text);
+ block.append(label);
+ this.insertStyle();
+
+ return block;
+ }
+
+ insertStyle() {
+
+ const css = `
+ .${this.componentClass} {
+ display: inline-block;
+ line-height: 0;
+ }
+ .${this.componentClass}__label {
+ display: inline-flex;
+ gap: ${this.size * 0.5}${this.units};
+ font-size: ${this.size * 1.5}${this.units}; /* 0.75rem; */
+ line-height: ${this.size}${this.units};
+ align-items: center;
+ justify-content: flex-start;
+ user-select: none;
+ cursor: pointer;
+ flex-direction: ${this.alignRight ? "row-reverse" : "row"};
+ text-align: ${this.alignRight ? "right" : "left"};
+ }
+ .${this.componentClass}__input {
+ opacity: 0;
+ width: 0;
+ height: 0;
+ position: absolute;
+ }
+ .${this.componentClass}__slider {
+ position: relative;
+ cursor: pointer;
+ background-color: ${this.colorOff};
+ -webkit-transition: .4s;
+ transition: .4s;
+ display: inline-block;
+ width: ${this.size * 2 + this.stroke * 2}${this.units};
+ height: ${this.size + this.stroke * 2}${this.units};
+ border-radius: ${this.size * 0.5 + this.stroke}${this.units};
+ }
+ .${this.componentClass}__slider::before {
+ position: absolute;
+ content: "";
+ height: ${this.size}${this.units};
+ width: ${this.size}${this.units};
+ left: ${this.stroke}${this.units};
+ bottom: ${this.stroke}${this.units};
+ background-color: white;
+ -webkit-transition: .4s;
+ transition: .4s;
+ border-radius: 50%;
+ }
+ input:checked + .${this.componentClass}__slider {
+ background-color: ${this.colorOn};
+ }
+ input:focus + .${this.componentClass}__slider {
+ box-shadow: 0 0 1px ${this.colorOn};
+ }
+ input:checked + .${this.componentClass}__slider::before {
+ -webkit-transform: translateX(${this.size}${this.units});
+ -ms-transform: translateX(${this.size}${this.units});
+ transform: translateX(${this.size}${this.units});
+ }
+ `;
+
+ const head = document.querySelector('head');
+ const style = document.createElement('style');
+ style.append(document.createTextNode(css));
+ style.setAttribute("data-slider-styles", '');
+ head.append(style);
+ }
+
+}
+
+class Dom {
+ constructor({
+ sourceId,
+ sourceContainerId,
+ referContainerId,
+ hashSplitter,
+ strictdocPointerSelector,
+ strictdocRequirementSelector,
+ strictdocRangeBannerSelector,
+ strictdocRangeBannerHeaderSelector,
+ strictdocRangeHandlerSelector,
+ strictdocRangeCloserSelector,
+ strictdocLineSelector,
+ strictdocLineNumberSelector,
+ strictdocLineContentSelector,
+ strictdocLineRangeSelector,
+ strictdocSourceFilterClass,
+ filteredClass,
+ coveredClass,
+ activeClass,
+ collapsedClass,
+ expandedClass,
+ coverageClass,
+ highlightClass,
+ focusClass,
+ }) {
+
+ // CONSTANTS
+ this.sourceId = sourceId || 'source';
+ this.sourceContainerId = sourceContainerId || 'sourceContainer';
+ this.referContainerId = referContainerId || 'referContainer';
+ this.hashSplitter = hashSplitter || '#';
+
+ // STRICTDOC SPECIFIC
+ this.strictdocPointerSelector = strictdocPointerSelector || '.source__range-pointer';
+ this.strictdocRequirementSelector = strictdocRequirementSelector || '.source-file__requirement';
+ this.strictdocRangeBannerSelector = strictdocRangeBannerSelector || '.source__range';
+ this.strictdocRangeBannerHeaderSelector = strictdocRangeBannerHeaderSelector || '.source__range-header';
+ this.strictdocRangeHandlerSelector = strictdocRangeHandlerSelector || '.source__range-handler';
+ this.strictdocRangeCloserSelector = strictdocRangeCloserSelector || '.source__range-closer';
+ this.strictdocLineSelector = strictdocLineSelector || '.source__line';
+ this.strictdocLineNumberSelector = strictdocLineNumberSelector || '.source__line-number';
+ this.strictdocLineContentSelector = strictdocLineContentSelector || '.source__line-content';
+ this.strictdocLineRangeSelector = strictdocLineRangeSelector || '.source__line-ranges';
+ this.strictdocSourceFilterClass = strictdocSourceFilterClass || 'source__filter';
+ this.filteredClass = filteredClass || 'filtered';
+ this.activeClass = activeClass || 'active';
+ this.coveredClass = coveredClass || 'covered';
+ this.coverageClass = coverageClass || 'coverage';
+ this.collapsedClass = collapsedClass || 'collapsed';
+ this.expandedClass = expandedClass || 'expanded';
+ this.highlightClass = highlightClass || 'highlighted';
+ this.focusClass = focusClass || 'focus';
+
+ // elements
+ this.sourceContainer;
+ this.referContainer;
+ this.source;
+ this.lines = {};
+ this.requirements = {};
+ this.ranges = {};
+ this.closers = {};
+
+ // state
+ this.active = {
+ range: null,
+ pointers: [],
+ labels: [],
+ focus: false,
+ };
+ }
+
+ prepare() {
+ this._prepareSourceContainer();
+ this._prepareReferContainer();
+ this._prepareSource();
+
+ this._prepareLines();
+ this._prepareRanges();
+ this._updateLinesWithRanges();
+ this._updateRangesWithRequirements();
+ this._updateRangesWithHandlers();
+ this._updateRangesWithBanners();
+ this._updateRangesWithClosers();
+
+ // console.log('this.lines', this.lines);
+ // console.log('this.ranges', this.ranges);
+ // console.log('this.closers', this.closers);
+ // console.log('this.requirements', this.requirements);
+ // console.log('this.active', this.active);
+ }
+
+ useLocationHash() {
+ const [_, reqId, rangeBegin, rangeEnd] = window.location.hash.split(this.hashSplitter);
+ const rangeAlias = rangeBegin ? this._generateRangeAlias(rangeBegin, rangeEnd) : undefined;
+
+ this.changeActive({
+ rangeBegin,
+ rangeEnd,
+ rangeAlias,
+ pointers: rangeAlias ? this.ranges[rangeAlias].pointers : null,
+ labels: (reqId && rangeAlias) ? this.ranges[rangeAlias][reqId] : null,
+ });
+
+ this.highlightRange();
+ }
+
+ changeActive = ({
+ rangeBegin,
+ rangeEnd,
+ rangeAlias,
+ pointers,
+ labels,
+ }) => {
+
+ // remove old 'active'
+ this.active.pointers?.forEach(pointer => pointer?.classList.remove(this.activeClass));
+ this.active.labels?.forEach(label => label?.classList.remove(this.activeClass));
+ if (this.active.rangeAlias) {
+ this.ranges[this.active.rangeAlias].banner.classList.remove(this.activeClass);
+
+ const closer = this.closers?.[this.active.rangeEnd];
+ console.assert(
+ closer,
+ "Closer must not be null. One known way of getting this error is " +
+ "when a closing function/range marker is missing and not registered " +
+ "with the file traceability info."
+ );
+
+ closer.classList.remove(this.activeClass);
+ }
+
+ // make changes to state
+ this.active.pointers = pointers;
+ this.active.labels = labels;
+ this.active.rangeBegin = rangeBegin;
+ this.active.rangeEnd = rangeEnd;
+ this.active.rangeAlias = rangeAlias;
+
+ // add new 'active'
+ this.active.pointers?.forEach(pointer => pointer.classList.add(this.activeClass));
+ this.active.labels?.forEach(label => label.classList.add(this.activeClass));
+ this.ranges[rangeAlias]?.banner.classList.add(this.activeClass);
+ this.closers[this.active.rangeEnd]?.classList.add(this.activeClass);
+ }
+
+ toggleRangeBannerVisibility(handler) {
+ const banner = handler.closest(this.strictdocRangeBannerSelector);
+
+ if (banner.classList.contains(this.expandedClass)) {
+ banner.classList.remove(this.expandedClass);
+ banner.classList.add(this.collapsedClass);
+ } else {
+ banner.classList.add(this.expandedClass);
+ banner.classList.remove(this.collapsedClass);
+ }
+ }
+
+ toggleCoverageVisibility(toggler) {
+ if (toggler) {
+ this.source.classList.add(this.coverageClass);
+ } else {
+ this.source.classList.remove(this.coverageClass);
+ }
+ }
+
+ highlightRange() {
+ this.scrollToActiveRangeIfNeeded();
+
+ const begin = parseInt(this.active.rangeBegin, 10);
+ const end = parseInt(this.active.rangeEnd, 10);
+
+ for (var key in this.lines) {
+ this.lines[key].line.classList.remove(this.highlightClass);
+ if (key >= begin && key <= end) {
+ this.lines[key].line.classList.add(this.highlightClass);
+ }
+ }
+ }
+
+ scrollToActiveRangeIfNeeded() {
+ // scroll to highlighted, do not scroll to top when unset highlighting:
+ if (this.active.rangeAlias) {
+ const activeRange = this.ranges[this.active.rangeAlias]?.bannerHeader || 0;
+ requestAnimationFrame(() => {
+ this.scrollTo(activeRange);
+ });
+ }
+ }
+
+ scrollTo(element) {
+ const top = element.offsetTop || 0;
+ this.sourceContainer.scrollTo({
+ top: top,
+ behavior: 'smooth',
+ });
+ }
+
+ _prepareSource() {
+ this.source = document.getElementById(this.sourceId);
+ this.source.style.position = 'relative';
+ this.source.style.zIndex = '1';
+ }
+
+ _prepareSourceContainer() {
+ this.sourceContainer = document.getElementById('sourceContainer');
+ }
+
+ _prepareReferContainer() {
+ this.referContainer = document.getElementById('referContainer');
+ }
+
+ _prepareLines() {
+ this.lines = [...document.querySelectorAll(this.strictdocLineSelector)]
+ .reduce((acc, line) => {
+ const lineNumber = line.querySelector(this.strictdocLineNumberSelector);
+ const lineContent = line.querySelector(this.strictdocLineContentSelector);
+ acc[line.dataset.line] = {
+ line: line,
+ lineNumber: lineNumber,
+ lineContent: lineContent,
+ ranges: []
+ };
+ return acc
+ }, {});
+ }
+
+ _getRangePart(hash) {
+ const parts = hash.split(this.hashSplitter);
+ return `${this.hashSplitter}${parts[parts.length - 2]}${this.hashSplitter}${parts[parts.length - 1]}`;
+ };
+
+ _prepareRanges() {
+ [...document.querySelectorAll(this.strictdocPointerSelector)]
+ .map(pointer => {
+ const thisFileOrOther = pointer.dataset.traceabilityFileType;
+ // consider only references to the current file:
+ if (thisFileOrOther === "other_file") {
+ return;
+ }
+
+ const rangeBegin = pointer.dataset.begin;
+ const rangeEnd = pointer.dataset.end;
+ const rangeReq = pointer.dataset.reqid;
+
+ const range = this._generateRangeAlias(rangeBegin, rangeEnd);
+
+ if (!this.ranges[range]) {
+ // add new range
+ this.ranges[range] = {};
+ this.ranges[range].pointers = [];
+
+ this.ranges[range].beginLine = this.lines[rangeBegin].lineNumber;
+ this.ranges[range].endLine = this.lines[rangeEnd].lineNumber;
+ this.ranges[range].begin = rangeBegin;
+ this.ranges[range].end = rangeEnd;
+ }
+
+ // todo pointers?
+ if (rangeReq) {
+
+ // add pointer from code
+ (this.ranges[range][rangeReq] ??= []).push(pointer);
+
+ } else {
+
+ // add pointer from menu
+ this.ranges[range].pointers.push(pointer);
+ }
+
+ pointer.addEventListener("click", (event) => {
+ const targetHash = `#${rangeReq || ""}${this.hashSplitter}${rangeBegin}${this.hashSplitter}${rangeEnd}`;
+ const currentHash = window.location.hash;
+
+ const isSameHash = currentHash === targetHash;
+ // Buttons linked to requirements include an ID in the hash,
+ // while buttons in the source code do not.
+ // Therefore, only the range part of the hash (e.g., #3#10)
+ // should be compared to identify the currently active range.
+ const isSameRange = this._getRangePart(currentHash) === `${this.hashSplitter}${rangeBegin}${this.hashSplitter}${rangeEnd}`;
+
+ const isModifierPressed = event.metaKey || event.ctrlKey;
+
+ const targetBannerHeader = this.ranges[range]?.bannerHeader;
+ const topBefore = targetBannerHeader?.getBoundingClientRect().top;
+
+ // Modifier click
+ if (isModifierPressed) {
+ event.preventDefault(); // cancel opening a new browser tab
+
+ if (isSameRange) {
+ this._toggleFocus();
+ this._compensateSourceContainerScrollPosition(targetBannerHeader, topBefore);
+ } else {
+ // Sets the URL hash to activate a specific range without reloading the page:
+ window.location.hash = targetHash;
+ this.useLocationHash();
+ this._activateFocus();
+ this._compensateSourceContainerScrollPosition(targetBannerHeader, topBefore);
+ }
+ return;
+ }
+
+ // Normal click
+ if (isSameRange) {
+ // active → reset
+ event.preventDefault();
+ // Removes hash from URL without reloading or adding history entry:
+ history.replaceState(null, '', window.location.pathname);
+ this.useLocationHash();
+ this._clearFocus();
+ this._compensateSourceContainerScrollPosition(targetBannerHeader, topBefore);
+ } else {
+ // inactive → just reset the focus,
+ // the basic functionality via URL will work itself out
+ this._clearFocus();
+ this._compensateSourceContainerScrollPosition(targetBannerHeader, topBefore);
+ }
+ });
+
+ });
+ }
+
+ _compensateSourceContainerScrollPosition(element, topBefore) {
+ // Compensates scroll to keep the given element in the same viewport position.
+ // Expects the element and its initial .getBoundingClientRect().top value as input.
+ // Measures element's top offset relative to the viewport before and after DOM changes.
+ // Uses requestAnimationFrame to wait for DOM/layout updates before measuring again.
+ // Calculates delta = after - before, i.e. how much the element moved visually.
+ // Scrolls by that delta to restore the element's original viewport position.
+ requestAnimationFrame(() => {
+ const topAfter = element?.getBoundingClientRect().top;
+ const delta = topAfter - topBefore;
+ this.sourceContainer.scrollBy({ top: delta });
+ });
+ }
+
+ _toggleFocus() {
+ if (this.active.focus) {
+ this.sourceContainer.classList.remove(this.focusClass);
+ this.referContainer.classList.remove(this.focusClass);
+ } else {
+ this.sourceContainer.classList.add(this.focusClass);
+ this.referContainer.classList.add(this.focusClass);
+ }
+ this.active.focus = !this.active.focus;
+ }
+
+ _activateFocus() {
+ if (!this.active.focus) {
+ this.active.focus = true;
+ this.sourceContainer.classList.add(this.focusClass);
+ this.referContainer.classList.add(this.focusClass);
+ }
+ }
+
+ _clearFocus() {
+ if (this.active.focus) {
+ this.active.focus = false;
+ this.sourceContainer.classList.remove(this.focusClass);
+ this.referContainer.classList.remove(this.focusClass);
+ }
+ }
+
+ _updateRangesWithRequirements() {
+ const requirements = [...document.querySelectorAll(this.strictdocRequirementSelector)];
+ requirements.forEach(requirement => {
+
+ const rangeBegin = requirement.dataset.begin;
+ const rangeEnd = requirement.dataset.end;
+ const rangeReq = requirement.dataset.reqid;
+
+ if (rangeEnd && rangeBegin) {
+ const range = this._generateRangeAlias(rangeBegin, rangeEnd);
+ console.assert(this.ranges[range], "The range must be registered:", range);
+
+ (this.ranges[range].requirements ??= {})[rangeReq] = {};
+ this.ranges[range].requirements[rangeReq].begin = rangeBegin;
+ this.ranges[range].requirements[rangeReq].end = rangeEnd;
+ this.ranges[range].requirements[rangeReq].element = requirement;
+ } else {
+ this.requirements[rangeReq] = requirement;
+ }
+
+
+ })
+ }
+
+ _updateRangesWithHandlers() {
+ const handlers = [...document.querySelectorAll(this.strictdocRangeHandlerSelector)];
+ handlers.forEach(handler => {
+
+ const rangeBegin = handler.dataset.begin;
+ const rangeEnd = handler.dataset.end;
+ const range = this._generateRangeAlias(rangeBegin, rangeEnd);
+
+ console.assert(this.ranges[range], "The range must be registered:", range);
+
+ this.ranges[range].handler = handler;
+ handler.addEventListener("click", event => this.toggleRangeBannerVisibility(event.currentTarget));
+ })
+ }
+
+ _updateRangesWithBanners() {
+ const banners = [...document.querySelectorAll(this.strictdocRangeBannerSelector)];
+ banners.forEach(banner => {
+
+ const rangeBegin = banner.dataset.begin;
+ const rangeEnd = banner.dataset.end;
+
+ if (rangeBegin && rangeEnd) {
+ const range = this._generateRangeAlias(rangeBegin, rangeEnd);
+ console.assert(this.ranges[range], "The range must be registered:", range);
+ this.ranges[range].banner = banner;
+ this.ranges[range].bannerHeader = banner.querySelector(this.strictdocRangeBannerHeaderSelector); // 'source__range-header'
+ }
+ })
+ }
+
+ _updateRangesWithClosers() {
+ const closers = [...document.querySelectorAll(this.strictdocRangeCloserSelector)];
+ closers.forEach(closer => {
+
+ const rangeEnd = closer.dataset.end;
+
+ if (rangeEnd) {
+ this.closers[rangeEnd] = closer;
+ }
+ })
+ }
+
+ _updateLinesWithRanges() {
+ Object.entries(this.ranges).forEach(([key, value]) => {
+ const begin = parseInt(value.begin, 10);
+ const end = parseInt(value.end, 10);
+
+ for (let i = begin; i <= end; i++) {
+ (this.lines[i].ranges ??= []).push(key);
+ (this.lines[i].pointers ??= []).push(...value.pointers);
+
+ console.assert(this.lines[i].lineNumber, `The line ${i} must be registered.`);
+ this.lines[i].lineNumber.classList.add(this.strictdocSourceFilterClass);
+ this.lines[i].line.classList.add(this.coveredClass);
+ }
+ });
+ }
+
+ _generateRangeAlias(begin, end) { return `${begin}${this.hashSplitter}${end}` };
+}
+
+const dom = new Dom({});
+
+window.addEventListener("load", function () {
+ dom.prepare();
+ dom.useLocationHash();
+
+ const switcher = new Switch(
+ {
+ labelText: 'Show coverage',
+ size: 0.5,
+ stroke: 0.2,
+ checked: false,
+ callback: (checked) => dom.toggleCoverageVisibility(checked),
+ }
+ );
+ document.getElementById('sourceCodeCoverageSwitch').append(switcher.create());
+
+ const tabsContainer = document.querySelector("sdoc-tabs");
+ if (tabsContainer) {
+ new SimpleTabs(tabsContainer);
+ }
+
+});
+
+window.addEventListener("hashchange", () => dom.useLocationHash());
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/stable_uri_forwarder.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/stable_uri_forwarder.js
new file mode 100644
index 0000000..fcabf7f
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/stable_uri_forwarder.js
@@ -0,0 +1,99 @@
+// stable_uri_forwarder.js
+//
+// This script is included from the project's index.html page (in static HTML export)
+// It checks for a known MID or UID in the #anchor, and then
+// redirects to the referenced section or node within the project.
+//
+// Example:
+// http://strictdoc.company.com/#SDOC_UG will redirect to
+// http://strictdoc.company.com/strictdoc/docs/strictdoc_01_user_guide.html#SDOC_UG
+//
+// Thanks to this mechanism, it becomes possible to export stable links to
+// nodes/requirements/sections for integration with external tools.
+// The external links remain stable, even if the node/requirement/section is moved
+// within the project.
+
+
+// Resolve the MID / UID to the correct page / anchor using the projectMap.
+function resolveStableUriRedirectUsingProjectMap(anchor) {
+ for (const [page, nodes] of Object.entries(projectMap)) {
+ for (const node of nodes) {
+ if (node['_LINK'].toLowerCase() === anchor.toLowerCase()) {
+ window.location.replace(page + "#" + node['_LINK']);
+ return;
+ }
+
+ const nodeHasUID = 'UID' in node && typeof node['UID'] === 'string';
+ if (nodeHasUID && node['UID'].toLowerCase() === anchor.toLowerCase()) {
+ window.location.replace(page + "#" + node['_LINK']);
+ return;
+ }
+
+ const nodeHasMID = 'MID' in node && typeof node['MID'] === 'string';
+ if (nodeHasMID && node['MID'].toLowerCase() === anchor.toLowerCase()) {
+ window.location.replace(page + "#" + node['_LINK']);
+ return;
+ }
+ }
+ }
+}
+
+// Dynamically load the projectMap an resolve MID / UID.
+function loadProjectMapAndResolveStableUriRedirect(anchor) {
+
+ // ProjectMap is loaded, no need to load it again.
+ if (typeof projectMap !== 'undefined') {
+ resolveStableUriRedirectUsingProjectMap(anchor);
+ return;
+ }
+
+ // Get script URL and derive from it the url of project_map.js
+ const scriptUrl = new URL(document.getElementById("stable_uri_forwarder").src, window.location
+ .href)
+ const projectMapUrl = new URL('project_map.js', scriptUrl).href;
+
+ // Dynamically load project map and resolve
+ const script = document.createElement("script");
+ script.src = projectMapUrl;
+ script.onload = () => resolveStableUriRedirectUsingProjectMap(anchor);
+ script.onerror = () => {
+ console.error(`Failed to load project map from ${projectMapUrl}`);
+ };
+ document.head.appendChild(script);
+}
+
+function processStableUriRedirect(anchor) {
+ const exportType = document.querySelector('meta[name="strictdoc-export-type"]')?.content;
+
+ if (exportType === 'webserver') {
+ // For the web server, we let the main_router.py dynamically forward UID to node.
+ window.location.replace("/UID/" + anchor);
+ } else if (exportType === 'static') {
+ // For static exports, we use the project_map.js.
+ loadProjectMapAndResolveStableUriRedirect(anchor)
+ }
+}
+
+
+// In case an anchor is present at content load time.
+document.addEventListener("DOMContentLoaded", () => {
+ const anchorParam = new URLSearchParams(window.location.search).get("a");
+ if (anchorParam) {
+ processStableUriRedirect(anchorParam)
+ return
+ }
+
+ // for legacy link support
+ const anchorHash = window.location.hash.substring(1);
+ if (anchorHash) {
+ processStableUriRedirect(anchorHash)
+ }
+});
+
+// In case an anchor is added manually afterwards (eases testing).
+window.addEventListener("hashchange", () => {
+ const anchor = window.location.hash.substring(1);
+ if (anchor) {
+ processStableUriRedirect(anchor)
+ }
+});
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/stimulus_umd.min.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/stimulus_umd.min.js
new file mode 100644
index 0000000..0df2936
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/stimulus_umd.min.js
@@ -0,0 +1,5 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Stimulus={})}(this,function(e){"use strict";class K{constructor(e,t,r){this.eventTarget=e,this.eventName=t,this.eventOptions=r,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){var t=function(t){{if("immediatePropagationStopped"in t)return t;{let e=t.stopImmediatePropagation;return Object.assign(t,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,e.call(this)}})}}}(e);for(const r of this.bindings){if(t.immediatePropagationStopped)break;r.handleEvent(t)}}hasBindings(){return 0{e=e.index,t=t.index;return ee.connect()))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach(e=>e.disconnect()))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce((e,t)=>e.concat(Array.from(t.values())),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=!1){this.fetchEventListenerForBinding(e).bindingDisconnected(e),t&&this.clearEventListenersForBinding(e)}handleError(e,t,r={}){this.application.handleError(e,"Error "+t,r)}clearEventListenersForBinding(e){var t=this.fetchEventListenerForBinding(e);t.hasBindings()||(t.disconnect(),this.removeMappedEventListenerFor(e))}removeMappedEventListenerFor(e){var{eventTarget:e,eventName:t,eventOptions:r}=e,s=this.fetchEventListenerMapForEventTarget(e),t=this.cacheKey(t,r);s.delete(t),0==s.size&&this.eventListenerMaps.delete(e)}fetchEventListenerForBinding(e){var{eventTarget:e,eventName:t,eventOptions:r}=e;return this.fetchEventListener(e,t,r)}fetchEventListener(e,t,r){var s=this.fetchEventListenerMapForEventTarget(e),i=this.cacheKey(t,r);let n=s.get(i);return n||(n=this.createEventListener(e,t,r),s.set(i,n)),n}createEventListener(e,t,r){e=new K(e,t,r);return this.started&&e.connect(),e}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const r=[e];return Object.keys(t).sort().forEach(e=>{r.push((t[e]?"":"!")+e)}),r.join(":")}}const j={stop({event:e,value:t}){return t&&e.stopPropagation(),!0},prevent({event:e,value:t}){return t&&e.preventDefault(),!0},self({event:e,value:t,element:r}){return!t||r===e.target}},$=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function U(e){var t,e=e.trim().match($)||[];let r=e[2],s=e[3];return s&&!["keydown","keyup","keypress"].includes(r)&&(r+="."+s,s=""),{eventTarget:"window"==(t=e[4])?window:"document"==t?document:void 0,eventName:r,eventOptions:e[7]?e[7].split(":").reduce((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)}),{}):{},identifier:e[5],methodName:e[6],keyFilter:e[1]||s}}function a(e){return e.replace(/(?:[_-])([a-z0-9])/g,(e,t)=>t.toUpperCase())}function s(e){return a(e.replace(/--/g,"-").replace(/__/g,"_"))}function l(e){return e.charAt(0).toUpperCase()+e.slice(1)}function h(e){return e.replace(/([A-Z])/g,(e,t)=>"-"+t.toLowerCase())}function c(e){return null!=e}function u(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const o=["meta","ctrl","alt","shift"];class P{constructor(e,t,r,s){this.element=e,this.index=t,this.eventTarget=r.eventTarget||e,this.eventName=r.eventName||function(e){var t=e.tagName.toLowerCase();if(t in i)return i[t](e)}(e)||n("missing event name"),this.eventOptions=r.eventOptions||{},this.identifier=r.identifier||n("missing identifier"),this.methodName=r.methodName||n("missing method name"),this.keyFilter=r.keyFilter||"",this.schema=s}static forToken(e,t){return new this(e.element,e.index,U(e.content),t)}toString(){var e=this.keyFilter?"."+this.keyFilter:"",t=this.eventTargetName?"@"+this.eventTargetName:"";return this.eventName+e+t+`->${this.identifier}#`+this.methodName}shouldIgnoreKeyboardEvent(e){var t;return!!this.keyFilter&&(t=this.keyFilter.split("+"),!!this.keyFilterDissatisfied(e,t)||!!(t=t.filter(e=>!o.includes(e))[0])&&(u(this.keyMappings,t)||n("contains unknown key filter: "+this.keyFilter),this.keyMappings[t].toLowerCase()!==e.key.toLowerCase()))}shouldIgnoreMouseEvent(e){var t;return!!this.keyFilter&&(t=[this.keyFilter],!!this.keyFilterDissatisfied(e,t))}get params(){var e,t,r={},s=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for({name:e,value:t}of Array.from(this.element.attributes)){var i=e.match(s),i=i&&i[1];i&&(r[a(i)]=function(t){try{return JSON.parse(t)}catch(e){return t}}(t))}return r}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(e,t){var[r,s,i,n]=o.map(e=>t.includes(e));return e.metaKey!==r||e.ctrlKey!==s||e.altKey!==i||e.shiftKey!==n}}const i={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function n(e){throw new Error(e)}class R{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){var t=this.prepareActionEvent(e);this.willBeInvokedByEvent(e)&&this.applyEventModifiers(t)&&this.invokeWithEvent(t)}get eventName(){return this.action.eventName}get method(){var e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){var t,r,s,i=this.action.element,n=this.context.application.actionDescriptorFilters,o=this.context.controller;let a=!0;for([t,r]of Object.entries(this.eventOptions))t in n&&(s=n[t],a=a&&s({name:t,value:r,event:e,element:i,controller:o}));return a}prepareActionEvent(e){return Object.assign(e,{params:this.action.params})}invokeWithEvent(t){var{target:r,currentTarget:s}=t;try{this.method.call(this.controller,t),this.context.logDebugActivity(this.methodName,{event:t,target:r,currentTarget:s,action:this.methodName})}catch(e){var{identifier:r,controller:s,element:i,index:n}=this;this.context.handleError(e,`invoking action "${this.action}"`,{identifier:r,controller:s,element:i,index:n,event:t})}}willBeInvokedByEvent(e){var t=e.target;return!(e instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(e)||e instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element)))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class d{constructor(e,t){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}pause(e){this.started&&(this.mutationObserver.disconnect(),this.started=!1),e(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){var e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const r of Array.from(e))this.addElement(r)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){this.elements.has(e)?this.delegate.elementAttributeChanged&&this.matchElement(e)?this.delegate.elementAttributeChanged(e,t):this.removeElement(e):this.matchElement(e)&&this.addElement(e)}processRemovedNodes(e){for(const r of Array.from(e)){var t=this.elementFromNode(r);t&&this.processTree(t,this.removeElement)}}processAddedNodes(e){for(const r of Array.from(e)){var t=this.elementFromNode(r);t&&this.elementIsActive(t)&&this.processTree(t,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const r of this.matchElementsInTree(e))t.call(this,r)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched)&&this.delegate.elementMatched(e)}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched)&&this.delegate.elementUnmatched(e)}}class m{constructor(e,t,r){this.attributeName=t,this.delegate=r,this.elementObserver=new d(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){var t=this.matchElement(e)?[e]:[],e=Array.from(e.querySelectorAll(this.selector));return t.concat(e)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function r(e,t,r){p(e,t).add(r)}function g(e,t,r){p(e,t).delete(r),f(e,t)}function p(e,t){let r=e.get(t);return r||(r=new Set,e.set(t,r)),r}function f(e,t){var r=e.get(t);null!=r&&0==r.size&&e.delete(t)}class v{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e.concat(Array.from(t)),[])}get size(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e+t.size,0)}add(e,t){r(this.valuesByKey,e,t)}delete(e,t){g(this.valuesByKey,e,t)}has(e,t){e=this.valuesByKey.get(e);return null!=e&&e.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(t){return Array.from(this.valuesByKey.values()).some(e=>e.has(t))}getValuesForKey(e){e=this.valuesByKey.get(e);return e?Array.from(e):[]}getKeysForValue(t){return Array.from(this.valuesByKey).filter(([,e])=>e.has(t)).map(([e])=>e)}}class z extends v{constructor(){super(),this.keysByValue=new Map}get values(){return Array.from(this.keysByValue.keys())}add(e,t){super.add(e,t),r(this.keysByValue,t,e)}delete(e,t){super.delete(e,t),g(this.keysByValue,t,e)}hasValue(e){return this.keysByValue.has(e)}getKeysForValue(e){e=this.keysByValue.get(e);return e?Array.from(e):[]}}class b{constructor(e,t,r,s){this._selector=t,this.details=s,this.elementObserver=new d(e,this),this.delegate=r,this.matchesByElement=new v}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(e){this._selector=e,this.refresh()}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){var t=this.selector;return!!t&&(t=e.matches(t),this.delegate.selectorMatchElement?t&&this.delegate.selectorMatchElement(e,this.details):t)}matchElementsInTree(e){var t,r=this.selector;return r?(t=this.matchElement(e)?[e]:[],e=Array.from(e.querySelectorAll(r)).filter(e=>this.matchElement(e)),t.concat(e)):[]}elementMatched(e){var t=this.selector;t&&this.selectorMatched(e,t)}elementUnmatched(e){for(const t of this.matchesByElement.getKeysForValue(e))this.selectorUnmatched(e,t)}elementAttributeChanged(e,t){var r,s,i=this.selector;i&&(r=this.matchElement(e),s=this.matchesByElement.has(i,e),r&&!s?this.selectorMatched(e,i):!r&&s&&this.selectorUnmatched(e,i))}selectorMatched(e,t){this.delegate.selectorMatched(e,t,this.details),this.matchesByElement.add(t,e)}selectorUnmatched(e,t){this.delegate.selectorUnmatched(e,t,this.details),this.matchesByElement.delete(t,e)}}class y{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){var t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){var r=this.delegate.getStringMapKeyForAttribute(e);if(null!=r){this.stringMap.has(e)||this.stringMapKeyAdded(r,e);var s=this.element.getAttribute(e);if(this.stringMap.get(e)!=s&&this.stringMapValueChanged(s,r,t),null==s){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(r,e,t)}else this.stringMap.set(e,s)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,r){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,r)}stringMapKeyRemoved(e,t,r){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,r)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map(e=>e.name)}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class O{constructor(e,t,r){this.attributeObserver=new m(e,t,this),this.delegate=r,this.tokensByElement=new v}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){var[e,t]=this.refreshTokensForElement(e);this.tokensUnmatched(e),this.tokensMatched(t)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach(e=>this.tokenMatched(e))}tokensUnmatched(e){e.forEach(e=>this.tokenUnmatched(e))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){var r,s,t=this.tokensByElement.getValuesForKey(e),e=this.readTokensForElement(e),i=(r=t,s=e,i=Math.max(r.length,s.length),Array.from({length:i},(e,t)=>[r[t],s[t]]).findIndex(([e,t])=>{return t=t,!((e=e)&&t&&e.index==t.index&&e.content==t.content)}));return-1==i?[[],[]]:[t.slice(i),e.slice(i)]}readTokensForElement(e){var r,s,t=this.attributeName,i=e.getAttribute(t)||"";return r=e,s=t,i.trim().split(/\s+/).filter(e=>e.length).map((e,t)=>({element:r,attributeName:s,content:e,index:t}))}}class A{constructor(e,t,r){this.tokenListObserver=new O(e,t,this),this.delegate=r,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){var t=e.element,r=this.fetchParseResultForToken(e).value;r&&(this.fetchValuesByTokenForElement(t).set(e,r),this.delegate.elementMatchedValue(t,r))}tokenUnmatched(e){var t=e.element,r=this.fetchParseResultForToken(e).value;r&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,r))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class _{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new A(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){var t=new R(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){var t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach(e=>this.delegate.bindingDisconnected(e,!0)),this.bindingsByAction.clear()}parseValueForToken(e){e=P.forToken(e,this.schema);if(e.identifier==this.identifier)return e}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class q{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new y(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){t=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,t.writer(this.receiver[e]),t.writer(t.defaultValue))}stringMapValueChanged(e,t,r){var s=this.valueDescriptorNameMap[t];null!==e&&(null===r&&(r=s.writer(s.defaultValue)),this.invokeChangedCallback(t,e,r))}stringMapKeyRemoved(e,t,r){var s=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,s.writer(this.receiver[e]),r):this.invokeChangedCallback(e,s.writer(s.defaultValue),r)}invokeChangedCallbacksForDefaultValues(){for(var{key:e,name:t,defaultValue:r,writer:s}of this.valueDescriptors)null==r||this.controller.data.has(e)||this.invokeChangedCallback(t,s(r),void 0)}invokeChangedCallback(t,r,s){var i=this.receiver[t+"Changed"];if("function"==typeof i){t=this.valueDescriptorNameMap[t];try{var n=t.reader(r);let e=s;s&&(e=t.reader(s)),i.call(this.receiver,n,e)}catch(e){throw e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${t.name}" - `+e.message),e}}}get valueDescriptors(){let t=this.valueDescriptorMap;return Object.keys(t).map(e=>t[e])}get valueDescriptorNameMap(){const t={};return Object.keys(this.valueDescriptorMap).forEach(e=>{e=this.valueDescriptorMap[e];t[e.name]=e}),t}hasValue(e){e="has"+l(this.valueDescriptorNameMap[e].name);return this.receiver[e]}}class W{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new v}start(){this.tokenListObserver||(this.tokenListObserver=new O(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var r;this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),null!=(r=this.tokenListObserver)&&r.pause(()=>this.delegate.targetConnected(e,t)))}disconnectTarget(e,t){var r;this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),null!=(r=this.tokenListObserver))&&r.pause(()=>this.delegate.targetDisconnected(e,t))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function E(e,r){e=t(e);return Array.from(e.reduce((t,e)=>(function(e,t){e=e[t];return Array.isArray(e)?e:[]}(e,r).forEach(e=>t.add(e)),t),new Set))}function J(e,r){return t(e).reduce((e,t)=>(e.push(...function(e,t){const r=e[t];return r?Object.keys(r).map(e=>[e,r[e]]):[]}(t,r)),e),[])}function t(e){for(var t=[];e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}class H{constructor(e,t){this.started=!1,this.context=e,this.delegate=t,this.outletsByName=new v,this.outletElementsByName=new v,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}start(){this.started||(this.outletDefinitions.forEach(e=>{this.setupSelectorObserverForOutlet(e),this.setupAttributeObserverForOutlet(e)}),this.started=!0,this.dependentContexts.forEach(e=>e.refresh()))}refresh(){this.selectorObserverMap.forEach(e=>e.refresh()),this.attributeObserverMap.forEach(e=>e.refresh())}stop(){this.started&&(this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers())}stopSelectorObservers(){0e.stop()),this.selectorObserverMap.clear())}stopAttributeObservers(){0e.stop()),this.attributeObserverMap.clear())}selectorMatched(e,t,{outletName:r}){var s=this.getOutlet(e,r);s&&this.connectOutlet(s,e,r)}selectorUnmatched(e,t,{outletName:r}){var s=this.getOutletFromMap(e,r);s&&this.disconnectOutlet(s,e,r)}selectorMatchElement(e,{outletName:t}){var r=this.selector(t),s=this.hasOutlet(e,t),t=e.matches(`[${this.schema.controllerAttribute}~=${t}]`);return!!r&&s&&t&&e.matches(r)}elementMatchedAttribute(e,t){t=this.getOutletNameFromOutletAttributeName(t);t&&this.updateSelectorObserverForOutlet(t)}elementAttributeValueChanged(e,t){t=this.getOutletNameFromOutletAttributeName(t);t&&this.updateSelectorObserverForOutlet(t)}elementUnmatchedAttribute(e,t){t=this.getOutletNameFromOutletAttributeName(t);t&&this.updateSelectorObserverForOutlet(t)}connectOutlet(e,t,r){var s;this.outletElementsByName.has(r,t)||(this.outletsByName.add(r,e),this.outletElementsByName.add(r,t),null!=(s=this.selectorObserverMap.get(r))&&s.pause(()=>this.delegate.outletConnected(e,t,r)))}disconnectOutlet(e,t,r){var s;this.outletElementsByName.has(r,t)&&(this.outletsByName.delete(r,e),this.outletElementsByName.delete(r,t),null!=(s=this.selectorObserverMap.get(r)))&&s.pause(()=>this.delegate.outletDisconnected(e,t,r))}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const r of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(r,t,e)}updateSelectorObserverForOutlet(e){var t=this.selectorObserverMap.get(e);t&&(t.selector=this.selector(e))}setupSelectorObserverForOutlet(e){var t=this.selector(e),t=new b(document.body,t,this,{outletName:e});this.selectorObserverMap.set(e,t),t.start()}setupAttributeObserverForOutlet(e){var t=this.attributeNameForOutletName(e),t=new m(this.scope.element,t,this);this.attributeObserverMap.set(e,t),t.start()}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}attributeNameForOutletName(e){return this.scope.schema.outletAttributeForScope(this.identifier,e)}getOutletNameFromOutletAttributeName(t){return this.outletDefinitions.find(e=>this.attributeNameForOutletName(e)===t)}get outletDependencies(){const r=new v;return this.router.modules.forEach(t=>{E(t.definition.controllerConstructor,"outlets").forEach(e=>r.add(e,t.identifier))}),r}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const t=this.dependentControllerIdentifiers;return this.router.contexts.filter(e=>t.includes(e.identifier))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(t,e){return this.outletsByName.getValuesForKey(e).find(e=>e.element===t)}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class M{constructor(e,t){this.logDebugActivity=(e,t={})=>{var{identifier:r,controller:s,element:i}=this;t=Object.assign({identifier:r,controller:s,element:i},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new _(this,this.dispatcher),this.valueObserver=new q(this,this.controller),this.targetObserver=new W(this,this),this.outletObserver=new H(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,r={}){var{identifier:s,controller:i,element:n}=this;r=Object.assign({identifier:s,controller:i,element:n},r),this.application.handleError(e,"Error "+t,r)}targetConnected(e,t){this.invokeControllerMethod(t+"TargetConnected",e)}targetDisconnected(e,t){this.invokeControllerMethod(t+"TargetDisconnected",e)}outletConnected(e,t,r){this.invokeControllerMethod(s(r)+"OutletConnected",e,t)}outletDisconnected(e,t,r){this.invokeControllerMethod(s(r)+"OutletDisconnected",e,t)}invokeControllerMethod(e,...t){var r=this.controller;"function"==typeof r[e]&&r[e](...t)}}function Z(e){return r=E(n=e=e,"blessings"),r=r.reduce((e,t)=>{var r=t(n);for(const i in r){var s=e[i]||{};e[i]=Object.assign(s,r[i])}return e},{}),t=Q(e),e=function(s,i){return G(i).reduce((e,t)=>{var r=function(e,t,r){var e=Object.getOwnPropertyDescriptor(e,r),s=e&&"value"in e;if(!s)return s=Object.getOwnPropertyDescriptor(t,r).value,e&&(s.get=e.get||s.get,s.set=e.set||s.set),s}(s,i,t);return r&&Object.assign(e,{[t]:r}),e},{})}(e.prototype,r),Object.defineProperties(t.prototype,e),t;var t,n,r}const G="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,Q=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return(t=e(function(){this.a.call(this)})).prototype.a=function(){},new t,e}catch(e){return e=>class extends e{}}var t})();class X{constructor(e,t){this.application=e,this.definition={identifier:t.identifier,controllerConstructor:Z(t.controllerConstructor)},this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){e=this.fetchContextForScope(e);this.connectedContexts.add(e),e.connect()}disconnectContextForScope(e){e=this.contextsByScope.get(e);e&&(this.connectedContexts.delete(e),e.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new M(this,e),this.contextsByScope.set(e,t)),t}}class Y{constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){return(this.data.get(this.getDataKey(e))||"").match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return e+"-class"}get data(){return this.scope.data}}class ee{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){e=this.getAttributeNameForKey(e);return this.element.getAttribute(e)}set(e,t){var r=this.getAttributeNameForKey(e);return this.element.setAttribute(r,t),this.get(e)}has(e){e=this.getAttributeNameForKey(e);return this.element.hasAttribute(e)}delete(e){return!!this.has(e)&&(e=this.getAttributeNameForKey(e),this.element.removeAttribute(e),!0)}getAttributeNameForKey(e){return`data-${this.identifier}-`+h(e)}}class te{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,r){let s=this.warnedKeysByObject.get(e);s||(s=new Set,this.warnedKeysByObject.set(e,s)),s.has(t)||(s.add(t),this.logger.warn(r,e))}}function w(e,t){return`[${e}~="${t}"]`}class re{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)],[])}findTarget(e){e=this.getSelectorForTargetName(e);return this.scope.findElement(e)}findAllTargets(e){e=this.getSelectorForTargetName(e);return this.scope.findAllElements(e)}getSelectorForTargetName(e){return w(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){var t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(t){var e=this.getLegacySelectorForTargetName(t);return this.scope.findAllElements(e).map(e=>this.deprecate(e,t))}getLegacySelectorForTargetName(e){e=this.identifier+"."+e;return w(this.schema.targetAttribute,e)}deprecate(e,t){var r,s,i;return e&&(r=this.identifier,s=this.schema.targetAttribute,i=this.schema.targetAttributeForScope(r),this.guide.warn(e,"target:"+t,`Please replace ${s}="${r}.${t}" with ${i}="${t}". `+`The ${s} attribute is deprecated and will be removed in a future version of Stimulus.`)),e}get guide(){return this.scope.guide}}class se{constructor(e,t){this.scope=e,this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findOutlet(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllOutlets(t)],[])}getSelectorForOutletName(e){e=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(e)}findOutlet(e){var t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){var t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(t,r){return this.scope.queryElements(t).filter(e=>this.matchesElement(e,t,r))[0]}findAllElements(t,r){return this.scope.queryElements(t).filter(e=>this.matchesElement(e,t,r))}matchesElement(e,t,r){var s=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&s.split(" ").includes(r)}}class k{constructor(e,t,r,s){this.targets=new re(this),this.classes=new Y(this),this.data=new ee(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=r,this.guide=new te(s),this.outlets=new se(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return w(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new k(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class ie{constructor(e,t,r){this.element=e,this.schema=t,this.delegate=r,this.valueListObserver=new A(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){var{element:e,content:t}=e;return this.parseValueForElementAndIdentifier(e,t)}parseValueForElementAndIdentifier(e,t){var r=this.fetchScopesByIdentifierForElement(e);let s=r.get(t);return s||(s=this.delegate.createScopeForElementAndIdentifier(e,t),r.set(t,s)),s}elementMatchedValue(e,t){var r=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,r),1==r&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){var r=this.scopeReferenceCounts.get(t);r&&(this.scopeReferenceCounts.set(t,r-1),1==r)&&this.delegate.scopeDisconnected(t)}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class ne{constructor(e){this.application=e,this.scopeObserver=new ie(this.element,this.schema,this),this.scopesByIdentifier=new v,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce((e,t)=>e.concat(t.contexts),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);var t=new X(this.application,e),t=(this.connectModule(t),e.controllerConstructor.afterLoad);t&&t.call(e.controllerConstructor,e.identifier,this.application)}unloadIdentifier(e){e=this.modulesByIdentifier.get(e);e&&this.disconnectModule(e)}getContextForElementAndIdentifier(t,e){e=this.modulesByIdentifier.get(e);if(e)return e.contexts.find(e=>e.element==t)}proposeToConnectScopeForElementAndIdentifier(e,t){var r=this.scopeObserver.parseValueForElementAndIdentifier(e,t);r?this.scopeObserver.elementMatchedValue(r.element,r):console.error(`Couldn't find or create scope for identifier: "${t}" and element:`,e)}handleError(e,t,r){this.application.handleError(e,t,r)}createScopeForElementAndIdentifier(e,t){return new k(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);var t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);var t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(t){this.modulesByIdentifier.set(t.identifier,t),this.scopesByIdentifier.getValuesForKey(t.identifier).forEach(e=>t.connectContextForScope(e))}disconnectModule(t){this.modulesByIdentifier.delete(t.identifier),this.scopesByIdentifier.getValuesForKey(t.identifier).forEach(e=>t.disconnectContextForScope(e))}}const N={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},F("abcdefghijklmnopqrstuvwxyz".split("").map(e=>[e,e]))),F("0123456789".split("").map(e=>[e,e])))};function F(e){return e.reduce((e,[t,r])=>Object.assign(Object.assign({},e),{[t]:r}),{})}class oe{constructor(e=document.documentElement,t=N){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,r={})=>{this.debug&&this.logFormattedMessage(e,t,r)},this.element=e,this.schema=t,this.dispatcher=new I(this),this.router=new ne(this),this.actionDescriptorFilters=Object.assign({},j)}static start(e,t){e=new this(e,t);return e.start(),e}async start(){await new Promise(e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",()=>e()):e()}),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)})}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>this.router.unloadIdentifier(e))}get controllers(){return this.router.contexts.map(e=>e.controller)}getControllerForElementAndIdentifier(e,t){e=this.router.getContextForElementAndIdentifier(e,t);return e?e.controller:null}handleError(e,t,r){this.logger.error(`%s
+
+%o
+
+%o`,t,e,r),null!=(r=window.onerror)&&r.call(window,t,"",0,0,e)}logFormattedMessage(e,t,r={}){r=Object.assign({application:this},r),this.logger.groupCollapsed(e+" #"+t),this.logger.log("details:",Object.assign({},r)),this.logger.groupEnd()}}function B(e,t,r){return e.application.getControllerForElementAndIdentifier(t,r)}function C(e,t,r){var s=B(e,t,r);return s||(e.application.router.proposeToConnectScopeForElementAndIdentifier(t,r),B(e,t,r))||void 0}function T([s,n],o){{let{token:e,typeDefinition:i}=o={controller:o,token:s,typeDefinition:n},t=h(e)+"-value",r=function(e){var{controller:e,token:t,typeDefinition:r}=e,s={controller:e,token:t,typeObject:r},s=function(e){var{controller:t,token:r,typeObject:s}=e,i=c(s.type),n=c(s.default),o=i&&n,a=i&&!n,i=!i&&n,n=S(s.type),e=x(e.typeObject.default);if(a)return n;if(i)return e;if(n===e)return o?n:void 0;throw new Error(`The specified default value for the Stimulus Value "${t?t+"."+r:r}" must match the defined type "${n}". The provided default value of "${s.default}" is of type "${e}".`)}(s),i=x(r),n=S(r),s=s||i||n;if(s)return s;i=e?e+"."+r:t;throw new Error(`Unknown value type "${i}" for "${t}" value`)}(o);return{type:r,key:t,name:a(t),get defaultValue(){var e=i;if(t=S(e))return D[t];var t=u(e,"default"),r=u(e,"type"),s=e;if(t)return s.default;if(r){t=s.type,r=S(t);if(r)return D[r]}return e},get hasCustomDefaultValue(){return void 0!==x(i)},reader:ae[r],writer:L[r]||L.default}}}function S(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function x(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const D={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},ae={array(e){var t=JSON.parse(e);if(Array.isArray(t))return t;throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${x(t)}"`)},boolean(e){return!("0"==e||"false"==String(e).toLowerCase())},number(e){return Number(e.replace(/_/g,""))},object(e){var t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${x(t)}"`);return t},string(e){return e}},L={default:function(e){return""+e},array:le,object:le};function le(e){return JSON.stringify(e)}class V{constructor(e){this.context=e}static get shouldLoad(){return!0}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:r={},prefix:s=this.identifier,bubbles:i=!0,cancelable:n=!0}={}){s=new CustomEvent(s?s+":"+e:e,{detail:r,bubbles:i,cancelable:n});return t.dispatchEvent(s),s}}V.blessings=[function(e){return E(e,"classes").reduce((e,t)=>{return Object.assign(e,{[(r=t)+"Class"]:{get(){var e=this.classes;if(e.has(r))return e.get(r);throw e=e.getAttributeName(r),new Error(`Missing attribute "${e}"`)}},[r+"Classes"]:{get(){return this.classes.getAll(r)}},[`has${l(r)}Class`]:{get(){return this.classes.has(r)}}});var r},{})},function(e){return E(e,"targets").reduce((e,t)=>{return Object.assign(e,{[(r=t)+"Target"]:{get(){var e=this.targets.find(r);if(e)return e;throw new Error(`Missing target element "${r}" for "${this.identifier}" controller`)}},[r+"Targets"]:{get(){return this.targets.findAll(r)}},[`has${l(r)}Target`]:{get(){return this.targets.has(r)}}});var r},{})},function(e){const t=J(e,"values");return t.reduce((e,t)=>Object.assign(e,function(e,t){let r=T(e,t),{key:s,name:i,reader:n,writer:o}=r;return{[i]:{get(){var e=this.data.get(s);return null!==e?n(e):r.defaultValue},set(e){void 0===e?this.data.delete(s):this.data.set(s,o(e))}},["has"+l(i)]:{get(){return this.data.has(s)||r.hasCustomDefaultValue}}}}(t)),{valueDescriptorMap:{get(){return t.reduce((e,t)=>{var t=T(t,this.identifier),r=this.data.getAttributeNameForKey(t.key);return Object.assign(e,{[r]:t})},{})}}})},function(e){return E(e,"outlets").reduce((e,t)=>{return Object.assign(e,{[(e=s(r=t))+"Outlet"]:{get(){var e=this.outlets.find(r),t=this.outlets.getSelectorForOutletName(r);if(e){e=C(this,e,r);if(e)return e;throw new Error(`The provided outlet element is missing an outlet controller "${r}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${r}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${t}".`)}},[e+"Outlets"]:{get(){var e=this.outlets.findAll(r);return 0{var t=C(this,e,r);if(t)return t;console.warn(`The provided outlet element is missing an outlet controller "${r}" instance for host controller "${this.identifier}"`,e)}).filter(e=>e):[]}},[e+"OutletElement"]:{get(){var e=this.outlets.find(r),t=this.outlets.getSelectorForOutletName(r);if(e)return e;throw new Error(`Missing outlet element "${r}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${t}".`)}},[e+"OutletElements"]:{get(){return this.outlets.findAll(r)}},[`has${l(e)}Outlet`]:{get(){return this.outlets.has(r)}}});var r},{})}],V.targets=[],V.outlets=[],V.values={},e.Application=oe,e.AttributeObserver=m,e.Context=M,e.Controller=V,e.ElementObserver=d,e.IndexedMultimap=z,e.Multimap=v,e.SelectorObserver=b,e.StringMapObserver=y,e.TokenListObserver=O,e.ValueListObserver=A,e.add=r,e.defaultSchema=N,e.del=g,e.fetch=p,e.prune=f,Object.defineProperty(e,"__esModule",{value:!0})});
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/table_vew.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/table_vew.css
new file mode 100644
index 0000000..263332e
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/table_vew.css
@@ -0,0 +1,79 @@
+/* ultimate table view */
+
+.content-view-table {
+ border-collapse: collapse;
+ width: 100%;
+ background-color: var(--color-bg-contrast);
+}
+
+/* .content-view-table td,
+.content-view-table th, */
+.content-view-th,
+.content-view-td {
+ padding: .5rem 1rem;
+ border: 1px solid #666;
+ vertical-align: top;
+}
+
+.content-view-th {
+ text-align: left;
+ text-transform: uppercase;
+ background-color: var(--color-border);
+ font-size: .85em;
+ font-weight: bold;
+}
+
+.content-view-td-type,
+.content-view-td-meta {
+ background-color: var(--color-bg-main);
+ font-size: .85em;
+}
+
+.content-view-td-type {
+ background-color: var(--color-bg-main);
+ text-align: left;
+ font-weight: normal;
+ text-transform: uppercase;
+}
+
+.content-view-table div.document {
+ /* TODO */
+ display: block;
+ max-width: 900px;
+}
+
+.content-view-table p:first-child {
+ margin-top: 0;
+}
+
+.content-view-table p:last-child {
+ margin-bottom: 0;
+}
+
+.content-view-td:empty {
+ width: 1%;
+}
+
+.content-view-td-content:not(:empty) {
+ min-width: 333px;
+ width: 30%;
+}
+
+.content-view-td-title:not(:empty) {
+ font-weight: bold;
+ min-width: 264px;
+}
+
+.content-view-td-related:not(:empty) {
+ min-width: 264px;
+}
+
+.content-view-td-related,
+.content-view-td-related > ul.requirement__link {
+ font-size: .85rem;
+ margin-top: 0;
+}
+
+.content-view-td-related > ul.requirement__link:last-child {
+ margin-bottom: 0;
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/toc_highlighting.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/toc_highlighting.js
new file mode 100644
index 0000000..fb96016
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/toc_highlighting.js
@@ -0,0 +1,291 @@
+const TOC_HIGHLIGHT_DEBUG = false;
+
+const TOC_FRAME_SELECTOR = 'turbo-frame#frame-toc'; // updating
+const TOC_LIST_SELECTOR = 'ul#toc';
+const TOC_ELEMENT_SELECTOR = 'a';
+const CONTENT_FRAME_SELECTOR = 'turbo-frame#frame_document_content'; // replacing => parentNode is needed
+const CONTENT_ELEMENT_SELECTOR = 'sdoc-anchor';
+
+let tocHighlightingState = {
+ data: {},
+ links: null,
+ anchors: null,
+ contentFrameTop: undefined,
+ closerForFolder: {},
+ folderSet: new Set(),
+};
+
+function resetState() {
+ tocHighlightingState.data = {};
+ tocHighlightingState.links = null;
+ tocHighlightingState.anchors = null;
+ tocHighlightingState.closerForFolder = {};
+ tocHighlightingState.folderSet = new Set();
+}
+
+window.addEventListener("hashchange", handleHashChange);
+window.addEventListener("load",function(){
+
+ // * Frames are stable and we define them once.
+ const tocFrame = document.querySelector(TOC_FRAME_SELECTOR);
+ const tocList = tocFrame ? tocFrame.querySelector(TOC_LIST_SELECTOR) : null;
+ const contentFrame = document.querySelector(CONTENT_FRAME_SELECTOR)?.parentNode;
+
+ if(!tocFrame || !tocList || !contentFrame) { return }
+
+ // ! depends on TOC markup
+ tocHighlightingState.contentFrameTop = contentFrame.offsetParent
+ ? contentFrame.offsetTop
+ : contentFrame.parentNode.offsetTop;
+
+ const anchorObserver = new IntersectionObserver(
+ handleIntersect,
+ {
+ root: null,
+ rootMargin: "0px",
+ });
+
+ // * Then we will refresh when the TOC tree is updated&
+ // * The content in the tocFrame frame will mutate:
+ const mutatingFrame = tocFrame;
+ new MutationObserver(function (mutationsList, observer) {
+ // * Use requestAnimationFrame to put highlightTOC
+ // * at the end of the event queue and to ensure
+ // * the code runs after all DOM changes have been applied.
+ requestAnimationFrame(() => {
+ highlightTOC(tocFrame, contentFrame, anchorObserver);
+ })
+ }).observe(
+ mutatingFrame,
+ {
+ // * We're looking at an updatable frame (mutates its contents,
+ // * and we don't care what mutations were made inside):
+ childList: true,
+ // attributes: true,
+ // characterData: true,
+ // subtree: true
+ }
+ );
+
+ // * Call for the first time only if the TOC actually contains items.
+ if (tocList && tocList.querySelector(TOC_ELEMENT_SELECTOR)) {
+ highlightTOC(tocFrame, contentFrame, anchorObserver);
+ }
+
+},false);
+
+function highlightTOC(tocFrame, contentFrame, anchorObserver) {
+
+ resetState();
+ processLinkList(tocFrame);
+ processAnchorList(contentFrame, anchorObserver);
+ handleHashChange();
+
+ TOC_HIGHLIGHT_DEBUG && console.log(tocHighlightingState);
+}
+
+function handleHashChange() {
+ const hash = window.location.hash;
+ const match = hash.match(/#(.*)/);
+ const fragment = match ? match[1] : null;
+
+ // Guard: no links collected yet (e.g., empty TOC or init race)
+ if (!tocHighlightingState.links || typeof tocHighlightingState.links.forEach !== 'function') {
+ return;
+ }
+
+ tocHighlightingState.links.forEach(link => {
+ targetItem(link, false)
+ });
+ // * When updating the hash
+ // * and there's a fragment,
+ fragment
+ // * and the corresponding link-anchor pair is registered,
+ && tocHighlightingState.data[fragment]
+ // * highlight the corresponding link.
+ && targetItem(tocHighlightingState.data[fragment].link)
+}
+
+function processLinkList(tocFrame) {
+ // * Collects all links in the TOC
+ tocHighlightingState.links = tocFrame.querySelectorAll(TOC_ELEMENT_SELECTOR);
+ if (!tocHighlightingState.links || tocHighlightingState.links.length === 0) {
+ return;
+ }
+ tocHighlightingState.links.length
+ && tocHighlightingState.links.forEach(link => {
+ const id = link.getAttribute('anchor');
+ tocHighlightingState.data[id] = {
+ 'link': link,
+ ...tocHighlightingState.data[id]
+ }
+
+ // ! depends on TOC markup
+ // is link in collapsible node and precedes the UL
+ // ! expected UL or null
+ const ul = link.nextSibling;
+
+ if (ul && ul.nodeName === 'UL') {
+ // register folder
+ tocHighlightingState.folderSet.add(id);
+
+ // register closer
+ const lastLink = findDeepestLastChild(ul);
+ const lastAnchor = lastLink.getAttribute('anchor');
+
+
+ if (!tocHighlightingState.closerForFolder[lastAnchor]) {
+ tocHighlightingState.closerForFolder[lastAnchor] = [];
+ }
+ tocHighlightingState.closerForFolder[lastAnchor].push(id);
+ }
+ });
+}
+
+function processAnchorList(contentFrame, anchorObserver) {
+ anchorObserver.disconnect(); // FIXME don`t work: have to hack at #rootBounds_null
+
+ // * Collects all anchors in the document
+ tocHighlightingState.anchors = null;
+ tocHighlightingState.anchors = contentFrame.querySelectorAll(CONTENT_ELEMENT_SELECTOR);
+ tocHighlightingState.anchors.length
+ && tocHighlightingState.anchors.forEach(anchor => {
+ const id = anchor.id;
+ tocHighlightingState.data[id] = {
+ 'anchor': anchor,
+ ...tocHighlightingState.data[id]
+ };
+ // * Adds an observer for the position of the anchor
+ anchorObserver.observe(anchor);
+ });
+}
+
+function handleIntersect(entries, observer) {
+
+ entries.forEach((entry) => {
+
+ // #rootBounds_null
+ // rootBounds: null
+ // after frame reload and before init
+ if(!entry.rootBounds) {
+ return
+ }
+
+ const anchor = entry.target.id;
+ // * For anchors that go into the viewport,
+ // * finds the corresponding links
+ const link = tocHighlightingState.data[anchor].link;
+
+ // * if there is no menu item for the section in the TOC
+ if(!link) {
+ return
+ }
+
+ if (entry.isIntersecting) { //! entry.intersectionRatio > 0 -- it happens to be equal to zero at the intersection!
+
+ TOC_HIGHLIGHT_DEBUG && console.group('🔶', entry.isIntersecting, entry.intersectionRatio, anchor, entry.intersectionRect.height);
+ // * and highlights them in the TOC,
+ fireItem(link)
+
+ // * semi-highlights folder in the TOC,
+ if (tocHighlightingState.folderSet.has(anchor)) {
+ TOC_HIGHLIGHT_DEBUG && console.log('🔴', anchor, '(visible folder)', );
+ fireFolder(link)
+ }
+
+ // * semi-highlights closer`s parent folder in the TOC,
+ if (tocHighlightingState.closerForFolder[anchor]) {
+ tocHighlightingState.closerForFolder[anchor].forEach(id => {
+ TOC_HIGHLIGHT_DEBUG && console.log(`🔴`, id, `(from ${anchor})`);
+ fireFolder(tocHighlightingState.data[id].link)
+ })
+ }
+ TOC_HIGHLIGHT_DEBUG && console.groupEnd();
+
+ } else {
+
+ TOC_HIGHLIGHT_DEBUG && console.group('🔹', entry.isIntersecting, entry.intersectionRatio, anchor);
+ // * or cancels highlighting for the rest of the links.
+ fireItem(link, false);
+
+ if(
+ // * If the node goes down ⬇️ off the screen
+ entry.boundingClientRect.bottom >= entry.rootBounds.bottom
+ // * and it's a folder
+ && tocHighlightingState.folderSet.has(anchor)
+ ) {
+ // ** remove highlights from folder in the TOC
+ TOC_HIGHLIGHT_DEBUG && console.log(`⚫ ⬇️`, anchor);
+ fireFolder(link, false)
+ }
+
+ if(
+ // * If the node goes up ⬆️ off the screen
+ entry.boundingClientRect.y < tocHighlightingState.contentFrameTop
+ // * and this is the last child of the section
+ && tocHighlightingState.closerForFolder[anchor]
+ ) {
+ // * When the LAST CHILD of the section disappears
+ // * over the upper boundary ( < tocHighlightingState.contentFrameTop),
+ // * strictly speaking, this occurs when the lower bound disappears:
+ // * entry.boundingClientRect.bottom.
+ // * But we will use the upper bound, entry.boundingClientRect.y
+ // * which will be less than or equal to the lower bound.
+
+ // ** remove highlights from closer`s parent folder in the TOC
+ tocHighlightingState.closerForFolder[anchor].forEach(id => {
+ TOC_HIGHLIGHT_DEBUG && console.log(`⚫ ⬆️`, id,);
+ fireFolder(tocHighlightingState.data[id].link, false)
+ });
+ }
+
+ TOC_HIGHLIGHT_DEBUG && console.groupEnd();
+ }
+ });
+
+}
+
+function findDeepestLastChild(element) {
+ // ! depends on TOC markup
+ // ul > li > div + a + ul > ...
+ // ul > li > a
+ // > li > a <---------------***
+ if (element.nodeName === 'A') {
+ return element;
+ }
+ const children = element.children;
+ if (children && children.length > 0) {
+ return findDeepestLastChild([...children].at(-1))
+ } else {
+ return element;
+ }
+}
+
+function targetItem(element, on = true) {
+ if (!element) { return } // Guard against race conditions:
+ // hashchange or intersection events may fire
+ // before the TOC is fully built, resulting in undefined link elements.
+ if(on) {
+ element.setAttribute('targeted', '');
+ } else {
+ element.removeAttribute('targeted');
+ }
+}
+
+function fireItem(element, on = true) {
+ if (!element) { return } // Guard against race conditions
+ if(on) {
+ element.setAttribute('intersected', '');
+ } else {
+ element.removeAttribute('intersected');
+ }
+}
+
+function fireFolder(element, on = true) {
+ if (!element) { return } // Guard against race conditions
+ if(on) {
+ element.setAttribute('parented', '');
+ } else {
+ element.removeAttribute('parented');
+ }
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/traceability_matrix_screen.css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/traceability_matrix_screen.css
new file mode 100644
index 0000000..6c9c279
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/traceability_matrix_screen.css
@@ -0,0 +1,148 @@
+.traceability_matrix {
+ --traceability_matrix-thead-height: calc(4 * var(--base-rhythm));
+
+
+ display: table;
+ border-collapse: collapse;
+}
+
+.traceability_matrix__anchor {
+ /* for Fixed Headers + Section Anchors */
+ scroll-snap-margin-top: var(--base-gap);
+ scroll-margin-top: var(--base-gap);
+}
+
+.traceability_matrix .traceability_matrix__thead {
+ position: sticky;
+ top: calc(-1 * var(--traceability_matrix-thead-height));
+ z-index: 2;
+ background-color: var(--color-bg-main);
+}
+
+.traceability_matrix .traceability_matrix__thead::before {
+ content: '';
+ position: absolute;
+ top: calc(-1 * var(--base-gap));
+ left: calc(-1 * var(--base-gap));
+ right: calc(-1 * var(--base-gap));
+ bottom: 0;
+ z-index: 0;
+ background-color: var(--color-bg-main);
+}
+
+.traceability_matrix__thead th {
+ height: var(--traceability_matrix-thead-height);
+ text-align: left;
+ vertical-align: middle;
+ line-height: 1;
+ position: relative;
+ background-color: var(--color-bg-secondary-invert);
+ padding-left: var(--base-rhythm);
+ border: 1px solid var(--color-border);
+}
+
+.traceability_matrix td {
+ border: 1px solid var(--color-border);
+ background-color: var(--color-bg-contrast);
+ vertical-align: top;
+}
+
+td.traceability_matrix__document {
+ position: sticky;
+ padding: 0;
+ top: 0;
+ z-index: 1;
+}
+
+.traceability_matrix__placeholder {
+ padding: var(--base-rhythm);
+ text-align: center;
+ font-size: var(--font-size-sm);
+}
+
+td.traceability_matrix__null {
+ height: calc(4 * var(--base-rhythm));
+ background-color: var(--color-bg-main);
+ border: none;
+}
+
+.traceability_matrix__document_line {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ column-gap: calc(2 * var(--base-rhythm));
+ font-size: var(--font-size-l);
+ font-weight: 600;
+ line-height: 1.2;
+ width: 100%;
+
+ padding: var(--base-rhythm);
+ padding-top: calc(1.5 * var(--base-rhythm));
+
+ border-bottom: 1px solid var(--color-border);
+}
+
+.traceability_matrix__document_stat {
+ margin-left: auto;
+}
+
+.traceability_matrix__requirement {
+ display: block;
+ position: relative;
+ font-size: var(--font-size-sm);
+ line-height: 1.2;
+ padding: var(--base-rhythm);
+}
+
+.traceability_matrix__file {
+ position: relative;
+ font-size: var(--font-size-sm);
+ line-height: 1.2;
+ margin-top: var(--base-rhythm);
+ margin-bottom: var(--base-rhythm);
+ padding-right: var(--base-rhythm);
+}
+
+.traceability_matrix__file a {
+ /* overflow-wrap: break-word; */
+ overflow-wrap: anywhere;
+ color: var(--color-link);
+ text-decoration: none;
+}
+
+.traceability_matrix__file a:hover {
+ color: var(--color-hover);
+}
+
+[with_relation] {
+ padding-left: calc(4 * var(--base-rhythm));
+}
+
+[with_relation]::before {
+ content: '';
+ font-size: var(--font-size);
+ line-height: 1;
+ position: absolute;
+ left: var(--base-rhythm);
+}
+
+.traceability_matrix__requirement[with_relation]::before {
+ top: var(--base-rhythm);
+}
+
+.traceability_matrix__file[with_relation]::before {
+ top: 0
+}
+
+/* ← → */
+[with_relation="parent"]::before {
+ content: '→';
+}
+
+[with_relation="child"]::before {
+ content: '←';
+}
+
+[with_relation="file"]::before {
+ content: '→';
+}
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/traceability_matrix_screen.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/traceability_matrix_screen.js
new file mode 100644
index 0000000..9be993e
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/traceability_matrix_screen.js
@@ -0,0 +1,48 @@
+// @relation(SDOC-SRS-112, scope=file)
+
+const SELECTOR = '[js-requirements-coverage]';
+
+const __log = (topic, ...payload) => {
+ console.log(`%c ${topic} `, 'background:yellow;color:black',
+ ...payload
+ );
+}
+
+function markSame(newUid, state, arr) {
+ // __log('state', state.currentUid);
+ state.currentUid && arr[state.currentUid].forEach(element => element.classList.remove('highlighted'));
+ state.currentUid = newUid;
+ arr[newUid].forEach(element => element.classList.add('highlighted'));
+
+}
+
+window.addEventListener("load", function () {
+ // __log(
+ // 'requirements-coverage',
+ // 'test'
+ // )
+
+ const state = {
+ currentUid: null
+ }
+
+ // https://stackoverflow.com/questions/32249997/how-to-check-if-data-attribute-exist-with-plain-javascript/32250073
+ const reqs = [...document.querySelectorAll(SELECTOR)]
+ .reduce((acc, req) => {
+ if (req.hasAttribute('data-uid')) {
+ req.addEventListener('click', () => markSame(uid, state, reqs));
+ const uid = req.dataset.uid;
+ acc[uid] = acc[uid] ? [...acc[uid], req] : [req];
+ } else {
+ req.classList.add('nouid')
+ acc.nouid.push(req);
+ }
+ return acc
+ }, { nouid: [] });
+
+ // __log(
+ // '--',
+ // reqs
+ // )
+
+});
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/tree(not_in_use).css b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/tree(not_in_use).css
new file mode 100644
index 0000000..acd2a13
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/tree(not_in_use).css
@@ -0,0 +1,146 @@
+.std-tree {
+ --tree-font-size: 16px;
+ --tree-line-height: calc(var(--tree-font-size)*1.25);
+ --tree-level-padding: calc(var(--tree-font-size)*1.5);
+ --tree-cell-padding: calc(var(--tree-font-size)*0.5);
+
+ --tree-level-line-width: 1px;
+
+ --tree-color-line: #808080;
+ --tree-color-fg: var(--color-fg-main, #444444);
+ --tree-color-bg: var(--color-bg-main, #F2F5F9);
+ --tree-color-row-hover-bg: var(--color-bg-contrast, #FFFFFF);
+ --tree-btn-bg-color: var(--color-bg-contrast, #FFFFFF);
+
+ --tree-half-sell-height: calc( var(--tree-line-height)/2 + var(--tree-cell-padding) );
+
+ --tree-ico-size: var(--tree-font-size, 1rem);
+
+ --tree-max-width: 800px;
+}
+
+
+/* tree */
+.std-tree {
+ font-size: var(--tree-font-size, 1rem);
+ line-height: var(--tree-line-height, 1.25);
+ color: var(--tree-color-fg, #444444);
+
+ position: relative;
+ width: -moz-fit-content;
+ width: fit-content;
+ /* margin: 0 auto; */
+}
+
+.std-tree ul {
+ list-style: none;
+ width: 100%;
+ padding: 0;
+ margin: 0;
+}
+
+.std-tree li {
+ position: relative;
+ padding-left: var(--tree-level-padding);
+}
+
+.std-tree ul ul > li::before {
+ content: '';
+ position: absolute;
+ left: calc(var(--tree-ico-size)*0.5 - var(--tree-level-padding));
+ top: calc(var(--tree-ico-size)*(-0.5));
+ height: 100%;
+ border-left: 1px solid var(--tree-color-line);
+}
+
+.std-tree ul > li:last-child::before {
+ height: calc(var(--tree-ico-size) + var(--tree-cell-padding));
+}
+
+.std-tree_ico {
+ display: inline-flex;
+ align-items: center;
+
+ position: absolute;
+ left: 0;
+ top: calc(var(--tree-cell-padding));
+}
+
+ ul ul .std-tree_ico::before {
+ content: '';
+ position: absolute;
+ left: calc(var(--tree-ico-size)*0.5 - var(--tree-level-padding));
+ right: 100%;
+ border-bottom: 1px solid var(--tree-color-line);
+ }
+
+ .std-tree_ico svg {
+ display: inline-block;
+ width: var(--tree-ico-size);
+ height: var(--tree-ico-size);
+
+ fill: var(--tree-color-line);
+ }
+
+ .std-tree_row {
+ padding-top: var(--tree-cell-padding);
+ padding-bottom: var(--tree-cell-padding);
+ padding-left: var(--tree-cell-padding);
+
+ display: flex;
+ justify-content: space-between;
+ }
+
+ .std-tree_folder {
+ font-weight: bold;
+ display: flex;
+ }
+
+ .std-tree_file {
+ order: 1;
+ flex-grow: 1;
+ }
+
+ .std-tree_file__title {
+ font-size: 1.25em;
+ color: #000;
+ transition: color .2s ease;
+ }
+
+ .std-tree_file-link:hover .std-tree_file__title {
+ color: var(--color-fg-accent);
+ }
+
+ .std-tree_file__name {
+ font-size: 0.85rem;
+ line-height: 1.2;
+ color: var(--color-fg-secondary);
+ margin-top: 0.25rem;
+ }
+
+ .std-tree_desc {
+ position: relative;
+ top: -2px;
+ color: #000;
+ }
+
+ .std-tree_name {
+ font-size: 0.85rem;
+ line-height: 1.2;
+ color: #666;
+ }
+
+ .std-tree_aside {
+ width: -moz-fit-content;
+ width: fit-content;
+ padding-left: 20px;
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ order: 3;
+ }
+
+ .std-tree_file-link {
+ position: relative;
+ top: -2px;
+ }
diff --git a/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/turbo.min.js b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/turbo.min.js
new file mode 100644
index 0000000..ee8fdf3
--- /dev/null
+++ b/tests/integration/_validation/20251011_strictdoc_guide_broken_admonition_page_split/assets/turbo.min.js
@@ -0,0 +1,24 @@
+!function(){if(void 0!==window.Reflect&&void 0!==window.customElements&&!window.customElements.polyfillWrapFlushCallback){const e=HTMLElement,t=function(){return Reflect.construct(e,[],this.constructor)};window.HTMLElement=t,HTMLElement.prototype=e.prototype,HTMLElement.prototype.constructor=HTMLElement,Object.setPrototypeOf(HTMLElement,e)}}(),function(e){function r(e,t,s){throw new e("Failed to execute 'requestSubmit' on 'HTMLFormElement': "+t+".",s)}"function"!=typeof e.requestSubmit&&(e.requestSubmit=function(e){var t,s;e?(s=this,(t=e)instanceof HTMLElement||r(TypeError,"parameter 1 is not of type 'HTMLElement'"),"submit"!=t.type&&r(TypeError,"The specified element is not a submit button"),t.form!=s&&r(DOMException,"The specified element is not owned by this form element","NotFoundError"),e.click()):((e=document.createElement("input")).type="submit",e.hidden=!0,this.appendChild(e),e.click(),this.removeChild(e))})}(HTMLFormElement.prototype);const submittersByForm=new WeakMap;function findSubmitterFromClickTarget(e){e=e instanceof Element?e:e instanceof Node?e.parentElement:null,e=e?e.closest("input, button"):null;return"submit"==(null==e?void 0:e.type)?e:null}function clickCaptured(e){e=findSubmitterFromClickTarget(e.target);e&&e.form&&submittersByForm.set(e.form,e)}var FrameLoadingStyle,FetchMethod,FormSubmissionState,FormEnctype,TimingMetric,VisitState,SystemStatusCode,PageStage;!function(){if(!("submitter"in Event.prototype)){let e;if("SubmitEvent"in window&&/Apple Computer/.test(navigator.vendor))e=window.SubmitEvent.prototype;else{if("SubmitEvent"in window)return;e=window.Event.prototype}addEventListener("click",clickCaptured,!0),Object.defineProperty(e,"submitter",{get(){if("submit"==this.type&&this.target instanceof HTMLFormElement)return submittersByForm.get(this.target)}})}}(),function(e){e.eager="eager",e.lazy="lazy"}(FrameLoadingStyle=FrameLoadingStyle||{});class FrameElement extends HTMLElement{constructor(){super(),this.loaded=Promise.resolve(),this.delegate=new FrameElement.delegateConstructor(this)}static get observedAttributes(){return["disabled","loading","src"]}connectedCallback(){this.delegate.connect()}disconnectedCallback(){this.delegate.disconnect()}reload(){var e=this["src"];this.src=null,this.src=e}attributeChangedCallback(e){"loading"==e?this.delegate.loadingStyleChanged():"src"==e?this.delegate.sourceURLChanged():this.delegate.disabledChanged()}get src(){return this.getAttribute("src")}set src(e){e?this.setAttribute("src",e):this.removeAttribute("src")}get loading(){return frameLoadingStyleFromString(this.getAttribute("loading")||"")}set loading(e){e?this.setAttribute("loading",e):this.removeAttribute("loading")}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}get autoscroll(){return this.hasAttribute("autoscroll")}set autoscroll(e){e?this.setAttribute("autoscroll",""):this.removeAttribute("autoscroll")}get complete(){return!this.delegate.isLoading}get isActive(){return this.ownerDocument===document&&!this.isPreview}get isPreview(){var e;return null==(e=null==(e=this.ownerDocument)?void 0:e.documentElement)?void 0:e.hasAttribute("data-turbo-preview")}}function frameLoadingStyleFromString(e){return"lazy"!==e.toLowerCase()?FrameLoadingStyle.eager:FrameLoadingStyle.lazy}function expandURL(e){return new URL(e.toString(),document.baseURI)}function getAnchor(e){return e.hash?e.hash.slice(1):(e=e.href.match(/#(.*)$/))?e[1]:void 0}function getAction(e,t){return expandURL((null==t?void 0:t.getAttribute("formaction"))||e.getAttribute("action")||e.action)}function getExtension(e){return(getLastPathComponent(e).match(/\.[^.]*$/)||[])[0]||""}function isHTML(e){return!!getExtension(e).match(/^(?:|\.(?:htm|html|xhtml))$/)}function isPrefixedBy(e,t){t=getPrefix(t);return e.href===expandURL(t).href||e.href.startsWith(t)}function locationIsVisitable(e,t){return isPrefixedBy(e,t)&&isHTML(e)}function getRequestURL(e){var t=getAnchor(e);return null!=t?e.href.slice(0,-(t.length+1)):e.href}function toCacheKey(e){return getRequestURL(e)}function urlsAreEqual(e,t){return expandURL(e).href==expandURL(t).href}function getPathComponents(e){return e.pathname.split("/").slice(1)}function getLastPathComponent(e){return getPathComponents(e).slice(-1)[0]}function getPrefix(e){return addTrailingSlash(e.origin+e.pathname)}function addTrailingSlash(e){return e.endsWith("/")?e:e+"/"}class FetchResponse{constructor(e){this.response=e}get succeeded(){return this.response.ok}get failed(){return!this.succeeded}get clientError(){return 400<=this.statusCode&&this.statusCode<=499}get serverError(){return 500<=this.statusCode&&this.statusCode<=599}get redirected(){return this.response.redirected}get location(){return expandURL(this.response.url)}get isHTML(){return this.contentType&&this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/)}get statusCode(){return this.response.status}get contentType(){return this.header("Content-Type")}get responseText(){return this.response.clone().text()}get responseHTML(){return this.isHTML?this.response.clone().text():Promise.resolve(void 0)}header(e){return this.response.headers.get(e)}}function dispatch(e,{target:t,cancelable:s,detail:r}={}){e=new CustomEvent(e,{cancelable:s,bubbles:!0,detail:r});return(t&&t.isConnected?t:document.documentElement).dispatchEvent(e),e}function nextAnimationFrame(){return new Promise(e=>requestAnimationFrame(()=>e()))}function nextEventLoopTick(){return new Promise(e=>setTimeout(()=>e(),0))}function nextMicrotask(){return Promise.resolve()}function parseHTMLDocument(e=""){return(new DOMParser).parseFromString(e,"text/html")}function unindent(e,...t){e=interpolate(e,t).replace(/^\n/,"").split("\n"),t=e[0].match(/^\s+/);const s=t?t[0].length:0;return e.map(e=>e.slice(s)).join("\n")}function interpolate(e,r){return e.reduce((e,t,s)=>{return e+t+(null==r[s]?"":r[s])},"")}function uuid(){return Array.apply(null,{length:36}).map((e,t)=>8==t||13==t||18==t||23==t?"-":14==t?"4":(19==t?Math.floor(4*Math.random())+8:Math.floor(15*Math.random())).toString(16)).join("")}function getAttribute(t,...e){for(const s of e.map(e=>null==e?void 0:e.getAttribute(t)))if("string"==typeof s)return s;return null}function markAsBusy(...e){for(const t of e)"turbo-frame"==t.localName&&t.setAttribute("busy",""),t.setAttribute("aria-busy","true")}function clearBusyState(...e){for(const t of e)"turbo-frame"==t.localName&&t.removeAttribute("busy"),t.removeAttribute("aria-busy")}function fetchMethodFromString(e){switch(e.toLowerCase()){case"get":return FetchMethod.get;case"post":return FetchMethod.post;case"put":return FetchMethod.put;case"patch":return FetchMethod.patch;case"delete":return FetchMethod.delete}}!function(e){e[e.get=0]="get",e[e.post=1]="post",e[e.put=2]="put",e[e.patch=3]="patch",e[e.delete=4]="delete"}(FetchMethod=FetchMethod||{});class FetchRequest{constructor(e,t,s,r=new URLSearchParams,i=null){this.abortController=new AbortController,this.resolveRequestPromise=e=>{},this.delegate=e,this.method=t,this.headers=this.defaultHeaders,this.body=r,this.url=s,this.target=i}get location(){return this.url}get params(){return this.url.searchParams}get entries(){return this.body?Array.from(this.body.entries()):[]}cancel(){this.abortController.abort()}async perform(){var e,t,s=this["fetchOptions"];null!=(t=(e=this.delegate).prepareHeadersForRequest)&&t.call(e,this.headers,this),await this.allowRequestToBeIntercepted(s);try{this.delegate.requestStarted(this);var r=await fetch(this.url.href,s);return await this.receive(r)}catch(e){if("AbortError"!==e.name)throw this.delegate.requestErrored(this,e),e}finally{this.delegate.requestFinished(this)}}async receive(e){e=new FetchResponse(e);return dispatch("turbo:before-fetch-response",{cancelable:!0,detail:{fetchResponse:e},target:this.target}).defaultPrevented?this.delegate.requestPreventedHandlingResponse(this,e):e.succeeded?this.delegate.requestSucceededWithResponse(this,e):this.delegate.requestFailedWithResponse(this,e),e}get fetchOptions(){var e;return{method:FetchMethod[this.method].toUpperCase(),credentials:"same-origin",headers:this.headers,redirect:"follow",body:this.isIdempotent?null:this.body,signal:this.abortSignal,referrer:null==(e=this.delegate.referrer)?void 0:e.href}}get defaultHeaders(){return{Accept:"text/html, application/xhtml+xml"}}get isIdempotent(){return this.method==FetchMethod.get}get abortSignal(){return this.abortController.signal}async allowRequestToBeIntercepted(e){var t=new Promise(e=>this.resolveRequestPromise=e);dispatch("turbo:before-fetch-request",{cancelable:!0,detail:{fetchOptions:e,url:this.url,resume:this.resolveRequestPromise},target:this.target}).defaultPrevented&&await t}}class AppearanceObserver{constructor(e,t){this.started=!1,this.intersect=e=>{e=e.slice(-1)[0];null!=e&&e.isIntersecting&&this.delegate.elementAppearedInViewport(this.element)},this.delegate=e,this.element=t,this.intersectionObserver=new IntersectionObserver(this.intersect)}start(){this.started||(this.started=!0,this.intersectionObserver.observe(this.element))}stop(){this.started&&(this.started=!1,this.intersectionObserver.unobserve(this.element))}}class StreamMessage{constructor(e){this.templateElement=document.createElement("template"),this.templateElement.innerHTML=e}static wrap(e){return"string"==typeof e?new this(e):e}get fragment(){var e=document.createDocumentFragment();for(const t of this.foreignElements)e.appendChild(document.importNode(t,!0));return e}get foreignElements(){return this.templateChildren.reduce((e,t)=>"turbo-stream"==t.tagName.toLowerCase()?[...e,t]:e,[])}get templateChildren(){return Array.from(this.templateElement.content.children)}}function formEnctypeFromString(e){switch(e.toLowerCase()){case FormEnctype.multipart:return FormEnctype.multipart;case FormEnctype.plain:return FormEnctype.plain;default:return FormEnctype.urlEncoded}}StreamMessage.contentType="text/vnd.turbo-stream.html",function(e){e[e.initialized=0]="initialized",e[e.requesting=1]="requesting",e[e.waiting=2]="waiting",e[e.receiving=3]="receiving",e[e.stopping=4]="stopping",e[e.stopped=5]="stopped"}(FormSubmissionState=FormSubmissionState||{}),function(e){e.urlEncoded="application/x-www-form-urlencoded",e.multipart="multipart/form-data",e.plain="text/plain"}(FormEnctype=FormEnctype||{});class FormSubmission{constructor(e,t,s,r=!1){this.state=FormSubmissionState.initialized,this.delegate=e,this.formElement=t,this.submitter=s,this.formData=buildFormData(t,s),this.location=expandURL(this.action),this.method==FetchMethod.get&&mergeFormDataEntries(this.location,[...this.body.entries()]),this.fetchRequest=new FetchRequest(this,this.method,this.location,this.body,this.formElement),this.mustRedirect=r}static confirmMethod(e,t){return confirm(e)}get method(){var e;return fetchMethodFromString(((null==(e=this.submitter)?void 0:e.getAttribute("formmethod"))||this.formElement.getAttribute("method")||"").toLowerCase())||FetchMethod.get}get action(){var e,t="string"==typeof this.formElement.action?this.formElement.action:null;return(null==(e=this.submitter)?void 0:e.getAttribute("formaction"))||this.formElement.getAttribute("action")||t||""}get body(){return this.enctype==FormEnctype.urlEncoded||this.method==FetchMethod.get?new URLSearchParams(this.stringFormData):this.formData}get enctype(){var e;return formEnctypeFromString((null==(e=this.submitter)?void 0:e.getAttribute("formenctype"))||this.formElement.enctype)}get isIdempotent(){return this.fetchRequest.isIdempotent}get stringFormData(){return[...this.formData].reduce((e,[t,s])=>e.concat("string"==typeof s?[[t,s]]:[]),[])}get confirmationMessage(){return this.formElement.getAttribute("data-turbo-confirm")}get needsConfirmation(){return null!==this.confirmationMessage}async start(){var{initialized:e,requesting:t}=FormSubmissionState;if(this.needsConfirmation&&!FormSubmission.confirmMethod(this.confirmationMessage,this.formElement))return;if(this.state==e)return this.state=t,this.fetchRequest.perform()}stop(){var{stopping:e,stopped:t}=FormSubmissionState;if(this.state!=e&&this.state!=t)return this.state=e,this.fetchRequest.cancel(),!0}prepareHeadersForRequest(e,t){t.isIdempotent||((t=getCookieValue(getMetaContent("csrf-param"))||getMetaContent("csrf-token"))&&(e["X-CSRF-Token"]=t),e.Accept=[StreamMessage.contentType,e.Accept].join(", "))}requestStarted(e){var t;this.state=FormSubmissionState.waiting,null!=(t=this.submitter)&&t.setAttribute("disabled",""),dispatch("turbo:submit-start",{target:this.formElement,detail:{formSubmission:this}}),this.delegate.formSubmissionStarted(this)}requestPreventedHandlingResponse(e,t){this.result={success:t.succeeded,fetchResponse:t}}requestSucceededWithResponse(e,t){t.clientError||t.serverError?this.delegate.formSubmissionFailedWithResponse(this,t):this.requestMustRedirect(e)&&responseSucceededWithoutRedirect(t)?(e=new Error("Form responses must redirect to another location"),this.delegate.formSubmissionErrored(this,e)):(this.state=FormSubmissionState.receiving,this.result={success:!0,fetchResponse:t},this.delegate.formSubmissionSucceededWithResponse(this,t))}requestFailedWithResponse(e,t){this.result={success:!1,fetchResponse:t},this.delegate.formSubmissionFailedWithResponse(this,t)}requestErrored(e,t){this.result={success:!1,error:t},this.delegate.formSubmissionErrored(this,t)}requestFinished(e){var t;this.state=FormSubmissionState.stopped,null!=(t=this.submitter)&&t.removeAttribute("disabled"),dispatch("turbo:submit-end",{target:this.formElement,detail:Object.assign({formSubmission:this},this.result)}),this.delegate.formSubmissionFinished(this)}requestMustRedirect(e){return!e.isIdempotent&&this.mustRedirect}}function buildFormData(e,t){var e=new FormData(e),s=null==t?void 0:t.getAttribute("name"),t=null==t?void 0:t.getAttribute("value");return s&&null!=t&&e.get(s)!=t&&e.append(s,t),e}function getCookieValue(t){var e;return null!=t&&(e=(document.cookie?document.cookie.split("; "):[]).find(e=>e.startsWith(t)))&&(e=e.split("=").slice(1).join("="))?decodeURIComponent(e):void 0}function getMetaContent(e){e=document.querySelector(`meta[name="${e}"]`);return e&&e.content}function responseSucceededWithoutRedirect(e){return 200==e.statusCode&&!e.redirected}function mergeFormDataEntries(e,t){var s,r,i=new URLSearchParams;for([s,r]of t)r instanceof File||i.append(s,r);return e.search=i.toString(),e}class Snapshot{constructor(e){this.element=e}get children(){return[...this.element.children]}hasAnchor(e){return null!=this.getElementForAnchor(e)}getElementForAnchor(e){return e?this.element.querySelector(`[id='${e}'], a[name='${e}']`):null}get isConnected(){return this.element.isConnected}get firstAutofocusableElement(){return this.element.querySelector("[autofocus]")}get permanentElements(){return[...this.element.querySelectorAll("[id][data-turbo-permanent]")]}getPermanentElementById(e){return this.element.querySelector(`#${e}[data-turbo-permanent]`)}getPermanentElementMapForSnapshot(e){var t={};for(const i of this.permanentElements){var s=i["id"],r=e.getPermanentElementById(s);r&&(t[s]=[i,r])}return t}}class FormInterceptor{constructor(e,t){this.submitBubbled=e=>{var t,s=e.target;!e.defaultPrevented&&s instanceof HTMLFormElement&&s.closest("turbo-frame, html")==this.element&&"dialog"!=((null==(t=e.submitter||void 0)?void 0:t.getAttribute("formmethod"))||s.method)&&this.delegate.shouldInterceptFormSubmission(s,t)&&(e.preventDefault(),e.stopImmediatePropagation(),this.delegate.formSubmissionIntercepted(s,t))},this.delegate=e,this.element=t}start(){this.element.addEventListener("submit",this.submitBubbled)}stop(){this.element.removeEventListener("submit",this.submitBubbled)}}class View{constructor(e,t){this.resolveRenderPromise=e=>{},this.resolveInterceptionPromise=e=>{},this.delegate=e,this.element=t}scrollToAnchor(e){e=this.snapshot.getElementForAnchor(e);e?(this.scrollToElement(e),this.focusElement(e)):this.scrollToPosition({x:0,y:0})}scrollToAnchorFromLocation(e){this.scrollToAnchor(getAnchor(e))}scrollToElement(e){e.scrollIntoView()}focusElement(e){e instanceof HTMLElement&&(e.hasAttribute("tabindex")?e.focus():(e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")))}scrollToPosition({x:e,y:t}){this.scrollRoot.scrollTo(e,t)}scrollToTop(){this.scrollToPosition({x:0,y:0})}get scrollRoot(){return window}async render(e){var{isPreview:t,shouldRender:s,newSnapshot:r}=e;if(s)try{this.renderPromise=new Promise(e=>this.resolveRenderPromise=e),this.renderer=e,this.prepareToRenderSnapshot(e);var i=new Promise(e=>this.resolveInterceptionPromise=e);this.delegate.allowsImmediateRender(r,this.resolveInterceptionPromise)||await i,await this.renderSnapshot(e),this.delegate.viewRenderedSnapshot(r,t),this.finishRenderingSnapshot(e)}finally{delete this.renderer,this.resolveRenderPromise(void 0),delete this.renderPromise}else this.invalidate()}invalidate(){this.delegate.viewInvalidated()}prepareToRenderSnapshot(e){this.markAsPreview(e.isPreview),e.prepareToRender()}markAsPreview(e){e?this.element.setAttribute("data-turbo-preview",""):this.element.removeAttribute("data-turbo-preview")}async renderSnapshot(e){await e.render()}finishRenderingSnapshot(e){e.finishRendering()}}class FrameView extends View{invalidate(){this.element.innerHTML=""}get snapshot(){return new Snapshot(this.element)}}class LinkInterceptor{constructor(e,t){this.clickBubbled=e=>{this.respondsToEventTarget(e.target)?this.clickEvent=e:delete this.clickEvent},this.linkClicked=e=>{this.clickEvent&&this.respondsToEventTarget(e.target)&&e.target instanceof Element&&this.delegate.shouldInterceptLinkClick(e.target,e.detail.url)&&(this.clickEvent.preventDefault(),e.preventDefault(),this.delegate.linkClickIntercepted(e.target,e.detail.url)),delete this.clickEvent},this.willVisit=()=>{delete this.clickEvent},this.delegate=e,this.element=t}start(){this.element.addEventListener("click",this.clickBubbled),document.addEventListener("turbo:click",this.linkClicked),document.addEventListener("turbo:before-visit",this.willVisit)}stop(){this.element.removeEventListener("click",this.clickBubbled),document.removeEventListener("turbo:click",this.linkClicked),document.removeEventListener("turbo:before-visit",this.willVisit)}respondsToEventTarget(e){e=e instanceof Element?e:e instanceof Node?e.parentElement:null;return e&&e.closest("turbo-frame, html")==this.element}}class Bardo{constructor(e){this.permanentElementMap=e}static preservingPermanentElements(e,t){e=new this(e);e.enter(),t(),e.leave()}enter(){for(const t in this.permanentElementMap){var[,e]=this.permanentElementMap[t];this.replaceNewPermanentElementWithPlaceholder(e)}}leave(){for(const t in this.permanentElementMap){var[e]=this.permanentElementMap[t];this.replaceCurrentPermanentElementWithClone(e),this.replacePlaceholderWithPermanentElement(e)}}replaceNewPermanentElementWithPlaceholder(e){var t=createPlaceholderForPermanentElement(e);e.replaceWith(t)}replaceCurrentPermanentElementWithClone(e){var t=e.cloneNode(!0);e.replaceWith(t)}replacePlaceholderWithPermanentElement(e){var t=this.getPlaceholderById(e.id);null!=t&&t.replaceWith(e)}getPlaceholderById(t){return this.placeholders.find(e=>e.content==t)}get placeholders(){return[...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")]}}function createPlaceholderForPermanentElement(e){var t=document.createElement("meta");return t.setAttribute("name","turbo-permanent-placeholder"),t.setAttribute("content",e.id),t}class Renderer{constructor(e,t,s,r=!0){this.currentSnapshot=e,this.newSnapshot=t,this.isPreview=s,this.willRender=r,this.promise=new Promise((e,t)=>this.resolvingFunctions={resolve:e,reject:t})}get shouldRender(){return!0}prepareToRender(){}finishRendering(){this.resolvingFunctions&&(this.resolvingFunctions.resolve(),delete this.resolvingFunctions)}createScriptElement(e){var t;return"false"==e.getAttribute("data-turbo-eval")?e:(t=document.createElement("script"),this.cspNonce&&(t.nonce=this.cspNonce),t.textContent=e.textContent,t.async=!1,copyElementAttributes(t,e),t)}preservingPermanentElements(e){Bardo.preservingPermanentElements(this.permanentElementMap,e)}focusFirstAutofocusableElement(){var e=this.connectedSnapshot.firstAutofocusableElement;elementIsFocusable(e)&&e.focus()}get connectedSnapshot(){return this.newSnapshot.isConnected?this.newSnapshot:this.currentSnapshot}get currentElement(){return this.currentSnapshot.element}get newElement(){return this.newSnapshot.element}get permanentElementMap(){return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot)}get cspNonce(){var e;return null==(e=document.head.querySelector('meta[name="csp-nonce"]'))?void 0:e.getAttribute("content")}}function copyElementAttributes(e,t){for(var{name:s,value:r}of[...t.attributes])e.setAttribute(s,r)}function elementIsFocusable(e){return e&&"function"==typeof e.focus}class FrameRenderer extends Renderer{get shouldRender(){return!0}async render(){await nextAnimationFrame(),this.preservingPermanentElements(()=>{this.loadFrameElement()}),this.scrollFrameIntoView(),await nextAnimationFrame(),this.focusFirstAutofocusableElement(),await nextAnimationFrame(),this.activateScriptElements()}loadFrameElement(){var e=document.createRange(),e=(e.selectNodeContents(this.currentElement),e.deleteContents(),this.newElement),t=null==(t=e.ownerDocument)?void 0:t.createRange();t&&(t.selectNodeContents(e),this.currentElement.appendChild(t.extractContents()))}scrollFrameIntoView(){if(this.currentElement.autoscroll||this.newElement.autoscroll){var e=this.currentElement.firstElementChild,t=readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"),"end");if(e)return e.scrollIntoView({block:t}),!0}return!1}activateScriptElements(){for(const t of this.newScriptElements){var e=this.createScriptElement(t);t.replaceWith(e)}}get newScriptElements(){return this.currentElement.querySelectorAll("script")}}function readScrollLogicalPosition(e,t){return"end"==e||"start"==e||"center"==e||"nearest"==e?e:t}class ProgressBar{constructor(){this.hiding=!1,this.value=0,this.visible=!1,this.trickle=()=>{this.setValue(this.value+Math.random()/100)},this.stylesheetElement=this.createStylesheetElement(),this.progressElement=this.createProgressElement(),this.installStylesheetElement(),this.setValue(0)}static get defaultCSS(){return unindent`
+ .turbo-progress-bar {
+ position: fixed;
+ display: block;
+ top: 0;
+ left: 0;
+ height: 3px;
+ background: #0076ff;
+ z-index: 9999;
+ transition:
+ width ${ProgressBar.animationDuration}ms ease-out,
+ opacity ${ProgressBar.animationDuration/2}ms ${ProgressBar.animationDuration/2}ms ease-in;
+ transform: translate3d(0, 0, 0);
+ }
+ `}show(){this.visible||(this.visible=!0,this.installProgressElement(),this.startTrickling())}hide(){this.visible&&!this.hiding&&(this.hiding=!0,this.fadeProgressElement(()=>{this.uninstallProgressElement(),this.stopTrickling(),this.visible=!1,this.hiding=!1}))}setValue(e){this.value=e,this.refresh()}installStylesheetElement(){document.head.insertBefore(this.stylesheetElement,document.head.firstChild)}installProgressElement(){this.progressElement.style.width="0",this.progressElement.style.opacity="1",document.documentElement.insertBefore(this.progressElement,document.body),this.refresh()}fadeProgressElement(e){this.progressElement.style.opacity="0",setTimeout(e,1.5*ProgressBar.animationDuration)}uninstallProgressElement(){this.progressElement.parentNode&&document.documentElement.removeChild(this.progressElement)}startTrickling(){this.trickleInterval||(this.trickleInterval=window.setInterval(this.trickle,ProgressBar.animationDuration))}stopTrickling(){window.clearInterval(this.trickleInterval),delete this.trickleInterval}refresh(){requestAnimationFrame(()=>{this.progressElement.style.width=10+90*this.value+"%"})}createStylesheetElement(){var e=document.createElement("style");return e.type="text/css",e.textContent=ProgressBar.defaultCSS,e}createProgressElement(){var e=document.createElement("div");return e.className="turbo-progress-bar",e}}ProgressBar.animationDuration=300;class HeadSnapshot extends Snapshot{constructor(){super(...arguments),this.detailsByOuterHTML=this.children.filter(e=>!elementIsNoscript(e)).map(e=>elementWithoutNonce(e)).reduce((e,t)=>{var s=t["outerHTML"],r=s in e?e[s]:{type:elementType(t),tracked:elementIsTracked(t),elements:[]};return Object.assign(Object.assign({},e),{[s]:Object.assign(Object.assign({},r),{elements:[...r.elements,t]})})},{})}get trackedElementSignature(){return Object.keys(this.detailsByOuterHTML).filter(e=>this.detailsByOuterHTML[e].tracked).join("")}getScriptElementsNotInSnapshot(e){return this.getElementsMatchingTypeNotInSnapshot("script",e)}getStylesheetElementsNotInSnapshot(e){return this.getElementsMatchingTypeNotInSnapshot("stylesheet",e)}getElementsMatchingTypeNotInSnapshot(t,s){return Object.keys(this.detailsByOuterHTML).filter(e=>!(e in s.detailsByOuterHTML)).map(e=>this.detailsByOuterHTML[e]).filter(({type:e})=>e==t).map(({elements:[e]})=>e)}get provisionalElements(){return Object.keys(this.detailsByOuterHTML).reduce((e,t)=>{var{type:t,tracked:s,elements:r}=this.detailsByOuterHTML[t];return null!=t||s?1{var[t]=this.detailsByOuterHTML[t]["elements"];return elementIsMetaElementWithName(t,s)?t:e},void 0)}}function elementType(e){return elementIsScript(e)?"script":elementIsStylesheet(e)?"stylesheet":void 0}function elementIsTracked(e){return"reload"==e.getAttribute("data-turbo-track")}function elementIsScript(e){return"script"==e.tagName.toLowerCase()}function elementIsNoscript(e){return"noscript"==e.tagName.toLowerCase()}function elementIsStylesheet(e){var t=e.tagName.toLowerCase();return"style"==t||"link"==t&&"stylesheet"==e.getAttribute("rel")}function elementIsMetaElementWithName(e,t){return"meta"==e.tagName.toLowerCase()&&e.getAttribute("name")==t}function elementWithoutNonce(e){return e.hasAttribute("nonce")&&e.setAttribute("nonce",""),e}class PageSnapshot extends Snapshot{constructor(e,t){super(e),this.headSnapshot=t}static fromHTMLString(e=""){return this.fromDocument(parseHTMLDocument(e))}static fromElement(e){return this.fromDocument(e.ownerDocument)}static fromDocument({head:e,body:t}){return new this(t,new HeadSnapshot(e))}clone(){return new PageSnapshot(this.element.cloneNode(!0),this.headSnapshot)}get headElement(){return this.headSnapshot.element}get rootLocation(){var e;return expandURL(null!=(e=this.getSetting("root"))?e:"/")}get cacheControlValue(){return this.getSetting("cache-control")}get isPreviewable(){return"no-preview"!=this.cacheControlValue}get isCacheable(){return"no-cache"!=this.cacheControlValue}get isVisitable(){return"reload"!=this.getSetting("visit-control")}getSetting(e){return this.headSnapshot.getMetaValue("turbo-"+e)}}!function(e){e.visitStart="visitStart",e.requestStart="requestStart",e.requestEnd="requestEnd",e.visitEnd="visitEnd"}(TimingMetric=TimingMetric||{}),function(e){e.initialized="initialized",e.started="started",e.canceled="canceled",e.failed="failed",e.completed="completed"}(VisitState=VisitState||{});const defaultOptions={action:"advance",historyChanged:!1,visitCachedSnapshot:()=>{},willRender:!0};!function(e){e[e.networkFailure=0]="networkFailure",e[e.timeoutFailure=-1]="timeoutFailure",e[e.contentTypeMismatch=-2]="contentTypeMismatch"}(SystemStatusCode=SystemStatusCode||{});class Visit{constructor(e,t,s,r={}){this.identifier=uuid(),this.timingMetrics={},this.followedRedirect=!1,this.historyChanged=!1,this.scrolled=!1,this.snapshotCached=!1,this.state=VisitState.initialized,this.delegate=e,this.location=t,this.restorationIdentifier=s||uuid();var{action:e,historyChanged:t,referrer:s,snapshotHTML:r,response:i,visitCachedSnapshot:n,willRender:o}=Object.assign(Object.assign({},defaultOptions),r);this.action=e,this.historyChanged=t,this.referrer=s,this.snapshotHTML=r,this.response=i,this.isSamePage=this.delegate.locationWithActionIsSamePage(this.location,this.action),this.visitCachedSnapshot=n,this.willRender=o,this.scrolled=!o}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get history(){return this.delegate.history}get restorationData(){return this.history.getRestorationDataForIdentifier(this.restorationIdentifier)}get silent(){return this.isSamePage}start(){this.state==VisitState.initialized&&(this.recordTimingMetric(TimingMetric.visitStart),this.state=VisitState.started,this.adapter.visitStarted(this),this.delegate.visitStarted(this))}cancel(){this.state==VisitState.started&&(this.request&&this.request.cancel(),this.cancelRender(),this.state=VisitState.canceled)}complete(){this.state==VisitState.started&&(this.recordTimingMetric(TimingMetric.visitEnd),this.state=VisitState.completed,this.adapter.visitCompleted(this),this.delegate.visitCompleted(this),this.followRedirect())}fail(){this.state==VisitState.started&&(this.state=VisitState.failed,this.adapter.visitFailed(this))}changeHistory(){var e;this.historyChanged||(e=this.location.href===(null==(e=this.referrer)?void 0:e.href)?"replace":this.action,e=this.getHistoryMethodForAction(e),this.history.update(e,this.location,this.restorationIdentifier),this.historyChanged=!0)}issueRequest(){this.hasPreloadedResponse()?this.simulateRequest():this.shouldIssueRequest()&&!this.request&&(this.request=new FetchRequest(this,FetchMethod.get,this.location),this.request.perform())}simulateRequest(){this.response&&(this.startRequest(),this.recordResponse(),this.finishRequest())}startRequest(){this.recordTimingMetric(TimingMetric.requestStart),this.adapter.visitRequestStarted(this)}recordResponse(e=this.response){(this.response=e)&&(e=e["statusCode"],isSuccessful(e)?this.adapter.visitRequestCompleted(this):this.adapter.visitRequestFailedWithStatusCode(this,e))}finishRequest(){this.recordTimingMetric(TimingMetric.requestEnd),this.adapter.visitRequestFinished(this)}loadResponse(){if(this.response){const{statusCode:e,responseHTML:t}=this.response;this.render(async()=>{this.cacheSnapshot(),this.view.renderPromise&&await this.view.renderPromise,isSuccessful(e)&&null!=t?(await this.view.renderPage(PageSnapshot.fromHTMLString(t),!1,this.willRender),this.adapter.visitRendered(this),this.complete()):(await this.view.renderError(PageSnapshot.fromHTMLString(t)),this.adapter.visitRendered(this),this.fail())})}}getCachedSnapshot(){var e=this.view.getCachedSnapshotForLocation(this.location)||this.getPreloadedSnapshot();if(e&&(!getAnchor(this.location)||e.hasAnchor(getAnchor(this.location)))&&("restore"==this.action||e.isPreviewable))return e}getPreloadedSnapshot(){if(this.snapshotHTML)return PageSnapshot.fromHTMLString(this.snapshotHTML)}hasCachedSnapshot(){return null!=this.getCachedSnapshot()}loadCachedSnapshot(){const e=this.getCachedSnapshot();if(e){const t=this.shouldIssueRequest();this.render(async()=>{this.cacheSnapshot(),this.isSamePage?this.adapter.visitRendered(this):(this.view.renderPromise&&await this.view.renderPromise,await this.view.renderPage(e,t,this.willRender),this.adapter.visitRendered(this),t||this.complete())})}}followRedirect(){var e;this.redirectedToLocation&&!this.followedRedirect&&null!=(e=this.response)&&e.redirected&&(this.adapter.visitProposedToLocation(this.redirectedToLocation,{action:"replace",response:this.response}),this.followedRedirect=!0)}goToSamePageAnchor(){this.isSamePage&&this.render(async()=>{this.cacheSnapshot(),this.adapter.visitRendered(this)})}requestStarted(){this.startRequest()}requestPreventedHandlingResponse(e,t){}async requestSucceededWithResponse(e,t){var s=await t.responseHTML,{redirected:r,statusCode:i}=t;null==s?this.recordResponse({statusCode:SystemStatusCode.contentTypeMismatch,redirected:r}):(this.redirectedToLocation=t.redirected?t.location:void 0,this.recordResponse({statusCode:i,responseHTML:s,redirected:r}))}async requestFailedWithResponse(e,t){var s=await t.responseHTML,{redirected:t,statusCode:r}=t;null==s?this.recordResponse({statusCode:SystemStatusCode.contentTypeMismatch,redirected:t}):this.recordResponse({statusCode:r,responseHTML:s,redirected:t})}requestErrored(e,t){this.recordResponse({statusCode:SystemStatusCode.networkFailure,redirected:!1})}requestFinished(){this.finishRequest()}performScroll(){this.scrolled||("restore"==this.action?this.scrollToRestoredPosition()||this.scrollToAnchor()||this.view.scrollToTop():this.scrollToAnchor()||this.view.scrollToTop(),this.isSamePage&&this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation,this.location),this.scrolled=!0)}scrollToRestoredPosition(){var e=this.restorationData["scrollPosition"];if(e)return this.view.scrollToPosition(e),!0}scrollToAnchor(){var e=getAnchor(this.location);if(null!=e)return this.view.scrollToAnchor(e),!0}recordTimingMetric(e){this.timingMetrics[e]=(new Date).getTime()}getTimingMetrics(){return Object.assign({},this.timingMetrics)}getHistoryMethodForAction(e){switch(e){case"replace":return history.replaceState;case"advance":case"restore":return history.pushState}}hasPreloadedResponse(){return"object"==typeof this.response}shouldIssueRequest(){return!this.isSamePage&&("restore"==this.action?!this.hasCachedSnapshot():this.willRender)}cacheSnapshot(){this.snapshotCached||(this.view.cacheSnapshot().then(e=>e&&this.visitCachedSnapshot(e)),this.snapshotCached=!0)}async render(e){this.cancelRender(),await new Promise(e=>{this.frame=requestAnimationFrame(()=>e())}),await e(),delete this.frame,this.performScroll()}cancelRender(){this.frame&&(cancelAnimationFrame(this.frame),delete this.frame)}}function isSuccessful(e){return 200<=e&&e<300}class BrowserAdapter{constructor(e){this.progressBar=new ProgressBar,this.showProgressBar=()=>{this.progressBar.show()},this.session=e}visitProposedToLocation(e,t){this.navigator.startVisit(e,uuid(),t)}visitStarted(e){e.loadCachedSnapshot(),e.issueRequest(),e.changeHistory(),e.goToSamePageAnchor()}visitRequestStarted(e){this.progressBar.setValue(0),e.hasCachedSnapshot()||"restore"!=e.action?this.showVisitProgressBarAfterDelay():this.showProgressBar()}visitRequestCompleted(e){e.loadResponse()}visitRequestFailedWithStatusCode(e,t){switch(t){case SystemStatusCode.networkFailure:case SystemStatusCode.timeoutFailure:case SystemStatusCode.contentTypeMismatch:return this.reload();default:return e.loadResponse()}}visitRequestFinished(e){this.progressBar.setValue(1),this.hideVisitProgressBar()}visitCompleted(e){}pageInvalidated(){this.reload()}visitFailed(e){}visitRendered(e){}formSubmissionStarted(e){this.progressBar.setValue(0),this.showFormProgressBarAfterDelay()}formSubmissionFinished(e){this.progressBar.setValue(1),this.hideFormProgressBar()}showVisitProgressBarAfterDelay(){this.visitProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay)}hideVisitProgressBar(){this.progressBar.hide(),null!=this.visitProgressBarTimeout&&(window.clearTimeout(this.visitProgressBarTimeout),delete this.visitProgressBarTimeout)}showFormProgressBarAfterDelay(){null==this.formProgressBarTimeout&&(this.formProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay))}hideFormProgressBar(){this.progressBar.hide(),null!=this.formProgressBarTimeout&&(window.clearTimeout(this.formProgressBarTimeout),delete this.formProgressBarTimeout)}reload(){window.location.reload()}get navigator(){return this.session.navigator}}class CacheObserver{constructor(){this.started=!1}start(){this.started||(this.started=!0,addEventListener("turbo:before-cache",this.removeStaleElements,!1))}stop(){this.started&&(this.started=!1,removeEventListener("turbo:before-cache",this.removeStaleElements,!1))}removeStaleElements(){for(const e of[...document.querySelectorAll('[data-turbo-cache="false"]')])e.remove()}}class FormSubmitObserver{constructor(e){this.started=!1,this.submitCaptured=()=>{removeEventListener("submit",this.submitBubbled,!1),addEventListener("submit",this.submitBubbled,!1)},this.submitBubbled=e=>{var t,s;e.defaultPrevented||(t=e.target instanceof HTMLFormElement?e.target:void 0,s=e.submitter||void 0,t&&"dialog"!=((null==s?void 0:s.getAttribute("formmethod"))||t.getAttribute("method"))&&this.delegate.willSubmitForm(t,s)&&(e.preventDefault(),this.delegate.formSubmitted(t,s)))},this.delegate=e}start(){this.started||(addEventListener("submit",this.submitCaptured,!0),this.started=!0)}stop(){this.started&&(removeEventListener("submit",this.submitCaptured,!0),this.started=!1)}}class FrameRedirector{constructor(e){this.element=e,this.linkInterceptor=new LinkInterceptor(this,e),this.formInterceptor=new FormInterceptor(this,e)}start(){this.linkInterceptor.start(),this.formInterceptor.start()}stop(){this.linkInterceptor.stop(),this.formInterceptor.stop()}shouldInterceptLinkClick(e,t){return this.shouldRedirect(e)}linkClickIntercepted(e,t){var s=this.findFrameElement(e);s&&s.delegate.linkClickIntercepted(e,t)}shouldInterceptFormSubmission(e,t){return this.shouldSubmit(e,t)}formSubmissionIntercepted(e,t){var s=this.findFrameElement(e,t);s&&(s.removeAttribute("reloadable"),s.delegate.formSubmissionIntercepted(e,t))}shouldSubmit(e,t){var s=getAction(e,t),r=this.element.ownerDocument.querySelector('meta[name="turbo-root"]'),r=expandURL(null!=(r=null==r?void 0:r.content)?r:"/");return this.shouldRedirect(e,t)&&locationIsVisitable(s,r)}shouldRedirect(e,t){t=this.findFrameElement(e,t);return!!t&&t!=e.closest("turbo-frame")}findFrameElement(e,t){t=(null==t?void 0:t.getAttribute("data-turbo-frame"))||e.getAttribute("data-turbo-frame");if(t&&"_top"!=t){e=this.element.querySelector(`#${t}:not([disabled])`);if(e instanceof FrameElement)return e}}}class History{constructor(e){this.restorationIdentifier=uuid(),this.restorationData={},this.started=!1,this.pageLoaded=!1,this.onPopState=e=>{this.shouldHandlePopState()&&(e=(e.state||{})["turbo"],e)&&(this.location=new URL(window.location.href),e=e["restorationIdentifier"],this.restorationIdentifier=e,this.delegate.historyPoppedToLocationWithRestorationIdentifier(this.location,e))},this.onPageLoad=async e=>{await nextMicrotask(),this.pageLoaded=!0},this.delegate=e}start(){this.started||(addEventListener("popstate",this.onPopState,!1),addEventListener("load",this.onPageLoad,!1),this.started=!0,this.replace(new URL(window.location.href)))}stop(){this.started&&(removeEventListener("popstate",this.onPopState,!1),removeEventListener("load",this.onPageLoad,!1),this.started=!1)}push(e,t){this.update(history.pushState,e,t)}replace(e,t){this.update(history.replaceState,e,t)}update(e,t,s=uuid()){e.call(history,{turbo:{restorationIdentifier:s}},"",t.href),this.location=t,this.restorationIdentifier=s}getRestorationDataForIdentifier(e){return this.restorationData[e]||{}}updateRestorationData(e){var t=this["restorationIdentifier"],s=this.restorationData[t];this.restorationData[t]=Object.assign(Object.assign({},s),e)}assumeControlOfScrollRestoration(){var e;this.previousScrollRestoration||(this.previousScrollRestoration=null!=(e=history.scrollRestoration)?e:"auto",history.scrollRestoration="manual")}relinquishControlOfScrollRestoration(){this.previousScrollRestoration&&(history.scrollRestoration=this.previousScrollRestoration,delete this.previousScrollRestoration)}shouldHandlePopState(){return this.pageIsLoaded()}pageIsLoaded(){return this.pageLoaded||"complete"==document.readyState}}class LinkClickObserver{constructor(e){this.started=!1,this.clickCaptured=()=>{removeEventListener("click",this.clickBubbled,!1),addEventListener("click",this.clickBubbled,!1)},this.clickBubbled=e=>{var t,s;this.clickEventIsSignificant(e)&&(t=e.composedPath&&e.composedPath()[0]||e.target,t=this.findLinkFromClickTarget(t))&&(s=this.getLocationForLink(t),this.delegate.willFollowLinkToLocation(t,s))&&(e.preventDefault(),this.delegate.followedLinkToLocation(t,s))},this.delegate=e}start(){this.started||(addEventListener("click",this.clickCaptured,!0),this.started=!0)}stop(){this.started&&(removeEventListener("click",this.clickCaptured,!0),this.started=!1)}clickEventIsSignificant(e){return!(e.target&&e.target.isContentEditable||e.defaultPrevented||1{var e=this["readyState"];"interactive"==e?this.pageIsInteractive():"complete"==e&&this.pageIsComplete()},this.pageWillUnload=()=>{this.delegate.pageWillUnload()},this.delegate=e}start(){this.started||(this.stage==PageStage.initial&&(this.stage=PageStage.loading),document.addEventListener("readystatechange",this.interpretReadyState,!1),addEventListener("pagehide",this.pageWillUnload,!1),this.started=!0)}stop(){this.started&&(document.removeEventListener("readystatechange",this.interpretReadyState,!1),removeEventListener("pagehide",this.pageWillUnload,!1),this.started=!1)}pageIsInteractive(){this.stage==PageStage.loading&&(this.stage=PageStage.interactive,this.delegate.pageBecameInteractive())}pageIsComplete(){this.pageIsInteractive(),this.stage==PageStage.interactive&&(this.stage=PageStage.complete,this.delegate.pageLoaded())}get readyState(){return document.readyState}}class ScrollObserver{constructor(e){this.started=!1,this.onScroll=()=>{this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})},this.delegate=e}start(){this.started||(addEventListener("scroll",this.onScroll,!1),this.onScroll(),this.started=!0)}stop(){this.started&&(removeEventListener("scroll",this.onScroll,!1),this.started=!1)}updatePosition(e){this.delegate.scrollPositionChanged(e)}}class StreamObserver{constructor(e){this.sources=new Set,this.started=!1,this.inspectFetchResponse=e=>{var t=fetchResponseFromEvent(e);t&&fetchResponseIsStream(t)&&(e.preventDefault(),this.receiveMessageResponse(t))},this.receiveMessageEvent=e=>{this.started&&"string"==typeof e.data&&this.receiveMessageHTML(e.data)},this.delegate=e}start(){this.started||(this.started=!0,addEventListener("turbo:before-fetch-response",this.inspectFetchResponse,!1))}stop(){this.started&&(this.started=!1,removeEventListener("turbo:before-fetch-response",this.inspectFetchResponse,!1))}connectStreamSource(e){this.streamSourceIsConnected(e)||(this.sources.add(e),e.addEventListener("message",this.receiveMessageEvent,!1))}disconnectStreamSource(e){this.streamSourceIsConnected(e)&&(this.sources.delete(e),e.removeEventListener("message",this.receiveMessageEvent,!1))}streamSourceIsConnected(e){return this.sources.has(e)}async receiveMessageResponse(e){e=await e.responseHTML;e&&this.receiveMessageHTML(e)}receiveMessageHTML(e){this.delegate.receivedMessageFromStream(new StreamMessage(e))}}function fetchResponseFromEvent(e){e=null==(e=e.detail)?void 0:e.fetchResponse;if(e instanceof FetchResponse)return e}function fetchResponseIsStream(e){return(null!=(e=e.contentType)?e:"").startsWith(StreamMessage.contentType)}class ErrorRenderer extends Renderer{async render(){this.replaceHeadAndBody(),this.activateScriptElements()}replaceHeadAndBody(){var{documentElement:e,head:t,body:s}=document;e.replaceChild(this.newHead,t),e.replaceChild(this.newElement,s)}activateScriptElements(){for(const s of this.scriptElements){var e,t=s.parentNode;t&&(e=this.createScriptElement(s),t.replaceChild(e,s))}}get newHead(){return this.newSnapshot.headSnapshot.element}get scriptElements(){return[...document.documentElement.querySelectorAll("script")]}}class PageRenderer extends Renderer{get shouldRender(){return this.newSnapshot.isVisitable&&this.trackedElementsAreIdentical}prepareToRender(){this.mergeHead()}async render(){this.willRender&&this.replaceBody()}finishRendering(){super.finishRendering(),this.isPreview||this.focusFirstAutofocusableElement()}get currentHeadSnapshot(){return this.currentSnapshot.headSnapshot}get newHeadSnapshot(){return this.newSnapshot.headSnapshot}get newElement(){return this.newSnapshot.element}mergeHead(){this.copyNewHeadStylesheetElements(),this.copyNewHeadScriptElements(),this.removeCurrentHeadProvisionalElements(),this.copyNewHeadProvisionalElements()}replaceBody(){this.preservingPermanentElements(()=>{this.activateNewBody(),this.assignNewBody()})}get trackedElementsAreIdentical(){return this.currentHeadSnapshot.trackedElementSignature==this.newHeadSnapshot.trackedElementSignature}copyNewHeadStylesheetElements(){for(const e of this.newHeadStylesheetElements)document.head.appendChild(e)}copyNewHeadScriptElements(){for(const e of this.newHeadScriptElements)document.head.appendChild(this.createScriptElement(e))}removeCurrentHeadProvisionalElements(){for(const e of this.currentHeadProvisionalElements)document.head.removeChild(e)}copyNewHeadProvisionalElements(){for(const e of this.newHeadProvisionalElements)document.head.appendChild(e)}activateNewBody(){document.adoptNode(this.newElement),this.activateNewBodyScriptElements()}activateNewBodyScriptElements(){for(const t of this.newBodyScriptElements){var e=this.createScriptElement(t);t.replaceWith(e)}}assignNewBody(){document.body&&this.newElement instanceof HTMLBodyElement?document.body.replaceWith(this.newElement):document.documentElement.appendChild(this.newElement)}get newHeadStylesheetElements(){return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot)}get newHeadScriptElements(){return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot)}get currentHeadProvisionalElements(){return this.currentHeadSnapshot.provisionalElements}get newHeadProvisionalElements(){return this.newHeadSnapshot.provisionalElements}get newBodyScriptElements(){return this.newElement.querySelectorAll("script")}}class SnapshotCache{constructor(e){this.keys=[],this.snapshots={},this.size=e}has(e){return toCacheKey(e)in this.snapshots}get(e){var t;if(this.has(e))return t=this.read(e),this.touch(e),t}put(e,t){return this.write(e,t),this.touch(e),t}clear(){this.snapshots={}}read(e){return this.snapshots[toCacheKey(e)]}write(e,t){this.snapshots[toCacheKey(e)]=t}touch(e){var e=toCacheKey(e),t=this.keys.indexOf(e);-1s.remove())):s.addEventListener("submit",()=>s.remove()),document.body.appendChild(s),dispatch("submit",{cancelable:!0,target:s})}return!1}allowsVisitingLocationWithAction(e,t){return this.locationWithActionIsSamePage(e,t)||this.applicationAllowsVisitingLocation(e)}visitProposedToLocation(e,t){extendURLWithDeprecatedProperties(e),this.adapter.visitProposedToLocation(e,t)}visitStarted(e){extendURLWithDeprecatedProperties(e.location),e.silent||this.notifyApplicationAfterVisitingLocation(e.location,e.action)}visitCompleted(e){this.notifyApplicationAfterPageLoad(e.getTimingMetrics())}locationWithActionIsSamePage(e,t){return this.navigator.locationWithActionIsSamePage(e,t)}visitScrolledToSamePageLocation(e,t){this.notifyApplicationAfterVisitingSamePageLocation(e,t)}willSubmitForm(e,t){var s=getAction(e,t);return this.elementDriveEnabled(e)&&(!t||this.elementDriveEnabled(t))&&locationIsVisitable(expandURL(s),this.snapshot.rootLocation)}formSubmitted(e,t){this.navigator.submitForm(e,t)}pageBecameInteractive(){this.view.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()}pageLoaded(){this.history.assumeControlOfScrollRestoration()}pageWillUnload(){this.history.relinquishControlOfScrollRestoration()}receivedMessageFromStream(e){this.renderStreamMessage(e)}viewWillCacheSnapshot(){var e;null!=(e=this.navigator.currentVisit)&&e.silent||this.notifyApplicationBeforeCachingSnapshot()}allowsImmediateRender({element:e},t){return!this.notifyApplicationBeforeRender(e,t).defaultPrevented}viewRenderedSnapshot(e,t){this.view.lastRenderedLocation=this.history.location,this.notifyApplicationAfterRender()}viewInvalidated(){this.adapter.pageInvalidated()}frameLoaded(e){this.notifyApplicationAfterFrameLoad(e)}frameRendered(e,t){this.notifyApplicationAfterFrameRender(e,t)}applicationAllowsFollowingLinkToLocation(e,t){return!this.notifyApplicationAfterClickingLinkToLocation(e,t).defaultPrevented}applicationAllowsVisitingLocation(e){return!this.notifyApplicationBeforeVisitingLocation(e).defaultPrevented}notifyApplicationAfterClickingLinkToLocation(e,t){return dispatch("turbo:click",{target:e,detail:{url:t.href},cancelable:!0})}notifyApplicationBeforeVisitingLocation(e){return dispatch("turbo:before-visit",{detail:{url:e.href},cancelable:!0})}notifyApplicationAfterVisitingLocation(e,t){return markAsBusy(document.documentElement),dispatch("turbo:visit",{detail:{url:e.href,action:t}})}notifyApplicationBeforeCachingSnapshot(){return dispatch("turbo:before-cache")}notifyApplicationBeforeRender(e,t){return dispatch("turbo:before-render",{detail:{newBody:e,resume:t},cancelable:!0})}notifyApplicationAfterRender(){return dispatch("turbo:render")}notifyApplicationAfterPageLoad(e={}){return clearBusyState(document.documentElement),dispatch("turbo:load",{detail:{url:this.location.href,timing:e}})}notifyApplicationAfterVisitingSamePageLocation(e,t){dispatchEvent(new HashChangeEvent("hashchange",{oldURL:e.toString(),newURL:t.toString()}))}notifyApplicationAfterFrameLoad(e){return dispatch("turbo:frame-load",{target:e})}notifyApplicationAfterFrameRender(e,t){return dispatch("turbo:frame-render",{detail:{fetchResponse:e},target:t,cancelable:!0})}elementDriveEnabled(e){e=null==e?void 0:e.closest("[data-turbo]");return this.drive?!e||"false"!=e.getAttribute("data-turbo"):!!e&&"true"==e.getAttribute("data-turbo")}getActionForLink(e){e=e.getAttribute("data-turbo-action");return isAction(e)?e:"advance"}getTargetFrameForLink(e){var t=e.getAttribute("data-turbo-frame");return t||((t=e.closest("turbo-frame"))?t.id:void 0)}get snapshot(){return this.view.snapshot}}function extendURLWithDeprecatedProperties(e){Object.defineProperties(e,deprecatedLocationPropertyDescriptors)}const deprecatedLocationPropertyDescriptors={absoluteURL:{get(){return this.toString()}}},session=new Session,navigator$1=session["navigator"];function start(){session.start()}function registerAdapter(e){session.registerAdapter(e)}function visit(e,t){session.visit(e,t)}function connectStreamSource(e){session.connectStreamSource(e)}function disconnectStreamSource(e){session.disconnectStreamSource(e)}function renderStreamMessage(e){session.renderStreamMessage(e)}function clearCache(){session.clearCache()}function setProgressBarDelay(e){session.setProgressBarDelay(e)}function setConfirmMethod(e){FormSubmission.confirmMethod=e}var Turbo=Object.freeze({__proto__:null,navigator:navigator$1,session:session,PageRenderer:PageRenderer,PageSnapshot:PageSnapshot,start:start,registerAdapter:registerAdapter,visit:visit,connectStreamSource:connectStreamSource,disconnectStreamSource:disconnectStreamSource,renderStreamMessage:renderStreamMessage,clearCache:clearCache,setProgressBarDelay:setProgressBarDelay,setConfirmMethod:setConfirmMethod});class FrameController{constructor(e){this.fetchResponseLoaded=e=>{},this.currentFetchRequest=null,this.resolveVisitPromise=()=>{},this.connected=!1,this.hasBeenLoaded=!1,this.settingSourceURL=!1,this.element=e,this.view=new FrameView(this,this.element),this.appearanceObserver=new AppearanceObserver(this,this.element),this.linkInterceptor=new LinkInterceptor(this,this.element),this.formInterceptor=new FormInterceptor(this,this.element)}connect(){this.connected||(this.connected=!0,this.reloadable=!1,this.loadingStyle==FrameLoadingStyle.lazy&&this.appearanceObserver.start(),this.linkInterceptor.start(),this.formInterceptor.start(),this.sourceURLChanged())}disconnect(){this.connected&&(this.connected=!1,this.appearanceObserver.stop(),this.linkInterceptor.stop(),this.formInterceptor.stop())}disabledChanged(){this.loadingStyle==FrameLoadingStyle.eager&&this.loadSourceURL()}sourceURLChanged(){this.loadingStyle!=FrameLoadingStyle.eager&&!this.hasBeenLoaded||this.loadSourceURL()}loadingStyleChanged(){this.loadingStyle==FrameLoadingStyle.lazy?this.appearanceObserver.start():(this.appearanceObserver.stop(),this.loadSourceURL())}async loadSourceURL(){if(!this.settingSourceURL&&this.enabled&&this.isActive&&(this.reloadable||this.sourceURL!=this.currentURL)){var t=this.currentURL;if(this.currentURL=this.sourceURL,this.sourceURL)try{this.element.loaded=this.visit(expandURL(this.sourceURL)),this.appearanceObserver.stop(),await this.element.loaded,this.hasBeenLoaded=!0}catch(e){throw this.currentURL=t,e}}}async loadResponse(e){(e.redirected||e.succeeded&&e.isHTML)&&(this.sourceURL=e.response.url);try{var t,s,r,i=await e.responseHTML;i&&(t=parseHTMLDocument(i)["body"],s=new Snapshot(await this.extractForeignFrameElement(t)),r=new FrameRenderer(this.view.snapshot,s,!1,!1),this.view.renderPromise&&await this.view.renderPromise,await this.view.render(r),session.frameRendered(e,this.element),session.frameLoaded(this.element),this.fetchResponseLoaded(e))}catch(e){console.error(e),this.view.invalidate()}finally{this.fetchResponseLoaded=()=>{}}}elementAppearedInViewport(e){this.loadSourceURL()}shouldInterceptLinkClick(e,t){return!e.hasAttribute("data-turbo-method")&&this.shouldInterceptNavigation(e)}linkClickIntercepted(e,t){this.reloadable=!0,this.navigateFrame(e,t)}shouldInterceptFormSubmission(e,t){return this.shouldInterceptNavigation(e,t)}formSubmissionIntercepted(e,t){this.formSubmission&&this.formSubmission.stop(),this.reloadable=!1,this.formSubmission=new FormSubmission(this,e,t);e=this.formSubmission.fetchRequest;this.prepareHeadersForRequest(e.headers,e),this.formSubmission.start()}prepareHeadersForRequest(e,t){e["Turbo-Frame"]=this.id}requestStarted(e){markAsBusy(this.element)}requestPreventedHandlingResponse(e,t){this.resolveVisitPromise()}async requestSucceededWithResponse(e,t){await this.loadResponse(t),this.resolveVisitPromise()}requestFailedWithResponse(e,t){console.error(t),this.resolveVisitPromise()}requestErrored(e,t){console.error(t),this.resolveVisitPromise()}requestFinished(e){clearBusyState(this.element)}formSubmissionStarted({formElement:e}){markAsBusy(e,this.findFrameElement(e))}formSubmissionSucceededWithResponse(e,t){var s=this.findFrameElement(e.formElement,e.submitter);this.proposeVisitIfNavigatedWithAction(s,e.formElement,e.submitter),s.delegate.loadResponse(t)}formSubmissionFailedWithResponse(e,t){this.element.delegate.loadResponse(t)}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished({formElement:e}){clearBusyState(e,this.findFrameElement(e))}allowsImmediateRender(e,t){return!0}viewRenderedSnapshot(e,t){}viewInvalidated(){}async visit(e){const t=new FetchRequest(this,FetchMethod.get,e,new URLSearchParams,this.element);return null!=(e=this.currentFetchRequest)&&e.cancel(),this.currentFetchRequest=t,new Promise(e=>{this.resolveVisitPromise=()=>{this.resolveVisitPromise=()=>{},this.currentFetchRequest=null,e()},t.perform()})}navigateFrame(e,t,s){var r=this.findFrameElement(e,s);this.proposeVisitIfNavigatedWithAction(r,e,s),r.setAttribute("reloadable",""),r.src=t}proposeVisitIfNavigatedWithAction(s,e,t){const r=getAttribute("data-turbo-action",t,e,s);if(isAction(r)){const i=new SnapshotSubstitution(s)["visitCachedSnapshot"];s.delegate.fetchResponseLoaded=e=>{var t;s.src&&({statusCode:e,redirected:t}=e,e={statusCode:e,redirected:t,responseHTML:s.ownerDocument.documentElement.outerHTML},session.visit(s.src,{action:r,response:e,visitCachedSnapshot:i,willRender:!1}))}}}findFrameElement(e,t){return null!=(t=getFrameElementById(getAttribute("data-turbo-frame",t,e)||this.element.getAttribute("target")))?t:this.element}async extractForeignFrameElement(e){var t,s=CSS.escape(this.id);try{if(t=activateElement(e.querySelector("turbo-frame#"+s),this.currentURL))return t;if(t=activateElement(e.querySelector(`turbo-frame[src][recurse~=${s}]`),this.currentURL))return await t.loaded,await this.extractForeignFrameElement(t);console.error(`Response has no matching element`)}catch(e){console.error(e)}return new FrameElement}formActionIsVisitable(e,t){return locationIsVisitable(expandURL(getAction(e,t)),this.rootLocation)}shouldInterceptNavigation(e,t){var s=getAttribute("data-turbo-frame",t,e)||this.element.getAttribute("target");if(e instanceof HTMLFormElement&&!this.formActionIsVisitable(e,t))return!1;if(!this.enabled||"_top"==s)return!1;if(s){s=getFrameElementById(s);if(s)return!s.disabled}return!(!session.elementDriveEnabled(e)||t&&!session.elementDriveEnabled(t))}get id(){return this.element.id}get enabled(){return!this.element.disabled}get sourceURL(){if(this.element.src)return this.element.src}get reloadable(){return this.findFrameElement(this.element).hasAttribute("reloadable")}set reloadable(e){var t=this.findFrameElement(this.element);e?t.setAttribute("reloadable",""):t.removeAttribute("reloadable")}set sourceURL(e){this.settingSourceURL=!0,this.element.src=null!=e?e:null,this.currentURL=this.element.src,this.settingSourceURL=!1}get loadingStyle(){return this.element.loading}get isLoading(){return void 0!==this.formSubmission||void 0!==this.resolveVisitPromise()}get isActive(){return this.element.isActive&&this.connected}get rootLocation(){var e=this.element.ownerDocument.querySelector('meta[name="turbo-root"]');return expandURL(null!=(e=null==e?void 0:e.content)?e:"/")}}class SnapshotSubstitution{constructor(e){this.visitCachedSnapshot=({element:e})=>{var{id:t,clone:s}=this;null!=(e=e.querySelector("#"+t))&&e.replaceWith(s)},this.clone=e.cloneNode(!0),this.id=e.id}}function getFrameElementById(e){if(null!=e){e=document.getElementById(e);if(e instanceof FrameElement)return e}}function activateElement(e,t){if(e){var s=e.getAttribute("src");if(null!=s&&null!=t&&urlsAreEqual(s,t))throw new Error(`Matching element has a source URL which references itself`);if((e=e.ownerDocument!==document?document.importNode(e,!0):e)instanceof FrameElement)return e.connectedCallback(),e.disconnectedCallback(),e}}const StreamActions={after(){this.targetElements.forEach(e=>{var t;return null==(t=e.parentElement)?void 0:t.insertBefore(this.templateContent,e.nextSibling)})},append(){this.removeDuplicateTargetChildren(),this.targetElements.forEach(e=>e.append(this.templateContent))},before(){this.targetElements.forEach(e=>{var t;return null==(t=e.parentElement)?void 0:t.insertBefore(this.templateContent,e)})},prepend(){this.removeDuplicateTargetChildren(),this.targetElements.forEach(e=>e.prepend(this.templateContent))},remove(){this.targetElements.forEach(e=>e.remove())},replace(){this.targetElements.forEach(e=>e.replaceWith(this.templateContent))},update(){this.targetElements.forEach(e=>{e.innerHTML="",e.append(this.templateContent)})}};class StreamElement extends HTMLElement{async connectedCallback(){try{await this.render()}catch(e){console.error(e)}finally{this.disconnect()}}async render(){var e;return null!=(e=this.renderPromise)?e:this.renderPromise=(async()=>{this.dispatchEvent(this.beforeRenderEvent)&&(await nextAnimationFrame(),this.performAction())})()}disconnect(){try{this.remove()}catch(e){}}removeDuplicateTargetChildren(){this.duplicateChildren.forEach(e=>e.remove())}get duplicateChildren(){var e,t=this.targetElements.flatMap(e=>[...e.children]).filter(e=>!!e.id);const s=[...null==(e=this.templateContent)?void 0:e.children].filter(e=>!!e.id).map(e=>e.id);return t.filter(e=>s.includes(e.id))}get performAction(){if(this.action){var e=StreamActions[this.action];if(e)return e;this.raise("unknown action")}this.raise("action attribute is missing")}get targetElements(){return this.target?this.targetElementsById:this.targets?this.targetElementsByQuery:void this.raise("target or targets attribute is missing")}get templateContent(){return this.templateElement.content.cloneNode(!0)}get templateElement(){if(this.firstElementChild instanceof HTMLTemplateElement)return this.firstElementChild;this.raise("first child element must be a element")}get action(){return this.getAttribute("action")}get target(){return this.getAttribute("target")}get targets(){return this.getAttribute("targets")}raise(e){throw new Error(this.description+": "+e)}get description(){var e;return null!=(e=(null!=(e=this.outerHTML.match(/<[^>]+>/))?e:[])[0])?e:""}get beforeRenderEvent(){return new CustomEvent("turbo:before-stream-render",{bubbles:!0,cancelable:!0})}get targetElementsById(){var e=null==(e=this.ownerDocument)?void 0:e.getElementById(this.target);return null!==e?[e]:[]}get targetElementsByQuery(){var e=null==(e=this.ownerDocument)?void 0:e.querySelectorAll(this.targets);return 0!==e.length?Array.prototype.slice.call(e):[]}}FrameElement.delegateConstructor=FrameController,customElements.define("turbo-frame",FrameElement),customElements.define("turbo-stream",StreamElement),(()=>{let e=document.currentScript;if(e&&!e.hasAttribute("data-turbo-suppress-warning"))for(;e=e.parentElement;)if(e==document.body)return console.warn(unindent`
+ You are loading Turbo from a
+
+
+
+
+
+
+
+ User Guide - PDF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Table of contents
+
+
+
+
+ 6.2.1.1.2
+
+
+ MARKUP
+
+
+
+
+
+
+ 6.2.2.1
+
+
+ TEXT
+
+
+
+
+
+
+ 6.2.3.1
+
+
+ SECTION
+
+
+
+
+
+
+ 6.2.4.2
+
+
+ UID
+
+
+
+
+
+
+ 6.2.4.3
+
+
+ LEVEL
+
+
+
+
+
+
+ 6.2.4.4
+
+
+ STATUS
+
+
+
+
+
+
+ 6.2.4.5
+
+
+ TAGS
+
+
+
+
+
+
+ 6.2.4.6
+
+
+ TITLE
+
+
+
+
+
+
+ 6.2.4.9
+
+
+ COMMENT
+
+
+
+
+
+
+ 6.3.2.2
+
+
+ PREFIX
+
+
+
+
+
+
+ 6.4
+
+
+ Links
+
+
+
+
+
+
+ 6.4.1
+
+
+ Links
+
+
+
+
+
+
+ 7.1
+
+
+ Images
+
+
+
+
+
+
+ 8.4
+
+
+ JSON
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1. Introduction
+
+
+
+
+
+
+
+ MID:
+
+
+75a595ff028741d0bf9067bba8fb787a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+27023bf63c414fd998437961c77a0e2e
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ StrictDoc is software for technical documentation and requirements management.
+ Summary of StrictDoc features:
+
+- The documentation files are stored as human-readable text files.
+- A simple domain-specific language DSL is used for writing the documents. The
+text format for encoding this language is called SDoc (strict-doc).
+- StrictDoc reads *.sdoc files and builds an in-memory representation of a
+document tree.
+- From this in-memory representation, StrictDoc can generate the documentation
+into a number of formats including HTML, RST, ReqIF, PDF, JSON, Excel.
+- StrictDoc has a web-based user interface which allows viewing and editing the documents and requirements. The changes are written back to .sdoc files.
+- The focus of the tool is modeling requirements and specifications documents.
+Such documents consist of multiple statements like "system X shall do Y"
+called requirements.
+- The requirements can be linked together to form the relationships, such as
+"parent-child". From these connections, many useful features, such as
+Requirements Traceability
+and Documentation Coverage, can be derived.
+- Requirements to source files traceability (experimental). See
+🔗 Traceability between requirements and source code.
+- Document grammar and custom fields support. The StrictDoc's grammar can be
+extended to support arbitrary special fields, such as "PRIORITY", "OWNER",
+or even more specialized fields, such as
+"Automotive Safety Integrity Level (ASIL)" or "Verification method".
+See 🔗 Document grammar.
+- Good performance of the textX
+parser and parallelized incremental generation of documents: generation of
+document trees with up to 2000–3000 requirements into HTML pages stays within
+a few seconds. From the second run, only changed documents are regenerated.
+Further performance tuning should be possible.
+
+ See also a summary of StrictDoc's existing limitations: 🔗 StrictDoc's limitations.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1.1. Contact the developers
+
+
+
+
+
+
+
+ MID:
+
+
+bcd0cf7c13cf4cf2ab176455aedc0c90
+
+ UID:
+
+
+SDOC_UG_CONTACT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+3ae6491057674be1abf057b7e0d9bf21
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ Operation young season whom point if. Candidate serious push today box house share. Natural those wife cultural.
+Hot small offer discussion. Personal each floor. Face bit federal area.
+Guess somebody size almost yeah. Respond ready paper. Six ready star bag.
+Station main go rule role machine. Nearly whatever place worker foreign. Court cell single tend popular either suddenly.https://groups.io/g/strictdoc. As of Q1 2025, this is the primary channel for general discussions and announcements about StrictDoc, uniting three previously separate communities: email, GitHub, and Discord.
+ For more interactive discussions, join us in Discord. Here is the invitation link: https://discord.gg/4BAAME9MmG.
+ The developers can be also contacted via email: Stanislav Pankevich s.pankevich@gmail.com and Maryna Balioura mettta@gmail.com.
+ See also 🔗 F.A.Q. for common topics and 🔗 Troubleshooting for troubleshooting the most common issues.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1.1.1. StrictDoc office hours
+
+
+
+
+
+
+
+ MID:
+
+
+8e4ede8cdc70402b91a59026d31a7020
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+c46def916b6f4df692c95f47414feebb
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ The StrictDoc team hosts a weekly 1-hour office hours meeting.
+ StrictDoc Office Hours provide an open space for users and contributors to connect with the core team. Spontaneous participation is highly encouraged – feel free to join at any time with questions, ideas, or feedback. By default, these slots are used for StrictDoc development unless a specific topic is agreed upon in advance.
+ The goal is to balance core development priorities with community-driven input. While the team follows a focused roadmap, these sessions create space for discussing feature requests, improvements, and other topics that matter most to users – especially active contributors. Agenda updates will be posted in the calendar when applicable.
+ Here is a public Google calendar to subscribe to.
+ When adding the calendar, it's recommended to enable notifications for new and updated events. This ensures you'll be informed if an event's agenda is updated with announcements or if the event is canceled.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2. Examples
+
+
+
+
+
+
+
+ MID:
+
+
+e0a00ca3085f444187050ce9576aa31b
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2.1. Hello World
+
+
+
+
+
+
+
+ MID:
+
+
+2122186075e8455181178b01331101fa
+
+ UID:
+
+
+SDOC_UG_HELLO_WORLD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+ffbdb80fb21d48adbaeffb782d7994a2
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ "Hello World" example of the SDoc text language:
+
+[DOCUMENT]
+TITLE: StrictDoc
+
+[REQUIREMENT]
+UID: SDOC-HIGH-REQS-MANAGEMENT
+TITLE: Requirements management
+STATEMENT: StrictDoc shall enable requirements management.
+
+ Create a file called hello_world.sdoc somewhere on your file system and copy the above "Hello World" example text to it. The file must end with a newline character.
+ Open a command-line terminal program supported on your system.
+ Once you have strictdoc installed (see 🔗 Installing StrictDoc below), switch to the directory with the hello_world.sdoc file. For example, assuming that the file is now in the workspace/hello_world directory in your user folder:
+
+cd <your user home directory>/workspace/hello_world
+
+ Run StrictDoc as follows:
+
+strictdoc export .
+
+ The expected output:
+
+$ strictdoc export hello.sdoc
+Parallelization: Enabled
+Step 'Collect traceability information' start
+Step 'Find and read SDoc files' start
+Reading SDOC: hello.sdoc .................................... 0.08s
+Step 'Find and read SDoc files' took: 0.09 sec
+Step 'Collect traceability information' start
+Step 'Collect traceability information' took: 0.01 sec
+Step 'Collect traceability information' took: 0.11 sec
+Published: StrictDoc ........................................ 0.24s
+...
+Export completed. Documentation tree can be found at:
+.../output/html
+
+ The HTML output produced so far has been generated statically. Now, start a StrictDoc server from the same directory:
+
+strictdoc server .
+
+ Rule instead college. Drug space page serve future term. Yard guy low measure approach friend senior. Arm year season heart tax.
+Blood box dog crime down. Turn statement plan.
+Decide reflect smile act. Truth rather despite race scientist. Statement see send from property soldier treatment. After everyone lose yes fly.
+Second bring entire explain. Key way free study team happy real teacher.
+
+INFO: Uvicorn running on http://127.0.0.1:5111 (Press CTRL+C to quit)
+
+ Open the URL in the browser and explore the contents of the example.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2.2. StrictDoc Examples repository
+
+
+
+
+
+
+
+ MID:
+
+
+83369fc77d584407b530b179a449479b
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+d6bde8e4055b42138d216b48692c8f26
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ The strictdoc-examples repository contains a collection of basic examples. Visit the repository and read its README for details.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2.3. StrictDoc Templates repository
+
+
+
+
+
+
+
+ MID:
+
+
+0a736f05ab154b2599988b63201d4f10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+47c2088447d7452ba28962ee220ba63a
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ The strictdoc-templates repository contains a growing collection of templates from the industry standards like DO-178C (aviation) and ECSS-E-ST-40C (space).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2.4. Other examples
+
+
+
+
+
+
+
+ MID:
+
+
+2b2e39c48cc740e5b8452d76881f667d
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+2eaa8bfe5a354fcbb704ea7fd94f3a0a
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ For a more comprehensive example, check the source file of this documentation
+which is written using StrictDoc:
+strictdoc_01_user_guide.sdoc.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3. Installing StrictDoc
+
+
+
+
+
+
+
+ MID:
+
+
+821b818006a14ed7aeb025d9ac8fe8b6
+
+ UID:
+
+
+SDOC_UG_GETTING_STARTED
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3.1. Requirements
+
+
+
+
+
+
+
+ MID:
+
+
+4e9f094a7b2949edb23c817c5e2276e4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+e7e4c2982d8e49deaa9b7413a09a4efa
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+
+- Python 3.9+
+- macOS, Linux or Windows
+- Command-line terminal program
+
+ Depending on an operating system, a terminal program can be, for example:
+
+- Terminal or iTerm2 on macOS
+- Gnome Terminal or konsole on Linux
+- Terminal or PowerShell on Windows.
+
+ A terminal program is required to input all the commands outlined in this user guide.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3.2. Installing StrictDoc as a Pip package (recommended way)
+
+
+
+
+
+
+
+ MID:
+
+
+914da2bf10364a6fbd9fc7f48b96c6e5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+872a60c673854cfd909787f2379d88c7
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+
+pip install strictdoc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3.3. Installing "nightly" StrictDoc as a Pip package
+
+
+
+
+
+
+
+ MID:
+
+
+b3e2c50e2d7e46acbce7ea0c646776ca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+867f22a2767a434586d1ee4f7ee161fb
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ Sometimes, it takes a while before the latest features and fixes reach the stable Pip release. In that case, installing a Pip package from the Git repository directly is possible:
+
+pip install -U --pre git+https://github.com/strictdoc-project/strictdoc.git@main
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3.4. Installing StrictDoc into a Docker container
+
+
+
+
+
+
+
+ MID:
+
+
+9e95ac9422f44aae92c0615176153815
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+32e04944c2a14ead93248ff1ea37a68d
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ StrictDoc can be installed with a dedicated Docker image.
+ To build the image:
+
+docker build . \
+ --build-arg STRICTDOC_SOURCE=pypi \
+ -t strictdoc:latest
+
+ The STRICTDOC_SOURCE argument is optional (default value is pypi) and can be used to specify which Git revision the container shall check out when installing StrictDoc with pip install. Possible values: a branch name, e.g., main, or a commit hash.
+ To run the container:
+
+docker run \
+ --name strictdoc \
+ --rm \
+ -e HOST_UID=$(id -u) \
+ -e HOST_GID=$(id -g) \
+ -v "$(pwd):/data" \
+ -i -t \
+ strictdoc:latest \
+ /bin/bash -c "strictdoc export --formats=html"
+
+
+docker run options breakdown
+
+
+
+
+
+| Option |
+Description |
+
+
+
+| --rm |
+Remove container when it is exited. |
+
+| HOST_UID and HOST_GID |
+These environment variables are used to tell the container that it should create a strictdoc user that has these values. This enables the content generated by the container to be visible outside the container under the permissions of the host user. |
+
+| -v "<folder on host>:/data" |
+Normally the folder on the host should be the folder with the StrictDoc documentation. The /data folder must always be specified without change because that's where the Docker container is designed to operate. |
+
+| /bin/bash -c "..." |
+This command shall typically be strictdoc export but it can also be skipped in which case the docker run will enter the container with SSH. |
+
+
+
+ If entering the container manually, the strictdoc command can be run as follows:
+
+bash-5.1# strictdoc export .
+bash-5.1# exit
+
+ The documentation shall be generated to ./output/html which is accessible both on the host and inside the container.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3.5. Installing StrictDoc as a Snap package (not maintained)
+
+
+
+
+
+
+
+ MID:
+
+
+e441594df15841d38f717194b722f3de
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+2adfe1bc6be542c3885ca4ea80b8d6e1
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ This way of installing StrictDoc is not maintained anymore. If you want to
+use it, refer to the instructions located in developer/snap/README.md.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3.6. Installing StrictDoc with Nix
+
+
+
+
+
+
+
+ MID:
+
+
+4af1193170a7416d81a799344dfc8ed6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+2045b5e37fc34a83b7457c43d816bf2c
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ StrictDoc is packaged in nixpkgs as strictdoc.
+ You can try it without installing with nix-shell:
+
+nix-shell -p strictdoc
+
+ or nix run:
+
+nix run nixpkgs#strictdoc
+
+ Or you can add it to your system's packages with:
+
+environment.systemPackages = [
+ pkgs.strictdoc
+];
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4. Running StrictDoc
+
+
+
+
+
+
+
+ MID:
+
+
+6cc72bf1a2a94999954e148a6bef374c
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4.1. Static HTML export
+
+
+
+
+
+
+
+ MID:
+
+
+1685e4d63d9746b784b4a55f17b0de30
+
+ UID:
+
+
+SECTION-UG-Static-HTML-export
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+c092847abfa04295b63f943c951f24c8
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ The easiest way to see the static HTML export feature in action is to run the 🔗 Hello World example.
+ The export command is the main producer of documentation. The native export format of StrictDoc is HTML. The export command supports a number of parameters, including the option for selecting export formats (HTML, RST, Excel, etc.). The options can be explored with the --help command.
+
+strictdoc export --help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4.2. Web server
+
+
+
+
+
+
+
+ MID:
+
+
+1a059d3ae7da45f8b53f3d74f3580980
+
+ UID:
+
+
+SECTION-UG-Web-server
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+1fc9f6f4f84d47439bf6aa3404227ca4
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ StrictDoc supports a web-based user interface. The StrictDoc web server is launched via the server command which accepts a path to a documentation tree as a parameter.
+
+strictdoc server .
+
+ The server command accepts a number of options. To explore the options, run:
+
+strictdoc server --help
+
+ StrictDoc uses 127.0.0.1 as a default host and 5111 as a default port. When running within Docker, the host argument --host can be specified, for example, --host 0.0.0.0 or a more specific host or IP address. The host and port can be also configured in a TOML config file, see 🔗 Host and port.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4.3. Security considerations
+
+
+
+
+
+
+
+ MID:
+
+
+9f7fcbdd8e564af8986349deb09745a5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+4fa89608f70e4a84a0e4b2930da28bbe
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+
+ Warning
+ TL;DR: StrictDoc's web server is not yet hardened against unsafe use. Making StrictDoc safe for deployment in public networks is an ongoing effort.
+ Using StrictDoc's command-line and web interfaces should be more secure if the web server is not deployed on a public network.
+
+ Due to current constraints (refer to 🔗 Limitations of web user interface), StrictDoc requires running a server through a command line interface in one window or OS process, and separately committing changes to documents using Git in another window or OS process. Deploying StrictDoc as a shared web server is impractical, as it still requires manual commits to SDoc files via the server's command line using Git. The future development plan for StrictDoc aims to enable its use as a standalone server application, which includes resolving the following security-related issues.
+ What makes StrictDoc's web server unsafe:
+
+- The web interface is not fully hardened against unsafe inputs, such as malformed strings or files. The web server does not perform comprehensive sanity checks on the size and validity of inputs across all its HTTP endpoints.
+- StrictDoc uses the pickle module to cache SDoc files, significantly improving performance. However, the pickle module is not secure. The pickled files are currently stored in the /tmp folder, which poses risks under certain circumstances.
+- The security-related properties of the textX/Arpeggio parser are not understood yet. We have opened a request to track this upstream: textX - Security considerations (#422).
+- Several uses of regular expressions may be unsafe, some of which have been identified by GitHub's CodeQL analyzer.
+- The security aspects of StrictDoc's dependencies have not yet been analyzed.
+
+ Simple series why especially either although Democrat Mr."Security" label. As StrictDoc becomes usable without command-line access, all known issues will need to be addressed or acknowledged as known limitations.
+ We are committed to continuously enhancing the functionality and security of StrictDoc and welcome user feedback and contributions in this area.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5. IDE support
+
+
+
+
+
+
+
+ MID:
+
+
+6d489d82b2e24bfeb2919be24262468f
+
+ UID:
+
+
+SDOC_UG_IDE_SUPPORT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+aad57726976f4882982458de90d168c7
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ StrictDoc language markup (SDoc) can be activated in all IDEs that support the
+TextMate grammars. When the StrictDoc grammar is integrated into an IDE, the
+SDoc syntax becomes highlighted just as any other syntax like Markdown, RST,
+Python, etc.
+ The TextMate grammars can be defined in either JSON or PLIST formats.
+The Sublime Text's Syntax is
+similar to the TextMate grammar but has more capabilities and is no longer
+backward-compatible with both TextMate's JSON and PLIST grammars.
+ The following IDEs are known to work:
+
+- Microsoft Visual Studio Code (TextMate JSON)
+- JetBrains's PyCharm and WebStorm (TextMate JSON). The other JetBrains IDEs are expected to work too.
+- Eclipse (TextMate JSON)
+- Sublime Text (Sublime Syntax)
+- Neovim (Tree-sitter grammar)
+
+ Due to the incompatibilities between these formats, the markup files are provided in separate repositories:
+
+ The instructions for installing the StrictDoc markup can be found in all repositories.
+ For any other IDE, when possible, it is recommended to use the TextMate JSON
+format, unless a given IDE is known to only support the TextMate bundle format
+(.tmbundle). The exception is Sublime Text which has its own format.
+
+ Note
+ The TextMate grammar and the Sublime Syntax for StrictDoc only provides syntax highlighting.
+More advanced features like autocompletion and deep validation of requirements can be only achieved with a dedicated Language Server Protocol (LSP) implementation for StrictDoc.
+The StrictDoc LSP is on StrictDoc's long-term roadmap, see
+Enhancement: Language Protocol Server for SDoc text language #577.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6. SDoc syntax
+
+
+
+
+
+
+
+ MID:
+
+
+24fb3436fa8c4b36929183eaac269376
+
+ UID:
+
+
+SECTION-UG-SDoc-syntax
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+556a4f61a4884f3088a743a0717f397f
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ StrictDoc defines a special syntax for writing specifications documents. This
+syntax is called SDoc and it's grammar is encoded with the
+textX
+tool.
+ The grammar is defined using textX language for defining grammars and is
+located in a single file:
+grammar.py.
+ This is how a minimal possible SDoc document looks like:
+
+[DOCUMENT]
+TITLE: StrictDoc
+
+ This documentation is written using StrictDoc. Here is the source file:
+strictdoc_01_user_guide.sdoc.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6.1. Document structure
+
+
+
+
+
+
+
+ MID:
+
+
+43c9624d3c97433a97f8e8f39e2dd784
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+5419c0c9bfcc4922ac5aa79ddb333188
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ An SDoc document consists of a [DOCUMENT] declaration followed by a sequence of leaf nodes or composite nodes.
+ A leaf node cannot contain any child nodes. It is simply a node with text fields. The default leaf nodes are defined as [TEXT] or [REQUIREMENT]. Any other [...] custom leaf node can be registered by a user in a document grammar as described below in 🔗 Document grammar.
+ Example of a leaf node:
+
+[REQUIREMENT]
+STATEMENT: StrictDoc shall be based on a document model.
+
+ A composite node can contain other composite or leaf nodes. The default composite node is [[SECTION]] which models a section/chapter in a document. Any other [[...]] composite node can be registered by a user in a document grammar.
+ Example of a composite node:
+
+[[SECTION]]
+TITLE: Document model
+
+[REQUIREMENT]
+STATEMENT: StrictDoc shall be based on a document model.
+
+[[/SECTION]]
+
+ The document elements are described further below in 🔗 Document elements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6.2. Document elements
+
+
+
+
+
+
+
+ MID:
+
+
+b4ceeb12bdf1448cb97b7974d4980189
+
+ UID:
+
+
+SECTION-UG-DOCUMENT-ELEMENTS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6.2.1. DOCUMENT
+
+
+
+
+
+
+
+ MID:
+
+
+db088d5977934056a851a24988e9266c
+
+ UID:
+
+
+SECTION-UG-Document
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MID:
+
+
+4b5c6f6fd70e44be8e5be10a38427e77
+
+
+
+
+
+
+
+ STATEMENT:
+
+
+
+ The [DOCUMENT] element must always be present in an SDoc document. It is a
+root of an SDoc document graph.
+
+[DOCUMENT]
+TITLE: StrictDoc
+(newline)
+
+ The following DOCUMENT fields are allowed:
+
+SDoc grammar DOCUMENT fields
+
+
+
+
+
+| Field |
+Description |
+
+
+
+| TITLE |
+Title of the document (mandatory) |
+
+| Treat ask able. Onto involve ago his class performance. Charge miss war fire deal dark interesting.
+Weight organization us major story weight. Style official floor.
+Health the impact film. This science fast talk low south how.UID |
+Unique identifier of the document |
+
+| VERSION |
+Current version of the document. Special @-macros GIT_VERSION and GIT_BRANCH can be used to get the document version from Git automatically. Example: VERSION: @GIT_VERSION (Git branch: @GIT_BRANCH). |
+
+| DATE |
+Publication date of the document. Special @-macros GIT_COMMIT_DATE and GIT_COMMIT_DATETIME can be used to get the document date from Git. Example: DATE: @GIT_COMMIT_DATETIME. |
+
+| CLASSIFICATION |
+Security classification of the document, e.g. Public, Internal, Restricted, Confidential |
+
+| PREFIX (formerly REQ_PREFIX) |
+Requirement prefix that should be used for automatic generation of UIDs. See 🔗 Automatic assignment of requirements UID. This field used to be called REQ_PREFIX but it was deprecated as of 2025-Q2. The REQ_PREFIX alias will be removed from the codebase in 2025-Q3. |
+
+| ROOT |
+Defines whether a document is a root object in a traceability graph. A root document is assumed to not have any parent requirements. The project statistics calculation will skip all root document's requirements when calculating the metric Non-root-level requirements not connected to any parent requirement. |
+
+| OPTIONS |
+Document configuration options |
+
+
+
+ The DOCUMENT declaration must always have a TITLE field. The other
+fields are optional. The OPTIONS field can be used for specifying
+the document configuration options.
+
+ Human though kitchen health from. Although report positive customer value. Share alone camera citizen relationship discover. Government else these task sense phone.
+Organization five yeah become.
+Control section song front energy away form sign. Relationship often detail southern across put south production. Television art allow most. Professional popular only not production.
+ The sequence of the fields is defined by the document's Grammar, i.e. should not be changed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User Guide
+
+
+ UID:
+
+
+SDOC_UGVERSION:
+
+
+Git commit: 0.12.1-9-g34c915db0, Git branch: stanislaw/plotly
+
+ DATE:
+
+
+2025-09-27 11:52:02
+
+
+
+
+
+
+
+
+ /
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |