likec4 1.59.4 → 1.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +2 -0
  2. package/__app__/codegen/react.mjs +4 -10
  3. package/__app__/codegen/webcomponent.mjs +6 -131
  4. package/__app__/index.html +15 -15
  5. package/__app__/src/aichat/index.mjs +11 -7
  6. package/__app__/src/chunks/AIChat.mjs +1355 -739
  7. package/__app__/src/chunks/ErrorComponent.mjs +444 -0
  8. package/__app__/src/chunks/Header.mjs +269 -0
  9. package/__app__/src/chunks/ViewReact.mjs +438 -0
  10. package/__app__/src/chunks/find.mjs +38 -0
  11. package/__app__/src/chunks/hooks.mjs +158 -472
  12. package/__app__/src/chunks/libs/@tabler/icons-react.mjs +340 -0
  13. package/__app__/src/chunks/libs/@tanstack-ai.mjs +11841 -1417
  14. package/__app__/src/chunks/libs/@tanstack.mjs +5110 -2404
  15. package/__app__/src/chunks/libs/fast-equals.mjs +507 -214
  16. package/__app__/src/chunks/libs/html-to-image.mjs +613 -0
  17. package/__app__/src/chunks/libs/nanostores.mjs +170 -0
  18. package/__app__/src/chunks/libs/react-resizable-panels.mjs +2792 -0
  19. package/__app__/src/chunks/react.mjs +22 -0
  20. package/__app__/src/chunks/rolldown-runtime.mjs +16 -29
  21. package/__app__/src/chunks/router.mjs +106 -0
  22. package/__app__/src/chunks/scope.mjs +106 -0
  23. package/__app__/src/chunks/searchParams.mjs +29 -0
  24. package/__app__/src/chunks/single-index.mjs +465 -0
  25. package/__app__/src/chunks/styled-system.mjs +1826 -2528
  26. package/__app__/src/chunks/useAsync.mjs +69 -0
  27. package/__app__/src/chunks/useSyncedRef.mjs +16 -0
  28. package/__app__/src/components/ColorSchemeToggle.mjs +124 -0
  29. package/__app__/src/components/CopyToClipboard.mjs +53 -0
  30. package/__app__/src/components/ErrorComponent.mjs +1 -0
  31. package/__app__/src/components/NavigationPanel.mjs +63 -0
  32. package/__app__/src/components/NotFound.mjs +155 -0
  33. package/__app__/src/components/ViewOutlet.mjs +9 -0
  34. package/__app__/src/components/model-diff/CompareModelProvider.mjs +44 -0
  35. package/__app__/src/components/model-diff/ModelDiffPanel.mjs +179 -0
  36. package/__app__/src/components/model-diff/compare-model.mjs +76 -0
  37. package/__app__/src/components/model-diff/state.mjs +45 -0
  38. package/__app__/src/components/search/OverviewSearch.mjs +92 -0
  39. package/__app__/src/components/search/OverviewSearchAdapter.mjs +94 -0
  40. package/__app__/src/components/sidebar/DiagramTree.css.mjs +48 -0
  41. package/__app__/src/components/sidebar/DiagramsTree.mjs +304 -0
  42. package/__app__/src/components/sidebar/Drawer.mjs +178 -0
  43. package/__app__/src/components/sidebar/SidebarBurger.mjs +28 -0
  44. package/__app__/src/components/sidebar/data.mjs +94 -0
  45. package/__app__/src/components/sidebar/state.mjs +16 -0
  46. package/__app__/src/components/view-page/Header.mjs +1 -0
  47. package/__app__/src/components/view-page/SelectProject.mjs +258 -0
  48. package/__app__/src/components/view-page/ShareModal.mjs +111 -0
  49. package/__app__/src/components/view-page/share-modal/AlertLocalhost.mjs +31 -0
  50. package/__app__/src/components/view-page/share-modal/CopyButtonChild.mjs +36 -0
  51. package/__app__/src/components/view-page/share-modal/EmbedPanel.mjs +100 -0
  52. package/__app__/src/components/view-page/share-modal/WebcomponentsPanel.mjs +264 -0
  53. package/__app__/src/components/view-page/state.mjs +17 -0
  54. package/__app__/src/context/LikeC4CustomizationContext.mjs +26 -0
  55. package/__app__/src/context/LikeC4IconRendererContext.mjs +29 -0
  56. package/__app__/src/context/LikeC4ModelContext.mjs +34 -0
  57. package/__app__/src/context/LikeC4ProjectsContext.mjs +40 -0
  58. package/__app__/src/context/ModelDiffsContext.mjs +33 -0
  59. package/__app__/src/context/safeCtx.mjs +14 -0
  60. package/__app__/src/fonts.css +112 -1
  61. package/__app__/src/hooks.mjs +1 -0
  62. package/__app__/src/main.mjs +6 -29151
  63. package/__app__/src/pages/EmbedPage.mjs +93 -0
  64. package/__app__/src/pages/ExportPage.mjs +691 -0
  65. package/__app__/src/pages/ProjectsOverview.mjs +23 -0
  66. package/__app__/src/pages/ViewAsD2.mjs +105 -0
  67. package/__app__/src/pages/ViewAsDot.mjs +65 -0
  68. package/__app__/src/pages/ViewAsMmd.mjs +109 -0
  69. package/__app__/src/pages/ViewAsPuml.mjs +105 -0
  70. package/__app__/src/pages/ViewEditor.mjs +220 -0
  71. package/__app__/src/pages/ViewReact.mjs +1 -0
  72. package/__app__/src/pages/export-layout.mjs +95 -0
  73. package/__app__/src/pages/export-page-params.mjs +9 -0
  74. package/__app__/src/pages/styles.css.mjs +23 -0
  75. package/__app__/src/routeTree.gen.mjs +105 -0
  76. package/__app__/src/router.mjs +1 -0
  77. package/__app__/src/routes/__root.mjs +65 -0
  78. package/__app__/src/routes/index.css.mjs +29 -0
  79. package/__app__/src/routes/index.mjs +32 -0
  80. package/__app__/src/routes/project._projectId/-components.mjs +100 -0
  81. package/__app__/src/routes/project._projectId/embed._viewId.mjs +5 -0
  82. package/__app__/src/routes/project._projectId/export._viewId.mjs +24 -0
  83. package/__app__/src/routes/project._projectId/index.mjs +14 -0
  84. package/__app__/src/routes/project._projectId/route.mjs +93 -0
  85. package/__app__/src/routes/project._projectId/view._viewId.d2.mjs +34 -0
  86. package/__app__/src/routes/project._projectId/view._viewId.dot.mjs +41 -0
  87. package/__app__/src/routes/project._projectId/view._viewId.index.mjs +7 -0
  88. package/__app__/src/routes/project._projectId/view._viewId.mjs +23 -0
  89. package/__app__/src/routes/project._projectId/view._viewId.mmd.mjs +39 -0
  90. package/__app__/src/routes/project._projectId/view._viewId.puml.mjs +34 -0
  91. package/__app__/src/routes/projects.mjs +36 -0
  92. package/__app__/src/routes/single-index.mjs +1 -0
  93. package/__app__/src/routes/webcomponent._.mjs +94 -0
  94. package/__app__/src/style.css +18497 -1
  95. package/config/schema.json +146 -97
  96. package/dist/app/render-view-client.css +1 -1
  97. package/dist/app/render-view-client.js +394 -238
  98. package/dist/chunks/enableServer.mjs +1 -1
  99. package/dist/chunks/filenames.mjs +25 -17
  100. package/dist/chunks/generate-likec4.mjs +5 -0
  101. package/dist/chunks/index.d.mts +255 -194
  102. package/dist/chunks/index2.d.mts +8246 -3610
  103. package/dist/chunks/libs/@chenglou/pretext.mjs +9 -0
  104. package/dist/chunks/libs/@chevrotain/gast.mjs +27 -1
  105. package/dist/chunks/libs/@chevrotain/regexp-to-ast.mjs +81 -9
  106. package/dist/chunks/libs/@logtape/logtape.mjs +5 -4
  107. package/dist/chunks/libs/@lume/kiwi.mjs +1 -1
  108. package/dist/chunks/libs/@ts-graphviz/common.d.mts +2 -4
  109. package/dist/chunks/libs/@ts-graphviz/core.mjs +1 -1
  110. package/dist/chunks/libs/birpc.mjs +1 -1
  111. package/dist/chunks/libs/chevrotain-allstar.mjs +2 -2
  112. package/dist/chunks/libs/chevrotain.mjs +88 -36
  113. package/dist/chunks/libs/clone.mjs +1 -0
  114. package/dist/chunks/libs/eventemitter3.mjs +1 -1
  115. package/dist/chunks/libs/fast-equals.mjs +1 -0
  116. package/dist/chunks/libs/fontkit.mjs +1 -0
  117. package/dist/chunks/libs/json5.mjs +4 -4
  118. package/dist/chunks/libs/langium.d.mts +6707 -6715
  119. package/dist/chunks/libs/langium.mjs +16 -24
  120. package/dist/chunks/libs/merge-error-cause.mjs +1 -1
  121. package/dist/chunks/libs/p-limit.mjs +1 -0
  122. package/dist/chunks/libs/p-queue.mjs +1 -1
  123. package/dist/chunks/libs/package-manager-detector.mjs +1 -1
  124. package/dist/chunks/libs/pako.mjs +1 -1
  125. package/dist/chunks/libs/pathe.mjs +1 -1
  126. package/dist/chunks/libs/pretty-ms.mjs +1 -1
  127. package/dist/chunks/libs/remeda.mjs +1 -1
  128. package/dist/chunks/libs/ufo.mjs +1 -1
  129. package/dist/chunks/libs/unstorage.mjs +1 -1
  130. package/dist/chunks/libs/which.mjs +1 -1
  131. package/dist/chunks/node.mjs +111 -77
  132. package/dist/chunks/rolldown-runtime.mjs +1 -1
  133. package/dist/chunks/sequence-view.mjs +1 -1
  134. package/dist/chunks/vite-plugin.mjs +185 -166
  135. package/dist/cli/index.mjs +254 -1306
  136. package/dist/config/index.d.mts +66 -5
  137. package/dist/config/index.mjs +1 -1
  138. package/dist/generators/likec4.d.mts +6530 -0
  139. package/dist/generators/likec4.mjs +1 -0
  140. package/dist/index.d.mts +2 -4
  141. package/dist/model/index.d.mts +0 -7
  142. package/dist/vite-plugin/index.d.mts +83 -58
  143. package/dist/vite-plugin/index.mjs +1 -1
  144. package/dist/vite-plugin/internal/chunks/rolldown-runtime.mjs +8 -0
  145. package/dist/vite-plugin/internal/index.d.mts +92 -17
  146. package/dist/vite-plugin/internal/index.mjs +225 -126
  147. package/generators/likec4/package.json +4 -0
  148. package/package.json +134 -122
  149. package/react/index.d.mts +7496 -26659
  150. package/react/index.mjs +533 -63936
  151. package/react/rolldown-runtime-CfRud99p.js +1 -0
  152. package/skills/likec4-dsl/SKILL.md +474 -0
  153. package/skills/likec4-dsl/evals/evals-public.json +207 -0
  154. package/skills/likec4-dsl/evals/grading-spec.json +603 -0
  155. package/skills/likec4-dsl/references/bridge-leanix-drawio.md +42 -0
  156. package/skills/likec4-dsl/references/cli.md +168 -0
  157. package/skills/likec4-dsl/references/configuration.md +266 -0
  158. package/skills/likec4-dsl/references/deployment.md +160 -0
  159. package/skills/likec4-dsl/references/diffs.md +52 -0
  160. package/skills/likec4-dsl/references/dynamic-views.md +455 -0
  161. package/skills/likec4-dsl/references/examples.md +370 -0
  162. package/skills/likec4-dsl/references/identifier-validity.md +90 -0
  163. package/skills/likec4-dsl/references/include-predicates-wildcards.md +180 -0
  164. package/skills/likec4-dsl/references/model.md +182 -0
  165. package/skills/likec4-dsl/references/predicates.md +123 -0
  166. package/skills/likec4-dsl/references/relationships-bidirectional.md +176 -0
  167. package/skills/likec4-dsl/references/specification.md +79 -0
  168. package/skills/likec4-dsl/references/style-tokens-colors.md +150 -0
  169. package/skills/likec4-dsl/references/troubleshooting.md +101 -0
  170. package/skills/likec4-dsl/references/views.md +329 -0
  171. package/vite-plugin-modules.d.ts +126 -51
  172. package/__app__/src/chunks/LikeC4Styles.mjs +0 -2306
  173. package/__app__/src/chunks/ProjectsOverview.mjs +0 -537
  174. package/__app__/src/chunks/es.mjs +0 -439
  175. package/__app__/src/chunks/libs/@floating-ui.mjs +0 -2532
  176. package/__app__/src/chunks/libs/@mantine.mjs +0 -13868
  177. package/__app__/src/chunks/libs/@xstate/react.mjs +0 -2015
  178. package/__app__/src/chunks/libs/@xyflow/react.mjs +0 -5367
  179. package/__app__/src/chunks/libs/bezier-js.mjs +0 -1007
  180. package/__app__/src/chunks/libs/d3.mjs +0 -2817
  181. package/__app__/src/chunks/libs/framer.mjs +0 -5926
  182. package/__app__/src/chunks/libs/zod.mjs +0 -3176
  183. package/dist/chunks/libs/@chevrotain/types.d.mts +0 -108
  184. package/dist/chunks/libs/picomatch.mjs +0 -1
  185. package/dist/chunks/libs/zod.d.mts +0 -3840
  186. package/dist/chunks/libs/zod.mjs +0 -65
@@ -1,4 +1,4 @@
1
- import{i as e}from"./rolldown-runtime.mjs";import{E as t,S as n,_ as r,g as i,r as a,x as o,y as s}from"./node.mjs";import{_ as c,b as l,g as u,h as d,y as f}from"./libs/langium.mjs";import{o as p}from"./libs/ufo.mjs";import{t as m}from"./libs/json5.mjs";import{C as h,T as g,a as _,b as v,l as y,n as b,z as ee}from"./libs/zod.mjs";import{l as x}from"./filenames.mjs";import{$ as S,B as te,F as C,H as ne,I as w,J as T,N as E,Q as D,U as O,Z as k,b as A,c as j,h as re,k as M,o as N,r as P,t as F,tt as I,v as ie,w as L,y as ae}from"./libs/remeda.mjs";import{n as oe,t as se}from"./libs/package-manager-detector.mjs";import{t as ce}from"./libs/birpc.mjs";import{t as le}from"./libs/pako.mjs";import{createRequire as ue}from"node:module";import{mkdir as de,readFile as fe,writeFile as pe}from"node:fs/promises";import{resolve as R}from"node:path";import{RichText as me,exact as he,flattenMarkdownOrString as z}from"@likec4/core/types";import{DefaultMap as B,LikeC4Styles as ge,exact as _e,invariant as ve,nonexhaustive as ye}from"@likec4/core";import{compareNatural as be,nonNullable as xe}from"@likec4/core/utils";import"@likec4/core/model";import Se from"nano-spawn";import{existsSync as Ce}from"node:fs";import{env as V}from"std-env";import H,{cwd as we}from"node:process";const pDebounce=(e,t,n={})=>{if(!Number.isFinite(t))throw TypeError("Expected `wait` to be a finite number");let r,i,a=[],onAbort=()=>{clearTimeout(i),i=void 0;try{n.signal?.throwIfAborted()}catch(e){for(let{reject:t}of a)t(e);a=[]}};return function(...o){return new Promise((s,c)=>{try{n.signal?.throwIfAborted()}catch(e){c(e);return}let l=n.before&&!i;clearTimeout(i),i=setTimeout(async()=>{i=void 0;let t=a;a=[];try{let i=n.before?r:await e.apply(this,o);for(let{resolve:e}of t)e(i)}catch(e){for(let{reject:n}of t)n(e)}r=void 0,n.signal?.removeEventListener(`abort`,onAbort)},t),l?(async()=>{try{r=await e.apply(this,o),s(r)}catch(e){c(e)}})():(a.push({resolve:s,reject:c}),n.signal&&a.length===1&&n.signal.addEventListener(`abort`,onAbort,{once:!0}))})}};pDebounce.promise=(e,t={})=>{let n,r;return async function(...i){if(n)return t.after?(r??={resolvers:[]},r.arguments=i,r.context=this,new Promise((e,t)=>{r.resolvers.push({resolve:e,reject:t})})):n;n=(async()=>{let t,n;try{t=await e.apply(this,i)}catch(e){n=e}for(;r;){let t=r;r=void 0;try{let n=await e.apply(t.context,t.arguments);for(let{resolve:e}of t.resolvers)e(n)}catch(e){for(let{reject:n}of t.resolvers)n(e)}}if(n)throw n;return t})();try{return await n}finally{n=void 0}}};function effectiveWebappExportFormats(e){let t=e.webapp?.exportFormats;if(!t)return[...x];let n=new Set(t);return x.filter(e=>n.has(e))}function isWebappExportFormatEnabled(e,t){return effectiveWebappExportFormats(e).includes(t)}function isJsonStringifyOutput(e){if(e.length===0)return!1;try{return JSON.parse(e),!0}catch{return!1}}function hardenJsonStringLiteralForEmbeddedScript(e){if(typeof e!=`string`)throw TypeError(`hardenJsonStringLiteralForEmbeddedScript: expected JSON.stringify(...) output as a string`);if(!isJsonStringifyOutput(e))throw TypeError(`hardenJsonStringLiteralForEmbeddedScript: expected JSON.stringify(...) output (string, object, array, number, boolean, or null)`);return e.replaceAll(`<`,`\\u003C`).replaceAll(`>`,`\\u003E`).replaceAll(`/`,`\\u002F`).replaceAll(`\u2028`,`\\u2028`).replaceAll(`\u2029`,`\\u2029`)}function generateMatches(e,t=`.js`){return{matches:n=>{let{module:r,projectId:i}=n.match(/likec4:plugin\/(?<projectId>.+)\/(?<module>.+)$/)?.groups??n.match(/likec4:(?<module>.+)\/(?<projectId>.+)$/)?.groups??{};return!r||!i?null:(r.endsWith(t)&&(r=r.slice(0,-t.length)),r===e?i:null)},virtualId:n=>p(`likec4:plugin`,n,e)+t}}function generateCombinedProjects(e,t,n){return{id:`likec4:${e}`,virtualId:`likec4:plugin/`+e+`.js`,async load({projects:r}){logGenerating(e);let i=(n?r.filter(({config:e})=>isWebappExportFormatEnabled(e,n)):r).map(({id:t})=>`${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(t))}: async () => await import(${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(p(`likec4:${e}`,t)))})`),a=n?hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(`Project does not enable ${n} export: `)):null,o=t+`Registry`;return{code:`
1
+ import{i as e}from"./rolldown-runtime.mjs";import{C as t,g as n,r,v as i,y as a}from"./node.mjs";import{i as o}from"./libs/pathe.mjs";import{$ as s,F as c,G as l,H as u,L as d,R as f,T as p,W as m,X as h,b as g,c as _,et as v,f as y,g as b,j as x,o as S,r as C,t as w,tt as T,x as E,y as ee}from"./libs/remeda.mjs";import{n as te,t as ne}from"./libs/package-manager-detector.mjs";import{o as D}from"./libs/ufo.mjs";import{t as re}from"./libs/birpc.mjs";import{t as O}from"./libs/json5.mjs";import{C as k,S as A,b as j,v as M,y as N}from"./libs/langium.mjs";import{$ as P,Q as F}from"./generate-likec4.mjs";import{l as ie}from"./filenames.mjs";import{t as ae}from"./libs/pako.mjs";import{createRequire as oe}from"node:module";import I,*as L from"zod/v4";import{access as se,mkdir as ce,readFile as le,writeFile as ue}from"node:fs/promises";import{resolve as R}from"node:path";import{RichText as de,exact as fe,flattenMarkdownOrString as pe}from"@likec4/core/types";import{DefaultMap as z,LikeC4Styles as me,exact as he,invariant as ge,nonexhaustive as _e}from"@likec4/core";import{compareNatural as ve,nonNullable as ye,resolveMarkdownRefs as be}from"@likec4/core/utils";import{constants as xe,existsSync as B}from"node:fs";import"@likec4/core/model";import Se from"nano-spawn";import{env as V}from"std-env";import H,{cwd as Ce}from"node:process";const we=I.object({title:I.string().nonempty().default(`LikeC4`),theme:I.enum([`light`,`dark`]).optional(),useHashHistory:I.boolean().default(!1),webcomponentPrefix:I.string().nonempty().default(`likec4`),customization:I.string().nonempty().optional()});function resolveAppOptions(e,t){return we.parse({title:e.title??t?.pageTitle,theme:e.theme??t?.theme,useHashHistory:e.useHashHistory??t?.useHashHistory,webcomponentPrefix:e.webcomponentPrefix??t?.webcomponentPrefix,customization:e.customization})}const pDebounce=(e,t,n={})=>{if(!Number.isFinite(t))throw TypeError("Expected `wait` to be a finite number");let r,i,a=[],onAbort=()=>{clearTimeout(i),i=void 0;try{n.signal?.throwIfAborted()}catch(e){for(let{reject:t}of a)t(e);a=[]}};return function(...o){return new Promise((s,c)=>{try{n.signal?.throwIfAborted()}catch(e){c(e);return}let l=n.before&&!i;clearTimeout(i),i=setTimeout(async()=>{i=void 0;let t=a;a=[];try{let i=n.before?r:await e.apply(this,o);for(let{resolve:e}of t)e(i)}catch(e){for(let{reject:n}of t)n(e)}r=void 0,n.signal?.removeEventListener(`abort`,onAbort)},t),l?(async()=>{try{r=await e.apply(this,o),s(r)}catch(e){c(e)}})():(a.push({resolve:s,reject:c}),n.signal&&a.length===1&&n.signal.addEventListener(`abort`,onAbort,{once:!0}))})}};pDebounce.promise=(e,t={})=>{let n,r;return async function(...i){if(n)return t.after?(r??={resolvers:[]},r.arguments=i,r.context=this,new Promise((e,t)=>{r.resolvers.push({resolve:e,reject:t})})):n;n=(async()=>{let t,n,a=!1;try{t=await e.apply(this,i)}catch(e){n=e,a=!0}for(;r;){let t=r;r=void 0;try{let n=await e.apply(t.context,t.arguments);for(let{resolve:e}of t.resolvers)e(n)}catch(e){for(let{reject:n}of t.resolvers)n(e)}}if(a)throw n;return t})();try{return await n}finally{n=void 0}}};function effectiveWebappExportFormats(e){let t=e.webapp?.exportFormats;if(!t)return[...ie];let n=new Set(t);return ie.filter(e=>n.has(e))}function isWebappExportFormatEnabled(e,t){return effectiveWebappExportFormats(e).includes(t)}function isJsonStringifyOutput(e){if(e.length===0)return!1;try{return JSON.parse(e),!0}catch{return!1}}function hardenJsonStringLiteralForEmbeddedScript(e){if(typeof e!=`string`)throw TypeError(`hardenJsonStringLiteralForEmbeddedScript: expected JSON.stringify(...) output as a string`);if(!isJsonStringifyOutput(e))throw TypeError(`hardenJsonStringLiteralForEmbeddedScript: expected JSON.stringify(...) output (string, object, array, number, boolean, or null)`);return e.replaceAll(`<`,`\\u003C`).replaceAll(`>`,`\\u003E`).replaceAll(`/`,`\\u002F`).replaceAll(`\u2028`,`\\u2028`).replaceAll(`\u2029`,`\\u2029`)}function generateMatches(e,t=`.js`){return{matches:n=>{let{module:r,projectId:i}=n.match(/likec4:plugin\/(?<projectId>.+)\/(?<module>.+)$/)?.groups??n.match(/likec4:(?<module>.+)\/(?<projectId>.+)$/)?.groups??{};return!r||!i?null:(r.endsWith(t)&&(r=r.slice(0,-t.length)),r===e?i:null)},virtualId:n=>D(`likec4:plugin`,n,e)+t}}function generateCombinedProjects(e,t,n){return{id:`likec4:${e}`,virtualId:`likec4:plugin/`+e+`.js`,async load({projects:r}){logGenerating(e);let i=(n?r.filter(({config:e})=>isWebappExportFormatEnabled(e,n)):r).map(({id:t})=>`${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(t))}: async () => await import(${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(D(`likec4:${e}`,t)))})`),a=n?hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(`Project does not enable ${n} export: `)):null,o=t+`Registry`;return{code:`
2
2
  export let ${o} = {
3
3
  ${i.join(`,
4
4
  `)}
@@ -34,13 +34,13 @@ if (import.meta.hot) {
34
34
  }
35
35
  })
