likec4 1.55.0 → 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 +71 -12
  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 -123
  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 +37 -57
  186. package/react/index.d.mts +2 -28
  187. package/react/index.mjs +50520 -53827
  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 -21225
  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 -189
  197. package/__app__/src/routes/single.js +0 -1924
  198. package/__app__/src/vendors.js +0 -52672
  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,1924 +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 toBlob, c$ as stripSearchParams, cZ as z, bS as useCallbackRef, aL as useIsMounted, T as Tooltip, dC as useAsync, dD as Ut, dE as qt, dF as Zt, dG 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), open = useCallback(() => setIsOpened(!0), []), close = useCallback(() => setIsOpened(!1), []);
266
- return useHotkeys([
267
- ["mod+k", open, { preventDefault: !0 }]
268
- ]), /* @__PURE__ */ jsxs(Fragment, { children: [
269
- /* @__PURE__ */ jsx(SearchControl, { onClick: open }),
270
- /* @__PURE__ */ jsx(FramerMotionConfig, { children: /* @__PURE__ */ jsx(AnimatePresence, { children: isOpened && /* @__PURE__ */ jsx(
271
- Overlay,
272
- {
273
- fullscreen: !0,
274
- withBackdrop: !1,
275
- backdrop: {
276
- opacity: 0.9
277
- },
278
- classes: {
279
- dialog: dialogCss,
280
- body: bodyCss
281
- },
282
- openDelay: 0,
283
- onClose: close,
284
- "data-likec4-search": "true",
285
- children: /* @__PURE__ */ jsx(OverviewSearchAdapter, { onClose: close, children: /* @__PURE__ */ jsx(SearchPanelContent, {}) })
286
- }
287
- ) }) })
288
- ] });
289
- });
290
- OverviewSearch.displayName = "OverviewSearch";
291
- function useTransparentBackground(enabled = !0) {
292
- useIsomorphicLayoutEffect(() => {
293
- const htmlEl = document.body.parentElement;
294
- if (!htmlEl || enabled !== !0) return;
295
- const classname = "transparent-bg";
296
- return htmlEl.classList.add(classname), () => {
297
- htmlEl.classList.remove(classname);
298
- };
299
- }, [enabled]);
300
- }
301
- function useLikeC4Views() {
302
- const $likec4model = useLikeC4ModelAtom(), [views, setViews] = useState([]);
303
- return useEffect(() => $likec4model.subscribe((next) => {
304
- setViews((prev) => {
305
- const nextViews = [...next.views()].map((v) => {
306
- const n = v.$layouted, p = prev.find((_) => _.id === v.id);
307
- return p && deepEqual(n, p) ? p : n;
308
- });
309
- return shallowEqual(prev, nextViews) ? prev : nextViews;
310
- });
311
- }), [$likec4model]), views;
312
- }
313
- function useCurrentViewId() {
314
- return useParams({
315
- select: (params) => params.viewId,
316
- strict: !1
317
- }) ?? "index";
318
- }
319
- function useCurrentView() {
320
- const viewId = useCurrentViewId(), $likec4model = useLikeC4ModelAtom(), [layoutType, setLayoutType] = useState("manual");
321
- useUpdateEffect(() => {
322
- setLayoutType("manual");
323
- }, [viewId]);
324
- const [view, setView] = useState(() => $likec4model.get().findView(viewId)?.$layouted ?? null);
325
- return useEffect(() => $likec4model.subscribe((next) => {
326
- setView((current) => {
327
- const vm = next.findView(viewId);
328
- if (!vm)
329
- return null;
330
- const nextView = layoutType === "auto" ? vm.$view : vm.$layouted;
331
- return deepEqual(current, nextView) ? current : nextView;
332
- });
333
- }), [$likec4model, viewId, layoutType]), [view, setLayoutType];
334
- }
335
- function useCurrentProject() {
336
- const projects = useLikeC4Projects(), projectId = useMatches({
337
- select: (m2) => m2.find((m22) => m22.routeId === "/project/$projectId")?.params?.projectId ?? m2.at(-1)?.context.projectId ?? "default"
338
- });
339
- return projects.find((p) => p.id === projectId) ?? projects[0];
340
- }
341
- const isTreeNodeData = (node) => "type" in node && ["file", "folder", "view", "deployment-view"].includes(node.type);
342
- function dropFilename(relativePath) {
343
- return relativePath === "" ? "" : relativePath.split("/").slice(0, -1).join("/");
344
- }
345
- function compareTreeNodes(a, b) {
346
- return a.children.length === 0 && b.children.length > 0 ? 1 : a.children.length > 0 && b.children.length === 0 ? -1 : compareNatural(a.label, b.label);
347
- }
348
- function buildDiagramTreeData(views, groupBy) {
349
- const root2 = {
350
- value: "",
351
- label: "Diagrams",
352
- type: "folder",
353
- children: []
354
- }, findParent = (path) => {
355
- let parent = root2;
356
- if (path === "")
357
- return parent;
358
- const segments = path.split("/"), traversed = ["@fs"];
359
- for (; segments.length; ) {
360
- const label = segments.shift();
361
- traversed.push(label);
362
- const value = traversed.join("/");
363
- let node = r(parent.children, (n) => n.value === value);
364
- node || (node = { label, value, type: "folder", children: [] }, parent.children.push(node)), parent = node;
365
- }
366
- return parent;
367
- };
368
- for (const view of views) {
369
- let relativePath;
370
- switch (groupBy) {
371
- case "by-files":
372
- relativePath = view.$view.sourcePath ?? "";
373
- break;
374
- case "by-folders":
375
- relativePath = dropFilename(view.$view.sourcePath ?? "");
376
- break;
377
- case "none":
378
- relativePath = "";
379
- break;
380
- default:
381
- nonexhaustive(groupBy);
382
- }
383
- const parent = findParent(relativePath);
384
- parent.children.push({
385
- value: view.id,
386
- label: view.title ?? view.id,
387
- type: view.isDeploymentView() ? "deployment-view" : "view",
388
- children: []
389
- }), parent !== root2 && (parent.children.sort(compareTreeNodes), groupBy === "by-files" && parent.type !== "file" && (parent.type = "file"));
390
- }
391
- return root2.children.sort(compareTreeNodes);
392
- }
393
- function useDiagramsTreeData(groupBy = "by-files") {
394
- const model = useLikeC4Model();
395
- return useMemo(() => buildDiagramTreeData([...model.views()], groupBy), [model, groupBy]);
396
- }
397
- const drawerOpenedAtom = atom(!1);
398
- onMount(drawerOpenedAtom, () => {
399
- drawerOpenedAtom.set(!1);
400
- });
401
- const useDrawerOpened = () => useStore$1(drawerOpenedAtom), SidebarDrawerOps = {
402
- open: () => drawerOpenedAtom.set(!0),
403
- close: () => drawerOpenedAtom.set(!1)
404
- }, 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 = () => {
405
- }, DiagramsTree = /* @__PURE__ */ memo(({ groupBy }) => {
406
- const views = useLikeC4Views(), data = useDiagramsTreeData(groupBy), navigate = useNavigate(), navigateTo = (viewId2) => {
407
- SidebarDrawerOps.close(), navigate({
408
- to: "/view/$viewId/",
409
- viewTransition: !1,
410
- params: { viewId: viewId2 }
411
- });
412
- }, [diagram] = useCurrentView(), viewId = diagram?.id ?? null, tree = useTree({
413
- multiple: !1
414
- });
415
- tree.setHoveredNode = setHoveredNode;
416
- const sourcePath = diagram?.sourcePath ?? null;
417
- useUpdateEffect(() => {
418
- tree.collapseAllNodes();
419
- }, [groupBy]), useEffect(() => {
420
- if (sourcePath) {
421
- const segments = sourcePath.split("/");
422
- let path = "@fs";
423
- for (const segment of segments)
424
- path += `/${segment}`, tree.expand(path);
425
- }
426
- }, [sourcePath, groupBy]), useEffect(() => {
427
- viewId && tree.select(viewId);
428
- }, [viewId]);
429
- const theme = useComputedColorScheme();
430
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
431
- Tree,
432
- {
433
- allowRangeSelection: !1,
434
- tree,
435
- data,
436
- styles: {
437
- node: {
438
- marginTop: 2,
439
- marginBottom: 2
440
- }
441
- },
442
- levelOffset: "md",
443
- renderNode: ({ node, selected, expanded, elementProps, hasChildren }) => /* @__PURE__ */ jsx(DiagramPreviewHoverCard, { diagram: hasChildren ? void 0 : views.find((v) => v.id === node.value), children: /* @__PURE__ */ jsx(
444
- Button,
445
- {
446
- fullWidth: !0,
447
- color: theme === "light" ? "dark" : "gray",
448
- variant: selected ? "transparent" : "subtle",
449
- size: "sm",
450
- fz: "sm",
451
- fw: hasChildren ? "600" : "500",
452
- justify: "flex-start",
453
- styles: {
454
- section: {
455
- opacity: 0.5
456
- }
457
- },
458
- leftSection: /* @__PURE__ */ jsxs(Fragment, { children: [
459
- !hasChildren && node.value === "index" && /* @__PURE__ */ jsx(IconStarFilled, { size: 14, opacity: 0.7 }),
460
- !hasChildren && node.value !== "index" && isTreeNodeData(node) && /* @__PURE__ */ jsxs(Fragment, { children: [
461
- node.type === "deployment-view" && /* @__PURE__ */ jsx(IconStack2, { size: 14 }),
462
- node.type === "view" && /* @__PURE__ */ jsx(IconLayoutDashboard, { size: 14 })
463
- ] }),
464
- hasChildren && /* @__PURE__ */ jsx(FolderIcon, { node, expanded })
465
- ] }),
466
- ...elementProps,
467
- ...!hasChildren && {
468
- onClick: (e2) => {
469
- e2.stopPropagation(), navigateTo(node.value);
470
- }
471
- },
472
- children: node.label
473
- }
474
- ) })
475
- }
476
- ) });
477
- }, (prev, next) => prev.groupBy === next.groupBy);
478
- function DiagramPreviewHoverCard({ diagram, children }) {
479
- 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;
480
- return /* @__PURE__ */ jsxs(Fragment, { children: [
481
- diagram && /* @__PURE__ */ jsxs(HoverCard, { position: "right-start", openDelay: 400, closeDelay: 100, keepMounted: !1, shadow: "lg", children: [
482
- /* @__PURE__ */ jsx(HoverCardTarget, { children }),
483
- /* @__PURE__ */ jsx(HoverCardDropdown, { style: { width, height }, p: "xs", children: /* @__PURE__ */ jsx(DiagramPreview, { diagram }) })
484
- ] }),
485
- !diagram && children
486
- ] });
487
- }
488
- const DiagramPreview = memo(({ diagram }) => {
489
- 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);
490
- return /* @__PURE__ */ jsx(
491
- StaticLikeC4Diagram,
492
- {
493
- view: diagram,
494
- fitView: !0,
495
- fitViewPadding: "4px",
496
- enableElementDetails: !1,
497
- reduceGraphics: !0,
498
- initialWidth: width,
499
- initialHeight: height
500
- }
501
- );
502
- }, (prev, next) => prev.diagram.id === next.diagram.id), SidebarDrawer = memo(() => {
503
- const opened = useDrawerOpened(), [grouping, setGrouping] = useLocalStorage({
504
- key: "sidebar-drawer-grouping",
505
- defaultValue: "by-files"
506
- }), isSingleProject = useMatches({
507
- select: (matches) => matches.some((match) => match.routeId === "/_single")
508
- });
509
- return /* @__PURE__ */ jsxs(
510
- Drawer.Root,
511
- {
512
- keepMounted: isSingleProject,
513
- opened,
514
- scrollAreaComponent: ScrollArea.Autosize,
515
- onClose: SidebarDrawerOps.close,
516
- children: [
517
- /* @__PURE__ */ jsx(Drawer.Overlay, { blur: 2 }),
518
- /* @__PURE__ */ jsxs(Drawer.Content, { children: [
519
- /* @__PURE__ */ jsxs(Drawer.Header, { children: [
520
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
521
- /* @__PURE__ */ jsx(
522
- Button,
523
- {
524
- component: Link,
525
- to: "/",
526
- leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 14 }),
527
- color: "dimmed",
528
- variant: "subtle",
529
- px: rem(5),
530
- styles: {
531
- section: {
532
- marginInlineEnd: 4
533
- }
534
- },
535
- size: "xs",
536
- children: "Overview"
537
- }
538
- ),
539
- /* @__PURE__ */ jsx(
540
- SegmentedControl,
541
- {
542
- size: "xs",
543
- withItemsBorders: !1,
544
- value: grouping,
545
- onChange: setGrouping,
546
- data: [
547
- { label: "By files", value: "by-files" },
548
- { label: "By folders", value: "by-folders" },
549
- { label: "List", value: "none" }
550
- ]
551
- }
552
- ),
553
- /* @__PURE__ */ jsx(
554
- Button,
555
- {
556
- leftSection: /* @__PURE__ */ jsx(IconStarFilled, { size: 12, stroke: 2 }),
557
- color: "dimmed",
558
- variant: "subtle",
559
- px: rem(5),
560
- styles: {
561
- section: {
562
- marginInlineEnd: 4
563
- }
564
- },
565
- size: "xs",
566
- renderRoot: (props) => /* @__PURE__ */ jsx(
567
- Link,
568
- {
569
- to: "/view/$viewId",
570
- params: { viewId: "index" },
571
- ...props
572
- }
573
- ),
574
- children: "Open index"
575
- }
576
- )
577
- ] }),
578
- /* @__PURE__ */ jsx(Drawer.CloseButton, {})
579
- ] }),
580
- /* @__PURE__ */ jsx(Drawer.Body, { children: /* @__PURE__ */ jsx(DiagramsTree, { groupBy: grouping }) })
581
- ] })
582
- ]
583
- }
584
- );
585
- });
586
- function filterLandingPageViews(views, filter) {
587
- return filter ? "include" in filter ? views.filter((view) => matchesAny(view, filter.include)) : "exclude" in filter ? views.filter((view) => !matchesAny(view, filter.exclude)) : views : views;
588
- }
589
- function matchesAny(view, patterns) {
590
- return patterns.some((pattern) => {
591
- if (pattern.startsWith("#")) {
592
- const tag = pattern.slice(1);
593
- return view.tags?.some((t) => t === tag) ?? !1;
594
- }
595
- return view.id === pattern;
596
- });
597
- }
598
- css({
599
- color: "text.dimmed"
600
- });
601
- css({
602
- // background: 'var(--color-surface)',
603
- });
604
- const previewBg = css({
605
- position: "relative",
606
- overflow: "hidden",
607
- padding: "0",
608
- margin: "0",
609
- backgroundOrigin: "padding-box",
610
- backgroundImage: "radial-gradient({colors.default.border} 15%, {colors.body} 15%)",
611
- backgroundPosition: "0 0",
612
- backgroundSize: "12px 12px",
613
- _after: {
614
- content: '" "',
615
- position: "absolute",
616
- top: "0",
617
- left: "0",
618
- right: "0",
619
- bottom: "0",
620
- zIndex: "1"
621
- }
622
- }), cardLink = css({
623
- position: "absolute",
624
- inset: "0",
625
- zIndex: 5
626
- }), Route$a = createFileRoute("/_single/single-index")({
627
- component: RouteComponent
628
- });
629
- function RouteComponent() {
630
- useDocumentTitle(pageTitle);
631
- const allViews = useLikeC4Views(), { landingPage } = useCurrentProject(), views = filterLandingPageViews(allViews, landingPage);
632
- return /* @__PURE__ */ jsxs(Container, { size: "xl", children: [
633
- /* @__PURE__ */ jsx(SidebarDrawer, {}),
634
- /* @__PURE__ */ jsxs(
635
- "div",
636
- {
637
- className: css({
638
- containerName: "likec4-root",
639
- containerType: "inline-size",
640
- display: "flex",
641
- alignItems: "flex-start",
642
- justifyContent: "space-between",
643
- padding: "xs",
644
- gap: "xs",
645
- position: "sticky",
646
- top: "0",
647
- zIndex: "10",
648
- backgroundColor: "likec4.panel.bg/85",
649
- backdropFilter: "blur(8px)"
650
- }),
651
- children: [
652
- /* @__PURE__ */ jsx(NavigationPanel$1.Root, { css: { position: "relative", width: "max-content", margin: "0" }, children: /* @__PURE__ */ jsxs(NavigationPanel$1.Body, { children: [
653
- /* @__PURE__ */ jsx("div", { style: { width: 0, height: 36 }, "aria-hidden": !0 }),
654
- /* @__PURE__ */ jsx(Burger, { size: "sm", onClick: SidebarDrawerOps.open, "aria-label": "Toggle navigation" }),
655
- /* @__PURE__ */ jsx(
656
- NavigationPanel$1.Logo,
657
- {
658
- css: { flexShrink: 0 },
659
- onClick: () => window.scrollTo({ top: 0, behavior: "smooth" })
660
- }
661
- ),
662
- /* @__PURE__ */ jsx(OverviewSearch, {})
663
- ] }) }),
664
- /* @__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, {}) }) }) })
665
- ]
666
- }
667
- ),
668
- /* @__PURE__ */ jsx(
669
- SimpleGrid,
670
- {
671
- p: { base: "md", sm: "md" },
672
- pt: { base: "sm", sm: "sm" },
673
- cols: { base: 1, sm: 2, md: 3, xl: 4 },
674
- spacing: { base: 10, sm: "xl" },
675
- verticalSpacing: { base: "md", sm: "xl" },
676
- children: views.map((v) => /* @__PURE__ */ jsx(ViewCard, { view: v }, v.id))
677
- }
678
- )
679
- ] });
680
- }
681
- function ViewCard({ view }) {
682
- const [visible, setVisible] = useState(!1), { ref, inViewport } = useInViewport();
683
- return useEffect(() => {
684
- if (!inViewport || visible) return;
685
- const tm = setTimeout(() => setVisible(!0), e$3(30, 80));
686
- return () => clearTimeout(tm);
687
- }, [inViewport, visible]), /* @__PURE__ */ jsxs(
688
- Card,
689
- {
690
- ref,
691
- shadow: "xs",
692
- padding: "lg",
693
- radius: "sm",
694
- className: "group",
695
- withBorder: !0,
696
- children: [
697
- /* @__PURE__ */ jsx(Card.Section, { children: /* @__PURE__ */ jsx(Box$1, { className: previewBg, style: { height: 200 }, children: visible && /* @__PURE__ */ jsx(
698
- StaticLikeC4Diagram,
699
- {
700
- background: "transparent",
701
- view,
702
- fitView: !0,
703
- fitViewPadding: "4px",
704
- reduceGraphics: !0
705
- }
706
- ) }) }),
707
- /* @__PURE__ */ jsx(Group, { justify: "space-between", mt: "md", children: /* @__PURE__ */ jsx(Text, { fw: 500, children: view.title ?? view.id }) }),
708
- /* @__PURE__ */ jsx(
709
- Markdown,
710
- {
711
- value: RichText.from(view.description),
712
- textScale: 0.75,
713
- emptyText: "No description",
714
- className: css({
715
- lineClamp: 3,
716
- mt: "1",
717
- transition: "fast",
718
- opacity: {
719
- base: 0.8,
720
- _groupHover: 1
721
- }
722
- })
723
- }
724
- ),
725
- /* @__PURE__ */ jsx(Link, { to: "/view/$viewId/", params: { viewId: view.id }, search: !0, className: cardLink })
726
- ]
727
- }
728
- );
729
- }
730
- function AdHocViewEditor({ projectId }) {
731
- return /* @__PURE__ */ jsx(
732
- LikeC4AdHocViewEditor,
733
- {
734
- service: {
735
- process: async ({ predicates }) => ({
736
- view: await likec4rpc.calcAdhocView({ projectId, predicates })
737
- })
738
- }
739
- }
740
- );
741
- }
742
- const Route$9 = createFileRoute("/_single/adhoc")({
743
- beforeLoad: () => {
744
- if (!isRpcAvailable)
745
- throw redirect({
746
- to: "/single-index/"
747
- });
748
- },
749
- component: Page$4
750
- });
751
- function Page$4() {
752
- const { projectId } = Route$9.useRouteContext();
753
- return /* @__PURE__ */ jsx(AdHocViewEditor, { projectId });
754
- }
755
- const Route$8 = createFileRoute("/_single/webcomponent/$")({
756
- component: WebcomponentPage
757
- });
758
- function WebcomponentPage() {
759
- const router = useRouter(), viewId = Route$8.useParams()._splat || "index", { colorScheme } = useMantineColorScheme();
760
- let base = router.basepath.endsWith("/") ? router.basepath : `${router.basepath}/`;
761
- const jsurl = new URL(
762
- `${base}likec4-views.js`,
763
- window.location.href
764
- ), iframeHtml = `
765
- <!DOCTYPE html>
766
- <html lang="en-US" style="color-scheme: ${colorScheme};">
767
- <head>
768
- <meta charset="utf-8" />
769
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no" />
770
- <style>
771
- * {
772
- border-width: 0px;
773
- border-style: solid;
774
- box-sizing: border-box;
775
- overflow-wrap: break-word;
776
- }
777
- html, body {
778
- margin: 0;
779
- background-color: transparent !important;
780
- width: 100%;
781
- height: 100%;
782
- font-size: 16px;
783
- }
784
- body {
785
- min-height: 100%;
786
- }
787
- </style>
788
- </head>
789
- <body>
790
- <div style="width: 100%; height: 100%; padding: clamp(0.5rem, 5vh, 4rem) clamp(0.5rem, 5vw, 5rem)">
791
- <${ComponentName.View} view-id="${encodeURIComponent(viewId)}"></${ComponentName.View}>
792
- </div>
793
- <script type="module" src="${jsurl.href}"><\/script>
794
- </body>
795
- </html>
796
- `;
797
- return /* @__PURE__ */ jsx(
798
- Box,
799
- {
800
- css: {
801
- position: "fixed",
802
- inset: "0",
803
- width: "100%",
804
- height: "100%",
805
- overflow: "hidden",
806
- "& iframe": {
807
- width: "100%",
808
- height: "100%",
809
- borderStyle: "none",
810
- backgroundColor: "transparent",
811
- overflow: "hidden"
812
- }
813
- },
814
- children: /* @__PURE__ */ jsx(
815
- "iframe",
816
- {
817
- srcDoc: iframeHtml,
818
- allowtransparency: "true"
819
- }
820
- )
821
- }
822
- );
823
- }
824
- const { withProvider, withContext } = createStyleContext(navigationPanel), shouldForwardProp = (prop, variantKeys) => !variantKeys.includes(prop) && (isValidMotionProp(prop) || !isCssProperty(prop)), Root = withProvider(MotionDiv, "root", {
825
- shouldForwardProp
826
- }), Body = withContext(MotionDiv, "body", {
827
- shouldForwardProp
828
- });
829
- withContext(MotionDiv, "label", {
830
- shouldForwardProp
831
- });
832
- withContext(MotionDiv, "dropdown", {
833
- shouldForwardProp
834
- });
835
- const NavigationPanel = {
836
- Root,
837
- Body
838
- };
839
- function SelectProject() {
840
- const projects = useLikeC4Projects$1(), project = useCurrentProject();
841
- return projects.length < 2 ? null : /* @__PURE__ */ jsxs(Menu, { shadow: "md", width: 200, trigger: "click-hover", openDelay: 200, children: [
842
- /* @__PURE__ */ jsx(MenuTarget, { children: /* @__PURE__ */ jsx(
843
- Button,
844
- {
845
- variant: "subtle",
846
- size: "sm",
847
- color: "gray",
848
- px: "sm",
849
- rightSection: /* @__PURE__ */ jsx(IconChevronDown, { opacity: 0.5, size: 14 }),
850
- visibleFrom: "md",
851
- children: project.title ?? project.id
852
- }
853
- ) }),
854
- /* @__PURE__ */ jsxs(MenuDropdown, { children: [
855
- /* @__PURE__ */ jsx(
856
- MenuItem,
857
- {
858
- renderRoot: (props) => /* @__PURE__ */ jsx(
859
- Link,
860
- {
861
- ...props,
862
- to: "/projects"
863
- }
864
- ),
865
- children: "Projects overview"
866
- }
867
- ),
868
- /* @__PURE__ */ jsx(MenuDivider, {}),
869
- projects.map(({ id, title: title2 }) => /* @__PURE__ */ jsx(
870
- MenuItem,
871
- {
872
- renderRoot: (props) => /* @__PURE__ */ jsx(
873
- Link,
874
- {
875
- ...props,
876
- to: "/project/$projectId/view/$viewId/",
877
- params: {
878
- projectId: id,
879
- viewId: "index"
880
- }
881
- }
882
- ),
883
- children: title2 ?? id
884
- },
885
- id
886
- ))
887
- ] })
888
- ] });
889
- }
890
- const AlertLocalhost = () => /* @__PURE__ */ jsx(
891
- Alert,
892
- {
893
- color: "yellow",
894
- icon: /* @__PURE__ */ jsx(IconAlertTriangle, {}),
895
- title: "Localhost URL",
896
- styles: { body: { gap: rem(4) } },
897
- children: /* @__PURE__ */ jsx(Text, { c: "yellow", size: "sm", children: "You need to deploy your project to make it available on the internet" })
898
- }
899
- ), CopyButtonChild = ({ copied, copy }) => /* @__PURE__ */ jsx(
900
- Button,
901
- {
902
- size: "xs",
903
- color: copied ? "teal" : "gray",
904
- variant: "light",
905
- leftSection: copied ? /* @__PURE__ */ jsx(IconCheck, { style: { width: rem(16) } }) : /* @__PURE__ */ jsx(IconCopy, { style: { width: rem(16) } }),
906
- onClick: copy,
907
- children: copied ? "Copied" : "Copy to clipboard"
908
- }
909
- ), EmbedPanel = ({ diagram }) => {
910
- const router = useRouter(), { colorScheme } = useMantineColorScheme(), [theme, setTheme] = useState(colorScheme), padding = 20;
911
- let location = router.buildLocation({
912
- to: "/embed/$viewId/",
913
- // '/' at the end added by Gemini 3, must have to pass typecheck
914
- params: { viewId: diagram.id },
915
- search: {
916
- padding,
917
- ...theme !== "auto" ? { theme } : {}
918
- // changed from "theme: theme !== 'auto' ? theme : undefined" by Gemini 3
919
- }
920
- }).href;
921
- location = useHashHistory ? `#${location}` : location;
922
- const url = new URL(location, window.location.href), width = diagram.bounds.width + padding * 2, height = diagram.bounds.height + padding * 2, href = url.href, code = `
923
- <div style="aspect-ratio:${width}/${height};width:100%;height:auto;max-width:${width}px;margin:0 auto">
924
- <iframe src="${href}" width="100%" height="100%" style="border:0;background:transparent;"></iframe>
925
- </div>
926
- `.trim();
927
- return /* @__PURE__ */ jsxs(Stack, { children: [
928
- code.includes("http://localhost") && /* @__PURE__ */ jsx(AlertLocalhost, {}),
929
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: "Embedded view is an iframe with a static diagram" }) }),
930
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
931
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
932
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "HTML" }) }),
933
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
934
- /* @__PURE__ */ jsx(ActionIcon, { component: "a", href, target: "_blank", variant: "light", color: "gray", children: /* @__PURE__ */ jsx(IconExternalLink, {}) }),
935
- /* @__PURE__ */ jsx(CopyButton$1, { value: code, timeout: 1500, children: CopyButtonChild })
936
- ] })
937
- ] }),
938
- /* @__PURE__ */ jsx(Code, { block: !0, children: code }),
939
- /* @__PURE__ */ jsx(
940
- Box$1,
941
- {
942
- style: {
943
- alignSelf: "flex-start"
944
- },
945
- children: /* @__PURE__ */ jsx(
946
- Select,
947
- {
948
- label: "Color scheme",
949
- value: theme,
950
- allowDeselect: !1,
951
- onChange: (v) => setTheme(v ?? "auto"),
952
- data: [
953
- { value: "auto", label: "Auto" },
954
- { value: "light", label: "Light" },
955
- { value: "dark", label: "Dark" }
956
- ]
957
- }
958
- )
959
- }
960
- )
961
- ] })
962
- ] });
963
- };
964
- function WebcomponentsPanel({ diagram }) {
965
- const router = useRouter();
966
- let base = router.basepath.endsWith("/") ? router.basepath : `${router.basepath}/`;
967
- const jscode = `
968
- <script module src="${new URL(
969
- `${base}likec4-views.js`,
970
- window.location.href
971
- ).href}"><\/script>
972
- `.trim(), htmlCode = `
973
- <${ComponentName.View}
974
- view-id="${encodeURIComponent(diagram.id)}"
975
- browser="true"
976
- dynamic-variant="sequence">
977
- </${ComponentName.View}>
978
- `.trim(), webcomponentPreview = router.buildLocation(
979
- {
980
- to: "/webcomponent/$/",
981
- // '/' at the end added by Gemini 3, must have to pass typecheck
982
- params: { _splat: diagram.id },
983
- search: !0
984
- }
985
- );
986
- return /* @__PURE__ */ jsxs(Stack, { children: [
987
- jscode.includes("http://localhost") && /* @__PURE__ */ jsx(AlertLocalhost, {}),
988
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: "Add this script to your page:" }) }),
989
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
990
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
991
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "JavaScript" }) }),
992
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
993
- /* @__PURE__ */ jsx(ActionIcon, { component: "a", href: webcomponentPreview.href, target: "_blank", variant: "light", color: "gray", children: /* @__PURE__ */ jsx(IconExternalLink, {}) }),
994
- /* @__PURE__ */ jsx(
995
- CopyButton$1,
996
- {
997
- value: jscode,
998
- timeout: 1500,
999
- children: CopyButtonChild
1000
- }
1001
- )
1002
- ] })
1003
- ] }),
1004
- /* @__PURE__ */ jsx(Code, { block: !0, children: jscode }),
1005
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
1006
- "This script defines a custom element (webcomponent) that renders your diagrams.",
1007
- /* @__PURE__ */ jsx("br", {}),
1008
- "Script must be inserted once in the ",
1009
- /* @__PURE__ */ jsx("code", { children: "<head>" }),
1010
- " or at the end of the ",
1011
- /* @__PURE__ */ jsx("code", { children: "<body>" }),
1012
- " ",
1013
- "tag."
1014
- ] }) })
1015
- ] }),
1016
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
1017
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
1018
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(Text, { fw: "500", size: "sm", children: "HTML" }) }),
1019
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(
1020
- CopyButton$1,
1021
- {
1022
- value: htmlCode,
1023
- timeout: 1500,
1024
- children: CopyButtonChild
1025
- }
1026
- ) })
1027
- ] }),
1028
- /* @__PURE__ */ jsx(Code, { block: !0, children: htmlCode }),
1029
- /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
1030
- "Insert this code to your page. Page may have multiple ",
1031
- /* @__PURE__ */ jsx("code", { children: "<likec4-view>" }),
1032
- "."
1033
- ] }) })
1034
- ] })
1035
- ] });
1036
- }
1037
- function ShareModal({
1038
- onClose
1039
- }) {
1040
- const [diagram] = useCurrentView(), [activeTab, setActiveTab] = useState("webcomponent");
1041
- return diagram ? /* @__PURE__ */ jsxs(
1042
- ModalRoot,
1043
- {
1044
- size: "xl",
1045
- opened: !0,
1046
- onClose,
1047
- children: [
1048
- /* @__PURE__ */ jsx(ModalOverlay, { backgroundOpacity: 0.5, blur: 3 }),
1049
- /* @__PURE__ */ jsx(ModalContent, { children: /* @__PURE__ */ jsxs(ModalBody, { children: [
1050
- /* @__PURE__ */ jsxs(Tabs, { value: activeTab, onChange: (tab) => setActiveTab(tab ?? "webcomponent"), children: [
1051
- /* @__PURE__ */ jsxs(TabsList, { children: [
1052
- /* @__PURE__ */ jsx(TabsTab, { value: "webcomponent", children: "Webcomponent" }),
1053
- /* @__PURE__ */ jsx(TabsTab, { value: "embed", children: "Embedded" })
1054
- ] }),
1055
- /* @__PURE__ */ jsx(TabsPanel, { value: "embed", pt: "md", children: /* @__PURE__ */ jsx(EmbedPanel, { diagram }) }),
1056
- /* @__PURE__ */ jsx(TabsPanel, { value: "webcomponent", pt: "md", children: /* @__PURE__ */ jsx(WebcomponentsPanel, { diagram }) })
1057
- ] }),
1058
- /* @__PURE__ */ jsx(Group, { justify: "flex-end", mt: "lg", children: /* @__PURE__ */ jsx(Button, { size: "sm", onClick: onClose, children: "Close" }) })
1059
- ] }) })
1060
- ]
1061
- }
1062
- ) : null;
1063
- }
1064
- const Header = memo(() => {
1065
- const projects = useLikeC4Projects$1(), isReactDiagramRoute = useMatches({
1066
- select(matches) {
1067
- return matches.some(
1068
- ({ routeId }) => routeId === "/_single/view/$viewId/" || routeId === "/project/$projectId/view/$viewId/"
1069
- );
1070
- }
1071
- }), { breakpoints } = useMantineTheme(), isTablet = useMediaQuery(`(min-width: ${breakpoints.md})`) ?? !1, [opened, { open, close }] = useDisclosure(!1);
1072
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1073
- /* @__PURE__ */ jsx(NavigationPanel.Root, { panelPosition: "right", hideBelow: "md", children: /* @__PURE__ */ jsxs(NavigationPanel.Body, { gap: "2", children: [
1074
- isReactDiagramRoute ? /* @__PURE__ */ jsxs(Fragment, { children: [
1075
- /* @__PURE__ */ jsx(SelectProject, {}),
1076
- projects.length <= 1 && /* @__PURE__ */ jsx(
1077
- Button,
1078
- {
1079
- size: isTablet ? "sm" : "xs",
1080
- leftSection: /* @__PURE__ */ jsx(IconShare, { size: 14 }),
1081
- onClick: open,
1082
- children: "Share"
1083
- }
1084
- ),
1085
- /* @__PURE__ */ jsx(ExportButton, {})
1086
- ] }) : /* @__PURE__ */ jsx(
1087
- Button,
1088
- {
1089
- component: Link,
1090
- to: "/view/$viewId/",
1091
- size: isTablet ? "sm" : "xs",
1092
- variant: "subtle",
1093
- color: "gray",
1094
- children: "Back to diagram"
1095
- }
1096
- ),
1097
- /* @__PURE__ */ jsx(Divider, { orientation: "vertical", visibleFrom: "md" }),
1098
- /* @__PURE__ */ jsx(ColorSchemeToggle, {})
1099
- ] }) }),
1100
- opened && /* @__PURE__ */ jsx(ShareModal, { onClose: close })
1101
- ] });
1102
- }), enableDownload = (params) => ({
1103
- ...params,
1104
- download: !0
1105
- });
1106
- function ExportButton() {
1107
- const isInsideProject = useMatches({
1108
- select: (matches) => matches.some(({ routeId }) => routeId === "/project/$projectId")
1109
- }), project = useCurrentProject(), viewId = useCurrentViewId(), handleDrawioExport = useCallback(async () => {
1110
- try {
1111
- const { loadDrawioSources } = await import("likec4:drawio"), { drawioEditUrl } = await loadDrawioSources(project.id), url = drawioEditUrl(viewId);
1112
- window.open(url, "_blank", "noopener,noreferrer");
1113
- } catch (error) {
1114
- console.error("Failed to export to Draw.io:", error);
1115
- }
1116
- }, [project.id, viewId]);
1117
- return /* @__PURE__ */ jsxs(Menu, { shadow: "md", width: 200, trigger: "click-hover", openDelay: 200, children: [
1118
- /* @__PURE__ */ jsx(MenuTarget, { children: /* @__PURE__ */ jsx(
1119
- Button,
1120
- {
1121
- variant: "subtle",
1122
- size: "sm",
1123
- color: "gray",
1124
- px: "sm",
1125
- rightSection: /* @__PURE__ */ jsx(IconChevronDown, { opacity: 0.5, size: 14 }),
1126
- visibleFrom: "md",
1127
- children: "Export"
1128
- }
1129
- ) }),
1130
- /* @__PURE__ */ jsxs(MenuDropdown, { children: [
1131
- /* @__PURE__ */ jsx(MenuLabel, { children: "Current view" }),
1132
- /* @__PURE__ */ jsx(
1133
- MenuItem,
1134
- {
1135
- renderRoot: (props) => /* @__PURE__ */ jsx(
1136
- Link,
1137
- {
1138
- target: "_blank",
1139
- to: isInsideProject ? "/project/$projectId/export/$viewId/" : "/export/$viewId/",
1140
- search: enableDownload,
1141
- ...props
1142
- }
1143
- ),
1144
- children: "Export as .png"
1145
- }
1146
- ),
1147
- /* @__PURE__ */ jsx(
1148
- MenuItem,
1149
- {
1150
- renderRoot: (props) => /* @__PURE__ */ jsx(
1151
- Link,
1152
- {
1153
- to: isInsideProject ? "/project/$projectId/view/$viewId/dot/" : "/view/$viewId/dot/",
1154
- search: !0,
1155
- ...props
1156
- }
1157
- ),
1158
- children: "Export as .dot"
1159
- }
1160
- ),
1161
- /* @__PURE__ */ jsx(
1162
- MenuItem,
1163
- {
1164
- renderRoot: (props) => /* @__PURE__ */ jsx(
1165
- Link,
1166
- {
1167
- to: isInsideProject ? "/project/$projectId/view/$viewId/d2" : "/view/$viewId/d2",
1168
- search: !0,
1169
- ...props
1170
- }
1171
- ),
1172
- children: "Export as .d2"
1173
- }
1174
- ),
1175
- /* @__PURE__ */ jsx(
1176
- MenuItem,
1177
- {
1178
- renderRoot: (props) => /* @__PURE__ */ jsx(
1179
- Link,
1180
- {
1181
- to: isInsideProject ? "/project/$projectId/view/$viewId/mmd" : "/view/$viewId/mmd",
1182
- search: !0,
1183
- ...props
1184
- }
1185
- ),
1186
- children: "Export as .mmd"
1187
- }
1188
- ),
1189
- /* @__PURE__ */ jsx(
1190
- MenuItem,
1191
- {
1192
- renderRoot: (props) => /* @__PURE__ */ jsx(
1193
- Link,
1194
- {
1195
- to: isInsideProject ? "/project/$projectId/view/$viewId/puml" : "/view/$viewId/puml",
1196
- search: !0,
1197
- ...props
1198
- }
1199
- ),
1200
- children: "Export as .puml"
1201
- }
1202
- ),
1203
- /* @__PURE__ */ jsx(MenuItem, { onClick: handleDrawioExport, children: "Export to Draw.io" }),
1204
- /* @__PURE__ */ jsx(MenuItem, { disabled: !0, children: "Export to Miro" }),
1205
- /* @__PURE__ */ jsx(MenuItem, { disabled: !0, children: "Export to Notion" })
1206
- ] })
1207
- ] });
1208
- }
1209
- const Route$7 = createFileRoute("/_single/view/$viewId")({
1210
- component: ViewLayout,
1211
- errorComponent: ({ error, reset }) => /* @__PURE__ */ jsx(Fallback, { error, resetErrorBoundary: reset })
1212
- });
1213
- function ViewLayout() {
1214
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1215
- /* @__PURE__ */ jsx(Outlet, {}),
1216
- /* @__PURE__ */ jsx(Header, {})
1217
- ] });
1218
- }
1219
- async function downloadAsPng({
1220
- pngFilename,
1221
- viewport
1222
- }) {
1223
- try {
1224
- const blob = await toBlob(viewport, {
1225
- backgroundColor: "transparent",
1226
- cacheBust: !0,
1227
- imagePlaceholder: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
1228
- });
1229
- if (!blob)
1230
- throw new Error("Failed to create PNG blob");
1231
- var url = URL.createObjectURL(blob), link = document.createElement("a");
1232
- link.setAttribute("download", `${pngFilename}.png`), link.href = url, document.body.appendChild(link), link.click(), await new Promise((resolve) => setTimeout(resolve, 1e3)), document.body.removeChild(link), URL.revokeObjectURL(url), window.close();
1233
- } catch (err) {
1234
- console.error(err), window.alert("Failed to export to PNG, check the console for more details.");
1235
- }
1236
- }
1237
- function ExportPage() {
1238
- const [diagram] = useCurrentView();
1239
- return useTransparentBackground(), diagram ? /* @__PURE__ */ jsx(GuardedExportPage, { diagram }) : /* @__PURE__ */ jsx("div", { children: "Loading..." });
1240
- }
1241
- function GuardedExportPage({ diagram }) {
1242
- const {
1243
- padding = 20,
1244
- download = !1,
1245
- dynamic
1246
- } = useSearch({
1247
- strict: !1
1248
- }), viewportRef = useRef(null), loadingOverlayRef = useRef(null), downloadedRef = useRef(!1), bounds = pickViewBounds(diagram, dynamic), downloadDiagram = () => {
1249
- const viewport = viewportRef.current;
1250
- if (!download || !viewport || !diagram || downloadedRef.current)
1251
- return;
1252
- const loadingOverlay = loadingOverlayRef.current;
1253
- loadingOverlay && (loadingOverlay.style.display = "none"), downloadedRef.current = !0, downloadAsPng({
1254
- pngFilename: diagram.id,
1255
- viewport
1256
- });
1257
- }, extraPadding = 16, width = bounds.width + padding * 2 + extraPadding, height = bounds.height + padding * 2 + extraPadding;
1258
- return /* @__PURE__ */ jsxs(
1259
- Box,
1260
- {
1261
- ref: viewportRef,
1262
- "data-testid": "export-page",
1263
- css: {
1264
- position: "fixed",
1265
- top: "0",
1266
- left: "0",
1267
- padding: "0",
1268
- margin: "0",
1269
- background: "transparent",
1270
- overflow: "hidden",
1271
- zIndex: 2
1272
- },
1273
- style: {
1274
- marginRight: "auto",
1275
- marginBottom: "auto",
1276
- minWidth: width,
1277
- width,
1278
- minHeight: height,
1279
- height
1280
- },
1281
- children: [
1282
- download && /* @__PURE__ */ jsx(LoadingOverlay, { ref: loadingOverlayRef, visible: !0 }),
1283
- /* @__PURE__ */ jsx(
1284
- LikeC4Diagram,
1285
- {
1286
- view: diagram,
1287
- fitView: !1,
1288
- fitViewPadding: {
1289
- top: "0px",
1290
- bottom: "0px",
1291
- left: "0px",
1292
- right: "0px"
1293
- },
1294
- background: "transparent",
1295
- reduceGraphics: !1,
1296
- dynamicViewVariant: dynamic,
1297
- className: "likec4-static-view",
1298
- pannable: !1,
1299
- zoomable: !1,
1300
- controls: !1,
1301
- enableNotations: !1,
1302
- enableElementDetails: !1,
1303
- enableRelationshipDetails: !1,
1304
- enableRelationshipBrowser: !1,
1305
- enableDynamicViewWalkthrough: !1,
1306
- enableFocusMode: !1,
1307
- enableSearch: !1,
1308
- nodesSelectable: !1,
1309
- enableElementTags: !1,
1310
- onInitialized: () => {
1311
- if (!viewportRef.current) {
1312
- console.error("viewportRef.current is null");
1313
- return;
1314
- }
1315
- const x = Math.round(-bounds.x + padding), y = Math.round(-bounds.y + padding);
1316
- [...viewportRef.current.querySelectorAll(".react-flow__viewport")].forEach((el) => {
1317
- el.style.transform = "translate(" + x + "px, " + y + "px)";
1318
- }), download && window.setTimeout(downloadDiagram, 500);
1319
- }
1320
- }
1321
- )
1322
- ]
1323
- }
1324
- );
1325
- }
1326
- const Route$6 = createFileRoute("/_single/export/$viewId")({
1327
- validateSearch: z.object({
1328
- download: z.boolean().optional().catch(!1)
1329
- }),
1330
- search: {
1331
- middlewares: [
1332
- stripSearchParams({
1333
- download: !1
1334
- })
1335
- ]
1336
- },
1337
- component: ExportPage
1338
- });
1339
- function EmbedPage() {
1340
- const {
1341
- padding = 20,
1342
- dynamic
1343
- } = useSearch({
1344
- strict: !1
1345
- }), [diagram] = useCurrentView();
1346
- if (useTransparentBackground(!!diagram), !diagram)
1347
- return /* @__PURE__ */ jsx("div", { children: "Loading..." });
1348
- const bounds = pickViewBounds(diagram, dynamic);
1349
- return /* @__PURE__ */ jsx(
1350
- "div",
1351
- {
1352
- style: {
1353
- position: "absolute",
1354
- top: 0,
1355
- left: "50%",
1356
- boxSizing: "border-box",
1357
- padding,
1358
- transform: "translateX(-50%)",
1359
- aspectRatio: `${bounds.width + padding * 2} / ${bounds.height + padding * 2}`,
1360
- width: "100vw",
1361
- maxWidth: bounds.width + padding * 2,
1362
- height: "auto",
1363
- maxHeight: "100vh"
1364
- },
1365
- children: /* @__PURE__ */ jsx(
1366
- StaticLikeC4Diagram,
1367
- {
1368
- view: diagram,
1369
- fitView: !0,
1370
- background: "transparent",
1371
- fitViewPadding: 0,
1372
- dynamicViewVariant: dynamic,
1373
- initialWidth: bounds.width,
1374
- initialHeight: bounds.height
1375
- }
1376
- )
1377
- }
1378
- );
1379
- }
1380
- const Route$5 = createFileRoute("/_single/embed/$viewId")({
1381
- component: EmbedPage
1382
- });
1383
- function ViewReact() {
1384
- const navigate = useNavigate(), [view, setLayoutType] = useCurrentView(), model = useLikeC4Model(), { dynamic } = useSearch({
1385
- from: "__root__"
1386
- }), onNavigateTo = useCallbackRef((viewId) => {
1387
- navigate({
1388
- to: "./",
1389
- viewTransition: !1,
1390
- params: (current) => ({
1391
- ...current,
1392
- viewId
1393
- }),
1394
- search: !0
1395
- });
1396
- }), title2 = view ? view.title ?? view.id : "View not found", pageTitle$1 = model.project.title ?? pageTitle;
1397
- if (useDocumentTitle(`${title2} - ${pageTitle$1}`), !view)
1398
- return /* @__PURE__ */ jsx(NotFound, {});
1399
- const hasNotations = (view.notation?.nodes ?? []).length > 0;
1400
- return /* @__PURE__ */ jsxs(
1401
- LikeC4Diagram,
1402
- {
1403
- view,
1404
- zoomable: !0,
1405
- pannable: !0,
1406
- controls: !0,
1407
- fitViewPadding: {
1408
- top: "70px",
1409
- bottom: "32px",
1410
- left: "32px",
1411
- right: "32px"
1412
- },
1413
- showNavigationButtons: !0,
1414
- enableSearch: !0,
1415
- enableFocusMode: !0,
1416
- enableDynamicViewWalkthrough: !0,
1417
- dynamicViewVariant: dynamic,
1418
- enableElementDetails: !0,
1419
- enableRelationshipDetails: !0,
1420
- enableRelationshipBrowser: !0,
1421
- enableElementTags: !0,
1422
- enableCompareWithLatest: !0,
1423
- enableNotations: hasNotations,
1424
- nodesSelectable: !0,
1425
- onNavigateTo,
1426
- onLayoutTypeChange: setLayoutType,
1427
- onLogoClick: () => {
1428
- navigate({
1429
- to: "/"
1430
- });
1431
- },
1432
- children: [
1433
- /* @__PURE__ */ jsx(ListenForDynamicVariantChange, {}),
1434
- /* @__PURE__ */ jsx(OpenRelationshipBrowserFromUrl, {}),
1435
- /* @__PURE__ */ jsx(FocusElementFromUrl, {})
1436
- ]
1437
- }
1438
- );
1439
- }
1440
- function OpenRelationshipBrowserFromUrl() {
1441
- const router = useRouter(), diagram = useDiagram(), { relationships } = useSearch({
1442
- from: "__root__"
1443
- }), processedRef = useRef(null), isInitializedRef = useRef(!1), isProcessingRef = useRef(Promise.resolve()), isMounted = useIsMounted(), openAndClear = (fqn) => {
1444
- isProcessingRef.current = isProcessingRef.current.then(async () => {
1445
- if (!(!isMounted() || processedRef.current === fqn))
1446
- try {
1447
- processedRef.current = fqn, diagram.openRelationshipsBrowser(fqn), await router.buildAndCommitLocation({
1448
- search: (s) => {
1449
- const { relationships: _, ...rest } = s;
1450
- return rest;
1451
- },
1452
- replace: !0,
1453
- viewTransition: !1
1454
- });
1455
- } catch (error) {
1456
- console.error("Failed to open relationship browser:", error);
1457
- }
1458
- });
1459
- }, process = () => {
1460
- if (!relationships) {
1461
- processedRef.current = null;
1462
- return;
1463
- }
1464
- relationships && processedRef.current !== relationships && openAndClear(relationships);
1465
- };
1466
- return useOnDiagramEvent("initialized", () => {
1467
- isInitializedRef.current = !0, process();
1468
- }), useUpdateEffect(() => {
1469
- process();
1470
- }, [relationships]), null;
1471
- }
1472
- function FocusElementFromUrl() {
1473
- const router = useRouter(), diagram = useDiagram(), { focusOnElement } = useSearch({
1474
- from: "__root__"
1475
- }), processedRef = useRef(null), focusAndClear = useCallbackRef((fqn) => {
1476
- try {
1477
- if (processedRef.current === fqn) return;
1478
- processedRef.current = fqn, diagram.focusOnElement(fqn), router.buildAndCommitLocation({
1479
- search: (s) => {
1480
- const { focusOnElement: _, ...rest } = s;
1481
- return rest;
1482
- },
1483
- replace: !0,
1484
- viewTransition: !1
1485
- });
1486
- } catch (error) {
1487
- console.error("focusOnElement failed:", error);
1488
- }
1489
- });
1490
- return useOnDiagramEvent("initialized", () => {
1491
- focusOnElement && processedRef.current !== focusOnElement && focusAndClear(focusOnElement);
1492
- }), useUpdateEffect(() => {
1493
- focusOnElement || (processedRef.current = null);
1494
- }, [focusOnElement]), null;
1495
- }
1496
- function ListenForDynamicVariantChange() {
1497
- const router = useRouter(), dynamicViewVariant = useDiagramContext((c) => c.dynamicViewVariant);
1498
- return useUpdateEffect(() => {
1499
- (router.latestLocation.search.dynamic ?? "diagram") !== dynamicViewVariant && router.buildAndCommitLocation({
1500
- search: (current) => ({
1501
- ...current,
1502
- dynamic: dynamicViewVariant
1503
- }),
1504
- viewTransition: !1
1505
- });
1506
- }, [dynamicViewVariant]), null;
1507
- }
1508
- function ViewEditor() {
1509
- const navigate = useNavigate(), project = useCurrentProject(), [view, setLayoutType] = useCurrentView(), $likec4model = useLikeC4ModelAtom(), { dynamic } = useSearch({ strict: !1 }), onNavigateTo = useCallbackRef((viewId) => {
1510
- navigate({
1511
- to: "./",
1512
- viewTransition: !1,
1513
- params: (current) => ({
1514
- ...current,
1515
- viewId
1516
- }),
1517
- search: !0
1518
- });
1519
- });
1520
- if (!view)
1521
- return /* @__PURE__ */ jsx(NotFound, {});
1522
- const hasNotations = (view.notation?.nodes ?? []).length > 0;
1523
- return /* @__PURE__ */ jsx(
1524
- LikeC4EditorProvider,
1525
- {
1526
- editor: {
1527
- fetchView: (id, layout) => {
1528
- const model = $likec4model.get().view(id);
1529
- return layout === "auto" ? model.$view : model.$layouted;
1530
- },
1531
- handleChange: (viewId, change) => {
1532
- const event = {
1533
- projectId: project.id,
1534
- viewId,
1535
- change
1536
- };
1537
- return likec4rpc.updateView(event);
1538
- }
1539
- },
1540
- children: /* @__PURE__ */ jsxs(
1541
- LikeC4Diagram,
1542
- {
1543
- view,
1544
- zoomable: !0,
1545
- pannable: !0,
1546
- controls: !0,
1547
- fitViewPadding: {
1548
- top: "70px",
1549
- bottom: "32px",
1550
- left: "50px",
1551
- right: "32px"
1552
- },
1553
- showNavigationButtons: !0,
1554
- enableNotations: isDevelopment || hasNotations,
1555
- enableSearch: !0,
1556
- enableDynamicViewWalkthrough: !0,
1557
- enableFocusMode: !0,
1558
- enableElementDetails: !0,
1559
- enableRelationshipDetails: !0,
1560
- enableRelationshipBrowser: !0,
1561
- enableElementTags: !0,
1562
- enableCompareWithLatest: !0,
1563
- dynamicViewVariant: dynamic,
1564
- onNavigateTo,
1565
- onLayoutTypeChange: setLayoutType,
1566
- onLogoClick: () => {
1567
- navigate({
1568
- to: "/"
1569
- });
1570
- },
1571
- children: [
1572
- /* @__PURE__ */ jsx(ListenForDynamicVariantChange, {}),
1573
- /* @__PURE__ */ jsx(OpenRelationshipBrowserFromUrl, {}),
1574
- /* @__PURE__ */ jsx(FocusElementFromUrl, {})
1575
- ]
1576
- }
1577
- )
1578
- }
1579
- );
1580
- }
1581
- const Route$4 = createFileRoute("/_single/view/$viewId/")({
1582
- component: isRpcAvailable ? ViewEditor : ViewReact
1583
- });
1584
- function CopyButton({ text }) {
1585
- 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) } }) }) }) });
1586
- }
1587
- function CopyToClipboard({ text }) {
1588
- return /* @__PURE__ */ jsx(Box$1, { pos: "absolute", top: "0", right: "0", p: "4", children: /* @__PURE__ */ jsx(CopyButton, { text }) });
1589
- }
1590
- const svgContainer = css({
1591
- minWidth: 300,
1592
- "& svg": {
1593
- width: "100%",
1594
- height: "auto"
1595
- }
1596
- }), cssScrollArea = css({
1597
- height: "100%",
1598
- "& .mantine-ScrollArea-viewport": {
1599
- minHeight: "100%"
1600
- },
1601
- "& .mantine-ScrollArea-viewport > div": {
1602
- minHeight: "100%",
1603
- height: "100%"
1604
- }
1605
- }), cssCodeBlock = css({
1606
- minHeight: "100%"
1607
- }), viewWithTopPadding = css({
1608
- height: "100%",
1609
- paddingTop: "[var(--header-height)]"
1610
- }), fetchFromKroki$1 = async (puml) => await (await fetch(krokiPumlSvgUrl, {
1611
- method: "POST",
1612
- cache: "force-cache",
1613
- body: JSON.stringify({
1614
- diagram_source: puml,
1615
- output_format: "svg"
1616
- }),
1617
- headers: {
1618
- "Content-Type": "application/json"
1619
- }
1620
- })).text();
1621
- function ViewAsPuml({ pumlSource }) {
1622
- const [krokiSvg, { execute }] = useAsync(fetchFromKroki$1, null);
1623
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1624
- Ut,
1625
- {
1626
- className: viewWithTopPadding,
1627
- orientation: "horizontal",
1628
- children: [
1629
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(
1630
- ScrollArea,
1631
- {
1632
- className: cssScrollArea,
1633
- p: 5,
1634
- styles: {
1635
- viewport: {
1636
- borderRadius: 6
1637
- }
1638
- },
1639
- children: [
1640
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: pumlSource }),
1641
- /* @__PURE__ */ jsx(CopyToClipboard, { text: pumlSource })
1642
- ]
1643
- }
1644
- ) }),
1645
- /* @__PURE__ */ jsx(
1646
- Zt,
1647
- {
1648
- style: {
1649
- width: 10
1650
- }
1651
- }
1652
- ),
1653
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(ScrollArea, { h: "100%", children: [
1654
- krokiSvg.status !== "success" && /* @__PURE__ */ jsxs(Fragment, { children: [
1655
- /* @__PURE__ */ jsx(
1656
- Button,
1657
- {
1658
- mt: "xs",
1659
- variant: "light",
1660
- disabled: krokiSvg.status === "loading",
1661
- onClick: () => {
1662
- execute(pumlSource);
1663
- },
1664
- children: krokiSvg.status === "loading" ? "Loading..." : "Render with Kroki"
1665
- }
1666
- ),
1667
- krokiSvg.status === "error" && /* @__PURE__ */ jsx(Box, { children: krokiSvg.error?.message })
1668
- ] }),
1669
- krokiSvg.status === "success" && /* @__PURE__ */ jsx(Box, { className: svgContainer, children: krokiSvg.result ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: krokiSvg.result } }) : /* @__PURE__ */ jsx(Box, { children: "Empty result" }) })
1670
- ] }) })
1671
- ]
1672
- }
1673
- ) });
1674
- }
1675
- const Route$3 = createFileRoute("/_single/view/$viewId/puml")({
1676
- component: Page$3,
1677
- staleTime: 1 / 0,
1678
- loader: async ({ params, context }) => {
1679
- const projectId = context.projectId, { viewId } = params, { loadPumlSources } = await import("likec4:puml");
1680
- try {
1681
- const { pumlSource } = await loadPumlSources(projectId);
1682
- return {
1683
- source: pumlSource(viewId)
1684
- };
1685
- } catch (error) {
1686
- throw console.error(error), notFound();
1687
- }
1688
- }
1689
- });
1690
- function Page$3() {
1691
- const { source } = Route$3.useLoaderData();
1692
- return /* @__PURE__ */ jsx(ViewAsPuml, { pumlSource: source });
1693
- }
1694
- const renderSvg = async (viewId, diagram) => {
1695
- const { default: mermaid } = await import("https://cdn.jsdelivr.net/npm/mermaid@11.12/dist/mermaid.esm.min.mjs");
1696
- mermaid.initialize({
1697
- theme: "dark"
1698
- });
1699
- const { svg } = await mermaid.render(viewId, diagram);
1700
- return svg;
1701
- };
1702
- function ViewAsMmd({ viewId, mmdSource }) {
1703
- const [mmdSvg, { execute }] = useAsync(renderSvg, null);
1704
- return useEffect(() => {
1705
- execute(viewId, mmdSource);
1706
- }, [mmdSource]), /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1707
- Ut,
1708
- {
1709
- className: viewWithTopPadding,
1710
- orientation: "horizontal",
1711
- children: [
1712
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(
1713
- ScrollArea,
1714
- {
1715
- className: cssScrollArea,
1716
- p: 5,
1717
- styles: {
1718
- viewport: {
1719
- borderRadius: 6
1720
- }
1721
- },
1722
- children: [
1723
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: mmdSource }),
1724
- /* @__PURE__ */ jsx(CopyToClipboard, { text: mmdSource })
1725
- ]
1726
- }
1727
- ) }),
1728
- /* @__PURE__ */ jsx(
1729
- Zt,
1730
- {
1731
- style: {
1732
- width: 10
1733
- }
1734
- }
1735
- ),
1736
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsx(ScrollArea, { h: "100%", children: mmdSvg.result && /* @__PURE__ */ jsx(Box, { className: svgContainer, dangerouslySetInnerHTML: { __html: mmdSvg.result } }) }) })
1737
- ]
1738
- }
1739
- ) });
1740
- }
1741
- const Route$2 = createFileRoute("/_single/view/$viewId/mmd")({
1742
- component: Page$2,
1743
- staleTime: 1 / 0,
1744
- loader: async ({ params, context }) => {
1745
- const projectId = context.projectId, { viewId } = params, { loadMmdSources } = await import("likec4:mmd");
1746
- try {
1747
- const { mmdSource } = await loadMmdSources(projectId);
1748
- return {
1749
- source: mmdSource(viewId)
1750
- };
1751
- } catch (error) {
1752
- throw console.error(error), notFound();
1753
- }
1754
- }
1755
- });
1756
- function Page$2() {
1757
- const { viewId } = Route$2.useParams(), { source } = Route$2.useLoaderData();
1758
- return /* @__PURE__ */ jsx(ViewAsMmd, { viewId, mmdSource: source });
1759
- }
1760
- function ViewAsDot({ dot, dotSvg }) {
1761
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Ut, { className: viewWithTopPadding, children: [
1762
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(
1763
- ScrollArea,
1764
- {
1765
- className: cssScrollArea,
1766
- p: 5,
1767
- styles: {
1768
- viewport: {
1769
- borderRadius: 6
1770
- }
1771
- },
1772
- children: [
1773
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: dot }),
1774
- /* @__PURE__ */ jsx(CopyToClipboard, { text: dot })
1775
- ]
1776
- }
1777
- ) }),
1778
- /* @__PURE__ */ jsx(
1779
- Zt,
1780
- {
1781
- style: {
1782
- width: 10
1783
- }
1784
- }
1785
- ),
1786
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsx(ScrollArea, { h: "100%", children: /* @__PURE__ */ jsx("div", { className: svgContainer, dangerouslySetInnerHTML: { __html: dotSvg } }) }) })
1787
- ] }) });
1788
- }
1789
- const Route$1 = createFileRoute("/_single/view/$viewId/dot")({
1790
- component: Page$1,
1791
- staleTime: 1 / 0,
1792
- loader: async ({ params, context }) => {
1793
- const projectId = context.projectId, { viewId } = params, { loadDotSources } = await import("likec4:dot");
1794
- try {
1795
- const { dotSource, svgSource } = await loadDotSources(projectId), dot = dotSource(viewId), dotSvg = svgSource(viewId);
1796
- return {
1797
- dot,
1798
- dotSvg
1799
- };
1800
- } catch (error) {
1801
- throw console.error(error), notFound();
1802
- }
1803
- }
1804
- });
1805
- function Page$1() {
1806
- const { dot, dotSvg } = Route$1.useLoaderData();
1807
- return /* @__PURE__ */ jsx(ViewAsDot, { dot, dotSvg });
1808
- }
1809
- const fetchFromKroki = async (d2) => await (await fetch(krokiD2SvgUrl, {
1810
- method: "POST",
1811
- cache: "force-cache",
1812
- body: JSON.stringify({
1813
- diagram_source: d2,
1814
- // diagram_options: {
1815
- // theme: 'colorblind-clear'
1816
- // },
1817
- output_format: "svg"
1818
- }),
1819
- headers: {
1820
- "Content-Type": "application/json"
1821
- }
1822
- })).text();
1823
- function ViewAsD2({ d2Source }) {
1824
- const [krokiSvg, { execute }] = useAsync(fetchFromKroki, null);
1825
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
1826
- Ut,
1827
- {
1828
- className: viewWithTopPadding,
1829
- orientation: "horizontal",
1830
- children: [
1831
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(
1832
- ScrollArea,
1833
- {
1834
- className: cssScrollArea,
1835
- p: 5,
1836
- styles: {
1837
- viewport: {
1838
- borderRadius: 6
1839
- }
1840
- },
1841
- children: [
1842
- /* @__PURE__ */ jsx(Code, { block: !0, className: cssCodeBlock, children: d2Source }),
1843
- /* @__PURE__ */ jsx(CopyToClipboard, { text: d2Source })
1844
- ]
1845
- }
1846
- ) }),
1847
- /* @__PURE__ */ jsx(
1848
- Zt,
1849
- {
1850
- style: {
1851
- width: 10
1852
- }
1853
- }
1854
- ),
1855
- /* @__PURE__ */ jsx(qt, { children: /* @__PURE__ */ jsxs(ScrollArea, { h: "100%", children: [
1856
- krokiSvg.status !== "success" && /* @__PURE__ */ jsxs(Fragment, { children: [
1857
- /* @__PURE__ */ jsx(
1858
- Button,
1859
- {
1860
- mt: "xs",
1861
- variant: "light",
1862
- disabled: krokiSvg.status === "loading",
1863
- onClick: () => {
1864
- execute(d2Source);
1865
- },
1866
- children: krokiSvg.status === "loading" ? "Loading..." : "Render with Kroki"
1867
- }
1868
- ),
1869
- krokiSvg.status === "error" && /* @__PURE__ */ jsx(Box, { children: krokiSvg.error?.message })
1870
- ] }),
1871
- krokiSvg.status === "success" && /* @__PURE__ */ jsx(Box, { className: svgContainer, children: krokiSvg.result ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: krokiSvg.result } }) : /* @__PURE__ */ jsx(Box, { children: "Empty result" }) })
1872
- ] }) })
1873
- ]
1874
- }
1875
- ) });
1876
- }
1877
- const Route = createFileRoute("/_single/view/$viewId/d2")({
1878
- component: Page,
1879
- staleTime: 1 / 0,
1880
- loader: async ({ context, params }) => {
1881
- const projectId = context.projectId, { viewId } = params, { loadD2Sources } = await import("likec4:d2");
1882
- try {
1883
- const { d2Source } = await loadD2Sources(projectId);
1884
- return {
1885
- source: d2Source(viewId)
1886
- };
1887
- } catch (error) {
1888
- throw console.error(error), notFound();
1889
- }
1890
- }
1891
- });
1892
- function Page() {
1893
- const { source } = Route.useLoaderData();
1894
- return /* @__PURE__ */ jsx(ViewAsD2, { d2Source: source });
1895
- }
1896
- export {
1897
- AdHocViewEditor as A,
1898
- ExportPage as E,
1899
- Fallback as F,
1900
- Header as H,
1901
- LikeC4IconRendererContext as L,
1902
- NotFound as N,
1903
- Route$b as R,
1904
- ViewOutlet as V,
1905
- Route$a as a,
1906
- Route$9 as b,
1907
- Route$8 as c,
1908
- Route$7 as d,
1909
- Route$6 as e,
1910
- Route$5 as f,
1911
- Route$4 as g,
1912
- Route$3 as h,
1913
- Route$2 as i,
1914
- Route$1 as j,
1915
- Route as k,
1916
- LikeC4ModelContext as l,
1917
- EmbedPage as m,
1918
- ViewEditor as n,
1919
- ViewReact as o,
1920
- ViewAsPuml as p,
1921
- ViewAsMmd as q,
1922
- ViewAsDot as r,
1923
- ViewAsD2 as s
1924
- };