pict-docuserve 1.4.13 → 1.4.15
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/pict-docuserve.js +21 -5
- package/dist/pict-docuserve.js.map +1 -1
- package/dist/pict-docuserve.min.js +1 -1
- package/dist/pict-docuserve.min.js.map +1 -1
- package/package.json +1 -1
- package/source/providers/Pict-Provider-Docuserve-Documentation.js +16 -1
- package/source/views/PictView-Docuserve-Content.js +93 -0
- package/source/views/PictView-Docuserve-TopBar-User.js +9 -5
package/dist/pict-docuserve.js
CHANGED
|
@@ -12873,7 +12873,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
|
|
|
12873
12873
|
// presumably different callback function.
|
|
12874
12874
|
// This makes sure that own properties are retained, so that
|
|
12875
12875
|
// decorations and such are not lost along the way.
|
|
12876
|
-
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],348:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],349:[function(require,module,exports){module.exports={"name":"pict-docuserve","version":"1.4.
|
|
12876
|
+
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],348:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],349:[function(require,module,exports){module.exports={"name":"pict-docuserve","version":"1.4.15","description":"Pict Documentation Server - A single-page documentation viewer built on Pict","main":"source/Pict-Application-Docuserve.js","bin":{"pict-docuserve":"source/cli/Docuserve-CLI-Run.js"},"files":["source/","dist/","html/"],"scripts":{"start":"node source/cli/Docuserve-CLI-Run.js serve","brand":"node node_modules/pict-section-theme/bin/pict-section-theme-brand.js --manifest ../../../Retold-Modules-Manifest.json --module pict-docuserve","build":"npx quack build && npx quack copy","build-docs":"npx quack build && npx quack copy && node source/cli/Docuserve-CLI-Run.js inject ./docs && node example_applications/build-examples.js stage-docs","serve-docs":"node source/cli/Docuserve-CLI-Run.js serve ./docs","serve-examples":"node example_applications/build-examples.js","test":"npx quack test","tests":"npx quack test -g","coverage":"npx quack coverage","prepublishOnly":"npm run build"},"author":"steven velozo <steven@velozo.com>","license":"MIT","dependencies":{"fable-serviceproviderbase":"^3.0.19","lunr":"^2.3.9","pict":"^1.0.372","pict-application":"^1.0.34","pict-provider":"^1.0.13","pict-provider-theme":"^1.1.2","pict-section-code":"^1.0.11","pict-section-content":"^1.0.13","pict-section-histogram":"^1.0.1","pict-section-modal":"^1.1.4","pict-section-theme":"^1.1.1","pict-service-commandlineutility":"^1.0.19","pict-view":"^1.0.68"},"devDependencies":{"pict-docuserve":"^1.4.4","quackage":"^1.3.0"},"copyFilesSettings":{"whenFileExists":"overwrite"},"copyFiles":[{"from":"./html/*","to":"./dist/"}],"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"retold":{"brand":{"Hash":"pict-docuserve","Name":"Pict Docuserve","Tagline":"A documentation viewer built on Pict","Palette":"default","Icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"frame-pict-docuserve-filled-light\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#692bbf\"/>\n\t\t<g clip-path=\"url(#frame-pict-docuserve-filled-light)\"><rect x=\"18\" y=\"30\" width=\"48\" height=\"48\" rx=\"8\" fill=\"#c13ccd\" opacity=\"0.9\"/>\n\t\t\t\t\t<rect x=\"30\" y=\"18\" width=\"48\" height=\"48\" rx=\"8\" fill=\"rgba(255,255,255,0.18)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"38\" font-weight=\"600\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">PD</text>\n\t</svg>","IconType":"svg","Favicon":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-pict-docuserve-light\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#692bbf\"/>\n\t\t<g clip-path=\"url(#fav-pict-docuserve-light)\"><rect x=\"28\" y=\"16\" width=\"52\" height=\"52\" rx=\"9\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">P</text>\n\t</svg>","FaviconDark":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-pict-docuserve-dark\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#9a6fd8\"/>\n\t\t<g clip-path=\"url(#fav-pict-docuserve-dark)\"><rect x=\"28\" y=\"16\" width=\"52\" height=\"52\" rx=\"9\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#101418\" letter-spacing=\"-1\">P</text>\n\t</svg>","Colors":{"Primary":"#692bbf","Secondary":"#c13ccd","PrimaryLight":"#692bbf","PrimaryDark":"#9a6fd8","SecondaryLight":"#c13ccd","SecondaryDark":"#d48adb"}}}};},{}],350:[function(require,module,exports){/**
|
|
12877
12877
|
* Docuserve-Brand — docuserve's own wordmark, used only as a fallback.
|
|
12878
12878
|
*
|
|
12879
12879
|
* Docuserve is a viewer: the docs being served dictate the brand, not
|
|
@@ -13580,7 +13580,10 @@ for(let i=0;i<this._Catalog.Groups.length;i++){let tmpGroup=this._Catalog.Groups
|
|
|
13580
13580
|
* @param {string} pGroup - The group key
|
|
13581
13581
|
* @param {string} pModule - The module name
|
|
13582
13582
|
* @returns {string|null} The GitHub repository URL or null
|
|
13583
|
-
*/resolveGitHubRepoURL(pGroup,pModule){if(!this._Catalog
|
|
13583
|
+
*/resolveGitHubRepoURL(pGroup,pModule){if(!this._Catalog){return null;}// Module-mode catalog: a single Module field, Groups is empty. On a
|
|
13584
|
+
// per-module docs site the route handlers leave CurrentModule blank, so
|
|
13585
|
+
// pModule may be empty -- the single Module is the answer either way.
|
|
13586
|
+
if(this._Catalog.Module&&this._Catalog.Module.Name&&(!pModule||this._Catalog.Module.Name===pModule)){let tmpModuleModeModule=this._Catalog.Module;let tmpModuleModeOrg=tmpModuleModeModule.Org||this._Catalog.GitHubOrg||'stevenvelozo';return'https://github.com/'+tmpModuleModeOrg+'/'+(tmpModuleModeModule.Repo||tmpModuleModeModule.Name);}if(!this._Catalog.Groups){return null;}for(let i=0;i<this._Catalog.Groups.length;i++){let tmpGroup=this._Catalog.Groups[i];if(tmpGroup.Key!==pGroup){continue;}for(let j=0;j<tmpGroup.Modules.length;j++){let tmpModule=tmpGroup.Modules[j];if(tmpModule.Name!==pModule){continue;}let tmpOrg=tmpModule.Org||this._Catalog.GitHubOrg||'stevenvelozo';return'https://github.com/'+tmpOrg+'/'+tmpModule.Repo;}}return null;}/**
|
|
13584
13587
|
* Get the module-specific sidebar entries for a given group/module.
|
|
13585
13588
|
*
|
|
13586
13589
|
* @param {string} pGroup - The group key
|
|
@@ -13672,7 +13675,7 @@ if(tmpPath.match(/\.md$/)){let tmpPageKey=tmpPath.replace(/\.md$/,'');return'#/p
|
|
|
13672
13675
|
// the child provides its own. We cannot read the parent's
|
|
13673
13676
|
// default_configuration.CSS at module scope because browserify's
|
|
13674
13677
|
// module initialisation order does not guarantee it is populated yet.
|
|
13675
|
-
CSS:/*css*/"\n\t\t.pict-content {\n\t\t\tpadding: 2em 3em;\n\t\t\tmax-width: 900px;\n\t\t\tmargin: 0 auto;\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-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: var(--theme-color-text-muted, #8A7F72);\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.pict-content h1 {\n\t\t\tfont-size: 2em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding-bottom: 0.3em;\n\t\t\tmargin-top: 0;\n\t\t}\n\t\t.pict-content h2 {\n\t\t\tfont-size: 1.5em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-light, #EAE3D8);\n\t\t\tpadding-bottom: 0.25em;\n\t\t\tmargin-top: 1.5em;\n\t\t}\n\t\t.pict-content h3 {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tmargin-top: 1.25em;\n\t\t}\n\t\t.pict-content h4, .pict-content h5, .pict-content h6 {\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmargin-top: 1em;\n\t\t}\n\t\t.pict-content p {\n\t\t\tline-height: 1.7;\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\tmargin: 0.75em 0;\n\t\t}\n\t\t.pict-content a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.pict-content a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t/* Plain <pre> (no wrap) - rare; keep for safety */\n\t\t.pict-content pre {\n\t\t\tbackground: var(--theme-color-background-secondary, #F6F3EE);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\tpadding: 1.25em;\n\t\t\tborder-radius: 6px;\n\t\t\tborder: 1px solid var(--theme-color-border-light, #E5DED1);\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/* Inline code */\n\t\t.pict-content code {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F0ECE4);\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: var(--theme-color-syntax-property, #9E3A50);\n\t\t\tfont-family: 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', 'Courier New', monospace;\n\t\t}\n\t\t.pict-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/* Fenced code block wrapper emitted by pict-section-content */\n\t\t.pict-content-code-wrap {\n\t\t\tposition: relative;\n\t\t\tfont-family: 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', 'Courier New', monospace;\n\t\t\tfont-size: 14px;\n\t\t\tline-height: 1.5;\n\t\t\tborder-radius: 6px;\n\t\t\tborder: 1px solid var(--theme-color-border-light, #E5DED1);\n\t\t\toverflow: auto;\n\t\t\tmargin: 1em 0;\n\t\t\tbackground: var(--theme-color-background-secondary, #F6F3EE);\n\t\t}\n\t\t.pict-content-code-wrap .pict-content-code-line-numbers {\n\t\t\tposition: absolute;\n\t\t\ttop: 0;\n\t\t\tleft: 0;\n\t\t\twidth: 40px;\n\t\t\tpadding: 1.25em 0;\n\t\t\ttext-align: right;\n\t\t\tbackground: var(--theme-color-background-tertiary, #EFEAE0);\n\t\t\tborder-right: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tcolor: var(--theme-color-text-muted, #A59986);\n\t\t\tfont-family: inherit;\n\t\t\tfont-size: inherit;\n\t\t\tline-height: inherit;\n\t\t\tuser-select: none;\n\t\t\tpointer-events: none;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\t\t.pict-content-code-wrap .pict-content-code-line-numbers span {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0 8px 0 0;\n\t\t}\n\t\t.pict-content-code-wrap pre {\n\t\t\tmargin: 0;\n\t\t\tbackground: var(--theme-color-background-secondary, #F6F3EE);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\tpadding: 1.25em 1.25em 1.25em 52px;\n\t\t\tborder: none;\n\t\t\tborder-radius: 0;\n\t\t\toverflow-x: auto;\n\t\t\tline-height: 1.5;\n\t\t\tfont-size: inherit;\n\t\t}\n\t\t.pict-content-code-wrap 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\tfont-family: inherit;\n\t\t}\n\t\t/* Syntax tokens \u2014 these rules must match the span classes emitted by\n\t\t pict-section-code's highlighter. Also apply without .pict-content-code-wrap\n\t\t as a belt-and-suspenders for any <pre><code> not emitted from a fence. */\n\t\t.pict-content-code-wrap .keyword,\n\t\t.pict-content pre code .keyword { color: var(--theme-color-syntax-keyword, #A03472); }\n\t\t.pict-content-code-wrap .string,\n\t\t.pict-content pre code .string { color: var(--theme-color-syntax-string, #1A6640); }\n\t\t.pict-content-code-wrap .number,\n\t\t.pict-content pre code .number { color: var(--theme-color-syntax-number, #B25A00); }\n\t\t.pict-content-code-wrap .comment,\n\t\t.pict-content pre code .comment { color: var(--theme-color-syntax-comment, #8A7F72); font-style: italic; }\n\t\t.pict-content-code-wrap .operator,\n\t\t.pict-content pre code .operator { color: var(--theme-color-syntax-operator, #2E7D74); }\n\t\t.pict-content-code-wrap .punctuation,\n\t\t.pict-content pre code .punctuation { color: var(--theme-color-syntax-punctuation, #2A241E); }\n\t\t.pict-content-code-wrap .function-name,\n\t\t.pict-content pre code .function-name { color: var(--theme-color-syntax-function, #2A5DB0); }\n\t\t.pict-content-code-wrap .property,\n\t\t.pict-content pre code .property { color: var(--theme-color-syntax-property, #9E3A50); }\n\t\t.pict-content-code-wrap .tag,\n\t\t.pict-content pre code .tag { color: var(--theme-color-syntax-tag, #9E3A50); }\n\t\t.pict-content-code-wrap .attr-name,\n\t\t.pict-content pre code .attr-name { color: var(--theme-color-syntax-attrname, #B25A00); }\n\t\t.pict-content-code-wrap .attr-value,\n\t\t.pict-content pre code .attr-value { color: var(--theme-color-syntax-attrvalue, #1A6640); }\n\t\t.pict-content blockquote {\n\t\t\tborder-left: 4px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em 1em;\n\t\t\tbackground: var(--theme-color-background-secondary, #F7F5F0);\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t}\n\t\t.pict-content blockquote p {\n\t\t\tmargin: 0.25em 0;\n\t\t}\n\t\t.pict-content ul, .pict-content ol {\n\t\t\tpadding-left: 2em;\n\t\t\tline-height: 1.8;\n\t\t}\n\t\t.pict-content li {\n\t\t\tmargin: 0.25em 0;\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-content hr {\n\t\t\tborder: none;\n\t\t\tborder-top: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tmargin: 2em 0;\n\t\t}\n\t\t.pict-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.pict-content table th {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F5F0E8);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 0.6em 0.8em;\n\t\t\ttext-align: left;\n\t\t\tfont-weight: 600;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t}\n\t\t.pict-content table td {\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 0.5em 0.8em;\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-content table tr:nth-child(even) {\n\t\t\tbackground: var(--theme-color-background-secondary, #F9F6F0);\n\t\t}\n\t\t.pict-content img {\n\t\t\tmax-width: 100%;\n\t\t\theight: auto;\n\t\t}\n\t\t.pict-content pre.mermaid {\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\ttext-align: center;\n\t\t\tpadding: 1em;\n\t\t\tborder: 1px solid var(--theme-color-border-light, #EAE3D8);\n\t\t}\n\t\t/* Force dark text inside mermaid SVGs so diagrams stay readable\n\t\t in dark mode (mermaid bg is always light). */\n\t\t.pict-content pre.mermaid text,\n\t\t.pict-content pre.mermaid .nodeLabel,\n\t\t.pict-content pre.mermaid .edgeLabel,\n\t\t.pict-content pre.mermaid .label,\n\t\t.pict-content pre.mermaid .cluster-label,\n\t\t.pict-content pre.mermaid span,\n\t\t.pict-content pre.mermaid foreignObject p,\n\t\t.pict-content pre.mermaid foreignObject div,\n\t\t.pict-content pre.mermaid foreignObject span {\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E) !important;\n\t\t\tfill: var(--theme-color-text-primary, #2A241E) !important;\n\t\t}\n\t\t.pict-content pre.mermaid .edgePath .path {\n\t\t\tstroke: var(--theme-color-text-secondary, #5E5549) !important;\n\t\t}\n\t\t.pict-content pre.mermaid .arrowheadPath {\n\t\t\tfill: var(--theme-color-text-secondary, #5E5549) !important;\n\t\t}\n\t\t/* Dark-mode override for handcrafted mermaid flowchart diagrams that\n\t\t bake per-node inline fill colors via 'style X fill:#...' directives\n\t\t (the architecture / module docs use these to mark layer hierarchy\n\t\t with Material pastels). Mermaid renders those as inline\n\t\t style=\"fill:#...\" SVG attributes \u2014 highest specificity, so neither\n\t\t themeVariables nor unflagged CSS can reach them. In light mode the\n\t\t pastels read fine; in dark mode the same light fills stamp a\n\t\t high-contrast island onto the dark page with unreadable text.\n\t\t Force the fills back to a theme background so dark-mode reads;\n\t\t light mode is intentionally unmodified so the per-layer hierarchy\n\t\t stays intact there. Sibling to the block-beta invert filter below:\n\t\t block-beta diagrams need full inversion (their inner palette is\n\t\t baked separately), flowcharts only need a fill swap. */\n\t\t.theme-dark .pict-content pre.mermaid .node rect,\n\t\t.theme-dark .pict-content pre.mermaid .node polygon,\n\t\t.theme-dark .pict-content pre.mermaid .node circle,\n\t\t.theme-dark .pict-content pre.mermaid .node ellipse,\n\t\t.theme-dark .pict-content pre.mermaid .node path,\n\t\t.theme-dark .pict-content pre.mermaid .cluster rect {\n\t\t\tfill: var(--theme-color-background-tertiary, #2A241E) !important;\n\t\t\tstroke: var(--theme-color-border-default, #5E5549) !important;\n\t\t}\n\t\t/* Mirror of the above for theme mode 'system' \u2014 when the user\n\t\t hasn't explicitly picked light or dark, the theme provider\n\t\t leaves <html> without .theme-light/.theme-dark and the CSS\n\t\t variables follow prefers-color-scheme. The .theme-dark-prefixed\n\t\t block above doesn't match in that case, so light pastels would\n\t\t win again on dark OSes. Mirror the rule under the media query,\n\t\t gated by :not(.theme-light) so an explicit light override on a\n\t\t dark OS still wins. */\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node rect,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node polygon,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node circle,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node ellipse,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node path,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .cluster rect {\n\t\t\t\tfill: var(--theme-color-background-tertiary, #2A241E) !important;\n\t\t\t\tstroke: var(--theme-color-border-default, #5E5549) !important;\n\t\t\t}\n\t\t}\n\t\t/* Mermaid 11's block-beta renderer ignores the themeVariables we\n\t\t pass to mermaid.initialize() \u2014 it bakes its own multi-color\n\t\t palette directly into each rect's inline SVG attributes. In\n\t\t light mode that palette is fine: Mermaid's pastel colors on a\n\t\t light page have good contrast and visual hierarchy. In dark\n\t\t mode those same light-pastel fills with dark text appear as a\n\t\t light-mode island stamped onto a dark page \u2014 poor contrast and\n\t\t visually jarring.\n\t\t Rather than collapsing the palette to a single theme color\n\t\t (which loses the per-cluster identity the diagram author chose),\n\t\t we invert the entire diagram with a CSS filter in dark mode.\n\t\t The 0.92 factor avoids a harsh pure-white\u2192pure-black flip; the\n\t\t hue-rotate(180deg) compensates for the hue shift invert()\n\t\t introduces, so red stays reddish, green stays greenish, etc.\n\t\t Scoped via :has(g.block) so only block-beta diagrams get\n\t\t filtered \u2014 flowchart / sequence / state diagrams already honor\n\t\t themeVariables and render mode-correctly without inversion. */\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) {\n\t\t\tfilter: invert(0.92) hue-rotate(180deg);\n\t\t\tbackground: transparent !important;\n\t\t\tborder-color: transparent !important;\n\t\t}\n\t\t/* When the block-beta inversion is active, the global \"force\n\t\t text to theme-color-text-primary\" rule above would set text\n\t\t to the dark-mode text color (light cream), which the filter\n\t\t then inverts to dark \u2014 unreadable against the now-dark fills.\n\t\t Reverting lets Mermaid's natural light-mode text color (dark)\n\t\t pass through the inversion, becoming light text in dark mode. */\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) text,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) .nodeLabel,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) .edgeLabel,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) .label,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) .cluster-label,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) span,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) foreignObject p,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) foreignObject div,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) foreignObject span {\n\t\t\t/* Force text to render DARK pre-filter so the dark-mode filter\n\t\t\t inverts it to LIGHT on the now-dark inverted blocks. Using\n\t\t\t the theme's light-mode text-primary hex directly (not the\n\t\t\t var() chain) because the chain would resolve to light cream\n\t\t\t in dark mode, which the filter would then invert BACK to\n\t\t\t dark \u2014 unreadable on the inverted dark blocks. */\n\t\t\tcolor: #3D3229 !important;\n\t\t\tfill: #3D3229 !important;\n\t\t}\n\t\t/* Inner blocks (the .basic.label-container rects inside block-beta\n\t\t diagrams, NOT the cluster wrappers) pick up mainBkg from the\n\t\t themeVariables we pass to mermaid.initialize(). In dark mode\n\t\t that's a dark color \u2014 which the SVG filter then inverts to\n\t\t light gray, undoing the dark-mode-ification. Force the inner\n\t\t blocks to render with a fixed light fill so the inversion\n\t\t produces dark cards in dark mode. In light mode (no filter)\n\t\t the white fill is effectively the same as Mermaid's default\n\t\t light-theme block bg \u2014 so no visual change there. */\n\t\t.pict-content pre.mermaid:has(g.block) rect.basic.label-container:not(.cluster) {\n\t\t\tfill: #FFFFFF !important;\n\t\t\tstroke: #6E6E6E !important;\n\t\t}\n\t\t.pict-content .pict-content-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.pict-content .pict-content-katex-inline {\n\t\t\tdisplay: inline;\n\t\t}\n\t\t.docuserve-module-external-link {\n\t\t\tpadding: 0.5em 0;\n\t\t\tmargin-bottom: 0.5em;\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-light, #EAE3D8);\n\t\t\tfont-size: 0.85em;\n\t\t\ttext-align: right;\n\t\t}\n\t\t.docuserve-module-external-link a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.docuserve-module-external-link a:hover {\n\t\t\ttext-decoration: underline;\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: var(--theme-color-text-secondary, #5E5549);\n\t\t}\n\t\t.docuserve-not-found h2 {\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\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: var(--theme-color-background-tertiary, #F0ECE4);\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: var(--theme-color-syntax-property, #9E3A50);\n\t\t}\n\n\t\t/* Fullscreen viewer for images and mermaid diagrams (click-to-zoom) */\n\t\t.pict-content [data-fullscreen-source] {\n\t\t\tcursor: zoom-in;\n\t\t\toutline: 1px solid transparent;\n\t\t\toutline-offset: 3px;\n\t\t\tborder-radius: 4px;\n\t\t\ttransition: outline-color 0.15s ease;\n\t\t}\n\t\t.pict-content [data-fullscreen-source]:hover {\n\t\t\toutline-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t/* Code block container with hover-revealed action buttons */\n\t\t.pict-content-code-container {\n\t\t\tposition: relative;\n\t\t\tdisplay: flex;\n\t\t\talign-items: flex-start;\n\t\t\tgap: 8px;\n\t\t\tmargin: 1em 0;\n\t\t}\n\t\t.pict-content-code-container > .pict-content-code-wrap {\n\t\t\tmargin: 0;\n\t\t\tflex: 1 1 auto;\n\t\t\tmin-width: 0;\n\t\t}\n\t\t.pict-content-code-actions {\n\t\t\tposition: sticky;\n\t\t\ttop: 64px;\n\t\t\talign-self: flex-start;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tgap: 6px;\n\t\t\tflex: 0 0 auto;\n\t\t\tpadding-top: 6px;\n\t\t\topacity: 0;\n\t\t\ttransform: translateX(-4px);\n\t\t\ttransition: opacity 0.15s ease, transform 0.15s ease;\n\t\t\tpointer-events: none;\n\t\t}\n\t\t.pict-content-code-container:hover .pict-content-code-actions,\n\t\t.pict-content-code-container:focus-within .pict-content-code-actions {\n\t\t\topacity: 1;\n\t\t\ttransform: translateX(0);\n\t\t\tpointer-events: auto;\n\t\t}\n\t\t.pict-content-code-action-btn {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\twidth: 28px;\n\t\t\theight: 28px;\n\t\t\tpadding: 0;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 6px;\n\t\t\tcursor: pointer;\n\t\t\tbox-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n\t\t\ttransition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;\n\t\t}\n\t\t.pict-content-code-action-btn svg {\n\t\t\tdisplay: block;\n\t\t\twidth: 14px;\n\t\t\theight: 14px;\n\t\t\tstroke: currentColor;\n\t\t\tfill: none;\n\t\t\tstroke-width: 1.6;\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-linejoin: round;\n\t\t}\n\t\t.pict-content-code-action-btn:hover {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n\t\t}\n\t\t.pict-content-code-action-btn:focus-visible {\n\t\t\toutline: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\toutline-offset: 2px;\n\t\t}\n\t\t.pict-content-code-action-btn.is-copied {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.pict-content-code-action-btn.is-copy-failed {\n\t\t\tbackground: #B23A3A;\n\t\t\tcolor: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder-color: #B23A3A;\n\t\t}\n\t\t/* Try-in-playground button \u2014 appended to JS code blocks. The\n\t\t triangle is filled (vs. the other action icons which are\n\t\t stroke-only) to read as a \"play\" affordance. */\n\t\t.docuserve-tryplay-btn svg polygon {\n\t\t\tfill: currentColor;\n\t\t\tstroke: none;\n\t\t}\n\t\t.docuserve-tryplay-btn svg {\n\t\t\twidth: 12px;\n\t\t\theight: 12px;\n\t\t}\n\t\t.pict-fullscreen-overlay {\n\t\t\tposition: fixed;\n\t\t\tinset: 0;\n\t\t\tz-index: 9999;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tbackground: rgba(0, 0, 0, 0.62);\n\t\t\tbackdrop-filter: blur(6px);\n\t\t\t-webkit-backdrop-filter: blur(6px);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-fullscreen-overlay[hidden] {\n\t\t\tdisplay: none;\n\t\t}\n\t\t.pict-fullscreen-titlebar {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: space-between;\n\t\t\tgap: 1em;\n\t\t\theight: 48px;\n\t\t\tpadding: 0 1em;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n\t\t\tflex: 0 0 auto;\n\t\t}\n\t\t.pict-fullscreen-title {\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\tletter-spacing: 0.01em;\n\t\t\twhite-space: nowrap;\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t}\n\t\t.pict-fullscreen-controls {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tgap: 4px;\n\t\t}\n\t\t.pict-fullscreen-btn {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\twidth: 32px;\n\t\t\theight: 32px;\n\t\t\tpadding: 0;\n\t\t\tbackground: transparent;\n\t\t\tborder: 1px solid transparent;\n\t\t\tborder-radius: 6px;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tcursor: pointer;\n\t\t\ttransition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n\t\t}\n\t\t.pict-fullscreen-btn svg {\n\t\t\tdisplay: block;\n\t\t\twidth: 16px;\n\t\t\theight: 16px;\n\t\t\tstroke: currentColor;\n\t\t\tfill: none;\n\t\t\tstroke-width: 1.75;\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-linejoin: round;\n\t\t}\n\t\t.pict-fullscreen-btn:hover {\n\t\t\tbackground: var(--theme-color-border-light, #EAE3D8);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t}\n\t\t.pict-fullscreen-btn:focus-visible {\n\t\t\toutline: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\toutline-offset: 2px;\n\t\t}\n\t\t.pict-fullscreen-close:hover {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-background-panel, #FFFFFF);\n\t\t}\n\t\t.pict-fullscreen-stage {\n\t\t\tflex: 1 1 auto;\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\toverflow: hidden;\n\t\t\tpadding: 1.5em;\n\t\t\tcursor: zoom-in;\n\t\t\ttouch-action: none;\n\t\t}\n\t\t.pict-fullscreen-stage.is-zoomed {\n\t\t\tcursor: grab;\n\t\t}\n\t\t.pict-fullscreen-stage.is-panning {\n\t\t\tcursor: grabbing;\n\t\t}\n\t\t.pict-fullscreen-content {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmax-width: 100%;\n\t\t\tmax-height: 100%;\n\t\t\ttransform-origin: center center;\n\t\t\ttransition: transform 0.05s linear;\n\t\t\twill-change: transform;\n\t\t}\n\t\t.pict-fullscreen-content > * {\n\t\t\tbox-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-img {\n\t\t\tmax-width: 90vw;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\t\t\tobject-fit: contain;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tpadding: 12px;\n\t\t\tborder-radius: 6px;\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg {\n\t\t\twidth: min(90vw, 1400px);\n\t\t\theight: auto;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\tpadding: 16px;\n\t\t\tborder-radius: 6px;\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg text,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg .nodeLabel,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg .edgeLabel,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg .label,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg span,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg foreignObject p,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg foreignObject div,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg foreignObject span {\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E) !important;\n\t\t\tfill: var(--theme-color-text-primary, #2A241E) !important;\n\t\t}\n\t\t/* Same dark-mode fill/stroke override as for inline diagrams, but\n\t\t scoped to the fullscreen-overlay clone \u2014 which lives under\n\t\t <body>, NOT inside .pict-content, so the pre.mermaid-scoped\n\t\t rules above don't reach it. */\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node rect,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node polygon,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node circle,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node ellipse,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node path,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .cluster rect {\n\t\t\tfill: var(--theme-color-background-tertiary, #2A241E) !important;\n\t\t\tstroke: var(--theme-color-border-default, #5E5549) !important;\n\t\t}\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node rect,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node polygon,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node circle,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node ellipse,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node path,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .cluster rect {\n\t\t\t\tfill: var(--theme-color-background-tertiary, #2A241E) !important;\n\t\t\t\tstroke: var(--theme-color-border-default, #5E5549) !important;\n\t\t\t}\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-codewrap {\n\t\t\tmax-width: 90vw;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\tmargin: 0;\n\t\t\toverflow: auto;\n\t\t\tbox-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);\n\t\t}\n\t",Templates:[{Hash:"Docuserve-Content-Template",Template:/*html*/"\n<div class=\"pict-content\" id=\"Docuserve-Content-Body\">\n\t<div class=\"pict-content-loading\">Loading documentation...</div>\n</div>\n"}],Renderables:[{RenderableHash:"Docuserve-Content-Display",TemplateHash:"Docuserve-Content-Template",DestinationAddress:"#Docuserve-Content-Container",RenderMethod:"replace"}]};class DocuserveContentView extends libPictContentView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}/**
|
|
13678
|
+
CSS:/*css*/"\n\t\t.pict-content {\n\t\t\tpadding: 2em 3em;\n\t\t\tmax-width: 900px;\n\t\t\tmargin: 0 auto;\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-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: var(--theme-color-text-muted, #8A7F72);\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.pict-content h1 {\n\t\t\tfont-size: 2em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding-bottom: 0.3em;\n\t\t\tmargin-top: 0;\n\t\t}\n\t\t.pict-content h2 {\n\t\t\tfont-size: 1.5em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-light, #EAE3D8);\n\t\t\tpadding-bottom: 0.25em;\n\t\t\tmargin-top: 1.5em;\n\t\t}\n\t\t.pict-content h3 {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tmargin-top: 1.25em;\n\t\t}\n\t\t.pict-content h4, .pict-content h5, .pict-content h6 {\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmargin-top: 1em;\n\t\t}\n\t\t.pict-content p {\n\t\t\tline-height: 1.7;\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\tmargin: 0.75em 0;\n\t\t}\n\t\t.pict-content a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.pict-content a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t/* Plain <pre> (no wrap) - rare; keep for safety */\n\t\t.pict-content pre {\n\t\t\tbackground: var(--theme-color-background-secondary, #F6F3EE);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\tpadding: 1.25em;\n\t\t\tborder-radius: 6px;\n\t\t\tborder: 1px solid var(--theme-color-border-light, #E5DED1);\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/* Inline code */\n\t\t.pict-content code {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F0ECE4);\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: var(--theme-color-syntax-property, #9E3A50);\n\t\t\tfont-family: 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', 'Courier New', monospace;\n\t\t}\n\t\t.pict-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/* Fenced code block wrapper emitted by pict-section-content */\n\t\t.pict-content-code-wrap {\n\t\t\tposition: relative;\n\t\t\tfont-family: 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', 'Courier New', monospace;\n\t\t\tfont-size: 14px;\n\t\t\tline-height: 1.5;\n\t\t\tborder-radius: 6px;\n\t\t\tborder: 1px solid var(--theme-color-border-light, #E5DED1);\n\t\t\toverflow: auto;\n\t\t\tmargin: 1em 0;\n\t\t\tbackground: var(--theme-color-background-secondary, #F6F3EE);\n\t\t}\n\t\t.pict-content-code-wrap .pict-content-code-line-numbers {\n\t\t\tposition: absolute;\n\t\t\ttop: 0;\n\t\t\tleft: 0;\n\t\t\twidth: 40px;\n\t\t\tpadding: 1.25em 0;\n\t\t\ttext-align: right;\n\t\t\tbackground: var(--theme-color-background-tertiary, #EFEAE0);\n\t\t\tborder-right: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tcolor: var(--theme-color-text-muted, #A59986);\n\t\t\tfont-family: inherit;\n\t\t\tfont-size: inherit;\n\t\t\tline-height: inherit;\n\t\t\tuser-select: none;\n\t\t\tpointer-events: none;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\t\t.pict-content-code-wrap .pict-content-code-line-numbers span {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0 8px 0 0;\n\t\t}\n\t\t.pict-content-code-wrap pre {\n\t\t\tmargin: 0;\n\t\t\tbackground: var(--theme-color-background-secondary, #F6F3EE);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\tpadding: 1.25em 1.25em 1.25em 52px;\n\t\t\tborder: none;\n\t\t\tborder-radius: 0;\n\t\t\toverflow-x: auto;\n\t\t\tline-height: 1.5;\n\t\t\tfont-size: inherit;\n\t\t}\n\t\t.pict-content-code-wrap 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\tfont-family: inherit;\n\t\t}\n\t\t/* Syntax tokens \u2014 these rules must match the span classes emitted by\n\t\t pict-section-code's highlighter. Also apply without .pict-content-code-wrap\n\t\t as a belt-and-suspenders for any <pre><code> not emitted from a fence. */\n\t\t.pict-content-code-wrap .keyword,\n\t\t.pict-content pre code .keyword { color: var(--theme-color-syntax-keyword, #A03472); }\n\t\t.pict-content-code-wrap .string,\n\t\t.pict-content pre code .string { color: var(--theme-color-syntax-string, #1A6640); }\n\t\t.pict-content-code-wrap .number,\n\t\t.pict-content pre code .number { color: var(--theme-color-syntax-number, #B25A00); }\n\t\t.pict-content-code-wrap .comment,\n\t\t.pict-content pre code .comment { color: var(--theme-color-syntax-comment, #8A7F72); font-style: italic; }\n\t\t.pict-content-code-wrap .operator,\n\t\t.pict-content pre code .operator { color: var(--theme-color-syntax-operator, #2E7D74); }\n\t\t.pict-content-code-wrap .punctuation,\n\t\t.pict-content pre code .punctuation { color: var(--theme-color-syntax-punctuation, #2A241E); }\n\t\t.pict-content-code-wrap .function-name,\n\t\t.pict-content pre code .function-name { color: var(--theme-color-syntax-function, #2A5DB0); }\n\t\t.pict-content-code-wrap .property,\n\t\t.pict-content pre code .property { color: var(--theme-color-syntax-property, #9E3A50); }\n\t\t.pict-content-code-wrap .tag,\n\t\t.pict-content pre code .tag { color: var(--theme-color-syntax-tag, #9E3A50); }\n\t\t.pict-content-code-wrap .attr-name,\n\t\t.pict-content pre code .attr-name { color: var(--theme-color-syntax-attrname, #B25A00); }\n\t\t.pict-content-code-wrap .attr-value,\n\t\t.pict-content pre code .attr-value { color: var(--theme-color-syntax-attrvalue, #1A6640); }\n\t\t.pict-content blockquote {\n\t\t\tborder-left: 4px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em 1em;\n\t\t\tbackground: var(--theme-color-background-secondary, #F7F5F0);\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t}\n\t\t.pict-content blockquote p {\n\t\t\tmargin: 0.25em 0;\n\t\t}\n\t\t.pict-content ul, .pict-content ol {\n\t\t\tpadding-left: 2em;\n\t\t\tline-height: 1.8;\n\t\t}\n\t\t.pict-content li {\n\t\t\tmargin: 0.25em 0;\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-content hr {\n\t\t\tborder: none;\n\t\t\tborder-top: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tmargin: 2em 0;\n\t\t}\n\t\t.pict-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.pict-content table th {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F5F0E8);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 0.6em 0.8em;\n\t\t\ttext-align: left;\n\t\t\tfont-weight: 600;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t}\n\t\t.pict-content table td {\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 0.5em 0.8em;\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-content table tr:nth-child(even) {\n\t\t\tbackground: var(--theme-color-background-secondary, #F9F6F0);\n\t\t}\n\t\t.pict-content img {\n\t\t\tmax-width: 100%;\n\t\t\theight: auto;\n\t\t}\n\t\t.pict-content pre.mermaid {\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\ttext-align: center;\n\t\t\tpadding: 1em;\n\t\t\tborder: 1px solid var(--theme-color-border-light, #EAE3D8);\n\t\t}\n\t\t/* Force dark text inside mermaid SVGs so diagrams stay readable\n\t\t in dark mode (mermaid bg is always light). */\n\t\t.pict-content pre.mermaid text,\n\t\t.pict-content pre.mermaid .nodeLabel,\n\t\t.pict-content pre.mermaid .edgeLabel,\n\t\t.pict-content pre.mermaid .label,\n\t\t.pict-content pre.mermaid .cluster-label,\n\t\t.pict-content pre.mermaid span,\n\t\t.pict-content pre.mermaid foreignObject p,\n\t\t.pict-content pre.mermaid foreignObject div,\n\t\t.pict-content pre.mermaid foreignObject span {\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E) !important;\n\t\t\tfill: var(--theme-color-text-primary, #2A241E) !important;\n\t\t}\n\t\t.pict-content pre.mermaid .edgePath .path {\n\t\t\tstroke: var(--theme-color-text-secondary, #5E5549) !important;\n\t\t}\n\t\t.pict-content pre.mermaid .arrowheadPath {\n\t\t\tfill: var(--theme-color-text-secondary, #5E5549) !important;\n\t\t}\n\t\t/* Dark-mode override for handcrafted mermaid flowchart diagrams that\n\t\t bake per-node inline fill colors via 'style X fill:#...' directives\n\t\t (the architecture / module docs use these to mark layer hierarchy\n\t\t with Material pastels). Mermaid renders those as inline\n\t\t style=\"fill:#...\" SVG attributes \u2014 highest specificity, so neither\n\t\t themeVariables nor unflagged CSS can reach them. In light mode the\n\t\t pastels read fine; in dark mode the same light fills stamp a\n\t\t high-contrast island onto the dark page with unreadable text.\n\t\t Force the fills back to a theme background so dark-mode reads;\n\t\t light mode is intentionally unmodified so the per-layer hierarchy\n\t\t stays intact there. Sibling to the block-beta invert filter below:\n\t\t block-beta diagrams need full inversion (their inner palette is\n\t\t baked separately), flowcharts only need a fill swap. */\n\t\t.theme-dark .pict-content pre.mermaid .node rect,\n\t\t.theme-dark .pict-content pre.mermaid .node polygon,\n\t\t.theme-dark .pict-content pre.mermaid .node circle,\n\t\t.theme-dark .pict-content pre.mermaid .node ellipse,\n\t\t.theme-dark .pict-content pre.mermaid .node path,\n\t\t.theme-dark .pict-content pre.mermaid .cluster rect {\n\t\t\tfill: var(--theme-color-background-tertiary, #2A241E) !important;\n\t\t\tstroke: var(--theme-color-border-default, #5E5549) !important;\n\t\t}\n\t\t/* Mirror of the above for theme mode 'system' \u2014 when the user\n\t\t hasn't explicitly picked light or dark, the theme provider\n\t\t leaves <html> without .theme-light/.theme-dark and the CSS\n\t\t variables follow prefers-color-scheme. The .theme-dark-prefixed\n\t\t block above doesn't match in that case, so light pastels would\n\t\t win again on dark OSes. Mirror the rule under the media query,\n\t\t gated by :not(.theme-light) so an explicit light override on a\n\t\t dark OS still wins. */\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node rect,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node polygon,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node circle,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node ellipse,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .node path,\n\t\t\thtml:not(.theme-light) .pict-content pre.mermaid .cluster rect {\n\t\t\t\tfill: var(--theme-color-background-tertiary, #2A241E) !important;\n\t\t\t\tstroke: var(--theme-color-border-default, #5E5549) !important;\n\t\t\t}\n\t\t}\n\t\t/* Mermaid 11's block-beta renderer ignores the themeVariables we\n\t\t pass to mermaid.initialize() \u2014 it bakes its own multi-color\n\t\t palette directly into each rect's inline SVG attributes. In\n\t\t light mode that palette is fine: Mermaid's pastel colors on a\n\t\t light page have good contrast and visual hierarchy. In dark\n\t\t mode those same light-pastel fills with dark text appear as a\n\t\t light-mode island stamped onto a dark page \u2014 poor contrast and\n\t\t visually jarring.\n\t\t Rather than collapsing the palette to a single theme color\n\t\t (which loses the per-cluster identity the diagram author chose),\n\t\t we invert the entire diagram with a CSS filter in dark mode.\n\t\t The 0.92 factor avoids a harsh pure-white\u2192pure-black flip; the\n\t\t hue-rotate(180deg) compensates for the hue shift invert()\n\t\t introduces, so red stays reddish, green stays greenish, etc.\n\t\t Scoped via :has(g.block) so only block-beta diagrams get\n\t\t filtered \u2014 flowchart / sequence / state diagrams already honor\n\t\t themeVariables and render mode-correctly without inversion. */\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) {\n\t\t\tfilter: invert(0.92) hue-rotate(180deg);\n\t\t\tbackground: transparent !important;\n\t\t\tborder-color: transparent !important;\n\t\t}\n\t\t/* When the block-beta inversion is active, the global \"force\n\t\t text to theme-color-text-primary\" rule above would set text\n\t\t to the dark-mode text color (light cream), which the filter\n\t\t then inverts to dark \u2014 unreadable against the now-dark fills.\n\t\t Reverting lets Mermaid's natural light-mode text color (dark)\n\t\t pass through the inversion, becoming light text in dark mode. */\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) text,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) .nodeLabel,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) .edgeLabel,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) .label,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) .cluster-label,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) span,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) foreignObject p,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) foreignObject div,\n\t\t.theme-dark .pict-content pre.mermaid:has(g.block) foreignObject span {\n\t\t\t/* Force text to render DARK pre-filter so the dark-mode filter\n\t\t\t inverts it to LIGHT on the now-dark inverted blocks. Using\n\t\t\t the theme's light-mode text-primary hex directly (not the\n\t\t\t var() chain) because the chain would resolve to light cream\n\t\t\t in dark mode, which the filter would then invert BACK to\n\t\t\t dark \u2014 unreadable on the inverted dark blocks. */\n\t\t\tcolor: #3D3229 !important;\n\t\t\tfill: #3D3229 !important;\n\t\t}\n\t\t/* Inner blocks (the .basic.label-container rects inside block-beta\n\t\t diagrams, NOT the cluster wrappers) pick up mainBkg from the\n\t\t themeVariables we pass to mermaid.initialize(). In dark mode\n\t\t that's a dark color \u2014 which the SVG filter then inverts to\n\t\t light gray, undoing the dark-mode-ification. Force the inner\n\t\t blocks to render with a fixed light fill so the inversion\n\t\t produces dark cards in dark mode. In light mode (no filter)\n\t\t the white fill is effectively the same as Mermaid's default\n\t\t light-theme block bg \u2014 so no visual change there. */\n\t\t.pict-content pre.mermaid:has(g.block) rect.basic.label-container:not(.cluster) {\n\t\t\tfill: #FFFFFF !important;\n\t\t\tstroke: #6E6E6E !important;\n\t\t}\n\t\t.pict-content .pict-content-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.pict-content .pict-content-katex-inline {\n\t\t\tdisplay: inline;\n\t\t}\n\t\t.docuserve-module-external-link {\n\t\t\tpadding: 0.5em 0;\n\t\t\tmargin-bottom: 0.5em;\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-light, #EAE3D8);\n\t\t\tfont-size: 0.85em;\n\t\t\ttext-align: right;\n\t\t}\n\t\t.docuserve-module-external-link a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.docuserve-module-external-link a:hover {\n\t\t\ttext-decoration: underline;\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: var(--theme-color-text-secondary, #5E5549);\n\t\t}\n\t\t.docuserve-not-found h2 {\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\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: var(--theme-color-background-tertiary, #F0ECE4);\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: var(--theme-color-syntax-property, #9E3A50);\n\t\t}\n\n\t\t/* Fullscreen viewer for images and mermaid diagrams (click-to-zoom) */\n\t\t.pict-content [data-fullscreen-source] {\n\t\t\tcursor: zoom-in;\n\t\t\toutline: 1px solid transparent;\n\t\t\toutline-offset: 3px;\n\t\t\tborder-radius: 4px;\n\t\t\ttransition: outline-color 0.15s ease;\n\t\t}\n\t\t.pict-content [data-fullscreen-source]:hover {\n\t\t\toutline-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t/* Code block container with hover-revealed action buttons */\n\t\t.pict-content-code-container {\n\t\t\tposition: relative;\n\t\t\tdisplay: flex;\n\t\t\talign-items: flex-start;\n\t\t\tgap: 8px;\n\t\t\tmargin: 1em 0;\n\t\t}\n\t\t.pict-content-code-container > .pict-content-code-wrap {\n\t\t\tmargin: 0;\n\t\t\tflex: 1 1 auto;\n\t\t\tmin-width: 0;\n\t\t}\n\t\t.pict-content-code-actions {\n\t\t\tposition: sticky;\n\t\t\ttop: 64px;\n\t\t\talign-self: flex-start;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tgap: 6px;\n\t\t\tflex: 0 0 auto;\n\t\t\tpadding-top: 6px;\n\t\t\topacity: 0;\n\t\t\ttransform: translateX(-4px);\n\t\t\ttransition: opacity 0.15s ease, transform 0.15s ease;\n\t\t\tpointer-events: none;\n\t\t}\n\t\t.pict-content-code-container:hover .pict-content-code-actions,\n\t\t.pict-content-code-container:focus-within .pict-content-code-actions {\n\t\t\topacity: 1;\n\t\t\ttransform: translateX(0);\n\t\t\tpointer-events: auto;\n\t\t}\n\t\t.pict-content-code-action-btn {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\twidth: 28px;\n\t\t\theight: 28px;\n\t\t\tpadding: 0;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 6px;\n\t\t\tcursor: pointer;\n\t\t\tbox-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n\t\t\ttransition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;\n\t\t}\n\t\t.pict-content-code-action-btn svg {\n\t\t\tdisplay: block;\n\t\t\twidth: 14px;\n\t\t\theight: 14px;\n\t\t\tstroke: currentColor;\n\t\t\tfill: none;\n\t\t\tstroke-width: 1.6;\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-linejoin: round;\n\t\t}\n\t\t.pict-content-code-action-btn:hover {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n\t\t}\n\t\t.pict-content-code-action-btn:focus-visible {\n\t\t\toutline: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\toutline-offset: 2px;\n\t\t}\n\t\t.pict-content-code-action-btn.is-copied {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.pict-content-code-action-btn.is-copy-failed {\n\t\t\tbackground: #B23A3A;\n\t\t\tcolor: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder-color: #B23A3A;\n\t\t}\n\t\t/* Try-in-playground button \u2014 appended to JS code blocks. The\n\t\t triangle is filled (vs. the other action icons which are\n\t\t stroke-only) to read as a \"play\" affordance. */\n\t\t.docuserve-tryplay-btn svg polygon {\n\t\t\tfill: currentColor;\n\t\t\tstroke: none;\n\t\t}\n\t\t.docuserve-tryplay-btn svg {\n\t\t\twidth: 12px;\n\t\t\theight: 12px;\n\t\t}\n\t\t.pict-fullscreen-overlay {\n\t\t\tposition: fixed;\n\t\t\tinset: 0;\n\t\t\tz-index: 9999;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tbackground: rgba(0, 0, 0, 0.62);\n\t\t\tbackdrop-filter: blur(6px);\n\t\t\t-webkit-backdrop-filter: blur(6px);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-fullscreen-overlay[hidden] {\n\t\t\tdisplay: none;\n\t\t}\n\t\t.pict-fullscreen-titlebar {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: space-between;\n\t\t\tgap: 1em;\n\t\t\theight: 48px;\n\t\t\tpadding: 0 1em;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n\t\t\tflex: 0 0 auto;\n\t\t}\n\t\t.pict-fullscreen-title {\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\tletter-spacing: 0.01em;\n\t\t\twhite-space: nowrap;\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t}\n\t\t.pict-fullscreen-controls {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tgap: 4px;\n\t\t}\n\t\t.pict-fullscreen-btn {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\twidth: 32px;\n\t\t\theight: 32px;\n\t\t\tpadding: 0;\n\t\t\tbackground: transparent;\n\t\t\tborder: 1px solid transparent;\n\t\t\tborder-radius: 6px;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tcursor: pointer;\n\t\t\ttransition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n\t\t}\n\t\t.pict-fullscreen-btn svg {\n\t\t\tdisplay: block;\n\t\t\twidth: 16px;\n\t\t\theight: 16px;\n\t\t\tstroke: currentColor;\n\t\t\tfill: none;\n\t\t\tstroke-width: 1.75;\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-linejoin: round;\n\t\t}\n\t\t.pict-fullscreen-btn:hover {\n\t\t\tbackground: var(--theme-color-border-light, #EAE3D8);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t}\n\t\t.pict-fullscreen-btn:focus-visible {\n\t\t\toutline: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\toutline-offset: 2px;\n\t\t}\n\t\t.pict-fullscreen-close:hover {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-background-panel, #FFFFFF);\n\t\t}\n\t\t.pict-fullscreen-stage {\n\t\t\tflex: 1 1 auto;\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\toverflow: hidden;\n\t\t\tpadding: 1.5em;\n\t\t\tcursor: zoom-in;\n\t\t\ttouch-action: none;\n\t\t}\n\t\t.pict-fullscreen-stage.is-zoomed {\n\t\t\tcursor: grab;\n\t\t}\n\t\t.pict-fullscreen-stage.is-panning {\n\t\t\tcursor: grabbing;\n\t\t}\n\t\t.pict-fullscreen-content {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmax-width: 100%;\n\t\t\tmax-height: 100%;\n\t\t\ttransform-origin: center center;\n\t\t\ttransition: transform 0.05s linear;\n\t\t\twill-change: transform;\n\t\t}\n\t\t.pict-fullscreen-content > * {\n\t\t\tbox-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-img {\n\t\t\tmax-width: 90vw;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\t\t\tobject-fit: contain;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tpadding: 12px;\n\t\t\tborder-radius: 6px;\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg {\n\t\t\twidth: min(90vw, 1400px);\n\t\t\theight: auto;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\tpadding: 16px;\n\t\t\tborder-radius: 6px;\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg text,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg .nodeLabel,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg .edgeLabel,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg .label,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg span,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg foreignObject p,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg foreignObject div,\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg foreignObject span {\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E) !important;\n\t\t\tfill: var(--theme-color-text-primary, #2A241E) !important;\n\t\t}\n\t\t/* Same dark-mode fill/stroke override as for inline diagrams, but\n\t\t scoped to the fullscreen-overlay clone \u2014 which lives under\n\t\t <body>, NOT inside .pict-content, so the pre.mermaid-scoped\n\t\t rules above don't reach it. */\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node rect,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node polygon,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node circle,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node ellipse,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node path,\n\t\t.theme-dark .pict-fullscreen-content .pict-fullscreen-mermaid-svg .cluster rect {\n\t\t\tfill: var(--theme-color-background-tertiary, #2A241E) !important;\n\t\t\tstroke: var(--theme-color-border-default, #5E5549) !important;\n\t\t}\n\t\t@media (prefers-color-scheme: dark) {\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node rect,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node polygon,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node circle,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node ellipse,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .node path,\n\t\t\thtml:not(.theme-light) .pict-fullscreen-content .pict-fullscreen-mermaid-svg .cluster rect {\n\t\t\t\tfill: var(--theme-color-background-tertiary, #2A241E) !important;\n\t\t\t\tstroke: var(--theme-color-border-default, #5E5549) !important;\n\t\t\t}\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-codewrap {\n\t\t\tmax-width: 90vw;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\tmargin: 0;\n\t\t\toverflow: auto;\n\t\t\tbox-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);\n\t\t}\n\n\t\t/* Bespoke pict-renderer-graph diagram theming. Inlined diagram SVGs\n\t\t (see _inlineDiagramSVGs) paint with var(--diagram-*); define those\n\t\t tokens per theme so the diagrams follow light/dark like everything\n\t\t else. Mirrors the .theme-dark + prefers-color-scheme pattern the\n\t\t mermaid rules above use. */\n\t\t.pict-content\n\t\t{\n\t\t\t--diagram-ink: #1B1F23;\n\t\t\t--diagram-paper: #FBF7EE;\n\t\t\t--diagram-accent: #C9602F;\n\t\t\t--diagram-highlight: #E8C547;\n\t\t\t--diagram-deemphasis: #8A7F72;\n\t\t\t--diagram-link: #2E7D74;\n\t\t}\n\t\t.theme-dark .pict-content\n\t\t{\n\t\t\t--diagram-ink: #E8E0D4;\n\t\t\t--diagram-paper: #20262E;\n\t\t\t--diagram-accent: #E8956A;\n\t\t\t--diagram-highlight: #E8C547;\n\t\t\t--diagram-deemphasis: #9A8F80;\n\t\t\t--diagram-link: #5FB3A8;\n\t\t}\n\t\t@media (prefers-color-scheme: dark)\n\t\t{\n\t\t\thtml:not(.theme-light) .pict-content\n\t\t\t{\n\t\t\t\t--diagram-ink: #E8E0D4;\n\t\t\t\t--diagram-paper: #20262E;\n\t\t\t\t--diagram-accent: #E8956A;\n\t\t\t\t--diagram-highlight: #E8C547;\n\t\t\t\t--diagram-deemphasis: #9A8F80;\n\t\t\t\t--diagram-link: #5FB3A8;\n\t\t\t}\n\t\t}\n\t\t.docuserve-inline-diagram\n\t\t{\n\t\t\tdisplay: block;\n\t\t\tmargin: 1.25em 0;\n\t\t\ttext-align: center;\n\t\t}\n\t\t.docuserve-inline-diagram svg\n\t\t{\n\t\t\tmax-width: 100%;\n\t\t\theight: auto;\n\t\t}\n\t",Templates:[{Hash:"Docuserve-Content-Template",Template:/*html*/"\n<div class=\"pict-content\" id=\"Docuserve-Content-Body\">\n\t<div class=\"pict-content-loading\">Loading documentation...</div>\n</div>\n"}],Renderables:[{RenderableHash:"Docuserve-Content-Display",TemplateHash:"Docuserve-Content-Template",DestinationAddress:"#Docuserve-Content-Container",RenderMethod:"replace"}]};class DocuserveContentView extends libPictContentView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}/**
|
|
13676
13679
|
* Display parsed HTML content in the content area.
|
|
13677
13680
|
*
|
|
13678
13681
|
* When viewing a module's documentation, prepends a link to the
|
|
@@ -13697,7 +13700,18 @@ let tmpEmbeds=tmpBody.querySelectorAll('[data-docuserve-playground]:not([data-do
|
|
|
13697
13700
|
if(tmpView&&typeof tmpView.mountInto==='function'){tmpEl.setAttribute('data-docuserve-mounted','1');tmpView.mountInto(tmpEl);}}// Add a "Try in Fable Playground" action button to every
|
|
13698
13701
|
// JavaScript code block. The button sits alongside the existing
|
|
13699
13702
|
// Copy / Fullscreen buttons in the hover-revealed action strip.
|
|
13700
|
-
this._addPlaygroundButtonsToCodeBlocks()
|
|
13703
|
+
this._addPlaygroundButtonsToCodeBlocks();// Inline diagram SVGs so their var(--diagram-*) colors cascade from
|
|
13704
|
+
// the active theme instead of being isolated inside an <img>.
|
|
13705
|
+
this._inlineDiagramSVGs();}/**
|
|
13706
|
+
* Replace `<img src="...svg">` in the rendered content with the SVG
|
|
13707
|
+
* inlined into the DOM. An `<img>` is style-isolated, so a diagram SVG
|
|
13708
|
+
* whose colors are `var(--diagram-*)` cannot see the page's theme
|
|
13709
|
+
* variables; inlining lets them cascade, which is what makes bespoke
|
|
13710
|
+
* pict-renderer-graph diagrams follow light/dark like the rest of the
|
|
13711
|
+
* docs. Idempotent (data-docuserve-inlined); any fetch/parse failure
|
|
13712
|
+
* leaves the original `<img>` untouched as a graceful fallback.
|
|
13713
|
+
*/_inlineDiagramSVGs(){let tmpBody=document.getElementById('Docuserve-Content-Body');if(!tmpBody){return;}let tmpImages=tmpBody.querySelectorAll('img[src$=".svg"]:not([data-docuserve-inlined])');for(let i=0;i<tmpImages.length;i++){let tmpImage=tmpImages[i];// Mark first so a re-render mid-fetch doesn't double-process.
|
|
13714
|
+
tmpImage.setAttribute('data-docuserve-inlined','1');let tmpSource=tmpImage.getAttribute('src');if(!tmpSource){continue;}let tmpAlt=tmpImage.getAttribute('alt')||'';fetch(tmpSource).then(pResponse=>pResponse&&pResponse.ok?pResponse.text():null).then(pSvgText=>{if(!pSvgText||!tmpImage.parentNode){return;}let tmpParsed=new DOMParser().parseFromString(pSvgText,'image/svg+xml');let tmpSvgElement=tmpParsed&&tmpParsed.documentElement;if(!tmpSvgElement||String(tmpSvgElement.tagName).toLowerCase()!=='svg'){return;}let tmpImported=document.importNode(tmpSvgElement,true);tmpImported.setAttribute('role','img');if(tmpAlt){tmpImported.setAttribute('aria-label',tmpAlt);}let tmpWrapper=document.createElement('span');tmpWrapper.className='docuserve-inline-diagram';tmpWrapper.appendChild(tmpImported);tmpImage.parentNode.replaceChild(tmpWrapper,tmpImage);}).catch(()=>{});}}/**
|
|
13701
13715
|
* Scan the rendered content body for `<code class="language-javascript">`
|
|
13702
13716
|
* (and `language-js`) blocks and inject a "▶ Try in Fable Playground"
|
|
13703
13717
|
* action button into each one's existing
|
|
@@ -14566,5 +14580,7 @@ if(tmpDocuserve.KeywordIndexLoaded){tmpHTML+='<a href="#/search/">Search</a>';}/
|
|
|
14566
14580
|
if(tmpDocuserve.TopBarLoaded&&tmpDocuserve.TopBar&&Array.isArray(tmpDocuserve.TopBar.ExternalLinks)){for(let i=0;i<tmpDocuserve.TopBar.ExternalLinks.length;i++){let tmpLink=tmpDocuserve.TopBar.ExternalLinks[i];let tmpHref=this._escapeHTML(tmpLink.Href||'#');let tmpText=this._escapeHTML(tmpLink.Text||'');let tmpIsExternal=/^https?:/i.test(tmpLink.Href||'');tmpHTML+='<a href="'+tmpHref+'"'+(tmpIsExternal?' target="_blank" rel="noopener"':'')+'>'+tmpText+'</a>';}}// "View source" — octocat link to the current module's GitHub repo, so
|
|
14567
14581
|
// every docs site links back to the source it documents (fixed on a
|
|
14568
14582
|
// per-module site, follows the current module on the aggregate).
|
|
14569
|
-
let tmpGroup=tmpDocuserve.CurrentGroup;let tmpModule=tmpDocuserve.CurrentModule;
|
|
14583
|
+
let tmpGroup=tmpDocuserve.CurrentGroup;let tmpModule=tmpDocuserve.CurrentModule;let tmpDocProvider=this.pict.providers['Docuserve-Documentation'];// On a per-module (module-mode) site the route handlers leave
|
|
14584
|
+
// CurrentModule blank; the single documented module lives on the catalog.
|
|
14585
|
+
if(!tmpModule&&tmpDocProvider&&tmpDocProvider._Catalog&&tmpDocProvider._Catalog.Module){tmpModule=tmpDocProvider._Catalog.Module.Name;}if(tmpModule&&tmpDocProvider&&typeof tmpDocProvider.resolveGitHubRepoURL==='function'){let tmpRepoURL=tmpDocProvider.resolveGitHubRepoURL(tmpGroup,tmpModule);if(tmpRepoURL){let tmpIcon=this.pict.icon('GitHub',{class:'docuserve-octocat',ariaLabel:'View source on GitHub'});tmpHTML+='<a class="docuserve-repo-link" href="'+this._escapeHTML(tmpRepoURL)+'"'+' target="_blank" rel="noopener"'+' title="View '+this._escapeHTML(tmpModule)+' source on GitHub">'+tmpIcon+'</a>';}}tmpEl.innerHTML=tmpHTML;}_escapeHTML(pText){if(pText==null){return'';}return String(pText).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''');}}module.exports=DocuserveTopBarUserView;module.exports.default_configuration=_ViewConfiguration;},{"pict-view":233}]},{},[352])(352);});
|
|
14570
14586
|
//# sourceMappingURL=pict-docuserve.js.map
|