36
36
  }
37
- `,moduleType:`js`}}}}const U=n.getChild(`vite`);function logGenerating(e,t){t?U.info(s.dim(`generating `)+s.magenta(`likec4:${e}/`)+s.magentaBright(t)):U.info(s.dim(`generating `)+s.magenta(`likec4:${e}`))}function isInstalled(e){try{return!!import.meta.resolve(e,H.cwd())}catch(e){return U.trace(t(e)),!1}}async function ensurePackage(e){let n=U.getChild(`pkg`);if(isInstalled(e)){n.trace`${e} installed`;return}n.warn(s.dim(`not found `)+s.green(e));let r=xe(await se(),()=>{n.error`Package manager not detected, install ${e} manually`,H.exit(1)}),{command:i,args:a}=xe(oe(r.agent,`add`,[e]),()=>{n.error`Install package ${e} manually`,H.exit(1)});n.info(s.dim(`installing `)+s.green(e));try{await Se(i,a)}catch(r){n.debug(t(r)),n.error`Install package ${e} manually`,H.exit(1)}}const W=U.getChild(`ai`);function chooseModel(e,t){let n=V[e];return n||=(W.info(`I will use `+s.green(t)+` model `+s.dim(`you can override with `)+s.yellow(e)+s.dim(` env var`)),t),n}const G=16e3;async function loadOpenAI(){W.info(`Found `+s.yellow(`OPENAI_API_KEY`)+s.dim(`, loading @tanstack/ai-openai`)),await ensurePackage(`@tanstack/ai-openai`);let{openaiText:e}=await import(`@tanstack/ai-openai`);return{adapter:e(chooseModel(`OPENAI_CHAT_MODEL`,`gpt-5.2`)),modelOptions:{reasoning:{effort:`medium`}},maxTokens:G}}async function loadOpenRouter(){W.info(`Found `+s.yellow(`OPENROUTER_API_KEY`)+s.dim(`, loading @tanstack/ai-openrouter`)),await ensurePackage(`@tanstack/ai-openrouter`);let{openRouterText:e}=await import(`@tanstack/ai-openrouter`);return{adapter:e(chooseModel(`OPENROUTER_CHAT_MODEL`,`openai/gpt-5.4`)),maxTokens:G}}async function loadAnthropic(){W.info(`Found `+s.yellow(`ANTHROPIC_API_KEY`)+s.dim(`, loading @tanstack/ai-anthropic`)),await ensurePackage(`@tanstack/ai-anthropic`);let{anthropicText:e}=await import(`@tanstack/ai-anthropic`);return{adapter:e(chooseModel(`ANTHROPIC_CHAT_MODEL`,`claude-sonnet-4-6`)),maxTokens:G}}async function loadGemini(){W.info(`Found `+s.yellow(`GEMINI_API_KEY`)+s.dim(`, loading @tanstack/ai-gemini`)),await ensurePackage(`@tanstack/ai-gemini`);let{geminiText:e}=await import(`@tanstack/ai-gemini`);return{adapter:e(chooseModel(`GEMINI_CHAT_MODEL`,`gemini-2.5-pro`)),maxTokens:G}}async function loadOllama(){W.info(`Found `+s.yellow(`OLLAMA_HOST`)+s.dim(`, loading @tanstack/ai-ollama`)),await ensurePackage(`@tanstack/ai-ollama`);let{ollamaText:e}=await import(`@tanstack/ai-ollama`),t=chooseModel(`OLLAMA_CHAT_MODEL`,`qwen3`);return{adapter:e(t),modelOptions:{model:t,think:`low`},maxTokens:G}}const Te={global_en:`https://api.minimax.io/v1`,cn_zh:`https://api.minimaxi.com/v1`};function chooseMiniMaxBaseURL(){let e=V.MINIMAX_REGION?.trim().toLowerCase();return e===`cn_zh`||e===`cn`||e===`cn-zh`||e===`china`?Te.cn_zh:Te.global_en}async function loadMiniMax(){let e=chooseMiniMaxBaseURL();W.info(`Found `+s.yellow(`MINIMAX_API_KEY`)+s.dim(`, loading OpenAI-compatible adapter on `)+s.green(e)),await ensurePackage(`@tanstack/ai-openai`);let{createOpenaiChat:t}=await import(`@tanstack/ai-openai`),n=V.MINIMAX_API_KEY;return{adapter:t(chooseModel(`MINIMAX_CHAT_MODEL`,`MiniMax-M3`),n,{baseURL:e}),maxTokens:G}}function pickLoader(){if(L(V.OPENAI_API_KEY))return loadOpenAI;if(L(V.OPENROUTER_API_KEY))return loadOpenRouter;if(L(V.ANTHROPIC_API_KEY))return loadAnthropic;if(L(V.GEMINI_API_KEY))return loadGemini;if(L(V.OLLAMA_HOST))return loadOllama;if(L(V.MINIMAX_API_KEY))return loadMiniMax}const Ee=re(async()=>{let e=pickLoader();if(e){await ensurePackage(`@tanstack/ai`);let t=await e();return W.info([`AI configured with`,s.green(t.adapter.name),`adapter`,s.dim(`you can disable it in plugin options`)].join(` `)),t}}),K=U.getChild(`icons`);function iconBundlePlugin(e){let t=we(),n=[t];e.workspace&&n.unshift(e.workspace);let r=ue(t),i,resolveIcon=async(e,t)=>{try{let i=r.resolve(`@likec4/icons/${e}/${t}`,{paths:n});return K.trace(s.dim(`found in package `)+i),await fe(i,`utf-8`)}catch{return}},readFromCache=async(e,t)=>{if(i)try{let n=R(i,e,`${t}.js`);if(Ce(n))return K.trace(s.dim(`read cached `)+`${e}/${t}.js`),await fe(n,`utf-8`)}catch{}},writeToCache=async(e,t,n)=>{if(i)try{let r=R(i,e);Ce(r)||await de(r,{recursive:!0});let a=R(r,`${t}.js`);await pe(a,n),K.trace(s.dim(`written to cache `)+a)}catch(n){K.error(s.dim(`failed to write to cache `)+`${e}/${t}.js`,{error:n})}},fetchFromRemote=async(e,t)=>{let n=p(`https://icons.like-c4.dev`,e,`${t}.js`);K.trace(s.dim(`fetching `)+n);let r=await fetch(n);if(!r.ok)throw Error(`Failed to fetch icon: ${r.status} ${r.statusText}`);return await r.text()},a=new B(async e=>{try{let[t,n]=e.split(`:`);(n.endsWith(`.jsx`)||n.endsWith(`.js`))&&(n=n.slice(0,n.lastIndexOf(`.`))),K.debug(s.dim(`resolving `)+s.green(`${t}:${n}`));let r=await readFromCache(t,n);return r??=await resolveIcon(t,n),r||(r=await fetchFromRemote(t,n),await writeToCache(t,n,r),r)}catch(t){return K.error(s.dim(`failed to resolve icon `)+s.red(e),{error:t}),`
37
+ `,moduleType:`js`}}}}const U=a.getChild(`vite`);function logGenerating(e,t){t?U.info(n.dim(`generating `)+n.magenta(`likec4:${e}/`)+n.magentaBright(t)):U.info(n.dim(`generating `)+n.magenta(`likec4:${e}`))}function isInstalled(e){try{return!!import.meta.resolve(e,H.cwd())}catch(e){return U.trace(t(e)),!1}}async function ensurePackage(e){let r=U.getChild(`pkg`);if(isInstalled(e)){r.trace`${e} installed`;return}r.warn(n.dim(`not found `)+n.green(e));let i=ye(await ne(),()=>{r.error`Package manager not detected, install ${e} manually`,H.exit(1)}),{command:a,args:o}=ye(te(i.agent,`add`,[e]),()=>{r.error`Install package ${e} manually`,H.exit(1)});r.info(n.dim(`installing `)+n.green(e));try{await Se(a,o)}catch(n){r.debug(t(n)),r.error`Install package ${e} manually`,H.exit(1)}}const W=U.getChild(`ai`);function chooseModel(e,t){let r=V[e];return r||=(W.info(`I will use `+n.green(t)+` model `+n.dim(`you can override with `)+n.yellow(e)+n.dim(` env var`)),t),r}const G=16e3;async function loadOpenAI(){W.info(`Found `+n.yellow(`OPENAI_API_KEY`)+n.dim(`, loading @tanstack/ai-openai`)),await ensurePackage(`@tanstack/ai-openai`);let{openaiText:e}=await import(`@tanstack/ai-openai`);return{adapter:e(chooseModel(`OPENAI_CHAT_MODEL`,`gpt-5.5`)),modelOptions:{reasoning:{effort:`medium`}},maxTokens:G}}async function loadOpenRouter(){W.info(`Found `+n.yellow(`OPENROUTER_API_KEY`)+n.dim(`, loading @tanstack/ai-openrouter`)),await ensurePackage(`@tanstack/ai-openrouter`);let{openRouterText:e}=await import(`@tanstack/ai-openrouter`);return{adapter:e(chooseModel(`OPENROUTER_CHAT_MODEL`,`openai/gpt-5.6-sol`)),maxTokens:G}}async function loadAnthropic(){W.info(`Found `+n.yellow(`ANTHROPIC_API_KEY`)+n.dim(`, loading @tanstack/ai-anthropic`)),await ensurePackage(`@tanstack/ai-anthropic`);let{anthropicText:e}=await import(`@tanstack/ai-anthropic`);return{adapter:e(chooseModel(`ANTHROPIC_CHAT_MODEL`,`claude-sonnet-5-5`)),maxTokens:G}}async function loadGemini(){W.info(`Found `+n.yellow(`GEMINI_API_KEY`)+n.dim(`, loading @tanstack/ai-gemini`)),await ensurePackage(`@tanstack/ai-gemini`);let{geminiText:e}=await import(`@tanstack/ai-gemini`);return{adapter:e(chooseModel(`GEMINI_CHAT_MODEL`,`gemini-3.5-flash`)),maxTokens:G}}async function loadOllama(){let e=`qwen3`;W.info(`Found `+n.yellow(`OLLAMA_HOST`)+n.dim(`, loading @tanstack/ai-ollama`)),await ensurePackage(`@tanstack/ai-ollama`);let{ollamaText:t}=await import(`@tanstack/ai-ollama`),r=chooseModel(`OLLAMA_CHAT_MODEL`,e);return{adapter:t(e),modelOptions:{model:r,think:`low`},maxTokens:G}}const Te={global_en:`https://api.minimax.io/v1`,cn_zh:`https://api.minimaxi.com/v1`};function chooseMiniMaxBaseURL(){let e=V.MINIMAX_REGION?.trim().toLowerCase();return e===`cn_zh`||e===`cn`||e===`cn-zh`||e===`china`?Te.cn_zh:Te.global_en}async function loadMiniMax(){let e=chooseMiniMaxBaseURL();W.info(`Found `+n.yellow(`MINIMAX_API_KEY`)+n.dim(`, loading OpenAI-compatible adapter on `)+n.green(e)),await ensurePackage(`@tanstack/ai-openai`);let{createOpenaiChat:t}=await import(`@tanstack/ai-openai`),r=V.MINIMAX_API_KEY;return{adapter:t(chooseModel(`MINIMAX_CHAT_MODEL`,`MiniMax-M3`),r,{baseURL:e}),maxTokens:G}}function pickLoader(){if(p(V.OPENAI_API_KEY))return loadOpenAI;if(p(V.OPENROUTER_API_KEY))return loadOpenRouter;if(p(V.ANTHROPIC_API_KEY))return loadAnthropic;if(p(V.GEMINI_API_KEY))return loadGemini;if(p(V.OLLAMA_HOST))return loadOllama;if(p(V.MINIMAX_API_KEY))return loadMiniMax}const Ee=b(async()=>{let e=pickLoader();if(e){await ensurePackage(`@tanstack/ai`);let t=await e();return W.info([`AI configured with`,n.green(t.adapter.name),`adapter`,n.dim(`you can disable it in plugin options`)].join(` `)),t}}),K=U.getChild(`icons`);function iconBundlePlugin(e){let t=Ce(),r=[t];e.workspace&&r.unshift(e.workspace);let i=oe(t),a,resolveIcon=async(e,t)=>{try{let a=i.resolve(`@likec4/icons/${e}/${t}`,{paths:r});return K.trace(n.dim(`found in package `)+a),await le(a,`utf-8`)}catch{return}},readFromCache=async(e,t)=>{if(a)try{let r=R(a,e,`${t}.js`);if(B(r))return K.trace(n.dim(`read cached `)+`${e}/${t}.js`),await le(r,`utf-8`)}catch{}},writeToCache=async(e,t,r)=>{if(a)try{let i=R(a,e);B(i)||await ce(i,{recursive:!0});let o=R(i,`${t}.js`);await ue(o,r),K.trace(n.dim(`written to cache `)+o)}catch(r){K.error(n.dim(`failed to write to cache `)+`${e}/${t}.js`,{error:r})}},fetchFromRemote=async(e,t)=>{let r=D(`https://icons.like-c4.dev`,e,`${t}.js`);K.trace(n.dim(`fetching `)+r);let i=await fetch(r);if(!i.ok)throw Error(`Failed to fetch icon: ${i.status} ${i.statusText}`);return await i.text()},o=new z(async e=>{try{let[t,r]=e.split(`:`);(r.endsWith(`.jsx`)||r.endsWith(`.js`))&&(r=r.slice(0,r.lastIndexOf(`.`))),K.debug(n.dim(`resolving `)+n.green(`${t}:${r}`));let i=await readFromCache(t,r);return i??=await resolveIcon(t,r),i||(i=await fetchFromRemote(t,r),await writeToCache(t,r,i),i)}catch(t){return K.error(n.dim(`failed to resolve icon `)+n.red(e),{error:t}),`
38
38
  export default function NotFoundIcon() {
39
39
  return null
40
40
  }
41
- `}});return{name:`likec4:icon-bundle`,sharedDuringBuild:!0,applyToEnvironment(t){return!e.environments||e.environments.includes(t.name)},configResolved({root:e,...t}){n.unshift(e),t.cacheDir&&(i=R(t.cacheDir,`likec4-icons`))},resolveId:{filter:{id:/likec4:icon-bundle/},handler(e){return{id:e,moduleSideEffects:!1}}},load:{filter:{id:/likec4:icon-bundle/},async handler(e){let t=e.split(`/`).slice(-2);if(!S(t,2))return null;let[n,r]=t;return{moduleType:`jsx`,code:await a.get(`${n}:${r}`)}}}}}const q=o(`ai-layout`);function truncate(e,t=100){return e=e.replaceAll(/\n/g,` `).trim(),e.length<=t?e:e.slice(0,t-1)+`…`}function mappedEntries(e){let t={};for(let[n,r]of e.entries())t[r]=n;return t}function edgeLabel(e){let t=e.label&&e.label!==`[...]`?e.label:void 0,n=z(e.description);return n&&(t=t?`${t}\n${n}`:n),t??=e.technology??void 0,t?truncate(t):void 0}function prepareLLMInput(e){let t=1,n=1,r=new B(e=>e.children.length===0?`n${n++}`:`c${t++}`),findNodeById=t=>e.nodes.find(e=>e.id===t),nodeId=e=>r.get(findNodeById(e)),i=new Set;e.nodes.forEach(e=>{r.get(e),e.children.length===0&&i.add(e.id)});let a=e.edges.find(e=>!i.has(e.source)||!i.has(e.target));if(a)throw q.error(`Non-leaf edge found in view`,{view:e.id,edge:{source:a.source,target:a.target}}),Error(`Non-leaf edge found in view, this is not supported by the current implementation`);let o=1,s=new B(e=>`e${o++}`),c=e.edges.map(e=>{let t=nodeId(e.source),n=nodeId(e.target),r=e.parent?nodeId(e.parent):null;e.dir===`back`&&([t,n]=[n,t]);let i=edgeLabel(e);return{id:s.get(e),...i&&{label:i},...r&&{parent:r},source:t,target:n}}),reduceNodes=(e,t)=>{let{level:n,kind:i,...a}=t,o=r.get(t),s=a.children.length>0,c=a.parent?nodeId(a.parent):void 0,l=truncate(a.title);if(s)return e.compounds.push(he({id:o,title:l,parent:c,children:a.children.map(nodeId),level:n})),e;let u=a.description?truncate(z(a.description),200):void 0;return e.nodes.push(he({id:o,kind:i,title:l,description:u,parent:c,level:n})),e};return{serialized:e.nodes.reduce(reduceNodes,{direction:e.autoLayout.direction,compounds:[],nodes:[],edges:c}),mapping:{nodes:mappedEntries(r),edges:mappedEntries(s)}}}const De=_([`TB`,`BT`,`LR`,`RL`]),J=g().nonempty().brand(),Oe=_([`same`,`source`,`sink`,`min`,`max`]),ke=v({rank:Oe,nodes:y(J)}),Y={id:g().nonempty().brand(),weight:b().int().min(0).max(20),minlen:b().int().min(0).max(4)},Ae=v({source:J,target:J,weight:Y.weight.optional(),minlen:Y.minlen.optional()}),je=v({direction:De.optional(),ranks:y(ke).default([]),edgeWeight:h(Y.id,Y.weight).default({}),edgeMinlen:h(Y.id,Y.minlen).default({}),reverseRank:y(Y.id).default([]),excludeFromRanking:y(Y.id).default([]),edgeOrder:y(Y.id).default([]),nodeOrder:y(J).default([]),invisibleEdges:y(Ae).default([]),reasoning:g().default(``)}),Me=/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/;function extractJson(e){let t=Me.exec(e);if(t&&t[1])return t[1];let n=e.indexOf(`{`),r=e.lastIndexOf(`}`);return n!==-1&&r!==-1&&r>n?e.slice(n,r+1):e.trim()}function parseOutput(e,t){try{let n=extractJson(e),r=m.parse(n),i=je.safeParse(r);if(!i.success){q.warn(`Failed to validate LLM response
42
- `+ee(i.error));return}return restoreIdsAndMapToHints(i.data,t)}catch(t){q.warn(`Failed to parse LLM response
43
- {response}`,{error:t,response:e});return}}function restoreIdsAndMapToHints(e,t){let{mapping:n}=t,nodeId=e=>{let t=n.nodes[e]?.id;return t||q.warn`Unknown node ID ${e} in LLM output, skipping`,t},mapToNodeId=e=>I(e,A(nodeId),k(C)),edgeId=e=>{let t=n.edges[e]?.id;return t||q.warn`Unknown edge ID ${e} in LLM output, skipping`,t},mapToNonEmpty=(e,t)=>{let n=e.map(t).filter(C);return S(n,1)?n:void 0},r=I(e.excludeFromRanking,A(edgeId),k(C),P(),e=>S(e,1)?e:void 0),i=I(e.reverseRank,A(edgeId),k(C),P(),e=>S(e,1)?e:void 0),a=(()=>{let e=new Set;return t=>t.filter(t=>!e.has(t)&&(e.add(t),!0))})(),o=I(e.ranks,A(e=>{let t=a(mapToNodeId(e.nodes));return S(t,1)?{rank:e.rank,nodes:t}:null}),k(L)),s=I(e.invisibleEdges,A(({source:e,target:t,minlen:n=1,weight:r=1})=>{let i=nodeId(e),a=nodeId(t);if(i&&a)return _e({weight:r===1?void 0:r,minlen:n===1?void 0:n,source:i,target:a})}),k(C),ne(e=>`${e.source}->${e.target}`),ie(([e,...t])=>I(t,j((e,t)=>_e({...e,...t,weight:e.weight&&t.weight?Math.max(e.weight,t.weight):e.weight||t.weight,minlen:e.minlen&&t.minlen?Math.max(e.minlen,t.minlen):e.minlen||t.minlen}),e))),F(),e=>S(e,1)?e:void 0),c=e.reasoning;c&&(c=c.replaceAll(`][`,`] [`),D(t.mapping.nodes).forEach(([e,t])=>{c=c.replaceAll(RegExp(`\\[${e}\\]`,`g`),"`"+t.id+"`")}),D(t.mapping.edges).forEach(([e,t])=>{c=c.replaceAll(RegExp(`\\[${e}\\]`,`g`),"`"+t.source+` -> `+t.target+"`")}));let safeMapEdgeKeys=e=>{let t={};for(let[n,r]of D(e)){let e=edgeId(n);e&&(t[e]=r)}return t};return _e({direction:e.direction,ranks:o,edgeWeight:safeMapEdgeKeys(e.edgeWeight),edgeMinlen:safeMapEdgeKeys(e.edgeMinlen),excludeFromRanking:r,reverseRank:i,edgeOrder:mapToNonEmpty(e.edgeOrder,edgeId),nodeOrder:mapToNonEmpty(e.nodeOrder,nodeId),invisibleEdges:s,reasoning:c})}const Ne={systemPrompt:`You are an advisor specializing in software architecture diagrams and graphviz (DOT) layout optimizations.
41
+ `}});return{name:`likec4:icon-bundle`,sharedDuringBuild:!0,applyToEnvironment(t){return!e.environments||e.environments.includes(t.name)},configResolved({root:e,...t}){r.unshift(e),t.cacheDir&&(a=R(t.cacheDir,`likec4-icons`))},resolveId:{filter:{id:/likec4:icon-bundle/},handler(e){return{id:e,moduleSideEffects:!1}}},load:{filter:{id:/likec4:icon-bundle/},async handler(e){let t=e.split(`/`).slice(-2);if(!T(t,2))return null;let[n,r]=t;return{moduleType:`jsx`,code:await o.get(`${n}:${r}`)}}}}}const q=/* @__PURE__ */ i(`ai-layout`);function truncate(e,t=100){return e=e.replaceAll(/\n/g,` `).trim(),e.length<=t?e:e.slice(0,t-1)+`…`}function mappedEntries(e){let t={};for(let[n,r]of e.entries())t[r]=n;return t}function edgeLabel(e){let t=e.label&&e.label!==`[...]`?e.label:void 0,n=pe(e.description);return n&&(t=t?`${t}\n${n}`:n),t??=e.technology??void 0,t?truncate(t):void 0}function prepareLLMInput(e){let t=1,n=1,r=new z(e=>e.children.length===0?`n${n++}`:`c${t++}`),findNodeById=t=>e.nodes.find(e=>e.id===t),nodeId=e=>r.get(findNodeById(e)),i=/* @__PURE__ */ new Set;e.nodes.forEach(e=>{r.get(e),e.children.length===0&&i.add(e.id)});let a=e.edges.find(e=>!i.has(e.source)||!i.has(e.target));if(a)throw q.error(`Non-leaf edge found in view`,{view:e.id,edge:{source:a.source,target:a.target}}),Error(`Non-leaf edge found in view, this is not supported by the current implementation`);let o=1,s=new z(e=>`e${o++}`),c=e.edges.map(e=>{let t=nodeId(e.source),n=nodeId(e.target),r=e.parent?nodeId(e.parent):null;e.dir===`back`&&([t,n]=[n,t]);let i=edgeLabel(e);return{id:s.get(e),...i&&{label:i},...r&&{parent:r},source:t,target:n}}),reduceNodes=(e,t)=>{let{level:n,kind:i,...a}=t,o=r.get(t),s=a.children.length>0,c=a.parent?nodeId(a.parent):void 0,l=truncate(a.title);if(s)return e.compounds.push(fe({id:o,title:l,parent:c,children:a.children.map(nodeId),level:n})),e;let u=a.description?truncate(pe(a.description),200):void 0;return e.nodes.push(fe({id:o,kind:i,title:l,description:u,parent:c,level:n})),e};return{serialized:e.nodes.reduce(reduceNodes,{direction:e.autoLayout.direction,compounds:[],nodes:[],edges:c}),mapping:{nodes:mappedEntries(r),edges:mappedEntries(s)}}}const De=L.enum([`TB`,`BT`,`LR`,`RL`]),J=L.string().nonempty().brand(),Oe=L.enum([`same`,`source`,`sink`,`min`,`max`]),ke=L.object({rank:Oe,nodes:L.array(J)}),Y={id:L.string().nonempty().brand(),weight:L.coerce.number().int().min(0).max(20),minlen:L.coerce.number().int().min(0).max(4)},Ae=L.object({source:J,target:J,weight:Y.weight.optional(),minlen:Y.minlen.optional()}),je=L.object({direction:De.optional(),ranks:L.array(ke).default([]),edgeWeight:L.record(Y.id,Y.weight).default({}),edgeMinlen:L.record(Y.id,Y.minlen).default({}),reverseRank:L.array(Y.id).default([]),excludeFromRanking:L.array(Y.id).default([]),edgeOrder:L.array(Y.id).default([]),nodeOrder:L.array(J).default([]),invisibleEdges:L.array(Ae).default([]),reasoning:L.string().default(``)}),Me=/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/;function extractJson(e){let t=Me.exec(e);if(t&&t[1])return t[1];let n=e.indexOf(`{`),r=e.lastIndexOf(`}`);return n!==-1&&r!==-1&&r>n?e.slice(n,r+1):e.trim()}function parseOutput(e,t){try{let n=extractJson(e),r=O.parse(n),i=je.safeParse(r);if(!i.success){q.warn(`Failed to validate LLM response
42
+ `+L.prettifyError(i.error));return}return restoreIdsAndMapToHints(i.data,t)}catch(t){q.warn(`Failed to parse LLM response
43
+ {response}`,{error:t,response:e});return}}function restoreIdsAndMapToHints(e,t){let{mapping:n}=t,nodeId=e=>{let t=n.nodes[e]?.id;return t||q.warn`Unknown node ID ${e} in LLM output, skipping`,t},mapToNodeId=e=>y(e,E(nodeId),s(d)),edgeId=e=>{let t=n.edges[e]?.id;return t||q.warn`Unknown edge ID ${e} in LLM output, skipping`,t},mapToNonEmpty=(e,t)=>{let n=e.map(t).filter(d);return T(n,1)?n:void 0},r=y(e.excludeFromRanking,E(edgeId),s(d),C(),e=>T(e,1)?e:void 0),i=y(e.reverseRank,E(edgeId),s(d),C(),e=>T(e,1)?e:void 0),a=(()=>{let e=/* @__PURE__ */ new Set;return t=>t.filter(t=>!e.has(t)&&(e.add(t),!0))})(),o=y(e.ranks,E(e=>{let t=a(mapToNodeId(e.nodes));return T(t,1)?{rank:e.rank,nodes:t}:null}),s(p)),c=y(e.invisibleEdges,E(({source:e,target:t,minlen:n=1,weight:r=1})=>{let i=nodeId(e),a=nodeId(t);if(i&&a)return he({weight:r===1?void 0:r,minlen:n===1?void 0:n,source:i,target:a})}),s(d),m(e=>`${e.source}->${e.target}`),ee(([e,...t])=>y(t,_((e,t)=>he({...e,...t,weight:e.weight&&t.weight?Math.max(e.weight,t.weight):e.weight||t.weight,minlen:e.minlen&&t.minlen?Math.max(e.minlen,t.minlen):e.minlen||t.minlen}),e))),w(),e=>T(e,1)?e:void 0),l=e.reasoning;l&&(l=l.replaceAll(`][`,`] [`),v(t.mapping.nodes).forEach(([e,t])=>{l=l.replaceAll(RegExp(`\\[${e}\\]`,`g`),"`"+t.id+"`")}),v(t.mapping.edges).forEach(([e,t])=>{l=l.replaceAll(RegExp(`\\[${e}\\]`,`g`),"`"+t.source+` -> `+t.target+"`")}));let safeMapEdgeKeys=e=>{let t={};for(let[n,r]of v(e)){let e=edgeId(n);e&&(t[e]=r)}return t};return he({direction:e.direction,ranks:o,edgeWeight:safeMapEdgeKeys(e.edgeWeight),edgeMinlen:safeMapEdgeKeys(e.edgeMinlen),excludeFromRanking:r,reverseRank:i,edgeOrder:mapToNonEmpty(e.edgeOrder,edgeId),nodeOrder:mapToNonEmpty(e.nodeOrder,nodeId),invisibleEdges:c,reasoning:l})}const Ne={systemPrompt:`You are an advisor specializing in software architecture diagrams and graphviz (DOT) layout optimizations.
44
44
  You receive a JSON of Diagram data with:
45
45
  - nodes (architectural elements, rendered as leaf boxes)
46
46
  - compounds (group of nodes or other compounds, define hierarchy and rendered as boxes around children)
@@ -54,7 +54,7 @@ Diagram (JSON object) fields:
54
54
  - compounds: Compound[]
55
55
  - nodes: Node[]
56
56
  - edges: Edge[]
57
- - direction: "TB" | "LR" | "BT" | "RL"
57
+ - direction: "TB" | "LR" | "BT" | "RL" | "Top
58
58
 
59
59
  Node (JSON object) fields:
60
60
  - id: string (starts with "n" followed by a number, e.g. "n1", "n2", etc.)
@@ -226,13 +226,13 @@ OUTPUT:
226
226
  "reasoning": "I reversed [e4] as it moves [n4] to the top, pushes [n3] to the next row and balances layout, [e5] \`minlen=0\` to keep [n2][n3] on same rank"
227
227
  }
