[{"data":1,"prerenderedAt":1286},["ShallowReactive",2],{"navigation_docs":3,"-guides-graph":412,"-guides-graph-surround":1281},[4,38,84,326,386],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":37},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,24,28,32],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":6},"Quick start: Nuxt","\u002Fgetting-started\u002Fquick-start-nuxt","1.getting-started\u002F3.quick-start-nuxt",{"title":25,"path":26,"stem":27,"icon":6},"Quick start: plain Vue","\u002Fgetting-started\u002Fquick-start-vue","1.getting-started\u002F4.quick-start-vue",{"title":29,"path":30,"stem":31,"icon":6},"Quick start: React","\u002Fgetting-started\u002Fquick-start-react","1.getting-started\u002F5.quick-start-react",{"title":33,"path":34,"stem":35,"icon":36},"Glossary","\u002Fgetting-started\u002Fglossary","1.getting-started\u002F6.glossary","i-lucide-book-a",false,{"title":39,"icon":40,"path":41,"stem":42,"children":43,"page":37},"Tutorial","i-lucide-graduation-cap","\u002Ftutorial","2.tutorial",[44,49,54,59,64,69,74,79],{"title":45,"path":46,"stem":47,"icon":48},"Tutorial: overview","\u002Ftutorial\u002Foverview","2.tutorial\u002F1.overview","i-lucide-map",{"title":50,"path":51,"stem":52,"icon":53},"Chapter 2: A simple editor","\u002Ftutorial\u002Fsimple-editor","2.tutorial\u002F2.simple-editor","i-lucide-pencil",{"title":55,"path":56,"stem":57,"icon":58},"Chapter 3: Compose features","\u002Ftutorial\u002Fcompose-features","2.tutorial\u002F3.compose-features","i-lucide-blocks",{"title":60,"path":61,"stem":62,"icon":63},"Chapter 4: Your own block, path A","\u002Ftutorial\u002Fown-block-path-a","2.tutorial\u002F4.own-block-path-a","i-lucide-square-plus",{"title":65,"path":66,"stem":67,"icon":68},"Chapter 5: Your own feature, path B","\u002Ftutorial\u002Fown-feature-path-b","2.tutorial\u002F5.own-feature-path-b","i-lucide-puzzle",{"title":70,"path":71,"stem":72,"icon":73},"Chapter 6: Backend and collaboration","\u002Ftutorial\u002Fbackend-and-collaboration","2.tutorial\u002F6.backend-and-collaboration","i-lucide-users",{"title":75,"path":76,"stem":77,"icon":78},"Chapter 7: AI","\u002Ftutorial\u002Fai","2.tutorial\u002F7.ai","i-lucide-sparkles",{"title":80,"path":81,"stem":82,"icon":83},"Chapter 8: The React surface","\u002Ftutorial\u002Freact-surface","2.tutorial\u002F8.react-surface","i-lucide-atom",{"title":85,"icon":14,"path":86,"stem":87,"children":88,"page":37},"Guides","\u002Fguides","3.guides",[89,93,98,103,108,112,116,121,126,130,134,139,144,149,154,159,164,169,174,179,184,189,194,199,204,209,213,218,223,228,233,237,242,247,251,256,261,266,271,276,281,286,291,295,302,307,311,316,321],{"title":90,"path":91,"stem":92,"icon":58},"Feature composition and entries","\u002Fguides\u002Fcomposition","3.guides\u002F1.composition",{"title":94,"path":95,"stem":96,"icon":97},"Media, mentions and transcript features","\u002Fguides\u002Fmedia-mentions-transcript","3.guides\u002F10.media-mentions-transcript","i-lucide-image",{"title":99,"path":100,"stem":101,"icon":102},"Authors and comments","\u002Fguides\u002Fauthors-and-comments","3.guides\u002F11.authors-and-comments","i-lucide-message-square-text",{"title":104,"path":105,"stem":106,"icon":107},"Themes (Obsidian)","\u002Fguides\u002Fthemes","3.guides\u002F12.themes","i-lucide-palette",{"title":109,"path":110,"stem":111,"icon":58},"Composites and the settings UI","\u002Fguides\u002Fcomposites","3.guides\u002F13.composites",{"title":113,"path":114,"stem":115,"icon":78},"AI","\u002Fguides\u002Fai","3.guides\u002F14.ai",{"title":117,"path":118,"stem":119,"icon":120},"Document tree","\u002Fguides\u002Fdocument-tree","3.guides\u002F15.document-tree","i-lucide-folder-tree",{"title":122,"path":123,"stem":124,"icon":125},"Markdown and code","\u002Fguides\u002Fmarkdown-and-code","3.guides\u002F16.markdown-and-code","i-lucide-file-code",{"title":127,"path":128,"stem":129,"icon":83},"Advanced editor in React","\u002Fguides\u002Fadvanced-react","3.guides\u002F17.advanced-react",{"title":131,"path":132,"stem":133,"icon":6},"Kitchen sink: learning path","\u002Fguides\u002Fadvanced-nuxt-example","3.guides\u002F18.advanced-nuxt-example",{"title":135,"path":136,"stem":137,"icon":138},"Production","\u002Fguides\u002Fproduction","3.guides\u002F19.production","i-lucide-server",{"title":140,"path":141,"stem":142,"icon":143},"Register the Nuxt module","\u002Fguides\u002Fnuxt-module","3.guides\u002F2.nuxt-module","i-lucide-package",{"title":145,"path":146,"stem":147,"icon":148},"Storage adapters, comment stores, Nitro host","\u002Fguides\u002Fstorage-adapters","3.guides\u002F20.storage-adapters","i-lucide-database",{"title":150,"path":151,"stem":152,"icon":153},"Migrating from #tiptap-editor","\u002Fguides\u002Fmigration","3.guides\u002F21.migration","i-lucide-arrow-right-left",{"title":155,"path":156,"stem":157,"icon":158},"Content tree mechanics","\u002Fguides\u002Fcontent-tree","3.guides\u002F22.content-tree","i-lucide-git-fork",{"title":160,"path":161,"stem":162,"icon":163},"Block capabilities, abilities and actions","\u002Fguides\u002Fblock-capabilities","3.guides\u002F23.block-capabilities","i-lucide-shield-check",{"title":165,"path":166,"stem":167,"icon":168},"Block types in code and JSON","\u002Fguides\u002Fblock-types","3.guides\u002F24.block-types","i-lucide-shapes",{"title":170,"path":171,"stem":172,"icon":173},"Derive methods and the Derivation index","\u002Fguides\u002Fderive-methods","3.guides\u002F25.derive-methods","i-lucide-git-branch-plus",{"title":175,"path":176,"stem":177,"icon":178},"Block properties and Property definitions","\u002Fguides\u002Fblock-properties","3.guides\u002F26.block-properties","i-lucide-sliders-horizontal",{"title":180,"path":181,"stem":182,"icon":183},"Image studio","\u002Fguides\u002Fimage-studio","3.guides\u002F27.image-studio","i-lucide-image-plus",{"title":185,"path":186,"stem":187,"icon":188},"Prüfung and Freigabestatus","\u002Fguides\u002Fpruefung","3.guides\u002F28.pruefung","i-lucide-stamp",{"title":190,"path":191,"stem":192,"icon":193},"Workspace: find, read, reference and embed Blocks across Documents","\u002Fguides\u002Fworkspace","3.guides\u002F29.workspace","i-lucide-network",{"title":195,"path":196,"stem":197,"icon":198},"EditorPorts: auth and storage","\u002Fguides\u002Feditor-ports","3.guides\u002F3.editor-ports","i-lucide-plug",{"title":200,"path":201,"stem":202,"icon":203},"Collections: an ordered list of Blocks","\u002Fguides\u002Fcollections","3.guides\u002F30.collections","i-lucide-list-checks",{"title":205,"path":206,"stem":207,"icon":208},"Data views: a query shown as table, list or board","\u002Fguides\u002Fdata-views","3.guides\u002F31.data-views","i-lucide-table-properties",{"title":210,"path":211,"stem":212,"icon":193},"Explore: backlinks, related Blocks and the trail","\u002Fguides\u002Fexplore","3.guides\u002F32.explore",{"title":214,"path":215,"stem":216,"icon":217},"Render: export a Block or a Document to a file","\u002Fguides\u002Frender","3.guides\u002F33.render","i-lucide-file-output",{"title":219,"path":220,"stem":221,"icon":222},"Importers: what a dropped file becomes","\u002Fguides\u002Fimporters","3.guides\u002F34.importers","i-lucide-file-input",{"title":224,"path":225,"stem":226,"icon":227},"Templates: start a Document from a Dokumentvorlage","\u002Fguides\u002Ftemplates","3.guides\u002F35.templates","i-lucide-file-stack",{"title":229,"path":230,"stem":231,"icon":232},"Citations","\u002Fguides\u002Fcitations","3.guides\u002F36.citations","i-lucide-quote",{"title":234,"path":235,"stem":236,"icon":163},"AI proposals and the export check","\u002Fguides\u002Fexport-check","3.guides\u002F37.export-check",{"title":238,"path":239,"stem":240,"icon":241},"Query: filter, sort, group and total Blocks","\u002Fguides\u002Fquery","3.guides\u002F38.query","i-lucide-list-filter",{"title":243,"path":244,"stem":245,"icon":246},"Edges: backlinks and authored connections","\u002Fguides\u002Fedges","3.guides\u002F39.edges","i-lucide-link-2",{"title":248,"path":249,"stem":250,"icon":163},"Server routes and authentication","\u002Fguides\u002Froutes-and-auth","3.guides\u002F4.routes-and-auth",{"title":252,"path":253,"stem":254,"icon":255},"Speech: text to audio, and subtitle files","\u002Fguides\u002Fspeech","3.guides\u002F41.speech","i-lucide-audio-lines",{"title":257,"path":258,"stem":259,"icon":260},"Graph: the Edges around a Block","\u002Fguides\u002Fgraph","3.guides\u002F42.graph","i-lucide-waypoints",{"title":262,"path":263,"stem":264,"icon":265},"PDF viewer: passages, anchors and quotes","\u002Fguides\u002Fpdf-viewer","3.guides\u002F43.pdf-viewer","i-lucide-file-search",{"title":267,"path":268,"stem":269,"icon":270},"Obsidian: import and export a vault","\u002Fguides\u002Fobsidian","3.guides\u002F44.obsidian","i-lucide-folder-input",{"title":272,"path":273,"stem":274,"icon":275},"Typst: render a Document as a PDF with citations","\u002Fguides\u002Ftypst","3.guides\u002F45.typst","i-lucide-file-text",{"title":277,"path":278,"stem":279,"icon":280},"Audio: read aloud, mixdown and ElevenLabs","\u002Fguides\u002Faudio","3.guides\u002F46.audio","i-lucide-audio-waveform",{"title":282,"path":283,"stem":284,"icon":285},"Slides: decks, slide layouts and exports","\u002Fguides\u002Fslides","3.guides\u002F47.slides","i-lucide-presentation",{"title":287,"path":288,"stem":289,"icon":290},"Knowledge graph: sources and concepts beside the Documents","\u002Fguides\u002Fknowledge-graph","3.guides\u002F49.knowledge-graph","i-lucide-share-2",{"title":292,"path":293,"stem":294,"icon":78},"AI configuration and secrets","\u002Fguides\u002Fai-configuration","3.guides\u002F5.ai-configuration",{"title":296,"path":297,"stem":298,"children":299,"icon":301},"Index on Postgres: typos, meaning and SQL pushdown","\u002Fguides\u002Findex-pg","3.guides\u002F50.index-pg",[300],{"title":296,"path":297,"stem":298,"icon":301},"i-lucide-database-zap",{"title":303,"path":304,"stem":305,"icon":306},"Charts: bar, line, pie and scatter over a query","\u002Fguides\u002Fcharts","3.guides\u002F51.charts","i-lucide-chart-column",{"title":308,"path":309,"stem":310,"icon":73},"Collaboration on the client","\u002Fguides\u002Fcollaboration","3.guides\u002F6.collaboration",{"title":312,"path":313,"stem":314,"icon":315},"Block UI (drag handle, hover actions)","\u002Fguides\u002Fblock-ui","3.guides\u002F7.block-ui","i-lucide-grip-vertical",{"title":317,"path":318,"stem":319,"icon":320},"Settings and app lifetime","\u002Fguides\u002Fsettings","3.guides\u002F8.settings","i-lucide-settings",{"title":322,"path":323,"stem":324,"icon":325},"Language","\u002Fguides\u002Flanguage","3.guides\u002F9.language","i-lucide-languages",{"title":327,"icon":14,"path":328,"stem":329,"children":330,"page":37},"Reference","\u002Freference","4.reference",[331,335,339,344,348,352,356,360,364,368,373,378,382],{"title":332,"path":333,"stem":334,"icon":143},"Public exports","\u002Freference\u002Fexports","4.reference\u002F1.exports",{"title":336,"path":337,"stem":338,"icon":173},"Derive method contract","\u002Freference\u002Fderive-methods","4.reference\u002F10.derive-methods",{"title":340,"path":341,"stem":342,"icon":343},"Changelog","\u002Freference\u002Fchangelog","4.reference\u002F11.changelog","i-lucide-history",{"title":345,"path":346,"stem":347,"icon":217},"Renderer port","\u002Freference\u002Frenderer-port","4.reference\u002F12.renderer-port",{"title":349,"path":350,"stem":351,"icon":255},"Speech port","\u002Freference\u002Fspeech-port","4.reference\u002F13.speech-port",{"title":353,"path":354,"stem":355,"icon":58},"Presets and features","\u002Freference\u002Fpresets-and-features","4.reference\u002F2.presets-and-features",{"title":357,"path":358,"stem":359,"icon":68},"Feature contract","\u002Freference\u002Ffeature-contract","4.reference\u002F3.feature-contract",{"title":361,"path":362,"stem":363,"icon":107},"CSS and UI-provider requirements","\u002Freference\u002Fcss-and-ui","4.reference\u002F4.css-and-ui",{"title":365,"path":366,"stem":367,"icon":148},"Vue-free advanced schema","\u002Freference\u002Fadvanced-schema","4.reference\u002F5.advanced-schema",{"title":369,"path":370,"stem":371,"icon":372},"Dependency rules","\u002Freference\u002Fdependency-rules","4.reference\u002F6.dependency-rules","i-lucide-git-branch",{"title":374,"path":375,"stem":376,"icon":377},"Commands","\u002Freference\u002Fcommands","4.reference\u002F7.commands","i-lucide-terminal",{"title":379,"path":380,"stem":381,"icon":163},"Block capability contract","\u002Freference\u002Fblock-capabilities","4.reference\u002F8.block-capabilities",{"title":383,"path":384,"stem":385,"icon":168},"Block type contract","\u002Freference\u002Fblock-types","4.reference\u002F9.block-types",{"title":387,"path":388,"stem":389,"children":390,"icon":393},"AI agents","\u002Fai-agents","5.ai-agents\u002F1.index",[391,394,398,402,407],{"title":392,"path":388,"stem":389,"icon":393},"Overview","i-lucide-bot",{"title":395,"path":396,"stem":397,"icon":198},"Integrate the editor","\u002Fai-agents\u002Fintegrate","5.ai-agents\u002F2.integrate",{"title":399,"path":400,"stem":401,"icon":68},"Add a block or feature","\u002Fai-agents\u002Fextend","5.ai-agents\u002F3.extend",{"title":403,"path":404,"stem":405,"icon":406},"Pitfalls and invariants","\u002Fai-agents\u002Finvariants","5.ai-agents\u002F4.invariants","i-lucide-shield-alert",{"title":408,"path":409,"stem":410,"icon":411},"Verify","\u002Fai-agents\u002Fverify","5.ai-agents\u002F5.verify","i-lucide-check-check",{"id":413,"title":257,"body":414,"description":1274,"extension":1275,"links":1276,"meta":1277,"navigation":1278,"path":258,"seo":1279,"stem":259,"__hash__":1280},"docs\u002F3.guides\u002F42.graph.md",{"type":415,"value":416,"toc":1268},"minimark",[417,440,445,543,562,569,644,680,684,730,793,847,873,876,968,974,978,983,1098,1112,1116,1122,1253,1264],[418,419,420,421,425,426,430,431,435,436,439],"p",{},"The ",[422,423,424],"a",{"href":244},"Edges"," of the Block index say which Block points at which. The ",[427,428,429],"strong",{},"graph"," is their neighbourhood in one answer: the Blocks within a few hops of a start, and the Edges between them. The library answers it (",[432,433,434],"code",{},"GET \u002Fapi\u002Feditor\u002Fgraph","); the add-on ",[432,437,438],{},"@skaile\u002Fforge-editor-graph"," draws it.",[441,442,444],"h2",{"id":443},"the-route","The route",[446,447,448,459],"table",{},[449,450,451],"thead",{},[452,453,454,457],"tr",{},[455,456],"th",{},[455,458],{},[460,461,462,482,497,518,532],"tbody",{},[452,463,464,468],{},[465,466,467],"td",{},"Route",[465,469,470,473,474,477,478,481],{},[432,471,472],{},"GET \u002Fapi\u002Feditor\u002Fgraph?documentId=&blockId=&depth="," (",[432,475,476],{},"API.graph",", port ",[432,479,480],{},"index",")",[452,483,484,487],{},[465,485,486],{},"Start",[465,488,489,492,493,496],{},[432,490,491],{},"documentId"," alone: every Block of the Document that has an Edge. With ",[432,494,495],{},"blockId",": that one Block (kept even without an Edge).",[452,498,499,504],{},[465,500,501],{},[432,502,503],{},"depth",[465,505,506,507,510,511,514,515],{},"Hops from the start Blocks, ",[432,508,509],{},"1"," to ",[432,512,513],{},"3",", default ",[432,516,517],{},"2",[452,519,520,523],{},[465,521,522],{},"Answer",[465,524,525,528,529],{},[432,526,527],{},"GraphData",": ",[432,530,531],{},"{ nodes: { address, title, type }[], edges: BlockEdge[], truncated: boolean }",[452,533,534,537],{},[465,535,536],{},"Client",[465,538,539,542],{},[432,540,541],{},"EditorBackend.index.graph({ documentId, blockId?, depth?, signal? })",", optional: a backend without it leaves it out",[418,544,545,546,549,550,553,554,557,558,561],{},"The walk follows Edges in ",[427,547,548],{},"both"," directions (what a Block points at and what points at it). It never follows ",[432,551,552],{},"tag"," Edges (a tag is no Block) or Edges to a Block that does not exist, and it never leaves the Documents the user may read: a Block in another Document is a node only when the user may read that Document. Every Edge in ",[432,555,556],{},"edges"," has both its Blocks in ",[432,559,560],{},"nodes",".",[418,563,564,565,568],{},"The answer holds at most 500 Blocks. When the walk meets more, it keeps the first ones in the order it found them (start Blocks first) and sets ",[432,566,567],{},"truncated",". Edges are answered once each, in the order they were met.",[446,570,571,581],{},[449,572,573],{},[452,574,575,578],{},[455,576,577],{},"Status",[455,579,580],{},"When",[460,582,583,599,609,619,631],{},[452,584,585,590],{},[465,586,587],{},[432,588,589],{},"400",[465,591,592,593,595,596,598],{},"no ",[432,594,491],{},", or a ",[432,597,503],{}," outside 1 to 3",[452,600,601,606],{},[465,602,603],{},[432,604,605],{},"401",[465,607,608],{},"no user",[452,610,611,616],{},[465,612,613],{},[432,614,615],{},"403",[465,617,618],{},"the user may not read the Document",[452,620,621,626],{},[465,622,623],{},[432,624,625],{},"404",[465,627,628,630],{},[432,629,495],{}," names no Block of the Document",[452,632,633,638],{},[465,634,635],{},[432,636,637],{},"501",[465,639,640,641,643],{},"the host has no ",[432,642,480],{}," port",[418,645,646,647,650,651,654,655,473,658,661,662,665,666,668,669,671,672,675,676,679],{},"The walk itself is ",[432,648,649],{},"walkGraph(seeds, source, { depth, maxNodes?, keepIsolated? })"," in ",[432,652,653],{},"@skaile\u002Fforge-editor\u002Fcore",", over a ",[432,656,657],{},"GraphSource",[432,659,660],{},"edges(address, direction)"," and ",[432,663,664],{},"node(address)","). The route reads a ",[432,667,657],{}," from the ",[432,670,480],{}," port; the memory backend (",[432,673,674],{},"createMemoryBackend",") reads one from its projected rows (",[432,677,678],{},"graphSourceOfRows","), so a test or a demo draws the same graph.",[441,681,683],{"id":682},"the-panel","The panel",[685,686,691],"pre",{"className":687,"code":688,"language":689,"meta":690,"style":690},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { GraphPanel } from '@skaile\u002Fforge-editor-graph\u002Fvue' \u002F\u002F or '@skaile\u002Fforge-editor-graph\u002Freact'\n","ts","",[432,692,693],{"__ignoreMap":690},[694,695,698,702,706,710,713,716,719,723,726],"span",{"class":696,"line":697},"line",1,[694,699,701],{"class":700},"s7zQu","import",[694,703,705],{"class":704},"sMK4o"," {",[694,707,709],{"class":708},"sTEyZ"," GraphPanel",[694,711,712],{"class":704}," }",[694,714,715],{"class":700}," from",[694,717,718],{"class":704}," '",[694,720,722],{"class":721},"sfazB","@skaile\u002Fforge-editor-graph\u002Fvue",[694,724,725],{"class":704},"'",[694,727,729],{"class":728},"sHwdD"," \u002F\u002F or '@skaile\u002Fforge-editor-graph\u002Freact'\n",[685,731,735],{"className":732,"code":733,"language":734,"meta":690,"style":690},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003CGraphPanel :document-id=\"documentId\" :block-id=\"blockId\" :open=\"openBlock\" \u002F>\n","vue",[432,736,737],{"__ignoreMap":690},[694,738,739,742,746,749,753,756,759,761,763,765,768,770,772,774,776,778,781,783,785,788,790],{"class":696,"line":697},[694,740,741],{"class":704},"\u003C",[694,743,745],{"class":744},"swJcz","GraphPanel",[694,747,748],{"class":704}," :",[694,750,752],{"class":751},"spNyl","document-id",[694,754,755],{"class":704},"=",[694,757,758],{"class":704},"\"",[694,760,491],{"class":708},[694,762,758],{"class":704},[694,764,748],{"class":704},[694,766,767],{"class":751},"block-id",[694,769,755],{"class":704},[694,771,758],{"class":704},[694,773,495],{"class":708},[694,775,758],{"class":704},[694,777,748],{"class":704},[694,779,780],{"class":751},"open",[694,782,755],{"class":704},[694,784,758],{"class":704},[694,786,787],{"class":708},"openBlock",[694,789,758],{"class":704},[694,791,792],{"class":704}," \u002F>\n",[446,794,795,804],{},[449,796,797],{},[452,798,799,802],{},[455,800,801],{},"Prop",[455,803],{},[460,805,806,815,824,838],{},[452,807,808,812],{},[465,809,810],{},[432,811,491],{},[465,813,814],{},"the Document the graph is about",[452,816,817,821],{},[465,818,819],{},[432,820,495],{},[465,822,823],{},"optional: the graph around this Block; it is drawn larger and in the middle",[452,825,826,831],{},[465,827,828],{},[432,829,830],{},"open(address)",[465,832,833,834,837],{},"what a click on a node does; resolve ",[432,835,836],{},"false"," when it did not happen",[452,839,840,844],{},[465,841,842],{},[432,843,503],{},[465,845,846],{},"hops to start with (1 to 3, default 2); the panel has a select for it",[418,848,849,852,853,856,857,860,861,864,865,868,869,872],{},[427,850,851],{},"Opening a Block"," is the host's job, as for a search hit: in the open Document ",[432,854,855],{},"editor.commands.revealBlock(blockId)",", else navigate to the Document with ",[432,858,859],{},"?block=\u003Cid>",". The workspace host of this repository does both in ",[432,862,863],{},"openHit","; the same function serves the graph (",[432,866,867],{},"{ documentId, blockId }"," is what a ",[432,870,871],{},"BlockSearchHit"," also carries).",[418,874,875],{},"The panel draws:",[446,877,878,886],{},[449,879,880],{},[452,881,882,884],{},[455,883],{},[455,885],{},[460,887,888,896,922,934,942,950,958],{},[452,889,890,893],{},[465,891,892],{},"Node",[465,894,895],{},"one per Block, labelled with its title (else its type); colour by Block type, the focus Block in rose",[452,897,898,901],{},[465,899,900],{},"Edge colour",[465,902,903,904,907,908,907,911,914,915,907,918,921],{},"the kind: ",[432,905,906],{},"reference",", ",[432,909,910],{},"derivation",[432,912,913],{},"embed",", and one colour per authored kind (",[432,916,917],{},"supports",[432,919,920],{},"contradicts",", ...), the same one every time",[452,923,924,927],{},[465,925,926],{},"Edge dashed",[465,928,929,930,933],{},"the Edge was written by hand (",[432,931,932],{},"origin: 'meta'",", in the inspector's „Kanten“ section); content Edges are solid",[452,935,936,939],{},[465,937,938],{},"Arrow",[465,940,941],{},"at the Block the Edge points to",[452,943,944,947],{},[465,945,946],{},"Legend",[465,948,949],{},"the kinds present, as they are drawn",[452,951,952,955],{},[465,953,954],{},"List",[465,956,957],{},"every node again as a button, for keyboards and screen readers (the canvas is WebGL and has only a label)",[452,959,960,963],{},[465,961,962],{},"Notice",[465,964,965,967],{},[432,966,567],{},": more than 500 Blocks, the rest left out",[418,969,970,971,561],{},"The panel renders nothing when the backend has no ",[432,972,973],{},"index.graph",[441,975,977],{"id":976},"framework-free-parts","Framework-free parts",[418,979,980,982],{},[432,981,438],{}," (no sigma, no DOM):",[446,984,985,993],{},[449,986,987],{},[452,988,989,991],{},[455,990],{},[455,992],{},[460,994,995,1017,1030,1040,1068,1088],{},[452,996,997,1002],{},[465,998,999],{},[432,1000,1001],{},"buildGraph(data, { focus?, iterations? })",[465,1003,1004,1005,1008,1009,1012,1013,1016],{},"the graphology ",[432,1006,1007],{},"MultiDirectedGraph",": node attributes ",[432,1010,1011],{},"label x y size color documentId blockId blockType focus",", Edge attributes ",[432,1014,1015],{},"color size dash gap kind origin","; positions are deterministic (circle, then ForceAtlas2)",[452,1018,1019,1024],{},[465,1020,1021],{},[432,1022,1023],{},"edgeStyleOf({ kind, origin })",[465,1025,1026,1029],{},[432,1027,1028],{},"{ color, dashed }",": the style table of the panel",[452,1031,1032,1037],{},[465,1033,1034],{},[432,1035,1036],{},"legendOf(data)",[465,1038,1039],{},"the legend entries",[452,1041,1042,1047],{},[465,1043,1044],{},[432,1045,1046],{},"createGraphPanelModel({ load, open, depth? })",[465,1048,1049,1050,1053,1054,907,1057,907,1060,907,1063,907,1065],{},"the model both components render: ",[432,1051,1052],{},"state"," (target, depth, status, last answer), ",[432,1055,1056],{},"setTarget",[432,1058,1059],{},"setDepth",[432,1061,1062],{},"reload",[432,1064,780],{},[432,1066,1067],{},"dispose",[452,1069,1070,1075],{},[465,1071,1072],{},[432,1073,1074],{},"graphLoaderOf(backend)",[465,1076,1077,1080,1081,1084,1085],{},[432,1078,1079],{},"load"," for ",[432,1082,1083],{},"createGraphPanelModel",", over ",[432,1086,1087],{},"backend.index.graph",[452,1089,1090,1095],{},[465,1091,1092],{},[432,1093,1094],{},"createGraphTranslator(locale, overrides?)",[465,1096,1097],{},"the add-on's own German and English strings",[418,1099,1100,1101,1104,1105,661,1108,1111],{},"sigma (WebGL) loads when a panel mounts, so importing the package costs nothing and server-side rendering never meets it. The dashed Edges use sigma's ",[432,1102,1103],{},"layerDashed"," with the Edge attributes ",[432,1106,1107],{},"dash",[432,1109,1110],{},"gap",": an authored Edge has 8 px dashes and 5 px gaps, every other Edge one dash longer than the canvas and no gap.",[441,1113,1115],{"id":1114},"wiring-a-host","Wiring a host",[418,1117,1118,1119,1121],{},"The add-on needs no feature and no port of its own. The host only mounts the panel where it wants it (a sidebar tab, the Block's details) and passes ",[432,1120,780],{},":",[685,1123,1125],{"className":732,"code":1124,"language":734,"meta":690,"style":690},"\u003Cscript setup lang=\"ts\">\nimport { GraphPanel } from '@skaile\u002Fforge-editor-graph\u002Fvue'\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CGraphPanel :document-id=\"documentId\" :block-id=\"blockId\" :open=\"openHit\" \u002F>\n\u003C\u002Ftemplate>\n",[432,1126,1127,1151,1171,1181,1188,1198,1244],{"__ignoreMap":690},[694,1128,1129,1131,1134,1137,1140,1142,1144,1146,1148],{"class":696,"line":697},[694,1130,741],{"class":704},[694,1132,1133],{"class":744},"script",[694,1135,1136],{"class":751}," setup",[694,1138,1139],{"class":751}," lang",[694,1141,755],{"class":704},[694,1143,758],{"class":704},[694,1145,689],{"class":721},[694,1147,758],{"class":704},[694,1149,1150],{"class":704},">\n",[694,1152,1154,1156,1158,1160,1162,1164,1166,1168],{"class":696,"line":1153},2,[694,1155,701],{"class":700},[694,1157,705],{"class":704},[694,1159,709],{"class":708},[694,1161,712],{"class":704},[694,1163,715],{"class":700},[694,1165,718],{"class":704},[694,1167,722],{"class":721},[694,1169,1170],{"class":704},"'\n",[694,1172,1174,1177,1179],{"class":696,"line":1173},3,[694,1175,1176],{"class":704},"\u003C\u002F",[694,1178,1133],{"class":744},[694,1180,1150],{"class":704},[694,1182,1184],{"class":696,"line":1183},4,[694,1185,1187],{"emptyLinePlaceholder":1186},true,"\n",[694,1189,1191,1193,1196],{"class":696,"line":1190},5,[694,1192,741],{"class":704},[694,1194,1195],{"class":744},"template",[694,1197,1150],{"class":704},[694,1199,1201,1204,1206,1208,1210,1212,1214,1216,1218,1220,1222,1224,1226,1228,1230,1232,1234,1236,1238,1240,1242],{"class":696,"line":1200},6,[694,1202,1203],{"class":704},"  \u003C",[694,1205,745],{"class":744},[694,1207,748],{"class":704},[694,1209,752],{"class":751},[694,1211,755],{"class":704},[694,1213,758],{"class":704},[694,1215,491],{"class":708},[694,1217,758],{"class":704},[694,1219,748],{"class":704},[694,1221,767],{"class":751},[694,1223,755],{"class":704},[694,1225,758],{"class":704},[694,1227,495],{"class":708},[694,1229,758],{"class":704},[694,1231,748],{"class":704},[694,1233,780],{"class":751},[694,1235,755],{"class":704},[694,1237,758],{"class":704},[694,1239,863],{"class":708},[694,1241,758],{"class":704},[694,1243,792],{"class":704},[694,1245,1247,1249,1251],{"class":696,"line":1246},7,[694,1248,1176],{"class":704},[694,1250,1195],{"class":744},[694,1252,1150],{"class":704},[418,1254,1255,1256,1259,1260,1263],{},"The repository's document pages (the file-drawer layout, ",[432,1257,1258],{},"app\u002Flayouts\u002Fdefault.vue",") show it behind ",[432,1261,1262],{},"NUXT_PUBLIC_ADDONS_GRAPH=1","; the kitchen sink's standalone pages have no workspace index and show no graph.",[1265,1266,1267],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":690,"searchDepth":1153,"depth":1153,"links":1269},[1270,1271,1272,1273],{"id":443,"depth":1153,"text":444},{"id":682,"depth":1153,"text":683},{"id":976,"depth":1153,"text":977},{"id":1114,"depth":1153,"text":1115},"The graph route that walks the Edges of the Block index in both directions, the walk's limits, the client call, and the @skaile\u002Fforge-editor-graph add-on that draws the answer with sigma in Vue and React.","md",null,{},{"icon":260},{"title":257,"description":1274},"tq3oRoXR2Ow-d0Eu1iC7hUZ6ZZjnrusJxeWGiUEqKi0",[1282,1284],{"title":252,"path":253,"stem":254,"description":1283,"icon":255,"children":-1},"The SpeechProvider port with its engines and voices, the SSE route that streams progress and stores the audio as an asset, the daily character budget, the client call, and the block action that exports a transcript as WebVTT or SubRip.",{"title":262,"path":263,"stem":264,"description":1285,"icon":265,"children":-1},"The add-on @skaile\u002Fforge-editor-pdf-viewer: the source-anchor property, a pdfjs viewer with a text layer, scrolling to a passage on reveal, and „Zitat anlegen“, which creates a quote block derived from the PDF.",1793213906857]