likec4 1.59.2 → 1.59.4

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 (69) hide show
  1. package/__app__/src/chunks/AIChat.mjs +118 -123
  2. package/__app__/src/chunks/LikeC4Styles.mjs +828 -686
  3. package/__app__/src/chunks/ProjectsOverview.mjs +82 -82
  4. package/__app__/src/chunks/es.mjs +1 -1
  5. package/__app__/src/chunks/hooks.mjs +164 -135
  6. package/__app__/src/chunks/libs/@floating-ui.mjs +649 -335
  7. package/__app__/src/chunks/libs/@mantine.mjs +2934 -2040
  8. package/__app__/src/chunks/libs/@tanstack-ai.mjs +28 -28
  9. package/__app__/src/chunks/libs/@tanstack.mjs +46 -51
  10. package/__app__/src/chunks/libs/@xstate/react.mjs +59 -40
  11. package/__app__/src/chunks/libs/@xyflow/react.mjs +535 -448
  12. package/__app__/src/chunks/libs/bezier-js.mjs +10 -9
  13. package/__app__/src/chunks/libs/d3.mjs +20 -45
  14. package/__app__/src/chunks/libs/fast-equals.mjs +62 -50
  15. package/__app__/src/chunks/libs/framer.mjs +300 -279
  16. package/__app__/src/chunks/libs/zod.mjs +17 -14
  17. package/__app__/src/chunks/rolldown-runtime.mjs +2 -2
  18. package/__app__/src/chunks/styled-system.mjs +2580 -132
  19. package/__app__/src/main.mjs +24925 -23485
  20. package/__app__/src/style.css +1 -1
  21. package/config/schema.json +49 -0
  22. package/dist/app/render-view-client.css +1 -0
  23. package/dist/app/render-view-client.js +739 -0
  24. package/dist/chunks/enableServer.mjs +1 -1
  25. package/dist/chunks/filenames.mjs +7 -6
  26. package/dist/chunks/index.d.mts +18 -1
  27. package/dist/chunks/index2.d.mts +79 -26
  28. package/dist/chunks/libs/@chevrotain/gast.mjs +1 -1
  29. package/dist/chunks/libs/@chevrotain/regexp-to-ast.mjs +5 -5
  30. package/dist/chunks/libs/@chevrotain/types.d.mts +108 -0
  31. package/dist/chunks/libs/@logtape/logtape.mjs +4 -4
  32. package/dist/chunks/libs/@lume/kiwi.mjs +1 -1
  33. package/dist/chunks/libs/birpc.mjs +1 -1
  34. package/dist/chunks/libs/chevrotain-allstar.mjs +1 -1
  35. package/dist/chunks/libs/chevrotain.mjs +16 -16
  36. package/dist/chunks/libs/json5.mjs +3 -3
  37. package/dist/chunks/libs/langium.d.mts +1777 -16
  38. package/dist/chunks/libs/langium.mjs +11 -11
  39. package/dist/chunks/libs/merge-error-cause.mjs +2 -2
  40. package/dist/chunks/libs/p-queue.mjs +1 -1
  41. package/dist/chunks/libs/package-manager-detector.mjs +1 -1
  42. package/dist/chunks/libs/pako.mjs +2 -2
  43. package/dist/chunks/libs/picomatch.mjs +1 -1
  44. package/dist/chunks/libs/pretty-ms.mjs +1 -1
  45. package/dist/chunks/libs/remeda.mjs +1 -1
  46. package/dist/chunks/libs/ufo.mjs +1 -1
  47. package/dist/chunks/libs/unstorage.mjs +1 -1
  48. package/dist/chunks/libs/zod.d.mts +1717 -17
  49. package/dist/chunks/libs/zod.mjs +4 -4
  50. package/dist/chunks/node.mjs +68 -57
  51. package/dist/chunks/rolldown-runtime.mjs +1 -1
  52. package/dist/chunks/sequence-view.mjs +1 -1
  53. package/dist/chunks/vite-plugin.mjs +168 -54
  54. package/dist/cli/index.d.mts +1 -1
  55. package/dist/cli/index.mjs +291 -165
  56. package/dist/config/index.d.mts +7 -1
  57. package/dist/config/index.mjs +1 -1
  58. package/dist/index.d.mts +3 -3
  59. package/dist/index.mjs +1 -1
  60. package/dist/model/index.d.mts +4 -4
  61. package/dist/vite-plugin/index.d.mts +2 -2
  62. package/dist/vite-plugin/internal/index.d.mts +72 -35
  63. package/dist/vite-plugin/internal/index.mjs +125 -44
  64. package/package.json +47 -47
  65. package/react/index.d.mts +22767 -1432
  66. package/react/index.mjs +38152 -32309
  67. package/vite-plugin-modules.d.ts +21 -1
  68. package/dist/chunks/dist.mjs +0 -10
  69. package/dist/chunks/logger.mjs +0 -1
