pict-docuserve 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.html CHANGED
@@ -10,6 +10,8 @@
10
10
 
11
11
  <!-- Application Stylesheet -->
12
12
  <link href="css/docuserve.css" rel="stylesheet">
13
+ <!-- KaTeX stylesheet for LaTeX equation rendering -->
14
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css">
13
15
  <!-- PICT Dynamic View CSS Container -->
14
16
  <style id="PICT-CSS"></style>
15
17
 
@@ -26,6 +28,11 @@
26
28
  <!-- The root container for the Pict application -->
27
29
  <div id="Docuserve-Application-Container"></div>
28
30
 
31
+ <!-- Mermaid diagram rendering -->
32
+ <script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
33
+ <script>mermaid.initialize({ startOnLoad: false, theme: 'default' });</script>
34
+ <!-- KaTeX for LaTeX equation rendering -->
35
+ <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js"></script>
29
36
  <!-- Load the Docuserve PICT Application Bundle -->
30
37
  <script src="./pict-docuserve.min.js" type="text/javascript"></script>
31
38
  </body>
@@ -6252,6 +6252,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
6252
6252
  tmpContentView.displayContent(tmpDocProvider.getErrorPageHTML(pGroup + '/' + pModule));
6253
6253
  return;
6254
6254
  }
6255
+ let tmpDocPath = pPath || 'README.md';
6255
6256
  tmpDocProvider.fetchDocument(tmpURL, (pError, pHTML) => {
6256
6257
  if (!pError) {
6257
6258
  tmpContentView.displayContent(pHTML);
@@ -6262,11 +6263,11 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
6262
6263
  // group/module/path as a relative path. This handles cases
6263
6264
  // where the catalog contains entries (e.g. example apps)
6264
6265
  // that don't correspond to real GitHub repositories.
6265
- let tmpLocalPath = pGroup + '/' + pModule + '/' + (pPath || 'README.md');
6266
+ let tmpLocalPath = pGroup + '/' + pModule + '/' + tmpDocPath;
6266
6267
  tmpDocProvider.fetchLocalDocument(tmpLocalPath, (pLocalError, pLocalHTML) => {
6267
6268
  tmpContentView.displayContent(pLocalHTML);
6268
- });
6269
- });
6269
+ }, pGroup, pModule, tmpDocPath);
6270
+ }, pGroup, pModule, tmpDocPath);
6270
6271
  }
6271
6272
 
6272
6273
  /**
@@ -6752,6 +6753,26 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
6752
6753
  return false;
6753
6754
  }
6754
6755
 
6756
+ /**
6757
+ * Check whether a group key exists in the loaded catalog.
6758
+ *
6759
+ * Used to dynamically validate group keys instead of hardcoding them.
6760
+ *
6761
+ * @param {string} pGroupKey - The group key (e.g. "fable", "example_applications")
6762
+ * @returns {boolean} True if the group is found in the catalog
6763
+ */
6764
+ isGroupInCatalog(pGroupKey) {
6765
+ if (!this._Catalog || !this._Catalog.Groups) {
6766
+ return false;
6767
+ }
6768
+ for (let i = 0; i < this._Catalog.Groups.length; i++) {
6769
+ if (this._Catalog.Groups[i].Key === pGroupKey) {
6770
+ return true;
6771
+ }
6772
+ }
6773
+ return false;
6774
+ }
6775
+
6755
6776
  /**
6756
6777
  * Search the keyword index for documents matching a query.
6757
6778
  *
@@ -6951,8 +6972,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
6951
6972
 
6952
6973
  // Check if it's a module path (group/module)
6953
6974
  if (tmpParts.length >= 2) {
6954
- let tmpGroupKeys = ['fable', 'meadow', 'orator', 'pict', 'utility'];
6955
- if (tmpGroupKeys.indexOf(tmpParts[0]) >= 0) {
6975
+ if (this.isGroupInCatalog(tmpParts[0])) {
6956
6976
  return '#/doc/' + tmpPath;
6957
6977
  }
6958
6978
  }
@@ -7080,8 +7100,11 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7080
7100
  *
7081
7101
  * @param {string} pURL - The URL to fetch
7082
7102
  * @param {Function} fCallback - Callback receiving (error, htmlContent)
7103
+ * @param {string} [pCurrentGroup] - The current group key for link resolution
7104
+ * @param {string} [pCurrentModule] - The current module name for link resolution
7105
+ * @param {string} [pCurrentDocPath] - The current document path for link resolution
7083
7106
  */