228
228
  \`\`\`
229
- </example>`,userPrompt:`Analyze semantics and suggest layout hints for the following diagram. Return only JSON object without any additional text or markdown formatting.`};async function enhanceLayoutWithAI(e,t,n){try{q.debug`generating AI layout hints for ${e.id} using ${t.name}`;let{serialized:r,mapping:i}=prepareLLMInput(e);return parseOutput(await t.sendRequest({...Ne,view:e,mapping:i,diagram:JSON.stringify(r)},n),{mapping:i,view:e})}catch(e){q.warn(`AI layout enhancement failed`,{error:e});return}}async function applySemanticLayout({logger:e,ai:t,likec4:n,server:r},i){ve(t,`AI is not configured`),e.info([s.green(`semantic:layout`),s.dim(`project:`),i.projectId,s.dim(`view:`),i.viewId].join(` `));let a={started:()=>r.hot.send(`likec4:apply-semantic-layout`,{type:`started`}),completed:()=>r.hot.send(`likec4:apply-semantic-layout`,{type:`completed`}),log:e=>r.hot.send(`likec4:apply-semantic-layout`,{log:e})},{chat:o,EventType:c}=await import(`@tanstack/ai`),l=(await n.computedModel(i.projectId)).findView(i.viewId);ve(l,`View ${i.viewId} not found in project ${i.projectId}`),e.info([s.green(`semantic:layout`),s.dim(`call`),t.adapter.name].join(` `));let u=await enhanceLayoutWithAI(l.$view,{name:t.adapter.name,async sendRequest({systemPrompt:e,userPrompt:n,diagram:r}){a.started();let i=o({...t,systemPrompts:[e],stream:!0,messages:[{role:`user`,content:[{type:`text`,content:e},{type:`text`,content:n},{type:`text`,content:r}]}]}),s=``;for await(let e of i)switch(e.type){case c.TEXT_MESSAGE_CONTENT:a.log(e.delta),s+=e.delta;break;case c.REASONING_MESSAGE_CONTENT:a.log(e.delta)}return s}});if(a.completed(),!u){e.warn([s.yellow(`semantic:layout`),`No semantic layout generated`].join(` `));return}e.info([s.green(`semantic:layout`),s.dim(`apply ai hints to layout`)].join(` `));let d=await n.views.layoutView({viewId:i.viewId,projectId:i.projectId,layoutHints:u});if(!d){e.error([s.red(`semantic:layout`),`layout hints failed`].join(` `));return}e.info([s.green(`semantic:layout`),s.dim(`save view snapshot`)].join(` `));let f=await n.editor.applyChange({viewId:i.viewId,projectId:i.projectId,change:{op:`save-view-snapshot`,layout:d.diagram}});if(!f.success){e.error([s.red(`semantic:layout`),`apply change failed`,f.error].join(` `));let t=Error(f.error);throw t.stack=f.error,t}e.info([s.green(`semantic:layout`),s.dim(`project:`),i.projectId,s.dim(`view:`),i.viewId,`✅`].join(` `))}async function calcAdhocView({logger:e,likec4:t},n){e.info([s.green(`adhoc:view`),s.dim(`project:`),n.projectId].join(` `));let r=await t.views.adhocView(n.predicates,n.projectId);return e.info([s.green(`adhoc:view`),`✅`].join(` `)),r}async function updateView({logger:e,likec4:t},n){e.info([s.green(`view:onChange`),s.dim(`project`),n.projectId,s.dim(`view`),n.viewId,s.dim(`change`),n.change.op].join(` `));let r=await t.editor.applyChange(n);if(!r.success){e.error(`Failed to apply view change:\n${r.error}`);let t=Error(r.error);throw t.stack=r.error,t}e.info([s.green(`view:onChange`),`✅`].join(` `))}function splitErrorMessage(e){let t=e.split(`
229
+ </example>`,userPrompt:`Analyze semantics and suggest layout hints for the following diagram. Return only JSON object without any additional text or markdown formatting.`};async function enhanceLayoutWithAI(e,t,n){try{q.debug`generating AI layout hints for ${e.id} using ${t.name}`;let{serialized:r,mapping:i}=prepareLLMInput(e);return parseOutput(await t.sendRequest({...Ne,view:e,mapping:i,diagram:JSON.stringify(r)},n),{mapping:i,view:e})}catch(e){q.warn(`AI layout enhancement failed`,{error:e});return}}async function applySemanticLayout({logger:e,ai:t,likec4:r,server:i},a){ge(t,`AI is not configured`),e.info([n.green(`semantic:layout`),n.dim(`project:`),a.projectId,n.dim(`view:`),a.viewId].join(` `));let o={started:()=>i.hot.send(`likec4:apply-semantic-layout`,{type:`started`}),completed:()=>i.hot.send(`likec4:apply-semantic-layout`,{type:`completed`}),log:e=>i.hot.send(`likec4:apply-semantic-layout`,{log:e})},{chat:s,EventType:c}=await import(`@tanstack/ai`),l=(await r.computedModel(a.projectId)).findView(a.viewId);ge(l,`View ${a.viewId} not found in project ${a.projectId}`),e.info([n.green(`semantic:layout`),n.dim(`call`),t.adapter.name].join(` `));let u=await enhanceLayoutWithAI(l.$view,{name:t.adapter.name,async sendRequest({systemPrompt:e,userPrompt:n,diagram:r}){o.started();let i=s({...t,systemPrompts:[e],stream:!0,messages:[{role:`user`,content:[{type:`text`,content:e},{type:`text`,content:n},{type:`text`,content:r}]}]}),a=``;for await(let e of i)switch(e.type){case c.TEXT_MESSAGE_CONTENT:o.log(e.delta),a+=e.delta;break;case c.REASONING_MESSAGE_CONTENT:o.log(e.delta)}return a}});if(o.completed(),!u){e.warn([n.yellow(`semantic:layout`),`No semantic layout generated`].join(` `));return}e.info([n.green(`semantic:layout`),n.dim(`apply ai hints to layout`)].join(` `));let d=await r.views.layoutView({viewId:a.viewId,projectId:a.projectId,layoutHints:u});if(!d){e.error([n.red(`semantic:layout`),`layout hints failed`].join(` `));return}e.info([n.green(`semantic:layout`),n.dim(`save view snapshot`)].join(` `));let f=await r.editor.applyChange({viewId:a.viewId,projectId:a.projectId,change:{op:`save-view-snapshot`,layout:d.diagram}});if(!f.success){e.error([n.red(`semantic:layout`),`apply change failed`,f.error].join(` `));let t=Error(f.error);throw t.stack=f.error,t}e.info([n.green(`semantic:layout`),n.dim(`project:`),a.projectId,n.dim(`view:`),a.viewId,`✅`].join(` `))}async function calcAdhocView({logger:e,likec4:t},r){e.info([n.green(`adhoc:view`),n.dim(`project:`),r.projectId].join(` `));let i=await t.views.adhocView(r.predicates,r.projectId);return e.info([n.green(`adhoc:view`),`✅`].join(` `)),i}async function updateView({logger:e,likec4:t},r){e.info([n.green(`view:onChange`),n.dim(`project`),r.projectId,n.dim(`view`),r.viewId,n.dim(`change`),r.change.op].join(` `));let i=await t.editor.applyChange(r);if(!i.success){e.error(`Failed to apply view change:\n${i.error}`);let t=Error(i.error);throw t.stack=i.error,t}e.info([n.green(`view:onChange`),`✅`].join(` `))}function splitErrorMessage(e){let t=e.split(`
230
230
  `),n=/^\s+at\s+/,r=t.findIndex(e=>n.test(e));return r===-1&&(r=1),{message:t.slice(0,r).join(`
231
231
  `),stack:t.slice(r).join(`
232
- `)}}function sendError(e,{name:t,error:n}){e.hot.send({type:`error`,err:{...splitErrorMessage(n),name:t??`LikeC4PluginError`,plugin:`vite-plugin-likec4`}})}function enablePluginRPC(e){let t=null,n=e.server;ce({updateView:t=>updateView(e,t),calcAdhocView:t=>calcAdhocView(e,t),applySemanticLayout:t=>applySemanticLayout(e,t)},{on:e=>n.hot.on(`likec4:rpc`,e),post:e=>n.hot.send(`likec4:rpc`,e),onTimeoutError(e){return e===`applySemanticLayout`},onFunctionError:(r,i)=>{e.logger.error(`RPC error in ${i}`,{error:r});let a=r.stack??r.message;try{t!==a&&(t=a,sendError(n,{name:r.name,error:a}))}catch(t){e.logger.error(`Failed to send error to client`,{error:t})}}})}function createAppConfigModule(e){let{webcomponentPrefix:t=`likec4`,pageTitle:n=`LikeC4`,useHashHistory:r=!1,theme:i=`auto`}=e||{};return{id:`likec4:app-config`,virtualId:`likec4:plugin/app-config.js`,async load(){return logGenerating(`app-config`),`
232
+ `)}}function sendError(e,{name:t,error:n}){e.hot.send({type:`error`,err:{...splitErrorMessage(n),name:t??`LikeC4PluginError`,plugin:`vite-plugin-likec4`}})}function enablePluginRPC(e){let t=null,n=e.server;re({updateView:t=>updateView(e,t),calcAdhocView:t=>calcAdhocView(e,t),applySemanticLayout:t=>applySemanticLayout(e,t)},{on:e=>n.hot.on(`likec4:rpc`,e),post:e=>n.hot.send(`likec4:rpc`,e),onTimeoutError(e){return e===`applySemanticLayout`},onFunctionError:(r,i)=>{e.logger.error(`RPC error in ${i}`,{error:r});let a=r.stack??r.message;try{t!==a&&(t=a,sendError(n,{name:r.name,error:a}))}catch(t){e.logger.error(`Failed to send error to client`,{error:t})}}})}function createAppConfigModule({webcomponentPrefix:e,title:t,useHashHistory:n,theme:r}){return{id:`likec4:app-config`,virtualId:`likec4:plugin/app-config.js`,async load(){return logGenerating(`app-config`),`
233
233
  export let ComponentName = {
234
- View: ${JSON.stringify(t+`-view`)},
235
- Browser: ${JSON.stringify(t+`-browser`)},
234
+ View: ${JSON.stringify(e+`-view`)},
235
+ Browser: ${JSON.stringify(e+`-browser`)},
236
236
  }
237
237
 
238
238
  let BASE = import.meta.env.BASE_URL
@@ -240,23 +240,54 @@ if (!BASE.endsWith('/')) {
240
240
  BASE = BASE + '/'
241
241
  }
242
242
 
243
- export let pageTitle = ${JSON.stringify(n)}
244
- export let useHashHistory = ${r}
243
+ export let pageTitle = ${JSON.stringify(t)}
244
+ export let useHashHistory = ${n}
245
245
 
246
246
  export let basepath = useHashHistory ? '/' : BASE
247
247
 
248
248
  export let isDevelopment = import.meta.env.DEV
249
249
 
250
- export let defaultTheme = ${JSON.stringify(i)}
250
+ export let defaultTheme = ${JSON.stringify(r??`auto`)}
251
251
 
252
252
  export let krokiD2SvgUrl = import.meta.env.VITE_KROKI_D2_SVG_URL || 'https://kroki.io/d2/svg'
253
253
  export let krokiPumlSvgUrl = import.meta.env.VITE_KROKI_D2_SVG_URL || 'https://kroki.io/plantuml/svg'
254
254
 
255
- `}}}const Pe=e(e=>e.charAt(0).toLocaleUpperCase()+e.slice(1),`capitalizeFirstLetter`),Fe=e(e=>e.split(`.`).map(Pe).join(``),`fqnName`),Ie=e(e=>Fe(e.parent?e.id.slice(e.parent.length+1):e.id),`nodeName`),d2direction=({autoLayout:e})=>{switch(e.direction){case`TB`:return`down`;case`BT`:return`up`;case`LR`:return`right`;case`RL`:return`left`}},d2shape=({shape:e})=>{switch(e){case`queue`:case`cylinder`:case`rectangle`:case`document`:return e;case`person`:return`c4-person`;case`storage`:return`stored_data`;case`component`:case`bucket`:case`mobile`:case`browser`:return`rectangle`}};function generateD2(e){let t=e.$view,{nodes:n,edges:a}=t,o=new Map,printNode=(e,t)=>{let r=Ie(e),a=(t?t+`.`:``)+r;o.set(e.id,a);let s=JSON.stringify(e.title),c=d2shape(e);return new u().append(r,`: {`,i).indent({indentedChildren:t=>t.append(`label: `,s,i).appendIf(c!==`rectangle`,`shape: `,c,i).appendIf(e.children.length>0,i,d(n.filter(t=>t.parent===e.id),e=>printNode(e,a))),indentation:2}).append(`}`,i)},printEdge=e=>new u().append(o.get(e.source),` -> `,o.get(e.target)).append(t=>e.label&&t.append(`: `,JSON.stringify(e.label)));return r(new u().append(`direction: `,d2direction(t),i,i).append(d(n.filter(e=>M(e.parent)),e=>printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(a.length>0,i,d(a,e=>printEdge(e),{appendNewLineIfNotEmpty:!0})))}const Le=`data:page/id,likec4-`,Re=`diagrams.drawio`;function escapeXml(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&apos;`)}function parseDrawioRoundtripComments(e){let t=e.split(/\r?\n/),n={},r={},i={},a={},o=!1,s=0;for(;s<t.length;){let e=t[s];if(e==null){s+=1;continue}if(e.trim()===`// <likec4.layout.drawio>`){o=!0,s+=1;let e=[];for(;s<t.length&&t[s]?.trim()!==`// </likec4.layout.drawio>`;){let n=t[s]?.trim();n?.startsWith(`// `)&&e.push(n.slice(3)),s+=1}if(e.length>0)try{let t=e.join(`
256
- `);n=JSON.parse(t)}catch{}s+=1;continue}if(e.trim()===`// <likec4.strokeColor.vertices>`){for(o=!0,s+=1;s<t.length&&t[s]?.trim()!==`// </likec4.strokeColor.vertices>`;){let e=t[s]?.trim();if(e?.startsWith(`// `)&&e.includes(`=`)){let t=e.slice(3).trim(),n=t.indexOf(`=`);if(n>0){let e=t.slice(0,n).trim(),i=t.slice(n+1).trim();e&&i&&(r[e]=i)}}s+=1}s+=1;continue}if(e.trim()===`// <likec4.strokeWidth.vertices>`){for(o=!0,s+=1;s<t.length&&t[s]?.trim()!==`// </likec4.strokeWidth.vertices>`;){let e=t[s]?.trim();if(e?.startsWith(`// `)&&e.includes(`=`)){let t=e.slice(3).trim(),n=t.indexOf(`=`);if(n>0){let e=t.slice(0,n).trim(),r=t.slice(n+1).trim();e&&r!==``&&(i[e]=r)}}s+=1}s+=1;continue}if(e.trim()===`// <likec4.edge.waypoints>`){for(o=!0,s+=1;s<t.length&&t[s]?.trim()!==`// </likec4.edge.waypoints>`;){let e=t[s]?.trim();if(e?.startsWith(`// `)){let t=e.slice(3).trim(),n=t.indexOf(` `);if(n>0){let e=t.slice(0,n).trim(),r=t.slice(n+1).trim();if(e&&r)try{let t=JSON.parse(r);Array.isArray(t)&&(a[e]=t)}catch{}}}s+=1}s+=1;continue}s+=1}return o?{layoutByView:n,strokeColorByFqn:r,strokeWidthByFqn:i,edgeWaypoints:a}:null}function compressDrawioDiagramXml(e){let t=encodeURIComponent(e),n=new TextEncoder().encode(t);return uint8ArrayToBase64(le.deflateRaw(n))}function uint8ArrayToBase64(e){if(typeof Buffer<`u`)return Buffer.from(e).toString(`base64`);let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}const X={getNotes(e){return e.notes},getSummary(e){return e.summary},getTags(e){return e.tags},getNavigateTo(e){return e.navigateTo},getIcon(e){return e.icon},getLinks(e){return e.links},getNotation(e){return e.notation},getCustomData(e){return e.customData},getChildren(e){return e.children}},Z={getKind(e){return e.kind},getNotation(e){return e.notation},getLinks(e){return e.links},getMetadata(e){return e.metadata},getCustomData(e){return e.customData}};function getEffectiveStyles(e){return e.$styles??ge.DEFAULT}function escapeHtml(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`)}function toNonEmptyString(e){if(e==null)return``;let t=typeof e;if(t===`string`){let t=e;return t.trim()===``?``:t}return t===`number`||t===`boolean`?String(e):``}function getContainerDashedStyle(e,t){return e&&t!==`none`||t===`dashed`?`dashed=1;`:``}function getDefaultStrokeWidth(e,t){return e===`none`?`0`:t||e?`1`:``}function applyStrokeColorOverride(e,t){return{fill:e?.fill??`#dae8fc`,stroke:t,font:e?.font??t}}function resolveThemeColor(e,t,n){return t&&t in e.theme.colors?t:n}function getThemeColorValues(e,t,n){let r=getEffectiveStyles(e),i=resolveThemeColor(r,t??n,n);try{return r.colors(i)}catch{return ge.DEFAULT.colors(n)}}function drawioShape(e){let t=`shape=rectangle;rounded=1;arcSize=12;`;switch(e){case`person`:return`shape=actor;`;case`rectangle`:case`browser`:case`mobile`:case`bucket`:return t;case`cylinder`:case`queue`:case`storage`:return`shape=cylinder3;whiteSpace=wrap;boundedLbl=1;backgroundOutline=1;size=15;`;case`document`:return`shape=document;whiteSpace=wrap;html=1;boundedLbl=1;`;case`component`:return`shape=component;`;default:return t}}function getElementColors(e,t){let n=getThemeColorValues(e,t,`primary`).elements;return{fill:String(n.fill??`#dae8fc`),stroke:String(n.stroke??`#2563eb`),font:String(n.hiContrast??n.stroke??`#1e40af`)}}function getEdgeStrokeColor(e,t){let n=getThemeColorValues(e,t??`gray`,`gray`);return String(n.relationships?.line??`#1e40af`)}function getEdgeLabelColors(e,t){let n=getThemeColorValues(e,t??`gray`,`gray`).relationships;return{font:String(n?.label??n?.line??`#1e40af`),background:String(n?.labelBg??`#ffffff`)}}function edgeAnchors(e,t){let n=e.x+e.width/2,r=e.y+e.height/2,i=t.x+t.width/2,a=t.y+t.height/2,o=i-n,s=a-r,c=Math.abs(o)>=Math.abs(s);return{exitX:c?+(o>=0):.5,exitY:c?.5:+(s>=0),entryX:c?o>=0?0:1:.5,entryY:c?.5:s>=0?0:1}}function normalizeEdgePoint(e){if(Array.isArray(e)&&e.length>=2&&typeof e[0]==`number`&&typeof e[1]==`number`)return[[e[0],e[1]]];let t=e;return typeof t.x==`number`&&typeof t.y==`number`?[[t.x,t.y]]:[]}function buildNodeValueHtml(e,t,n,r,i,a){return n?``:t===``?`<div style="box-sizing:border-box;width:100%;min-height:100%;display:flex;align-items:center;justify-content:center;text-align:center;color:${r};font-family:${i};"><b style="font-size:${a}px;">${escapeHtml(e)}</b></div>`:`<div style="box-sizing:border-box;width:100%;min-height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;color:${r};font-family:${i};"><b style="font-size:${a}px;">${escapeHtml(e)}</b><br/><span style="font-weight:normal;font-size:${a}px;">${escapeHtml(t)}</span></div>`}function pushStylePart(e,t,n){n!=null&&n!==``&&e.push(`${t}=${encodeURIComponent(n)}`)}function pushStylePartNum(e,t,n){n!=null&&e.push(`${t}=${n}`)}function buildNavLinkStyle(e){return e===``?``:`link=${encodeURIComponent(`${Le}${e}`)};`}function toExportString(e){let t=e==null?null:z(e);return t!=null&&!E(t)?t.trim():``}function linksToStyleJson(e){return!Array.isArray(e)||e.length===0?``:encodeURIComponent(JSON.stringify(e.map(e=>({url:e.url,title:e.title}))))}function metadataToStyleJson(e){return typeof e!=`object`||!e||Array.isArray(e)||Object.keys(e).length===0?``:encodeURIComponent(JSON.stringify(e))}const ze=/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;function buildLikec4StyleForNode(e){let t=[];return pushStylePart(t,`likec4Description`,e.desc),pushStylePart(t,`likec4Technology`,e.tech),pushStylePart(t,`likec4Notes`,e.notes),pushStylePart(t,`likec4Tags`,e.tagList),pushStylePart(t,`likec4NavigateTo`,e.navTo),pushStylePart(t,`likec4Icon`,e.iconName),pushStylePart(t,`likec4Summary`,e.summaryStr),e.linksJson!==``&&t.push(`likec4Links=${e.linksJson}`),pushStylePart(t,`likec4Border`,e.borderVal),pushStylePartNum(t,`likec4Opacity`,e.containerOpacityNum),pushStylePart(t,`likec4StrokeWidth`,e.strokeWidth),e.colorNameForRoundtrip!==``&&t.push(`likec4ColorName=${e.colorNameForRoundtrip}`),pushStylePart(t,`likec4Size`,e.nodeStyle?.size),pushStylePart(t,`likec4Padding`,e.nodeStyle?.padding),pushStylePart(t,`likec4TextSize`,e.nodeStyle?.textSize),pushStylePart(t,`likec4IconPosition`,e.nodeStyle?.iconPosition),e.strokeHex&&ze.test(e.strokeHex)&&pushStylePart(t,`likec4StrokeColor`,e.strokeHex),pushStylePart(t,`likec4Notation`,e.nodeNotation??void 0),t.length>0?t.join(`;`)+`;`:``}function buildBridgeManagedStyleForNode(e,t,n,r){if(r?.profile!==`leanix`)return``;let i=[`bridgeManaged=true`,`likec4Id=${encodeURIComponent(e)}`,`likec4Kind=${encodeURIComponent(t)}`,`likec4ViewId=${encodeURIComponent(n)}`];r.projectId!=null&&r.projectId!==``&&i.push(`likec4ProjectId=${encodeURIComponent(r.projectId)}`);let a=r.leanixFactSheetTypeByKind?.[t];return a!=null&&a!==``&&i.push(`leanixFactSheetType=${encodeURIComponent(a)}`),i.join(`;`)+`;`}function buildBridgeManagedStyleForEdge(e,t){return t?.profile===`leanix`?`bridgeManaged=true;likec4RelationId=${encodeURIComponent(e)};`:``}function buildMxUserObjectXml(e){return!e||typeof e!=`object`||Array.isArray(e)||Object.keys(e).length===0?``:`
257
- <mxUserObject>`+Object.entries(e).map(([e,t])=>{let n=typeof t==`string`?t:t==null?``:String(t);return`<data key="${escapeXml(e)}">${escapeXml(n)}</data>`}).join(``)+`</mxUserObject>`}function buildLikec4StyleForEdge(e){let t=[];return pushStylePart(t,`likec4Description`,e.edgeDesc),pushStylePart(t,`likec4Technology`,e.edgeTech),pushStylePart(t,`likec4Notes`,e.edgeNotes),pushStylePart(t,`likec4NavigateTo`,e.edgeNavTo),pushStylePart(t,`likec4RelationshipKind`,e.edgeKind??void 0),pushStylePart(t,`likec4Notation`,e.edgeNotation??void 0),e.edgeLinksJson!==``&&t.push(`likec4Links=${e.edgeLinksJson}`),e.edgeMetadataJson!==``&&t.push(`likec4Metadata=${e.edgeMetadataJson}`),t.length>0?t.join(`;`)+`;`:``}function buildEdgeLabelValue(e){return e.label?escapeXml(e.label):``}function buildEdgeGeometryXml(e,t){let n=t?.[`${e.source}|${e.target}|${e.id}`]??t?.[`${e.source}|${e.target}`],r=Array.isArray(n)?n.flatMap(normalizeEdgePoint):[];return r.length>0?`<mxGeometry relative="1" as="geometry">${`<Array as="points">`+r.map(([e,t])=>`<mxPoint x="${Math.round(e)}" y="${Math.round(t)}"/>`).join(``)+`</Array>`}</mxGeometry>`:`<mxGeometry relative="1" as="geometry" />`}function buildEdgeStyleString(e,t,n,r,i){let{bboxes:a,fontFamily:o}=t,s=a.get(e.source),c=a.get(e.target),l=s&&c?edgeAnchors(s,c):{exitX:1,exitY:.5,entryX:0,entryY:.5},u=`exitX=${l.exitX};exitY=${l.exitY};entryX=${l.entryX};entryY=${l.entryY};`,d=getEdgeStrokeColor(n,e.color),f=e.line===`dashed`?`dashed=1;`:e.line===`dotted`?`dashed=1;dashPattern=1 1;`:``,p=drawioArrow(e.head),m=e.tail==null||e.tail===`none`?`none`:drawioArrow(e.tail),h=buildLikec4StyleForEdge({edgeDesc:toExportString(e.description),edgeTech:toExportString(e.technology),edgeNotes:toExportString(e.notes),edgeNavTo:toNonEmptyString(e.navigateTo),edgeKind:Z.getKind(e),edgeNotation:Z.getNotation(e),edgeLinksJson:linksToStyleJson(Z.getLinks(e)),edgeMetadataJson:metadataToStyleJson(Z.getMetadata(e))}),g=buildBridgeManagedStyleForEdge(e.id,i),_=getEdgeLabelColors(n,e.color);return`endArrow=${p};startArrow=${m};html=1;rounded=0;${u}strokeColor=${d};strokeWidth=2;${f}${r===``?``:`fontColor=${_.font};fontSize=12;align=center;verticalAlign=middle;labelBackgroundColor=none;fontFamily=${encodeURIComponent(o)};`}${h}${g}`}function buildEdgeCellXml(e,t,n,r,i,a){let{defaultParentId:o}=t,s=i(e.source),c=i(e.target),l=buildEdgeLabelValue(e),u=buildEdgeGeometryXml(e,n?.edgeWaypoints);return`<mxCell id="${a}" value="${l}" style="${buildEdgeStyleString(e,t,r,l,n)}" edge="1" parent="${o}" source="${s}" target="${c}">
255
+ `}}}const generateCustomizationCode=e=>e?`
256
+ import { atom, useStore } from 'likec4/vite-plugin/internal'
257
+ import components from ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e))}
258
+
259
+ export let $customComponents = atom(components)
260
+
261
+ export function useCustomComponents() {
262
+ return useStore($customComponents)
263
+ }
264
+
265
+ if (import.meta.hot) {
266
+ import.meta.hot.accept(md => {
267
+ if (!import.meta.hot.data.$update) {
268
+ import.meta.hot.data.$update = $customComponents
269
+ }
270
+ const update = md?.$customComponents
271
+ if (update) {
272
+ import.meta.hot.data.$update.set(update.get())
273
+ } else {
274
+ import.meta.hot.invalidate()
275
+ }
276
+ })
277
+ }
278
+ `:`
279
+ import { atom, useStore } from 'likec4/vite-plugin/internal'
280
+
281
+ export let $customComponents = atom(undefined)
282
+
283
+ export function useCustomComponents() {
284
+ return useStore($customComponents)
285
+ }
286
+ `,Pe={id:`likec4:customization`,virtualId:`likec4:plugin/customization.js`,async load({customizationFile:e}){return logGenerating(`customization`),{code:generateCustomizationCode(e),moduleType:`js`}}},Fe=/* @__PURE__ */ e(e=>e.charAt(0).toLocaleUpperCase()+e.slice(1),`capitalizeFirstLetter`),Ie=/* @__PURE__ */ e(e=>e.split(`.`).map(Fe).join(``),`fqnName`),d2key=e=>JSON.stringify(e),d2string=e=>JSON.stringify(e).replaceAll("${","\\${"),Le=/* @__PURE__ */ e(e=>{let t=e.parent?e.parent+`.`:``;return d2key(Ie(t&&e.id.startsWith(t)?e.id.slice(t.length):e.id))},`nodeName`),d2direction=({autoLayout:e})=>{switch(e.direction){case`TB`:return`down`;case`BT`:return`up`;case`LR`:return`right`;case`RL`:return`left`}},d2shape=({shape:e})=>{switch(e){case`queue`:case`cylinder`:case`rectangle`:case`document`:return e;case`person`:return`c4-person`;case`storage`:return`stored_data`;case`component`:case`bucket`:case`agent`:case`mobile`:case`browser`:return`rectangle`}};function generateD2(e){let t=e.$view,{nodes:n,edges:r}=t,i=/* @__PURE__ */ new Map,printNode=(e,t)=>{let r=Le(e),a=(t?t+`.`:``)+r;i.set(e.id,a);let o=d2string(e.title),s=d2shape(e);return new N().append(r,`: {`,F).indent({indentedChildren:t=>t.append(`label: `,o,F).appendIf(s!==`rectangle`,`shape: `,s,F).appendIf(e.children.length>0,F,M(n.filter(t=>t.parent===e.id),e=>printNode(e,a))),indentation:2}).append(`}`,F)},printEdge=e=>new N().append(i.get(e.source),` -> `,i.get(e.target)).append(t=>e.label&&t.append(`: `,d2string(e.label)));return P(new N().append(`direction: `,d2direction(t),F,F).append(M(n.filter(e=>x(e.parent)),e=>printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(r.length>0,F,M(r,e=>printEdge(e),{appendNewLineIfNotEmpty:!0})))}const Re=`data:page/id,likec4-`,ze=`diagrams.drawio`;function escapeXml(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&apos;`)}function parseDrawioRoundtripComments(e){let t=e.split(/\r?\n/),n={},r={},i={},a={},o=!1,s=0;for(;s<t.length;){let e=t[s];if(e==null)s+=1;else if(e.trim()===`// <likec4.layout.drawio>`){o=!0,s+=1;let e=[];for(;s<t.length&&t[s]?.trim()!==`// </likec4.layout.drawio>`;){let n=t[s]?.trim();n?.startsWith(`// `)&&e.push(n.slice(3)),s+=1}if(e.length>0)try{let t=e.join(`
287
+ `);n=JSON.parse(t)}catch{}s+=1}else if(e.trim()===`// <likec4.strokeColor.vertices>`){for(o=!0,s+=1;s<t.length&&t[s]?.trim()!==`// </likec4.strokeColor.vertices>`;){let e=t[s]?.trim();if(e?.startsWith(`// `)&&e.includes(`=`)){let t=e.slice(3).trim(),n=t.indexOf(`=`);if(n>0){let e=t.slice(0,n).trim(),i=t.slice(n+1).trim();e&&i&&(r[e]=i)}}s+=1}s+=1}else if(e.trim()===`// <likec4.strokeWidth.vertices>`){for(o=!0,s+=1;s<t.length&&t[s]?.trim()!==`// </likec4.strokeWidth.vertices>`;){let e=t[s]?.trim();if(e?.startsWith(`// `)&&e.includes(`=`)){let t=e.slice(3).trim(),n=t.indexOf(`=`);if(n>0){let e=t.slice(0,n).trim(),r=t.slice(n+1).trim();e&&r!==``&&(i[e]=r)}}s+=1}s+=1}else if(e.trim()===`// <likec4.edge.waypoints>`){for(o=!0,s+=1;s<t.length&&t[s]?.trim()!==`// </likec4.edge.waypoints>`;){let e=t[s]?.trim();if(e?.startsWith(`// `)){let t=e.slice(3).trim(),n=t.indexOf(` `);if(n>0){let e=t.slice(0,n).trim(),r=t.slice(n+1).trim();if(e&&r)try{let t=JSON.parse(r);Array.isArray(t)&&(a[e]=t)}catch{}}}s+=1}s+=1}else s+=1}return o?{layoutByView:n,strokeColorByFqn:r,strokeWidthByFqn:i,edgeWaypoints:a}:null}function compressDrawioDiagramXml(e){let t=encodeURIComponent(e),n=new TextEncoder().encode(t);return uint8ArrayToBase64(ae.deflateRaw(n))}function uint8ArrayToBase64(e){if(typeof Buffer<`u`)return Buffer.from(e).toString(`base64`);let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}const X={getNotes(e){return e.notes},getSummary(e){return e.summary},getTags(e){return e.tags},getNavigateTo(e){return e.navigateTo},getIcon(e){return e.icon},getLinks(e){return e.links},getNotation(e){return e.notation},getCustomData(e){return e.customData},getChildren(e){return e.children}},Z={getKind(e){return e.kind},getNotation(e){return e.notation},getLinks(e){return e.links},getMetadata(e){return e.metadata},getCustomData(e){return e.customData}};function getEffectiveStyles(e){return e.$styles??me.DEFAULT}function escapeHtml(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`)}function toNonEmptyString(e){if(e==null)return``;let t=typeof e;if(t===`string`){let t=e;return t.trim()===``?``:t}return t===`number`||t===`boolean`?String(e):``}function getContainerDashedStyle(e,t){return e&&t!==`none`||t===`dashed`?`dashed=1;`:``}function getDefaultStrokeWidth(e,t){return e===`none`?`0`:t||e?`1`:``}function applyStrokeColorOverride(e,t){return{fill:e?.fill??`#dae8fc`,stroke:t,font:e?.font??t}}function resolveThemeColor(e,t,n){return t&&t in e.theme.colors?t:n}function getThemeColorValues(e,t,n){let r=getEffectiveStyles(e),i=resolveThemeColor(r,t??n,n);try{return r.colors(i)}catch{return me.DEFAULT.colors(n)}}function drawioShape(e){let t=`shape=rectangle;rounded=1;arcSize=12;`;switch(e){case`person`:return`shape=actor;`;case`rectangle`:case`browser`:case`mobile`:case`bucket`:case`agent`:return t;case`cylinder`:case`queue`:case`storage`:return`shape=cylinder3;whiteSpace=wrap;boundedLbl=1;backgroundOutline=1;size=15;`;case`document`:return`shape=document;whiteSpace=wrap;html=1;boundedLbl=1;`;case`component`:return`shape=component;`;default:return t}}function getElementColors(e,t){let n=getThemeColorValues(e,t,`primary`).elements;return{fill:String(n.fill??`#dae8fc`),stroke:String(n.stroke??`#2563eb`),font:String(n.hiContrast??n.stroke??`#1e40af`)}}function getEdgeStrokeColor(e,t){let n=getThemeColorValues(e,t??`gray`,`gray`);return String(n.relationships?.line??`#1e40af`)}function getEdgeLabelColors(e,t){let n=getThemeColorValues(e,t??`gray`,`gray`).relationships;return{font:String(n?.label??n?.line??`#1e40af`),background:String(n?.labelBg??`#ffffff`)}}function edgeAnchors(e,t){let n=e.x+e.width/2,r=e.y+e.height/2,i=t.x+t.width/2,a=t.y+t.height/2,o=i-n,s=a-r,c=Math.abs(o)>=Math.abs(s);return{exitX:c?+(o>=0):.5,exitY:c?.5:+(s>=0),entryX:c?o>=0?0:1:.5,entryY:c?.5:s>=0?0:1}}function normalizeEdgePoint(e){if(Array.isArray(e)&&e.length>=2&&typeof e[0]==`number`&&typeof e[1]==`number`)return[[e[0],e[1]]];let t=e;return typeof t.x==`number`&&typeof t.y==`number`?[[t.x,t.y]]:[]}function buildNodeValueHtml(e,t,n,r,i,a){return n?``:t===``?`<div style="box-sizing:border-box;width:100%;min-height:100%;display:flex;align-items:center;justify-content:center;text-align:center;color:${r};font-family:${i};"><b style="font-size:${a}px;">${escapeHtml(e)}</b></div>`:`<div style="box-sizing:border-box;width:100%;min-height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;color:${r};font-family:${i};"><b style="font-size:${a}px;">${escapeHtml(e)}</b><br/><span style="font-weight:normal;font-size:${a}px;">${escapeHtml(t)}</span></div>`}function pushStylePart(e,t,n){n!=null&&n!==``&&e.push(`${t}=${encodeURIComponent(n)}`)}function pushStylePartNum(e,t,n){n!=null&&e.push(`${t}=${n}`)}function buildNavLinkStyle(e){return e===``?``:`link=${encodeURIComponent(`${Re}${e}`)};`}function toExportString(e,t){let n=e==null?null:pe(e);return n==null||c(n)?``:(typeof e==`object`&&e&&e.md!=null?be(n,t?.$model?.resolveMarkdownRef):n).trim()}function linksToStyleJson(e){return!Array.isArray(e)||e.length===0?``:encodeURIComponent(JSON.stringify(e.map(e=>({url:e.url,title:e.title}))))}function metadataToStyleJson(e){return typeof e!=`object`||!e||Array.isArray(e)||Object.keys(e).length===0?``:encodeURIComponent(JSON.stringify(e))}const Be=/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;function buildLikec4StyleForNode(e){let t=[];return pushStylePart(t,`likec4Description`,e.desc),pushStylePart(t,`likec4Technology`,e.tech),pushStylePart(t,`likec4Notes`,e.notes),pushStylePart(t,`likec4Tags`,e.tagList),pushStylePart(t,`likec4NavigateTo`,e.navTo),pushStylePart(t,`likec4Icon`,e.iconName),pushStylePart(t,`likec4Summary`,e.summaryStr),e.linksJson!==``&&t.push(`likec4Links=${e.linksJson}`),pushStylePart(t,`likec4Border`,e.borderVal),pushStylePartNum(t,`likec4Opacity`,e.containerOpacityNum),pushStylePart(t,`likec4StrokeWidth`,e.strokeWidth),e.colorNameForRoundtrip!==``&&t.push(`likec4ColorName=${e.colorNameForRoundtrip}`),pushStylePart(t,`likec4Size`,e.nodeStyle?.size),pushStylePart(t,`likec4Padding`,e.nodeStyle?.padding),pushStylePart(t,`likec4TextSize`,e.nodeStyle?.textSize),pushStylePart(t,`likec4IconPosition`,e.nodeStyle?.iconPosition),e.strokeHex&&Be.test(e.strokeHex)&&pushStylePart(t,`likec4StrokeColor`,e.strokeHex),pushStylePart(t,`likec4Notation`,e.nodeNotation??void 0),t.length>0?t.join(`;`)+`;`:``}function buildBridgeManagedStyleForNode(e,t,n,r){if(r?.profile!==`leanix`)return``;let i=[`bridgeManaged=true`,`likec4Id=${encodeURIComponent(e)}`,`likec4Kind=${encodeURIComponent(t)}`,`likec4ViewId=${encodeURIComponent(n)}`];r.projectId!=null&&r.projectId!==``&&i.push(`likec4ProjectId=${encodeURIComponent(r.projectId)}`);let a=r.leanixFactSheetTypeByKind?.[t];return a!=null&&a!==``&&i.push(`leanixFactSheetType=${encodeURIComponent(a)}`),i.join(`;`)+`;`}function buildBridgeManagedStyleForEdge(e,t){return t?.profile===`leanix`?`bridgeManaged=true;likec4RelationId=${encodeURIComponent(e)};`:``}function buildMxUserObjectXml(e){return!e||typeof e!=`object`||Array.isArray(e)||Object.keys(e).length===0?``:`
288
+ <mxUserObject>`+Object.entries(e).map(([e,t])=>{let n=typeof t==`string`?t:t==null?``:String(t);return`<data key="${escapeXml(e)}">${escapeXml(n)}</data>`}).join(``)+`</mxUserObject>`}function buildLikec4StyleForEdge(e){let t=[];return pushStylePart(t,`likec4Description`,e.edgeDesc),pushStylePart(t,`likec4Technology`,e.edgeTech),pushStylePart(t,`likec4Notes`,e.edgeNotes),pushStylePart(t,`likec4NavigateTo`,e.edgeNavTo),pushStylePart(t,`likec4RelationshipKind`,e.edgeKind??void 0),pushStylePart(t,`likec4Notation`,e.edgeNotation??void 0),e.edgeLinksJson!==``&&t.push(`likec4Links=${e.edgeLinksJson}`),e.edgeMetadataJson!==``&&t.push(`likec4Metadata=${e.edgeMetadataJson}`),t.length>0?t.join(`;`)+`;`:``}function buildEdgeLabelValue(e){return e.label?escapeXml(e.label):``}function buildEdgeGeometryXml(e,t){let n=t?.[`${e.source}|${e.target}|${e.id}`]??t?.[`${e.source}|${e.target}`],r=Array.isArray(n)?n.flatMap(normalizeEdgePoint):[];return r.length>0?`<mxGeometry relative="1" as="geometry">${`<Array as="points">`+r.map(([e,t])=>`<mxPoint x="${Math.round(e)}" y="${Math.round(t)}"/>`).join(``)+`</Array>`}</mxGeometry>`:`<mxGeometry relative="1" as="geometry" />`}function buildEdgeStyleString(e,t,n,r,i){let{bboxes:a,fontFamily:o}=t,s=a.get(e.source),c=a.get(e.target),l=s&&c?edgeAnchors(s,c):{exitX:1,exitY:.5,entryX:0,entryY:.5},u=`exitX=${l.exitX};exitY=${l.exitY};entryX=${l.entryX};entryY=${l.entryY};`,d=getEdgeStrokeColor(n,e.color),f=e.line===`dashed`?`dashed=1;`:e.line===`dotted`?`dashed=1;dashPattern=1 1;`:``,p=drawioArrow(e.head),m=e.tail==null||e.tail===`none`?`none`:drawioArrow(e.tail),h=buildLikec4StyleForEdge({edgeDesc:toExportString(e.description,n),edgeTech:toExportString(e.technology),edgeNotes:toExportString(e.notes,n),edgeNavTo:toNonEmptyString(e.navigateTo),edgeKind:Z.getKind(e),edgeNotation:Z.getNotation(e),edgeLinksJson:linksToStyleJson(Z.getLinks(e)),edgeMetadataJson:metadataToStyleJson(Z.getMetadata(e))}),g=buildBridgeManagedStyleForEdge(e.id,i),_=getEdgeLabelColors(n,e.color);return`endArrow=${p};startArrow=${m};html=1;rounded=0;${u}strokeColor=${d};strokeWidth=2;${f}${r===``?``:`fontColor=${_.font};fontSize=12;align=center;verticalAlign=middle;labelBackgroundColor=none;fontFamily=${encodeURIComponent(o)};`}${h}${g}`}function buildEdgeCellXml(e,t,n,r,i,a){let{defaultParentId:o}=t,s=i(e.source),c=i(e.target),l=buildEdgeLabelValue(e),u=buildEdgeGeometryXml(e,n?.edgeWaypoints);return`<mxCell id="${a}" value="${l}" style="${buildEdgeStyleString(e,t,r,l,n)}" edge="1" parent="${o}" source="${s}" target="${c}">
258
289
  ${u}${buildMxUserObjectXml(Z.getCustomData(e))}
259
- </mxCell>`}function computeNodeGeometry(e,t,n){let{bboxes:r,defaultParentId:i,nodeIdsInView:a}=t,o=n(e.id),s=r.get(e.id),{width:c,height:l}=s,u=e.parent!=null&&a.has(e.parent)?n(e.parent):i,d=e.parent==null?void 0:r.get(e.parent);return{id:o,parentId:u,x:d==null?s.x+t.offsetX:s.x-d.x,y:d==null?s.y+t.offsetY:s.y-d.y,width:c,height:l}}function computeNodeStylePartsAndValue(e,t,n,r){let{containerNodeIds:i,effectiveStyles:a,fontFamily:o,containerTitleFontSizePx:s,containerTitleColor:c}=t,l=n?.strokeColorByNodeId,u=n?.strokeWidthByNodeId,d=i.has(e.id),f=e.kind??``,p=e.title,m=toExportString(e.description),h=toExportString(e.technology),g=toExportString(X.getNotes(e)),_=X.getTags(e),v=Array.isArray(_)&&_.length>0?_.join(`,`):``,y=toNonEmptyString(X.getNavigateTo(e)),b=toNonEmptyString(X.getIcon(e)),ee=f===`actor`||e.shape===`person`,x=d?`shape=rectangle;rounded=0;container=1;collapsible=0;startSize=0;`:ee?`shape=actor;`:drawioShape(e.shape),S=l?.[e.id],te=u?.[e.id],C=S?applyStrokeColorOverride(getElementColors(r,e.color),S):getElementColors(r,e.color),ne=C?.fill??`#dae8fc`,w=C?.stroke??`#2563eb`,T=C?.font??C?.stroke??`#1e40af`,E=`fillColor=${ne};strokeColor=${w};fontColor=${T};`,D=e.style,O=a.fontSize(D?.textSize),k=escapeXml(buildNodeValueHtml(p,m,d,T,o,O)),A=D?.border,j=te??getDefaultStrokeWidth(A,d),re=j===``?``:`strokeWidth=${j};`,M=getContainerDashedStyle(d,A),N=d===!0?D?.opacity??15:void 0,P=N!=null&&d===!0?`fillOpacity=${Math.min(100,Math.max(0,N))};`:``,F=buildLikec4StyleForNode({desc:m,tech:h,notes:g,tagList:v,navTo:y,iconName:b,summaryStr:toExportString(X.getSummary(e)),linksJson:linksToStyleJson(X.getLinks(e)),borderVal:A,containerOpacityNum:N,strokeWidth:j,colorNameForRoundtrip:e.color?encodeURIComponent(String(e.color)):``,nodeStyle:D,strokeHex:w,nodeNotation:X.getNotation(e)})+buildBridgeManagedStyleForNode(e.id,f,t.view.id,n),I=buildMxUserObjectXml(X.getCustomData(e)),ie=buildNavLinkStyle(y);return{value:k,styleStr:`${d?`align=left;verticalAlign=top;overflow=fill;whiteSpace=wrap;html=1;`:`align=center;verticalAlign=middle;verticalLabelPosition=middle;labelPosition=center;fontSize=${O};fontStyle=1;spacingTop=4;spacingLeft=2;spacingRight=2;spacingBottom=2;overflow=fill;whiteSpace=wrap;html=1;fontFamily=${encodeURIComponent(o)};`}${x}${E}${re}${M}${P}${ie}${F}`,userObjectXml:I,navTo:y,isContainer:d,title:p,fontFamily:o,containerTitleFontSizePx:s,containerTitleColor:c}}function computeNodeCellExportData(e,t,n,r,i,a){let o=computeNodeGeometry(e,t,i),s=computeNodeStylePartsAndValue(e,t,n,r);return{...o,value:s.value,styleStr:s.styleStr,userObjectXml:s.userObjectXml,navTo:s.navTo,isContainer:s.isContainer,fontFamily:s.fontFamily,...s.isContainer&&{title:s.title??``,titleCellId:String(a),containerTitleFontSizePx:s.containerTitleFontSizePx,containerTitleColor:s.containerTitleColor}}}function buildNodeCellXml(e){let t=`<mxGeometry height="${Math.round(e.height)}" width="${Math.round(e.width)}" x="${Math.round(e.x)}" y="${Math.round(e.y)}" as="geometry" />`,n=e.userObjectXml===``?`\n ${t}`:`${e.userObjectXml}\n ${t}`,r=e.isContainer&&e.title!=null?escapeXml(e.title):e.value,i=e.navTo===``?`<mxCell id="${e.id}" value="${e.value}" style="${e.styleStr}" vertex="1" parent="${e.parentId}">\n ${n}\n</mxCell>`:`<UserObject label="${r}" link="${Le}${escapeXml(e.navTo)}" id="${e.id}">\n <mxCell parent="${e.parentId}" style="${e.styleStr}" value="${e.value}" vertex="1">\n ${n}\n</mxCell>\n</UserObject>`;return e.isContainer?{vertexXml:i,titleCellXml:buildContainerTitleCellXml(e.title??``,e.titleCellId??e.id,e.navTo,e.id,e.fontFamily,e.containerTitleFontSizePx??12,e.containerTitleColor??`#74c0fc`),isContainer:!0}:{vertexXml:i,isContainer:!1}}function buildContainerTitleCellXml(e,t,n,r,i,a,o){let s=escapeXml(e),c=Math.max(60,Math.min(260,e.length*8)),l=buildNavLinkStyle(n),u=`shape=text;html=1;fillColor=none;strokeColor=none;align=left;verticalAlign=top;fontSize=${a};fontStyle=1;fontColor=${o};fontFamily=${encodeURIComponent(i)};${l}`;if(n===``)return`<mxCell id="${t}" value="${s}" style="${u}" vertex="1" parent="${r}">\n <mxGeometry x="8" y="8" width="${c}" height="18" as="geometry" />\n</mxCell>`;let d=`<mxCell parent="${r}" style="${u}" value="${s}" vertex="1">\n <mxGeometry x="8" y="8" width="${c}" height="18" as="geometry" />\n</mxCell>`;return`<UserObject label="${escapeXml(e)}" link="${Le}${escapeXml(n)}" id="${t}">\n ${d}\n</UserObject>`}function getViewTitle(e){return typeof e.title==`string`?e.title:null}function getViewDescriptionString(e){let t=e.description;return typeof t==`object`&&t&&`txt`in t?String(t.txt):typeof t==`object`&&t&&`md`in t?String(t.md):typeof t==`string`?t:``}function getLeanixRootStyleParts(e,t){let n=[`bridgeManaged=true;`,`likec4ViewId=${encodeURIComponent(e.id)};`];return t.projectId!=null&&t.projectId!==``&&n.push(`likec4ProjectId=${encodeURIComponent(t.projectId)};`),n}function buildRootCellStyle(e,t){let n=getViewTitle(e),r=getViewDescriptionString(e),i=r.trim()===``?``:encodeURIComponent(r.trim()),a=e.notation,o=typeof a==`string`&&a!==``?a:void 0,s=o==null?``:encodeURIComponent(o),c=[`rounded=1;whiteSpace=wrap;html=1;fillColor=none;strokeColor=none;`,`likec4ViewTitle=${encodeURIComponent(n??e.id)};`,i===``?``:`likec4ViewDescription=${i};`,s===``?``:`likec4ViewNotation=${s};`];return t?.profile===`leanix`&&c.push(...getLeanixRootStyleParts(e,t)),c.join(``)}function drawioArrow(e){switch(e){case`none`:return`none`;case`open`:case`onormal`:case`vee`:return`open`;case`diamond`:case`odiamond`:return`diamond`;case`dot`:case`odot`:return`oval`;case`crow`:return`block`;default:return`block`}}const Q={x:0,y:0,width:120,height:60};function isDefaultBbox(e){return e.x===Q.x&&e.y===Q.y&&e.width===Q.width&&e.height===Q.height}function spreadUnlaidNodesOverVertical(e,t,n){let bboxKey=e=>`${e.x},${e.y},${e.width},${e.height}`,r=t.filter(e=>!n.has(e.id)),i=new Map;for(let t of r){let n=e.get(t.id);if(!n)continue;let r=bboxKey(n),a=i.get(r)??[];a.push(t),i.set(r,a)}for(let t of i.values()){if(t.length<=1)continue;let n=t[0],r=n?e.get(n.id):void 0;r&&isDefaultBbox(r)&&t.forEach((t,n)=>{e.set(t.id,{...r,x:r.x,y:r.y+n*(r.height+24)})})}}function computeContainerBboxesFromChildren(e,t,n,r,i,a){let o=[...n].filter(e=>t.has(e.id)).sort((e,t)=>(t.level??0)-(e.level??0));for(let t of o){let n=(X.getChildren(t)??[]).filter(e=>r.has(e));if(n.length===0||!isDefaultBbox(e.get(t.id)))continue;let o=1/0,s=1/0,c=-1/0,l=-1/0;for(let t of n){let n=e.get(t);n&&(o=Math.min(o,n.x),s=Math.min(s,n.y),c=Math.max(c,n.x+n.width),l=Math.max(l,n.y+n.height))}o!==1/0&&e.set(t.id,{x:o-i,y:s-a,width:c-o+2*i,height:l-s+2*a})}}function computeContentBoundsAndOffsets(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e.values())t=Math.min(t,a.x),n=Math.min(n,a.y),r=Math.max(r,a.x+a.width),i=Math.max(i,a.y+a.height);t===1/0&&(t=0),n===1/0&&(n=0),r===-1/0&&(r=t+800),i===-1/0&&(i=n+600);let a=t+(r-t)/2,o=n+(i-n)/2;return{offsetX:400-a,offsetY:300-o,canvasWidth:800,canvasHeight:600}}function computeDiagramLayout(e,t){let n=e.$view,{nodes:r}=n,i=t?.layoutOverride,a=[...r].sort((e,t)=>M(e.parent)&&M(t.parent)?0:M(e.parent)?-1:M(t.parent)?1:e.parent===t.parent?0:e.id.startsWith(t.id+`.`)?1:t.id.startsWith(e.id+`.`)?-1:0),getBBox=e=>{let t=i?.[e.id];if(t)return t;let n=e;return{x:typeof n.x==`number`?n.x:Array.isArray(n.position)?n.position[0]:0,y:typeof n.y==`number`?n.y:Array.isArray(n.position)?n.position[1]:0,width:typeof n.width==`number`?n.width:n.size?.width??120,height:typeof n.height==`number`?n.height:n.size?.height??60}},o=new Map;for(let e of a)o.set(e.id,getBBox(e));let s=new Set(r.map(e=>e.id)),c=new Set(r.filter(e=>{let t=X.getChildren(e);return Array.isArray(t)&&t.some(e=>s.has(e))}).map(e=>e.id));spreadUnlaidNodesOverVertical(o,a,c);let l=getEffectiveStyles(e),u=l.theme.spacing.xl;computeContainerBboxesFromChildren(o,c,a,s,u,l.theme.spacing.xl+l.theme.spacing.md);let{offsetX:d,offsetY:f,canvasWidth:p,canvasHeight:m}=computeContentBoundsAndOffsets(o);return{view:n,bboxes:o,containerNodeIds:c,sortedNodes:a,offsetX:d,offsetY:f,canvasWidth:p,canvasHeight:m,defaultParentId:`1`,rootId:`0`,effectiveStyles:l,fontFamily:`'IBM Plex Sans Variable',ui-sans-serif,system-ui,sans-serif`,containerTitleFontSizePx:Math.round(l.theme.textSizes.xs),containerTitleColor:`#74c0fc`,nodeIdsInView:s}}function generateDiagramContent(e,t){let n=e.$view,{edges:r}=n,i=t?.compressed!==!1,a=computeDiagramLayout(e,t),{sortedNodes:o,defaultParentId:s,rootId:c,canvasWidth:l,canvasHeight:u}=a,d=new Map,f=2,getCellId=e=>{let t=d.get(e);if(!t){if(f>=1e4)throw Error(`DrawIO cell ID range exhausted`);t=String(f++),d.set(e,t)}return t},p=[],m=[],h=[],g=1e4;for(let n of o){let r=buildNodeCellXml(computeNodeCellExportData(n,a,t,e,getCellId,g));r.isContainer?(p.push(r.vertexXml),r.titleCellXml&&p.push(r.titleCellXml),g++):m.push(r.vertexXml)}for(let n of r){if(f>=1e4)throw Error(`DrawIO cell ID range exhausted`);let r=String(f++);h.push(buildEdgeCellXml(n,a,t,e,getCellId,r))}let _=[`<mxCell id="${s}" value="" style="${buildRootCellStyle(n,t)}" vertex="1" parent="${c}">
290
+ </mxCell>`}function computeNodeGeometry(e,t,n){let{bboxes:r,defaultParentId:i,nodeIdsInView:a}=t,o=n(e.id),s=r.get(e.id),{width:c,height:l}=s,u=e.parent!=null&&a.has(e.parent)?n(e.parent):i,d=e.parent==null?void 0:r.get(e.parent);return{id:o,parentId:u,x:d==null?s.x+t.offsetX:s.x-d.x,y:d==null?s.y+t.offsetY:s.y-d.y,width:c,height:l}}function computeNodeStylePartsAndValue(e,t,n,r){let{containerNodeIds:i,effectiveStyles:a,fontFamily:o,containerTitleFontSizePx:s,containerTitleColor:c}=t,l=n?.strokeColorByNodeId,u=n?.strokeWidthByNodeId,d=i.has(e.id),f=e.kind??``,p=e.title,m=toExportString(e.description,r),h=toExportString(e.technology),g=toExportString(X.getNotes(e),r),_=X.getTags(e),v=Array.isArray(_)&&_.length>0?_.join(`,`):``,y=toNonEmptyString(X.getNavigateTo(e)),b=toNonEmptyString(X.getIcon(e)),x=f===`actor`||e.shape===`person`,S=d?`shape=rectangle;rounded=0;container=1;collapsible=0;startSize=0;`:x?`shape=actor;`:drawioShape(e.shape),C=l?.[e.id],w=u?.[e.id],T=C?applyStrokeColorOverride(getElementColors(r,e.color),C):getElementColors(r,e.color),E=T?.fill??`#dae8fc`,ee=T?.stroke??`#2563eb`,te=T?.font??T?.stroke??`#1e40af`,ne=`fillColor=${E};strokeColor=${ee};fontColor=${te};`,D=e.style,re=a.fontSize(D?.textSize),O=escapeXml(buildNodeValueHtml(p,m,d,te,o,re)),k=D?.border,A=w??getDefaultStrokeWidth(k,d),j=A===``?``:`strokeWidth=${A};`,M=getContainerDashedStyle(d,k),N=d===!0?D?.opacity??15:void 0,P=N!=null&&d===!0?`fillOpacity=${Math.min(100,Math.max(0,N))};`:``,F=buildLikec4StyleForNode({desc:m,tech:h,notes:g,tagList:v,navTo:y,iconName:b,summaryStr:toExportString(X.getSummary(e),r),linksJson:linksToStyleJson(X.getLinks(e)),borderVal:k,containerOpacityNum:N,strokeWidth:A,colorNameForRoundtrip:e.color?encodeURIComponent(String(e.color)):``,nodeStyle:D,strokeHex:ee,nodeNotation:X.getNotation(e)})+buildBridgeManagedStyleForNode(e.id,f,t.view.id,n),ie=buildMxUserObjectXml(X.getCustomData(e)),ae=buildNavLinkStyle(y);return{value:O,styleStr:`${d?`align=left;verticalAlign=top;overflow=fill;whiteSpace=wrap;html=1;`:`align=center;verticalAlign=middle;verticalLabelPosition=middle;labelPosition=center;fontSize=${re};fontStyle=1;spacingTop=4;spacingLeft=2;spacingRight=2;spacingBottom=2;overflow=fill;whiteSpace=wrap;html=1;fontFamily=${encodeURIComponent(o)};`}${S}${ne}${j}${M}${P}${ae}${F}`,userObjectXml:ie,navTo:y,isContainer:d,title:p,fontFamily:o,containerTitleFontSizePx:s,containerTitleColor:c}}function computeNodeCellExportData(e,t,n,r,i,a){let o=computeNodeGeometry(e,t,i),s=computeNodeStylePartsAndValue(e,t,n,r);return{...o,value:s.value,styleStr:s.styleStr,userObjectXml:s.userObjectXml,navTo:s.navTo,isContainer:s.isContainer,fontFamily:s.fontFamily,...s.isContainer&&{title:s.title??``,titleCellId:String(a),containerTitleFontSizePx:s.containerTitleFontSizePx,containerTitleColor:s.containerTitleColor}}}function buildNodeCellXml(e){let t=`<mxGeometry height="${Math.round(e.height)}" width="${Math.round(e.width)}" x="${Math.round(e.x)}" y="${Math.round(e.y)}" as="geometry" />`,n=e.userObjectXml===``?`\n ${t}`:`${e.userObjectXml}\n ${t}`,r=e.isContainer&&e.title!=null?escapeXml(e.title):e.value,i=e.navTo===``?`<mxCell id="${e.id}" value="${e.value}" style="${e.styleStr}" vertex="1" parent="${e.parentId}">\n ${n}\n</mxCell>`:`<UserObject label="${r}" link="${Re}${escapeXml(e.navTo)}" id="${e.id}">\n <mxCell parent="${e.parentId}" style="${e.styleStr}" value="${e.value}" vertex="1">\n ${n}\n</mxCell>\n</UserObject>`;return e.isContainer?{vertexXml:i,titleCellXml:buildContainerTitleCellXml(e.title??``,e.titleCellId??e.id,e.navTo,e.id,e.fontFamily,e.containerTitleFontSizePx??12,e.containerTitleColor??`#74c0fc`),isContainer:!0}:{vertexXml:i,isContainer:!1}}function buildContainerTitleCellXml(e,t,n,r,i,a,o){let s=escapeXml(e),c=Math.max(60,Math.min(260,e.length*8)),l=buildNavLinkStyle(n),u=`shape=text;html=1;fillColor=none;strokeColor=none;align=left;verticalAlign=top;fontSize=${a};fontStyle=1;fontColor=${o};fontFamily=${encodeURIComponent(i)};${l}`;if(n===``)return`<mxCell id="${t}" value="${s}" style="${u}" vertex="1" parent="${r}">\n <mxGeometry x="8" y="8" width="${c}" height="18" as="geometry" />\n</mxCell>`;let d=`<mxCell parent="${r}" style="${u}" value="${s}" vertex="1">\n <mxGeometry x="8" y="8" width="${c}" height="18" as="geometry" />\n</mxCell>`;return`<UserObject label="${escapeXml(e)}" link="${Re}${escapeXml(n)}" id="${t}">\n ${d}\n</UserObject>`}function getViewTitle(e){return typeof e.title==`string`?e.title:null}function getViewDescriptionString(e){let t=e.$view.description;return typeof t==`object`&&t&&`txt`in t?String(t.txt):typeof t==`object`&&t&&`md`in t?be(String(t.md),e.$model?.resolveMarkdownRef):typeof t==`string`?t:``}function getLeanixRootStyleParts(e,t){let n=[`bridgeManaged=true;`,`likec4ViewId=${encodeURIComponent(e.id)};`];return t.projectId!=null&&t.projectId!==``&&n.push(`likec4ProjectId=${encodeURIComponent(t.projectId)};`),n}function buildRootCellStyle(e,t){let n=e.$view,r=getViewTitle(n),i=getViewDescriptionString(e),a=i.trim()===``?``:encodeURIComponent(i.trim()),o=n.notation,s=typeof o==`string`&&o!==``?o:void 0,c=s==null?``:encodeURIComponent(s),l=[`rounded=1;whiteSpace=wrap;html=1;fillColor=none;strokeColor=none;`,`likec4ViewTitle=${encodeURIComponent(r??n.id)};`,a===``?``:`likec4ViewDescription=${a};`,c===``?``:`likec4ViewNotation=${c};`];return t?.profile===`leanix`&&l.push(...getLeanixRootStyleParts(n,t)),l.join(``)}function drawioArrow(e){switch(e){case`none`:return`none`;case`open`:case`onormal`:case`vee`:return`open`;case`diamond`:case`odiamond`:return`diamond`;case`dot`:case`odot`:return`oval`;case`crow`:return`block`;default:return`block`}}const Q={x:0,y:0,width:120,height:60};function isDefaultBbox(e){return e.x===Q.x&&e.y===Q.y&&e.width===Q.width&&e.height===Q.height}function spreadUnlaidNodesOverVertical(e,t,n){let bboxKey=e=>`${e.x},${e.y},${e.width},${e.height}`,r=t.filter(e=>!n.has(e.id)),i=/* @__PURE__ */ new Map;for(let t of r){let n=e.get(t.id);if(!n)continue;let r=bboxKey(n),a=i.get(r)??[];a.push(t),i.set(r,a)}for(let t of i.values()){if(t.length<=1)continue;let n=t[0],r=n?e.get(n.id):void 0;r&&isDefaultBbox(r)&&t.forEach((t,n)=>{e.set(t.id,{...r,x:r.x,y:r.y+n*(r.height+24)})})}}function computeContainerBboxesFromChildren(e,t,n,r,i,a){let o=[...n].filter(e=>t.has(e.id)).sort((e,t)=>(t.level??0)-(e.level??0));for(let t of o){let n=(X.getChildren(t)??[]).filter(e=>r.has(e));if(n.length===0||!isDefaultBbox(e.get(t.id)))continue;let o=1/0,s=1/0,c=-1/0,l=-1/0;for(let t of n){let n=e.get(t);n&&(o=Math.min(o,n.x),s=Math.min(s,n.y),c=Math.max(c,n.x+n.width),l=Math.max(l,n.y+n.height))}o!==1/0&&e.set(t.id,{x:o-i,y:s-a,width:c-o+2*i,height:l-s+2*a})}}function computeContentBoundsAndOffsets(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e.values())t=Math.min(t,a.x),n=Math.min(n,a.y),r=Math.max(r,a.x+a.width),i=Math.max(i,a.y+a.height);t===1/0&&(t=0),n===1/0&&(n=0),r===-1/0&&(r=t+800),i===-1/0&&(i=n+600);let a=t+(r-t)/2,o=n+(i-n)/2;return{offsetX:400-a,offsetY:300-o,canvasWidth:800,canvasHeight:600}}function computeDiagramLayout(e,t){let n=e.$view,{nodes:r}=n,i=t?.layoutOverride,a=[...r].sort((e,t)=>x(e.parent)&&x(t.parent)?0:x(e.parent)?-1:x(t.parent)?1:e.parent===t.parent?0:e.id.startsWith(t.id+`.`)?1:t.id.startsWith(e.id+`.`)?-1:0),getBBox=e=>{let t=i?.[e.id];if(t)return t;let n=e;return{x:typeof n.x==`number`?n.x:Array.isArray(n.position)?n.position[0]:0,y:typeof n.y==`number`?n.y:Array.isArray(n.position)?n.position[1]:0,width:typeof n.width==`number`?n.width:n.size?.width??120,height:typeof n.height==`number`?n.height:n.size?.height??60}},o=/* @__PURE__ */ new Map;for(let e of a)o.set(e.id,getBBox(e));let s=new Set(r.map(e=>e.id)),c=new Set(r.filter(e=>{let t=X.getChildren(e);return Array.isArray(t)&&t.some(e=>s.has(e))}).map(e=>e.id));spreadUnlaidNodesOverVertical(o,a,c);let l=getEffectiveStyles(e),u=l.theme.spacing.xl;computeContainerBboxesFromChildren(o,c,a,s,u,l.theme.spacing.xl+l.theme.spacing.md);let{offsetX:d,offsetY:f,canvasWidth:p,canvasHeight:m}=computeContentBoundsAndOffsets(o);return{view:n,bboxes:o,containerNodeIds:c,sortedNodes:a,offsetX:d,offsetY:f,canvasWidth:p,canvasHeight:m,defaultParentId:`1`,rootId:`0`,effectiveStyles:l,fontFamily:`'IBM Plex Sans Variable',ui-sans-serif,system-ui,sans-serif`,containerTitleFontSizePx:Math.round(l.theme.textSizes.xs),containerTitleColor:`#74c0fc`,nodeIdsInView:s}}function generateDiagramContent(e,t){let n=e.$view,{edges:r}=n,i=t?.compressed!==!1,a=computeDiagramLayout(e,t),{sortedNodes:o,defaultParentId:s,rootId:c,canvasWidth:l,canvasHeight:u}=a,d=/* @__PURE__ */ new Map,f=2,getCellId=e=>{let t=d.get(e);if(!t){if(f>=1e4)throw Error(`DrawIO cell ID range exhausted`);t=String(f++),d.set(e,t)}return t},p=[],m=[],h=[],g=1e4;for(let n of o){let r=buildNodeCellXml(computeNodeCellExportData(n,a,t,e,getCellId,g));r.isContainer?(p.push(r.vertexXml),r.titleCellXml&&p.push(r.titleCellXml),g++):m.push(r.vertexXml)}for(let n of r){if(f>=1e4)throw Error(`DrawIO cell ID range exhausted`);let r=String(f++);h.push(buildEdgeCellXml(n,a,t,e,getCellId,r))}let _=[`<mxCell id="${s}" value="" style="${buildRootCellStyle(e,t)}" vertex="1" parent="${c}">
260
291
  <mxGeometry x="0" y="0" width="${l}" height="${u}" as="geometry" />
261
292
  </mxCell>`,...p,...m,...h].join(`
262
293
  `),v=(getViewTitle(n)??n.id).trim()||n.id,y=`<mxGraphModel dx="800" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
@@ -264,7 +295,7 @@ export let krokiPumlSvgUrl = import.meta.env.VITE_KROKI_D2_SVG_URL || 'https://k
264
295
  <mxCell id="${c}" />
265
296
  ${_}
266
297
  </root>
267
- </mxGraphModel>`,b=i?compressDrawioDiagramXml(y):y;return{name:v,id:n.id,content:b}}function wrapInMxFile(e,t){let n=escapeXml(t??new Date().toISOString());return e.length===0?`<?xml version="1.0" encoding="UTF-8"?>
298
+ </mxGraphModel>`,b=i?compressDrawioDiagramXml(y):y;return{name:v,id:n.id,content:b}}function wrapInMxFile(e,t){let n=escapeXml(t??(/* @__PURE__ */ new Date()).toISOString());return e.length===0?`<?xml version="1.0" encoding="UTF-8"?>
268
299
  <mxfile host="LikeC4" modified="${n}" agent="LikeC4" version="1.0" etag="" type="device">
269
300
  </mxfile>
270
301
  `:`<?xml version="1.0" encoding="UTF-8"?>
@@ -272,8 +303,8 @@ export let krokiPumlSvgUrl = import.meta.env.VITE_KROKI_D2_SVG_URL || 'https://k
272
303
  ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}">${e.content}</diagram>`).join(`