@@ -1,20 +1,22 @@
1
- import{i as e}from"./rolldown-runtime.mjs";import{f as t,r as n,t as r}from"./dist.mjs";import{_ as i,b as a,g as o,h as s,y as c}from"./libs/langium.mjs";import{o as l}from"./libs/ufo.mjs";import{t as u}from"./libs/json5.mjs";import{R as d,S as f,a as p,c as m,n as h,w as g,y as _}from"./libs/zod.mjs";import{$ as v,B as y,F as b,H as ee,I as te,J as x,K as ne,N as S,Q as C,U as w,Z as T,b as E,c as D,h as O,k,o as A,r as j,t as M,tt as N,v as P,w as F,y as re}from"./libs/remeda.mjs";import{n as ie}from"./node.mjs";import{n as ae,t as oe}from"./libs/package-manager-detector.mjs";import{n as I,t as L}from"./logger.mjs";import{t as se}from"./libs/birpc.mjs";import{t as ce}from"./libs/pako.mjs";import{createRequire as le}from"node:module";import{mkdir as ue,readFile as de,writeFile as fe}from"node:fs/promises";import{resolve as R}from"node:path";import{RichText as pe,exact as me,flattenMarkdownOrString as z}from"@likec4/core/types";import{DefaultMap as B,LikeC4Styles as he,exact as V,invariant as ge,nonexhaustive as _e}from"@likec4/core";import{compareNatural as ve,nonNullable as ye}from"@likec4/core/utils";import"@likec4/core/model";import be from"nano-spawn";import{existsSync as xe}from"node:fs";import{env as H}from"std-env";import U,{cwd as Se}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 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=>l(`likec4:plugin`,n,e)+t}}function generateCombinedProjects(e,t){return{id:`likec4:${e}`,virtualId:`likec4:plugin/`+e+`.js`,async load({projects:n}){return L(e),{code:`
2
- export let ${t}Fn = {
3
- ${n.map(({id:t})=>`${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(t))}: async () => await import(${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(l(`likec4:${e}`,t)))})`).join(`,
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:`
2
+ export let ${o} = {
3
+ ${i.join(`,
4
4
  `)}
5
5
  }
6
6
 
7
7
  export async function ${t}(projectId) {
8
- let fn = ${t}Fn[projectId]
8
+ let fn = ${o}[projectId]
9
9
  if (!fn) {
10
- const projects = Object.keys(${t}Fn)
10
+ const projects = Object.keys(${o})
11
11
  console.error('Unknown projectId: ' + projectId + ' (available: ' + projects + ')')
12
+ ${n?`throw new Error(${a} + projectId)`:`
12
13
  if (projects.length === 0) {
13
14
  throw new Error('No projects found, invalid state')
14
15
  }
15
16
  projectId = projects[0]
16
17
  console.warn('Falling back to project: ' + projectId)
17
- fn = ${t}Fn[projectId]
18
+ fn = ${o}[projectId]
19
+ `}
18
20
  }
19
21
  return await fn()
20
22
  }
@@ -22,25 +24,23 @@ export async function ${t}(projectId) {
22
24
  if (import.meta.hot) {
23
25
  import.meta.hot.accept(md => {
24
26
  if (!import.meta.hot.data.$update) {
25
- import.meta.hot.data.$update = ${t}Fn
27
+ import.meta.hot.data.$update = ${o}
26
28
  }
27
- const update = md.${t}Fn
29
+ const update = md.${o}
28
30
  if (update) {
29
- for (const [id, fn] of Object.entries(update)) {
30
- import.meta.hot.data.$update[id] ??= fn
31
- }
31
+ Object.assign(import.meta.hot.data.$update, update)
32
32
  } else {
33
33
  import.meta.hot.invalidate()
34
- }
34
+ }
35
35
  })
36
36
  }
37
- `,moduleType:`js`}}}}function isInstalled(e){try{return!!import.meta.resolve(e,U.cwd())}catch(e){return I.trace(t(e)),!1}}async function ensurePackage(e){let n=I.getChild(`pkg`);if(isInstalled(e)){n.trace`${e} installed`;return}n.warn(r.dim(`not found `)+r.green(e));let{command:i,args:a}=ye(ae(ye(await oe(),()=>{n.error`Package manager not detected, install ${e} manually`,U.exit(1)}).agent,`add`,[e]),()=>{n.error`Install package ${e} manually`,U.exit(1)});n.info(r.dim(`installing `)+r.green(e));try{await be(i,a)}catch(r){n.debug(t(r)),n.error`Install package ${e} manually`,U.exit(1)}}const W=I.getChild(`ai`);function chooseModel(e,t){let n=H[e];return n||=(W.info(`I will use `+r.green(t)+` model `+r.dim(`you can override with `)+r.yellow(e)+r.dim(` env var`)),t),n}const G=16e3;async function loadOpenAI(){W.info(`Found `+r.yellow(`OPENAI_API_KEY`)+r.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 `+r.yellow(`OPENROUTER_API_KEY`)+r.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 `+r.yellow(`ANTHROPIC_API_KEY`)+r.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 `+r.yellow(`GEMINI_API_KEY`)+r.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 `+r.yellow(`OLLAMA_HOST`)+r.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}}function pickLoader(){if(F(H.OPENAI_API_KEY))return loadOpenAI;if(F(H.OPENROUTER_API_KEY))return loadOpenRouter;if(F(H.ANTHROPIC_API_KEY))return loadAnthropic;if(F(H.GEMINI_API_KEY))return loadGemini;if(F(H.OLLAMA_HOST))return loadOllama}const Ce=O(async()=>{let e=pickLoader();if(e){await ensurePackage(`@tanstack/ai`);let t=await e();return W.info([`AI configured with`,r.green(t.adapter.name),`adapter`,r.dim(`you can disable it in plugin options`)].join(` `)),t}}),K=I.getChild(`icons`);function iconBundlePlugin(e){let t=Se(),n=[t];e.workspace&&n.unshift(e.workspace);let i=le(t),a,resolveIcon=async(e,t)=>{try{let a=i.resolve(`@likec4/icons/${e}/${t}`,{paths:n});return K.trace(r.dim(`found in package `)+a),await de(a,`utf-8`)}catch{return}},readFromCache=async(e,t)=>{if(a)try{let n=R(a,e,`${t}.js`);if(xe(n))return K.trace(r.dim(`read cached `)+`${e}/${t}.js`),await de(n,`utf-8`)}catch{}},writeToCache=async(e,t,n)=>{if(a)try{let i=R(a,e);xe(i)||await ue(i,{recursive:!0});let o=R(i,`${t}.js`);await fe(o,n),K.trace(r.dim(`written to cache `)+o)}catch(n){K.error(r.dim(`failed to write to cache `)+`${e}/${t}.js`,{error:n})}},fetchFromRemote=async(e,t)=>{let n=l(`https://icons.like-c4.dev`,e,`${t}.js`);K.trace(r.dim(`fetching `)+n);let i=await fetch(n);if(!i.ok)throw Error(`Failed to fetch icon: ${i.status} ${i.statusText}`);return await i.text()},o=new B(async e=>{try{let[t,n]=e.split(`:`);(n.endsWith(`.jsx`)||n.endsWith(`.js`))&&(n=n.slice(0,n.lastIndexOf(`.`))),K.debug(r.dim(`resolving `)+r.green(`${t}:${n}`));let i=await readFromCache(t,n);return i??=await resolveIcon(t,n),i||(i=await fetchFromRemote(t,n),await writeToCache(t,n,i),i)}catch(t){return K.error(r.dim(`failed to resolve icon `)+r.red(e),{error:t}),`
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}),`
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&&(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(!v(t,2))return null;let[n,r]=t;return{moduleType:`jsx`,code:await o.get(`${n}:${r}`)}}}}}const q=n(`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(me({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(me({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 we=p([`TB`,`BT`,`LR`,`RL`]),J=g().nonempty().brand(),Te=_({rank:p([`same`,`source`,`sink`,`min`,`max`]),nodes:m(J)}),Y={id:g().nonempty().brand(),weight:h().int().min(0).max(20),minlen:h().int().min(0).max(4)},Ee=_({source:J,target:J,weight:Y.weight.optional(),minlen:Y.minlen.optional()}),De=_({direction:we.optional(),ranks:m(Te).default([]),edgeWeight:f(Y.id,Y.weight).default({}),edgeMinlen:f(Y.id,Y.minlen).default({}),reverseRank:m(Y.id).default([]),excludeFromRanking:m(Y.id).default([]),edgeOrder:m(Y.id).default([]),nodeOrder:m(J).default([]),invisibleEdges:m(Ee).default([]),reasoning:g().default(``)}),Oe=/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/;function extractJson(e){let t=Oe.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=u.parse(n),i=De.safeParse(r);if(!i.success){q.warn(`Failed to validate LLM response
42
- `+d(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=>N(e,E(nodeId),T(b)),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(b);return v(n,1)?n:void 0},r=N(e.excludeFromRanking,E(edgeId),T(b),j(),e=>v(e,1)?e:void 0),i=N(e.reverseRank,E(edgeId),T(b),j(),e=>v(e,1)?e:void 0),a=(()=>{let e=new Set;return t=>t.filter(t=>e.has(t)?!1:(e.add(t),!0))})(),o=N(e.ranks,E(e=>{let t=a(mapToNodeId(e.nodes));return v(t,1)?{rank:e.rank,nodes:t}:null}),T(F)),s=N(e.invisibleEdges,E(({source:e,target:t,minlen:n=1,weight:r=1})=>{let i=nodeId(e),a=nodeId(t);if(!(!i||!a))return V({weight:r===1?void 0:r,minlen:n===1?void 0:n,source:i,target:a})}),T(b),ee(e=>`${e.source}->${e.target}`),P(([e,...t])=>N(t,D((e,t)=>V({...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))),M(),e=>v(e,1)?e:void 0),c=e.reasoning;c&&(c=c.replaceAll(`][`,`] [`),C(t.mapping.nodes).forEach(([e,t])=>{c=c.replaceAll(RegExp(`\\[${e}\\]`,`g`),"`"+t.id+"`")}),C(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 C(e)){let e=edgeId(n);e&&(t[e]=r)}return t};return V({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 ke={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}){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.
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)
@@ -226,10 +226,10 @@ 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({...ke,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:i},a){ge(t,`AI is not configured`),e.info([r.green(`semantic:layout`),r.dim(`project:`),a.projectId,r.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 n.computedModel(a.projectId)).findView(a.viewId);ge(l,`View ${a.viewId} not found in project ${a.projectId}`),e.info([r.green(`semantic:layout`),r.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);break}return a}});if(o.completed(),!u){e.warn([r.yellow(`semantic:layout`),`No semantic layout generated`].join(` `));return}e.info([r.green(`semantic:layout`),r.dim(`apply ai hints to layout`)].join(` `));let d=await n.views.layoutView({viewId:a.viewId,projectId:a.projectId,layoutHints:u});if(!d){e.error([r.red(`semantic:layout`),`layout hints failed`].join(` `));return}e.info([r.green(`semantic:layout`),r.dim(`save view snapshot`)].join(` `));let f=await n.editor.applyChange({viewId:a.viewId,projectId:a.projectId,change:{op:`save-view-snapshot`,layout:d.diagram}});if(!f.success){e.error([r.red(`semantic:layout`),`apply change failed`,f.error].join(` `));let t=Error(f.error);throw t.stack=f.error,t}e.info([r.green(`semantic:layout`),r.dim(`project:`),a.projectId,r.dim(`view:`),a.viewId,`✅`].join(` `))}async function calcAdhocView({logger:e,likec4:t},n){e.info([r.green(`adhoc:view`),r.dim(`project:`),n.projectId].join(` `));let i=await t.views.adhocView(n.predicates,n.projectId);return e.info([r.green(`adhoc:view`),`✅`].join(` `)),i}async function updateView({logger:e,likec4:t},n){e.info([r.green(`view:onChange`),r.dim(`project`),n.projectId,r.dim(`view`),n.viewId,r.dim(`change`),n.change.op].join(` `));let i=await t.editor.applyChange(n);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([r.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: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(`
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;se({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 L(`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;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`),`
233
233
  export let ComponentName = {
234
234
  View: ${JSON.stringify(t+`-view`)},
235
235
  Browser: ${JSON.stringify(t+`-browser`)},
@@ -252,11 +252,11 @@ export let defaultTheme = ${JSON.stringify(i)}
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 Ae=e(e=>e.charAt(0).toLocaleUpperCase()+e.slice(1),`capitalizeFirstLetter`),je=e(e=>e.split(`.`).map(Ae).join(``),`fqnName`),Me=e(e=>je(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:r}=t,a=new Map,printNode=(e,t)=>{let r=Me(e),c=(t?t+`.`:``)+r;a.set(e.id,c);let l=JSON.stringify(e.title),u=d2shape(e);return new o().append(r,`: {`,i).indent({indentedChildren:t=>t.append(`label: `,l,i).appendIf(u!==`rectangle`,`shape: `,u,i).appendIf(e.children.length>0,i,s(n.filter(t=>t.parent===e.id),e=>printNode(e,c))),indentation:2}).append(`}`,i)},printEdge=e=>new o().append(a.get(e.source),` -> `,a.get(e.target)).append(t=>e.label&&t.append(`: `,JSON.stringify(e.label)));return c(new o().append(`direction: `,d2direction(t),i,i).append(s(n.filter(e=>k(e.parent)),e=>printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(r.length>0,i,s(r,e=>printEdge(e),{appendNewLineIfNotEmpty:!0})))}const X=`data:page/id,likec4-`,Ne=`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(ce.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 Z={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}},Q={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??he.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 he.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(`${X}${e}`)};`}function toExportString(e){let t=e==null?null:z(e);return t!=null&&!S(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 Pe=/^#([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&&Pe.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:Q.getKind(e),edgeNotation:Q.getNotation(e),edgeLinksJson:linksToStyleJson(Q.getLinks(e)),edgeMetadataJson:metadataToStyleJson(Q.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
- ${u}${buildMxUserObjectXml(Q.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(Z.getNotes(e)),_=Z.getTags(e),v=Array.isArray(_)&&_.length>0?_.join(`,`):``,y=toNonEmptyString(Z.getNavigateTo(e)),b=toNonEmptyString(Z.getIcon(e)),ee=f===`actor`||e.shape===`person`,te=d?`shape=rectangle;rounded=0;container=1;collapsible=0;startSize=0;`:ee?`shape=actor;`:drawioShape(e.shape),x=l?.[e.id],ne=u?.[e.id],S=x?applyStrokeColorOverride(getElementColors(r,e.color),x):getElementColors(r,e.color),C=S?.fill??`#dae8fc`,w=S?.stroke??`#2563eb`,T=S?.font??S?.stroke??`#1e40af`,E=`fillColor=${C};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=ne??getDefaultStrokeWidth(A,d),M=j===``?``:`strokeWidth=${j};`,N=getContainerDashedStyle(d,A),P=d===!0?D?.opacity??15:void 0,F=P!=null&&d===!0?`fillOpacity=${Math.min(100,Math.max(0,P))};`:``,re=buildLikec4StyleForNode({desc:m,tech:h,notes:g,tagList:v,navTo:y,iconName:b,summaryStr:toExportString(Z.getSummary(e)),linksJson:linksToStyleJson(Z.getLinks(e)),borderVal:A,containerOpacityNum:P,strokeWidth:j,colorNameForRoundtrip:e.color?encodeURIComponent(String(e.color)):``,nodeStyle:D,strokeHex:w,nodeNotation:Z.getNotation(e)})+buildBridgeManagedStyleForNode(e.id,f,t.view.id,n),ie=buildMxUserObjectXml(Z.getCustomData(e)),ae=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)};`}${te}${E}${M}${N}${F}${ae}${re}`,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="${X}${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="${X}${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 $={x:0,y:0,width:120,height:60};function isDefaultBbox(e){return e.x===$.x&&e.y===$.y&&e.width===$.width&&e.height===$.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=(Z.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:800/2-a,offsetY:600/2-o,canvasWidth:800,canvasHeight:600}}function computeDiagramLayout(e,t){let n=e.$view,{nodes:r}=n,i=t?.layoutOverride,a=[...r].sort((e,t)=>k(e.parent)&&k(t.parent)?0:k(e.parent)?-1:k(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=Z.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}">
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}">
258
+ ${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}">
260
260
  <mxGeometry x="0" y="0" width="${l}" height="${u}" as="geometry" />
261
261
  </mxCell>`,...p,...m,...h].join(`
262
262
  `),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">
@@ -272,8 +272,8 @@ export let krokiPumlSvgUrl = import.meta.env.VITE_KROKI_D2_SVG_URL || 'https://k
272
272
  ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}">${e.content}</diagram>`).join(`
273
273
  `)}
274
274
  </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 Fe=e(e=>e.charAt(0).toLocaleUpperCase()+e.slice(1),`capitalizeFirstLetter`),Ie=e(e=>e.split(`.`).map(Fe).join(``),`fqnName`),Le=e(e=>Ie(e.parent?e.id.slice(e.parent.length+1):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:_e(e)}};function generateMermaid(e){let t=e.$view,{nodes:n,edges:r}=t,a=new Map,printNode=(e,t)=>{let r=Le(e),c=(t?t+`.`:``)+r;a.set(e.id,c);let l=new o;if(e.children.length>0){let t=toSingleQuotes(e.title);l.append(`subgraph `,c,'["`',t,'`"]',i).indent({indentedChildren:[s(n.filter(t=>t.parent===e.id),e=>printNode(e,c),{appendNewLineIfNotEmpty:!0})],indentation:2}).append(`end`,i)}else l.append(c,mmdshape(e));return l},printEdge=e=>new o().append(a.get(e.source),` -.`,e.label?' "`'+toSingleQuotes(e.label)+'`" .-':`-`,`> `,a.get(e.target));return c(new o().append(`---`,i,`title: ${JSON.stringify(toSingleQuotes(e.titleOrId))}`,i,`---`,i).append(`graph `,t.autoLayout.direction,i).indent({indentedChildren:e=>{e.append(s(n.filter(e=>k(e.parent)),e=>printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(r.length>0,s(r,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:_e(e)}},escapeLabel=e=>S(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:a}=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,l=new Map,printHeader=()=>new o().append(`title "`,e.titleOrId,`"`,i).append(pumlDirection(t),` direction`,i),printTheme=()=>new o().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 o().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);l.set(e.id,n);let s=pe.from(e.description);return new o().append(t,` `).append(`"`).append(`==`,r).appendIf(!!a,`\\n<size:10>[`,a,`]</size>`).appendIf(s.nonEmpty,`\\n\\n`,escapeLabel(s.text)).append(`"`,` <<`,n,`>> `,`as `,n,i)},printBoundary=e=>{let t=escapeLabel(e.title)||nodeName(e),n=fqnName(e.id);return l.set(e.id,n),new o().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(s(r.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 o().append(l.get(e.source),` .[`,r,`,thickness=2].> `,l.get(e.target));return(n||t)&&(a.append(` : `,n.split(`
276
- `).map(e=>S(e)?e:withColor(e)).join(`\\n`)),t&&t!==n&&a.append(`\\n<size:8>[`,withColor(t),`]</size>`)),a.append(i)};return c(new o().append(`@startuml`,i).append(printHeader(),i).append(printTheme(),i).append(s(r.filter(e=>e.children.length==0),e=>printStereotypes(e),{appendNewLineIfNotEmpty:!0})).append(s(r.filter(e=>k(e.parent)),e=>e.children.length>0?printBoundary(e):printNode(e),{appendNewLineIfNotEmpty:!0})).appendIf(a.length>0,i,s(a,e=>printEdge(e),{appendNewLineIfNotEmpty:!0})).append(`@enduml`,i))}function code$9(e){let t=new o;return t.appendTemplate`
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`
277
277
  /******************************************************************************
278
278
  * This file was generated
279
279
  * DO NOT EDIT MANUALLY!
@@ -282,7 +282,7 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
282
282
 
283
283
  export let d2Source = (viewId) => {
284
284
  switch (viewId) {
285
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(s([...e.views()],e=>a`
285
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d([...e.views()],e=>l`
286
286
  case ${JSON.stringify(e.id)}: {
287
287
  return ${JSON.stringify(generateD2(e))}
288
288
  }
@@ -290,9 +290,9 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
290
290
  default: {
291
291
  throw new Error('Unknown viewId: ' + viewId)
292
292
  }
293
- `}}).append(i,` }`,i).appendTemplate`
293
+ `}}).append(c,` }`,c).appendTemplate`
294
294
  }
295
- `.append(i,i),c(t)}e(code$9,`code`);const Re={...generateMatches(`d2`),async load({likec4:e,project:t}){return L(`d2`,t.id),{code:code$9(await e.computedModel(t.id)),moduleType:`js`}}},ze=generateCombinedProjects(`d2`,`loadD2Sources`);function code$8(e){let t=new o;return t.appendTemplate`
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`
296
296
  /******************************************************************************
297
297
  * This file was generated
298
298
  * DO NOT EDIT MANUALLY!
@@ -301,7 +301,7 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
301
301
 
302
302
  export let dotSource = (viewId) => {
303
303
  switch (viewId) {
304
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(s(Object.keys(e),t=>a`
304
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d(Object.keys(e),t=>l`
305
305
  case ${JSON.stringify(t)}: {
306
306
  return ${JSON.stringify(e[t].dot)}
307
307
  }
@@ -309,12 +309,12 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
309
309
  default: {
310
310
  throw new Error('Unknown viewId: ' + viewId)
311
311
  }
312
- `}}).append(i,` }`,i).appendTemplate`
312
+ `}}).append(c,` }`,c).appendTemplate`
313
313
  }
314
314
 
315
315
  export let svgSource = (viewId) => {
316
316
  switch (viewId) {
317
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(s(Object.keys(e),t=>a`
317
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d(Object.keys(e),t=>l`
318
318
  case ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(t))}: {
319
319
  return ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e[t].svg))}
320
320
  }
@@ -322,7 +322,7 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
322
322
  default: {
323
323
  throw new Error('Unknown viewId: ' + viewId)
324
324
  }
325
- `}}).append(i,` }`,i,`}`,i,i),c(t)}e(code$8,`code`);const Be={...generateMatches(`dot`),async load({likec4:e,project:t}){return L(`dot`,t.id),{code:code$8(re(await e.views.viewsAsGraphvizOut(t.id),({id:e,svg:t,dot:n})=>[e,{dot:n,svg:t}])),moduleType:`js`}}},Ve=generateCombinedProjects(`dot`,`loadDotSources`);function code$7(e){let t=new o;return t.appendTemplate`
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`
326
326
  /******************************************************************************
327
327
  * This file was generated
328
328
  * DO NOT EDIT MANUALLY!
@@ -331,7 +331,7 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
331
331
 
332
332
  export function drawioEditUrl(viewId) {
333
333
  switch (viewId) {
334
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(s([...e.views()],e=>a`
334
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d([...e.views()],e=>l`
335
335
  case ${JSON.stringify(e.id)}: {
336
336
  return ${JSON.stringify(generateDrawioEditUrl(generateDrawio(e)))}
337
337
  }
@@ -339,9 +339,9 @@ ${e.map(e=>` <diagram name="${escapeXml(e.name)}" id="likec4-${escapeXml(e.id)}
339
339
  default: {
340
340
  throw new Error('Unknown viewId: ' + viewId)
341
341
  }
342
- `}}).append(i,` }`,i).appendTemplate`
342
+ `}}).append(c,` }`,c).appendTemplate`
343
343
  }
344
- `.append(i,i),c(t)}e(code$7,`code`);const He={...generateMatches(`drawio`),async load({likec4:e,project:t}){return L(`drawio`,t.id),{code:code$7(await e.layoutedModel(t.id)),moduleType:`js`}}},Ue=generateCombinedProjects(`drawio`,`loadDrawioSources`),We=/^(https?:)?\/\//i;function code$6(e){let{imports:t,cases:n}=N(e,ne(e=>e.nodes),E(e=>e.icon??void 0),T(e=>F(e)&&!We.test(e)),j(),A(ve)).reduce((e,t,n)=>{let r=t.startsWith(`file:`),i=`Icon`+n.toString().padStart(2,`0`);if(r)return e.imports.push(`import ${i} from '${t}?inline'`),e.cases.push(` '${t}': () => jsx('img', { src: ${i} })`),e;let[a,o]=t.split(`:`),s=`likec4:icon-bundle/${a}/${o}.jsx`;return e.imports.push(`import ${i} from '${s}'`),e.cases.push(` '${a}:${o}': ${i}`),e},{imports:[],cases:[]});return`
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`
345
345
  import { jsx } from 'react/jsx-runtime'
346
346
  ${t.join(`
347
347
  `)}
@@ -350,6 +350,36 @@ const Icons = {
350
350
  ${n.join(`,
351
351
  `)}
352
352
  }
353
+
354
+ function MaskedSvgIcon({ src, style, ...props }) {
355
+ const maskUrl = 'url(' + JSON.stringify(src) + ')'
356
+ return jsx('span', {
357
+ ...props,
358
+ style: {
359
+ ...style,
360
+ display: 'inline-block',
361
+ width: '100%',
362
+ height: '100%',
363
+ backgroundColor: 'currentColor',
364
+ maskImage: maskUrl,
365
+ maskRepeat: 'no-repeat',
366
+ maskPosition: 'center',
367
+ maskSize: 'contain',
368
+ WebkitMaskImage: maskUrl,
369
+ WebkitMaskRepeat: 'no-repeat',
370
+ WebkitMaskPosition: 'center',
371
+ WebkitMaskSize: 'contain'
372
+ }
373
+ })
374
+ }
375
+
376
+ function LocalSvgIcon({ src, raw, ...props }) {
377
+ if (typeof raw === 'string' && /currentcolor/i.test(raw)) {
378
+ return jsx(MaskedSvgIcon, { ...props, src })
379
+ }
380
+ return jsx('img', { ...props, src })
381
+ }
382
+
353
383
  export function IconRenderer({ node, ...props }) {
354
384
  const IconComponent = Icons[node.icon ?? '']
355
385
  if (!IconComponent) {
@@ -357,13 +387,13 @@ export function IconRenderer({ node, ...props }) {
357
387
  }
358
388
  return jsx(IconComponent, props)
359
389
  }
360
- `}e(code$6,`code`);const Ge={...generateMatches(`icons`,`.jsx`),async load({likec4:e,project:t}){L(`icons`,t.id);let n=await e.computedModel(t.id);return{moduleType:`jsx`,code:code$6([...M(n.$data.views),...M(n.$data.manualLayouts??{})])}}},Ke=/^[a-zA-Z0-9_.-]+$/;function embedProjectIdAsJsString(e){if(!Ke.test(e))throw Error(`Unsafe value for code generation: ${e}`);return JSON.stringify(e)}function embedUrlAsJsString(e){return JSON.stringify(e)}const qe={id:`likec4:icons`,virtualId:`likec4:plugin/icons.jsx`,async load({projects:e,logger:t}){L(`icons`);let{imports:n,cases:i}=e.filter(e=>Ke.test(e.id)?!0:(t.warn(r.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(l(`likec4:icons`,t.id)));return e.imports.push(`import {IconRenderer as ${r}} from ${a}`),e.cases.push(` ${i}: ${r}`),e},{imports:[],cases:[]});return{code:`
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:`
361
391
  import { jsx } from 'react/jsx-runtime'
362
392
  ${n.join(`
363
393
  `)}
364
394
 
365
395
  export let ProjectIconsRegistry = {
366
- ${i.join(`,
396
+ ${r.join(`,
367
397
  `)}
368
398
  }
369
399
 
@@ -397,7 +427,7 @@ if (import.meta.hot) {
397
427
  }
398
428
  })
399
429
  }
400
- `,moduleType:`jsx`}}};function code$5(e){let t=new o;return t.appendTemplate`
430
+ `,moduleType:`jsx`}}};function code$5(e){let t=new u;return t.appendTemplate`
401
431
  /******************************************************************************
402
432
  * This file was generated
403
433
  * DO NOT EDIT MANUALLY!
@@ -406,7 +436,7 @@ if (import.meta.hot) {
406
436
 
407
437
  export let mmdSource = (viewId) => {
408
438
  switch (viewId) {
409
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(s([...e.views()],e=>a`
439
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d([...e.views()],e=>l`
410
440
  case ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e.id))}: {
411
441
  return ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(generateMermaid(e)))}
412
442
  }
@@ -414,13 +444,13 @@ if (import.meta.hot) {
414
444
  default: {
415
445
  throw new Error('Unknown viewId: ' + viewId)
416
446
  }
417
- `}}).append(i,` }`,i).appendTemplate`
447
+ `}}).append(c,` }`,c).appendTemplate`
418
448
  }
419
449
 
420
- `.append(i,i),c(t)}e(code$5,`code`);const Je={...generateMatches(`mmd`),async load({likec4:e,project:t}){return L(`mmd`,t.id),{code:code$5(await e.computedModel(t.id)),moduleType:`js`}}},Ye=generateCombinedProjects(`mmd`,`loadMmdSources`),projectModelCode=e=>`
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=>`
421
451
  import { createHooksForModel, atom } from 'likec4/vite-plugin/internal'
422
452
 
423
- export let $likec4data = atom(${u.stringify(e.$data)})
453
+ export let $likec4data = atom(${m.stringify(e.$data)})
424
454
 
425
455
  export let {
426
456
  updateModel,
@@ -443,11 +473,11 @@ if (import.meta.hot) {
443
473
  }
444
474
  })
445
475
  }
446
- `,Xe={...generateMatches(`model`),async load({likec4:e,project:t}){L(`model`,t.id);let n=await e.layoutedModel(t.id);return{code:projectModelCode(n),moduleType:`js`}}},Ze=generateCombinedProjects(`model`,`loadModel`),Qe=e(e=>`
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=>`
447
477
  import { atom, useStore } from 'likec4/vite-plugin/internal'
448
478
 
449
479
  export const isSingleProject = ${e.length===1};
450
- export const projects = ${u.stringify(e,null,2)};
480
+ export const projects = ${m.stringify(e,null,2)};
451
481
 
452
482
  export const $projects = atom([...projects])
453
483
 
@@ -473,10 +503,10 @@ if (import.meta.hot) {
473
503
  }
474
504
  })
475
505
  }
476
- `,`code`),$e={id:`likec4:projects`,virtualId:`likec4:plugin/projects.js`,async load({projects:e}){return L(`projects`),{code:Qe(E(e,e=>({id:e.id,title:e.title,landingPage:e.config.landingPage}))),moduleType:`js`}}},et=e(e=>`
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=>`
477
507
  import { atom, useStore } from 'likec4/vite-plugin/internal'
478
508
 
479
- export const $viewdata = atom(${u.stringify(e)})
509
+ export const $viewdata = atom(${m.stringify(e)})
480
510
 
481
511
  export function useLikeC4ProjectsOverview() {
482
512
  return useStore($viewdata)
@@ -499,7 +529,7 @@ if (import.meta.hot) {
499
529
  export function useLikeC4ProjectsOverview() {
500
530
  throw new Error('No projects overview available for this workspace: single project mode is enabled')
501
531
  }
502
- `,tt={id:`likec4:projects-overview`,virtualId:`likec4:plugin/projects-overview.js`,async load({projects:e,likec4:t}){if(e.length<2)return noProjects();L(`projects-overview`);let n=await t.projectsOverview();return{code:et(n),moduleType:`js`}}};function code$2(e){let t=new o;return t.appendTemplate`
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`
503
533
  /******************************************************************************
504
534
  * This file was generated
505
535
  * DO NOT EDIT MANUALLY!
@@ -508,7 +538,7 @@ export function useLikeC4ProjectsOverview() {
508
538
 
509
539
  export let pumlSource = (viewId) => {
510
540
  switch (viewId) {
511
- `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(s([...e.views()],e=>a`
541
+ `.appendNewLine().indent({indentation:4,indentedChildren(t){t.append(d([...e.views()],e=>l`
512
542
  case ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e.id))}: {
513
543
  return ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(generatePuml(e)))}
514
544
  }
@@ -516,9 +546,9 @@ export function useLikeC4ProjectsOverview() {
516
546
  default: {
517
547
  throw new Error('Unknown viewId: ' + viewId)
518
548
  }
519
- `}}).append(i,` }`,i).appendTemplate`
549
+ `}}).append(c,` }`,c).appendTemplate`
520
550
  }
521
- `.append(i,i),c(t)}e(code$2,`code`);const nt={...generateMatches(`puml`),async load({likec4:e,project:t}){return L(`puml`,t.id),{code:code$2(await e.computedModel(t.id)),moduleType:`js`}}},rt=generateCombinedProjects(`puml`,`loadPumlSources`),projectCode=e=>`
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=>`
522
552
  import { jsx as _jsx } from "react/jsx-runtime";
523
553
  import { LikeC4ModelProvider as Provider, LikeC4View as GenericView, ReactLikeC4 as GenericReactLikeC4 } from 'likec4/react';
524
554
  import { IconRenderer } from 'likec4:icons/${e}'
@@ -541,14 +571,14 @@ export {
541
571
  useLikeC4View,
542
572
  useLikeC4Views
543
573
  }
544
- `,it={...generateMatches(`react`),async load({project:e}){return L(`react`,e.id),{code:projectCode(e.id),moduleType:`js`}}},at={id:`likec4:react`,virtualId:`likec4:plugin/react.js`,async load({projects:e}){let t=x(e);return L(`react-default-project`),{code:`export {
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 {
545
575
  useLikeC4Model,
546
576
  useLikeC4View,
547
577
  useLikeC4Views,
548
578
  LikeC4ModelProvider,
549
579
  LikeC4View,
550
580
  ReactLikeC4
551
- } from 'likec4:react/${t.id}'`,moduleType:`js`}}},ot=e(({isAIAvailable:e,ai:t,rpcEnabled:n})=>`
581
+ } from 'likec4:react/${t.id}'`,moduleType:`js`}}},ft=e(({isAIAvailable:e,ai:t,rpcEnabled:n})=>`
552
582
  import { createRpc } from 'likec4/vite-plugin/internal'
553
583
 
554
584
  export const isRpcAvailable = !!import.meta.hot && ${n}
@@ -580,7 +610,7 @@ export const likec4rpc = rpc ?? {
580
610
  throw new Error('likec4rpc.calcAdhocView is not available in production')
581
611
  },
582
612
  }
583
- `,`code`),st={id:`likec4:rpc`,virtualId:`likec4:plugin/rpc.js`,async load(e){return L(`rpc`),{code:ot(e),moduleType:`js`,moduleSideEffects:!1}}},code=e=>`
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=>`
584
614
  export { IconRenderer } from 'likec4:icons/${e}'
585
615
  export {
586
616
  $likec4data,
@@ -590,4 +620,88 @@ export {
590
620
  useLikeC4View
591
621
  } from 'likec4:model/${e}'
592
622
  export const projectId = ${hardenJsonStringLiteralForEmbeddedScript(JSON.stringify(e))}
593
- `,ct={id:`likec4:single-project`,virtualId:`likec4:plugin/single-project.js`,async load({projects:e}){let t=x(e);return L(`single-project`,t.id),code(t.id)}},lt=[Xe,Ge,Re,Be,Je,nt,He],ut=[...lt,it],dt=[$e,Ze,tt,ct,at,ze,Ve,Ye,rt,Ue,qe,st];function LikeC4VitePlugin({environments:e,appConfig:n,ai:i=`auto`,...a}){let o,s,c=!1,l,u=a.watch??!1,d=[...dt,createAppConfigModule(n)],initAI=async()=>{if(te(i))throw Error(`Invalid AI configuration: true is not allowed, use an object with adapter configuration or false to disable AI`);if(i!==`disabled`)return i===`auto`?await Ce():i};function moduleopts(e){return{rpcEnabled:c,isAIAvailable:!!l,ai:l,assetsDir:s,likec4:o,logger:I,...e}}let projectsChangeDetector=()=>{let e=E(e=>({id:e.id,title:e.title,folder:e.folder.toString(),landingPage:e.config.landingPage})),t;return n=>{let r=e(n);return t??=r,y(t,r)?!1:(t=r,!0)}};return[iconBundlePlugin({environments:e?[e].flat():void 0,workspace:a.workspace??a.languageServices?.workspacePath}),{name:`vite-plugin-likec4`,sharedDuringBuild:!0,applyToEnvironment(t){return!e||e.includes(t.name)},async configResolved(e){let t=c=e.command===`serve`;if(a.languageServices)o=a.languageServices;else{let n=u=t&&(a.watch??!0);o=(await ie(a.workspace??e.root,{manualLayouts:!0,graphviz:a.graphviz??`wasm`,configureLogger:`console`,logLevel:a.logLevel??`warning`,printErrors:a.printErrors??!0,throwIfInvalid:a.throwIfInvalid??!1,watch:n})).languageServices}s=o.workspaceUri.fsPath,c&&(l=await initAI())},resolveId:{filter:{id:/^likec4:/},handler(e){for(let t of ut){let n=t.matches(e);if(n)return t.virtualId(n)}for(let t of d)if(t.id===e)return t.virtualId;return null}},load:{filter:{id:/likec4:plugin/},async handler(e){for(let t of ut){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 d)if(t.virtualId===e){let e=o.projects();return v(e,1)?await t.load.call(this,moduleopts({projects:e})):null}return null}},async configureServer(e){if(c){if(enablePluginRPC.call(this,moduleopts({server:e})),l){I.info(r.dim(`enabling`)+` `+r.magenta(`AI Chat`));let{enableAIServer:t}=await import(`./enableServer.mjs`);t.call(this,moduleopts({server:e}))}return()=>{let n=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 I.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}}}),I.trace(r.dim(`sent LikeC4ValidationError`))}catch(e){I.error(t(e))}return!0},reloadProjects=async()=>{let e=o.projects();i(e)?(I.trace(r.dim(`onProjectsUpdate - change detected`)),await reloadModule($e.virtualId),await reloadModule(qe.virtualId),await reloadModule(Ze.virtualId),e.length>1&&await reloadModule(tt.virtualId)):I.trace(r.dim(`onProjectsUpdate - no change`))};o.projectsManager.onProjectsUpdate(pDebounce(reloadProjects,100)),o.builder.onModelParsed(onModelParsedBatched(async e=>{if(!hasErrors())for(let t of e){I.trace(r.dim(`onModelParsed project`)+` `+r.cyan(t));for(let e of lt)await reloadModule(e.virtualId(t))}}))}}},async buildEnd(){u&&await o.dispose()}}]}function onModelParsedBatched(e){return w(n=>{e(n).catch(e=>{I.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,Ne as s,LikeC4VitePlugin as t};
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'
626
+ import { LikeC4View } from ${jsStringLiteral(`likec4:react/${e}`)}
627
+
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
+ 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
706
+ }
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};