likec4 1.55.1 → 1.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/__app__/chunks/ColorSchemeToggle.mjs +1 -0
  2. package/__app__/chunks/DiagramActorProvider.mjs +10 -0
  3. package/__app__/chunks/Fallback.mjs +1 -0
  4. package/__app__/chunks/Header.mjs +13 -0
  5. package/__app__/chunks/IconRenderer.mjs +1 -0
  6. package/__app__/chunks/LikeC4Diagram.mjs +19 -0
  7. package/__app__/chunks/LikeC4ModelContext.mjs +1 -0
  8. package/__app__/chunks/LikeC4ModelContext2.mjs +1 -0
  9. package/__app__/chunks/LikeC4Styles.mjs +48 -0
  10. package/__app__/chunks/NavigationPanel.mjs +1 -0
  11. package/__app__/chunks/StaticLikeC4Diagram.mjs +1 -0
  12. package/__app__/chunks/ViewReact.mjs +1 -0
  13. package/__app__/chunks/__root.mjs +1 -0
  14. package/__app__/chunks/adhoc-editor.mjs +1 -0
  15. package/__app__/chunks/hooks.mjs +1 -0
  16. package/__app__/chunks/libs/@dagrejs/dagre.mjs +1 -0
  17. package/__app__/chunks/libs/@floating-ui/core.mjs +1 -0
  18. package/__app__/chunks/libs/@floating-ui/dom.mjs +1 -0
  19. package/__app__/chunks/libs/@floating-ui/react.mjs +1 -0
  20. package/__app__/chunks/libs/@mantine/core.mjs +41 -0
  21. package/__app__/chunks/libs/@mantine/hooks.mjs +1 -0
  22. package/__app__/chunks/libs/@nanostores/react.mjs +1 -0
  23. package/__app__/chunks/libs/@react-hookz/web.mjs +1 -0
  24. package/__app__/chunks/libs/@tabler/icons-react.mjs +15 -0
  25. package/__app__/chunks/libs/@tanstack/history.mjs +1 -0
  26. package/__app__/chunks/libs/@tanstack/react-router.mjs +3 -0
  27. package/__app__/chunks/libs/@tanstack/router-core.mjs +1 -0
  28. package/__app__/chunks/libs/@xstate/react.mjs +1 -0
  29. package/__app__/chunks/libs/@xstate/store.mjs +1 -0
  30. package/__app__/chunks/libs/@xyflow/react.mjs +7 -0
  31. package/__app__/chunks/libs/@zag-js/anatomy.mjs +1 -0
  32. package/__app__/chunks/libs/@zag-js/collection.mjs +1 -0
  33. package/__app__/chunks/libs/@zag-js/core.mjs +1 -0
  34. package/__app__/chunks/libs/@zag-js/react.mjs +1 -0
  35. package/__app__/chunks/libs/@zag-js/tree-view.mjs +1 -0
  36. package/__app__/chunks/libs/bezier-js.mjs +1 -0
  37. package/__app__/chunks/libs/d3-path.mjs +1 -0
  38. package/__app__/chunks/libs/d3-shape.mjs +1 -0
  39. package/__app__/chunks/libs/fast-equals.mjs +1 -0
  40. package/__app__/chunks/libs/framer-motion.mjs +9 -0
  41. package/__app__/chunks/libs/html-to-image.mjs +2 -0
  42. package/__app__/chunks/libs/motion-dom.mjs +1 -0
  43. package/__app__/chunks/libs/motion.mjs +1 -0
  44. package/__app__/chunks/libs/nanostores.mjs +1 -0
  45. package/__app__/chunks/libs/react-error-boundary.mjs +1 -0
  46. package/__app__/chunks/libs/react-resizable-panels.mjs +1 -0
  47. package/__app__/chunks/libs/remeda.mjs +1 -0
  48. package/__app__/chunks/libs/xstate.mjs +1 -0
  49. package/__app__/chunks/libs/zod.mjs +39 -0
  50. package/__app__/chunks/rolldown-runtime.mjs +1 -0
  51. package/__app__/chunks/safeCtx.mjs +1 -0
  52. package/__app__/chunks/searchParams.mjs +1 -0
  53. package/__app__/chunks/single-index.mjs +1 -0
  54. package/__app__/chunks/styled-system.mjs +1 -0
  55. package/__app__/chunks/styles.css.mjs +1 -0
  56. package/__app__/chunks/useLikeC4Project.mjs +1 -0
  57. package/__app__/chunks/useUpdateEffect.mjs +1 -0
  58. package/__app__/codegen/react.mjs +11 -0
  59. package/__app__/codegen/webcomponent.mjs +790 -0
  60. package/__app__/src/fonts.css +1 -1
  61. package/__app__/src/main.mjs +1 -0
  62. package/__app__/src/pages/AdHocViewEditor.mjs +1 -0
  63. package/__app__/src/pages/EmbedPage.mjs +1 -0
  64. package/__app__/src/pages/ExportPage.mjs +1 -0
  65. package/__app__/src/pages/ProjectsOverview.mjs +1 -0
  66. package/__app__/src/pages/ViewAsD2.mjs +1 -0
  67. package/__app__/src/pages/ViewAsDot.mjs +1 -0
  68. package/__app__/src/pages/ViewAsMmd.mjs +1 -0
  69. package/__app__/src/pages/ViewAsPuml.mjs +1 -0
  70. package/__app__/src/pages/ViewEditor.mjs +1 -0
  71. package/__app__/src/pages/ViewReact.mjs +1 -0
  72. package/__app__/src/routeTree.gen.mjs +1 -0
  73. package/__app__/src/routes/__root.mjs +1 -0
  74. package/__app__/src/routes/_single/adhoc.mjs +1 -0
  75. package/__app__/src/routes/_single/embed._viewId.mjs +1 -0
  76. package/__app__/src/routes/_single/export._viewId.mjs +1 -0
  77. package/__app__/src/routes/_single/route.mjs +1 -0
  78. package/__app__/src/routes/_single/single-index.mjs +1 -0
  79. package/__app__/src/routes/_single/view._viewId.d2.mjs +1 -0
  80. package/__app__/src/routes/_single/view._viewId.dot.mjs +1 -0
  81. package/__app__/src/routes/_single/view._viewId.index.mjs +1 -0
  82. package/__app__/src/routes/_single/view._viewId.mjs +1 -0
  83. package/__app__/src/routes/_single/view._viewId.mmd.mjs +1 -0
  84. package/__app__/src/routes/_single/view._viewId.puml.mjs +1 -0
  85. package/__app__/src/routes/_single/webcomponent._.mjs +33 -0
  86. package/__app__/src/routes/index.mjs +1 -0
  87. package/__app__/src/routes/project._projectId/-components.mjs +1 -0
  88. package/__app__/src/routes/project._projectId/adhoc.mjs +1 -0
  89. package/__app__/src/routes/project._projectId/embed._viewId.mjs +1 -0
  90. package/__app__/src/routes/project._projectId/export._viewId.mjs +1 -0
  91. package/__app__/src/routes/project._projectId/index.mjs +1 -0
  92. package/__app__/src/routes/project._projectId/route.mjs +1 -0
  93. package/__app__/src/routes/project._projectId/view._viewId.d2.mjs +1 -0
  94. package/__app__/src/routes/project._projectId/view._viewId.dot.mjs +1 -0
  95. package/__app__/src/routes/project._projectId/view._viewId.index.mjs +1 -0
  96. package/__app__/src/routes/project._projectId/view._viewId.mjs +1 -0
  97. package/__app__/src/routes/project._projectId/view._viewId.mmd.mjs +1 -0
  98. package/__app__/src/routes/project._projectId/view._viewId.puml.mjs +1 -0
  99. package/__app__/src/routes/projects.mjs +1 -0
  100. package/__app__/src/style.css +1 -1
  101. package/dist/chunks/filenames.mjs +17 -0
  102. package/dist/{_chunks → chunks}/index.d.mts +2 -1
  103. package/dist/{_chunks → chunks}/index2.d.mts +70 -11
  104. package/dist/chunks/libs/@chevrotain/gast.mjs +1 -0
  105. package/dist/chunks/libs/@chevrotain/regexp-to-ast.mjs +9 -0
  106. package/dist/chunks/libs/@chevrotain/utils.mjs +1 -0
  107. package/dist/chunks/libs/@hono/mcp.mjs +45 -0
  108. package/dist/chunks/libs/@hono/node-server.mjs +1 -0
  109. package/dist/{_chunks → chunks}/libs/@logtape/logtape.d.mts +2 -0
  110. package/dist/chunks/libs/@logtape/logtape.mjs +4 -0
  111. package/dist/chunks/libs/@lume/kiwi.mjs +1 -0
  112. package/dist/chunks/libs/@modelcontextprotocol/sdk.mjs +12 -0
  113. package/dist/chunks/libs/ajv.mjs +1 -0
  114. package/dist/chunks/libs/ansi-align.mjs +2 -0
  115. package/dist/chunks/libs/ansi-regex.mjs +1 -0
  116. package/dist/chunks/libs/ansi-styles.mjs +1 -0
  117. package/dist/chunks/libs/atomically.mjs +1 -0
  118. package/dist/chunks/libs/birpc.mjs +1 -0
  119. package/dist/chunks/libs/boxen.mjs +22 -0
  120. package/dist/chunks/libs/chevrotain-allstar.mjs +2 -0
  121. package/dist/chunks/libs/chevrotain.mjs +58 -0
  122. package/dist/chunks/libs/conf.mjs +1 -0
  123. package/dist/chunks/libs/defu.mjs +1 -0
  124. package/dist/chunks/libs/destr.mjs +1 -0
  125. package/dist/chunks/libs/eventemitter3.mjs +1 -0
  126. package/dist/chunks/libs/find-up-simple.mjs +1 -0
  127. package/dist/chunks/libs/get-port.mjs +1 -0
  128. package/dist/chunks/libs/hono.mjs +1 -0
  129. package/dist/chunks/libs/is-docker.mjs +1 -0
  130. package/dist/chunks/libs/is-error-instance.mjs +1 -0
  131. package/dist/chunks/libs/is-inside-container.mjs +1 -0
  132. package/dist/chunks/libs/is-plain-obj.mjs +1 -0
  133. package/dist/chunks/libs/isexe.mjs +1 -0
  134. package/dist/chunks/libs/json5.mjs +14 -0
  135. package/dist/chunks/libs/khroma.mjs +1 -0
  136. package/dist/chunks/libs/ky.mjs +3 -0
  137. package/dist/{_chunks → chunks}/libs/langium.d.mts +4 -4
  138. package/dist/chunks/libs/langium.mjs +32 -0
  139. package/dist/chunks/libs/merge-error-cause.mjs +2 -0
  140. package/dist/chunks/libs/p-debounce.mjs +1 -0
  141. package/dist/chunks/libs/p-limit.mjs +1 -0
  142. package/dist/chunks/libs/p-queue.mjs +1 -0
  143. package/dist/chunks/libs/p-timeout.mjs +1 -0
  144. package/dist/chunks/libs/package-manager-detector.mjs +1 -0
  145. package/dist/chunks/libs/package-up.mjs +1 -0
  146. package/dist/chunks/libs/pako.mjs +1 -0
  147. package/dist/chunks/libs/parse-ms.mjs +1 -0
  148. package/dist/chunks/libs/pathe.mjs +1 -0
  149. package/dist/chunks/libs/picomatch.mjs +1 -0
  150. package/dist/chunks/libs/pretty-ms.mjs +1 -0
  151. package/dist/chunks/libs/remeda.mjs +1 -0
  152. package/dist/chunks/libs/safe-stringify.mjs +1 -0
  153. package/dist/chunks/libs/strip-indent.mjs +1 -0
  154. package/dist/chunks/libs/tinyrainbow.mjs +1 -0
  155. package/dist/{_chunks → chunks}/libs/ts-graphviz.d.mts +2 -0
  156. package/dist/chunks/libs/ts-graphviz.mjs +4 -0
  157. package/dist/chunks/libs/ufo.mjs +1 -0
  158. package/dist/chunks/libs/unstorage.mjs +1 -0
  159. package/dist/chunks/libs/which.mjs +1 -0
  160. package/dist/chunks/libs/word-wrap.mjs +12 -0
  161. package/dist/{_chunks → chunks}/libs/zod.d.mts +2 -0
  162. package/dist/chunks/node.mjs +76 -0
  163. package/dist/chunks/plugin.mjs +400 -0
  164. package/dist/chunks/rolldown-runtime.mjs +1 -0
  165. package/dist/chunks/sequence-view.mjs +1 -0
  166. package/dist/cli/index.mjs +262 -136
  167. package/dist/config/index.d.mts +1 -2
  168. package/dist/config/index.mjs +1 -1
  169. package/dist/index.d.mts +4 -8
  170. package/dist/index.mjs +1 -1
  171. package/dist/model/index.d.mts +2 -1
  172. package/dist/model/index.mjs +1 -1
  173. package/dist/vite-plugin/index.d.mts +38 -8
  174. package/dist/vite-plugin/index.mjs +1 -1
  175. package/dist/{_chunks → vite-plugin/internal/chunks}/libs/@nanostores/react.d.mts +2 -56
  176. package/dist/vite-plugin/internal/chunks/libs/@nanostores/react.mjs +1 -0
  177. package/dist/vite-plugin/internal/chunks/libs/birpc.mjs +1 -0
  178. package/dist/vite-plugin/internal/chunks/libs/fast-equals.mjs +1 -0
  179. package/dist/vite-plugin/internal/chunks/libs/nanostores.d.mts +59 -0
  180. package/dist/vite-plugin/internal/chunks/libs/nanostores.mjs +1 -0
  181. package/dist/vite-plugin/internal/chunks/libs/remeda.mjs +1 -0
  182. package/dist/vite-plugin/internal/chunks/rolldown-runtime.mjs +1 -0
  183. package/dist/vite-plugin/{internal.d.mts → internal/index.d.mts} +12 -3
  184. package/dist/vite-plugin/internal/index.mjs +1 -0
  185. package/package.json +35 -55
  186. package/react/index.d.mts +2 -28
  187. package/react/index.mjs +50520 -53863
  188. package/vite-plugin/internal/package.json +2 -2
  189. package/vite-plugin-modules.d.ts +14 -0
  190. package/__app__/react/likec4.tsx +0 -25
  191. package/__app__/src/ProjectsOverview.js +0 -16
  192. package/__app__/src/const.js +0 -19
  193. package/__app__/src/likec4.js +0 -21254
  194. package/__app__/src/main.js +0 -7
  195. package/__app__/src/routes/index.js +0 -324
  196. package/__app__/src/routes/projects.js +0 -193
  197. package/__app__/src/routes/single.js +0 -1983
  198. package/__app__/src/vendors.js +0 -52683
  199. package/__app__/src/webcomponent.js +0 -68
  200. package/dist/THIRD-PARTY-LICENSES.md +0 -1609
  201. package/dist/_chunks/libs/@chevrotain/cst-dts-gen.mjs +0 -30
  202. package/dist/_chunks/libs/@chevrotain/regexp-to-ast.mjs +0 -9
  203. package/dist/_chunks/libs/@chevrotain/types.d.mts +0 -1
  204. package/dist/_chunks/libs/@chevrotain/utils.mjs +0 -1
  205. package/dist/_chunks/libs/@hono/mcp.mjs +0 -45
  206. package/dist/_chunks/libs/@hono/node-server.mjs +0 -1
  207. package/dist/_chunks/libs/@logtape/logtape.mjs +0 -4
  208. package/dist/_chunks/libs/@lume/kiwi.mjs +0 -1
  209. package/dist/_chunks/libs/@modelcontextprotocol/sdk.mjs +0 -12
  210. package/dist/_chunks/libs/@nanostores/react.mjs +0 -1
  211. package/dist/_chunks/libs/ajv.mjs +0 -1
  212. package/dist/_chunks/libs/ansi-align.mjs +0 -2
  213. package/dist/_chunks/libs/ansi-regex.mjs +0 -1
  214. package/dist/_chunks/libs/ansi-styles.mjs +0 -1
  215. package/dist/_chunks/libs/atomically.mjs +0 -1
  216. package/dist/_chunks/libs/birpc.mjs +0 -1
  217. package/dist/_chunks/libs/boxen.mjs +0 -22
  218. package/dist/_chunks/libs/chevrotain-allstar.mjs +0 -2
  219. package/dist/_chunks/libs/chevrotain.mjs +0 -58
  220. package/dist/_chunks/libs/conf.mjs +0 -1
  221. package/dist/_chunks/libs/defu.mjs +0 -1
  222. package/dist/_chunks/libs/destr.mjs +0 -1
  223. package/dist/_chunks/libs/esm-env.mjs +0 -1
  224. package/dist/_chunks/libs/eventemitter3.mjs +0 -1
  225. package/dist/_chunks/libs/fast-equals.mjs +0 -1
  226. package/dist/_chunks/libs/find-up-simple.mjs +0 -1
  227. package/dist/_chunks/libs/get-port.mjs +0 -1
  228. package/dist/_chunks/libs/is-docker.mjs +0 -1
  229. package/dist/_chunks/libs/is-error-instance.mjs +0 -1
  230. package/dist/_chunks/libs/is-inside-container.mjs +0 -1
  231. package/dist/_chunks/libs/is-plain-obj.mjs +0 -1
  232. package/dist/_chunks/libs/isexe.mjs +0 -1
  233. package/dist/_chunks/libs/json5.mjs +0 -14
  234. package/dist/_chunks/libs/khroma.mjs +0 -1
  235. package/dist/_chunks/libs/ky.mjs +0 -3
  236. package/dist/_chunks/libs/langium.mjs +0 -33
  237. package/dist/_chunks/libs/merge-error-cause.mjs +0 -2
  238. package/dist/_chunks/libs/p-limit.mjs +0 -1
  239. package/dist/_chunks/libs/p-queue.mjs +0 -1
  240. package/dist/_chunks/libs/p-timeout.mjs +0 -1
  241. package/dist/_chunks/libs/package-manager-detector.mjs +0 -1
  242. package/dist/_chunks/libs/package-up.mjs +0 -1
  243. package/dist/_chunks/libs/pako.mjs +0 -1
  244. package/dist/_chunks/libs/parse-ms.mjs +0 -1
  245. package/dist/_chunks/libs/pathe.mjs +0 -1
  246. package/dist/_chunks/libs/picomatch.mjs +0 -1
  247. package/dist/_chunks/libs/pretty-ms.mjs +0 -1
  248. package/dist/_chunks/libs/remeda.mjs +0 -2
  249. package/dist/_chunks/libs/safe-stringify.mjs +0 -1
  250. package/dist/_chunks/libs/strip-indent.mjs +0 -1
  251. package/dist/_chunks/libs/tinyrainbow.mjs +0 -1
  252. package/dist/_chunks/libs/ts-graphviz.mjs +0 -4
  253. package/dist/_chunks/libs/ufo.mjs +0 -1
  254. package/dist/_chunks/libs/unstorage.mjs +0 -1
  255. package/dist/_chunks/libs/which.mjs +0 -1
  256. package/dist/_chunks/libs/word-wrap.mjs +0 -12
  257. package/dist/_chunks/node.mjs +0 -76
  258. package/dist/_chunks/rolldown-runtime.mjs +0 -1
  259. package/dist/_chunks/sequence.mjs +0 -1
  260. package/dist/_chunks/src.mjs +0 -17
  261. package/dist/_chunks/src2.mjs +0 -499
  262. package/dist/vite-plugin/internal.mjs +0 -1
  263. /package/dist/{_chunks → chunks}/libs/vscode-languageserver.mjs +0 -0