273
304
  `)}
274
305
  </mxfile>
275
- `}function generateDrawio(e,t){return wrapInMxFile([generateDiagramContent(e,t)],t?.modified)}function generateDrawioMulti(e,t,n){return wrapInMxFile(e.map(e=>generateDiagramContent(e,t?.[e.$view.id])),n)}function buildOptionsFromRoundtrip(e,t,n){let r={compressed:!1,...n};if(!t)return r;let i=t.layoutByView[e]?.nodes;return i!=null&&(r.layoutOverride=i),Object.keys(t.strokeColorByFqn).length>0&&(r.strokeColorByNodeId=t.strokeColorByFqn),Object.keys(t.strokeWidthByFqn).length>0&&(r.strokeWidthByNodeId=t.strokeWidthByFqn),Object.keys(t.edgeWaypoints).length>0&&(r.edgeWaypoints=t.edgeWaypoints),r}function buildDrawioExportOptionsForViews(e,t,n){let r=t?parseDrawioRoundtripComments(t):null;return Object.fromEntries(e.map(e=>[e,buildOptionsFromRoundtrip(e,r,n)]))}function generateDrawioEditUrl(e){let t=compressDrawioDiagramXml(e),n=JSON.stringify({type:`xml`,compressed:!0,data:t});return`https://app.diagrams.net/#create=`+encodeURIComponent(n)}const Be=e(e=>e.charAt(0).toLocaleUpperCase()+e.slice(1),`capitalizeFirstLetter`),safeChars=e=>e.replace(/\W/g,`_`),Ve=e(e=>e.split(`.`).map(safeChars).map(Be).join(``),`fqnName`),He=e(e=>{let t=e.parent?e.parent+`.`:``;return Ve(t&&e.id.startsWith(t)?e.id.slice(t.length):e.id)},`nodeName`),toSingleQuotes=e=>e.replace(/\\?"/g,`'`),mmdshape=({shape:e,title:t})=>{let n=`label: ${JSON.stringify(t)}`;switch(e){case`queue`:return`@{ shape: horizontal-cylinder, ${n} }`;case`person`:return`@{ icon: "fa:user", shape: rounded, ${n} }`;case`storage`:return`@{ shape: disk, ${n} }`;case`cylinder`:return`@{ shape: cylinder, ${n} }`;case`mobile`:case`browser`:return`@{ shape: rounded, ${n} }`;case`bucket`:return`@{ shape: trap-t, ${n} }`;case`rectangle`:return`@{ shape: rectangle, ${n} }`;case`document`:return`@{ shape: doc, ${n} }`;case`component`:return`@{ shape: rectangle, ${n} }`;default:ye(e)}};function generateMermaid(e){let t=e.$view,{nodes:n,edges:a}=t,o=new Map,printNode=(e,t)=>{let r=He(e),a=(t?t+`.`:``)+r;o.set(e.id,a);let s=new u;if(e.children.length>0){let t=toSingleQuotes(e.title);s.append(`subgraph `,a,'["`',t,'`"]',i).indent({indentedChildren:[d(n.filter(t=>t.parent===e.id),e=>printNode(e,a),{appendNewLineIfNotEmpty:!0})],indentation:2}).append(`end`,i)}else s.append(a,mmdshape(e));return s},printEdge=e=>new u().append(o.get(e.source),` -.`,e.label?' "`'+toSingleQuotes(e.label)+'`" .-':`-`,`> `,o.get(e.target));return r(new u().append(`---`,i,`title: ${JSON.stringify(toSingleQuotes(e.titleOrId))}`,i,`---`,i).append(`graph `,t.autoLayout.direction,i).indent({indentedChildren:e=>{e.append(d(n.filter(e=>M(e.parent)),e=>printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(a.length>0,d(a,e=>printEdge(e),{appendNewLineIfNotEmpty:!0}))},indentation:2}))}const capitalizeFirstLetter=e=>e.charAt(0).toLocaleUpperCase()+e.slice(1),fqnName=e=>e.split(/[.-]/).map(capitalizeFirstLetter).join(``),nodeName=e=>fqnName(e.parent?e.id.slice(e.parent.length+1):e.id),pumlColor=(e,t,n=`#3b82f6`)=>e?t(e)??n:n,pumlDirection=({autoLayout:e})=>{switch(e.direction){case`TB`:return`top to bottom`;case`BT`:return console.warn(`Bottom to top direction is not supported. Defaulting to top to bottom.`),`top to bottom`;case`LR`:return`left to right`;case`RL`:return console.warn(`Right to left direction is not supported. Defaulting to left to right.`),`left to right`}},pumlShape=({shape:e})=>{switch(e){case`queue`:case`rectangle`:case`person`:return e;case`storage`:case`cylinder`:return`database`;case`component`:return`component`;case`document`:case`mobile`:case`bucket`:case`browser`:return`rectangle`;default:ye(e)}},escapeLabel=e=>E(e)?null:JSON.stringify(e).slice(1,-1).replace(/\\"/g,`"`);function generatePuml(e){let t=e.$view,n=e.$model.$styles.theme.colors,{nodes:a,edges:o}=t,elementColorProvider=e=>t=>t in n?n[t].elements[e]:void 0,relationshipsColorProvider=e=>t=>t in n?n[t].relationships[e]:void 0,s=new Map,printHeader=()=>new u().append(`title "`,e.titleOrId,`"`,i).append(pumlDirection(t),` direction`,i),printTheme=()=>new u().append(`hide stereotype`,i).append(`skinparam ranksep `,`60`,i).append(`skinparam nodesep `,`30`,i).append(`skinparam {`,i).indent({indentedChildren:e=>e.append(`arrowFontSize `,`10`,i).append(`defaultTextAlignment `,`center`,i).append(`wrapWidth `,`200`,i).append(`maxMessageSize `,`100`,i).append(`shadowing `,`false`,i),indentation:2}).append(`}`,i),printStereotypes=e=>{let t=pumlShape(e),n=fqnName(e.id);return new u().append(`skinparam `,t,`<<`,n,`>>`,`{`,i).indent({indentedChildren:t=>t.append(`BackgroundColor `,pumlColor(e.color,elementColorProvider(`fill`)),i).append(`FontColor `,pumlColor(e.color,elementColorProvider(`hiContrast`),`#FFFFFF`),i).append(`BorderColor `,pumlColor(e.color,elementColorProvider(`stroke`)),i),indentation:2}).append(`}`,i)},printNode=e=>{let t=pumlShape(e),n=fqnName(e.id),r=escapeLabel(e.title)||nodeName(e),a=escapeLabel(e.technology);s.set(e.id,n);let o=me.from(e.description);return new u().append(t,` `).append(`"`).append(`==`,r).appendIf(!!a,`\\n<size:10>[`,a,`]</size>`).appendIf(o.nonEmpty,`\\n\\n`,escapeLabel(o.text)).append(`"`,` <<`,n,`>> `,`as `,n,i)},printBoundary=e=>{let t=escapeLabel(e.title)||nodeName(e),n=fqnName(e.id);return s.set(e.id,n),new u().append(`rectangle "`,t,`" <<`,n,`>> as `,n,` {`,i).indent({indentedChildren:t=>t.append(`skinparam `,`RectangleBorderColor<<`,n,`>> `,pumlColor(e.color,elementColorProvider(`fill`)),i).append(`skinparam `,`RectangleFontColor<<`,n,`>> `,pumlColor(e.color,elementColorProvider(`fill`)),i).append(`skinparam `,`RectangleBorderStyle<<`,n,`>> `,`dashed`,i,i).append(d(a.filter(t=>t.parent===e.id),e=>e.children.length>0?printBoundary(e):printNode(e))),indentation:2}).append(`}`,i)},printEdge=e=>{let t=e.technology||``,n=e.label||t,r=pumlColor(e.color,relationshipsColorProvider(`line`),`#777777`),withColor=e=>`<color:${r}>${e.replaceAll(`"`,`'`)}`,a=new u().append(s.get(e.source),` .[`,r,`,thickness=2].> `,s.get(e.target));return(n||t)&&(a.append(` : `,n.split(`
276
- `).map(e=>E(e)?e:withColor(e)).join(`\\n`)),t&&t!==n&&a.append(`\\n<size:8>[`,withColor(t),`]</size>`)),a.append(i)};return r(new u().append(`@startuml`,i).append(printHeader(),i).append(printTheme(),i).append(d(a.filter(e=>e.children.length==0),e=>printStereotypes(e),{appendNewLineIfNotEmpty:!0})).append(d(a.filter(e=>M(e.parent)),e=>e.children.length>0?printBoundary(e):printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(o.length>0,i,d(o,e=>printEdge(e),{appendNewLineIfNotEmpty:!0})).append(`@enduml`,i))}function code$8(e){let t=new u;return t.appendTemplate`
306
+ `}function generateDrawio(e,t){return wrapInMxFile([generateDiagramContent(e,t)],t?.modified)}function generateDrawioMulti(e,t,n){return wrapInMxFile(e.map(e=>generateDiagramContent(e,t?.[e.$view.id])),n)}function buildOptionsFromRoundtrip(e,t,n){let r={compressed:!1,...n};if(!t)return r;let i=t.layoutByView[e]?.nodes;return i!=null&&(r.layoutOverride=i),Object.keys(t.strokeColorByFqn).length>0&&(r.strokeColorByNodeId=t.strokeColorByFqn),Object.keys(t.strokeWidthByFqn).length>0&&(r.strokeWidthByNodeId=t.strokeWidthByFqn),Object.keys(t.edgeWaypoints).length>0&&(r.edgeWaypoints=t.edgeWaypoints),r}function buildDrawioExportOptionsForViews(e,t,n){let r=t?parseDrawioRoundtripComments(t):null;return Object.fromEntries(e.map(e=>[e,buildOptionsFromRoundtrip(e,r,n)]))}function generateDrawioEditUrl(e){let t=compressDrawioDiagramXml(e),n=JSON.stringify({type:`xml`,compressed:!0,data:t});return`https://app.diagrams.net/#create=`+encodeURIComponent(n)}const Ve=/* @__PURE__ */ e(e=>e.charAt(0).toLocaleUpperCase()+e.slice(1),`capitalizeFirstLetter`),safeChars=e=>e.replace(/\W/g,`_`),He=/* @__PURE__ */ e(e=>e.split(`.`).map(safeChars).map(Ve).join(``),`fqnName`),Ue=/* @__PURE__ */ e(e=>{let t=e.parent?e.parent+`.`:``;return He(t&&e.id.startsWith(t)?e.id.slice(t.length):e.id)},`nodeName`),toSingleQuotes=e=>e.replace(/\\?"/g,`'`),mmdshape=({shape:e,title:t})=>{let n=`label: ${JSON.stringify(t)}`;switch(e){case`queue`:return`@{ shape: horizontal-cylinder, ${n} }`;case`person`:return`@{ icon: "fa:user", shape: rounded, ${n} }`;case`storage`:return`@{ shape: disk, ${n} }`;case`cylinder`:return`@{ shape: cylinder, ${n} }`;case`mobile`:case`browser`:return`@{ shape: rounded, ${n} }`;case`bucket`:return`@{ shape: trap-t, ${n} }`;case`rectangle`:return`@{ shape: rectangle, ${n} }`;case`document`:return`@{ shape: doc, ${n} }`;case`agent`:case`component`:return`@{ shape: rectangle, ${n} }`;default:_e(e)}},mmdArrow=(e,t)=>{let n=t?`"\`${toSingleQuotes(t)}\`"`:null;switch(!0){case e===`solid`:return n?` -- ${n} --> `:` --> `;case e===`dashed`:case e===`dotted`:return n?` -. ${n} .-> `:` -.-> `;default:_e(e)}},mmdDashArray=e=>e===`dashed`?`8 4`:null;function printNodeColors(e,t){let n=m(t,e=>e.color),r=/* @__PURE__ */ new Set([`default`]),uniqueClassName=e=>{let t=safeChars(e),n=t;for(let e=2;r.has(n);e++)n=`${t}_${e}`;return r.add(n),n};return M(Object.entries(n),([t,n])=>{let{fill:r,stroke:i,hiContrast:a}=e.colors(t).elements,o=uniqueClassName(t);return new N().append(`classDef `,o,` fill:`,r,`,stroke:`,i,`,color:`,a,F).append(`class `,n.map(e=>e.name).join(`,`),` `,o)},{appendNewLineIfNotEmpty:!0})}function printEdgeStyles(e,t){let n=/* @__PURE__ */ new Map;return t.forEach((t,r)=>{let i=e.colors(t.color).relationships.line,a=mmdDashArray(t.line),o=`stroke:${i}`+(a?`,stroke-dasharray:${a}`:``),s=n.get(o);s?s.push(r):n.set(o,[r])}),M([...n],([e,t])=>`linkStyle ${t.join(`,`)} ${e}`,{appendNewLineIfNotEmpty:!0})}function generateMermaid(e){let t=e.$view,n=e.$model.$styles,{nodes:r,edges:i}=t,a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Set,uniqueName=e=>{let t=e;for(let n=2;o.has(t);n++)t=`${e}${n}`;return o.add(t),t},printNode=(e,t)=>{let n=Ue(e),i=uniqueName((t?t+`.`:``)+n);a.set(e.id,i);let o=new N;if(e.children.length>0){let t=toSingleQuotes(e.title);o.append(`subgraph `,i,'["`',t,'`"]',F).indent({indentedChildren:[M(r.filter(t=>t.parent===e.id),e=>printNode(e,i),{appendNewLineIfNotEmpty:!0})],indentation:2}).append(`end`,F)}else o.append(i,mmdshape(e));return o},printEdge=e=>new N().append(a.get(e.source),mmdArrow(e.line,e.label),a.get(e.target));return P(new N().append(`---`,F,`title: ${JSON.stringify(toSingleQuotes(e.titleOrId))}`,F,`---`,F).append(`graph `,t.autoLayout.direction,F).indent({indentedChildren:e=>{e.append(M(r.filter(e=>x(e.parent)),e=>printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(i.length>0,M(i,e=>printEdge(e),{appendNewLineIfNotEmpty:!0})).append(printNodeColors(n,r.filter(e=>e.children.length===0&&e.shape!==`person`).map(e=>({color:e.color,name:a.get(e.id)})))).appendIf(i.length>0,printEdgeStyles(n,i))},indentation:2}))}const capitalizeFirstLetter=e=>e.charAt(0).toLocaleUpperCase()+e.slice(1),fqnName=e=>e.split(/[.-]/).map(capitalizeFirstLetter).join(``),nodeName=e=>fqnName(e.parent?e.id.slice(e.parent.length+1):e.id),pumlColor=(e,t,n=`#3b82f6`)=>e?t(e)??n:n,pumlDirection=({autoLayout:e})=>{switch(e.direction){case`TB`:return`top to bottom`;case`BT`:return console.warn(`Bottom to top direction is not supported. Defaulting to top to bottom.`),`top to bottom`;case`LR`:return`left to right`;case`RL`:return console.warn(`Right to left direction is not supported. Defaulting to left to right.`),`left to right`}},pumlShape=({shape:e})=>{switch(e){case`queue`:case`rectangle`:case`person`:return e;case`storage`:case`cylinder`:return`database`;case`component`:return`component`;case`document`:case`mobile`:case`bucket`:case`agent`:case`browser`:return`rectangle`;default:_e(e)}},escapeLabel=e=>c(e)?null:JSON.stringify(e).slice(1,-1).replace(/\\"/g,`"`);function generatePuml(e){let t=e.$view,n=e.$model.$styles.theme.colors,{nodes:r,edges:i}=t,elementColorProvider=e=>t=>t in n?n[t].elements[e]:void 0,relationshipsColorProvider=e=>t=>t in n?n[t].relationships[e]:void 0,a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Set;for(let e of r){let t=fqnName(e.id),n=t;for(let e=2;o.has(n);e++)n=`${t}${e}`;o.add(n),a.set(e.id,n)}let pumlName=e=>a.get(e.id)??fqnName(e.id),printHeader=()=>new N().append(`title "`,e.titleOrId,`"`,F).append(pumlDirection(t),` direction`,F),printTheme=()=>new N().append(`hide stereotype`,F).append(`skinparam ranksep `,`60`,F).append(`skinparam nodesep `,`30`,F).append(`skinparam {`,F).indent({indentedChildren:e=>e.append(`arrowFontSize `,`10`,F).append(`defaultTextAlignment `,`center`,F).append(`wrapWidth `,`200`,F).append(`maxMessageSize `,`100`,F).append(`shadowing `,`false`,F),indentation:2}).append(`}`,F),printStereotypes=e=>{let t=pumlShape(e),n=pumlName(e);return new N().append(`skinparam `,t,`<<`,n,`>>`,`{`,F).indent({indentedChildren:t=>t.append(`BackgroundColor `,pumlColor(e.color,elementColorProvider(`fill`)),F).append(`FontColor `,pumlColor(e.color,elementColorProvider(`hiContrast`),`#FFFFFF`),F).append(`BorderColor `,pumlColor(e.color,elementColorProvider(`stroke`)),F),indentation:2}).append(`}`,F)},printNode=t=>{let n=pumlShape(t),r=pumlName(t),i=escapeLabel(t.title)||nodeName(t),a=escapeLabel(t.technology),o=de.from(t.description,e.$model.resolveMarkdownRef);return new N().append(n,` `).append(`"`).append(`==`,i).appendIf(!!a,`\\n<size:10>[`,a,`]</size>`).appendIf(o.nonEmpty,`\\n\\n`,escapeLabel(o.text)).append(`"`,` <<`,r,`>> `,`as `,r,F)},printBoundary=e=>{let t=escapeLabel(e.title)||nodeName(e),n=pumlName(e);return new N().append(`rectangle "`,t,`" <<`,n,`>> as `,n,` {`,F).indent({indentedChildren:t=>t.append(`skinparam `,`RectangleBorderColor<<`,n,`>> `,pumlColor(e.color,elementColorProvider(`fill`)),F).append(`skinparam `,`RectangleFontColor<<`,n,`>> `,pumlColor(e.color,elementColorProvider(`fill`)),F).append(`skinparam `,`RectangleBorderStyle<<`,n,`>> `,`dashed`,F,F).append(M(r.filter(t=>t.parent===e.id),e=>e.children.length>0?printBoundary(e):printNode(e))),indentation:2}).append(`}`,F)},printEdge=e=>{let t=e.technology||``,n=e.label||t,r=pumlColor(e.color,relationshipsColorProvider(`line`),`#777777`),withColor=e=>`<color:${r}>${e.replaceAll(`"`,`'`)}`,i=new N().append(a.get(e.source),` .[`,r,`,thickness=2].> `,a.get(e.target));return(n||t)&&(i.append(` : `,n.split(`
307
+ `).map(e=>c(e)?e:withColor(e)).join(`\\n`)),t&&t!==n&&i.append(`\\n<size:8>[`,withColor(t),`]</size>`)),i.append(F)};return P(new N().append(`@startuml`,F).append(printHeader(),F).append(printTheme(),F).append(M(r.filter(e=>e.children.length==0),e=>printStereotypes(e),{appendNewLineIfNotEmpty:!0})).append(M(r.filter(e=>x(e.parent)),e=>e.children.length>0?printBoundary(e):printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(i.length>0,F,M(i,e=>printEdge(e),{appendNewLineIfNotEmpty:!0})).append(`@enduml`,F))}function code$9(e){let t=new N;return t.appendTemplate`
277
308
  /******************************************************************************
278
309
  * This file was generated
279
310
  * DO NOT EDIT MANUALLY!
@@ -282,7 +313,7 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
282
313
 
283
314
  export let d2Source = (viewId) => {
284
315
  switch (viewId) {
285
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d([...e.views()],e=>l`
316
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(M([...e.views()],e=>k`
286
317
  case ${JSON.stringify(e.id)}: {
287
318
  return ${JSON.stringify(generateD2(e))}
288
319
  }
@@ -290,9 +321,27 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
290
321
  default: {
291
322
  throw new Error('Unknown viewId: ' + viewId)
292
323
  }
293
- `}}).append(c,` }`,c).appendTemplate`
324
+ `}}).append(j,` }`,j).appendTemplate`
294
325
  }
295
- `.append(c,c),f(t)}e(code$8,`code`);const Ue={exportFormat:`d2`,...generateMatches(`d2`),async load({likec4:e,project:t}){return logGenerating(`d2`,t.id),{code:code$8(await e.computedModel(t.id)),moduleType:`js`}}},We=generateCombinedProjects(`d2`,`loadD2Sources`,`d2`);function code$7(e){let t=new u;return t.appendTemplate`
326
+ `.append(j,j),A(t)}e(code$9,`code`);const We={exportFormat:`d2`,...generateMatches(`d2`),async load({likec4:e,project:t}){return logGenerating(`d2`,t.id),{code:code$9(await e.computedModel(t.id)),moduleType:`js`}}},Ge=generateCombinedProjects(`d2`,`loadD2Sources`,`d2`),Ke=/* @__PURE__ */ e(e=>`
327
+ import { atom } from 'likec4/vite-plugin/internal'
328
+
329
+ export let $diffs = atom(${O.stringify(e)})
330
+
331
+ if (import.meta.hot) {
332
+ import.meta.hot.accept(md => {
333
+ if (!import.meta.hot.data.$diffs) {
334
+ import.meta.hot.data.$diffs = $diffs
335
+ }
336
+ const update = md.$diffs?.get()
337
+ if (update) {
338
+ import.meta.hot.data.$diffs.set(update)
339
+ } else {
340
+ import.meta.hot.invalidate()
341
+ }
342
+ })
343
+ }
344
+ `,`code`),qe={...generateMatches(`diffs`),async load({likec4:e,project:t}){logGenerating(`diffs`,t.id);let n=await e.modelDiffs.list(t.id),r={};for(let i of n){let n={};for(let{id:r}of i.views){let a=await e.modelDiffs.layoutCompareView({projectId:t.id,diffId:i.id,viewId:r});a&&(n[r]=a)}r[i.id]=n}return{code:Ke({diffs:n,views:r}),moduleType:`js`}}},Je=generateCombinedProjects(`diffs`,`loadDiffs`);function code$7(e){let t=new N;return t.appendTemplate`
296
345
  /******************************************************************************
297
346
  * This file was generated
298
347
  * DO NOT EDIT MANUALLY!
@@ -301,7 +350,7 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
301
350
 
302
351
  export let dotSource = (viewId) => {
303
352
  switch (viewId) {
304
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d(Object.keys(e),t=>l`
353
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(M(Object.keys(e),t=>k`
305
354
  case ${JSON.stringify(t)}: {
306
355
  return ${JSON.stringify(e[t].dot)}
307
356
  }
@@ -309,12 +358,12 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
309
358
  default: {
310
359
  throw new Error('Unknown viewId: ' + viewId)
311
360
  }
312
- `}}).append(c,` }`,c).appendTemplate`
361
+ `}}).append(j,` }`,j).appendTemplate`
313
362
  }
314
363
 
315
364
  export let svgSource = (viewId) => {
316
365
  switch (viewId) {
317
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d(Object.keys(e),t=>l`
366
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(M(Object.keys(e),t=>k`
318
367
  case ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(t))}: {
319
368
  return ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e[t].svg))}
320
369
  }
@@ -322,7 +371,7 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
322
371
  default: {
323
372
  throw new Error('Unknown viewId: ' + viewId)
324
373
  }
325
- `}}).append(c,` }`,c,`}`,c,c),f(t)}e(code$7,`code`);const Ge={exportFormat:`dot`,...generateMatches(`dot`),async load({likec4:e,project:t}){logGenerating(`dot`,t.id);let n=await e.views.viewsAsGraphvizOut(t.id);return{code:code$7(ae(n,({id:e,svg:t,dot:n})=>[e,{dot:n,svg:t}])),moduleType:`js`}}},Ke=generateCombinedProjects(`dot`,`loadDotSources`,`dot`);function code$6(e){let t=new u;return t.appendTemplate`
374
+ `}}).append(j,` }`,j,`}`,j,j),A(t)}e(code$7,`code`);const Ye={exportFormat:`dot`,...generateMatches(`dot`),async load({likec4:e,project:t}){logGenerating(`dot`,t.id);let n=await e.views.viewsAsGraphvizOut(t.id);return{code:code$7(g(n,({id:e,svg:t,dot:n})=>[e,{dot:n,svg:t}])),moduleType:`js`}}},Xe=generateCombinedProjects(`dot`,`loadDotSources`,`dot`);function code$6(e){let t=new N;return t.appendTemplate`
326
375
  /******************************************************************************
327
376
  * This file was generated
328
377
  * DO NOT EDIT MANUALLY!
@@ -331,7 +380,7 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
331
380
 
332
381
  export function drawioEditUrl(viewId) {
333
382
  switch (viewId) {
334
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d([...e.views()],e=>l`
383
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(M([...e.views()],e=>k`
335
384
  case ${JSON.stringify(e.id)}: {
336
385
  return ${JSON.stringify(generateDrawioEditUrl(generateDrawio(e)))}
337
386
  }
@@ -339,9 +388,9 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
339
388
  default: {
340
389
  throw new Error('Unknown viewId: ' + viewId)
341
390
  }
342
- `}}).append(c,` }`,c).appendTemplate`
391
+ `}}).append(j,` }`,j).appendTemplate`
343
392
  }
344
- `.append(c,c),f(t)}e(code$6,`code`);const qe={exportFormat:`drawio`,...generateMatches(`drawio`),async load({likec4:e,project:t}){return logGenerating(`drawio`,t.id),{code:code$6(await e.layoutedModel(t.id)),moduleType:`js`}}},Je=generateCombinedProjects(`drawio`,`loadDrawioSources`,`drawio`),Ye=/^(https?:)?\/\//i,Xe=new Set([`aws`,`azure`,`gcp`,`tech`,`bootstrap`]);function iconRef(e){if(!(!L(e)||Ye.test(e)||e===`none`||e.startsWith(`data:image`)))return e.startsWith(`file:`)||parseBundledIconRef(e)?e:void 0}function iconRefsFromModelData(e){let iconsFromViews=e=>F(e).flatMap(e=>e.nodes.map(e=>e.icon)),iconsFromStyled=e=>F(e).map(e=>e.style?.icon);return I([...iconsFromViews(e.views),...iconsFromViews(e.manualLayouts??{}),...iconsFromStyled(e.elements),...iconsFromStyled(e.deployments.elements)],A(iconRef),k(L),P(),N(be))}const isLocalSvg=e=>e.startsWith(`file:`)?e.toLowerCase().split(/[?#]/)[0]?.endsWith(`.svg`)??!1:!1,$=e(e=>hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e)),`jsStringLiteral`);function isBundledIconGroup(e){return Xe.has(e)}function parseBundledIconRef(e){let t=e.indexOf(`:`);if(t<=0||t===e.length-1)return null;let n=e.slice(0,t);return isBundledIconGroup(n)?{group:n,icon:e.slice(t+1)}:null}function generateIconRendererCode(e){let{imports:t,cases:n}=iconRefsFromModelData(e).reduce((e,t,n)=>{let r=t.startsWith(`file:`),i=`Icon`+n.toString().padStart(2,`0`),a=$(t);if(r){if(isLocalSvg(t)){let n=`${i}Raw`;e.imports.push(`import ${n} from ${$(`${t}?raw`)}`),e.imports.push(`import ${i} from ${$(`${t}?inline`)}`),e.cases.push(` ${a}: props => jsx(LocalSvgIcon, { ...props, src: ${i}, raw: ${n} })`)}else e.imports.push(`import ${i} from ${$(`${t}?inline`)}`),e.cases.push(` ${a}: props => jsx('img', { ...props, src: ${i} })`);return e}let o=parseBundledIconRef(t);if(!o)return e;let{group:s,icon:c}=o,l=`likec4:icon-bundle/${s}/${c}.jsx`;return e.imports.push(`import ${i} from ${$(l)}`),e.cases.push(` ${a}: ${i}`),e},{imports:[],cases:[]});return`
393
+ `.append(j,j),A(t)}e(code$6,`code`);const Ze={exportFormat:`drawio`,...generateMatches(`drawio`),async load({likec4:e,project:t}){return logGenerating(`drawio`,t.id),{code:code$6(await e.layoutedModel(t.id)),moduleType:`js`}}},Qe=generateCombinedProjects(`drawio`,`loadDrawioSources`,`drawio`),$e=/^(https?:)?\/\//i,et=/* @__PURE__ */ new Set([`aws`,`azure`,`gcp`,`md`,`tech`,`bootstrap`]);function iconRef(e){if(!(!p(e)||$e.test(e)||e===`none`||e.startsWith(`data:image`)))return e.startsWith(`file:`)||parseBundledIconRef(e)?e:void 0}function iconRefsFromModelData(e){let iconsFromViews=e=>w(e).flatMap(e=>e.nodes.map(e=>e.icon)),iconsFromStyled=e=>w(e).map(e=>e.style?.icon);return y([...iconsFromViews(e.views),...iconsFromViews(e.manualLayouts??{}),...iconsFromStyled(e.elements),...iconsFromStyled(e.deployments.elements)],E(iconRef),s(p),C(),S(ve))}const isLocalSvg=e=>e.startsWith(`file:`)?e.toLowerCase().split(/[?#]/)[0]?.endsWith(`.svg`)??!1:!1,$=/* @__PURE__ */ e(e=>hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e)),`jsStringLiteral`);function isBundledIconGroup(e){return et.has(e)}function parseBundledIconRef(e){let t=e.indexOf(`:`);if(t<=0||t===e.length-1)return null;let n=e.slice(0,t);return isBundledIconGroup(n)?{group:n,icon:e.slice(t+1)}:null}function generateIconRendererCode(e){let{imports:t,cases:n}=iconRefsFromModelData(e).reduce((e,t,n)=>{let r=t.startsWith(`file:`),i=`Icon`+n.toString().padStart(2,`0`),a=$(t);if(r){if(isLocalSvg(t)){let n=`${i}Raw`;e.imports.push(`import ${n} from ${$(`${t}?raw`)}`),e.imports.push(`import ${i} from ${$(`${t}?inline`)}`),e.cases.push(` ${a}: props => jsx(LocalSvgIcon, { ...props, src: ${i}, raw: ${n} })`)}else e.imports.push(`import ${i} from ${$(`${t}?inline`)}`),e.cases.push(` ${a}: props => jsx('img', { ...props, src: ${i} })`);return e}let o=parseBundledIconRef(t);if(!o)return e;let{group:s,icon:c}=o,l=`likec4:icon-bundle/${s}/${c}.jsx`;return e.imports.push(`import ${i} from ${$(l)}`),e.cases.push(` ${a}: ${i}`),e},{imports:[],cases:[]});return`
345
394
  import { jsx } from 'react/jsx-runtime'
