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