7084
- fetchDocument(pURL, fCallback) {
7107
+ fetchDocument(pURL, fCallback, pCurrentGroup, pCurrentModule, pCurrentDocPath) {
7085
7108
  let tmpCallback = typeof fCallback === 'function' ? fCallback : () => {};
7086
7109
  if (!pURL) {
7087
7110
  return tmpCallback('No URL provided', '');
@@ -7100,7 +7123,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7100
7123
  if (!pMarkdown) {
7101
7124
  return tmpCallback('Document not found', this.getErrorPageHTML(pURL));
7102
7125
  }
7103
- let tmpHTML = this.parseMarkdown(pMarkdown);
7126
+ let tmpHTML = this.parseMarkdown(pMarkdown, pCurrentGroup, pCurrentModule, pCurrentDocPath);
7104
7127
  this._ContentCache[pURL] = tmpHTML;
7105
7128
  return tmpCallback(null, tmpHTML);
7106
7129
  }).catch(pError => {
@@ -7114,11 +7137,14 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7114
7137
  *
7115
7138
  * @param {string} pPath - The relative path (e.g. 'architecture.md')
7116
7139
  * @param {Function} fCallback - Callback receiving (error, htmlContent)
7140
+ * @param {string} [pCurrentGroup] - The current group key for link resolution
7141
+ * @param {string} [pCurrentModule] - The current module name for link resolution
7142
+ * @param {string} [pCurrentDocPath] - The current document path for link resolution
7117
7143
  */
7118
- fetchLocalDocument(pPath, fCallback) {
7144
+ fetchLocalDocument(pPath, fCallback, pCurrentGroup, pCurrentModule, pCurrentDocPath) {
7119
7145
  let tmpDocsBase = this.pict.AppData.Docuserve.DocsBaseURL || '';
7120
7146
  let tmpURL = tmpDocsBase + pPath;
7121
- this.fetchDocument(tmpURL, fCallback);
7147
+ this.fetchDocument(tmpURL, fCallback, pCurrentGroup, pCurrentModule, pCurrentDocPath);
7122
7148
  }
7123
7149
 
7124
7150
  /**
@@ -7129,32 +7155,81 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7129
7155
  * lists, blockquotes, and horizontal rules.
7130
7156
  *
7131
7157
  * @param {string} pMarkdown - The raw markdown text
7158
+ * @param {string} [pCurrentGroup] - The current group key for link resolution
7159
+ * @param {string} [pCurrentModule] - The current module name for link resolution
7160
+ * @param {string} [pCurrentDocPath] - The current document path for link resolution
7132
7161
  * @returns {string} The parsed HTML
7133
7162
  */
7134
- parseMarkdown(pMarkdown) {
7163
+ parseMarkdown(pMarkdown, pCurrentGroup, pCurrentModule, pCurrentDocPath) {
7135
7164
  if (!pMarkdown) {
7136
7165
  return '';
7137
7166
  }
7138
7167
  let tmpLines = pMarkdown.split('\n');
7139
7168
  let tmpHTML = [];
7140
7169
  let tmpInCodeBlock = false;
7170
+ let tmpCodeFenceLength = 0;
7141
7171
  let tmpCodeLang = '';
7142
7172
  let tmpCodeLines = [];
7143
7173
  let tmpInList = false;
7144
7174
  let tmpListType = '';
7145
7175
  let tmpInBlockquote = false;
7146
7176
  let tmpBlockquoteLines = [];
7177
+ let tmpInMathBlock = false;
7178
+ let tmpMathLines = [];
7147
7179
  for (let i = 0; i < tmpLines.length; i++) {
7148
7180
  let tmpLine = tmpLines[i];
7149
7181
 
7150
- // Code blocks (fenced)
7151
- if (tmpLine.match(/^```/)) {
7182
+ // Display math blocks ($$...$$) — skip if inside a code block
7183
+ if (!tmpInCodeBlock && tmpLine.trim().match(/^\$\$/)) {
7184
+ if (tmpInMathBlock) {
7185
+ // End math block
7186
+ tmpHTML.push('<div class="docuserve-katex-display">' + tmpMathLines.join('\n') + '</div>');
7187
+ tmpInMathBlock = false;
7188
+ tmpMathLines = [];
7189
+ } else {
7190
+ // Close any open list or blockquote
7191
+ if (tmpInList) {
7192
+ tmpHTML.push(tmpListType === 'ul' ? '</ul>' : '</ol>');
7193
+ tmpInList = false;
7194
+ }
7195
+ if (tmpInBlockquote) {
7196
+ tmpHTML.push('<blockquote>' + this.parseMarkdown(tmpBlockquoteLines.join('\n'), pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</blockquote>');
7197
+ tmpInBlockquote = false;
7198
+ tmpBlockquoteLines = [];
7199
+ }
7200
+ tmpInMathBlock = true;
7201
+ }
7202
+ continue;
7203
+ }
7204
+ if (tmpInMathBlock) {
7205
+ tmpMathLines.push(tmpLine);
7206
+ continue;
7207
+ }
7208
+
7209
+ // Code blocks (fenced) — track fence length so ````x```` nests around ```y```
7210
+ let tmpFenceMatch = tmpLine.match(/^(`{3,})/);
7211
+ if (tmpFenceMatch) {
7212
+ let tmpFenceLen = tmpFenceMatch[1].length;
7152
7213
  if (tmpInCodeBlock) {
7153
- // End code block
7154
- tmpHTML.push('<pre><code class="language-' + this.escapeHTML(tmpCodeLang) + '">' + this.escapeHTML(tmpCodeLines.join('\n')) + '</code></pre>');
7155
- tmpInCodeBlock = false;
7156
- tmpCodeLang = '';
7157
- tmpCodeLines = [];
7214
+ // Only close if the closing fence is at least as long as the opening
7215
+ if (tmpFenceLen >= tmpCodeFenceLength && tmpLine.trim() === tmpFenceMatch[1]) {
7216
+ // End code block
7217
+ if (tmpCodeLang === 'mermaid') {
7218
+ // Mermaid diagrams: output raw content for client-side rendering
7219
+ tmpHTML.push('<pre class="mermaid">' + tmpCodeLines.join('\n') + '</pre>');
7220
+ } else {
7221
+ tmpHTML.push('<pre><code class="language-' + this.escapeHTML(tmpCodeLang) + '">' + this.escapeHTML(tmpCodeLines.join('\n')) + '</code></pre>');
7222
+ }
7223
+ tmpInCodeBlock = false;
7224
+ tmpCodeFenceLength = 0;
7225
+ tmpCodeLang = '';
7226
+ tmpCodeLines = [];
7227
+ continue;
7228
+ } else {
7229
+ // Inner fence with fewer backticks — treat as content
7230
+ tmpCodeLines.push(tmpLine);
7231
+ continue;
7232
+ }
7158
7233
  } else {
7159
7234
  // Close any open list or blockquote
7160
7235
  if (tmpInList) {
@@ -7162,15 +7237,16 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7162
7237
  tmpInList = false;
7163
7238
  }
7164
7239
  if (tmpInBlockquote) {
7165
- tmpHTML.push('<blockquote>' + this.parseMarkdown(tmpBlockquoteLines.join('\n')) + '</blockquote>');
7240
+ tmpHTML.push('<blockquote>' + this.parseMarkdown(tmpBlockquoteLines.join('\n'), pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</blockquote>');
7166
7241
  tmpInBlockquote = false;
7167
7242
  tmpBlockquoteLines = [];
7168
7243
  }
7169
- // Start code block
7170
- tmpCodeLang = tmpLine.replace(/^```/, '').trim();
7244
+ // Start code block — record fence length
7245
+ tmpCodeFenceLength = tmpFenceLen;
7246
+ tmpCodeLang = tmpLine.replace(/^`{3,}/, '').trim();
7171
7247
  tmpInCodeBlock = true;
7248
+ continue;
7172
7249
  }
7173
- continue;
7174
7250
  }
7175
7251
  if (tmpInCodeBlock) {
7176
7252
  tmpCodeLines.push(tmpLine);
@@ -7191,7 +7267,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7191
7267
  tmpBlockquoteLines.push(tmpLine.replace(/^>\s?/, ''));
7192
7268
  continue;
7193
7269
  } else if (tmpInBlockquote) {
7194
- tmpHTML.push('<blockquote>' + this.parseMarkdown(tmpBlockquoteLines.join('\n')) + '</blockquote>');
7270
+ tmpHTML.push('<blockquote>' + this.parseMarkdown(tmpBlockquoteLines.join('\n'), pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</blockquote>');
7195
7271
  tmpInBlockquote = false;
7196
7272
  tmpBlockquoteLines = [];
7197
7273
  }
@@ -7214,7 +7290,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7214
7290
  tmpInList = false;
7215
7291
  }
7216
7292
  let tmpLevel = tmpHeadingMatch[1].length;
7217
- let tmpText = this.parseInline(tmpHeadingMatch[2]);
7293
+ let tmpText = this.parseInline(tmpHeadingMatch[2], pCurrentGroup, pCurrentModule, pCurrentDocPath);
7218
7294
  let tmpID = tmpHeadingMatch[2].toLowerCase().replace(/[^\w\s-]/g, '').replace(/\s+/g, '-');
7219
7295
  tmpHTML.push('<h' + tmpLevel + ' id="' + tmpID + '">' + tmpText + '</h' + tmpLevel + '>');
7220
7296
  continue;
@@ -7231,7 +7307,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7231
7307
  tmpInList = true;
7232
7308
  tmpListType = 'ul';
7233
7309
  }
7234
- tmpHTML.push('<li>' + this.parseInline(tmpULMatch[2]) + '</li>');
7310
+ tmpHTML.push('<li>' + this.parseInline(tmpULMatch[2], pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</li>');
7235
7311
  continue;
7236
7312
  }
7237
7313
 
@@ -7246,7 +7322,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7246
7322
  tmpInList = true;
7247
7323
  tmpListType = 'ol';
7248
7324
  }
7249
- tmpHTML.push('<li>' + this.parseInline(tmpOLMatch[2]) + '</li>');
7325
+ tmpHTML.push('<li>' + this.parseInline(tmpOLMatch[2], pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</li>');
7250
7326
  continue;
7251
7327
  }
7252
7328
 
@@ -7276,7 +7352,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7276
7352
  });
7277
7353
  tmpTableHTML += '<thead><tr>';
7278
7354
  for (let h = 0; h < tmpHeaders.length; h++) {
7279
- tmpTableHTML += '<th>' + this.parseInline(tmpHeaders[h].trim()) + '</th>';
7355
+ tmpTableHTML += '<th>' + this.parseInline(tmpHeaders[h].trim(), pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</th>';
7280
7356
  }
7281
7357
  tmpTableHTML += '</tr></thead>';
7282
7358
 
@@ -7292,7 +7368,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7292
7368
  });
7293
7369
  tmpTableHTML += '<tr>';
7294
7370
  for (let c = 0; c < tmpCells.length; c++) {
7295
- tmpTableHTML += '<td>' + this.parseInline(tmpCells[c].trim()) + '</td>';
7371
+ tmpTableHTML += '<td>' + this.parseInline(tmpCells[c].trim(), pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</td>';
7296
7372
  }
7297
7373
  tmpTableHTML += '</tr>';
7298
7374
  }
@@ -7302,7 +7378,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7302
7378
  }
7303
7379
 
7304
7380
  // Regular paragraph
7305
- tmpHTML.push('<p>' + this.parseInline(tmpLine) + '</p>');
7381
+ tmpHTML.push('<p>' + this.parseInline(tmpLine, pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</p>');
7306
7382
  }
7307
7383
 
7308
7384
  // Close any trailing open elements
@@ -7310,7 +7386,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7310
7386
  tmpHTML.push(tmpListType === 'ul' ? '</ul>' : '</ol>');
7311
7387
  }
7312
7388
  if (tmpInBlockquote) {
7313
- tmpHTML.push('<blockquote>' + this.parseMarkdown(tmpBlockquoteLines.join('\n')) + '</blockquote>');
7389
+ tmpHTML.push('<blockquote>' + this.parseMarkdown(tmpBlockquoteLines.join('\n'), pCurrentGroup, pCurrentModule, pCurrentDocPath) + '</blockquote>');
7314
7390
  }
7315
7391
  if (tmpInCodeBlock) {
7316
7392
  tmpHTML.push('<pre><code>' + this.escapeHTML(tmpCodeLines.join('\n')) + '</code></pre>');
@@ -7322,9 +7398,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7322
7398
  * Parse inline markdown elements (bold, italic, code, links, images).
7323
7399
  *
7324
7400
  * @param {string} pText - The text to parse
7401
+ * @param {string} [pCurrentGroup] - The current group key for link resolution
7402
+ * @param {string} [pCurrentModule] - The current module name for link resolution
7403
+ * @param {string} [pCurrentDocPath] - The current document path for link resolution
7325
7404
  * @returns {string} HTML with inline elements
7326
7405
  */
7327
- parseInline(pText) {
7406
+ parseInline(pText, pCurrentGroup, pCurrentModule, pCurrentDocPath) {
7328
7407
  if (!pText) {
7329
7408
  return '';
7330
7409
  }
@@ -7333,6 +7412,12 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7333
7412
  // Inline code (backticks) - handle first to avoid interfering with other patterns
7334
7413
  tmpResult = tmpResult.replace(/`([^`]+)`/g, '<code>$1</code>');
7335
7414
 
7415
+ // Inline LaTeX equations ($...$) — must be processed before other inline patterns
7416
+ // Match single $ delimiters that aren't adjacent to spaces (to avoid false positives with currency)
7417
+ tmpResult = tmpResult.replace(/\$([^\$\s][^\$]*?[^\$\s])\$/g, '<span class="docuserve-katex-inline">$1</span>');
7418
+ // Also match single-character inline math like $x$
7419
+ tmpResult = tmpResult.replace(/\$([^\$\s])\$/g, '<span class="docuserve-katex-inline">$1</span>');
7420
+
7336
7421
  // Images
7337
7422
  tmpResult = tmpResult.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1">');
7338
7423
 
@@ -7340,7 +7425,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7340
7425
  tmpResult = tmpResult.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (pMatch, pLinkText, pHref) => {
7341
7426
  // Convert internal doc links to hash routes
7342
7427
  if (pHref.match(/^\//) || pHref.match(/^[^:]+\.md/)) {
7343
- let tmpRoute = this.convertDocLink(pHref);
7428
+ let tmpRoute = this.convertDocLink(pHref, pCurrentGroup, pCurrentModule, pCurrentDocPath);
7344
7429
  return '<a href="' + tmpRoute + '">' + pLinkText + '</a>';
7345
7430
  }
7346
7431
  return '<a href="' + pHref + '" target="_blank" rel="noopener">' + pLinkText + '</a>';
@@ -7359,24 +7444,45 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7359
7444
  /**
7360
7445
  * Convert a docsify-style internal link to a hash route for docuserve.
7361
7446
  *
7447
+ * When module context is provided, relative links (e.g. "api.md" or
7448
+ * "./settings-manager.md") are resolved within the current module and
7449
+ * document directory rather than falling back to the docs root.
7450
+ *
7362
7451
  * @param {string} pHref - The original link href
7452
+ * @param {string} [pCurrentGroup] - The current group key (e.g. "fable")
7453
+ * @param {string} [pCurrentModule] - The current module name (e.g. "fable")
7454
+ * @param {string} [pCurrentDocPath] - The current document path within the module (e.g. "services/README.md")
7363
7455
  * @returns {string} The converted hash route
7364
7456
  */
7365
- convertDocLink(pHref) {
7457
+ convertDocLink(pHref, pCurrentGroup, pCurrentModule, pCurrentDocPath) {
7458
+ // Strip leading ./ prefix for relative paths
7459
+ let tmpPath = pHref.replace(/^\.\//, '');
7366
7460
  // Remove leading slash
7367
- let tmpPath = pHref.replace(/^\//, '');
7461
+ tmpPath = tmpPath.replace(/^\//, '');
7368
7462
 
7369
- // If it looks like a module path (group/module/), convert to our route format
7463
+ // If it looks like an absolute module path (group/module/...), route directly
7370
7464
  let tmpParts = tmpPath.split('/');
7371
7465
  if (tmpParts.length >= 2) {
7372
- // Check if first segment matches a known group key
7373
- let tmpGroupKeys = ['fable', 'meadow', 'orator', 'pict', 'utility'];
7374
- if (tmpGroupKeys.indexOf(tmpParts[0]) >= 0) {
7466
+ if (this.isGroupInCatalog(tmpParts[0])) {
7375
7467
  return '#/doc/' + tmpPath;
7376
7468
  }
7377
7469
  }
7378
7470
 
7379
- // Local doc page
7471
+ // If we have module context, resolve relative to current document's directory
7472
+ if (pCurrentGroup && pCurrentModule) {
7473
+ // Determine the directory of the current document
7474
+ let tmpDocDir = '';
7475
+ if (pCurrentDocPath) {
7476
+ let tmpDirParts = pCurrentDocPath.split('/');
7477
+ if (tmpDirParts.length > 1) {
7478
+ tmpDirParts.pop(); // Remove filename
7479
+ tmpDocDir = tmpDirParts.join('/') + '/';
7480
+ }
7481
+ }
7482
+ return '#/doc/' + pCurrentGroup + '/' + pCurrentModule + '/' + tmpDocDir + tmpPath;
7483
+ }
7484
+
7485
+ // Local doc page (no module context)
7380
7486
  if (tmpPath.match(/\.md$/)) {
7381
7487
  let tmpPageKey = tmpPath.replace(/\.md$/, '');
7382
7488
  return '#/page/' + tmpPageKey;
@@ -7414,7 +7520,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7414
7520
  DefaultRenderable: "Docuserve-Content-Display",
7415
7521
  DefaultDestinationAddress: "#Docuserve-Content-Container",
7416
7522
  AutoRender: false,
7417
- CSS: /*css*/"\n\t\t.docuserve-content {\n\t\t\tpadding: 2em 3em;\n\t\t\tmax-width: 900px;\n\t\t\tmargin: 0 auto;\n\t\t}\n\t\t.docuserve-content-loading {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmin-height: 200px;\n\t\t\tcolor: #999;\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.docuserve-content h1 {\n\t\t\tfont-size: 2em;\n\t\t\tcolor: #2c3e50;\n\t\t\tborder-bottom: 1px solid #eee;\n\t\t\tpadding-bottom: 0.3em;\n\t\t\tmargin-top: 0;\n\t\t}\n\t\t.docuserve-content h2 {\n\t\t\tfont-size: 1.5em;\n\t\t\tcolor: #2c3e50;\n\t\t\tborder-bottom: 1px solid #f0f0f0;\n\t\t\tpadding-bottom: 0.25em;\n\t\t\tmargin-top: 1.5em;\n\t\t}\n\t\t.docuserve-content h3 {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: #333;\n\t\t\tmargin-top: 1.25em;\n\t\t}\n\t\t.docuserve-content h4, .docuserve-content h5, .docuserve-content h6 {\n\t\t\tcolor: #555;\n\t\t\tmargin-top: 1em;\n\t\t}\n\t\t.docuserve-content p {\n\t\t\tline-height: 1.7;\n\t\t\tcolor: #444;\n\t\t\tmargin: 0.75em 0;\n\t\t}\n\t\t.docuserve-content a {\n\t\t\tcolor: #42b983;\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.docuserve-content a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t.docuserve-content pre {\n\t\t\tbackground: #2c3e50;\n\t\t\tcolor: #ecf0f1;\n\t\t\tpadding: 1.25em;\n\t\t\tborder-radius: 6px;\n\t\t\toverflow-x: auto;\n\t\t\tline-height: 1.5;\n\t\t\tfont-size: 0.9em;\n\t\t}\n\t\t.docuserve-content code {\n\t\t\tbackground: #f4f4f5;\n\t\t\tpadding: 0.15em 0.4em;\n\t\t\tborder-radius: 3px;\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: #e74c3c;\n\t\t}\n\t\t.docuserve-content pre code {\n\t\t\tbackground: none;\n\t\t\tpadding: 0;\n\t\t\tcolor: inherit;\n\t\t\tfont-size: inherit;\n\t\t}\n\t\t.docuserve-content blockquote {\n\t\t\tborder-left: 4px solid #42b983;\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em 1em;\n\t\t\tbackground: #f9f9f9;\n\t\t\tcolor: #666;\n\t\t}\n\t\t.docuserve-content blockquote p {\n\t\t\tmargin: 0.25em 0;\n\t\t}\n\t\t.docuserve-content ul, .docuserve-content ol {\n\t\t\tpadding-left: 2em;\n\t\t\tline-height: 1.8;\n\t\t}\n\t\t.docuserve-content li {\n\t\t\tmargin: 0.25em 0;\n\t\t\tcolor: #444;\n\t\t}\n\t\t.docuserve-content hr {\n\t\t\tborder: none;\n\t\t\tborder-top: 1px solid #eee;\n\t\t\tmargin: 2em 0;\n\t\t}\n\t\t.docuserve-content table {\n\t\t\twidth: 100%;\n\t\t\tborder-collapse: collapse;\n\t\t\tmargin: 1em 0;\n\t\t}\n\t\t.docuserve-content table th {\n\t\t\tbackground: #f5f7fa;\n\t\t\tborder: 1px solid #e0e0e0;\n\t\t\tpadding: 0.6em 0.8em;\n\t\t\ttext-align: left;\n\t\t\tfont-weight: 600;\n\t\t\tcolor: #2c3e50;\n\t\t}\n\t\t.docuserve-content table td {\n\t\t\tborder: 1px solid #e0e0e0;\n\t\t\tpadding: 0.5em 0.8em;\n\t\t\tcolor: #444;\n\t\t}\n\t\t.docuserve-content table tr:nth-child(even) {\n\t\t\tbackground: #fafafa;\n\t\t}\n\t\t.docuserve-content img {\n\t\t\tmax-width: 100%;\n\t\t\theight: auto;\n\t\t}\n\t\t.docuserve-not-found {\n\t\t\ttext-align: center;\n\t\t\tpadding: 3em 1em;\n\t\t\tcolor: #666;\n\t\t}\n\t\t.docuserve-not-found h2 {\n\t\t\tcolor: #999;\n\t\t\tfont-size: 1.5em;\n\t\t\tborder-bottom: none;\n\t\t}\n\t\t.docuserve-not-found code {\n\t\t\tbackground: #f4f4f5;\n\t\t\tpadding: 0.15em 0.4em;\n\t\t\tborder-radius: 3px;\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: #e74c3c;\n\t\t}\n\t",
7523
+ CSS: /*css*/"\n\t\t.docuserve-content {\n\t\t\tpadding: 2em 3em;\n\t\t\tmax-width: 900px;\n\t\t\tmargin: 0 auto;\n\t\t}\n\t\t.docuserve-content-loading {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmin-height: 200px;\n\t\t\tcolor: #999;\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.docuserve-content h1 {\n\t\t\tfont-size: 2em;\n\t\t\tcolor: #2c3e50;\n\t\t\tborder-bottom: 1px solid #eee;\n\t\t\tpadding-bottom: 0.3em;\n\t\t\tmargin-top: 0;\n\t\t}\n\t\t.docuserve-content h2 {\n\t\t\tfont-size: 1.5em;\n\t\t\tcolor: #2c3e50;\n\t\t\tborder-bottom: 1px solid #f0f0f0;\n\t\t\tpadding-bottom: 0.25em;\n\t\t\tmargin-top: 1.5em;\n\t\t}\n\t\t.docuserve-content h3 {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: #333;\n\t\t\tmargin-top: 1.25em;\n\t\t}\n\t\t.docuserve-content h4, .docuserve-content h5, .docuserve-content h6 {\n\t\t\tcolor: #555;\n\t\t\tmargin-top: 1em;\n\t\t}\n\t\t.docuserve-content p {\n\t\t\tline-height: 1.7;\n\t\t\tcolor: #444;\n\t\t\tmargin: 0.75em 0;\n\t\t}\n\t\t.docuserve-content a {\n\t\t\tcolor: #42b983;\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.docuserve-content a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t.docuserve-content pre {\n\t\t\tbackground: #2c3e50;\n\t\t\tcolor: #ecf0f1;\n\t\t\tpadding: 1.25em;\n\t\t\tborder-radius: 6px;\n\t\t\toverflow-x: auto;\n\t\t\tline-height: 1.5;\n\t\t\tfont-size: 0.9em;\n\t\t}\n\t\t.docuserve-content code {\n\t\t\tbackground: #f4f4f5;\n\t\t\tpadding: 0.15em 0.4em;\n\t\t\tborder-radius: 3px;\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: #e74c3c;\n\t\t}\n\t\t.docuserve-content pre code {\n\t\t\tbackground: none;\n\t\t\tpadding: 0;\n\t\t\tcolor: inherit;\n\t\t\tfont-size: inherit;\n\t\t}\n\t\t.docuserve-content blockquote {\n\t\t\tborder-left: 4px solid #42b983;\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em 1em;\n\t\t\tbackground: #f9f9f9;\n\t\t\tcolor: #666;\n\t\t}\n\t\t.docuserve-content blockquote p {\n\t\t\tmargin: 0.25em 0;\n\t\t}\n\t\t.docuserve-content ul, .docuserve-content ol {\n\t\t\tpadding-left: 2em;\n\t\t\tline-height: 1.8;\n\t\t}\n\t\t.docuserve-content li {\n\t\t\tmargin: 0.25em 0;\n\t\t\tcolor: #444;\n\t\t}\n\t\t.docuserve-content hr {\n\t\t\tborder: none;\n\t\t\tborder-top: 1px solid #eee;\n\t\t\tmargin: 2em 0;\n\t\t}\n\t\t.docuserve-content table {\n\t\t\twidth: 100%;\n\t\t\tborder-collapse: collapse;\n\t\t\tmargin: 1em 0;\n\t\t}\n\t\t.docuserve-content table th {\n\t\t\tbackground: #f5f7fa;\n\t\t\tborder: 1px solid #e0e0e0;\n\t\t\tpadding: 0.6em 0.8em;\n\t\t\ttext-align: left;\n\t\t\tfont-weight: 600;\n\t\t\tcolor: #2c3e50;\n\t\t}\n\t\t.docuserve-content table td {\n\t\t\tborder: 1px solid #e0e0e0;\n\t\t\tpadding: 0.5em 0.8em;\n\t\t\tcolor: #444;\n\t\t}\n\t\t.docuserve-content table tr:nth-child(even) {\n\t\t\tbackground: #fafafa;\n\t\t}\n\t\t.docuserve-content img {\n\t\t\tmax-width: 100%;\n\t\t\theight: auto;\n\t\t}\n\t\t.docuserve-content pre.mermaid {\n\t\t\tbackground: #fff;\n\t\t\tcolor: #333;\n\t\t\ttext-align: center;\n\t\t\tpadding: 1em;\n\t\t}\n\t\t.docuserve-content .docuserve-katex-display {\n\t\t\ttext-align: center;\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em;\n\t\t\toverflow-x: auto;\n\t\t}\n\t\t.docuserve-content .docuserve-katex-inline {\n\t\t\tdisplay: inline;\n\t\t}\n\t\t.docuserve-not-found {\n\t\t\ttext-align: center;\n\t\t\tpadding: 3em 1em;\n\t\t\tcolor: #666;\n\t\t}\n\t\t.docuserve-not-found h2 {\n\t\t\tcolor: #999;\n\t\t\tfont-size: 1.5em;\n\t\t\tborder-bottom: none;\n\t\t}\n\t\t.docuserve-not-found code {\n\t\t\tbackground: #f4f4f5;\n\t\t\tpadding: 0.15em 0.4em;\n\t\t\tborder-radius: 3px;\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: #e74c3c;\n\t\t}\n\t",
7418
7524
  Templates: [{
7419
7525
  Hash: "Docuserve-Content-Template",
7420
7526
  Template: /*html*/"\n<div class=\"docuserve-content\" id=\"Docuserve-Content-Body\">\n\t<div class=\"docuserve-content-loading\">Loading documentation...</div>\n</div>\n"
@@ -7444,6 +7550,80 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7444
7550
  if (tmpContentContainer) {
7445
7551
  tmpContentContainer.scrollTop = 0;
7446
7552
  }
7553
+
7554
+ // Post-render: initialize Mermaid diagrams if mermaid is available
7555
+ this.renderMermaidDiagrams();
7556
+
7557
+ // Post-render: render KaTeX equations if katex is available
7558
+ this.renderKaTeXEquations();
7559
+ }
7560
+
7561
+ /**
7562
+ * Render any Mermaid diagram blocks in the content area.
7563
+ * Mermaid blocks are `<pre class="mermaid">` elements produced by parseMarkdown.
7564
+ */
7565
+ renderMermaidDiagrams() {
7566
+ if (typeof mermaid === 'undefined') {
7567
+ return;
7568
+ }
7569
+ let tmpContentBody = document.getElementById('Docuserve-Content-Body');
7570
+ if (!tmpContentBody) {
7571
+ return;
7572
+ }
7573
+ let tmpMermaidElements = tmpContentBody.querySelectorAll('pre.mermaid');
7574
+ if (tmpMermaidElements.length < 1) {
7575
+ return;
7576
+ }
7577
+
7578
+ // mermaid.run() will process all pre.mermaid elements in the container
7579
+ try {
7580
+ mermaid.run({
7581
+ nodes: tmpMermaidElements
7582
+ });
7583
+ } catch (pError) {
7584
+ this.log.error('Mermaid rendering error: ' + pError.message);
7585
+ }
7586
+ }
7587
+
7588
+ /**
7589
+ * Render KaTeX inline and display math elements in the content area.
7590
+ * Inline: `<span class="docuserve-katex-inline">`
7591
+ * Display: `<div class="docuserve-katex-display">`
7592
+ */
7593
+ renderKaTeXEquations() {
7594
+ if (typeof katex === 'undefined') {
7595
+ return;
7596
+ }
7597
+ let tmpContentBody = document.getElementById('Docuserve-Content-Body');
7598
+ if (!tmpContentBody) {
7599
+ return;
7600
+ }
7601
+
7602
+ // Render inline math
7603
+ let tmpInlineElements = tmpContentBody.querySelectorAll('.docuserve-katex-inline');
7604
+ for (let i = 0; i < tmpInlineElements.length; i++) {
7605
+ try {
7606
+ katex.render(tmpInlineElements[i].textContent, tmpInlineElements[i], {
7607
+ throwOnError: false,
7608
+ displayMode: false
7609
+ });
7610
+ } catch (pError) {
7611
+ this.log.warn('KaTeX inline error: ' + pError.message);
7612
+ }
7613
+ }
7614
+
7615
+ // Render display math
7616
+ let tmpDisplayElements = tmpContentBody.querySelectorAll('.docuserve-katex-display');
7617
+ for (let i = 0; i < tmpDisplayElements.length; i++) {
7618
+ try {
7619
+ katex.render(tmpDisplayElements[i].textContent, tmpDisplayElements[i], {
7620
+ throwOnError: false,
7621
+ displayMode: true
7622
+ });
7623
+ } catch (pError) {
7624
+ this.log.warn('KaTeX display error: ' + pError.message);
7625
+ }
7626
+ }
7447
7627
  }
7448
7628
 
7449
7629
  /**
@@ -7650,10 +7830,10 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
7650
7830
  DefaultRenderable: "Docuserve-Sidebar-Content",
7651
7831
  DefaultDestinationAddress: "#Docuserve-Sidebar-Container",
7652
7832
  AutoRender: false,
7653
- CSS: /*css*/"\n\t\t.docuserve-sidebar {\n\t\t\tbackground-color: #f8f9fa;\n\t\t\tborder-right: 1px solid #e0e0e0;\n\t\t\tpadding: 1em 0;\n\t\t\theight: 100%;\n\t\t\tposition: relative;\n\t\t}\n\t\t.docuserve-sidebar-close {\n\t\t\tposition: absolute;\n\t\t\ttop: 0.5em;\n\t\t\tright: 0.5em;\n\t\t\tbackground: none;\n\t\t\tborder: none;\n\t\t\tcolor: #999;\n\t\t\tfont-size: 1.2em;\n\t\t\tcursor: pointer;\n\t\t\tpadding: 0.2em 0.4em;\n\t\t\tline-height: 1;\n\t\t}\n\t\t.docuserve-sidebar-close:hover {\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-search {\n\t\t\tpadding: 0 1em 1em 1em;\n\t\t\tborder-bottom: 1px solid #e9ecef;\n\t\t\tmargin-bottom: 0.5em;\n\t\t}\n\t\t.docuserve-sidebar-search input {\n\t\t\twidth: 100%;\n\t\t\tpadding: 0.5em 0.75em;\n\t\t\tborder: 1px solid #ddd;\n\t\t\tborder-radius: 4px;\n\t\t\tfont-size: 0.85em;\n\t\t\toutline: none;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\t\t.docuserve-sidebar-search input:focus {\n\t\t\tborder-color: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-search-results {\n\t\t\tmargin-top: 0.5em;\n\t\t}\n\t\t.docuserve-sidebar-search-results a {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.4em 0.5em;\n\t\t\tcolor: #444;\n\t\t\ttext-decoration: none;\n\t\t\tfont-size: 0.82em;\n\t\t\tborder-radius: 3px;\n\t\t\ttransition: background-color 0.1s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-sidebar-search-results a:hover {\n\t\t\tbackground-color: #e9ecef;\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-search-result-title {\n\t\t\tfont-weight: 600;\n\t\t\tcolor: #333;\n\t\t}\n\t\t.docuserve-sidebar-search-results a:hover .docuserve-sidebar-search-result-title {\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-search-result-meta {\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: #999;\n\t\t}\n\t\t.docuserve-sidebar-search-all {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.4em 0.5em;\n\t\t\tfont-size: 0.82em;\n\t\t\tcolor: #42b983;\n\t\t\ttext-decoration: none;\n\t\t\tfont-weight: 600;\n\t\t\tcursor: pointer;\n\t\t\tborder-top: 1px solid #e9ecef;\n\t\t\tmargin-top: 0.25em;\n\t\t\tpadding-top: 0.5em;\n\t\t}\n\t\t.docuserve-sidebar-search-all:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t.docuserve-sidebar-home {\n\t\t\tpadding: 0.5em 1.25em;\n\t\t\tfont-weight: 600;\n\t\t\tfont-size: 0.85em;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.03em;\n\t\t}\n\t\t.docuserve-sidebar-home a {\n\t\t\tcolor: #666;\n\t\t\ttext-decoration: none;\n\t\t\tcursor: pointer;\n\t\t\tuser-select: none;\n\t\t}\n\t\t.docuserve-sidebar-home a:hover {\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-group {\n\t\t\tmargin-top: 0.25em;\n\t\t}\n\t\t.docuserve-sidebar-group-title {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.5em 1.25em;\n\t\t\tfont-weight: 600;\n\t\t\tfont-size: 0.85em;\n\t\t\tcolor: #666;\n\t\t\ttext-decoration: none;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.03em;\n\t\t\tcursor: pointer;\n\t\t\tuser-select: none;\n\t\t}\n\t\t.docuserve-sidebar-group-title:hover {\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-modules {\n\t\t\tlist-style: none;\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\t\t}\n\t\t.docuserve-sidebar-modules li {\n\t\t\tpadding: 0;\n\t\t}\n\t\t.docuserve-sidebar-modules a {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.3em 1.25em 0.3em 2em;\n\t\t\tcolor: #555;\n\t\t\ttext-decoration: none;\n\t\t\tfont-size: 0.85em;\n\t\t\ttransition: background-color 0.1s, color 0.1s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-sidebar-modules a:hover {\n\t\t\tbackground-color: #e9ecef;\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-modules a.active {\n\t\t\tcolor: #42b983;\n\t\t\tfont-weight: 600;\n\t\t\tbackground-color: #e8f5e9;\n\t\t}\n\t\t.docuserve-sidebar-modules .no-docs {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.3em 1.25em 0.3em 2em;\n\t\t\tcolor: #bbb;\n\t\t\tfont-size: 0.85em;\n\t\t}\n\t\t.docuserve-sidebar-module-nav {\n\t\t\tborder-top: 1px solid #e9ecef;\n\t\t\tmargin-top: 0.5em;\n\t\t\tpadding-top: 0.5em;\n\t\t}\n\t\t.docuserve-sidebar-module-nav-section {\n\t\t\tpadding: 0.4em 1.25em;\n\t\t\tfont-weight: 600;\n\t\t\tfont-size: 0.8em;\n\t\t\tcolor: #888;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.02em;\n\t\t}\n\t\t.docuserve-sidebar-module-nav a {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.25em 1.25em 0.25em 2.25em;\n\t\t\tcolor: #555;\n\t\t\ttext-decoration: none;\n\t\t\tfont-size: 0.82em;\n\t\t\ttransition: background-color 0.1s, color 0.1s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-sidebar-module-nav a:hover {\n\t\t\tbackground-color: #e9ecef;\n\t\t\tcolor: #42b983;\n\t\t}\n\t",
7833
+ CSS: /*css*/"\n\t\t.docuserve-sidebar {\n\t\t\tbackground-color: #f8f9fa;\n\t\t\tborder-right: 1px solid #e0e0e0;\n\t\t\tpadding: 1em 0;\n\t\t\tpadding-top: 0;\n\t\t\theight: 100%;\n\t\t\tposition: relative;\n\t\t}\n\t\t.docuserve-sidebar-header {\n\t\t\tdisplay: flex;\n\t\t\tjustify-content: flex-end;\n\t\t\tpadding: 0.4em 0.5em 0;\n\t\t}\n\t\t.docuserve-sidebar-close {\n\t\t\tbackground: none;\n\t\t\tborder: none;\n\t\t\tcolor: #999;\n\t\t\tfont-size: 1.2em;\n\t\t\tcursor: pointer;\n\t\t\tpadding: 0.2em 0.4em;\n\t\t\tline-height: 1;\n\t\t}\n\t\t.docuserve-sidebar-close:hover {\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-search {\n\t\t\tpadding: 0 1em 1em 1em;\n\t\t\tborder-bottom: 1px solid #e9ecef;\n\t\t\tmargin-bottom: 0.5em;\n\t\t}\n\t\t.docuserve-sidebar-search input {\n\t\t\twidth: 100%;\n\t\t\tpadding: 0.5em 0.75em;\n\t\t\tborder: 1px solid #ddd;\n\t\t\tborder-radius: 4px;\n\t\t\tfont-size: 0.85em;\n\t\t\toutline: none;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\t\t.docuserve-sidebar-search input:focus {\n\t\t\tborder-color: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-search-results {\n\t\t\tmargin-top: 0.5em;\n\t\t}\n\t\t.docuserve-sidebar-search-results a {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.4em 0.5em;\n\t\t\tcolor: #444;\n\t\t\ttext-decoration: none;\n\t\t\tfont-size: 0.82em;\n\t\t\tborder-radius: 3px;\n\t\t\ttransition: background-color 0.1s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-sidebar-search-results a:hover {\n\t\t\tbackground-color: #e9ecef;\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-search-result-title {\n\t\t\tfont-weight: 600;\n\t\t\tcolor: #333;\n\t\t}\n\t\t.docuserve-sidebar-search-results a:hover .docuserve-sidebar-search-result-title {\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-search-result-meta {\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: #999;\n\t\t}\n\t\t.docuserve-sidebar-search-all {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.4em 0.5em;\n\t\t\tfont-size: 0.82em;\n\t\t\tcolor: #42b983;\n\t\t\ttext-decoration: none;\n\t\t\tfont-weight: 600;\n\t\t\tcursor: pointer;\n\t\t\tborder-top: 1px solid #e9ecef;\n\t\t\tmargin-top: 0.25em;\n\t\t\tpadding-top: 0.5em;\n\t\t}\n\t\t.docuserve-sidebar-search-all:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t.docuserve-sidebar-home {\n\t\t\tpadding: 0.5em 1.25em;\n\t\t\tfont-weight: 600;\n\t\t\tfont-size: 0.85em;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.03em;\n\t\t}\n\t\t.docuserve-sidebar-home a {\n\t\t\tcolor: #666;\n\t\t\ttext-decoration: none;\n\t\t\tcursor: pointer;\n\t\t\tuser-select: none;\n\t\t}\n\t\t.docuserve-sidebar-home a:hover {\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-group {\n\t\t\tmargin-top: 0.25em;\n\t\t}\n\t\t.docuserve-sidebar-group-title {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.5em 1.25em;\n\t\t\tfont-weight: 600;\n\t\t\tfont-size: 0.85em;\n\t\t\tcolor: #666;\n\t\t\ttext-decoration: none;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.03em;\n\t\t\tcursor: pointer;\n\t\t\tuser-select: none;\n\t\t}\n\t\t.docuserve-sidebar-group-title:hover {\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-modules {\n\t\t\tlist-style: none;\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\t\t}\n\t\t.docuserve-sidebar-modules li {\n\t\t\tpadding: 0;\n\t\t}\n\t\t.docuserve-sidebar-modules a {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.3em 1.25em 0.3em 2em;\n\t\t\tcolor: #555;\n\t\t\ttext-decoration: none;\n\t\t\tfont-size: 0.85em;\n\t\t\ttransition: background-color 0.1s, color 0.1s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-sidebar-modules a:hover {\n\t\t\tbackground-color: #e9ecef;\n\t\t\tcolor: #42b983;\n\t\t}\n\t\t.docuserve-sidebar-modules a.active {\n\t\t\tcolor: #42b983;\n\t\t\tfont-weight: 600;\n\t\t\tbackground-color: #e8f5e9;\n\t\t}\n\t\t.docuserve-sidebar-modules .no-docs {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.3em 1.25em 0.3em 2em;\n\t\t\tcolor: #bbb;\n\t\t\tfont-size: 0.85em;\n\t\t}\n\t\t.docuserve-sidebar-module-nav {\n\t\t\tborder-top: 1px solid #e9ecef;\n\t\t\tmargin-top: 0.5em;\n\t\t\tpadding-top: 0.5em;\n\t\t}\n\t\t.docuserve-sidebar-module-nav-section {\n\t\t\tpadding: 0.4em 1.25em;\n\t\t\tfont-weight: 600;\n\t\t\tfont-size: 0.8em;\n\t\t\tcolor: #888;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.02em;\n\t\t}\n\t\t.docuserve-sidebar-module-nav a {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0.25em 1.25em 0.25em 2.25em;\n\t\t\tcolor: #555;\n\t\t\ttext-decoration: none;\n\t\t\tfont-size: 0.82em;\n\t\t\ttransition: background-color 0.1s, color 0.1s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-sidebar-module-nav a:hover {\n\t\t\tbackground-color: #e9ecef;\n\t\t\tcolor: #42b983;\n\t\t}\n\t",
7654
7834
  Templates: [{
7655
7835
  Hash: "Docuserve-Sidebar-Template",
7656
- Template: /*html*/"\n<div class=\"docuserve-sidebar\">\n\t<button class=\"docuserve-sidebar-close\" onclick=\"{~P~}.views['Docuserve-Sidebar'].toggleSidebar()\">&times;</button>\n\t<div id=\"Docuserve-Sidebar-Search\" class=\"docuserve-sidebar-search\" style=\"display:none;\">\n\t\t<input type=\"text\" placeholder=\"Search docs...\" id=\"Docuserve-Sidebar-Search-Input\">\n\t\t<div id=\"Docuserve-Sidebar-Search-Results\" class=\"docuserve-sidebar-search-results\"></div>\n\t</div>\n\t<div class=\"docuserve-sidebar-home\">\n\t\t<a onclick=\"{~P~}.PictApplication.navigateTo('/Home')\">Home</a>\n\t</div>\n\t<div id=\"Docuserve-Sidebar-Groups\"></div>\n\t<div id=\"Docuserve-Sidebar-ModuleNav\"></div>\n</div>\n"
7836
+ Template: /*html*/"\n<div class=\"docuserve-sidebar\">\n\t<div class=\"docuserve-sidebar-header\">\n\t\t<button class=\"docuserve-sidebar-close\" onclick=\"{~P~}.views['Docuserve-Sidebar'].toggleSidebar()\">&times;</button>\n\t</div>\n\t<div id=\"Docuserve-Sidebar-Search\" class=\"docuserve-sidebar-search\" style=\"display:none;\">\n\t\t<input type=\"text\" placeholder=\"Search docs...\" id=\"Docuserve-Sidebar-Search-Input\">\n\t\t<div id=\"Docuserve-Sidebar-Search-Results\" class=\"docuserve-sidebar-search-results\"></div>\n\t</div>\n\t<div class=\"docuserve-sidebar-home\">\n\t\t<a onclick=\"{~P~}.PictApplication.navigateTo('/Home')\">Home</a>\n\t</div>\n\t<div id=\"Docuserve-Sidebar-Groups\"></div>\n\t<div id=\"Docuserve-Sidebar-ModuleNav\"></div>\n</div>\n"
7657
7837
  }],
7658
7838
  Renderables: [{
7659
7839
  RenderableHash: "Docuserve-Sidebar-Content",