[{"data":1,"prerenderedAt":4510},["ShallowReactive",2],{"navigation_docs":3,"-guides-composites":412,"-guides-composites-surround":4505},[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":109,"body":414,"description":4498,"extension":4499,"links":4500,"meta":4501,"navigation":4502,"path":110,"seo":4503,"stem":111,"__hash__":4504},"docs\u002F3.guides\u002F13.composites.md",{"type":415,"value":416,"toc":4484},"minimark",[417,433,905,919,942,1004,1009,1477,1536,1818,1910,2164,2202,2251,2324,2362,2407,2443,2535,2539,2558,2562,2579,2689,2695,2771,2797,2800,2817,2821,2828,2944,2951,2961,2965,2982,3151,3154,3157,3186,3224,3230,3234,3240,3350,3501,3608,3612,3729,3751,3755,3761,3864,3977,4045,4049,4059,4152,4156,4198,4342,4355,4477,4480],[418,419,420,424,425,428,429,432],"p",{},[421,422,423],"code",{},"compositeFeature()"," adds Typed blocks: Container blocks with a Block type, a title, a description, tags, the Block properties their Block type defines and a body that may hold more blocks and Typed blocks. It needs no AI, media, transcript or Yjs code (",[421,426,427],{},"bun run check:editor-entries"," proves it with the ",[421,430,431],{},"composites"," fixture), and it adds no dependency beyond the core peers.",[434,435,440],"pre",{"className":436,"code":437,"language":438,"meta":439,"style":439},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nimport { compositeFeature } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fvue'\nimport { coreContentFeature, coreUiFeature, defineEditor } from '@skaile\u002Fforge-editor\u002Fcore'\nimport { EditorSettingsPanel, EditorSurface, EditorToolbar } from '@skaile\u002Fforge-editor\u002Fvue'\nimport type { Editor } from '@tiptap\u002Fvue-3'\nimport { shallowRef } from 'vue'\n\nconst preset = defineEditor({ features: [coreContentFeature(), coreUiFeature(), compositeFeature()] })\nconst editor = shallowRef\u003CEditor>()\nconst tab = shallowRef\u003Cstring>()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CEditorToolbar :editor=\"editor\" \u002F>\n  \u003CEditorSurface v-model=\"content\" :preset=\"preset\" settings-ui=\"external\" @ready=\"editor = $event\" @settings-open=\"tab = $event ?? tab\" \u002F>\n  \u003CEditorSettingsPanel v-model:tab=\"tab\" :editor=\"editor\" \u002F>\n\u003C\u002Ftemplate>\n","vue","",[421,441,442,477,506,538,569,593,613,620,674,698,719,729,734,744,770,860,896],{"__ignoreMap":439},[443,444,447,451,455,459,462,465,468,472,474],"span",{"class":445,"line":446},"line",1,[443,448,450],{"class":449},"sMK4o","\u003C",[443,452,454],{"class":453},"swJcz","script",[443,456,458],{"class":457},"spNyl"," setup",[443,460,461],{"class":457}," lang",[443,463,464],{"class":449},"=",[443,466,467],{"class":449},"\"",[443,469,471],{"class":470},"sfazB","ts",[443,473,467],{"class":449},[443,475,476],{"class":449},">\n",[443,478,480,484,487,491,494,497,500,503],{"class":445,"line":479},2,[443,481,483],{"class":482},"s7zQu","import",[443,485,486],{"class":449}," {",[443,488,490],{"class":489},"sTEyZ"," compositeFeature",[443,492,493],{"class":449}," }",[443,495,496],{"class":482}," from",[443,498,499],{"class":449}," '",[443,501,502],{"class":470},"@skaile\u002Fforge-editor\u002Fcomposites\u002Fvue",[443,504,505],{"class":449},"'\n",[443,507,509,511,513,516,519,522,524,527,529,531,533,536],{"class":445,"line":508},3,[443,510,483],{"class":482},[443,512,486],{"class":449},[443,514,515],{"class":489}," coreContentFeature",[443,517,518],{"class":449},",",[443,520,521],{"class":489}," coreUiFeature",[443,523,518],{"class":449},[443,525,526],{"class":489}," defineEditor",[443,528,493],{"class":449},[443,530,496],{"class":482},[443,532,499],{"class":449},[443,534,535],{"class":470},"@skaile\u002Fforge-editor\u002Fcore",[443,537,505],{"class":449},[443,539,541,543,545,548,550,553,555,558,560,562,564,567],{"class":445,"line":540},4,[443,542,483],{"class":482},[443,544,486],{"class":449},[443,546,547],{"class":489}," EditorSettingsPanel",[443,549,518],{"class":449},[443,551,552],{"class":489}," EditorSurface",[443,554,518],{"class":449},[443,556,557],{"class":489}," EditorToolbar",[443,559,493],{"class":449},[443,561,496],{"class":482},[443,563,499],{"class":449},[443,565,566],{"class":470},"@skaile\u002Fforge-editor\u002Fvue",[443,568,505],{"class":449},[443,570,572,574,577,579,582,584,586,588,591],{"class":445,"line":571},5,[443,573,483],{"class":482},[443,575,576],{"class":482}," type",[443,578,486],{"class":449},[443,580,581],{"class":489}," Editor",[443,583,493],{"class":449},[443,585,496],{"class":482},[443,587,499],{"class":449},[443,589,590],{"class":470},"@tiptap\u002Fvue-3",[443,592,505],{"class":449},[443,594,596,598,600,603,605,607,609,611],{"class":445,"line":595},6,[443,597,483],{"class":482},[443,599,486],{"class":449},[443,601,602],{"class":489}," shallowRef",[443,604,493],{"class":449},[443,606,496],{"class":482},[443,608,499],{"class":449},[443,610,438],{"class":470},[443,612,505],{"class":449},[443,614,616],{"class":445,"line":615},7,[443,617,619],{"emptyLinePlaceholder":618},true,"\n",[443,621,623,626,629,631,634,637,640,643,646,649,652,655,657,659,661,663,665,668,671],{"class":445,"line":622},8,[443,624,625],{"class":457},"const",[443,627,628],{"class":489}," preset ",[443,630,464],{"class":449},[443,632,526],{"class":633},"s2Zo4",[443,635,636],{"class":489},"(",[443,638,639],{"class":449},"{",[443,641,642],{"class":453}," features",[443,644,645],{"class":449},":",[443,647,648],{"class":489}," [",[443,650,651],{"class":633},"coreContentFeature",[443,653,654],{"class":489},"()",[443,656,518],{"class":449},[443,658,521],{"class":633},[443,660,654],{"class":489},[443,662,518],{"class":449},[443,664,490],{"class":633},[443,666,667],{"class":489},"()] ",[443,669,670],{"class":449},"}",[443,672,673],{"class":489},")\n",[443,675,677,679,682,684,686,688,692,695],{"class":445,"line":676},9,[443,678,625],{"class":457},[443,680,681],{"class":489}," editor ",[443,683,464],{"class":449},[443,685,602],{"class":633},[443,687,450],{"class":449},[443,689,691],{"class":690},"sBMFI","Editor",[443,693,694],{"class":449},">",[443,696,697],{"class":489},"()\n",[443,699,701,703,706,708,710,712,715,717],{"class":445,"line":700},10,[443,702,625],{"class":457},[443,704,705],{"class":489}," tab ",[443,707,464],{"class":449},[443,709,602],{"class":633},[443,711,450],{"class":449},[443,713,714],{"class":690},"string",[443,716,694],{"class":449},[443,718,697],{"class":489},[443,720,722,725,727],{"class":445,"line":721},11,[443,723,724],{"class":449},"\u003C\u002F",[443,726,454],{"class":453},[443,728,476],{"class":449},[443,730,732],{"class":445,"line":731},12,[443,733,619],{"emptyLinePlaceholder":618},[443,735,737,739,742],{"class":445,"line":736},13,[443,738,450],{"class":449},[443,740,741],{"class":453},"template",[443,743,476],{"class":449},[443,745,747,750,753,756,759,761,763,765,767],{"class":445,"line":746},14,[443,748,749],{"class":449},"  \u003C",[443,751,752],{"class":453},"EditorToolbar",[443,754,755],{"class":449}," :",[443,757,758],{"class":457},"editor",[443,760,464],{"class":449},[443,762,467],{"class":449},[443,764,758],{"class":489},[443,766,467],{"class":449},[443,768,769],{"class":449}," \u002F>\n",[443,771,773,775,778,781,783,785,788,790,792,795,797,799,801,803,806,808,810,813,815,818,821,823,825,827,830,833,835,837,840,842,844,847,849,851,854,856,858],{"class":445,"line":772},15,[443,774,749],{"class":449},[443,776,777],{"class":453},"EditorSurface",[443,779,780],{"class":457}," v-model",[443,782,464],{"class":449},[443,784,467],{"class":449},[443,786,787],{"class":489},"content",[443,789,467],{"class":449},[443,791,755],{"class":449},[443,793,794],{"class":457},"preset",[443,796,464],{"class":449},[443,798,467],{"class":449},[443,800,794],{"class":489},[443,802,467],{"class":449},[443,804,805],{"class":457}," settings-ui",[443,807,464],{"class":449},[443,809,467],{"class":449},[443,811,812],{"class":470},"external",[443,814,467],{"class":449},[443,816,817],{"class":449}," @",[443,819,820],{"class":457},"ready",[443,822,464],{"class":449},[443,824,467],{"class":449},[443,826,758],{"class":489},[443,828,829],{"class":449}," = ",[443,831,832],{"class":489},"$event",[443,834,467],{"class":449},[443,836,817],{"class":449},[443,838,839],{"class":457},"settings-open",[443,841,464],{"class":449},[443,843,467],{"class":449},[443,845,846],{"class":489},"tab",[443,848,829],{"class":449},[443,850,832],{"class":489},[443,852,853],{"class":449}," ?? ",[443,855,846],{"class":489},[443,857,467],{"class":449},[443,859,769],{"class":449},[443,861,863,865,868,870,872,874,876,878,880,882,884,886,888,890,892,894],{"class":445,"line":862},16,[443,864,749],{"class":449},[443,866,867],{"class":453},"EditorSettingsPanel",[443,869,780],{"class":457},[443,871,645],{"class":449},[443,873,846],{"class":457},[443,875,464],{"class":449},[443,877,467],{"class":449},[443,879,846],{"class":489},[443,881,467],{"class":449},[443,883,755],{"class":449},[443,885,758],{"class":457},[443,887,464],{"class":449},[443,889,467],{"class":449},[443,891,758],{"class":489},[443,893,467],{"class":449},[443,895,769],{"class":449},[443,897,899,901,903],{"class":445,"line":898},17,[443,900,724],{"class":449},[443,902,741],{"class":453},[443,904,476],{"class":449},[418,906,907,908,911,912,915,916,645],{},"Import the feature CSS after ",[421,909,910],{},"tailwindcss",", ",[421,913,914],{},"@nuxt\u002Fui"," and ",[421,917,918],{},"core.css",[434,920,924],{"className":921,"code":922,"language":923,"meta":439,"style":439},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","@import \"@skaile\u002Fforge-editor\u002Fstyles\u002Fcomposites.css\";\n","css",[421,925,926],{"__ignoreMap":439},[443,927,928,931,934,937,939],{"class":445,"line":446},[443,929,930],{"class":482},"@import",[443,932,933],{"class":449}," \"",[443,935,936],{"class":470},"@skaile\u002Fforge-editor\u002Fstyles\u002Fcomposites.css",[443,938,467],{"class":449},[443,940,941],{"class":449},";\n",[418,943,944,945,947,948,951,952,911,955,911,958,911,961,911,964,967,968,911,971,974,975,978,979,982,983,911,986,989,990,911,992,994,995,998,999,1003],{},"On React the feature is ",[421,946,423],{}," from ",[421,949,950],{},"@skaile\u002Fforge-editor\u002Fcomposites\u002Freact",", with the same components (",[421,953,954],{},"CompositeTable",[421,956,957],{},"CompositeInspector",[421,959,960],{},"CompositeView",[421,962,963],{},"CompositeDetails",[421,965,966],{},"CompositeFieldEditor",", ...) and hooks (",[421,969,970],{},"useCompositeRows",[421,972,973],{},"useCompositeAnchors","); the framework-free ",[421,976,977],{},"@skaile\u002Fforge-editor\u002Fcomposites"," holds ",[421,980,981],{},"compositeFeatureCore(ui, options)",", the nodes, conversions, fences and the models behind the hooks (",[421,984,985],{},"createCompositeRows",[421,987,988],{},"observeCompositeAnchors","). ",[421,991,752],{},[421,993,777],{}," and the settings components come from ",[421,996,997],{},"@skaile\u002Fforge-editor\u002Freact"," (",[1000,1001,1002],"a",{"href":30},"simple React setup",").",[1005,1006,1008],"h2",{"id":1007},"what-the-feature-contributes","What the feature contributes",[1010,1011,1012,1041,1047,1068,1150,1273,1393,1423,1432],"ul",{},[1013,1014,1015,1019,1020,1023,1024,1027,1028,1031,1032,1036,1037,1040],"li",{},[1016,1017,1018],"strong",{},"Nodes and node views:"," ",[421,1021,1022],{},"typedBlock"," (attributes ",[421,1025,1026],{},"blockType",", the id of the Block type, and ",[421,1029,1030],{},"meta",", the Block properties) with its title, description and tags children. The title, description and tags are ",[1033,1034,1035],"em",{},"chrome",": they cannot be selected, dragged, deleted or duplicated apart from their Typed block. Stored documents with the old ",[421,1038,1039],{},"metaVisible"," attribute still load; the attribute is dropped.",[1013,1042,1043,1046],{},[1016,1044,1045],{},"Toolbar group:"," insert a Typed block of the default Block type, „In Block umwandeln“ (Block type menu for the block at the caret) and „Gliederung umwandeln“ (headings ↔ Typed blocks, the direction of the Structure mode first; the last entry opens the settings when some feature contributes a tab).",[1013,1048,1049,1055,1056,1059,1060,1063,1064,1003],{},[1016,1050,1051,1054],{},[421,1052,1053],{},"\u002F"," commands, block actions and overlay:"," one insert command per Block type, the heading ↔ Typed block conversions, the Typed-block-specific hover action (Markdown export of a Typed block whose Block type lists the ",[421,1057,1058],{},"export"," capability, the built-in ",[421,1061,1062],{},"document",") and the chip\u002Fdetails-popover overlay (",[1000,1065,1067],{"href":1066},"#chips-and-details-popover","below",[1013,1069,1070,1073,1074,1081,1082,1085,1086,1089,1090,1093,1094,1097,1098,1100,1101,1104,1105,911,1108,911,1111,1114,1115,1117,1118,1120,1121,1124,1125,998,1128,1131,1132,1135,1136,1139,1140,1143,1144,1003],{},[1016,1071,1072],{},"Conversion providers"," (below), ",[1016,1075,1076,1077,1080],{},"Markdown ",[421,1078,1079],{},":::"," fences"," for import (",[421,1083,1084],{},"::: kind {meta}",", where ",[421,1087,1088],{},"kind"," is the Block type id, or ",[421,1091,1092],{},"::: kind #\u003Cblock id> {meta}",": a Typed block that a ",[421,1095,1096],{},"reference"," chip or ",[421,1099,1096],{}," property points at writes its block id after the Block type id, so ",[421,1102,1103],{},"[@\u003Cid>]"," references survive a Markdown round trip; other fences carry no id; ",[421,1106,1107],{},"## title",[421,1109,1110],{},"> description",[421,1112,1113],{},"Tags: #a #b",", body, ",[421,1116,1079],{},"; nested fences close with the same bare ",[421,1119,1079],{},"; a fence of a Block type that is not registered stays an ",[421,1122,1123],{},"opaqueFence"," and is written back verbatim) and export, ",[1016,1126,1127],{},"legacy migration",[421,1129,1130],{},"section"," blocks of old documents become Typed blocks; servers read stored content through ",[421,1133,1134],{},"currentContent"," of ",[421,1137,1138],{},"@skaile\u002Fforge-editor\u002Fserver","), and the ",[421,1141,1142],{},"structure"," pipeline stage that turns Markdown headings into Typed blocks or Typed blocks into headings according to the Structure mode (Structure mode nests Typed blocks, Flat mode uses headings).\nThe fences are an import\u002Fexport format, not storage: the stored document JSON (Yjs in a collaborative session) is canonical, and a fence carries a block ID only for a referenced Typed block, so an external edit of exported Markdown gives the other blocks new IDs on import (",[1000,1145,1149],{"href":1146,"rel":1147},"https:\u002F\u002Fgithub.com\u002Fskaile-ai\u002Fforge-editor\u002Fblob\u002Fmain\u002Fdocs\u002Fadr\u002F0001-database-canonical-markdown-export.md",[1148],"nofollow","ADR-0001",[1013,1151,1152,1155,1156,911,1158,1161,1162,915,1165,1168,1169,1172,1173,1176,1177,1180,1181,1184,1185,1188,1189,1192,1193,1196,1197,1200,1201,998,1204,1207,1208,1211,1212,911,1215,911,1218,911,1221,911,1224,911,1227,1230,1231,1234,1235,911,1238,998,1241,1244,1245,1247,1248,1250,1251,1254,1255,1257,1258,1261,1262,1265,1266,1269,1270,1272],{},[1016,1153,1154],{},"Typed blocks with a Source, and Derived blocks."," The Block types ",[421,1157,1062],{},[421,1159,1160],{},"recording"," (audio\u002Fvideo), ",[421,1163,1164],{},"paper",[421,1166,1167],{},"book"," (PDF) and ",[421,1170,1171],{},"figure"," (image) list the ",[421,1174,1175],{},"source"," capability (config ",[421,1178,1179],{},"{ media }",", a list of ",[421,1182,1183],{},"SOURCE_MEDIA_TYPES","): the first ",[421,1186,1187],{},"audio|video|image|file"," block of their body is the Source media, which ",[421,1190,1191],{},"sourceOf(composite, blockTypes)"," returns with its asset reference and ",[421,1194,1195],{},"hash",". A child Typed block of the ",[421,1198,1199],{},"rendition"," Block type (shown as “Readable rendition”) holds the readable form (transcript, full text, description) as a block tree. Any Typed block may carry ",[421,1202,1203],{},"meta.derivation",[421,1205,1206],{},"Derivation",": ",[421,1209,1210],{},"from"," an asset or a block, ",[421,1213,1214],{},"method",[421,1216,1217],{},"model",[421,1219,1220],{},"createdAt",[421,1222,1223],{},"inputHash",[421,1225,1226],{},"outputHash",[421,1228,1229],{},"output",") and is then a Derived block; ",[421,1232,1233],{},"derivedChildrenOf(composite)"," lists the Derived blocks in a Typed block's body, ",[421,1236,1237],{},"derivationOf",[421,1239,1240],{},"derivationState",[421,1242,1243],{},"stale",": the source's ",[421,1246,1195],{}," or, for a block source, its Markdown hash differs from ",[421,1249,1223],{},"; ",[421,1252,1253],{},"edited",": the body differs from ",[421,1256,1226],{},") and ",[421,1259,1260],{},"bodyMarkdown"," read the record. A Derived block starts collapsed (chevron, caret expands it), carries an „abgeleitet“ badge, and its chrome shows „Quelle geändert“ for an asset source that changed; the details card additionally shows method, model, date, „bearbeitet“, „Quelle geändert“ for block sources and a link to the stored raw output. Existing Typed blocks (of any Block type) with the former ",[421,1263,1264],{},"meta.transcript"," property are migrated on load into such a Readable rendition (on load, in the Feature's ",[421,1267,1268],{},"migrateContent"," hook and in ",[421,1271,1134],{}," on the server; the stored property decides, not the Block type).",[1013,1274,1275,1278,1279,998,1282,1285,1286,1289,1290,911,1293,911,1296,911,1299,911,1302,911,1305,1308,1309,1311,1312,1315,1316,1319,1320,1323,1324,1326,1327,1330,1331,1333,1334,1337,1338,1340,1341,1344,1345,1348,1349,1352,1353,1355,1356,911,1359,1362,1363,1366,1367,1370,1371,1374,1375,1378,1379,1053,1382,1385,1386,1389,1390,1003],{},[1016,1276,1277],{},"Bibliography and references."," The property types ",[421,1280,1281],{},"bibliography",[421,1283,1284],{},"meta.bib"," as CSL-JSON, ",[421,1287,1288],{},"CslItem",", the Bibliographic record; form editor with „DOI abrufen“ and „BibTeX kopieren“; ",[421,1291,1292],{},"bibOf",[421,1294,1295],{},"cslOf",[421,1297,1298],{},"citeShort",[421,1300,1301],{},"citeFull",[421,1303,1304],{},"bibtexOf",[421,1306,1307],{},"yearOf","), ",[421,1310,1096],{}," (a Block reference to a Typed block of the document, ",[421,1313,1314],{},"PropertyDefinition.targets"," limits the Block types) and ",[421,1317,1318],{},"derivation"," (read-only) extend the Property definitions of the ",[421,1321,1322],{},"properties"," capability (the ",[421,1325,1281],{}," capability gives the type the record, the ",[421,1328,1329],{},"references"," capability the ",[421,1332,1096],{}," chips); the block action „Literaturangabe exportieren (BibTeX)“ downloads a ",[421,1335,1336],{},".bib",". The inline ",[421,1339,1096],{}," chip (",[421,1342,1343],{},"ReferenceNode",") is inserted with ",[421,1346,1347],{},"[@"," or ",[421,1350,1351],{},"\u002Fverweis",", shows the target's ",[421,1354,1298],{}," or title, takes a locator („Stelle“: ",[421,1357,1358],{},"S. 12",[421,1360,1361],{},"3:07",") and reveals the target on click; with a locator ",[421,1364,1365],{},"revealSource(editor, targetId, locator)"," also seeks the source audio\u002Fvideo or opens the PDF viewer at that page. Markdown is ",[421,1368,1369],{},"[@\u003Cblock id>]"," \u002F ",[421,1372,1373],{},"[@\u003Cblock id>, \u003Clocator>]","; the details card lists backlinks („Verweise“, ",[421,1376,1377],{},"compositeBacklinks","). Transcript segments carry ",[421,1380,1381],{},"start",[421,1383,1384],{},"end"," (seconds) and a ",[421,1387,1388],{},"mm:ss"," button that seeks the source (",[421,1391,1392],{},"seekSource",[1013,1394,1395,1398,1399,1402,1403,1344,1406,1348,1409,1412,1413,1416,1417,1420,1421,1003],{},[1016,1396,1397],{},"Citations."," The inline ",[421,1400,1401],{},"cite"," node (",[421,1404,1405],{},"CiteNode",[421,1407,1408],{},"\u002Fzitat",[421,1410,1411],{},"[cite:",", names a bibliography entry of the Document by its BibTeX key, shows ",[421,1414,1415],{},"(Autor Jahr)"," and is written as ",[421,1418,1419],{},"[cite:\u003Ckey>, \u003Clocator>]"," in Markdown (",[1000,1422,229],{"href":230},[1013,1424,1425,1431],{},[1016,1426,1427,1428,645],{},"Settings tab ",[421,1429,1430],{},"editing"," the Structure mode (Structure mode or Flat mode), the scope of „Gliederung umwandeln“ without a selection, the root of a file browser's tree and the default Block type of new Typed blocks. The values live in the shared settings model, so every panel and editor of the app sees the same choice.",[1013,1433,1434,1019,1437,1440,1441,1257,1444,1447,1448,1450,1451,1454,1455,1458,1459,911,1462,1465,1466,1469,1470,1473,1474,1476],{},[1016,1435,1436],{},"Baskets, hidden titles, focus and splitting.",[421,1438,1439],{},"meta.basket"," (a Basket from ",[421,1442,1443],{},"compositeFeature({ baskets })",[421,1445,1446],{},"meta.titleHidden"," (title hidden) are reserved ",[421,1449,1030],{}," keys that every Block type keeps (",[1000,1452,1067],{"href":1453},"#reserved-meta-keys","); focus mode (",[421,1456,1457],{},"focusComposite",", block action „Fokussieren“, the focus chip) the split commands (",[421,1460,1461],{},"splitCompositeAtCaret",[421,1463,1464],{},"splitCompositeByLength"," and their four block actions) and the merge command (",[421,1467,1468],{},"mergeCompositeWithNext",", block action „Mit nächstem zusammenführen“) are part of the feature. The setting ",[421,1471,1472],{},"blocks.splitTargetChars"," (default 1500) has a field „Zielgröße beim Teilen (Zeichen)“ in the „Bearbeiten“ tab. All of it is explained in ",[1000,1475,155],{"href":156},".",[418,1478,1479,1480,1483,1484,1487,1488,1491,1492,1495,1496,911,1499,911,1502,911,1505,911,1508,1257,1510,1513,1514,1517,1518,1521,1522,1525,1526,1529,1530,1532,1533,1535],{},"Block types are data. ",[421,1481,1482],{},"compositeFeature({ blockTypes })"," replaces the built-in ",[421,1485,1486],{},"defaultBlockTypes(ctx.t)"," (section, task, ...; labelled in the context's language). A ",[421,1489,1490],{},"BlockType"," is an ",[421,1493,1494],{},"id",", its presentation (",[421,1497,1498],{},"label",[421,1500,1501],{},"icon",[421,1503,1504],{},"titlePlaceholder",[421,1506,1507],{},"descriptionPlaceholder",[421,1509,1035],{},[421,1511,1512],{},"capabilities",": a list of ",[421,1515,1516],{},"{ id, config? }"," entries, one per ",[1000,1519,1520],{"href":358},"Block capability"," the type supports. A capability the type does not list is absent from its Typed blocks: the Block inspector shows no properties, no Basket menu appears, the block actions that ",[421,1523,1524],{},"require"," it are not offered. No other field on the type switches a behaviour. ",[421,1527,1528],{},"blockTypesOf(editor)"," returns the editor's own list and an unknown ",[421,1531,1088],{}," id falls back to the ",[421,1534,1130],{}," presentation under its own label.",[434,1537,1540],{"className":1538,"code":1539,"language":471,"meta":439,"style":439},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const blockTypes: BlockType[] = [\n  ...defaultBlockTypes(ctx.t),\n  {\n    id: 'decision',\n    label: 'Entscheidung',\n    icon: 'i-lucide-gavel',\n    capabilities: [\n      { id: 'basket' },\n      { id: 'titleHidden' },\n      { id: 'properties', config: { definitions: [{ key: 'status', label: 'Status', type: 'select', options: [{ value: 'open', label: 'Offen' }] }] } },\n    ],\n  },\n]\n",[421,1541,1542,1562,1581,1586,1603,1619,1635,1644,1664,1681,1801,1808,1813],{"__ignoreMap":439},[443,1543,1544,1546,1549,1551,1554,1557,1559],{"class":445,"line":446},[443,1545,625],{"class":457},[443,1547,1548],{"class":489}," blockTypes",[443,1550,645],{"class":449},[443,1552,1553],{"class":690}," BlockType",[443,1555,1556],{"class":489},"[] ",[443,1558,464],{"class":449},[443,1560,1561],{"class":489}," [\n",[443,1563,1564,1567,1570,1573,1575,1578],{"class":445,"line":479},[443,1565,1566],{"class":449},"  ...",[443,1568,1569],{"class":633},"defaultBlockTypes",[443,1571,1572],{"class":489},"(ctx",[443,1574,1476],{"class":449},[443,1576,1577],{"class":489},"t)",[443,1579,1580],{"class":449},",\n",[443,1582,1583],{"class":445,"line":508},[443,1584,1585],{"class":449},"  {\n",[443,1587,1588,1591,1593,1595,1598,1601],{"class":445,"line":540},[443,1589,1590],{"class":453},"    id",[443,1592,645],{"class":449},[443,1594,499],{"class":449},[443,1596,1597],{"class":470},"decision",[443,1599,1600],{"class":449},"'",[443,1602,1580],{"class":449},[443,1604,1605,1608,1610,1612,1615,1617],{"class":445,"line":571},[443,1606,1607],{"class":453},"    label",[443,1609,645],{"class":449},[443,1611,499],{"class":449},[443,1613,1614],{"class":470},"Entscheidung",[443,1616,1600],{"class":449},[443,1618,1580],{"class":449},[443,1620,1621,1624,1626,1628,1631,1633],{"class":445,"line":595},[443,1622,1623],{"class":453},"    icon",[443,1625,645],{"class":449},[443,1627,499],{"class":449},[443,1629,1630],{"class":470},"i-lucide-gavel",[443,1632,1600],{"class":449},[443,1634,1580],{"class":449},[443,1636,1637,1640,1642],{"class":445,"line":615},[443,1638,1639],{"class":453},"    capabilities",[443,1641,645],{"class":449},[443,1643,1561],{"class":489},[443,1645,1646,1649,1652,1654,1656,1659,1661],{"class":445,"line":622},[443,1647,1648],{"class":449},"      {",[443,1650,1651],{"class":453}," id",[443,1653,645],{"class":449},[443,1655,499],{"class":449},[443,1657,1658],{"class":470},"basket",[443,1660,1600],{"class":449},[443,1662,1663],{"class":449}," },\n",[443,1665,1666,1668,1670,1672,1674,1677,1679],{"class":445,"line":676},[443,1667,1648],{"class":449},[443,1669,1651],{"class":453},[443,1671,645],{"class":449},[443,1673,499],{"class":449},[443,1675,1676],{"class":470},"titleHidden",[443,1678,1600],{"class":449},[443,1680,1663],{"class":449},[443,1682,1683,1685,1687,1689,1691,1693,1695,1697,1700,1702,1704,1707,1709,1711,1713,1716,1718,1720,1723,1725,1727,1730,1732,1734,1737,1739,1741,1743,1745,1747,1750,1752,1754,1757,1759,1761,1763,1766,1768,1770,1773,1775,1777,1779,1781,1783,1786,1788,1790,1793,1795,1797,1799],{"class":445,"line":700},[443,1684,1648],{"class":449},[443,1686,1651],{"class":453},[443,1688,645],{"class":449},[443,1690,499],{"class":449},[443,1692,1322],{"class":470},[443,1694,1600],{"class":449},[443,1696,518],{"class":449},[443,1698,1699],{"class":453}," config",[443,1701,645],{"class":449},[443,1703,486],{"class":449},[443,1705,1706],{"class":453}," definitions",[443,1708,645],{"class":449},[443,1710,648],{"class":489},[443,1712,639],{"class":449},[443,1714,1715],{"class":453}," key",[443,1717,645],{"class":449},[443,1719,499],{"class":449},[443,1721,1722],{"class":470},"status",[443,1724,1600],{"class":449},[443,1726,518],{"class":449},[443,1728,1729],{"class":453}," label",[443,1731,645],{"class":449},[443,1733,499],{"class":449},[443,1735,1736],{"class":470},"Status",[443,1738,1600],{"class":449},[443,1740,518],{"class":449},[443,1742,576],{"class":453},[443,1744,645],{"class":449},[443,1746,499],{"class":449},[443,1748,1749],{"class":470},"select",[443,1751,1600],{"class":449},[443,1753,518],{"class":449},[443,1755,1756],{"class":453}," options",[443,1758,645],{"class":449},[443,1760,648],{"class":489},[443,1762,639],{"class":449},[443,1764,1765],{"class":453}," value",[443,1767,645],{"class":449},[443,1769,499],{"class":449},[443,1771,1772],{"class":470},"open",[443,1774,1600],{"class":449},[443,1776,518],{"class":449},[443,1778,1729],{"class":453},[443,1780,645],{"class":449},[443,1782,499],{"class":449},[443,1784,1785],{"class":470},"Offen",[443,1787,1600],{"class":449},[443,1789,493],{"class":449},[443,1791,1792],{"class":489},"] ",[443,1794,670],{"class":449},[443,1796,1792],{"class":489},[443,1798,670],{"class":449},[443,1800,1663],{"class":449},[443,1802,1803,1806],{"class":445,"line":721},[443,1804,1805],{"class":489},"    ]",[443,1807,1580],{"class":449},[443,1809,1810],{"class":445,"line":731},[443,1811,1812],{"class":449},"  },\n",[443,1814,1815],{"class":445,"line":736},[443,1816,1817],{"class":489},"]\n",[1819,1820,1821,1836],"table",{},[1822,1823,1824],"thead",{},[1825,1826,1827,1833],"tr",{},[1828,1829,1830,1832],"th",{},[421,1831,1490],{}," member",[1828,1834,1835],{},"Content",[1837,1838,1839,1855,1868,1879,1901],"tbody",{},[1825,1840,1841,1846],{},[1842,1843,1844],"td",{},[421,1845,1494],{},[1842,1847,1848,1849,1851,1852,1854],{},"the Block type id, stored in the ",[421,1850,1026],{}," attribute and written after ",[421,1853,1079],{}," in Markdown fences",[1825,1856,1857,1863],{},[1842,1858,1859,911,1861],{},[421,1860,1498],{},[421,1862,1501],{},[1842,1864,1865,1866],{},"name and icon in menus, the details popover and the ",[1000,1867,117],{"href":118},[1825,1869,1870,1876],{},[1842,1871,1872,911,1874],{},[421,1873,1504],{},[421,1875,1507],{},[1842,1877,1878],{},"placeholders of the empty title and description (the summary)",[1825,1880,1881,1885],{},[1842,1882,1883],{},[421,1884,1035],{},[1842,1886,1887,911,1890,911,1893,1896,1897,1900],{},[421,1888,1889],{},"tags",[421,1891,1892],{},"tone",[421,1894,1895],{},"controls"," (see ",[1033,1898,1899],{},"Chrome per Block type"," below)",[1825,1902,1903,1907],{},[1842,1904,1905],{},[421,1906,1512],{},[1842,1908,1909],{},"the capabilities the type supports, each with its config. An unknown id or an invalid config throws when the editor is created",[1819,1911,1912,1925],{},[1822,1913,1914],{},[1825,1915,1916,1919,1922],{},[1828,1917,1918],{},"Capability (declared by)",[1828,1920,1921],{},"Config",[1828,1923,1924],{},"What it gives a Typed block of the type",[1837,1926,1927,1969,1990,2009,2024,2038,2052,2100,2117,2149],{},[1825,1928,1929,1935,1940],{},[1842,1930,1931,1934],{},[421,1932,1933],{},"container"," (built in)",[1842,1936,1937],{},[421,1938,1939],{},"{ accepts?: readonly string[] | 'all', nestedAfterContent?: boolean, root?: boolean }",[1842,1941,1942,1943,1946,1947,1950,1951,1954,1955,1950,1958,1961,1962,1964,1965,1968],{},"a body of its own; ",[421,1944,1945],{},"accepts"," names the Accepted children (see ",[1033,1948,1949],{},"Accepted children"," below), ",[421,1952,1953],{},"nestedAfterContent"," keeps nested Typed blocks after the own content (see ",[1033,1956,1957],{},"Order of nested Typed blocks",[421,1959,1960],{},"root: true"," makes the type the Block type of the document tree's document rows (the built-in ",[421,1963,1062],{}," sets it; ",[421,1966,1967],{},"isRootBlockType(type)"," reads it)",[1825,1970,1971,1976,1981],{},[1842,1972,1973,1975],{},[421,1974,1322],{}," (composites)",[1842,1977,1978],{},[421,1979,1980],{},"{ definitions: PropertyDefinition[] }",[1842,1982,1983,1984,1986,1987,1989],{},"the Block properties stored in ",[421,1985,1030],{},", shown in the details popover, the table and the Block inspector's Block properties section (any node with a ",[421,1988,1030],{}," attribute whose Block type lists the capability)",[1825,1991,1992,1996,2001],{},[1842,1993,1994,1975],{},[421,1995,1175],{},[1842,1997,1998],{},[421,1999,2000],{},"{ media: SourceMedia[] }",[1842,2002,2003,2004,2006,2007],{},"a Source: the first body child of one of these media types (",[421,2005,1183],{},"); needs ",[421,2008,1933],{},[1825,2010,2011,2015,2018],{},[1842,2012,2013,1975],{},[421,2014,1281],{},[1842,2016,2017],{},"none",[1842,2019,2020,2021,2023],{},"the Bibliographic record in ",[421,2022,1284],{}," and the BibTeX export action",[1825,2025,2026,2030,2032],{},[1842,2027,2028,1975],{},[421,2029,1658],{},[1842,2031,2017],{},[1842,2033,2034,2035,2037],{},"the Basket menu and stripe (",[421,2036,1439],{},")",[1825,2039,2040,2044,2046],{},[1842,2041,2042,1975],{},[421,2043,1676],{},[1842,2045,2017],{},[1842,2047,2048,2049,2051],{},"the eye button in the chrome („Titel ausblenden“ \u002F „Titel einblenden“) that sets and clears ",[421,2050,1446],{},"; a type without it has no button (the flag is still kept)",[1825,2053,2054,2063,2068],{},[1842,2055,2056,2059,2060,2037],{},[421,2057,2058],{},"ai-brief"," (composites; read by ",[421,2061,2062],{},"composite-ai",[1842,2064,2065],{},[421,2066,2067],{},"BlockTypeAi",[1842,2069,2070,2071,2074,2075,911,2078,2081,2082,2085,2086,1257,2088,2091,2092,2095,2096,2099],{},"the AI brief: ",[421,2072,2073],{},"purpose"," goes into every AI request's block model; ",[421,2076,2077],{},"instructions",[421,2079,2080],{},"instructionsField"," (the key of a ",[421,2083,2084],{},"textarea"," property whose non-empty value replaces ",[421,2087,2077],{},[421,2089,2090],{},"contentTemplate"," (the AI content template: Markdown target text whose ",[421,2093,2094],{},"{key}"," placeholders are replaced by the Typed block's ",[421,2097,2098],{},"meta[key]",", unknown ones stay) are read only by the AI fill of a Typed block. Without it the AI fill is not offered for the type",[1825,2101,2102,2106,2108],{},[1842,2103,2104,1975],{},[421,2105,1329],{},[1842,2107,2017],{},[1842,2109,2110,2111,2113,2114,2116],{},"the ",[421,2112,1096],{}," chips and the backlinks; implied by a ",[421,2115,1096],{}," property",[1825,2118,2119,2126,2131],{},[1842,2120,2121,2059,2123,2037],{},[421,2122,483],{},[421,2124,2125],{},"composite-media",[1842,2127,2128],{},[421,2129,2130],{},"{ media?: SourceMedia[] }",[1842,2132,2133,2134,2137,2138,2140,2141,2143,2144,2146,2147],{},"imported files land in a Typed block of the type: with ",[421,2135,2136],{},"media",", those of that media type (the built-in ",[421,2139,1160],{}," takes audio and video, ",[421,2142,1171],{}," images); without, every file no other type takes (the built-in ",[421,2145,1062],{},"). Needs ",[421,2148,1933],{},[1825,2150,2151,2155,2157],{},[1842,2152,2153,1975],{},[421,2154,1058],{},[1842,2156,2017],{},[1842,2158,2159,2160,2163],{},"the block action „Exportieren“ (",[421,2161,2162],{},"document-export","): the Typed block's contents as a Markdown file",[418,2165,2166,1019,2169,2172,2173,2175,2176,2179,2180,2182,2183,2186,2187,2190,2191,2194,2195,2198,2199,2201],{},[1016,2167,2168],{},"Order of nested Typed blocks.",[421,2170,2171],{},"nestedAfterContent: true"," in a Block type's ",[421,2174,1933],{}," config (default ",[421,2177,2178],{},"false",") says that the nested Typed blocks of a Typed block of this type follow its own content, and a merge keeps that order. ",[421,2181,1468],{}," merging A = ",[421,2184,2185],{},"[Ca, Na]"," and B = ",[421,2188,2189],{},"[Cb, Nb]"," (C the leading blocks of the body that are not Typed blocks, N the rest from the first nested Typed block on) gives ",[421,2192,2193],{},"[Ca, Cb, Na, Nb]"," instead of ",[421,2196,2197],{},"[Ca, Na, Cb, Nb]","; when A has no nested Typed blocks the content of B goes in at the end of A's content, ahead of Nb. A body that is one empty paragraph still adds nothing, the ",[421,2200,1945],{}," check and the single undo step are unchanged. Block types without the flag merge as before.",[418,2203,2204,2205,1370,2208,998,2211,1308,2213,2216,2217,2220,2221,911,2224,911,2227,911,2230,2233,2234,2236,2237,915,2240,998,2243,2245,2246,998,2249,1003],{},"Read them with ",[421,2206,2207],{},"capabilitiesOf(editor, node)",[421,2209,2210],{},"capabilitiesAt(editor, pos)",[421,2212,535],{},[421,2214,2215],{},"capabilityConfigOf(editor, node, id)"," for the config and ",[421,2218,2219],{},"capabilityDataOf(editor, node, id)"," for the contents (the source child, the basket id, the record). The pure accessors ",[421,2222,2223],{},"propertiesOf(type)",[421,2225,2226],{},"sourceMediaOf(type)",[421,2228,2229],{},"aiBriefOf(type)",[421,2231,2232],{},"acceptsOf(type)"," read a ",[421,2235,1490],{}," directly; ",[421,2238,2239],{},"blockTypeConfigOf(type, id)",[421,2241,2242],{},"listsCapability(type, id)",[421,2244,535],{},") do the same for the config of any capability. A host that adds a Block type to the preset's list from another feature uses ",[421,2247,2248],{},"EditorFeature.blockTypes",[1000,2250,357],{"href":358},[1819,2252,2253,2264],{},[1822,2254,2255],{},[1825,2256,2257,2262],{},[1828,2258,2259,1832],{},[421,2260,2261],{},"PropertyDefinition",[1828,2263,1835],{},[1837,2265,2266,2281,2291,2312],{},[1825,2267,2268,2275],{},[1842,2269,2270,911,2273],{},[421,2271,2272],{},"key",[421,2274,1498],{},[1842,2276,2277,2278,2280],{},"the key under which the Block property is stored in ",[421,2279,1030],{},", and its label",[1825,2282,2283,2288],{},[1842,2284,2285],{},[421,2286,2287],{},"type",[1842,2289,2290],{},"one of the types above",[1825,2292,2293,2298],{},[1842,2294,2295],{},[421,2296,2297],{},"options",[1842,2299,2300,2303,2304,1348,2306,2309,2310,2037],{},[421,2301,2302],{},"{ value, label }"," choices of a ",[421,2305,1749],{},[421,2307,2308],{},"multiselect"," property (required for ",[421,2311,2308],{},[1825,2313,2314,2319],{},[1842,2315,2316],{},[421,2317,2318],{},"targets",[1842,2320,2321,2323],{},[421,2322,1096],{}," only: the Block type ids the Block reference may point to; absent = any Typed block",[418,2325,2326,2331,2332,2334,2335,2337,2338,2340,2341,2343,2344,2347,2348,2351,2352,2354,2355,2358,2359,2361],{},[1016,2327,2328,2330],{},[421,2329,2308],{}," properties."," A property of type ",[421,2333,2308],{}," holds several of its ",[421,2336,2297],{}," (required, ",[421,2339,2302],{}," as for ",[421,2342,1749],{},") and stores them as a ",[421,2345,2346],{},"string[]"," under its key: ",[421,2349,2350],{},"meta.topics = ['a', 'b']",". The details popover and the Block inspector show a multi-choice menu (a checkbox list in the React binding); an empty choice removes the key from ",[421,2353,1030],{},", non-string entries are dropped (",[421,2356,2357],{},"metaWithProperty","). Table cells, sort keys and the AI brief read the option labels joined by ",[421,2360,911],{},"; the chat model is told to write a JSON list.",[418,2363,2364,1019,2367,2370,2371,2374,2375,2378,2379,2382,2383,2385,2386,2389,2390,2393,2394,2397,2398,2400,2401,2403,2404,1476],{},[1016,2365,2366],{},"Chrome per Block type.",[421,2368,2369],{},"BlockType.chrome?: { tags?: boolean, tone?: string, controls?: boolean }"," (default: everything shown) tunes the chrome of one Block type. ",[421,2372,2373],{},"chrome: { tags: false }"," hides the tag row of that type: no tag chips and no ",[421,2376,2377],{},"+"," chip on the title line, and no tags field in the Block inspector (",[421,2380,2381],{},"CompositeRow.tagsVisible"," is ",[421,2384,2178],{},"). The ",[421,2387,2388],{},"typedBlockTags"," node stays in the schema, empty, like for every Block type (the node itself is never shown: its row is data, see above). ",[421,2391,2392],{},"chrome: { controls: false }"," renders the chrome of that type as in a read-only editor although the editor is editable (",[421,2395,2396],{},"CompositeRow.controls","): no Basket menu, status menu, title-visibility (eye) button, tag removal or ",[421,2399,2377],{}," chip, and no drag handle on the Block type icon; the details popover opens read-only, and „Mit nächstem zusammenführen“ (",[421,2402,1468],{},") is refused when the Typed block or the one it would absorb has such a Block type, so the tree row button and the block action are gone. An existing Basket, status and tags still show as read-only chips. Use it for a Block type whose attributes a host guard refuses to change, so no button invites a click that is refused. Default ",[421,2405,2406],{},"true",[418,2408,2409,1019,2412,2415,2416,2419,2420,2423,2424,2427,2428,2431,2432,2435,2436,2438,2439,2442],{},[1016,2410,2411],{},"Block type tone.",[421,2413,2414],{},"chrome: { tone: 'var(--color-amber-600)' }"," (any CSS colour or ",[421,2417,2418],{},"var(...)",") sets a Block type apart: every Typed block of it gets ",[421,2421,2422],{},"data-block-type-tone"," and the inline variable ",[421,2425,2426],{},"--sk-block-type-tone"," on its wrapper, a tinted surface (",[421,2429,2430],{},"color-mix"," of the tone at ",[421,2433,2434],{},"--sk-block-type-tone-mix",", 8% light and 14% dark; override the token to change the strength) and a left border in the tone, and its rows in the ",[1000,2437,117],{"href":118}," tint the Block type icon (",[421,2440,2441],{},"TreeItem.tone","). Block types without a tone look as before; a Basket stripe wins on the border. A host uses it to paint source text apart from its own content.",[418,2444,2445,2448,2449,2451,2452,2454,2455,1250,2458,2461,2462,2465,2466,2468,2469,2471,2472,911,2474,911,2477,911,2479,911,2481,911,2483,911,2485,915,2487,2489,2490,2492,2493,911,2495,915,2498,2501,2502,1348,2504,2506,2507,2492,2509,2512,2513,2516,2517,2520,2521,2523,2524,2527,2528,2531,2532,2534],{},[1016,2446,2447],{},"Accepted children."," The ",[421,2450,1945],{}," of a Block type's ",[421,2453,1933],{}," config (",[421,2456,2457],{},"{ id: 'container', config: { accepts } }",[421,2459,2460],{},"readonly string[] | 'all'",") names the Block types a Block type accepts as nested Typed blocks: a list of Block type ids, or ",[421,2463,2464],{},"'all'",". Without ",[421,2467,1933],{}," or without ",[421,2470,1945],{},", a Block type accepts no Typed block; the built-in ",[421,2473,1130],{},[421,2475,2476],{},"folder",[421,2478,1062],{},[421,2480,1160],{},[421,2482,1164],{},[421,2484,1167],{},[421,2486,1171],{},[421,2488,1199],{}," list ",[421,2491,1933],{}," with ",[421,2494,2464],{},[421,2496,2497],{},"task",[421,2499,2500],{},"note"," accept no Typed block. A host list that defines its own ",[421,2503,2476],{},[421,2505,1062],{}," type must give it ",[421,2508,1933],{},[421,2510,2511],{},"accepts: 'all'",". Paragraphs, lists and other content that is no Typed block are always allowed, and top-level Typed blocks have no parent. ",[421,2514,2515],{},"acceptsChild(blockTypes, parentType, childType)"," answers the question for a list of Block types (a parent type the list does not know accepts nothing). The rule is enforced in the editor by the ",[421,2518,2519],{},"AcceptedChildren"," extension, which ",[421,2522,423],{}," registers: every local edit that leaves the document with more Typed blocks nested in a Typed block that does not accept their Block type than before is refused — block drag, „In Block umwandeln“, the Block type switch of the details popover, paste, AI inserts and review acceptance, ",[421,2525,2526],{},"moveBlockInto"," — and the user gets the notice „Verschachtelung nicht möglich“ with „\u003CBlock type> nimmt keine \u003CBlock type> auf.“ (Block type labels, e.g. „Notiz nimmt keine Aufgabe auf.“). Only ",[1033,2529,2530],{},"new"," violations are refused: a document that already nests against the rule stays as it is and can still be edited, and collaboration replays, undo\u002Fredo and loading a whole document are never blocked. The ",[1000,2533,117],{"href":118}," applies the same rule to drops.",[1005,2536,2538],{"id":2537},"block-types-from-a-json-file","Block types from a JSON file",[418,2540,2541,2542,915,2545,2548,2549,2552,2553,2555,2556,1476],{},"A Block type is plain data, so a host can keep its Block types in a JSON file and load them with ",[421,2543,2544],{},"parseBlockTypes",[421,2546,2547],{},"mergeBlockTypes",". The file is checked against the capability registry, the server takes the same list, and the example ",[421,2550,2551],{},"examples\u002Fvue-two-pane"," defines the Block type „Idee“ only in such a file. See ",[1000,2554,165],{"href":166}," and the ",[1000,2557,383],{"href":384},[1005,2559,2561],{"id":2560},"reserved-meta-keys","Reserved meta keys",[418,2563,2564,2565,2567,2568,2570,2571,2574,2575,2578],{},"A Block type's ",[421,2566,1322],{}," capability decides which ",[421,2569,1030],{}," entries (Block properties) the details popover and the table show, and ",[421,2572,2573],{},"changeBlockType",", conversions and the Markdown fence keep ",[1016,2576,2577],{},"only"," the keys the target Block type declares, plus these four, which every Block type keeps and no Block type declares:",[1819,2580,2581,2597],{},[1822,2582,2583],{},[1825,2584,2585,2589,2592,2594],{},[1828,2586,2587,1715],{},[421,2588,1030],{},[1828,2590,2591],{},"Constant",[1828,2593,1835],{},[1828,2595,2596],{},"Written by",[1837,2598,2599,2622,2644,2664],{},[1825,2600,2601,2605,2610,2615],{},[1842,2602,2603],{},[421,2604,1318],{},[1842,2606,2607],{},[421,2608,2609],{},"DERIVATION_KEY",[1842,2611,2612,2613,2037],{},"provenance (",[421,2614,1206],{},[1842,2616,2617,2618],{},"“Create readable rendition” (English label), „Ableiten (KI)“, ",[1000,2619,2621],{"href":2620},"\u002Fguides\u002Fcontent-tree#block-transfer","block transfer",[1825,2623,2624,2629,2634,2639],{},[1842,2625,2626],{},[421,2627,2628],{},"bib",[1842,2630,2631],{},[421,2632,2633],{},"BIB_KEY",[1842,2635,2636,2637,2037],{},"Bibliographic record (",[421,2638,1288],{},[1842,2640,2110,2641,2643],{},[421,2642,1281],{}," property, „Literaturangaben abrufen“",[1825,2645,2646,2650,2655,2658],{},[1842,2647,2648],{},[421,2649,1658],{},[1842,2651,2652],{},[421,2653,2654],{},"BASKET_KEY",[1842,2656,2657],{},"id of the Typed block's Basket",[1842,2659,2660,2663],{},[421,2661,2662],{},"setCompositeBasket(basket | null, pos?)",", the Basket button in the chrome",[1825,2665,2666,2670,2675,2680],{},[1842,2667,2668],{},[421,2669,1676],{},[1842,2671,2672],{},[421,2673,2674],{},"TITLE_HIDDEN_KEY",[1842,2676,2677,2679],{},[421,2678,2406],{}," while the title is hidden",[1842,2681,2682,2685,2686,2688],{},[421,2683,2684],{},"setCompositeTitleHidden(hidden, pos?)",", the eye button in the chrome (Block types with the ",[421,2687,1676],{}," capability), every split",[418,2690,2691,2692,1003],{},"Do not declare a Property definition with one of these keys. In Markdown they travel in the fence's meta JSON (",[421,2693,2694],{},"::: section {\"basket\":\"red\",\"titleHidden\":true}",[418,2696,2697,1019,2700,2702,2703,2706,2707,2382,2710,911,2713,2716,2717,998,2720,911,2723,911,2726,911,2729,911,2732,1250,2735,2738,2739,2742,2743,2746,2747,2750,2751,1402,2753,2756,2757,2760,2761,2763,2764,2766,2767,2770],{},[1016,2698,2699],{},"Baskets.",[421,2701,1443],{}," (or ",[421,2704,2705],{},"composeEditor({ compositeBaskets })",") sets the Baskets a Typed block can be put in: ",[421,2708,2709],{},"Basket",[421,2711,2712],{},"{ id, label, color }",[421,2714,2715],{},"color"," any CSS colour; the default is ",[421,2718,2719],{},"defaultBaskets(t)",[421,2721,2722],{},"red",[421,2724,2725],{},"orange",[421,2727,2728],{},"yellow",[421,2730,2731],{},"green",[421,2733,2734],{},"blue",[421,2736,2737],{},"BASKET_IDS",") coloured by the CSS variables ",[421,2740,2741],{},"--sk-basket-\u003Cid>",", which a host overrides. ",[421,2744,2745],{},"compositeBasketsOf(editor)"," returns the editor's list, ",[421,2748,2749],{},"basketOf(node)"," the Basket of a ",[421,2752,1022],{},[421,2754,2755],{},"null"," without), ",[421,2758,2759],{},"setCompositeBasket"," refuses an unknown id (",[421,2762,2178],{},") and removes the key with ",[421,2765,2755],{},". The chrome row has a Basket button (a coloured dot, “No basket” to clear), a Typed block in a Basket gets a coloured left stripe, and the ",[1000,2768,117],{"href":2769},"\u002Fguides\u002Fdocument-tree#baskets-focus-and-foreign-drops"," shows the dot on its row and filters by Basket.",[418,2772,2773,1019,2776,2778,2779,2782,2783,2786,2787,2790,2791,2793,2794,1476],{},[1016,2774,2775],{},"Hidden titles.",[421,2777,1446],{}," hides the title behind a thin strip that keeps the chrome row. When the caret enters a hidden title it shows for the rest of the editor session (",[421,2780,2781],{},"CompositeStorage.revealedTitles","); ",[421,2784,2785],{},"titleHiddenOf(node)"," reads the flag and ",[421,2788,2789],{},"setCompositeTitleHidden(false, pos)"," also ends the reveal. The eye button that hides and shows the title belongs to the ",[421,2792,1676],{}," capability: a Block type that does not list it has no button (every built-in type lists it). Splitting a Typed block makes hidden titles for the generated parts; see ",[1000,2795,155],{"href":2796},"\u002Fguides\u002Fcontent-tree#hidden-titles",[1005,2798,170],{"id":2799},"derive-methods-and-the-derivation-index",[418,2801,2802,2803,2806,2807,1250,2809,2812,2813,2555,2815,1476],{},"Transcription, summary, AI fill, AI derivation and bibliography fetch are derive methods: a Feature contributes them as ",[421,2804,2805],{},"deriveMethods",", and the preset merges them into one registry. A Derived block records its Derivation in ",[421,2808,1203],{},[421,2810,2811],{},"derivationIndexOf(doc)"," finds the Derived blocks of an original, and a Derived block whose original was deleted shows „Quelle fehlt“ \u002F \"Source missing\". See ",[1000,2814,170],{"href":171},[1000,2816,336],{"href":337},[1005,2818,2820],{"id":2819},"chips-and-details-popover","Chips and details popover",[418,2822,2823,2824,2827],{},"The feature mounts one overlay (",[421,2825,2826],{},"CompositeChrome",") beside the editor, so every Typed block looks the same in every host:",[1010,2829,2830,2857,2874,2884,2904,2916,2927],{},[1013,2831,2832,2835,2836,2838,2839,2841,2842,2845,2846,2849,2850,2852,2853,2856],{},[1016,2833,2834],{},"Chips on the title line."," The Block type's ",[421,2837,1722],{}," property (a ",[421,2840,1749],{},") shows as a status chip; its dropdown changes the value. Every tag is a ",[421,2843,2844],{},"#tag"," chip with a ",[421,2847,2848],{},"×"," that appears on hover or focus, and a ",[421,2851,2377],{}," chip opens a tags editor (the same suggestions as the ",[421,2854,2855],{},"#"," list). Block types without a status property show only the tags.",[1013,2858,2859,2862,2863,2866,2867,2870,2871,2873],{},[1016,2860,2861],{},"Details popover."," The Block type icon on the Typed block's left border opens a popover (about 18rem wide, scaling and fading in from the icon within ~160 ms; no animation with ",[421,2864,2865],{},"prefers-reduced-motion","). At the top is the Block type as a dropdown of all Block types (icon and label, no label above it), below it every property of the Block type except the status (the chip edits it) and the summary. ",[421,2868,2869],{},"Escape"," or a click outside closes it, unless a dropdown inside is open (that one takes its own ",[421,2872,2869],{}," first).",[1013,2875,2876,2879,2880,2883],{},[1016,2877,2878],{},"The icon is the drag handle."," In an editable editor, dragging the Block type icon moves the Typed block (the cursor is a grab hand): the Typed block becomes the selection and is dragged like with the standard drag handle, so dropping it elsewhere in the editor moves it with its content (",[421,2881,2882],{},"Alt"," copies). A click without movement opens the popover. Typed blocks show no standard drag handle; blocks without a Block type icon keep theirs.",[1013,2885,2886,2889,2890,2382,2893,2896,2897,2900,2901,2903],{},[1016,2887,2888],{},"Icon visibility."," The settings value ",[421,2891,2892],{},"blocks.blockTypeIcon",[421,2894,2895],{},"'always'"," (default) or ",[421,2898,2899],{},"'hover'",". With ",[421,2902,2899],{}," the icon is invisible (120 ms fade) until the Typed block or its chips are hovered, its popover is open or the icon has keyboard focus; a nested Typed block's hover also reveals the icons of the Typed blocks around it. The invisible icon stays focusable and clickable, and dragging it works as soon as the pointer reaches it.",[1013,2905,2906,2909,2910,2912,2913,2915],{},[1016,2907,2908],{},"Changing the Block type"," asks first. Choosing another Block type shows an inline warning in the popover instead of applying it: „Blocktyp wirklich ändern? Beim Wechsel zu „\u003CBlock type>“ gehen diese Angaben verloren:“ followed by the property values the new Block type does not declare (",[421,2911,2573],{}," keeps only the meta keys of the new Block type), or just „Blocktyp wirklich ändern?“ when nothing would be lost. „Ändern“ runs ",[421,2914,2573],{}," for the Typed block resolved at that moment, „Abbrechen“ keeps the Block type.",[1013,2917,2918,2921,2922,1053,2924,2926],{},[1016,2919,2920],{},"Read-only editors."," Chips and popover render without edit affordances: no status menu, no ",[421,2923,2848],{},[421,2925,2377],{},", the Block type as plain text instead of the dropdown, disabled properties, the summary as plain text. The icon still opens the popover but cannot be dragged.",[1013,2928,2929,2932,2933,2935,2936,2939,2940,2943],{},[1016,2930,2931],{},"Layout."," The chips on the title line run on to the editor's right edge; nothing reserves a margin column. The ",[421,2934,1022],{}," node view's own description and tags rows stay in the document as data, but ",[421,2937,2938],{},"composites.css"," hides them: chips and popover are their only editors. The description is the ",[1033,2941,2942],{},"summary"," in the popover.",[418,2945,2946,2947,2950],{},"The hover bar of ",[421,2948,2949],{},"BlockAction","s is right-aligned 8px inside the editor's right edge for every block and is hidden while the editor is read-only.",[418,2952,2953,2954,2957,2958,1003],{},"On the toolbar surface the Typed block actions (export, BibTeX, focus, the four splits and „Mit nächstem zusammenführen“) declare ",[421,2955,2956],{},"target: 'typedBlock'",", so they stay on the toolbar while the caret is in a paragraph inside the Typed block; they address the nearest enclosing Typed block (see ",[1000,2959,2960],{"href":313},"Block UI",[1005,2962,2964],{"id":2963},"headings-typed-blocks","Headings ↔ Typed blocks",[418,2966,2967,915,2970,2973,2974,2977,2978,2981],{},[421,2968,2969],{},"convertHeadingsToComposites({ recursive, scope, kind })",[421,2971,2972],{},"convertCompositesToHeadings({ recursive, scope })"," are editor commands; ",[421,2975,2976],{},"convertBlockTo(target)"," converts one block. Every conversion runs in a single transaction, so ",[1016,2979,2980],{},"one undo step"," reverses it and redo restores it:",[434,2983,2985],{"className":1538,"code":2984,"language":471,"meta":439,"style":439},"editor.commands.convertHeadingsToComposites({ recursive: true, scope: 'document', kind: 'section' })\neditor.commands.undo() \u002F\u002F back to the headings, in one step\neditor.commands.convertBlockTo({ type: 'typedBlock', blockType: 'task' }, pos)\neditor.commands.convertCompositesToHeadings({ recursive: false, scope: 'heading' })\n",[421,2986,2987,3044,3064,3110],{"__ignoreMap":439},[443,2988,2989,2991,2993,2996,2998,3001,3003,3005,3008,3010,3014,3016,3019,3021,3023,3025,3027,3029,3032,3034,3036,3038,3040,3042],{"class":445,"line":446},[443,2990,758],{"class":489},[443,2992,1476],{"class":449},[443,2994,2995],{"class":489},"commands",[443,2997,1476],{"class":449},[443,2999,3000],{"class":633},"convertHeadingsToComposites",[443,3002,636],{"class":489},[443,3004,639],{"class":449},[443,3006,3007],{"class":453}," recursive",[443,3009,645],{"class":449},[443,3011,3013],{"class":3012},"sfNiH"," true",[443,3015,518],{"class":449},[443,3017,3018],{"class":453}," scope",[443,3020,645],{"class":449},[443,3022,499],{"class":449},[443,3024,1062],{"class":470},[443,3026,1600],{"class":449},[443,3028,518],{"class":449},[443,3030,3031],{"class":453}," kind",[443,3033,645],{"class":449},[443,3035,499],{"class":449},[443,3037,1130],{"class":470},[443,3039,1600],{"class":449},[443,3041,493],{"class":449},[443,3043,673],{"class":489},[443,3045,3046,3048,3050,3052,3054,3057,3060],{"class":445,"line":479},[443,3047,758],{"class":489},[443,3049,1476],{"class":449},[443,3051,2995],{"class":489},[443,3053,1476],{"class":449},[443,3055,3056],{"class":633},"undo",[443,3058,3059],{"class":489},"() ",[443,3061,3063],{"class":3062},"sHwdD","\u002F\u002F back to the headings, in one step\n",[443,3065,3066,3068,3070,3072,3074,3077,3079,3081,3083,3085,3087,3089,3091,3093,3096,3098,3100,3102,3104,3107],{"class":445,"line":508},[443,3067,758],{"class":489},[443,3069,1476],{"class":449},[443,3071,2995],{"class":489},[443,3073,1476],{"class":449},[443,3075,3076],{"class":633},"convertBlockTo",[443,3078,636],{"class":489},[443,3080,639],{"class":449},[443,3082,576],{"class":453},[443,3084,645],{"class":449},[443,3086,499],{"class":449},[443,3088,1022],{"class":470},[443,3090,1600],{"class":449},[443,3092,518],{"class":449},[443,3094,3095],{"class":453}," blockType",[443,3097,645],{"class":449},[443,3099,499],{"class":449},[443,3101,2497],{"class":470},[443,3103,1600],{"class":449},[443,3105,3106],{"class":449}," },",[443,3108,3109],{"class":489}," pos)\n",[443,3111,3112,3114,3116,3118,3120,3123,3125,3127,3129,3131,3134,3136,3138,3140,3142,3145,3147,3149],{"class":445,"line":540},[443,3113,758],{"class":489},[443,3115,1476],{"class":449},[443,3117,2995],{"class":489},[443,3119,1476],{"class":449},[443,3121,3122],{"class":633},"convertCompositesToHeadings",[443,3124,636],{"class":489},[443,3126,639],{"class":449},[443,3128,3007],{"class":453},[443,3130,645],{"class":449},[443,3132,3133],{"class":3012}," false",[443,3135,518],{"class":449},[443,3137,3018],{"class":453},[443,3139,645],{"class":449},[443,3141,499],{"class":449},[443,3143,3144],{"class":470},"heading",[443,3146,1600],{"class":449},[443,3148,493],{"class":449},[443,3150,673],{"class":489},[418,3152,3153],{},"Flattening keeps description, tags and Block properties as text below the heading, so nothing is lost silently; a document title above the headings stays as is.",[1005,3155,1072],{"id":3156},"conversion-providers",[418,3158,3159,3160,3162,3163,3166,3167,1308,3170,3173,3174,1308,3176,911,3179,3182,3183,1476],{},"The „Umwandeln in …“ menus and ",[421,3161,3076],{}," run over the conversion providers of the preset's features. A provider is inert data: ",[421,3164,3165],{},"targets(editor, node)"," (what it offers for ",[421,3168,3169],{},"node",[421,3171,3172],{},"parseTarget(id)"," (the target an id names, or ",[421,3175,2755],{},[421,3177,3178],{},"label(target)",[421,3180,3181],{},"convert(state, $start, target)"," and optionally ",[421,3184,3185],{},"handlesSource(node)",[1010,3187,3188,3199,3211,3217],{},[1013,3189,3190,3191,3194,3195,3198],{},"The ",[1016,3192,3193],{},"owner"," of a target is the first provider, in feature order, whose ",[421,3196,3197],{},"parseTarget"," parses its id. It supplies the label and, unless another provider claims the source block, executes the conversion.",[1013,3200,3201,3202,3206,3207,3210],{},"A provider that returns true from ",[1016,3203,3204],{},[421,3205,3185],{}," claims every conversion of such source blocks. The composite feature uses it for Typed blocks: converting a Typed block into a paragraph, heading, list, quote or code block is executed by the composite provider (it unwraps the Typed block), while ",[421,3208,3209],{},"typedBlock:\u003Cblock type id>"," targets are owned by its second provider (wrap a block, a heading with its section or switch the Block type).",[1013,3212,3213,3216],{},[421,3214,3215],{},"coreContentFeature()","'s provider declines every target that is not a core target, so features can add targets without interfering with it.",[1013,3218,3219,3220,3223],{},"A target id advertised by two providers for the same block throws (",[421,3221,3222],{},"the conversion target \"paragraph\" is advertised by more than one provider",") instead of silently picking one.",[418,3225,3226,3227,1476],{},"A feature of your own adds targets the same way: ",[421,3228,3229],{},"defineEditor({ features: [coreContentFeature(), coreUiFeature(), { id: 'mine', conversions: [myProvider] }] })",[1005,3231,3233],{"id":3232},"vue-free-schema-entry","Vue-free schema entry",[418,3235,3236,3239],{},[421,3237,3238],{},"@skaile\u002Fforge-editor\u002Fcomposites\u002Fschema"," imports no Vue, node view or feature factory. A server that validates or seeds documents builds its schema from it:",[434,3241,3243],{"className":1538,"code":3242,"language":471,"meta":439,"style":439},"import { getSchema } from '@tiptap\u002Fcore'\nimport { coreSchemaExtensions } from '@skaile\u002Fforge-editor\u002Fcore\u002Fschema'\nimport { compositeSchemaExtensions } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fschema'\n\nconst schema = getSchema([...coreSchemaExtensions(), ...compositeSchemaExtensions({ blockTypes })])\n",[421,3244,3245,3265,3285,3304,3308],{"__ignoreMap":439},[443,3246,3247,3249,3251,3254,3256,3258,3260,3263],{"class":445,"line":446},[443,3248,483],{"class":482},[443,3250,486],{"class":449},[443,3252,3253],{"class":489}," getSchema",[443,3255,493],{"class":449},[443,3257,496],{"class":482},[443,3259,499],{"class":449},[443,3261,3262],{"class":470},"@tiptap\u002Fcore",[443,3264,505],{"class":449},[443,3266,3267,3269,3271,3274,3276,3278,3280,3283],{"class":445,"line":479},[443,3268,483],{"class":482},[443,3270,486],{"class":449},[443,3272,3273],{"class":489}," coreSchemaExtensions",[443,3275,493],{"class":449},[443,3277,496],{"class":482},[443,3279,499],{"class":449},[443,3281,3282],{"class":470},"@skaile\u002Fforge-editor\u002Fcore\u002Fschema",[443,3284,505],{"class":449},[443,3286,3287,3289,3291,3294,3296,3298,3300,3302],{"class":445,"line":508},[443,3288,483],{"class":482},[443,3290,486],{"class":449},[443,3292,3293],{"class":489}," compositeSchemaExtensions",[443,3295,493],{"class":449},[443,3297,496],{"class":482},[443,3299,499],{"class":449},[443,3301,3238],{"class":470},[443,3303,505],{"class":449},[443,3305,3306],{"class":445,"line":540},[443,3307,619],{"emptyLinePlaceholder":618},[443,3309,3310,3312,3315,3317,3319,3322,3325,3328,3330,3332,3335,3338,3340,3342,3345,3347],{"class":445,"line":571},[443,3311,625],{"class":457},[443,3313,3314],{"class":489}," schema ",[443,3316,464],{"class":449},[443,3318,3253],{"class":633},[443,3320,3321],{"class":489},"([",[443,3323,3324],{"class":449},"...",[443,3326,3327],{"class":633},"coreSchemaExtensions",[443,3329,654],{"class":489},[443,3331,518],{"class":449},[443,3333,3334],{"class":449}," ...",[443,3336,3337],{"class":633},"compositeSchemaExtensions",[443,3339,636],{"class":489},[443,3341,639],{"class":449},[443,3343,3344],{"class":489}," blockTypes ",[443,3346,670],{"class":449},[443,3348,3349],{"class":489},")])\n",[418,3351,3352,3353,911,3355,911,3358,911,3361,911,3364,911,3367,911,3370,911,3373,911,3375,911,3378,911,3381,911,3384,911,3387,911,3390,911,3393,911,3396,911,3398,3400,3401,3404,3405,1308,3407,911,3410,911,3413,911,3416,911,3419,911,3422,911,3425,911,3428,915,3431,3434,3435,3437,3438,911,3441,1308,3444,1053,3447,3450,3451,911,3453,1308,3455,3458,3459,998,3461,911,3463,911,3465,911,3467,911,3470,911,3472,3474,3475,3477,3478,915,3480,3482,3483,3485,3486,3488,3489,911,3492,3494,3495,3497,3498,1003],{},"It also exports the pure helpers: ",[421,3354,1569],{},[421,3356,3357],{},"blockTypeOf",[421,3359,3360],{},"acceptsChild",[421,3362,3363],{},"acceptsImport",[421,3365,3366],{},"importTypeOf",[421,3368,3369],{},"propertiesOf",[421,3371,3372],{},"setBlockProperty",[421,3374,2357],{},[421,3376,3377],{},"blockPropertiesAt",[421,3379,3380],{},"carriesProperties",[421,3382,3383],{},"sourceMediaOf",[421,3385,3386],{},"aiBriefOf",[421,3388,3389],{},"aiBlockTypesOf",[421,3391,3392],{},"acceptsOf",[421,3394,3395],{},"isRootBlockType",[421,3397,2544],{},[421,3399,2547],{}," (with ",[421,3402,3403],{},"BlockTypeJsonError",", see ",[1033,3406,2538],{},[421,3408,3409],{},"compositeConversions",[421,3411,3412],{},"convertCompositeBlocks",[421,3414,3415],{},"blocksFromMarkdown",[421,3417,3418],{},"compositeFence",[421,3420,3421],{},"groupHeadingsIntoComposites",[421,3423,3424],{},"flattenCompositesToHeadings",[421,3426,3427],{},"headingGroupRange",[421,3429,3430],{},"compositeChromeBlocks",[421,3432,3433],{},"structureBlocks",". ",[421,3436,977],{}," (framework-free) re-exports them next to the node views (",[421,3439,3440],{},"Composite",[421,3442,3443],{},"CompositeTags",[421,3445,3446],{},"Structure",[421,3448,3449],{},"structureOf",", the framework-free rows and anchors models (",[421,3452,985],{},[421,3454,988],{},[421,3456,3457],{},"compositeFeatureCore(ui)"," and the helpers below. The bindings are ",[421,3460,502],{},[421,3462,423],{},[421,3464,954],{},[421,3466,957],{},[421,3468,3469],{},"SettingsEditingTab",[421,3471,970],{},[421,3473,973],{},", ...) and ",[421,3476,950],{}," (the same names as React components and hooks; ",[421,3479,954],{},[421,3481,957],{}," take ",[421,3484,758],{}," and are placed beside the editor, ",[421,3487,954],{}," has ",[421,3490,3491],{},"onSelect",[421,3493,957],{}," a ",[421,3496,1062],{}," node and ",[421,3499,3500],{},"documentFocused",[418,3502,3503,3504,3506,3507,911,3509,911,3512,3514,3515,911,3518,911,3520,911,3522,911,3524,911,3527,915,3530,3533,3534,3536,3537,3540,3541,911,3544,911,3547,911,3549,911,3551,911,3553,911,3555,911,3557,1250,3559,911,3561,911,3564,911,3567,3570,3571,3574,3575,3577,3578,911,3581,911,3584,911,3586,911,3589,911,3591,2555,3594,3597,3598,998,3601,3603,3604,1053,3606,1476],{},"Helpers for Source media, Derived blocks, bibliography and references (also in ",[421,3505,3238],{}," unless noted): ",[421,3508,1183],{},[421,3510,3511],{},"sourceOf",[421,3513,1260],{},"; the Derivation helpers ",[421,3516,3517],{},"derivedChildrenOf",[421,3519,2609],{},[421,3521,1237],{},[421,3523,1240],{},[421,3525,3526],{},"derivationIndexOf",[421,3528,3529],{},"derivedOf",[421,3531,3532],{},"derivationOriginOf"," (exported from ",[421,3535,535],{}," only; ",[421,3538,3539],{},"derivationState(doc, derivedPos, bodyHash, documentId?)"," takes the document and the position of the Derived block); ",[421,3542,3543],{},"CSL_TYPES",[421,3545,3546],{},"cslTypeOptions",[421,3548,1292],{},[421,3550,1295],{},[421,3552,1298],{},[421,3554,1301],{},[421,3556,1304],{},[421,3558,1307],{},[421,3560,1343],{},[421,3562,3563],{},"referencesFromText",[421,3565,3566],{},"normalizeReferences",[421,3568,3569],{},"compositeIdsOf"," (schema entry only), ",[421,3572,3573],{},"referenceMarkdown",". Only ",[421,3576,977],{}," adds ",[421,3579,3580],{},"referenceSuggestion",[421,3582,3583],{},"referenceLabel",[421,3585,1377],{},[421,3587,3588],{},"revealSource",[421,3590,1392],{},[421,3592,3593],{},"parseLocator",[421,3595,3596],{},"SourceReveal"," extension. ",[421,3599,3600],{},"sha256Hex",[421,3602,535],{},") is the hash behind ",[421,3605,1223],{},[421,3607,1226],{},[1005,3609,3611],{"id":3610},"block-outline-and-markdown-export-helpers","Block outline and Markdown export helpers",[1010,3613,3614,3708],{},[1013,3615,3616,3619,3620,3623,3624,3627,3628,3630,3631,2492,3634,915,3637,3640,3641,3644,3645,3648,3649,3652,3653,3656,3657,2382,3659,3661,3662,3665,3666,3668,3669,998,3672,3674,3675,911,3678,1348,3681,3684,3685,3688,3689,3691,3692,2382,3695,3434,3698,3701,3702,3704,3705,3707],{},[421,3617,3618],{},"documentOutline(doc, untitled, capabilitiesOf?, documentId?)"," is the model of the Block outline: the headings and Typed blocks of the document as one tree in document order (",[421,3621,3622],{},"DocumentOutlineEntry",": a ",[421,3625,3626],{},"DocumentOutlineBlock"," with a ",[421,3629,1088],{},", or a ",[421,3632,3633],{},"DocumentOutlineHeading",[421,3635,3636],{},"level",[421,3638,3639],{},"text","); a heading nests under the nearest shallower heading before it, a Typed block under the heading it follows, and the headings in a Typed block's body start their own levels below it. ",[421,3642,3643],{},"compositeOutline(doc, hiddenKinds, untitled)"," reads only the Typed blocks as a tree (",[421,3646,3647],{},"OutlineNode",": key, id, position, kind, title, ",[421,3650,3651],{},"labelFromBody",", summary flag, children); a Typed block without a title gets the text of the first heading of its own body, else the start of the first text of its own body (60 characters, then „…“), else the ",[421,3654,3655],{},"untitled"," argument, and ",[421,3658,3651],{},[421,3660,2406],{}," for the first two; Typed blocks of a hidden Block type drop out and their descendants move up. ",[421,3663,3664],{},"moveIntoVerdict(editor, id, targetId, t)"," says whether block ",[421,3667,1494],{}," may move into the Typed block ",[421,3670,3671],{},"targetId",[421,3673,2755],{}," = the end of the document): a ",[421,3676,3677],{},"MoveVerdict",[421,3679,3680],{},"{ ok: true }",[421,3682,3683],{},"{ ok: false, reason }"," with a short sentence in the language of ",[421,3686,3687],{},"t"," (the editor's translator) (the block or the target no longer exists, the target is no Typed block, a block into itself or into a Typed block it contains, or the target's Block type does not accept the block's Block type, see ",[1033,3690,1949],{},"). A block that is no Typed block may move into any Typed block unless it holds Typed blocks of a refused Block type; moving a block to the end of the Typed block it already sits in is never refused. ",[421,3693,3694],{},"canMoveBlockInto(editor, id, targetId)",[421,3696,3697],{},"moveIntoVerdict(...).ok",[421,3699,3700],{},"moveBlockInto(editor, id, targetId)"," moves the block to the end of a Typed block's body (or the document with ",[421,3703,2755],{},") in one transaction and returns whether the document changed (",[421,3706,2178],{},": refused by the verdict or by the editor).",[1013,3709,3710,3713,3714,3716,3717,3720,3721,3724,3725,3728],{},[421,3711,3712],{},"headingsMarkdown(editor, blocks, level)"," exports blocks as Markdown with every Typed block turned into a heading (the outermost at ",[421,3715,3636],{},") followed by its description, tags and body; ",[421,3718,3719],{},"documentCompositeMarkdown(editor, node)"," does the same for one Typed block as a document, ",[421,3722,3723],{},"markdownFileName(node)"," names the file and ",[421,3726,3727],{},"downloadText(filename, text)"," offers it as a download.",[418,3730,3731,3732,998,3735,911,3738,3741,3742,947,3745,1348,3748,1476],{},"The heading-only outline of a plain editor stays ",[421,3733,3734],{},"@skaile\u002Fforge-editor\u002Foutline",[421,3736,3737],{},"headingOutline",[421,3739,3740],{},"revealBlockInEditor","); its component is ",[421,3743,3744],{},"EditorOutline",[421,3746,3747],{},"\u002Foutline\u002Fvue",[421,3749,3750],{},"\u002Foutline\u002Freact",[1005,3752,3754],{"id":3753},"block-table-and-block-inspector","Block table and Block inspector",[418,3756,3757,3758,3760],{},"Two components show the Block properties of the Typed blocks beside an editor. Both take the editor from the surface's ",[421,3759,820],{}," event as a prop, follow it when it changes, and render their empty state without one.",[1010,3762,3763,3791],{},[1013,3764,3765,3767,3768,3771,3772,3775,3776,3778,3779,3781,3782,3784,3785,947,3788,1476],{},[421,3766,954],{}," (prop ",[421,3769,3770],{},"editor?: Editor","; event ",[421,3773,3774],{},"select(row)",") lists every Typed block as a sortable, filterable table: Typed block (indented by nesting), Block type, one column per property of the Block types in the document (select values show their option label, dates are formatted; ",[421,3777,2084],{}," properties get no column), Tags and whether a summary exists. Above it: text search over title, summary and tags, Block type and tag chips, one select per ",[421,3780,1749],{}," property (for example Status), a reset and a row count. A header click sorts ascending, descending, then not at all. The table does not change the document; ",[421,3783,1749],{}," hands the host the clicked row, so the host can switch back to the text and call ",[421,3786,3787],{},"revealBlockInEditor(editor, row)",[421,3789,3790],{},"\u002Foutline",[1013,3792,3793,3795,3796,911,3798,3801,3802,3804,3805,3807,3808,3810,3811,3813,3814,3816,3817,3819,3820,3823,3824,3827,3828,911,3831,915,3834,3837,3838,3840,3841,3843,3844,998,3847,1207,3850,911,3852,911,3855,911,3857,1257,3860,3863],{},[421,3794,957],{}," (props ",[421,3797,3770],{},[421,3799,3800],{},"documentFocused?: boolean","; slot ",[421,3803,1062],{},") is the Block inspector: a side panel that shows one section at a time, chosen by where the caret is. The Document facts section („Dokument“) shows before the editor was ever focused, while the caret is in editor text outside any Typed block, and while the host's document input is focused; the Typed block section („Block“) shows while the caret is in a Typed block (also after opening a row from ",[421,3806,954],{},"). Clicking into the panel never switches sections, and there is no empty state. Pass ",[421,3809,3500],{}," as ",[421,3812,2406],{}," while your document-level input (e.g. the title field) has the focus: the panel then switches to „Dokument“ and stays there after the input blurs, until the caret returns to the editor. A summary draft typed in the panel is committed when it switches away from „Block“. The „Dokument“ section starts with the host's ",[421,3815,1062],{}," slot (the library knows nothing about titles, folders or dates of your storage), followed by what the document itself says: Typed blocks per Block type and how many have a summary, all tags, all mentions. The „Block“ section edits the Typed block under the caret: Block type, summary (as text; formatting on the unchanged text stays, a summary with mentions or tags is read-only there and edited in the document), tags with suggestions and creation, one input per Block property, and the summary state. Every edit is one editor transaction, so it reaches collaborators and undo like any other edit. A summary typed in the panel is written only while the document still holds the text the draft started from; when a collaborator changed it meanwhile, their text wins and is loaded into the panel. A read-only editor (",[421,3818,777],{},"'s ",[421,3821,3822],{},"editable",") disables the controls. Give the panel its width and border through ",[421,3825,3826],{},"class",". Host rows in the slot match its layout with ",[421,3829,3830],{},"\u003Cdl class=\"grid grid-cols-[6.5rem_minmax(0,1fr)] items-start gap-x-3 gap-y-2\">",[421,3832,3833],{},"dt.min-h-6.leading-6.text-muted",[421,3835,3836],{},"dd.min-h-6.leading-6.text-highlighted",". The Block properties section (heading „Blockeigenschaften“ \u002F \"Block properties\") lists the Property definitions that the ",[421,3839,1322],{}," capability gives the block under the caret, for any block that carries ",[421,3842,1030],{}," values; the model exposes it as ",[421,3845,3846],{},"state.properties",[421,3848,3849],{},"BlockProperties",[421,3851,1494],{},[421,3853,3854],{},"pos",[421,3856,1030],{},[421,3858,3859],{},"definitions",[421,3861,3862],{},"setField"," writes to it. The Document facts section stays the Document's own facts.",[434,3865,3867],{"className":436,"code":3866,"language":438,"meta":439,"style":439},"\u003CCompositeTable v-if=\"view === 'table'\" :editor=\"editor\" @select=\"openRow\" \u002F>\n\u003CCompositeInspector :editor=\"editor\" class=\"w-80 border-l border-default\">\n  \u003Ctemplate #document>\n    \u003CMyDocumentFacts \u002F>\n  \u003C\u002Ftemplate>\n\u003C\u002FCompositeInspector>\n",[421,3868,3869,3922,3954,3959,3964,3969],{"__ignoreMap":439},[443,3870,3871,3873,3875,3878,3880,3882,3885,3888,3890,3892,3895,3897,3899,3901,3903,3905,3907,3909,3911,3913,3915,3918,3920],{"class":445,"line":446},[443,3872,450],{"class":449},[443,3874,954],{"class":453},[443,3876,3877],{"class":482}," v-if",[443,3879,464],{"class":449},[443,3881,467],{"class":449},[443,3883,3884],{"class":489},"view ",[443,3886,3887],{"class":449},"===",[443,3889,499],{"class":449},[443,3891,1819],{"class":470},[443,3893,3894],{"class":449},"'\"",[443,3896,755],{"class":449},[443,3898,758],{"class":457},[443,3900,464],{"class":449},[443,3902,467],{"class":449},[443,3904,758],{"class":489},[443,3906,467],{"class":449},[443,3908,817],{"class":449},[443,3910,1749],{"class":457},[443,3912,464],{"class":449},[443,3914,467],{"class":449},[443,3916,3917],{"class":489},"openRow",[443,3919,467],{"class":449},[443,3921,769],{"class":449},[443,3923,3924,3926,3928,3930,3932,3934,3936,3938,3940,3943,3945,3947,3950,3952],{"class":445,"line":479},[443,3925,450],{"class":449},[443,3927,957],{"class":453},[443,3929,755],{"class":449},[443,3931,758],{"class":457},[443,3933,464],{"class":449},[443,3935,467],{"class":449},[443,3937,758],{"class":489},[443,3939,467],{"class":449},[443,3941,3942],{"class":457}," class",[443,3944,464],{"class":449},[443,3946,467],{"class":449},[443,3948,3949],{"class":470},"w-80 border-l border-default",[443,3951,467],{"class":449},[443,3953,476],{"class":449},[443,3955,3956],{"class":445,"line":508},[443,3957,3958],{"class":489},"  \u003Ctemplate #document>\n",[443,3960,3961],{"class":445,"line":540},[443,3962,3963],{"class":489},"    \u003CMyDocumentFacts \u002F>\n",[443,3965,3966],{"class":445,"line":571},[443,3967,3968],{"class":489},"  \u003C\u002Ftemplate>\n",[443,3970,3971,3973,3975],{"class":445,"line":595},[443,3972,724],{"class":449},[443,3974,957],{"class":453},[443,3976,476],{"class":449},[418,3978,3979,3980,3983,3984,998,3987,3990,3991,3993,3994,3996,3997,1308,3999,4002,4003,911,4005,4008,4009,915,4012,4015,4016,911,4019,915,4022,4025,4026,4029,4030,4033,4034,4036,4037,4040,4041,4044],{},"Own views read the same model: ",[421,3981,3982],{},"useCompositeRows(editor)"," returns ",[421,3985,3986],{},"rows",[421,3988,3989],{},"CompositeRow",": key, id, position, ",[421,3992,1088],{}," with label and icon (the Block type), title, summary text and whether it is text only, tags, ",[421,3995,1030],{},", the Block type's Property definitions (",[421,3998,3859],{},[421,4000,4001],{},"tagsVisible",", depth), ",[421,4004,1889],{},[421,4006,4007],{},"kinds"," (the Block types with counts), ",[421,4010,4011],{},"mentions",[421,4013,4014],{},"focused"," (the Typed block under the caret), re-read once per frame after a document change. ",[421,4017,4018],{},"setBlockProperty(editor, row, key, value)",[421,4020,4021],{},"setCompositeTags(editor, row, tags)",[421,4023,4024],{},"setCompositeDescription(editor, row, text, expected?)"," write in one transaction and find the Typed block again by its block ID, so a row read before a remote change stays usable. ",[421,4027,4028],{},"setCompositeDescription"," stores ",[421,4031,4032],{},"compositeDescriptionText(text)"," (one line), replacing only the changed span so marks on the rest stay; it returns ",[421,4035,2178],{}," instead of dropping a mention or tag in the summary, or, with ",[421,4038,4039],{},"expected",", when the summary no longer holds that text. ",[421,4042,4043],{},"compositeRows(doc, kinds)"," is the same read without Vue.",[1005,4046,4048],{"id":4047},"settings-panel-and-modal","Settings panel and modal",[418,4050,4051,4052,998,4055,4058],{},"Features contribute settings ",[1033,4053,4054],{},"tabs",[421,4056,4057],{},"settingsTabs: ctx => [{ id, label: ctx.t('…'), icon?, component, props? }]",", a factory over the app context so labels follow its language); the UI that shows them is core and decoupled from any one feature:",[1010,4060,4061,4078,4115,4145],{},[1013,4062,4063,3795,4065,911,4067,1250,4070,4073,4074,4077],{},[421,4064,867],{},[421,4066,758],{},[421,4068,4069],{},"contentClass?",[421,4071,4072],{},"v-model:tab",") renders one tab per tab contributed by the preset registered for that editor, wherever you place it. With ",[1016,4075,4076],{},"no tab"," (or no editor) it renders nothing.",[1013,4079,4080,3795,4083,1250,4085,911,4088,4090,4091,4094,4095,4098,4099,4102,4103,4106,4107,4110,4111,4114],{},[421,4081,4082],{},"EditorSettingsModal",[421,4084,758],{},[421,4086,4087],{},"v-model:open",[421,4089,4072],{},") is the same panel in a popup: a Nuxt UI modal titled „Einstellungen“ (",[421,4092,4093],{},"settings.title","; \"Settings\" with ",[421,4096,4097],{},"locale: 'en'",") with a fixed width (",[421,4100,4101],{},"42rem"," from the ",[421,4104,4105],{},"sm"," breakpoint), a blurred, dimmed backdrop, the panel in a scroll area of fixed height (",[421,4108,4109],{},"h-[32rem]",") and a „Schließen“ footer; the description says whether the values apply to the account or to this browser (",[421,4112,4113],{},"synced","). With no tab it renders nothing.",[1013,4116,4117,4119,4120,1207,4125,4128,4129,4132,4133,4138,4139,4141,4142,4144],{},[421,4118,777],{}," takes ",[1016,4121,4122],{},[421,4123,4124],{},"settingsUi",[421,4126,4127],{},"'internal'"," (default) mounts the modal itself and opens it from the toolbar's settings entry; ",[421,4130,4131],{},"'external'"," mounts nothing and emits ",[1016,4134,4135],{},[421,4136,4137],{},"settingsOpen(tab?)"," instead, so the host opens its own settings page, drawer or panel, or places an ",[421,4140,4082],{}," itself (every page of the Nuxt app's kitchen sink does, see ",[1000,4143,131],{"href":132},"; the example above sets the shown tab from the event). Without any contributed tab the surface neither opens nor emits, and the toolbar's settings entry is hidden.",[1013,4146,4147,4148,4151],{},"The values are shared app settings (",[421,4149,4150],{},"useEditorSettings()","): several panels and editors edit the same preferences, stored per account when a server is configured and per browser otherwise. Another feature's tab (for example the AI tab) appears in the same panel as soon as its feature is part of the preset.",[1005,4153,4155],{"id":4154},"file-import-into-typed-blocks","File import into Typed blocks",[418,4157,4158,947,4161,4164,4165,4167,4168,4170,4171,1019,4174,915,4176,998,4178,4181,4182,915,4185,4188,4189,428,4191,911,4193,915,4195,4197],{},[421,4159,4160],{},"compositeMediaFeature()",[421,4162,4163],{},"@skaile\u002Fforge-editor\u002Fintegrations\u002Fcomposite-media"," connects two features that know nothing of each other: with it, every imported file lands wrapped in a Typed block of the Block type whose ",[421,4166,483],{}," capability takes it (by default a ",[421,4169,1062],{},"). It ",[421,4172,4173],{},"requires",[421,4175,431],{},[421,4177,2136],{},[421,4179,4180],{},"defineEditor"," throws when either is missing); neither of them imports it, so ",[421,4183,4184],{},"core + media",[421,4186,4187],{},"core + composites"," bundles stay free of it (",[421,4190,427],{},[421,4192,2136],{},[421,4194,431],{},[421,4196,2125],{}," fixtures).",[434,4199,4201],{"className":1538,"code":4200,"language":471,"meta":439,"style":439},"import { compositeFeature } from '@skaile\u002Fforge-editor\u002Fcomposites\u002Fvue'\nimport { compositeMediaFeature } from '@skaile\u002Fforge-editor\u002Fintegrations\u002Fcomposite-media'\nimport { coreContentFeature, coreUiFeature, defineEditor } from '@skaile\u002Fforge-editor\u002Fcore'\nimport { mediaFeature } from '@skaile\u002Fforge-editor\u002Fmedia\u002Fvue'\n\nconst preset = defineEditor({ features: [coreContentFeature(), coreUiFeature(), mediaFeature(), compositeFeature(), compositeMediaFeature()] })\n",[421,4202,4203,4221,4240,4266,4286,4290],{"__ignoreMap":439},[443,4204,4205,4207,4209,4211,4213,4215,4217,4219],{"class":445,"line":446},[443,4206,483],{"class":482},[443,4208,486],{"class":449},[443,4210,490],{"class":489},[443,4212,493],{"class":449},[443,4214,496],{"class":482},[443,4216,499],{"class":449},[443,4218,502],{"class":470},[443,4220,505],{"class":449},[443,4222,4223,4225,4227,4230,4232,4234,4236,4238],{"class":445,"line":479},[443,4224,483],{"class":482},[443,4226,486],{"class":449},[443,4228,4229],{"class":489}," compositeMediaFeature",[443,4231,493],{"class":449},[443,4233,496],{"class":482},[443,4235,499],{"class":449},[443,4237,4163],{"class":470},[443,4239,505],{"class":449},[443,4241,4242,4244,4246,4248,4250,4252,4254,4256,4258,4260,4262,4264],{"class":445,"line":508},[443,4243,483],{"class":482},[443,4245,486],{"class":449},[443,4247,515],{"class":489},[443,4249,518],{"class":449},[443,4251,521],{"class":489},[443,4253,518],{"class":449},[443,4255,526],{"class":489},[443,4257,493],{"class":449},[443,4259,496],{"class":482},[443,4261,499],{"class":449},[443,4263,535],{"class":470},[443,4265,505],{"class":449},[443,4267,4268,4270,4272,4275,4277,4279,4281,4284],{"class":445,"line":540},[443,4269,483],{"class":482},[443,4271,486],{"class":449},[443,4273,4274],{"class":489}," mediaFeature",[443,4276,493],{"class":449},[443,4278,496],{"class":482},[443,4280,499],{"class":449},[443,4282,4283],{"class":470},"@skaile\u002Fforge-editor\u002Fmedia\u002Fvue",[443,4285,505],{"class":449},[443,4287,4288],{"class":445,"line":571},[443,4289,619],{"emptyLinePlaceholder":618},[443,4291,4292,4294,4296,4298,4300,4302,4304,4306,4308,4310,4312,4314,4316,4318,4320,4322,4324,4326,4328,4330,4332,4334,4336,4338,4340],{"class":445,"line":595},[443,4293,625],{"class":457},[443,4295,628],{"class":489},[443,4297,464],{"class":449},[443,4299,526],{"class":633},[443,4301,636],{"class":489},[443,4303,639],{"class":449},[443,4305,642],{"class":453},[443,4307,645],{"class":449},[443,4309,648],{"class":489},[443,4311,651],{"class":633},[443,4313,654],{"class":489},[443,4315,518],{"class":449},[443,4317,521],{"class":633},[443,4319,654],{"class":489},[443,4321,518],{"class":449},[443,4323,4274],{"class":633},[443,4325,654],{"class":489},[443,4327,518],{"class":449},[443,4329,490],{"class":633},[443,4331,654],{"class":489},[443,4333,518],{"class":449},[443,4335,4229],{"class":633},[443,4337,667],{"class":489},[443,4339,670],{"class":449},[443,4341,673],{"class":489},[418,4343,4344,4345,915,4347,4349,4350,911,4353,1003],{},"Install it after ",[421,4346,431],{},[421,4348,2136],{},"; its CSS is the two feature stylesheets (",[421,4351,4352],{},"media.css",[421,4354,2938],{},[1010,4356,4357,4439,4471],{},[1013,4358,4359,4362,4363,911,4366,3404,4369,4373,4374,4376,4377,4380,4381,4383,4384,4386,4387,4389,4390,4392,4393,911,4395,1348,4397,4399,4400,4402,4403,4406,4407,911,4410,4413,4414,4417,4418,1308,4421,4424,4425,4427,4428,4431,4432,4435,4436,4438],{},[1016,4360,4361],{},"Wrapping."," It contributes a wrapping importer (",[421,4364,4365],{},"importers",[421,4367,4368],{},"accepts: ['*']",[1000,4370,4372],{"href":4371},".\u002F34.importers","Importers","). The blocks of every imported file — the parsed text or Markdown, the transcript of a subtitle file, the references of a BibTeX file, or the uploaded image, audio, video or file block — go into one Typed block whose Block type is the first one whose ",[421,4375,483],{}," capability names the file's media (",[421,4378,4379],{},"importTypeOf(blockTypes, media)","), else the first that lists ",[421,4382,483],{}," without media: with the built-in types audio and video become a ",[421,4385,1160],{},", images a ",[421,4388,1171],{},", everything else (PDFs, office files, text and Markdown) a ",[421,4391,1062],{},". A Block type list without such a catch-all leaves the other files unwrapped, and a host type that is called ",[421,4394,1062],{},[421,4396,1160],{},[421,4398,1171],{}," takes files only when it lists ",[421,4401,483],{},". The title is the file name without its last extension (the whole name for ",[421,4404,4405],{},".env","); the Block properties hold the file's own properties first (the frontmatter of a Markdown file), then ",[421,4408,4409],{},"filename",[421,4411,4412],{},"mimeType"," (the file's, else ",[421,4415,4416],{},"text\u002Fmarkdown"," for text and ",[421,4419,4420],{},"application\u002Foctet-stream",[421,4422,4423],{},"size"," and the import date, which win on a clash; the details popover shows them. Drop, paste, the toolbar's media buttons, the ",[421,4426,1053],{}," commands and the audio recorder all import through ",[421,4429,4430],{},"editor.storage.media.importFiles",", so they all wrap. A plan that is Typed blocks already and has no properties (the transcript of a ",[421,4433,4434],{},".vtt",", the entries of a ",[421,4437,1336],{},") is not wrapped again. Without the integration the blocks are inserted as they are.",[1013,4440,4441,4444,4445,4447,4448,4451,4452,4454,4455,4457,4458,911,4461,911,4463,911,4465,915,4468,4470],{},[1016,4442,4443],{},"Actions."," It adds the ",[421,4446,1053],{}," command „Datei importieren“ (",[421,4449,4450],{},"\u002Fdatei",", available where Typed blocks may be inserted) that picks any files and imports them at the caret. Slash entries follow the feature order, so it is listed after the media entries when installed after ",[421,4453,2136],{},". The block action „Quelle ersetzen“ (on Typed blocks of a Block type with a Source, ",[421,4456,3511],{},") picks a file of the Source media's type, uploads it and rewrites ",[421,4459,4460],{},"src",[421,4462,1195],{},[421,4464,4412],{},[421,4466,4467],{},"title",[421,4469,4423],{}," of the existing Source media block; block ids stay, so references and Derived blocks keep resolving (Derived blocks turn stale by hash comparison).",[1013,4472,4473,4476],{},[1016,4474,4475],{},"Not included."," Summaries and transcription of imported documents need AI and belong to the AI integrations, not here.",[418,4478,4479],{},"Importers are additive: two features may both contribute some, and a second wrapping importer wraps the plan of the first. Only the importer ids must be unique.",[4481,4482,4483],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}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}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}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}",{"title":439,"searchDepth":479,"depth":479,"links":4485},[4486,4487,4488,4489,4490,4491,4492,4493,4494,4495,4496,4497],{"id":1007,"depth":479,"text":1008},{"id":2537,"depth":479,"text":2538},{"id":2560,"depth":479,"text":2561},{"id":2799,"depth":479,"text":170},{"id":2819,"depth":479,"text":2820},{"id":2963,"depth":479,"text":2964},{"id":3156,"depth":479,"text":1072},{"id":3232,"depth":479,"text":3233},{"id":3610,"depth":479,"text":3611},{"id":3753,"depth":479,"text":3754},{"id":4047,"depth":479,"text":4048},{"id":4154,"depth":479,"text":4155},"Add Typed blocks with Block types, chips and property views, plus the settings panel and the file-import integration.","md",null,{},{"icon":58},{"title":109,"description":4498},"E_Q3bkldG02ckrLzXIOKX6_wr48S56CVrO3PEIEW38U",[4506,4508],{"title":104,"path":105,"stem":106,"description":4507,"icon":107,"children":-1},"Render an Obsidian theme on the whole app, choose, upload and delete themes, and know the limits.",{"title":113,"path":114,"stem":115,"description":4509,"icon":78,"children":-1},"Add AI to an editor: selection menu, sidebar, ghost text, backend endpoints, integrations with Typed blocks and transcripts, agent operations and fence formats.",1793213902043]