346
395
  ${t.join(`
347
396
  `)}
@@ -387,47 +436,71 @@ export function IconRenderer({ node, ...props }) {
387
436
  }
388
437
  return jsx(IconComponent, props)
389
438
  }
390
- `}const Ze={...generateMatches(`icons`,`.jsx`),async load({likec4:e,project:t}){return logGenerating(`icons`,t.id),{moduleType:`jsx`,code:generateIconRendererCode((await e.computedModel(t.id)).$data)}}},Qe=/^[a-zA-Z0-9_.-]+$/;function embedProjectIdAsJsString(e){if(!Qe.test(e))throw Error(`Unsafe value for code generation: ${e}`);return JSON.stringify(e)}function embedUrlAsJsString(e){return JSON.stringify(e)}const $e={id:`likec4:icons`,virtualId:`likec4:plugin/icons.jsx`,async load({projects:e,logger:t}){logGenerating(`icons`);let{imports:n,cases:r}=e.filter(e=>Qe.test(e.id)?!0:(t.warn(s.yellow(`Skipping project with unsafe id for icons registry: ${e.id}`)),!1)).reduce((e,t,n)=>{let r=`Project`+n.toString().padStart(2,`0`),i=hardenJsonStringLiteralForEmbeddedScript(embedProjectIdAsJsString(t.id)),a=hardenJsonStringLiteralForEmbeddedScript(embedUrlAsJsString(p(`likec4:icons`,t.id)));return e.imports.push(`import {IconRenderer as ${r}} from ${a}`),e.cases.push(` ${i}: ${r}`),e},{imports:[],cases:[]});return{code:`
439
+ `}const tt={...generateMatches(`icons`,`.jsx`),async load({likec4:e,project:t}){return logGenerating(`icons`,t.id),{moduleType:`jsx`,code:generateIconRendererCode((await e.computedModel(t.id)).$data)}}},nt=/^[a-zA-Z0-9_.-]+$/;function embedProjectIdAsJsString(e){if(!nt.test(e))throw Error(`Unsafe value for code generation: ${e}`);return JSON.stringify(e)}function embedUrlAsJsString(e){return JSON.stringify(e)}const rt={id:`likec4:icons`,virtualId:`likec4:plugin/icons.js`,async load({projects:e,logger:t}){return logGenerating(`icons`),{code:`
440
+ import { lazy, Suspense } from 'react'
391
441
  import { jsx } from 'react/jsx-runtime'