@@ -1,1983 +0,0 @@
1
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { d8 as useRouter, d9 as useParams, da as isNotFound, db as Container, br as Alert, U as Text, dc as Code, W as Button, dd as e, de as e$1, as as e$2, bt as Group, bh as rem, df as Link, bZ as Title, d1 as createFileRoute, Q as m, d0 as Outlet, k as useMantineColorScheme, dg as useComputedColorScheme, cY as useNavigate, aA as ActionIcon, c9 as useHotkeys, aI as AnimatePresence, d as deepEqual, s as shallowEqual, dh as useMatches, di as useIsomorphicLayoutEffect, a9 as r, dj as onMount, v as useStore$1, r as atom, bq as useTree, bs as Tree, b6 as HoverCard, b7 as HoverCardTarget, b8 as HoverCardDropdown, R as ThemeIcon, ch as useLocalStorage, dk as Drawer, bP as ScrollArea, S as SegmentedControl, d3 as useDocumentTitle, dl as Burger, dm as SimpleGrid, dn as useInViewport, dp as e$3, ci as Card, aQ as Box$1, d2 as redirect, aF as MotionDiv, cN as isValidMotionProp, aD as Menu, bc as MenuTarget, bd as MenuDropdown, be as MenuItem, dq as MenuDivider, bp as Stack, b5 as CopyButton$1, dr as Select, ds as ModalRoot, dt as ModalOverlay, du as ModalContent, dv as ModalBody, bL as Tabs, bM as TabsList, bN as TabsTab, bO as TabsPanel, dw as useMantineTheme, dx as useMediaQuery, cq as useDisclosure, aG as Divider, dy as MenuLabel, dz as useSearch, dA as LoadingOverlay, dB as toJpeg, dC as toBlob, c$ as stripSearchParams, cZ as z, bS as useCallbackRef, aL as useIsMounted, T as Tooltip, dD as useAsync, dE as Ut, dF as qt, dG as Zt, dH as notFound } from "../vendors.js";
3
- import { loadModel } from "likec4:model";
4
- import { c as css, s as styled, I as IconRendererProvider, a as LikeC4ModelProvider, b as IconMoonStars, d as IconSun, n as normalizeSearch, S as SearchContext, e as SearchControl, F as FramerMotionConfig, O as Overlay, f as bodyCss, g as dialogCss, h as SearchPanelContent, u as useUpdateEffect, i as useLikeC4Model, j as StaticLikeC4Diagram, B as Box, k as IconStarFilled, l as IconStack2, m as IconLayoutDashboard, o as IconFileCode, p as IconFolderOpen, q as IconFolderFilled, r as IconArrowLeft, N as NavigationPanel$1, M as Markdown, t as LikeC4AdHocViewEditor, v as createStyleContext, w as navigationPanel, x as isCssProperty, y as useLikeC4Projects$1, z as IconChevronDown, A as IconAlertTriangle, C as IconCheck, D as IconCopy, E as IconExternalLink, G as IconShare, H as pickViewBounds, J as LikeC4Diagram, K as useDiagramContext, P as useDiagram, Q as useOnDiagramEvent, R as LikeC4EditorProvider } from "../likec4.js";
5
- import { getProjectIcons } from "likec4:icons";
6
- import { useMemo, createContext, useContext, useRef, useEffect, useState, useCallback, memo } from "react";
7
- import { useStore } from "likec4/vite-plugin/internal";
8
- import { RichText } from "@likec4/core/types";
9
- import { nonexhaustive, compareNatural } from "@likec4/core/utils";
10
- import { pageTitle, ComponentName, useHashHistory, isDevelopment, krokiPumlSvgUrl, krokiD2SvgUrl } from "../const.js";
11
- import { likec4rpc, isRpcAvailable } from "likec4:rpc";
12
- import { R as Route$c, r as resolveForceColorScheme } from "./index.js";
13
- import { useLikeC4Projects } from "likec4:projects";
14
- function Fallback({ error: _error, resetErrorBoundary }) {
15
- const router = useRouter(), params = useParams({
16
- strict: !1
17
- });
18
- if (isNotFound(_error))
19
- return /* @__PURE__ */ jsx(Container, { my: "md", children: /* @__PURE__ */ jsxs(Alert, { variant: "light", color: "orange", children: [
20
- /* @__PURE__ */ jsxs(Text, { c: "orange", fz: "md", children: [
21
- "The diagram",
22
- " ",
23
- /* @__PURE__ */ jsx(Code, { color: "orange", children: params.viewId ?? "unknown" }),
24
- " ",
25
- "does not exist or contains errors"
26
- ] }),
27
- /* @__PURE__ */ jsx(
28
- Button,
29
- {
30
- onClick: () => {
31
- resetErrorBoundary(), router.navigate({
32
- to: "/"
33
- });
34
- },
35
- variant: "light",
36
- color: "orange",
37
- mt: "lg",
38
- size: "xs",
39
- children: "Go to overview"
40
- }
41
- )
42
- ] }) });
43
- const error = _error;
44
- let message = "Unknown error";
45
- try {
46
- switch (!0) {
47
- case e$2(error):
48
- message = "Unknown error";
49
- break;
50
- case e$1(error):
51
- message = error.stack ?? error.message;
52
- break;
53
- case typeof error == "string":
54
- message = error;
55
- break;
56
- case e(error):
57
- message = error.stack ?? error.message ?? `${error}`;
58
- break;
59
- default:
60
- message = `${error}`;
61
- break;
62
- }
63
- } catch (e2) {
64
- message = `${e2}`;
65
- }
66
- return /* @__PURE__ */ jsx(Container, { my: "md", children: /* @__PURE__ */ jsxs(Alert, { variant: "filled", color: "red", title: "Something went wrong", children: [
67
- /* @__PURE__ */ jsx(Code, { block: !0, color: "red", children: message }),
68
- /* @__PURE__ */ jsxs(Group, { mt: "lg", children: [
69
- /* @__PURE__ */ jsx(
70
- Button,
71
- {
72
- onClick: () => {
73
- router.invalidate().finally(() => {
74
- resetErrorBoundary();
75
- });
76
- },
77
- color: "red",
78
- variant: "white",
79
- size: "xs",
80
- children: "Try again"
81
- }
82
- ),
83
- /* @__PURE__ */ jsx(
84
- Button,
85
- {
86
- onClick: () => {
87
- resetErrorBoundary(), router.navigate({ to: "/" });
88
- },
89
- color: "red",
90
- size: "xs",
91
- children: "Go to overview"
92
- }
93
- )
94
- ] })
95
- ] }) });
96
- }
97
- const content = css({
98
- paddingTop: "[120px]",
99
- position: "relative",
100
- zIndex: "1",
101
- sm: {
102
- paddingTop: "[220px]"
103
- }
104
- }), image = css({
105
- position: "absolute",
106
- inset: "0",
107
- opacity: 0.2
108
- }), inner = css({
109
- position: "relative"
110
- }), root = css({
111
- paddingTop: "[80px]",
112
- paddingBottom: "[80px]"
113
- }), description = css({
114
- maxWidth: rem(540),
115
- margin: "auto",
116
- marginTop: "xl",
117
- marginBottom: "[calc({spacing.xl}*1.5)]"
118
- }), title = css({
119
- textAlign: "center",
120
- fontWeight: "[900]",
121
- fontSize: "[38px]"
122
- });
123
- function NotFound() {
124
- const params = useParams({
125
- strict: !1
126
- });
127
- return params.viewId ? /* @__PURE__ */ jsx(Container, { my: "md", children: /* @__PURE__ */ jsxs(Alert, { variant: "light", color: "orange", children: [
128
- /* @__PURE__ */ jsxs(Text, { c: "orange", fz: "md", children: [
129
- "The diagram",
130
- " ",
131
- /* @__PURE__ */ jsx(Code, { color: "orange", children: params.viewId }),
132
- " ",
133
- "does not exist or contains errors"
134
- ] }),
135
- /* @__PURE__ */ jsx(
136
- Button,
137
- {
138
- component: Link,
139
- to: "/",
140
- variant: "light",
141
- color: "orange",
142
- mt: "lg",
143
- size: "xs",
144
- children: "Go to overview"
145
- }
146
- )
147
- ] }) }) : /* @__PURE__ */ jsx(Container, { className: root, children: /* @__PURE__ */ jsxs("div", { className: inner, children: [
148
- /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 362 145", className: image, children: /* @__PURE__ */ jsx(
149
- "path",
150
- {
151
- fill: "currentColor",
152
- d: "M62.6 142c-2.133 0-3.2-1.067-3.2-3.2V118h-56c-2 0-3-1-3-3V92.8c0-1.333.4-2.733 1.2-4.2L58.2 4c.8-1.333 2.067-2 3.8-2h28c2 0 3 1 3 3v85.4h11.2c.933 0 1.733.333 2.4 1 .667.533 1 1.267 1 2.2v21.2c0 .933-.333 1.733-1 2.4-.667.533-1.467.8-2.4.8H93v20.8c0 2.133-1.067 3.2-3.2 3.2H62.6zM33 90.4h26.4V51.2L33 90.4zM181.67 144.6c-7.333 0-14.333-1.333-21-4-6.666-2.667-12.866-6.733-18.6-12.2-5.733-5.467-10.266-13-13.6-22.6-3.333-9.6-5-20.667-5-33.2 0-12.533 1.667-23.6 5-33.2 3.334-9.6 7.867-17.133 13.6-22.6 5.734-5.467 11.934-9.533 18.6-12.2 6.667-2.8 13.667-4.2 21-4.2 7.467 0 14.534 1.4 21.2 4.2 6.667 2.667 12.8 6.733 18.4 12.2 5.734 5.467 10.267 13 13.6 22.6 3.334 9.6 5 20.667 5 33.2 0 12.533-1.666 23.6-5 33.2-3.333 9.6-7.866 17.133-13.6 22.6-5.6 5.467-11.733 9.533-18.4 12.2-6.666 2.667-13.733 4-21.2 4zm0-31c9.067 0 15.6-3.733 19.6-11.2 4.134-7.6 6.2-17.533 6.2-29.8s-2.066-22.2-6.2-29.8c-4.133-7.6-10.666-11.4-19.6-11.4-8.933 0-15.466 3.8-19.6 11.4-4 7.6-6 17.533-6 29.8s2 22.2 6 29.8c4.134 7.467 10.667 11.2 19.6 11.2zM316.116 142c-2.134 0-3.2-1.067-3.2-3.2V118h-56c-2 0-3-1-3-3V92.8c0-1.333.4-2.733 1.2-4.2l56.6-84.6c.8-1.333 2.066-2 3.8-2h28c2 0 3 1 3 3v85.4h11.2c.933 0 1.733.333 2.4 1 .666.533 1 1.267 1 2.2v21.2c0 .933-.334 1.733-1 2.4-.667.533-1.467.8-2.4.8h-11.2v20.8c0 2.133-1.067 3.2-3.2 3.2h-27.2zm-29.6-51.6h26.4V51.2l-26.4 39.2z"
153
- }
154
- ) }),
155
- /* @__PURE__ */ jsxs("div", { className: content, children: [
156
- /* @__PURE__ */ jsx(Title, { className: title, children: "Nothing to see here" }),
157
- /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "lg", ta: "center", className: description, children: "Page you are trying to open does not exist. You may have mistyped the address, or the page has been moved to another URL. If you think this is an error contact support." }),
158
- /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(Button, { component: Link, to: "/", search: !0, size: "md", children: "Take me back to home page" }) })
159
- ] })
160
- ] }) });
161
- }
162
- const ViewOutlet = styled("div", {
163
- base: {
164
- padding: "0",
165
- margin: "0",
166
- width: "full",
167
- height: "full"
168
- }
169
- });
170
- function LikeC4IconRendererContext({ children, projectId }) {
171
- const IconRenderer = useMemo(() => getProjectIcons(projectId), [projectId]);
172
- return /* @__PURE__ */ jsx(IconRendererProvider, { value: IconRenderer, children });
173
- }
174
- const LikeC4ModelDataContext = createContext(null), LikeC4ModelDataContextProvider = LikeC4ModelDataContext.Provider, useLikeC4ModelAtom = () => {
175
- const ctx = useContext(LikeC4ModelDataContext);
176
- if (ctx === null)
177
- throw new Error("LikeC4ModelAtom is not provided");
178
- return ctx;
179
- };
180
- function LikeC4ModelContext({ likec4model, children }) {
181
- const model = useStore(likec4model);
182
- return /* @__PURE__ */ jsx(LikeC4ModelDataContextProvider, { value: likec4model, children: /* @__PURE__ */ jsx(LikeC4ModelProvider, { likec4model: model, children }) });
183
- }
184
- const Route$b = createFileRoute("/_single")({
185
- staleTime: 1 / 0,
186
- loaderDeps() {
187
- return [];
188
- },
189
- loader: async ({ context }) => {
190
- const projectId = context.projectId;
191
- return {
192
- $likec4model: (await loadModel(projectId)).$likec4model,
193
- projectId
194
- };
195
- },
196
- component: RouteComponent$1
197
- });
198
- function RouteComponent$1() {
199
- const { $likec4model, projectId } = Route$b.useLoaderData();
200
- return /* @__PURE__ */ jsx(ViewOutlet, { children: /* @__PURE__ */ jsx(m, { FallbackComponent: Fallback, children: /* @__PURE__ */ jsx(LikeC4IconRendererContext, { projectId, children: /* @__PURE__ */ jsx(LikeC4ModelContext, { likec4model: $likec4model, children: /* @__PURE__ */ jsx(Outlet, {}) }) }) }) });
201
- }
202
- function ColorSchemeToggle() {
203
- const { setColorScheme } = useMantineColorScheme({
204
- keepTransitions: !0
205
- }), computedColorScheme = useComputedColorScheme("light"), navigate = useNavigate(), { theme: urlTheme } = Route$c.useSearch(), isForced = resolveForceColorScheme(urlTheme) != null, pendingScheme = useRef(null);
206
- return useEffect(() => {
207
- pendingScheme.current != null && !isForced && (setColorScheme(pendingScheme.current), pendingScheme.current = null);
208
- }, [isForced, setColorScheme]), /* @__PURE__ */ jsxs(
209
- ActionIcon,
210
- {
211
- size: "md",
212
- variant: "subtle",
213
- color: "gray",
214
- onClick: () => {
215
- if (pendingScheme.current != null) return;
216
- const next = computedColorScheme === "light" ? "dark" : "light";
217
- isForced ? (pendingScheme.current = next, navigate({
218
- from: Route$c.fullPath,
219
- search: (prev) => ({ ...prev, theme: void 0 }),
220
- replace: !0
221
- }).catch(() => {
222
- pendingScheme.current = null;
223
- })) : setColorScheme(next);
224
- },
225
- "aria-label": "Toggle color scheme",
226
- children: [
227
- /* @__PURE__ */ jsx(IconMoonStars, { stroke: 1.5, display: computedColorScheme === "light" ? "block" : "none" }),
228
- /* @__PURE__ */ jsx(IconSun, { stroke: 1.5, display: computedColorScheme === "dark" ? "block" : "none" })
229
- ]
230
- }
231
- );
232
- }
233
- function OverviewSearchAdapter({
234
- onClose,
235
- children
236
- }) {
237
- const [searchValue, setSearchValue] = useState(""), [pickViewFor, setPickViewFor] = useState(null), navigate = useNavigate(), navigateTo = useCallback((viewId, focusOnElement) => {
238
- onClose(), navigate({
239
- to: "/view/$viewId/",
240
- params: { viewId },
241
- search: (prev) => ({
242
- ...prev,
243
- ...focusOnElement && { focusOnElement }
244
- })
245
- });
246
- }, [navigate, onClose]), openPickView = useCallback((elementFqn) => {
247
- setPickViewFor(elementFqn);
248
- }, []), closePickView = useCallback(() => {
249
- setPickViewFor(null);
250
- }, []), value = useMemo(() => ({
251
- searchValue,
252
- setSearchValue,
253
- normalizedSearch: normalizeSearch(searchValue),
254
- navigateTo,
255
- openPickView,
256
- closePickView,
257
- pickViewFor,
258
- close: onClose,
259
- currentViewId: null,
260
- openedWithSearch: null
261
- }), [searchValue, pickViewFor, navigateTo, openPickView, closePickView, onClose]);
262
- return /* @__PURE__ */ jsx(SearchContext.Provider, { value, children });
263
- }
264
- const OverviewSearch = memo(() => {
265
- const [isOpened, setIsOpened] = useState(!1), dialogElRef = useRef(null), open = useCallback(() => setIsOpened(!0), []), close = useCallback(() => setIsOpened(!1), []), captureDialogRef = useCallback((node) => {
266
- node && (dialogElRef.current = node);
267
- }, []), handleExitComplete = useCallback(() => {
268
- dialogElRef.current?.open && dialogElRef.current.close(), dialogElRef.current = null;
269
- }, []);
270
- return useHotkeys([
271
- ["mod+k", open, { preventDefault: !0 }]
272
- ]), /* @__PURE__ */ jsxs(Fragment, { children: [
273
- /* @__PURE__ */ jsx(SearchControl, { onClick: open }),
274
- /* @__PURE__ */ jsx(FramerMotionConfig, { children: /* @__PURE__ */ jsx(AnimatePresence, { onExitComplete: handleExitComplete, children: isOpened && /* @__PURE__ */ jsx(
275
- Overlay,
276
- {
277
- ref: captureDialogRef,
278
- fullscreen: !0,
279
- withBackdrop: !1,
280
- backdrop: {
281
- opacity: 0.9
282
- },
283
- classes: {
284
- dialog: dialogCss,
285
- body: bodyCss
286
- },
287
- openDelay: 0,
288
- onClose: close,
289
- "data-likec4-search": "true",
290
- children: /* @__PURE__ */ jsx(OverviewSearchAdapter, { onClose: close, children: /* @__PURE__ */ jsx(SearchPanelContent, {}) })
291
- }
292
- ) }) })
293
- ] });
294
- });
295
- OverviewSearch.displayName = "OverviewSearch";
296
- function useTransparentBackground(enabled = !0) {
297
- useIsomorphicLayoutEffect(() => {
298
- const htmlEl = document.body.parentElement;
299
- if (!htmlEl || enabled !== !0) return;
300
- const classname = "transparent-bg";
301
- return htmlEl.classList.add(classname), () => {
302
- htmlEl.classList.remove(classname);
303
- };
304
- }, [enabled]);
305
- }
306
- function useLikeC4Views() {
307
- const $likec4model = useLikeC4ModelAtom(), [views, setViews] = useState([]);
308
- return useEffect(() => $likec4model.subscribe((next) => {
309
- setViews((prev) => {
310
- const nextViews = [...next.views()].map((v) => {
311
- const n = v.$layouted, p = prev.find((_) => _.id === v.id);
312
- return p && deepEqual(n, p) ? p : n;
313
- });
314
- return shallowEqual(prev, nextViews) ? prev : nextViews;
315
- });
316
- }), [$likec4model]), views;
317
- }
318
- function useCurrentViewId() {
319
- return useParams({
320
- select: (params) => params.viewId,
321
- strict: !1
322
- }) ?? "index";
323
- }
324
- function useCurrentView() {
325
- const viewId = useCurrentViewId(), $likec4model = useLikeC4ModelAtom(), [layoutType, setLayoutType] = useState("manual");
326
- useUpdateEffect(() => {
327
- setLayoutType("manual");
328
- }, [viewId]);
329
- const [view, setView] = useState(() => $likec4model.get().findView(viewId)?.$layouted ?? null);
330
- return useEffect(() => $likec4model.subscribe((next) => {
331
- setView((current) => {
332
- const vm = next.findView(viewId);
333
- if (!vm)
334
- return null;
335
- const nextView = layoutType === "auto" ? vm.$view : vm.$layouted;
336
- return deepEqual(current, nextView) ? current : nextView;
337
- });
338
- }), [$likec4model, viewId, layoutType]), [view, setLayoutType];
339
- }
340
- function useCurrentProject() {
341
- const projects = useLikeC4Projects(), projectId = useMatches({
342
- select: (m2) => m2.find((m22) => m22.routeId === "/project/$projectId")?.params?.projectId ?? m2.at(-1)?.context.projectId ?? "default"
343
- });
344
- return projects.find((p) => p.id === projectId) ?? projects[0];
345
- }
346
- const isTreeNodeData = (node) => "type" in node && ["file", "folder", "view", "deployment-view"].includes(node.type);
347
- function dropFilename(relativePath) {
348
- return relativePath === "" ? "" : relativePath.split("/").slice(0, -1).join("/");
349
- }
350
- function compareTreeNodes(a, b) {
351
- return a.children.length === 0 && b.children.length > 0 ? 1 : a.children.length > 0 && b.children.length === 0 ? -1 : compareNatural(a.label, b.label);
352
- }
353
- function buildDiagramTreeData(views, groupBy) {
354
- const root2 = {
355
- value: "",
356
- label: "Diagrams",
357
- type: "folder",
358
- children: []
359
- }, findParent = (path) => {
360
- let parent = root2;
361
- if (path === "")
362
- return parent;
363
- const segments = path.split("/"), traversed = ["@fs"];
364
- for (; segments.length; ) {
365
- const label = segments.shift();
366
- traversed.push(label);
367
- const value = traversed.join("/");
368
- let node = r(parent.children, (n) => n.value === value);
369
- node || (node = { label, value, type: "folder", children: [] }, parent.children.push(node)), parent = node;
370
- }
371
- return parent;
372
- };
373
- for (const view of views) {
374
- let relativePath;
375
- switch (groupBy) {
376
- case "by-files":
377
- relativePath = view.$view.sourcePath ?? "";
378
- break;
379
- case "by-folders":
380
- relativePath = dropFilename(view.$view.sourcePath ?? "");
381
- break;
382
- case "none":
383
- relativePath = "";
384
- break;
385
- default:
386
- nonexhaustive(groupBy);
387
- }
388
- const parent = findParent(relativePath);
389
- parent.children.push({
390
- value: view.id,
391
- label: view.title ?? view.id,
392
- type: view.isDeploymentView() ? "deployment-view" : "view",
393
- children: []
394
- }), parent !== root2 && (parent.children.sort(compareTreeNodes), groupBy === "by-files" && parent.type !== "file" && (parent.type = "file"));
395
- }
396
- return root2.children.sort(compareTreeNodes);
397
- }
398
- function useDiagramsTreeData(groupBy = "by-files") {
399
- const model = useLikeC4Model();
400
- return useMemo(() => buildDiagramTreeData([...model.views()], groupBy), [model, groupBy]);
401
- }
402
- const drawerOpenedAtom = atom(!1);
403
- onMount(drawerOpenedAtom, () => {
404
- drawerOpenedAtom.set(!1);
405
- });
406
- const useDrawerOpened = () => useStore$1(drawerOpenedAtom), SidebarDrawerOps = {
407
- open: () => drawerOpenedAtom.set(!0),
408
- close: () => drawerOpenedAtom.set(!1)
409
- }, isFile = (node) => isTreeNodeData(node) && node.type === "file", FolderIcon = ({ node, expanded }) => isFile(node) ? /* @__PURE__ */ jsx(ThemeIcon, { size: "sm", variant: "transparent", color: "indigo", children: /* @__PURE__ */ jsx(IconFileCode, { size: 16 }) }) : /* @__PURE__ */ jsx(ThemeIcon, { size: "sm", variant: "transparent", color: "violet", children: expanded ? /* @__PURE__ */ jsx(IconFolderOpen, { size: 16 }) : /* @__PURE__ */ jsx(IconFolderFilled, { size: 16 }) }), setHoveredNode = () => {
410
- }, DiagramsTree = /* @__PURE__ */ memo(({ groupBy }) => {
411
- const views = useLikeC4Views(), data = useDiagramsTreeData(groupBy), navigate = useNavigate(), navigateTo = (viewId2) => {
412
- SidebarDrawerOps.close(), navigate({
413
- to: "/view/$viewId/",
414
- viewTransition: !1,
415
- params: { viewId: viewId2 }
416
- });
417
- }, [diagram] = useCurrentView(), viewId = diagram?.id ?? null, tree = useTree({
418
- multiple: !1
419
- });
420
- tree.setHoveredNode = setHoveredNode;
421
- const sourcePath = diagram?.sourcePath ?? null;
422
- useUpdateEffect(() => {
423
- tree.collapseAllNodes();
424
- }, [groupBy]), useEffect(() => {
425
- if (sourcePath) {
426
- const segments = sourcePath.split("/");
427
- let path = "@fs";
428
- for (const segment of segments)
429
- path += `/${segment}`, tree.expand(path);
430
- }
431
- }, [sourcePath, groupBy]), useEffect(() => {
432
- viewId && tree.select(viewId);
433
- }, [viewId]);
434
- const theme = useComputedColorScheme();
435
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
436
- Tree,
437
- {
438
- allowRangeSelection: !1,
439
- tree,
440
- data,
441
- styles: {
442
- node: {
443
- marginTop: 2,
444
- marginBottom: 2
445
- }
446
- },
447
- levelOffset: "md",
448
- renderNode: ({ node, selected, expanded, elementProps, hasChildren }) => /* @__PURE__ */ jsx(DiagramPreviewHoverCard, { diagram: hasChildren ? void 0 : views.find((v) => v.id === node.value), children: /* @__PURE__ */ jsx(
449
- Button,
450
- {
451
- fullWidth: !0,
452
- color: theme === "light" ? "dark" : "gray",
453
- variant: selected ? "transparent" : "subtle",
454
- size: "sm",
455
- fz: "sm",
456
- fw: hasChildren ? "600" : "500",
457
- justify: "flex-start",
458
- styles: {
459
- section: {
460
- opacity: 0.5
461
- }
462
- },
463
- leftSection: /* @__PURE__ */ jsxs(Fragment, { children: [
464
- !hasChildren && node.value === "index" && /* @__PURE__ */ jsx(IconStarFilled, { size: 14, opacity: 0.7 }),
465
- !hasChildren && node.value !== "index" && isTreeNodeData(node) && /* @__PURE__ */ jsxs(Fragment, { children: [
466
- node.type === "deployment-view" && /* @__PURE__ */ jsx(IconStack2, { size: 14 }),
467
- node.type === "view" && /* @__PURE__ */ jsx(IconLayoutDashboard, { size: 14 })
468
- ] }),
469
- hasChildren && /* @__PURE__ */ jsx(FolderIcon, { node, expanded })
470
- ] }),
471
- ...elementProps,
472
- ...!hasChildren && {
473
- onClick: (e2) => {
474
- e2.stopPropagation(), navigateTo(node.value);
475
- }
476
- },
477
- children: node.label
478
- }
479
- ) })
480
- }
481
- ) });
482
- }, (prev, next) => prev.groupBy === next.groupBy);
483
- function DiagramPreviewHoverCard({ diagram, children }) {
484
- const ratio = diagram ? Math.max(diagram.bounds.width / 400, diagram.bounds.height / 300) : 1, width = diagram ? Math.round(diagram.bounds.width / ratio) : 0, height = diagram ? Math.round(diagram.bounds.height / ratio) : 0;
485
- return /* @__PURE__ */ jsxs(Fragment, { children: [
486
- diagram && /* @__PURE__ */ jsxs(HoverCard, { position: "right-start", openDelay: 400, closeDelay: 100, keepMounted: !1, shadow: "lg", children: [
487
- /* @__PURE__ */ jsx(HoverCardTarget, { children }),
488
- /* @__PURE__ */ jsx(HoverCardDropdown, { style: { width, height }, p: "xs", children: /* @__PURE__ */ jsx(DiagramPreview, { diagram }) })
489
- ] }),
490
- !diagram && children
491
- ] });
492
- }
493
- const DiagramPreview = memo(({ diagram }) => {
494
- const ratio = Math.max(diagram.bounds.width / 400, diagram.bounds.height / 300), width = Math.round(diagram.bounds.width / ratio), height = Math.round(diagram.bounds.height / ratio);
495
- return /* @__PURE__ */ jsx(
496
- StaticLikeC4Diagram,
497
- {
498
- view: diagram,
499
- fitView: !0,
500
- fitViewPadding: "4px",
501
- enableElementDetails: !1,
502
- reduceGraphics: !0,
503
- initialWidth: width,
504
- initialHeight: height
505
- }
506
- );
507
- }, (prev, next) => prev.diagram.id === next.diagram.id), SidebarDrawer = memo(() => {
508
- const opened = useDrawerOpened(), [grouping, setGrouping] = useLocalStorage({
509
- key: "sidebar-drawer-grouping",
510
- defaultValue: "by-files"
511
- }), isSingleProject = useMatches({
512
- select: (matches) => matches.some((match) => match.routeId === "/_single")
513
- });
514
- return /* @__PURE__ */ jsxs(
515
- Drawer.Root,
516
- {
517
- keepMounted: isSingleProject,
518
- opened,
519
- scrollAreaComponent: ScrollArea.Autosize,
520
- onClose: SidebarDrawerOps.close,
521
- children: [
522
- /* @__PURE__ */ jsx(Drawer.Overlay, { blur: 2 }),
523
- /* @__PURE__ */ jsxs(Drawer.Content, { children: [
524
- /* @__PURE__ */ jsxs(Drawer.Header, { children: [
525
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
526
- /* @__PURE__ */ jsx(
527
- Button,
528
- {
529
- component: Link,
530
- to: "/",
531
- leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 14 }),
532
- color: "dimmed",
533
- variant: "subtle",
534
- px: rem(5),
535
- styles: {
536
- section: {
537
- marginInlineEnd: 4
538
- }
539
- },
540
- size: "xs",
541
- children: "Overview"
542
- }
543
- ),
544
- /* @__PURE__ */ jsx(
545
- SegmentedControl,
546
- {
547
- size: "xs",
548
- withItemsBorders: !1,
549
- value: grouping,
550
- onChange: setGrouping,
551
- data: [
552
- { label: "By files", value: "by-files" },
553
- { label: "By folders", value: "by-folders" },
554
- { label: "List", value: "none" }
555
- ]
556
- }
557
- ),
558
- /* @__PURE__ */ jsx(
559
- Button,
560
- {
561
- leftSection: /* @__PURE__ */ jsx(IconStarFilled, { size: 12, stroke: 2 }),
562
- color: "dimmed",
563
- variant: "subtle",
564
- px: rem(5),
565
- styles: {
566
- section: {
567
- marginInlineEnd: 4
568
- }
569
- },
570
- size: "xs",
571
- renderRoot: (props) => /* @__PURE__ */ jsx(
572
- Link,
573
- {
574
- to: "/view/$viewId",
575
- params: { viewId: "index" },
576
- ...props
577
- }
578
- ),
579
- children: "Open index"
580
- }
581
- )
582
- ] }),
583
- /* @__PURE__ */ jsx(Drawer.CloseButton, {})
584
- ] }),
585
- /* @__PURE__ */ jsx(Drawer.Body, { children: /* @__PURE__ */ jsx(DiagramsTree, { groupBy: grouping }) })
586
- ] })
587
- ]
588
- }
589
- );
590
- });
591
- function filterLandingPageViews(views, filter) {
592
- return filter ? "include" in filter ? views.filter((view) => matchesAny(view, filter.include)) : "exclude" in filter ? views.filter((view) => !matchesAny(view, filter.exclude)) : views : views;
593
- }
594
- function matchesAny(view, patterns) {
595
- return patterns.some((pattern) => {
596
- if (pattern.startsWith("#")) {
597
- const tag = pattern.slice(1);
598
- return view.tags?.some((t) => t === tag) ?? !1;
599
- }
600
- return view.id === pattern;
601
- });
602
- }
603
- css({
604
- color: "text.dimmed"
605
- });
606
- css({
607
- // background: 'var(--color-surface)',
608
- });
609
- const previewBg = css({
610
- position: "relative",
611
- overflow: "hidden",
612
- padding: "0",
613
- margin: "0",
614
- backgroundOrigin: "padding-box",
615
- backgroundImage: "radial-gradient({colors.default.border} 15%, {colors.body} 15%)",
616
- backgroundPosition: "0 0",
617
- backgroundSize: "12px 12px",
618
- _after: {
619
- content: '" "',
620
- position: "absolute",
621
- top: "0",
622
- left: "0",
623
- right: "0",
624
- bottom: "0",
625
- zIndex: "1"
626
- }
627
- }), cardLink = css({
628
- position: "absolute",
629
- inset: "0",
630
- zIndex: 5
631
- }), Route$a = createFileRoute("/_single/single-index")({
632
- component: RouteComponent
633
- });
634
- function RouteComponent() {
635
- useDocumentTitle(pageTitle);
636
- const allViews = useLikeC4Views(), { landingPage } = useCurrentProject(), views = filterLandingPageViews(allViews, landingPage);
637
- return /* @__PURE__ */ jsxs(Container, { size: "xl", children: [
638
- /* @__PURE__ */ jsx(SidebarDrawer, {}),
639
- /* @__PURE__ */ jsxs(
640
- "div",
641
- {
642
- className: css({
643
- containerName: "likec4-root",
644
- containerType: "inline-size",
645
- display: "flex",
646
- alignItems: "flex-start",
647
- justifyContent: "space-between",
648
- padding: "xs",
649
- gap: "xs",
650
- position: "sticky",
651
- top: "0",
652
- zIndex: "10",
653
- backgroundColor: "likec4.panel.bg/85",
654
- backdropFilter: "blur(8px)"
655
- }),
656
- children: [
657
- /* @__PURE__ */ jsx(NavigationPanel$1.Root, { css: { position: "relative", width: "max-content", margin: "0" }, children: /* @__PURE__ */ jsxs(NavigationPanel$1.Body, { children: [
658
- /* @__PURE__ */ jsx("div", { style: { width: 0, height: 36 }, "aria-hidden": !0 }),
659
- /* @__PURE__ */ jsx(Burger, { size: "sm", onClick: SidebarDrawerOps.open, "aria-label": "Toggle navigation" }),
660
- /* @__PURE__ */ jsx(
661
- NavigationPanel$1.Logo,
662
- {
663
- css: { flexShrink: 0 },
664
- onClick: () => window.scrollTo({ top: 0, behavior: "smooth" })
665
- }
666
- ),
667
- /* @__PURE__ */ jsx(OverviewSearch, {})
668
- ] }) }),
669
- /* @__PURE__ */ jsx(NavigationPanel$1.Root, { panelPosition: "right", css: { position: "relative", margin: "0" }, children: /* @__PURE__ */ jsx(NavigationPanel$1.Body, { children: /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", minHeight: 36 }, children: /* @__PURE__ */ jsx(ColorSchemeToggle, {}) }) }) })
670
- ]
671
- }
672
- ),
673
- /* @__PURE__ */ jsx(
674
- SimpleGrid,
675
- {
676
- p: { base: "md", sm: "md" },
677
- pt: { base: "sm", sm: "sm" },
678
- cols: { base: 1, sm: 2, md: 3, xl: 4 },
679
- spacing: { base: 10, sm: "xl" },
680
- verticalSpacing: { base: "md", sm: "xl" },
681
- children: views.map((v) => /* @__PURE__ */ jsx(ViewCard, { view: v }, v.id))
682
- }
683
- )
684
- ] });
685
- }
686
- function ViewCard({ view }) {
687
- const [visible, setVisible] = useState(!1), { ref, inViewport } = useInViewport();
688
- return useEffect(() => {
689
- if (!inViewport || visible) return;
690
- const tm = setTimeout(() => setVisible(!0), e$3(30, 80));
691
- return () => clearTimeout(tm);
692
- }, [inViewport, visible]), /* @__PURE__ */ jsxs(
693
- Card,
694
- {
695
- ref,
696
- shadow: "xs",
697
- padding: "lg",
698
- radius: "sm",
699
- className: "group",
700
- withBorder: !0,
701
- children: [
702
- /* @__PURE__ */ jsx(Card.Section, { children: /* @__PURE__ */ jsx(Box$1, { className: previewBg, style: { height: 200 }, children: visible && /* @__PURE__ */ jsx(
703
- StaticLikeC4Diagram,
704
- {
705
- background: "transparent",
706
- view,
707
- fitView: !0,
708
- fitViewPadding: "4px",
709
- reduceGraphics: !0
710
- }
711
- ) }) }),
712
- /* @__PURE__ */ jsx(Group, { justify: "space-between", mt: "md", children: /* @__PURE__ */ jsx(Text, { fw: 500, children: view.title ?? view.id }) }),
713
- /* @__PURE__ */ jsx(
714
- Markdown,
715
- {
716
- value: RichText.from(view.description),
717
- textScale: 0.75,
718
- emptyText: "No description",
719
- className: css({
720
- lineClamp: 3,
721
- mt: "1",
722
- transition: "fast",
723
- opacity: {
724
- base: 0.8,
725
- _groupHover: 1
726
- }
727
- })
728
- }
729
- ),
730
- /* @__PURE__ */ jsx(Link, { to: "/view/$viewId/", params: { viewId: view.id }, search: !0, className: cardLink })
731
- ]
732
- }
733
- );
734
- }
735
- function AdHocViewEditor({ projectId }) {
736
- return /* @__PURE__ */ jsx(
737
- LikeC4AdHocViewEditor,
738
- {
739
- service: {
740
- process: async ({ predicates }) => ({
741
- view: await likec4rpc.calcAdhocView({ projectId, predicates })
742
- })
743
- }
744
- }
745
- );
746
- }
747
- const Route$9 = createFileRoute("/_single/adhoc")({
748
- beforeLoad: () => {
749
- if (!isRpcAvailable)
750
- throw redirect({
751
- to: "/single-index/"
752
- });
753
- },
754
- component: Page$4
755
- });
756
- function Page$4() {
757
- const { projectId } = Route$9.useRouteContext();
758
- return /* @__PURE__ */ jsx(AdHocViewEditor, { projectId });
759
- }
760
- const Route$8 = createFileRoute("/_single/webcomponent/$")({
761
- component: WebcomponentPage
762
- });
763
- function WebcomponentPage() {
764
- const router = useRouter(), viewId = Route$8.useParams()._splat || "index", { colorScheme } = useMantineColorScheme();
765
- let base = router.basepath.endsWith("/") ? router.basepath : `${router.basepath}/`;
766
- const jsurl = new URL(
767
- `${base}likec4-views.js`,
768
- window.location.href
769
- ), iframeHtml = `
770
- <!DOCTYPE html>
771
- <html lang="en-US" style="color-scheme: ${colorScheme};">
772
- <head>
773
- <meta charset="utf-8" />
774
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no" />
775
- <style>
776
- * {
777
- border-width: 0px;
778
- border-style: solid;
779
- box-sizing: border-box;
780
- overflow-wrap: break-word;
781
- }
782
- html, body {
783
- margin: 0;
784
- background-color: transparent !important;
785
- width: 100%;
786
- height: 100%;
787
- font-size: 16px;
788
- }
789
- body {
790
- min-height: 100%;
791
- }
792
- </style>
793
- </head>
794
- <body>
795
- <div style="width: 100%; height: 100%; padding: clamp(0.5rem, 5vh, 4rem) clamp(0.5rem, 5vw, 5rem)">
796
- <${ComponentName.View} view-id="${encodeURIComponent(viewId)}"></${ComponentName.View}>
797
- </div>
798
- <script type="module" src="${jsurl.href}"><\/script>
799
- </body>
800
- </html>
801
- `;
802
- return /* @__PURE__ */ jsx(
803
- Box,
804
- {
805
- css: {
806
- position: "fixed",
807
- inset: "0",
808
- width: "100%",
809
- height: "100%",
810
- overflow: "hidden",
811
- "& iframe": {
812
- width: "100%",
813
- height: "100%",
814
- borderStyle: "none",
815
- backgroundColor: "transparent",
816
- overflow: "hidden"
817
- }
818
- },
819
- children: /* @__PURE__ */ jsx(
820
- "iframe",
821
- {
822
- srcDoc: iframeHtml,
823
- allowtransparency: "true"
824
- }
825
- )
826
- }
827
- );
828
- }
829
- const { withProvider, withContext } = createStyleContext(navigationPanel), shouldForwardProp = (prop, variantKeys) => !variantKeys.includes(prop) && (isValidMotionProp(prop) || !isCssProperty(prop)), Root = withProvider(MotionDiv, "root", {
830
- shouldForwardProp
831
- }), Body = withContext(MotionDiv, "body", {
832
- shouldForwardProp
833
- });
834
- withContext(MotionDiv, "label", {
835
- shouldForwardProp
836
- });
837
- withContext(MotionDiv, "dropdown", {
838
- shouldForwardProp
839
- });
840
- const NavigationPanel = {
841
- Root,
842
- Body
843
- };
844
- function SelectProject() {
845
- const projects = useLikeC4Projects$1(), project = useCurrentProject();
846
- return projects.length < 2 ? null : /* @__PURE__ */ jsxs(Menu, { shadow: "md", width: 200, trigger: "click-hover", openDelay: 200, children: [
847
- /* @__PURE__ */ jsx(MenuTarget, { children: /* @__PURE__ */ jsx(
848
- Button,
849
- {
850
- variant: "subtle",
851
- size: "sm",
852
- color: "gray",
853
- px: "sm",
854
- rightSection: /* @__PURE__ */ jsx(IconChevronDown, { opacity: 0.5, size: 14 }),
855
- visibleFrom: "md",
856
- children: project.title ?? project.id
857
- }
858
- ) }),
859
- /* @__PURE__ */ jsxs(MenuDropdown, { children: [
860
- /* @__PURE__ */ jsx(
861
- MenuItem,
862
- {
863
- renderRoot: (props) => /* @__PURE__ */ jsx(
864
- Link,
865
- {
866
- ...props,
867
- to: "/projects"
868
- }
869
- ),
870
- children: "Projects overview"
871
- }
872
- ),
873
- /* @__PURE__ */ jsx(MenuDivider, {}),
874
- projects.map(({ id, title: title2 }) => /* @__PURE__ */ jsx(
875
- MenuItem,
876
- {
877
- renderRoot: (props) => /* @__PURE__ */ jsx(
878
- Link,
879
- {
880
- ...props,
881
- to: "/project/$projectId/view/$viewId/",
882
- params: {
883
- projectId: id,
884
- viewId: "index"
885
- }
886
- }
887
- ),
888
- children: title2 ?? id
889
- },
890
- id
891
- ))
892
- ] })
893
- ] });
894
- }
895
- const AlertLocalhost = () => /* @__PURE__ */ jsx(
896
- Alert,
897
- {
898
- color: "yellow",
899
- icon: /* @__PURE__ */ jsx(IconAlertTriangle, {}),
900
- title: "Localhost URL",
901
- styles: { body: { gap: rem(4) } },
902
- children: /* @__PURE__ */ jsx(Text, { c: "yellow", size: "sm", children: "You need to deploy your project to make it available on the internet" })
903
- }
904
- ), CopyButtonChild = ({ copied, copy }) => /* @__PURE__ */ jsx(
905
- Button,
906
- {
907
- size: "xs",
908
- color: copied ? "teal" : "gray",
909
- variant: "light",
910
- leftSection: copied ? /* @__PURE__ */ jsx(IconCheck, { style: { width: rem(16) } }) : /* @__PURE__ */ jsx(IconCopy, { style: { width: rem(16) } }),
911
- onClick: copy,
912
- children: copied ? "Copied" : "Copy to clipboard"
913
- }
914
- ), EmbedPanel = ({ diagram }) => {
915
- const router = useRouter(), { colorScheme } = useMantineColorScheme(), [theme, setTheme] = useState(colorScheme), padding = 20;
916
- let location = router.buildLocation({
917
- to: "/embed/$viewId/",
918
- // '/' at the end added by Gemini 3, must have to pass typecheck
919
- params: { viewId: diagram.id },
920
- search: {
921
- padding,
922
- ...theme !== "auto" ? { theme } : {}
923
- // changed from "theme: theme !== 'auto' ? theme : undefined" by Gemini 3
924
- }
925
- }).href;
926
- location = useHashHistory ? `#${location}` : location;
927
- const url = new URL(location, window.location.href), width = diagram.bounds.width + padding * 2, height = diagram.bounds.height + padding * 2, href = url.href, code = `
928
- <div style="aspect-ratio:${width}/${height};width:100%;height:auto;max-width:${width}px;margin:0 auto">
929
- <iframe src="${href}" width="100%" height="100%" style="border:0;background:transparent;"></iframe>
930
- </div>
931
- `.trim();
932
- return /* @__PURE__ */ jsxs(Stack, { children: [
933
- code.includes("http://localhost") && /* @__PURE__ */ jsx(AlertLocalhost, {}),
934
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: "Embedded view is an iframe with a static diagram" }) }),
935
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
936
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
937
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "HTML" }) }),
938
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
939
- /* @__PURE__ */ jsx(ActionIcon, { component: "a", href, target: "_blank", variant: "light", color: "gray", children: /* @__PURE__ */ jsx(IconExternalLink, {}) }),
940
- /* @__PURE__ */ jsx(CopyButton$1, { value: code, timeout: 1500, children: CopyButtonChild })
941
- ] })
942
- ] }),
943
- /* @__PURE__ */ jsx(Code, { block: !0, children: code }),
944
- /* @__PURE__ */ jsx(
945
- Box$1,
946
- {
947
- style: {
948
- alignSelf: "flex-start"
949
- },
950
- children: /* @__PURE__ */ jsx(
951
- Select,
952
- {
953
- label: "Color scheme",
954
- value: theme,
955
- allowDeselect: !1,
956
- onChange: (v) => setTheme(v ?? "auto"),
957
- data: [
958
- { value: "auto", label: "Auto" },
959
- { value: "light", label: "Light" },
960
- { value: "dark", label: "Dark" }
961
- ]
962
- }
963
- )
964
- }
965
- )
966
- ] })
967
- ] });
968
- };
969
- function WebcomponentsPanel({ diagram }) {
970
- const router = useRouter();
971
- let base = router.basepath.endsWith("/") ? router.basepath : `${router.basepath}/`;
972
- const jscode = `
973
- <script module src="${new URL(
974
- `${base}likec4-views.js`,
975
- window.location.href
976
- ).href}"><\/script>
977
- `.trim(), htmlCode = `
978
- <${ComponentName.View}
979
- view-id="${encodeURIComponent(diagram.id)}"
980
- browser="true"
981
- dynamic-variant="sequence">
982
- </${ComponentName.View}>
983
- `.trim(), webcomponentPreview = router.buildLocation(
984
- {
985
- to: "/webcomponent/$/",
986
- // '/' at the end added by Gemini 3, must have to pass typecheck
987
- params: { _splat: diagram.id },
988
- search: !0
989
- }
990
- );
991
- return /* @__PURE__ */ jsxs(Stack, { children: [
992
- jscode.includes("http://localhost") && /* @__PURE__ */ jsx(AlertLocalhost, {}),
993
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: "Add this script to your page:" }) }),
994
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
995
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
996
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "JavaScript" }) }),
997
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
998
- /* @__PURE__ */ jsx(ActionIcon, { component: "a", href: webcomponentPreview.href, target: "_blank", variant: "light", color: "gray", children: /* @__PURE__ */ jsx(IconExternalLink, {}) }),
999
- /* @__PURE__ */ jsx(
1000
- CopyButton$1,
1001
- {
1002
- value: jscode,
1003
- timeout: 1500,
1004
- children: CopyButtonChild
1005
- }
1006
- )
1007
- ] })
1008
- ] }),
1009
- /* @__PURE__ */ jsx(Code, { block: !0, children: jscode }),
1010
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
1011
- "This script defines a custom element (webcomponent) that renders your diagrams.",
1012
- /* @__PURE__ */ jsx("br", {}),
1013
- "Script must be inserted once in the ",
1014
- /* @__PURE__ */ jsx("code", { children: "<head>" }),
1015
- " or at the end of the ",
1016
- /* @__PURE__ */ jsx("code", { children: "<body>" }),
1017
- " ",
1018
- "tag."
1019
- ] }) })
1020
- ] }),
1021
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
1022
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
1023
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "HTML" }) }),
1024
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(
1025
- CopyButton$1,
1026
- {
1027
- value: htmlCode,
1028
- timeout: 1500,
1029
- children: CopyButtonChild
1030
- }
1031
- ) })
1032
- ] }),
1033
- /* @__PURE__ */ jsx(Code, { block: !0, children: htmlCode }),
1034
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
1035
- "Insert this code to your page. Page may have multiple ",
1036
- /* @__PURE__ */ jsx("code", { children: "<likec4-view>" }),
1037
- "."
1038
- ] }) })
1039
- ] })
1040
- ] });
1041
- }
1042
- function ShareModal({
1043
- onClose
1044
- }) {
1045
- const [diagram] = useCurrentView(), [activeTab, setActiveTab] = useState("webcomponent");
1046
- return diagram ? /* @__PURE__ */ jsxs(
1047
- ModalRoot,
1048
- {
1049
- size: "xl",
1050
- opened: !0,
1051
- onClose,
1052
- children: [
1053
- /* @__PURE__ */ jsx(ModalOverlay, { backgroundOpacity: 0.5, blur: 3 }),
1054
- /* @__PURE__ */ jsx(ModalContent, { children: /* @__PURE__ */ jsxs(ModalBody, { children: [
1055
- /* @__PURE__ */ jsxs(Tabs, { value: activeTab, onChange: (tab) => setActiveTab(tab ?? "webcomponent"), children: [
1056
- /* @__PURE__ */ jsxs(TabsList, { children: [
1057
- /* @__PURE__ */ jsx(TabsTab, { value: "webcomponent", children: "Webcomponent" }),
1058
- /* @__PURE__ */ jsx(TabsTab, { value: "embed", children: "Embedded" })
1059
- ] }),
1060
- /* @__PURE__ */ jsx(TabsPanel, { value: "embed", pt: "md", children: /* @__PURE__ */ jsx(EmbedPanel, { diagram }) }),
1061
- /* @__PURE__ */ jsx(TabsPanel, { value: "webcomponent", pt: "md", children: /* @__PURE__ */ jsx(WebcomponentsPanel, { diagram }) })
1062
- ] }),
1063
- /* @__PURE__ */ jsx(Group, { justify: "flex-end", mt: "lg", children: /* @__PURE__ */ jsx(Button, { size: "sm", onClick: onClose, children: "Close" }) })
1064
- ] }) })
1065
- ]
1066
- }
1067
- ) : null;
1068
- }
1069
- const Header = memo(() => {
1070
- const projects = useLikeC4Projects$1(), isReactDiagramRoute = useMatches({
1071
- select(matches) {
1072
- return matches.some(
1073
- ({ routeId }) => routeId === "/_single/view/$viewId/" || routeId === "/project/$projectId/view/$viewId/"
1074
- );
1075
- }
1076
- }), { breakpoints } = useMantineTheme(), isTablet = useMediaQuery(`(min-width: ${breakpoints.md})`) ?? !1, [opened, { open, close }] = useDisclosure(!1);
1077
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1078
- /* @__PURE__ */ jsx(NavigationPanel.Root, { panelPosition: "right", hideBelow: "md", children: /* @__PURE__ */ jsxs(NavigationPanel.Body, { gap: "2", children: [
1079
- isReactDiagramRoute ? /* @__PURE__ */ jsxs(Fragment, { children: [
1080
- /* @__PURE__ */ jsx(SelectProject, {}),
1081
- projects.length <= 1 && /* @__PURE__ */ jsx(
1082
- Button,
1083
- {
1084
- size: isTablet ? "sm" : "xs",
1085
- leftSection: /* @__PURE__ */ jsx(IconShare, { size: 14 }),
1086
- onClick: open,
1087
- children: "Share"
1088
- }
1089
- ),
1090
- /* @__PURE__ */ jsx(ExportButton, {})
1091
- ] }) : /* @__PURE__ */ jsx(
1092
- Button,
1093
- {
1094
- component: Link,
1095
- to: "/view/$viewId/",
1096
- size: isTablet ? "sm" : "xs",
1097
- variant: "subtle",
1098
- color: "gray",
1099
- children: "Back to diagram"
1100
- }
1101
- ),
1102
- /* @__PURE__ */ jsx(Divider, { orientation: "vertical", visibleFrom: "md" }),
1103
- /* @__PURE__ */ jsx(ColorSchemeToggle, {})
1104
- ] }) }),
1105
- opened && /* @__PURE__ */ jsx(ShareModal, { onClose: close })
1106
- ] });
1107
- }), enableDownload = (params) => ({
1108
- ...params,
1109
- download: !0
1110
- }), enableJpegDownload = (params) => ({
1111
- ...params,
1112
- download: !0,
1113
- format: "jpeg"
1114
- });
1115
- function ExportButton() {
1116
- const isInsideProject = useMatches({
1117
- select: (matches) => matches.some(({ routeId }) => routeId === "/project/$projectId")
1118
- }), project = useCurrentProject(), viewId = useCurrentViewId(), handleDrawioExport = useCallback(async () => {
1119
- try {
1120
- const { loadDrawioSources } = await import("likec4:drawio"), { drawioEditUrl } = await loadDrawioSources(project.id), url = drawioEditUrl(viewId);
1121
- window.open(url, "_blank", "noopener,noreferrer");
1122
- } catch (error) {
1123
- console.error("Failed to export to Draw.io:", error);
1124
- }
1125
- }, [project.id, viewId]);
1126
- return /* @__PURE__ */ jsxs(Menu, { shadow: "md", width: 200, trigger: "click-hover", openDelay: 200, children: [
1127
- /* @__PURE__ */ jsx(MenuTarget, { children: /* @__PURE__ */ jsx(
1128
- Button,
1129
- {
1130
- variant: "subtle",
1131
- size: "sm",
1132
- color: "gray",
1133
- px: "sm",
1134
- rightSection: /* @__PURE__ */ jsx(IconChevronDown, { opacity: 0.5, size: 14 }),
1135
- visibleFrom: "md",
1136
- children: "Export"
1137
- }
1138
- ) }),
1139
- /* @__PURE__ */ jsxs(MenuDropdown, { children: [
1140
- /* @__PURE__ */ jsx(MenuLabel, { children: "Current view" }),
1141
- /* @__PURE__ */ jsx(
1142
- MenuItem,
1143
- {
1144
- renderRoot: (props) => /* @__PURE__ */ jsx(
1145
- Link,
1146
- {
1147
- target: "_blank",
1148
- to: isInsideProject ? "/project/$projectId/export/$viewId/" : "/export/$viewId/",
1149
- search: enableDownload,
1150
- ...props
1151
- }
1152
- ),
1153
- children: "Export as .png"
1154
- }
1155
- ),
1156
- /* @__PURE__ */ jsx(
1157
- MenuItem,
1158
- {
1159
- renderRoot: (props) => /* @__PURE__ */ jsx(
1160
- Link,
1161
- {
1162
- target: "_blank",
1163
- to: isInsideProject ? "/project/$projectId/export/$viewId/" : "/export/$viewId/",
1164
- search: enableJpegDownload,
1165
- ...props
1166
- }
1167
- ),
1168
- children: "Export as .jpg"
1169
- }
1170
- ),
1171
- /* @__PURE__ */ jsx(
1172
- MenuItem,
1173
- {
1174
- renderRoot: (props) => /* @__PURE__ */ jsx(
1175
- Link,
1176
- {
1177
- to: isInsideProject ? "/project/$projectId/view/$viewId/dot/" : "/view/$viewId/dot/",
1178
- search: !0,
1179
- ...props
1180
- }
1181
- ),
1182
- children: "Export as .dot"
1183
- }
1184
- ),
1185
- /* @__PURE__ */ jsx(
1186
- MenuItem,
1187
- {
1188
- renderRoot: (props) => /* @__PURE__ */ jsx(
1189
- Link,
1190
- {
1191
- to: isInsideProject ? "/project/$projectId/view/$viewId/d2" : "/view/$viewId/d2",
1192
- search: !0,
1193
- ...props
1194
- }
1195
- ),
1196
- children: "Export as .d2"
1197
- }
1198
- ),
1199
- /* @__PURE__ */ jsx(
1200
- MenuItem,
1201
- {
1202
- renderRoot: (props) => /* @__PURE__ */ jsx(
1203
- Link,
1204
- {
1205
- to: isInsideProject ? "/project/$projectId/view/$viewId/mmd" : "/view/$viewId/mmd",
1206
- search: !0,
1207
- ...props
1208
- }
1209
- ),
1210
- children: "Export as .mmd"
1211
- }
1212
- ),
1213
- /* @__PURE__ */ jsx(
1214
- MenuItem,
1215
- {
1216
- renderRoot: (props) => /* @__PURE__ */ jsx(
1217
- Link,
1218
- {
1219
- to: isInsideProject ? "/project/$projectId/view/$viewId/puml" : "/view/$viewId/puml",
1220
- search: !0,
1221
- ...props
1222
- }
1223
- ),
1224
- children: "Export as .puml"
1225
- }
1226
- ),
1227
- /* @__PURE__ */ jsx(MenuItem, { onClick: handleDrawioExport, children: "Export to Draw.io" }),
1228
- /* @__PURE__ */ jsx(MenuItem, { disabled: !0, children: "Export to Miro" }),
1229
- /* @__PURE__ */ jsx(MenuItem, { disabled: !0, children: "Export to Notion" })
1230
- ] })
1231
- ] });
1232
- }
1233
- const Route$7 = createFileRoute("/_single/view/$viewId")({
1234
- component: ViewLayout,
1235
- errorComponent: ({ error, reset }) => /* @__PURE__ */ jsx(Fallback, { error, resetErrorBoundary: reset })
1236
- });
1237
- function ViewLayout() {
1238
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1239
- /* @__PURE__ */ jsx(Outlet, {}),
1240
- /* @__PURE__ */ jsx(Header, {})
1241
- ] });
1242
- }
1243
- function triggerDownload(url, filename) {
1244
- const link = document.createElement("a");
1245
- return link.setAttribute("download", filename), link.href = url, document.body.appendChild(link), link.click(), new Promise(
1246
- (resolve) => setTimeout(() => {
1247
- document.body.removeChild(link), URL.revokeObjectURL(url), resolve();
1248
- }, 1e3)
1249
- );
1250
- }
1251
- async function downloadAsPng({
1252
- pngFilename,
1253
- viewport
1254
- }) {
1255
- try {
1256
- const blob = await toBlob(viewport, {
1257
- backgroundColor: "transparent",
1258
- cacheBust: !0,
1259
- imagePlaceholder: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
1260
- });
1261
- if (!blob)
1262
- throw new Error("Failed to create PNG blob");
1263
- const url = URL.createObjectURL(blob);
1264
- await triggerDownload(url, `${pngFilename}.png`), window.close();
1265
- } catch (err) {
1266
- console.error(err), window.alert("Failed to export to PNG, check the console for more details.");
1267
- }
1268
- }
1269
- async function downloadAsJpeg({
1270
- filename,
1271
- viewport,
1272
- quality = 0.8
1273
- }) {
1274
- try {
1275
- const backgroundColor = getComputedStyle(document.documentElement).getPropertyValue("--mantine-color-body"), dataUrl = await toJpeg(viewport, {
1276
- backgroundColor,
1277
- quality,
1278
- cacheBust: !0,
1279
- // 1x1 transparent GIF used as fallback when remote images fail to load
1280
- imagePlaceholder: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
1281
- });
1282
- await triggerDownload(dataUrl, `${filename}.jpg`), window.close();
1283
- } catch (err) {
1284
- console.error(err), window.alert("Failed to export to JPEG, check the console for more details.");
1285
- }
1286
- }
1287
- function ExportPage() {
1288
- const [diagram] = useCurrentView(), { format } = useSearch({ strict: !1 }), isJpeg = format === "jpeg";
1289
- return useTransparentBackground(!isJpeg), diagram ? /* @__PURE__ */ jsx(GuardedExportPage, { diagram, isJpeg }) : /* @__PURE__ */ jsx("div", { children: "Loading..." });
1290
- }
1291
- function GuardedExportPage({ diagram, isJpeg }) {
1292
- const {
1293
- padding = 20,
1294
- download = !1,
1295
- quality,
1296
- dynamic
1297
- } = useSearch({
1298
- strict: !1
1299
- }), viewportRef = useRef(null), loadingOverlayRef = useRef(null), downloadedRef = useRef(!1), bounds = pickViewBounds(diagram, dynamic), downloadDiagram = () => {
1300
- const viewport = viewportRef.current;
1301
- if (!download || !viewport || !diagram || downloadedRef.current)
1302
- return;
1303
- const loadingOverlay = loadingOverlayRef.current;
1304
- loadingOverlay && (loadingOverlay.style.display = "none"), downloadedRef.current = !0, isJpeg ? downloadAsJpeg({
1305
- filename: diagram.id,
1306
- viewport,
1307
- quality: quality ?? 0.8
1308
- }) : downloadAsPng({
1309
- pngFilename: diagram.id,
1310
- viewport
1311
- });
1312
- }, extraPadding = 16, width = bounds.width + padding * 2 + extraPadding, height = bounds.height + padding * 2 + extraPadding;
1313
- return /* @__PURE__ */ jsxs(
1314
- Box,
1315
- {
1316
- ref: viewportRef,
1317
- "data-testid": "export-page",
1318
- css: {
1319
- position: "fixed",
1320
- top: "0",
1321
- left: "0",
1322
- padding: "0",
1323
- margin: "0",
1324
- overflow: "hidden",
1325
- zIndex: 2
1326
- },
1327
- style: {
1328
- marginRight: "auto",
1329
- marginBottom: "auto",
1330
- minWidth: width,
1331
- width,
1332
- minHeight: height,
1333
- height,
1334
- background: isJpeg ? "var(--mantine-color-body)" : "transparent"
1335
- },
1336
- children: [
1337
- download && /* @__PURE__ */ jsx(LoadingOverlay, { ref: loadingOverlayRef, visible: !0 }),
1338
- /* @__PURE__ */ jsx(
1339
- LikeC4Diagram,
1340
- {
1341
- view: diagram,
1342
- fitView: !1,
1343
- fitViewPadding: {
1344
- top: "0px",
1345
- bottom: "0px",
1346
- left: "0px",
1347
- right: "0px"
1348
- },
1349
- background: isJpeg ? "solid" : "transparent",
1350
- reduceGraphics: !1,
1351
- dynamicViewVariant: dynamic,
1352
- className: "likec4-static-view",
1353
- pannable: !1,
1354
- zoomable: !1,
1355
- controls: !1,
1356
- enableNotations: !1,
1357
- enableElementDetails: !1,
1358
- enableRelationshipDetails: !1,
1359
- enableRelationshipBrowser: !1,
1360
- enableDynamicViewWalkthrough: !1,
1361
- enableFocusMode: !1,
1362
- enableSearch: !1,
1363
- nodesSelectable: !1,
1364
- enableElementTags: !1,
1365
- onInitialized: () => {
1366
- if (!viewportRef.current) {
1367
- console.error("viewportRef.current is null");
1368
- return;
1369
- }
1370
- const x = Math.round(-bounds.x + padding), y = Math.round(-bounds.y + padding);
1371
- [...viewportRef.current.querySelectorAll(".react-flow__viewport")].forEach((el) => {
1372
- el.style.transform = "translate(" + x + "px, " + y + "px)";
1373
- }), download && window.setTimeout(downloadDiagram, 500);
1374
- }
1375
- }
1376
- )
1377
- ]
1378
- }
1379
- );
1380
- }
1381
- const Route$6 = createFileRoute("/_single/export/$viewId")({
1382
- validateSearch: z.object({
1383
- download: z.boolean().optional().catch(!1),
1384
- format: z.enum(["png", "jpeg"]).optional().catch("png"),
1385
- quality: z.number().min(0).max(1).optional().catch(void 0)
1386
- }),
1387
- search: {
1388
- middlewares: [
1389
- stripSearchParams({
1390
- download: !1,
1391
- format: "png",
1392
- quality: void 0
1393
- })
1394
- ]
1395
- },
1396
- component: ExportPage
1397
- });
1398
- function EmbedPage() {
1399
- const {
1400
- padding = 20,
1401
- dynamic
1402
- } = useSearch({
1403
- strict: !1
1404
- }), [diagram] = useCurrentView();
1405
- if (useTransparentBackground(!!diagram), !diagram)
1406
- return /* @__PURE__ */ jsx("div", { children: "Loading..." });
1407
- const bounds = pickViewBounds(diagram, dynamic);
1408
- return /* @__PURE__ */ jsx(
1409
- "div",
1410
- {
1411
- style: {
1412
- position: "absolute",
1413
- top: 0,
1414
- left: "50%",
1415
- boxSizing: "border-box",
1416
- padding,
1417
- transform: "translateX(-50%)",
1418
- aspectRatio: `${bounds.width + padding * 2} / ${bounds.height + padding * 2}`,
1419
- width: "100vw",
1420
- maxWidth: bounds.width + padding * 2,
1421
- height: "auto",
1422
- maxHeight: "100vh"
1423
- },
1424
- children: /* @__PURE__ */ jsx(
1425
- StaticLikeC4Diagram,
1426
- {
1427
- view: diagram,
1428
- fitView: !0,
1429
- background: "transparent",
1430
- fitViewPadding: 0,
1431
- dynamicViewVariant: dynamic,
1432
- initialWidth: bounds.width,
1433
- initialHeight: bounds.height
1434
- }
1435
- )
1436
- }
1437
- );
1438
- }
1439
- const Route$5 = createFileRoute("/_single/embed/$viewId")({
1440
- component: EmbedPage
1441
- });
1442
- function ViewReact() {
1443
- const navigate = useNavigate(), [view, setLayoutType] = useCurrentView(), model = useLikeC4Model(), { dynamic } = useSearch({
1444
- from: "__root__"
1445
- }), onNavigateTo = useCallbackRef((viewId) => {
1446
- navigate({
1447
- to: "./",
1448
- viewTransition: !1,
1449
- params: (current) => ({
1450
- ...current,
1451
- viewId
1452
- }),
1453
- search: !0
1454
- });
1455
- }), title2 = view ? view.title ?? view.id : "View not found", pageTitle$1 = model.project.title ?? pageTitle;
1456
- if (useDocumentTitle(`${title2} - ${pageTitle$1}`), !view)
1457
- return /* @__PURE__ */ jsx(NotFound, {});
1458
- const hasNotations = (view.notation?.nodes ?? []).length > 0;
1459
- return /* @__PURE__ */ jsxs(
1460
- LikeC4Diagram,
1461
- {
1462
- view,
1463
- zoomable: !0,
1464
- pannable: !0,
1465
- controls: !0,
1466
- fitViewPadding: {
1467
- top: "70px",
1468
- bottom: "32px",
1469
- left: "32px",
1470
- right: "32px"
1471
- },
1472
- showNavigationButtons: !0,
1473
- enableSearch: !0,
1474
- enableFocusMode: !0,
1475
- enableDynamicViewWalkthrough: !0,
1476
- dynamicViewVariant: dynamic,
1477
- enableElementDetails: !0,
1478
- enableRelationshipDetails: !0,
1479
- enableRelationshipBrowser: !0,
1480
- enableElementTags: !0,
1481
- enableCompareWithLatest: !0,
1482
- enableNotations: hasNotations,
1483
- nodesSelectable: !0,
1484
- onNavigateTo,
1485
- onLayoutTypeChange: setLayoutType,
1486
- onLogoClick: () => {
1487
- navigate({
1488
- to: "/"
1489
- });
1490
- },
1491
- children: [
1492
- /* @__PURE__ */ jsx(ListenForDynamicVariantChange, {}),
1493
- /* @__PURE__ */ jsx(OpenRelationshipBrowserFromUrl, {}),
1494
- /* @__PURE__ */ jsx(FocusElementFromUrl, {})
1495
- ]
1496
- }
1497
- );
1498
- }
1499
- function OpenRelationshipBrowserFromUrl() {
1500
- const router = useRouter(), diagram = useDiagram(), { relationships } = useSearch({
1501
- from: "__root__"
1502
- }), processedRef = useRef(null), isInitializedRef = useRef(!1), isProcessingRef = useRef(Promise.resolve()), isMounted = useIsMounted(), openAndClear = (fqn) => {
1503
- isProcessingRef.current = isProcessingRef.current.then(async () => {
1504
- if (!(!isMounted() || processedRef.current === fqn))
1505
- try {
1506
- processedRef.current = fqn, diagram.openRelationshipsBrowser(fqn), await router.buildAndCommitLocation({
1507
- search: (s) => {
1508
- const { relationships: _, ...rest } = s;
1509
- return rest;
1510
- },
1511
- replace: !0,
1512
- viewTransition: !1
1513
- });
1514
- } catch (error) {
1515
- console.error("Failed to open relationship browser:", error);
1516
- }
1517
- });
1518
- }, process = () => {
1519
- if (!relationships) {
1520
- processedRef.current = null;
1521
- return;
1522
- }
1523
- relationships && processedRef.current !== relationships && openAndClear(relationships);
1524
- };
1525
- return useOnDiagramEvent("initialized", () => {
1526
- isInitializedRef.current = !0, process();
1527
- }), useUpdateEffect(() => {
1528
- process();
1529
- }, [relationships]), null;
1530
- }
1531
- function FocusElementFromUrl() {
1532
- const router = useRouter(), diagram = useDiagram(), { focusOnElement } = useSearch({
1533
- from: "__root__"
1534
- }), processedRef = useRef(null), focusAndClear = useCallbackRef((fqn) => {
1535
- try {
1536
- if (processedRef.current === fqn) return;
1537
- processedRef.current = fqn, diagram.focusOnElement(fqn), router.buildAndCommitLocation({
1538
- search: (s) => {
1539
- const { focusOnElement: _, ...rest } = s;
1540
- return rest;
1541
- },
1542
- replace: !0,
1543
- viewTransition: !1
1544
- });
1545
- } catch (error) {
1546
- console.error("focusOnElement failed:", error);
1547
- }
1548
- });
1549
- return useOnDiagramEvent("initialized", () => {
1550
- focusOnElement && processedRef.current !== focusOnElement && focusAndClear(focusOnElement);
1551
- }), useUpdateEffect(() => {
1552
- focusOnElement || (processedRef.current = null);
1553
- }, [focusOnElement]), null;
1554
- }
1555
- function ListenForDynamicVariantChange() {
1556
- const router = useRouter(), dynamicViewVariant = useDiagramContext((c) => c.dynamicViewVariant);
1557
- return useUpdateEffect(() => {
1558
- (router.latestLocation.search.dynamic ?? "diagram") !== dynamicViewVariant && router.buildAndCommitLocation({
1559
- search: (current) => ({
1560
- ...current,
1561
- dynamic: dynamicViewVariant
1562
- }),
1563
- viewTransition: !1
1564
- });
1565
- }, [dynamicViewVariant]), null;
1566
- }
1567
- function ViewEditor() {
1568
- const navigate = useNavigate(), project = useCurrentProject(), [view, setLayoutType] = useCurrentView(), $likec4model = useLikeC4ModelAtom(), { dynamic } = useSearch({ strict: !1 }), onNavigateTo = useCallbackRef((viewId) => {
1569
- navigate({
1570
- to: "./",
1571
- viewTransition: !1,
1572
- params: (current) => ({
1573
- ...current,
1574
- viewId
1575
- }),
1576
- search: !0
1577
- });
1578
- });
1579
- if (!view)
1580
- return /* @__PURE__ */ jsx(NotFound, {});
1581
- const hasNotations = (view.notation?.nodes ?? []).length > 0;
1582
- return /* @__PURE__ */ jsx(
1583
- LikeC4EditorProvider,
1584
- {
1585
- editor: {
1586
- fetchView: (id, layout) => {
1587
- const model = $likec4model.get().view(id);
1588
- return layout === "auto" ? model.$view : model.$layouted;
1589
- },
1590
- handleChange: (viewId, change) => {
1591
- const event = {
1592
- projectId: project.id,
1593
- viewId,
1594
- change
1595
- };
1596
- return likec4rpc.updateView(event);
1597
- }
1598
- },
1599
- children: /* @__PURE__ */ jsxs(
1600
- LikeC4Diagram,
1601
- {
1602
- view,
1603
- zoomable: !0,
1604
- pannable: !0,
1605
- controls: !0,
1606
- fitViewPadding: {
1607
- top: "70px",
1608
- bottom: "32px",
1609
- left: "50px",
1610
- right: "32px"
1611
- },
1612
- showNavigationButtons: !0,
1613
- enableNotations: isDevelopment || hasNotations,
1614
- enableSearch: !0,
1615
- enableDynamicViewWalkthrough: !0,
1616
- enableFocusMode: !0,
1617
- enableElementDetails: !0,
1618
- enableRelationshipDetails: !0,
1619
- enableRelationshipBrowser: !0,
1620
- enableElementTags: !0,
1621
- enableCompareWithLatest: !0,
1622
- dynamicViewVariant: dynamic,
1623
- onNavigateTo,
1624
- onLayoutTypeChange: setLayoutType,
1625
- onLogoClick: () => {
1626
- navigate({
1627
- to: "/"
1628
- });
1629
- },
1630
- children: [
1631
- /* @__PURE__ */ jsx(ListenForDynamicVariantChange, {}),
1632
- /* @__PURE__ */ jsx(OpenRelationshipBrowserFromUrl, {}),
1633
- /* @__PURE__ */ jsx(FocusElementFromUrl, {})
1634
- ]
1635
- }
1636
- )
1637
- }
1638
- );
1639
- }
1640
- const Route$4 = createFileRoute("/_single/view/$viewId/")({
1641
- component: isRpcAvailable ? ViewEditor : ViewReact
1642
- });
1643
- function CopyButton({ text }) {
1644
- return /* @__PURE__ */ jsx(CopyButton$1, { value: text, timeout: 2e3, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy", withArrow: !0, position: "right", children: /* @__PURE__ */ jsx(ActionIcon, { color: copied ? "teal" : "gray", variant: copied ? "light" : "subtle", onClick: copy, children: copied ? /* @__PURE__ */ jsx(IconCheck, { style: { width: rem(16) } }) : /* @__PURE__ */ jsx(IconCopy, { style: { width: rem(16) } }) }) }) });
1645
- }
1646
- function CopyToClipboard({ text }) {
1647
- return /* @__PURE__ */ jsx(Box$1, { pos: "absolute", top: "0", right: "0", p: "4", children: /* @__PURE__ */ jsx(CopyButton, { text }) });
1648
- }
1649
- const svgContainer = css({
1650
- minWidth: 300,
1651
- "& svg": {
1652
- width: "100%",
1653
- height: "auto"
1654
- }
1655
- }), cssScrollArea = css({
1656
- height: "100%",
1657
- "& .mantine-ScrollArea-viewport": {
1658
- minHeight: "100%"
1659
- },
1660
- "& .mantine-ScrollArea-viewport > div": {
1661
- minHeight: "100%",
1662
- height: "100%"
1663
- }
1664
- }), cssCodeBlock = css({
1665
- minHeight: "100%"
1666
- }), viewWithTopPadding = css({
1667
- height: "100%",
1668
- paddingTop: "[var(--header-height)]"
1669
- }), fetchFromKroki$1 = async (puml) => await (await fetch(krokiPumlSvgUrl, {
1670
- method: "POST",
1671
- cache: "force-cache",
1672
- body: JSON.stringify({
1673
- diagram_source: puml,
1674
- output_format: "svg"
1675
- }),
1676
- headers: {
1677
- "Content-Type": "application/json"
1678
- }
1679
- })).text();
1680
- function ViewAsPuml({ pumlSource }) {
1681
- const [krokiSvg, { execute }] = useAsync(fetchFromKroki$1, null);
1682
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1683
- Ut,
1684
- {
1685
- className: viewWithTopPadding,
1686
- orientation: "horizontal",
1687
- children: [
1688
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(
1689
- ScrollArea,
1690
- {
1691
- className: cssScrollArea,
1692
- p: 5,
1693
- styles: {
1694
- viewport: {
1695
- borderRadius: 6
1696
- }
1697
- },
1698
- children: [
1699
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: pumlSource }),
1700
- /* @__PURE__ */ jsx(CopyToClipboard, { text: pumlSource })
1701
- ]
1702
- }
1703
- ) }),
1704
- /* @__PURE__ */ jsx(
1705
- Zt,
1706
- {
1707
- style: {
1708
- width: 10
1709
- }
1710
- }
1711
- ),
1712
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(ScrollArea, { h: "100%", children: [
1713
- krokiSvg.status !== "success" && /* @__PURE__ */ jsxs(Fragment, { children: [
1714
- /* @__PURE__ */ jsx(
1715
- Button,
1716
- {
1717
- mt: "xs",
1718
- variant: "light",
1719
- disabled: krokiSvg.status === "loading",
1720
- onClick: () => {
1721
- execute(pumlSource);
1722
- },
1723
- children: krokiSvg.status === "loading" ? "Loading..." : "Render with Kroki"
1724
- }
1725
- ),
1726
- krokiSvg.status === "error" && /* @__PURE__ */ jsx(Box, { children: krokiSvg.error?.message })
1727
- ] }),
1728
- krokiSvg.status === "success" && /* @__PURE__ */ jsx(Box, { className: svgContainer, children: krokiSvg.result ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: krokiSvg.result } }) : /* @__PURE__ */ jsx(Box, { children: "Empty result" }) })
1729
- ] }) })
1730
- ]
1731
- }
1732
- ) });
1733
- }
1734
- const Route$3 = createFileRoute("/_single/view/$viewId/puml")({
1735
- component: Page$3,
1736
- staleTime: 1 / 0,
1737
- loader: async ({ params, context }) => {
1738
- const projectId = context.projectId, { viewId } = params, { loadPumlSources } = await import("likec4:puml");
1739
- try {
1740
- const { pumlSource } = await loadPumlSources(projectId);
1741
- return {
1742
- source: pumlSource(viewId)
1743
- };
1744
- } catch (error) {
1745
- throw console.error(error), notFound();
1746
- }
1747
- }
1748
- });
1749
- function Page$3() {
1750
- const { source } = Route$3.useLoaderData();
1751
- return /* @__PURE__ */ jsx(ViewAsPuml, { pumlSource: source });
1752
- }
1753
- const renderSvg = async (viewId, diagram) => {
1754
- const { default: mermaid } = await import("https://cdn.jsdelivr.net/npm/mermaid@11.12/dist/mermaid.esm.min.mjs");
1755
- mermaid.initialize({
1756
- theme: "dark"
1757
- });
1758
- const { svg } = await mermaid.render(viewId, diagram);
1759
- return svg;
1760
- };
1761
- function ViewAsMmd({ viewId, mmdSource }) {
1762
- const [mmdSvg, { execute }] = useAsync(renderSvg, null);
1763
- return useEffect(() => {
1764
- execute(viewId, mmdSource);
1765
- }, [mmdSource]), /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1766
- Ut,
1767
- {
1768
- className: viewWithTopPadding,
1769
- orientation: "horizontal",
1770
- children: [
1771
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(
1772
- ScrollArea,
1773
- {
1774
- className: cssScrollArea,
1775
- p: 5,
1776
- styles: {
1777
- viewport: {
1778
- borderRadius: 6
1779
- }
1780
- },
1781
- children: [
1782
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: mmdSource }),
1783
- /* @__PURE__ */ jsx(CopyToClipboard, { text: mmdSource })
1784
- ]
1785
- }
1786
- ) }),
1787
- /* @__PURE__ */ jsx(
1788
- Zt,
1789
- {
1790
- style: {
1791
- width: 10
1792
- }
1793
- }
1794
- ),
1795
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsx(ScrollArea, { h: "100%", children: mmdSvg.result && /* @__PURE__ */ jsx(Box, { className: svgContainer, dangerouslySetInnerHTML: { __html: mmdSvg.result } }) }) })
1796
- ]
1797
- }
1798
- ) });
1799
- }
1800
- const Route$2 = createFileRoute("/_single/view/$viewId/mmd")({
1801
- component: Page$2,
1802
- staleTime: 1 / 0,
1803
- loader: async ({ params, context }) => {
1804
- const projectId = context.projectId, { viewId } = params, { loadMmdSources } = await import("likec4:mmd");
1805
- try {
1806
- const { mmdSource } = await loadMmdSources(projectId);
1807
- return {
1808
- source: mmdSource(viewId)
1809
- };
1810
- } catch (error) {
1811
- throw console.error(error), notFound();
1812
- }
1813
- }
1814
- });
1815
- function Page$2() {
1816
- const { viewId } = Route$2.useParams(), { source } = Route$2.useLoaderData();
1817
- return /* @__PURE__ */ jsx(ViewAsMmd, { viewId, mmdSource: source });
1818
- }
1819
- function ViewAsDot({ dot, dotSvg }) {
1820
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Ut, { className: viewWithTopPadding, children: [
1821
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(
1822
- ScrollArea,
1823
- {
1824
- className: cssScrollArea,
1825
- p: 5,
1826
- styles: {
1827
- viewport: {
1828
- borderRadius: 6
1829
- }
1830
- },
1831
- children: [
1832
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: dot }),
1833
- /* @__PURE__ */ jsx(CopyToClipboard, { text: dot })
1834
- ]
1835
- }
1836
- ) }),
1837
- /* @__PURE__ */ jsx(
1838
- Zt,
1839
- {
1840
- style: {
1841
- width: 10
1842
- }
1843
- }
1844
- ),
1845
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsx(ScrollArea, { h: "100%", children: /* @__PURE__ */ jsx("div", { className: svgContainer, dangerouslySetInnerHTML: { __html: dotSvg } }) }) })
1846
- ] }) });
1847
- }
1848
- const Route$1 = createFileRoute("/_single/view/$viewId/dot")({
1849
- component: Page$1,
1850
- staleTime: 1 / 0,
1851
- loader: async ({ params, context }) => {
1852
- const projectId = context.projectId, { viewId } = params, { loadDotSources } = await import("likec4:dot");
1853
- try {
1854
- const { dotSource, svgSource } = await loadDotSources(projectId), dot = dotSource(viewId), dotSvg = svgSource(viewId);
1855
- return {
1856
- dot,
1857
- dotSvg
1858
- };
1859
- } catch (error) {
1860
- throw console.error(error), notFound();
1861
- }
1862
- }
1863
- });
1864
- function Page$1() {
1865
- const { dot, dotSvg } = Route$1.useLoaderData();
1866
- return /* @__PURE__ */ jsx(ViewAsDot, { dot, dotSvg });
1867
- }
1868
- const fetchFromKroki = async (d2) => await (await fetch(krokiD2SvgUrl, {
1869
- method: "POST",
1870
- cache: "force-cache",
1871
- body: JSON.stringify({
1872
- diagram_source: d2,
1873
- // diagram_options: {
1874
- // theme: 'colorblind-clear'
1875
- // },
1876
- output_format: "svg"
1877
- }),
1878
- headers: {
1879
- "Content-Type": "application/json"
1880
- }
1881
- })).text();
1882
- function ViewAsD2({ d2Source }) {
1883
- const [krokiSvg, { execute }] = useAsync(fetchFromKroki, null);
1884
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1885
- Ut,
1886
- {
1887
- className: viewWithTopPadding,
1888
- orientation: "horizontal",
1889
- children: [
1890
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(
1891
- ScrollArea,
1892
- {
1893
- className: cssScrollArea,
1894
- p: 5,
1895
- styles: {
1896
- viewport: {
1897
- borderRadius: 6
1898
- }
1899
- },
1900
- children: [
1901
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: d2Source }),
1902
- /* @__PURE__ */ jsx(CopyToClipboard, { text: d2Source })
1903
- ]
1904
- }
1905
- ) }),
1906
- /* @__PURE__ */ jsx(
1907
- Zt,
1908
- {
1909
- style: {
1910
- width: 10
1911
- }
1912
- }
1913
- ),
1914
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(ScrollArea, { h: "100%", children: [
1915
- krokiSvg.status !== "success" && /* @__PURE__ */ jsxs(Fragment, { children: [
1916
- /* @__PURE__ */ jsx(
1917
- Button,
1918
- {
1919
- mt: "xs",
1920
- variant: "light",
1921
- disabled: krokiSvg.status === "loading",
1922
- onClick: () => {
1923
- execute(d2Source);
1924
- },
1925
- children: krokiSvg.status === "loading" ? "Loading..." : "Render with Kroki"
1926
- }
1927
- ),
1928
- krokiSvg.status === "error" && /* @__PURE__ */ jsx(Box, { children: krokiSvg.error?.message })
1929
- ] }),
1930
- krokiSvg.status === "success" && /* @__PURE__ */ jsx(Box, { className: svgContainer, children: krokiSvg.result ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: krokiSvg.result } }) : /* @__PURE__ */ jsx(Box, { children: "Empty result" }) })
1931
- ] }) })
1932
- ]
1933
- }
1934
- ) });
1935
- }
1936
- const Route = createFileRoute("/_single/view/$viewId/d2")({
1937
- component: Page,
1938
- staleTime: 1 / 0,
1939
- loader: async ({ context, params }) => {
1940
- const projectId = context.projectId, { viewId } = params, { loadD2Sources } = await import("likec4:d2");
1941
- try {
1942
- const { d2Source } = await loadD2Sources(projectId);
1943
- return {
1944
- source: d2Source(viewId)
1945
- };
1946
- } catch (error) {
1947
- throw console.error(error), notFound();
1948
- }
1949
- }
1950
- });
1951
- function Page() {
1952
- const { source } = Route.useLoaderData();
1953
- return /* @__PURE__ */ jsx(ViewAsD2, { d2Source: source });
1954
- }
1955
- export {
1956
- AdHocViewEditor as A,
1957
- ExportPage as E,
1958
- Fallback as F,
1959
- Header as H,
1960
- LikeC4IconRendererContext as L,
1961
- NotFound as N,
1962
- Route$b as R,
1963
- ViewOutlet as V,
1964
- Route$a as a,
1965
- Route$9 as b,
1966
- Route$8 as c,
1967
- Route$7 as d,
1968
- Route$6 as e,
1969
- Route$5 as f,
1970
- Route$4 as g,
1971
- Route$3 as h,
1972
- Route$2 as i,
1973
- Route$1 as j,
1974
- Route as k,
1975
- LikeC4ModelContext as l,
1976
- EmbedPage as m,
1977
- ViewEditor as n,
1978
- ViewReact as o,
1979
- ViewAsPuml as p,
1980
- ViewAsMmd as q,
1981
- ViewAsDot as r,
1982
- ViewAsD2 as s
1983
- };