392
- ${n.join(`
393
- `)}
394
442
 
395
443
  export let ProjectIconsRegistry = {
396
- ${r.join(`,
444
+ ${e.filter(e=>nt.test(e.id)?!0:(t.warn(n.yellow(`Skipping project with unsafe id for icons registry: ${e.id}`)),!1)).map(e=>` ${hardenJsonStringLiteralForEmbeddedScript(embedProjectIdAsJsString(e.id))}: () => import(${hardenJsonStringLiteralForEmbeddedScript(embedUrlAsJsString(D(`likec4:icons`,e.id)))})`).join(`,
397
445
  `)}
398
446
  }
399
447
 
400
- export function getProjectIcons(projectId) {
401
- return (props) => {
402
- let Renderer = ProjectIconsRegistry[projectId]
403
- if (!Renderer) {
404
- const projects = Object.keys(ProjectIconsRegistry)
405
- console.error('Unknown projectId: ' + projectId + ' (available: ' + projects + ')')
406
- if (projects.length === 0) {
407
- throw new Error('No projects found, invalid state')
408
- }
409
- projectId = projects[0]
410
- console.warn('Falling back to project: ' + projectId)
411
- Renderer = ProjectIconsRegistry[projectId]
412
- }
413
- return jsx(Renderer, props)
448
+ // Lazy icon renderers by requested project id, cleared on HMR updates
449
+ const lazyRegistry = new Map()
450
+
451
+ let invalidateMe = false
452
+
453
+ function resolveLoader(projectId) {
454
+ if (Object.hasOwn(ProjectIconsRegistry, projectId)) {
455
+ return ProjectIconsRegistry[projectId]
456
+ }
457
+ const projects = Object.keys(ProjectIconsRegistry)
458
+ console.error('Unknown projectId: ' + projectId + ' (available: ' + projects + ')')
459
+ if (projects.length === 0) {
460
+ throw new Error('No projects found, invalid state')
414
461
  }
462
+ invalidateMe = true
463
+ console.warn('Falling back to project: ' + projects[0])
464
+ return ProjectIconsRegistry[projects[0]]
465
+ }
466
+
467
+ function getLazyRenderer(projectId) {
468
+ let Renderer = lazyRegistry.get(projectId)
469
+ if (!Renderer) {
470
+ const loader = resolveLoader(projectId)
471
+ Renderer = lazy(async () => {
472
+ const { IconRenderer } = await loader()
473
+ return { default: IconRenderer }
474
+ })
475
+ lazyRegistry.set(projectId, Renderer)
476
+ }
477
+ return Renderer
478
+ }
479
+
480
+ export function getProjectIcons(projectId) {
481
+ // Renderer is resolved on each render, so that HMR updates are picked up
482
+ return (props) => jsx(Suspense, { children: jsx(getLazyRenderer(projectId), props) })
415
483
  }
416
484
 
417
485
  if (import.meta.hot) {
418
486
  import.meta.hot.accept(md => {
419
487
  if (!import.meta.hot.data.$update) {
420
- import.meta.hot.data.$update = ProjectIconsRegistry
488
+ import.meta.hot.data.$update = (updateData) => {
489
+ Object.assign(ProjectIconsRegistry, updateData)
490
+ lazyRegistry.clear()
491
+ const shouldInvalidate = invalidateMe
492
+ invalidateMe = false
493
+ return shouldInvalidate
494
+ }
421
495
  }
422
496
  const update = md.ProjectIconsRegistry
423
- if (update) {
424
- Object.assign(import.meta.hot.data.$update, update)
425
- } else {
497
+ const shouldInvalidate = update ? import.meta.hot.data.$update(update) : true
498
+ if (shouldInvalidate) {
426
499
  import.meta.hot.invalidate()
427
500
  }
428
501
  })
429
502
  }
430
- `,moduleType:`jsx`}}};function code$5(e){let t=new u;return t.appendTemplate`
503
+ `,moduleType:`js`}}};function code$5(e){let t=new N;return t.appendTemplate`
431
504
  /******************************************************************************
432
505
  * This file was generated
433
506
  * DO NOT EDIT MANUALLY!
@@ -436,7 +509,7 @@ if (import.meta.hot) {
436
509
 
437
510
  export let mmdSource = (viewId) => {
438
511
  switch (viewId) {
439
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d([...e.views()],e=>l`
512
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(M([...e.views()],e=>k`
440
513
  case ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e.id))}: {
441
514
  return ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(generateMermaid(e)))}
442
515
  }
@@ -444,20 +517,26 @@ if (import.meta.hot) {
444
517
  default: {
445
518
  throw new Error('Unknown viewId: ' + viewId)
446
519
  }
447
- `}}).append(c,` }`,c).appendTemplate`
520
+ `}}).append(j,` }`,j).appendTemplate`
448
521
  }
449
522
 
450
- `.append(c,c),f(t)}e(code$5,`code`);const et={exportFormat:`mmd`,...generateMatches(`mmd`),async load({likec4:e,project:t}){return logGenerating(`mmd`,t.id),{code:code$5(await e.computedModel(t.id)),moduleType:`js`}}},tt=generateCombinedProjects(`mmd`,`loadMmdSources`,`mmd`),projectModelCode=e=>`
523
+ `.append(j,j),A(t)}e(code$5,`code`);const it={exportFormat:`mmd`,...generateMatches(`mmd`),async load({likec4:e,project:t}){return logGenerating(`mmd`,t.id),{code:code$5(await e.computedModel(t.id)),moduleType:`js`}}},at=generateCombinedProjects(`mmd`,`loadMmdSources`,`mmd`),customCssFiles=async({config:e,folder:t})=>{let n=(e.styles?.customCss?.paths??[]).map(e=>o(t.fsPath,e)),r=await Promise.all(n.map(e=>se(e,xe.R_OK).then(()=>!0,()=>!1)));return n.filter((e,t)=>r[t])},modelDataCode=(e,t)=>{if(t.length===0)return{imports:``,data:O.stringify(e)};let n={...e.project.styles,customCss:{content:``}};return{imports:t.map((e,t)=>`import customCss${t} from ${JSON.stringify(`${e}?inline`)}`).join(`
524
+ `),data:`(data => {
525
+ data.project.styles.customCss.content = [${t.map((e,t)=>`customCss${t}`).join(`, `)}].join('\\n')
526
+ return data
527
+ })(${O.stringify({...e,project:{...e.project,styles:n}})})`}},projectModelCode=(e,t)=>{let{imports:n,data:r}=modelDataCode(e.$data,t);return`
451
528
  import { createHooksForModel, atom } from 'likec4/vite-plugin/internal'
529
+ ${n}
452
530
 
453
- export let $likec4data = atom(${m.stringify(e.$data)})
531
+ export let $likec4data = atom(${r})
454
532
 
455
533
  export let {
456
534
  updateModel,
457
535
  $likec4model,
458
536
  useLikeC4Model,
459
537
  useLikeC4Views,
460
- useLikeC4View
538
+ useLikeC4View,
539
+ isLikeC4ViewId
461
540
  } = createHooksForModel($likec4data)
462
541
 
463
542
  if (import.meta.hot) {
@@ -473,11 +552,11 @@ if (import.meta.hot) {
473
552
  }
474
553
  })
475
554
  }
476
- `,nt={...generateMatches(`model`),async load({likec4:e,project:t}){logGenerating(`model`,t.id);let n=await e.layoutedModel(t.id);return{code:projectModelCode(n),moduleType:`js`}}},rt=generateCombinedProjects(`model`,`loadModel`),it=e(e=>`
555
+ `},ot={...generateMatches(`model`),async load({likec4:e,project:t}){logGenerating(`model`,t.id);let n=await e.layoutedModel(t.id);return{code:projectModelCode(n,await customCssFiles(t)),moduleType:`js`}}},st=generateCombinedProjects(`model`,`loadModel`),ct=/* @__PURE__ */ e(e=>`
477
556
  import { atom, useStore } from 'likec4/vite-plugin/internal'
478
557
 
479
558
  export const isSingleProject = ${e.length===1};
480
- export const projects = ${m.stringify(e,null,2)};
559
+ export const projects = ${O.stringify(e,null,2)};
481
560
 
482
561
  export const $projects = atom([...projects])
483
562
 
@@ -503,10 +582,10 @@ if (import.meta.hot) {
503
582
  }
504
583
  })
505
584
  }
506
- `,`code`),at={id:`likec4:projects`,virtualId:`likec4:plugin/projects.js`,async load({projects:e}){return logGenerating(`projects`),{code:it(A(e,e=>({id:e.id,title:e.title,path:e.path,landingPage:e.config.landingPage,relationshipBrowserDefaultScope:e.config.webapp?.relationshipsBrowser?.defaultScope??`view`,exportFormats:effectiveWebappExportFormats(e.config)}))),moduleType:`js`}}},ot=e(e=>`
585
+ `,`code`),lt={id:`likec4:projects`,virtualId:`likec4:plugin/projects.js`,async load({projects:e}){return logGenerating(`projects`),{code:ct(E(e,e=>({id:e.id,title:e.title,path:e.path,landingPage:e.config.landingPage,relationshipBrowserDefaultScope:e.config.webapp?.relationshipsBrowser?.defaultScope??`view`,exportFormats:effectiveWebappExportFormats(e.config)}))),moduleType:`js`}}},ut=/* @__PURE__ */ e(e=>`
507
586
  import { atom, useStore } from 'likec4/vite-plugin/internal'
508
587
 
509
- export const $viewdata = atom(${m.stringify(e)})
588
+ export const $viewdata = atom(${O.stringify(e)})
510
589
 
511
590
  export function useLikeC4ProjectsOverview() {
512
591
  return useStore($viewdata)
@@ -529,7 +608,7 @@ if (import.meta.hot) {
529
608
  export function useLikeC4ProjectsOverview() {
530
609
  throw new Error('No projects overview available for this workspace: single project mode is enabled')
531
610
  }
532
- `,st={id:`likec4:projects-overview`,virtualId:`likec4:plugin/projects-overview.js`,async load({projects:e,likec4:t}){if(e.length<2)return noProjects();logGenerating(`projects-overview`);let n=await t.projectsOverview();return{code:ot(n),moduleType:`js`}}};function code$2(e){let t=new u;return t.appendTemplate`
611
+ `,dt={id:`likec4:projects-overview`,virtualId:`likec4:plugin/projects-overview.js`,async load({projects:e,likec4:t}){if(e.length<2)return noProjects();logGenerating(`projects-overview`);let n=await t.projectsOverview();return{code:ut(n),moduleType:`js`}}};function code$2(e){let t=new N;return t.appendTemplate`
533
612
  /******************************************************************************
534
613
  * This file was generated
535
614
  * DO NOT EDIT MANUALLY!
@@ -538,7 +617,7 @@ export function useLikeC4ProjectsOverview() {
538
617
 
539
618
  export let pumlSource = (viewId) => {
540
619
  switch (viewId) {
541
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d([...e.views()],e=>l`
620
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(M([...e.views()],e=>k`
542
621
  case ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e.id))}: {
543
622
  return ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(generatePuml(e)))}
544
623
  }
@@ -546,39 +625,55 @@ export function useLikeC4ProjectsOverview() {
546
625
  default: {
547
626
  throw new Error('Unknown viewId: ' + viewId)
548
627
  }
549
- `}}).append(c,` }`,c).appendTemplate`
628
+ `}}).append(j,` }`,j).appendTemplate`
550
629
  }
551
- `.append(c,c),f(t)}e(code$2,`code`);const ct={exportFormat:`puml`,...generateMatches(`puml`),async load({likec4:e,project:t}){return logGenerating(`puml`,t.id),{code:code$2(await e.computedModel(t.id)),moduleType:`js`}}},lt=generateCombinedProjects(`puml`,`loadPumlSources`,`puml`),projectCode=e=>`
552
- import { jsx as _jsx } from "react/jsx-runtime";
553
- import { LikeC4ModelProvider as Provider, LikeC4View as GenericView, ReactLikeC4 as GenericReactLikeC4 } from 'likec4/react';
554
- import { IconRenderer } from 'likec4:icons/${e}'
555
-
556
- import { useLikeC4Model, useLikeC4Views, useLikeC4View } from 'likec4:model/${e}'
630
+ `.append(j,j),A(t)}e(code$2,`code`);const ft={exportFormat:`puml`,...generateMatches(`puml`),async load({likec4:e,project:t}){return logGenerating(`puml`,t.id),{code:code$2(await e.computedModel(t.id)),moduleType:`js`}}},pt=generateCombinedProjects(`puml`,`loadPumlSources`,`puml`),modelProviderCode=e=>e?`
631
+ import { CustomizationProvider } from 'likec4/react';
632
+ import { useCustomComponents } from 'likec4:customization'
557
633
 
558
634
  export function LikeC4ModelProvider({ children }) {
559
- const likeC4Model = useLikeC4Model()
560
- return (_jsx(Provider, { likec4model: likeC4Model, children: children }));
561
- }
635
+ const likec4model = useLikeC4Model()
636
+ const components = useCustomComponents()
637
+ return (jsx(CustomizationProvider, { components, children: jsx(Provider, { likec4model, children }) }));
638
+ }`:`
639
+ export function LikeC4ModelProvider({ children }) {
640
+ const likec4model = useLikeC4Model()
641
+ return (jsx(Provider, { likec4model, children }));
642
+ }`,generateProjectReactCode=(e,t)=>`
643
+ import { jsx } from "react/jsx-runtime";
644
+ import { LikeC4ModelProvider as Provider, LikeC4View as GenericView, ReactLikeC4 as GenericReactLikeC4 } from 'likec4/react';
645
+ import { IconRenderer as renderIcon } from 'likec4:icons/${e}'
646
+ import { useLikeC4Model } from 'likec4:model/${e}'
647
+ ${modelProviderCode(t)}
562
648
  export function LikeC4View(props) {
563
- return (_jsx(LikeC4ModelProvider, { children: _jsx(GenericView, { renderIcon: IconRenderer, ...props }) }));
649
+ return (jsx(LikeC4ModelProvider, { children: jsx(GenericView, { renderIcon, ...props }) }));
564
650
  }
565
651
  export function ReactLikeC4(props) {
566
- return (_jsx(LikeC4ModelProvider, { children: _jsx(GenericReactLikeC4, { renderIcon: IconRenderer, ...props }) }));
652
+ return (jsx(LikeC4ModelProvider, { children: jsx(GenericReactLikeC4, { renderIcon, ...props }) }));
567
653
  }
568
654
 
655
+ export { IconRenderer } from 'likec4:icons/${e}'
656
+
569
657
  export {
570
- useLikeC4Model,
571
- useLikeC4View,
572
- useLikeC4Views
573
- }
574
- `,ut={...generateMatches(`react`),async load({project:e}){return logGenerating(`react`,e.id),{code:projectCode(e.id),moduleType:`js`}}},dt={id:`likec4:react`,virtualId:`likec4:plugin/react.js`,async load({projects:e}){let t=T(e);return logGenerating(`react-default-project`),{code:`export {
658
+ useLikeC4Model,
659
+ useLikeC4Views,
660
+ useLikeC4View,
661
+ $likec4model,
662
+ $likec4data,
663
+ isLikeC4ViewId
664
+ } from 'likec4:model/${e}'
665
+ `,mt={...generateMatches(`react`),async load({project:e,customizationFile:t}){return logGenerating(`react`,e.id),{code:generateProjectReactCode(e.id,!!t),moduleType:`js`}}},ht={id:`likec4:react`,virtualId:`likec4:plugin/react.js`,async load({projects:e}){let t=h(e);return logGenerating(`react-default-project`),{code:`export {
666
+ $likec4data,
667
+ $likec4model,
575
668
  useLikeC4Model,
576
669
  useLikeC4View,
577
670
  useLikeC4Views,
671
+ isLikeC4ViewId,
672
+ IconRenderer,
578
673
  LikeC4ModelProvider,
579
674
  LikeC4View,
580
- ReactLikeC4
581
- } from 'likec4:react/${t.id}'`,moduleType:`js`}}},ft=e(({isAIAvailable:e,ai:t,rpcEnabled:n})=>`
675
+ ReactLikeC4,
676
+ } from 'likec4:react/${t.id}'`,moduleType:`js`}}},gt=/* @__PURE__ */ e(({isAIAvailable:e,ai:t,rpcEnabled:n})=>`
582
677
  import { createRpc } from 'likec4/vite-plugin/internal'
583
678
 
584
679
  export const isRpcAvailable = !!import.meta.hot && ${n}
@@ -610,98 +705,22 @@ export const likec4rpc = rpc ?? {
610
705
  throw new Error('likec4rpc.calcAdhocView is not available in production')
611
706
  },
612
707
  }
613
- `,`code`),pt={id:`likec4:rpc`,virtualId:`likec4:plugin/rpc.js`,async load(e){return logGenerating(`rpc`),{code:ft(e),moduleType:`js`,moduleSideEffects:!1}}},code=e=>`
708
+ `,`code`),_t={id:`likec4:rpc`,virtualId:`likec4:plugin/rpc.js`,async load(e){return logGenerating(`rpc`),{code:gt(e),moduleType:`js`,moduleSideEffects:`no-treeshake`}}},code=e=>`
614
709
  export { IconRenderer } from 'likec4:icons/${e}'
615
710
  export {
616
711
  $likec4data,
617
712
  $likec4model,
618
713
  useLikeC4Model,
619
714
  useLikeC4Views,
620
- useLikeC4View
715
+ useLikeC4View,
716
+ isLikeC4ViewId
621
717
  } from 'likec4:model/${e}'
622
718
  export const projectId = ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e))}
623
- `,mt={id:`likec4:single-project`,virtualId:`likec4:plugin/single-project.js`,async load({projects:e}){let t=T(e);return logGenerating(`single-project`,t.id),code(t.id)}},jsStringLiteral=e=>hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e)),generateWebcomponentsCode=e=>{let t=jsStringLiteral(e);return`
624
- import { createElement } from 'react'
625
- import { createRoot } from 'react-dom/client'
719
+ `,vt={id:`likec4:single-project`,virtualId:`likec4:plugin/single-project.js`,async load({projects:e}){let t=h(e);return logGenerating(`single-project`,t.id),code(t.id)}},jsStringLiteral=e=>hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e)),generateWebcomponentsCode=e=>{let t=jsStringLiteral(e);return`
720
+ import { defineLikeC4Webcomponent } from 'likec4/react'
626
721
  import { LikeC4View } from ${jsStringLiteral(`likec4:react/${e}`)}
627
722
 
628
- const projectId = ${t}
629
- const projectIdSymbol = Symbol.for('likec4.webcomponent.projectId')
630
-
631
- function booleanAttribute(element, name, fallback) {
632
- const value = element.getAttribute(name)
633
- return value === null ? fallback : value.toLowerCase() !== 'false'
634
- }
635
-
636
- function enumAttribute(element, name, values) {
637
- const value = element.getAttribute(name)
638
- return value !== null && values.includes(value) ? value : undefined
639
- }
640
-
641
- function propsFrom(element) {
642
- const props = {
643
- viewId: element.getAttribute('view-id') ?? 'index',
644
- browser: booleanAttribute(element, 'browser', true),
645
- }
646
- const dynamicViewVariant = enumAttribute(element, 'dynamic-variant', ['diagram', 'sequence'])
647
- const colorScheme = enumAttribute(element, 'color-scheme', ['light', 'dark'])
648
- if (dynamicViewVariant) {
649
- props.dynamicViewVariant = dynamicViewVariant
650
- }
651
- if (colorScheme) {
652
- props.colorScheme = colorScheme
653
- }
654
- return props
655
- }
656
-
657
- function createLikeC4ViewElement() {
658
- return class LikeC4ViewElement extends HTMLElement {
659
- static observedAttributes = ['view-id', 'browser', 'dynamic-variant', 'color-scheme']
660
-
661
- constructor() {
662
- super()
663
- this.shadow = this.attachShadow({ mode: 'open', delegatesFocus: true })
664
- const style = document.createElement('style')
665
- style.textContent = ':host { display: contents; background-color: transparent; margin: 0; padding: 0; }'
666
- this.mount = document.createElement('div')
667
- this.mount.style.display = 'contents'
668
- this.shadow.append(style, this.mount)
669
- }
670
-
671
- connectedCallback() {
672
- this.root ??= createRoot(this.mount)
673
- this.render()
674
- }
675
-
676
- disconnectedCallback() {
677
- this.root?.unmount()
678
- this.root = undefined
679
- }
680
-
681
- attributeChangedCallback() {
682
- if (this.root) {
683
- this.render()
684
- }
685
- }
686
-
687
- render() {
688
- this.root.render(createElement(LikeC4View, propsFrom(this)))
689
- }
690
- }
691
- }
692
-
693
723
  export function defineWebcomponent(name) {
694
- const existing = customElements.get(name)
695
- if (existing) {
696
- if (existing[projectIdSymbol] === projectId) {
697
- return existing
698
- }
699
- throw new Error('Custom element "' + name + '" is already defined')
700
- }
701
-
702
- const LikeC4ViewElement = createLikeC4ViewElement()
703
- Object.defineProperty(LikeC4ViewElement, projectIdSymbol, { value: projectId })
704
- customElements.define(name, LikeC4ViewElement)
705
- return LikeC4ViewElement
724
+ return defineLikeC4Webcomponent(name, LikeC4View, ${t})
706
725
  }
707
- `},ht={...generateMatches(`webcomponents`),async load({project:e}){return logGenerating(`webcomponents`,e.id),{code:generateWebcomponentsCode(e.id),moduleType:`js`}}},gt=[nt,Ze,Ue,Ge,et,ct,qe],_t=[We,Ke,tt,lt,Je],vt=[...gt,ut,ht],yt=[at,rt,st,mt,dt,..._t,$e,pt];function LikeC4VitePlugin({environments:e,appConfig:n,ai:r=`auto`,...i}){let o,c,l=!1,u,d=i.watch??!1,f=[...yt,createAppConfigModule(n)],initAI=async()=>{if(w(r))throw Error(`Invalid AI configuration: true is not allowed, use an object with adapter configuration or false to disable AI`);if(r!==`disabled`)return r===`auto`?await Ee():r};function moduleopts(e){return{rpcEnabled:l,isAIAvailable:!!u,ai:u,assetsDir:c,likec4:o,logger:U,...e}}let projectsChangeDetector=()=>{let e=A(e=>({id:e.id,title:e.title,path:e.path,folder:e.folder.toString(),landingPage:e.config.landingPage,exportFormats:effectiveWebappExportFormats(e.config)})),t;return n=>{let r=e(n);return t??=r,!te(t,r)&&(t=r,!0)}};return[iconBundlePlugin({environments:e?[e].flat():void 0,workspace:i.workspace??i.languageServices?.workspacePath}),{name:`vite-plugin-likec4`,sharedDuringBuild:!0,applyToEnvironment(t){return!e||e.includes(t.name)},async configResolved(e){let t=l=e.command===`serve`;if(i.languageServices)o=i.languageServices;else{let n=d=t&&(i.watch??!0);o=(await a(i.workspace??e.root,{manualLayouts:!0,graphviz:i.graphviz??`wasm`,configureLogger:`console`,logLevel:i.logLevel??`warning`,printErrors:i.printErrors??!0,throwIfInvalid:i.throwIfInvalid??!1,watch:n})).languageServices}c=o.workspaceUri.fsPath,l&&(u=await initAI())},resolveId:{filter:{id:/^likec4:/},handler(e){for(let t of vt){let n=t.matches(e);if(n)return t.virtualId(n)}for(let t of f)if(t.id===e)return t.virtualId;return null}},load:{filter:{id:/likec4:plugin/},async handler(e){for(let t of vt){let n=t.matches(e);if(n){let e=o.project(n);return await t.load.call(this,moduleopts({project:e}))}}for(let t of f)if(t.virtualId===e){let e=o.projects();return S(e,1)?await t.load.call(this,moduleopts({projects:e})):null}return null}},async configureServer(e){if(l){if(enablePluginRPC.call(this,moduleopts({server:e})),u){U.info(s.dim(`enabling`)+` `+s.magenta(`AI Chat`));let{enableAIServer:t}=await import(`./enableServer.mjs`);t.call(this,moduleopts({server:e}))}return()=>{let n=e.hot,r=projectsChangeDetector(),reloadModule=async n=>{let r=e.moduleGraph.getModuleById(n);if(!r||r.importers.size===0)return!1;try{return await e.reloadModule(r),!0}catch(e){return U.error(t(e)),!1}},hasErrors=()=>{let[e]=o.getErrors();if(!e)return!1;try{n.send({type:`error`,err:{name:`LikeC4ValidationError`,...splitErrorMessage(e.message),plugin:`vite-plugin-likec4`,loc:{file:e.sourceFsPath,line:e.line,column:e.range.start.character+1}}}),U.trace(s.dim(`sent LikeC4ValidationError`))}catch(e){U.error(t(e))}return!0},reloadProjects=async()=>{let e=o.projects();if(r(e)){U.trace(s.dim(`onProjectsUpdate - change detected`)),await reloadModule(at.virtualId),await reloadModule($e.virtualId),await reloadModule(rt.virtualId);for(let e of _t)await reloadModule(e.virtualId);e.length>1&&await reloadModule(st.virtualId)}else U.trace(s.dim(`onProjectsUpdate - no change`))};o.projectsManager.onProjectsUpdate(pDebounce(reloadProjects,100)),o.builder.onModelParsed(onModelParsedBatched(async e=>{if(!hasErrors())for(let t of e){U.trace(s.dim(`onModelParsed project`)+` `+s.cyan(t));for(let e of gt)await reloadModule(e.virtualId(t))}}))}}},async buildEnd(){d&&await o.dispose()}}]}function onModelParsedBatched(e){return O(n=>{e(n).catch(e=>{U.error(t(e))})},{reducer:(e,t)=>(e??=new Set,e.add(t),e),triggerAt:`end`,minQuietPeriodMs:130,maxBurstDurationMs:500}).call}export{generateDrawio as a,generateD2 as c,buildDrawioExportOptionsForViews as i,enhanceLayoutWithAI as l,generatePuml as n,generateDrawioMulti as o,generateMermaid as r,Re as s,LikeC4VitePlugin as t,U as u};
726
+ `},yt={...generateMatches(`webcomponents`),async load({project:e}){return logGenerating(`webcomponents`,e.id),{code:generateWebcomponentsCode(e.id),moduleType:`js`}}},bt=[ot,qe,tt,We,Ye,it,ft,Ze],xt=[Je,Ge,Xe,at,pt,Qe],St=[...bt,mt,yt],Ct=[lt,st,dt,vt,ht,...xt,rt,_t,Pe];function LikeC4VitePlugin({environments:e,appConfig:i,title:a,theme:s,useHashHistory:c,webcomponentPrefix:l,customization:d,ai:p=`auto`,...m}){let h=resolveAppOptions({title:a,theme:s,useHashHistory:c,webcomponentPrefix:l,customization:d},i),g,_,v,y=!1,b,x=m.watch??!1,S=[...Ct,createAppConfigModule(h)],initAI=async()=>{if(f(p))throw Error(`Invalid AI configuration: true is not allowed, use an object with adapter configuration or false to disable AI`);if(p!==`disabled`)return p===`auto`?await Ee():p};function moduleopts(e){return{rpcEnabled:y,isAIAvailable:!!b,ai:b,assetsDir:_,customizationFile:v,likec4:g,logger:U,...e}}let projectsChangeDetector=()=>{let e=E(e=>({id:e.id,title:e.title,path:e.path,folder:e.folder.toString(),landingPage:e.config.landingPage,exportFormats:effectiveWebappExportFormats(e.config)})),t;return n=>{let r=e(n);return t??=r,!u(t,r)&&(t=r,!0)}};return[iconBundlePlugin({environments:e?[e].flat():void 0,workspace:m.workspace??m.languageServices?.workspacePath}),{name:`vite-plugin-likec4`,sharedDuringBuild:!0,applyToEnvironment(t){return!e||e.includes(t.name)},async configResolved(e){let t=y=e.command===`serve`;if(h.customization&&(v=o(e.root,h.customization),!B(v)))throw Error(`LikeC4 customization file not found: ${v}`);if(m.languageServices)g=m.languageServices;else{let n=x=t&&(m.watch??!0);g=(await r(m.workspace??e.root,{manualLayouts:!0,graphviz:m.graphviz??`wasm`,configureLogger:`console`,logLevel:m.logLevel??`warning`,printErrors:m.printErrors??!0,throwIfInvalid:m.throwIfInvalid??!1,watch:n})).languageServices}_=g.workspaceUri.fsPath,y&&(b=await initAI())},resolveId:{filter:{id:/^likec4:/},handler(e){for(let t of St){let n=t.matches(e);if(n)return t.virtualId(n)}for(let t of S)if(t.id===e)return t.virtualId;return null}},load:{filter:{id:/likec4:plugin/},async handler(e){for(let t of St){let n=t.matches(e);if(n){let e=g.project(n);return await t.load.call(this,moduleopts({project:e}))}}let t=g.projects();if(!T(t,1))return null;for(let n of S)if(n.virtualId===e)return await n.load.call(this,moduleopts({projects:t}));return null}},async configureServer(e){if(y){if(enablePluginRPC.call(this,moduleopts({server:e})),b){U.info(n.dim(`enabling`)+` `+n.magenta(`AI Chat`));let{enableAIServer:t}=await import(`./enableServer.mjs`);t.call(this,moduleopts({server:e}))}return()=>{let r=e.hot,i=projectsChangeDetector(),reloadModule=async n=>{let r=e.moduleGraph.getModuleById(n);if(!r||r.importers.size===0)return!1;try{return await e.reloadModule(r),!0}catch(e){return U.error(t(e)),!1}},hasErrors=()=>{let[e]=g.getErrors();if(!e)return!1;try{r.send({type:`error`,err:{name:`LikeC4ValidationError`,...splitErrorMessage(e.message),plugin:`vite-plugin-likec4`,loc:{file:e.sourceFsPath,line:e.line,column:e.range.start.character+1}}}),U.trace(n.dim(`sent LikeC4ValidationError`))}catch(e){U.error(t(e))}return!0},reloadProjects=async()=>{let e=g.projects();if(i(e)){U.trace(n.dim(`onProjectsUpdate - change detected`)),await reloadModule(lt.virtualId),await reloadModule(rt.virtualId),await reloadModule(st.virtualId);for(let e of xt)await reloadModule(e.virtualId);e.length>1&&await reloadModule(dt.virtualId)}else U.trace(n.dim(`onProjectsUpdate - no change`))};g.projectsManager.onProjectsUpdate(pDebounce(reloadProjects,50)),g.builder.onModelParsed(onModelParsedBatched(async e=>{if(!hasErrors())for(let t of e){U.trace(n.dim(`onModelParsed project`)+` `+n.cyan(t));for(let e of bt)await reloadModule(e.virtualId(t))}}))}}},async buildEnd(){x&&await g.dispose()}}]}function onModelParsedBatched(e){return l(n=>{e(n).catch(e=>{U.error(t(e))})},{reducer:(e,t)=>(e??=/* @__PURE__ */ new Set,e.add(t),e),triggerAt:`end`,minQuietPeriodMs:100,maxBurstDurationMs:500}).call}export{generateDrawio as a,generateD2 as c,we as d,buildDrawioExportOptionsForViews as i,enhanceLayoutWithAI as l,generatePuml as n,generateDrawioMulti as o,generateMermaid as r,ze as s,LikeC4VitePlugin as t,U as u};