Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1fd4dc244 | ||
|
|
9436f8ddda | ||
|
|
62699769d5 | ||
|
|
5608dc5661 | ||
|
|
29e92a9702 | ||
|
|
0e0da3b1e9 | ||
|
|
d273e1d722 | ||
|
|
c799dff042 | ||
|
|
c675dc02e9 | ||
|
|
ab760f35fa | ||
|
|
8a436791de | ||
|
|
d16a1776e6 | ||
|
|
ab720e0267 | ||
|
|
d7db71e38a | ||
|
|
b466e8430e | ||
|
|
ea404df79b | ||
|
|
15cdb7b64a | ||
|
|
340911f271 | ||
|
|
44d15c0f5e | ||
|
|
c36e51fb9f |
@@ -1,4 +1,5 @@
|
||||
MERMAID_DOMAIN=''
|
||||
MERMAID_BASE_PATH=''
|
||||
MERMAID_DOCS_URL='https://mermaid.js.org'
|
||||
MERMAID_ANALYTICS_URL=''
|
||||
MERMAID_RENDERER_URL='https://mermaid.ink'
|
||||
|
||||
@@ -19,6 +19,9 @@ ARG MERMAID_KROKI_RENDERER_URL
|
||||
ARG MERMAID_ANALYTICS_URL
|
||||
ARG MERMAID_DOMAIN
|
||||
ARG MERMAID_IS_ENABLED_MERMAID_CHART_LINKS
|
||||
ARG MERMAID_PRIVACY_POLICY_URL
|
||||
ARG MERMAID_HIDE_PRIVACY_POLICY
|
||||
ARG MERMAID_BASE_PATH
|
||||
|
||||
COPY . ./
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ If you want to speed up the progress for mermaid-live-editor, join the Discord c
|
||||
docker run --platform linux/amd64 --publish 8000:8080 ghcr.io/mermaid-js/mermaid-live-editor
|
||||
```
|
||||
|
||||
The published docker image is built using our default environment variables. You cannot override them when running the image. If you need to customize them, you will need to build the image yourself.
|
||||
|
||||
### To configure renderer URL
|
||||
|
||||
When building set the MERMAID_RENDERER_URL build argument to the rendering
|
||||
|
||||
+2
-1
@@ -48,6 +48,7 @@
|
||||
"chai": "^4.5.0",
|
||||
"clsx": "^2.1.1",
|
||||
"cssnano": "^6.1.2",
|
||||
"dotenv": "^17.3.1",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-es": "^4.1.0",
|
||||
@@ -102,7 +103,7 @@
|
||||
"hammerjs": "^2.0.8",
|
||||
"js-base64": "3.7.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mermaid": "^11.12.0",
|
||||
"mermaid": "^11.13.0",
|
||||
"mode-watcher": "^0.5.1",
|
||||
"monaco-editor": "0.52.2",
|
||||
"pako": "2.1.0",
|
||||
|
||||
Generated
+126
-93
@@ -37,22 +37,22 @@ importers:
|
||||
version: 6.1.4(@codemirror/language@6.11.0)(@codemirror/state@6.5.2)(@codemirror/view@6.36.7)(@lezer/highlight@1.2.1)
|
||||
'@mermaid-js/examples':
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0(mermaid@11.12.0)
|
||||
version: 1.0.0(mermaid@11.13.0)
|
||||
'@mermaid-js/layout-elk':
|
||||
specifier: ^0.1.9
|
||||
version: 0.1.9(mermaid@11.12.0)
|
||||
version: 0.1.9(mermaid@11.13.0)
|
||||
'@mermaid-js/layout-tidy-tree':
|
||||
specifier: ^0.2.1
|
||||
version: 0.2.1(mermaid@11.12.0)
|
||||
version: 0.2.1(mermaid@11.13.0)
|
||||
'@mermaid-js/mermaid-zenuml':
|
||||
specifier: ^0.2.2
|
||||
version: 0.2.2(mermaid@11.12.0)
|
||||
version: 0.2.2(mermaid@11.13.0)
|
||||
codemirror:
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
version: 1.11.13
|
||||
version: 1.11.18
|
||||
hammerjs:
|
||||
specifier: ^2.0.8
|
||||
version: 2.0.8
|
||||
@@ -63,8 +63,8 @@ importers:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
mermaid:
|
||||
specifier: ^11.12.0
|
||||
version: 11.12.0
|
||||
specifier: ^11.13.0
|
||||
version: 11.13.0
|
||||
mode-watcher:
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1(svelte@5.38.6)
|
||||
@@ -165,6 +165,9 @@ importers:
|
||||
cssnano:
|
||||
specifier: ^6.1.2
|
||||
version: 6.1.2(postcss@8.5.3)
|
||||
dotenv:
|
||||
specifier: ^17.3.1
|
||||
version: 17.3.1
|
||||
eslint:
|
||||
specifier: ^9.39.2
|
||||
version: 9.39.2(jiti@2.6.1)
|
||||
@@ -317,20 +320,20 @@ packages:
|
||||
'@braintree/sanitize-url@7.1.1':
|
||||
resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==}
|
||||
|
||||
'@chevrotain/cst-dts-gen@11.0.3':
|
||||
resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==}
|
||||
'@chevrotain/cst-dts-gen@11.1.2':
|
||||
resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==}
|
||||
|
||||
'@chevrotain/gast@11.0.3':
|
||||
resolution: {integrity: sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==}
|
||||
'@chevrotain/gast@11.1.2':
|
||||
resolution: {integrity: sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==}
|
||||
|
||||
'@chevrotain/regexp-to-ast@11.0.3':
|
||||
resolution: {integrity: sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==}
|
||||
'@chevrotain/regexp-to-ast@11.1.2':
|
||||
resolution: {integrity: sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==}
|
||||
|
||||
'@chevrotain/types@11.0.3':
|
||||
resolution: {integrity: sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==}
|
||||
'@chevrotain/types@11.1.2':
|
||||
resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==}
|
||||
|
||||
'@chevrotain/utils@11.0.3':
|
||||
resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==}
|
||||
'@chevrotain/utils@11.1.2':
|
||||
resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==}
|
||||
|
||||
'@codemirror/autocomplete@6.18.6':
|
||||
resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==}
|
||||
@@ -802,8 +805,8 @@ packages:
|
||||
peerDependencies:
|
||||
mermaid: ^10 || ^11
|
||||
|
||||
'@mermaid-js/parser@0.6.2':
|
||||
resolution: {integrity: sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==}
|
||||
'@mermaid-js/parser@1.0.1':
|
||||
resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==}
|
||||
|
||||
'@nodelib/fs.scandir@2.1.5':
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
@@ -1320,6 +1323,9 @@ packages:
|
||||
resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@upsetjs/venn.js@2.0.0':
|
||||
resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==}
|
||||
|
||||
'@vitest/coverage-v8@3.2.4':
|
||||
resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==}
|
||||
peerDependencies:
|
||||
@@ -1585,8 +1591,8 @@ packages:
|
||||
peerDependencies:
|
||||
chevrotain: ^11.0.0
|
||||
|
||||
chevrotain@11.0.3:
|
||||
resolution: {integrity: sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==}
|
||||
chevrotain@11.1.2:
|
||||
resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==}
|
||||
|
||||
chokidar@3.6.0:
|
||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||
@@ -1759,8 +1765,8 @@ packages:
|
||||
peerDependencies:
|
||||
cytoscape: ^3.2.0
|
||||
|
||||
cytoscape@3.31.1:
|
||||
resolution: {integrity: sha512-Hx5Mtb1+hnmAKaZZ/7zL1Y5HTFYOjdDswZy/jD+1WINRU8KVi1B7+vlHdsTwY+VCFucTreoyu1RDzQJ9u0d2Hw==}
|
||||
cytoscape@3.33.1:
|
||||
resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
d3-array@2.12.1:
|
||||
@@ -1902,19 +1908,19 @@ packages:
|
||||
resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
dagre-d3-es@7.0.11:
|
||||
resolution: {integrity: sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==}
|
||||
dagre-d3-es@7.0.14:
|
||||
resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==}
|
||||
|
||||
data-urls@5.0.0:
|
||||
resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
dayjs@1.11.13:
|
||||
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
|
||||
|
||||
dayjs@1.11.18:
|
||||
resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==}
|
||||
|
||||
dayjs@1.11.20:
|
||||
resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==}
|
||||
|
||||
debug@4.4.0:
|
||||
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -1987,9 +1993,16 @@ packages:
|
||||
dompurify@3.2.6:
|
||||
resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==}
|
||||
|
||||
dompurify@3.3.3:
|
||||
resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==}
|
||||
|
||||
domutils@3.2.2:
|
||||
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
|
||||
|
||||
dotenv@17.3.1:
|
||||
resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -2310,11 +2323,12 @@ packages:
|
||||
|
||||
glob@10.4.5:
|
||||
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
hasBin: true
|
||||
|
||||
glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
|
||||
globals@14.0.0:
|
||||
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
|
||||
@@ -2568,8 +2582,8 @@ packages:
|
||||
json-stable-stringify-without-jsonify@1.0.1:
|
||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||
|
||||
katex@0.16.22:
|
||||
resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==}
|
||||
katex@0.16.38:
|
||||
resolution: {integrity: sha512-cjHooZUmIAUmDsHBN+1n8LaZdpmbj03LtYeYPyuYB7OuloiaeaV6N4LcfjcnHVzGWjVQmKrxxTrpDcmSzEZQwQ==}
|
||||
hasBin: true
|
||||
|
||||
keyv@4.5.4:
|
||||
@@ -2588,9 +2602,9 @@ packages:
|
||||
kolorist@1.8.0:
|
||||
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
|
||||
|
||||
langium@3.3.1:
|
||||
resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
langium@4.2.1:
|
||||
resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==}
|
||||
engines: {node: '>=20.10.0', npm: '>=10.2.3'}
|
||||
|
||||
layout-base@1.0.2:
|
||||
resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==}
|
||||
@@ -2706,6 +2720,9 @@ packages:
|
||||
lodash-es@4.17.21:
|
||||
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||
|
||||
lodash-es@4.17.23:
|
||||
resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==}
|
||||
|
||||
lodash.memoize@4.1.2:
|
||||
resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
|
||||
|
||||
@@ -2776,8 +2793,8 @@ packages:
|
||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
mermaid@11.12.0:
|
||||
resolution: {integrity: sha512-ZudVx73BwrMJfCFmSSJT84y6u5brEoV8DOItdHomNLz32uBjNrelm7mg95X7g+C6UoQH/W6mBLGDEDv73JdxBg==}
|
||||
mermaid@11.13.0:
|
||||
resolution: {integrity: sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==}
|
||||
|
||||
micromatch@4.0.8:
|
||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||
@@ -3011,6 +3028,7 @@ packages:
|
||||
plausible-tracker@0.3.9:
|
||||
resolution: {integrity: sha512-hMhneYm3GCPyQon88SZrVJx+LlqhM1kZFQbuAgXPoh/Az2YvO1B6bitT9qlhpiTdJlsT5lsr3gPmzoVjb5CDXA==}
|
||||
engines: {node: '>=10'}
|
||||
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
|
||||
|
||||
playwright-core@1.52.0:
|
||||
resolution: {integrity: sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==}
|
||||
@@ -4029,8 +4047,8 @@ packages:
|
||||
resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==}
|
||||
hasBin: true
|
||||
|
||||
vscode-uri@3.0.8:
|
||||
resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
|
||||
vscode-uri@3.1.0:
|
||||
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
||||
|
||||
w3c-keyname@2.2.8:
|
||||
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
||||
@@ -4049,6 +4067,7 @@ packages:
|
||||
whatwg-encoding@3.1.1:
|
||||
resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
|
||||
engines: {node: '>=18'}
|
||||
deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation
|
||||
|
||||
whatwg-mimetype@4.0.0:
|
||||
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
|
||||
@@ -4179,22 +4198,22 @@ snapshots:
|
||||
|
||||
'@braintree/sanitize-url@7.1.1': {}
|
||||
|
||||
'@chevrotain/cst-dts-gen@11.0.3':
|
||||
'@chevrotain/cst-dts-gen@11.1.2':
|
||||
dependencies:
|
||||
'@chevrotain/gast': 11.0.3
|
||||
'@chevrotain/types': 11.0.3
|
||||
lodash-es: 4.17.21
|
||||
'@chevrotain/gast': 11.1.2
|
||||
'@chevrotain/types': 11.1.2
|
||||
lodash-es: 4.17.23
|
||||
|
||||
'@chevrotain/gast@11.0.3':
|
||||
'@chevrotain/gast@11.1.2':
|
||||
dependencies:
|
||||
'@chevrotain/types': 11.0.3
|
||||
lodash-es: 4.17.21
|
||||
'@chevrotain/types': 11.1.2
|
||||
lodash-es: 4.17.23
|
||||
|
||||
'@chevrotain/regexp-to-ast@11.0.3': {}
|
||||
'@chevrotain/regexp-to-ast@11.1.2': {}
|
||||
|
||||
'@chevrotain/types@11.0.3': {}
|
||||
'@chevrotain/types@11.1.2': {}
|
||||
|
||||
'@chevrotain/utils@11.0.3': {}
|
||||
'@chevrotain/utils@11.1.2': {}
|
||||
|
||||
'@codemirror/autocomplete@6.18.6':
|
||||
dependencies:
|
||||
@@ -4663,32 +4682,32 @@ snapshots:
|
||||
|
||||
'@marijn/find-cluster-break@1.0.2': {}
|
||||
|
||||
'@mermaid-js/examples@1.0.0(mermaid@11.12.0)':
|
||||
'@mermaid-js/examples@1.0.0(mermaid@11.13.0)':
|
||||
dependencies:
|
||||
mermaid: 11.12.0
|
||||
mermaid: 11.13.0
|
||||
|
||||
'@mermaid-js/layout-elk@0.1.9(mermaid@11.12.0)':
|
||||
'@mermaid-js/layout-elk@0.1.9(mermaid@11.13.0)':
|
||||
dependencies:
|
||||
d3: 7.9.0
|
||||
elkjs: 0.9.3
|
||||
mermaid: 11.12.0
|
||||
mermaid: 11.13.0
|
||||
|
||||
'@mermaid-js/layout-tidy-tree@0.2.1(mermaid@11.12.0)':
|
||||
'@mermaid-js/layout-tidy-tree@0.2.1(mermaid@11.13.0)':
|
||||
dependencies:
|
||||
d3: 7.9.0
|
||||
mermaid: 11.12.0
|
||||
mermaid: 11.13.0
|
||||
|
||||
'@mermaid-js/mermaid-zenuml@0.2.2(mermaid@11.12.0)':
|
||||
'@mermaid-js/mermaid-zenuml@0.2.2(mermaid@11.13.0)':
|
||||
dependencies:
|
||||
'@zenuml/core': 3.36.0
|
||||
mermaid: 11.12.0
|
||||
mermaid: 11.13.0
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
- ts-node
|
||||
|
||||
'@mermaid-js/parser@0.6.2':
|
||||
'@mermaid-js/parser@1.0.1':
|
||||
dependencies:
|
||||
langium: 3.3.1
|
||||
langium: 4.2.1
|
||||
|
||||
'@nodelib/fs.scandir@2.1.5':
|
||||
dependencies:
|
||||
@@ -5212,6 +5231,11 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.42.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
'@upsetjs/venn.js@2.0.0':
|
||||
optionalDependencies:
|
||||
d3-selection: 3.0.0
|
||||
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||
|
||||
'@vitest/coverage-v8@3.2.4(vitest@3.2.4)':
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
@@ -5547,19 +5571,19 @@ snapshots:
|
||||
|
||||
check-error@2.1.1: {}
|
||||
|
||||
chevrotain-allstar@0.3.1(chevrotain@11.0.3):
|
||||
chevrotain-allstar@0.3.1(chevrotain@11.1.2):
|
||||
dependencies:
|
||||
chevrotain: 11.0.3
|
||||
lodash-es: 4.17.21
|
||||
chevrotain: 11.1.2
|
||||
lodash-es: 4.17.23
|
||||
|
||||
chevrotain@11.0.3:
|
||||
chevrotain@11.1.2:
|
||||
dependencies:
|
||||
'@chevrotain/cst-dts-gen': 11.0.3
|
||||
'@chevrotain/gast': 11.0.3
|
||||
'@chevrotain/regexp-to-ast': 11.0.3
|
||||
'@chevrotain/types': 11.0.3
|
||||
'@chevrotain/utils': 11.0.3
|
||||
lodash-es: 4.17.21
|
||||
'@chevrotain/cst-dts-gen': 11.1.2
|
||||
'@chevrotain/gast': 11.1.2
|
||||
'@chevrotain/regexp-to-ast': 11.1.2
|
||||
'@chevrotain/types': 11.1.2
|
||||
'@chevrotain/utils': 11.1.2
|
||||
lodash-es: 4.17.23
|
||||
|
||||
chokidar@3.6.0:
|
||||
dependencies:
|
||||
@@ -5749,17 +5773,17 @@ snapshots:
|
||||
'@asamuzakjp/css-color': 3.1.1
|
||||
rrweb-cssom: 0.8.0
|
||||
|
||||
cytoscape-cose-bilkent@4.1.0(cytoscape@3.31.1):
|
||||
cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1):
|
||||
dependencies:
|
||||
cose-base: 1.0.3
|
||||
cytoscape: 3.31.1
|
||||
cytoscape: 3.33.1
|
||||
|
||||
cytoscape-fcose@2.2.0(cytoscape@3.31.1):
|
||||
cytoscape-fcose@2.2.0(cytoscape@3.33.1):
|
||||
dependencies:
|
||||
cose-base: 2.2.0
|
||||
cytoscape: 3.31.1
|
||||
cytoscape: 3.33.1
|
||||
|
||||
cytoscape@3.31.1: {}
|
||||
cytoscape@3.33.1: {}
|
||||
|
||||
d3-array@2.12.1:
|
||||
dependencies:
|
||||
@@ -5928,20 +5952,20 @@ snapshots:
|
||||
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||
d3-zoom: 3.0.0
|
||||
|
||||
dagre-d3-es@7.0.11:
|
||||
dagre-d3-es@7.0.14:
|
||||
dependencies:
|
||||
d3: 7.9.0
|
||||
lodash-es: 4.17.21
|
||||
lodash-es: 4.17.23
|
||||
|
||||
data-urls@5.0.0:
|
||||
dependencies:
|
||||
whatwg-mimetype: 4.0.0
|
||||
whatwg-url: 14.2.0
|
||||
|
||||
dayjs@1.11.13: {}
|
||||
|
||||
dayjs@1.11.18: {}
|
||||
|
||||
dayjs@1.11.20: {}
|
||||
|
||||
debug@4.4.0:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
@@ -5994,12 +6018,18 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
|
||||
dompurify@3.3.3:
|
||||
optionalDependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
|
||||
domutils@3.2.2:
|
||||
dependencies:
|
||||
dom-serializer: 2.0.0
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
|
||||
dotenv@17.3.1: {}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
@@ -6594,7 +6624,7 @@ snapshots:
|
||||
|
||||
json-stable-stringify-without-jsonify@1.0.1: {}
|
||||
|
||||
katex@0.16.22:
|
||||
katex@0.16.38:
|
||||
dependencies:
|
||||
commander: 8.3.0
|
||||
|
||||
@@ -6610,13 +6640,13 @@ snapshots:
|
||||
|
||||
kolorist@1.8.0: {}
|
||||
|
||||
langium@3.3.1:
|
||||
langium@4.2.1:
|
||||
dependencies:
|
||||
chevrotain: 11.0.3
|
||||
chevrotain-allstar: 0.3.1(chevrotain@11.0.3)
|
||||
chevrotain: 11.1.2
|
||||
chevrotain-allstar: 0.3.1(chevrotain@11.1.2)
|
||||
vscode-languageserver: 9.0.1
|
||||
vscode-languageserver-textdocument: 1.0.12
|
||||
vscode-uri: 3.0.8
|
||||
vscode-uri: 3.1.0
|
||||
|
||||
layout-base@1.0.2: {}
|
||||
|
||||
@@ -6720,6 +6750,8 @@ snapshots:
|
||||
|
||||
lodash-es@4.17.21: {}
|
||||
|
||||
lodash-es@4.17.23: {}
|
||||
|
||||
lodash.memoize@4.1.2: {}
|
||||
|
||||
lodash.merge@4.6.2: {}
|
||||
@@ -6780,23 +6812,24 @@ snapshots:
|
||||
|
||||
merge2@1.4.1: {}
|
||||
|
||||
mermaid@11.12.0:
|
||||
mermaid@11.13.0:
|
||||
dependencies:
|
||||
'@braintree/sanitize-url': 7.1.1
|
||||
'@iconify/utils': 3.0.2
|
||||
'@mermaid-js/parser': 0.6.2
|
||||
'@mermaid-js/parser': 1.0.1
|
||||
'@types/d3': 7.4.3
|
||||
cytoscape: 3.31.1
|
||||
cytoscape-cose-bilkent: 4.1.0(cytoscape@3.31.1)
|
||||
cytoscape-fcose: 2.2.0(cytoscape@3.31.1)
|
||||
'@upsetjs/venn.js': 2.0.0
|
||||
cytoscape: 3.33.1
|
||||
cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1)
|
||||
cytoscape-fcose: 2.2.0(cytoscape@3.33.1)
|
||||
d3: 7.9.0
|
||||
d3-sankey: 0.12.3
|
||||
dagre-d3-es: 7.0.11
|
||||
dayjs: 1.11.18
|
||||
dompurify: 3.2.6
|
||||
katex: 0.16.22
|
||||
dagre-d3-es: 7.0.14
|
||||
dayjs: 1.11.20
|
||||
dompurify: 3.3.3
|
||||
katex: 0.16.38
|
||||
khroma: 2.1.0
|
||||
lodash-es: 4.17.21
|
||||
lodash-es: 4.17.23
|
||||
marked: 16.3.0
|
||||
roughjs: 4.6.6
|
||||
stylis: 4.3.6
|
||||
@@ -7915,7 +7948,7 @@ snapshots:
|
||||
dependencies:
|
||||
vscode-languageserver-protocol: 3.17.5
|
||||
|
||||
vscode-uri@3.0.8: {}
|
||||
vscode-uri@3.1.0: {}
|
||||
|
||||
w3c-keyname@2.2.8: {}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Online FlowChart & Diagrams Editor - Mermaid Live Editor</title>
|
||||
<meta name="og:image" content="%sveltekit.assets%/favicon.svg" />
|
||||
<link rel="canonical" href="https://mermaid.ai/live" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Simplify documentation and avoid heavy tools. Open source Visio Alternative. Commonly used for explaining your code! Mermaid is a simple markdown-like script language for generating charts from text via javascript." />
|
||||
|
||||
Vendored
+2
@@ -7,6 +7,8 @@ interface ImportMetaEnv {
|
||||
readonly MERMAID_DOCS_URL?: string;
|
||||
readonly MERMAID_DOMAIN?: string;
|
||||
readonly MERMAID_IS_ENABLED_MERMAID_CHART_LINKS?: string;
|
||||
readonly MERMAID_PRIVACY_POLICY_URL?: string;
|
||||
readonly MERMAID_HIDE_PRIVACY_POLICY?: string;
|
||||
// more env variables...
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
const showErrorDebounced = debounce(() => {
|
||||
showError = true;
|
||||
}, 5000);
|
||||
}, 3000);
|
||||
|
||||
$effect(() => {
|
||||
if ($stateStore.error) {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
<script lang="ts">
|
||||
import McWrapper from '$/components/McWrapper.svelte';
|
||||
import MermaidChartIcon from '$/components/MermaidChartIcon.svelte';
|
||||
import { Button } from '$/components/ui/button';
|
||||
import { standardizeDiagramType } from '$/util/mermaid';
|
||||
import { stateStore, urlsStore } from '$/util/state';
|
||||
import { logMermaidChartClick } from '$/util/stats';
|
||||
import { quintInOut } from 'svelte/easing';
|
||||
import { slide } from 'svelte/transition';
|
||||
|
||||
const visualEditDiagramTypes = new Set([
|
||||
'flowchart',
|
||||
'stateDiagram',
|
||||
'classDiagram',
|
||||
'sequenceDiagram',
|
||||
'er',
|
||||
'requirement',
|
||||
'mindmap'
|
||||
]);
|
||||
|
||||
const diagramType = $derived.by(() => {
|
||||
const dt = $stateStore.diagramType;
|
||||
return dt ? standardizeDiagramType(dt) : undefined;
|
||||
});
|
||||
|
||||
const showVisualEdit = $derived.by(() => {
|
||||
return diagramType ? visualEditDiagramTypes.has(diagramType) : false;
|
||||
});
|
||||
|
||||
interface EnhancedEditAction {
|
||||
campaign: string;
|
||||
label: string;
|
||||
medium: 'ai_edit' | 'visual_edit' | 'voice_edit';
|
||||
source: string;
|
||||
}
|
||||
|
||||
let currentActionMedium = $state<EnhancedEditAction['medium'] | undefined>(undefined);
|
||||
let previousDiagramType = $state<string | undefined>(undefined);
|
||||
|
||||
const availableActions = $derived.by<EnhancedEditAction[]>(() => {
|
||||
if (!$stateStore.diagramType) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const actions: EnhancedEditAction[] = [
|
||||
{ campaign: 'ai_1', label: 'with AI', medium: 'ai_edit', source: 'aiEdit' },
|
||||
{ campaign: 'voice_1', label: 'with Voice', medium: 'voice_edit', source: 'voiceEdit' }
|
||||
];
|
||||
|
||||
if (showVisualEdit) {
|
||||
actions.unshift({
|
||||
campaign: 'visual_1',
|
||||
label: 'Visually',
|
||||
medium: 'visual_edit',
|
||||
source: 'visualEdit'
|
||||
});
|
||||
}
|
||||
|
||||
return actions;
|
||||
});
|
||||
|
||||
const currentAction = $derived.by(() => {
|
||||
const actions = availableActions;
|
||||
if (actions.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return actions.find(({ medium }) => medium === currentActionMedium) ?? actions[0];
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
const actions = availableActions;
|
||||
|
||||
if (!diagramType || actions.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hasCurrentAction = actions.some(({ medium }) => medium === currentActionMedium);
|
||||
|
||||
if (diagramType !== previousDiagramType || !hasCurrentAction) {
|
||||
currentActionMedium = actions[Math.floor(Math.random() * actions.length)].medium;
|
||||
previousDiagramType = diagramType;
|
||||
}
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (diagramType) {
|
||||
return;
|
||||
}
|
||||
|
||||
previousDiagramType = undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if currentAction}
|
||||
<McWrapper>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
href={$urlsStore.mermaidChart({
|
||||
medium: currentAction.medium,
|
||||
campaign: currentAction.campaign
|
||||
}).save}
|
||||
target="_blank"
|
||||
onclick={() => logMermaidChartClick(currentAction.source)}>
|
||||
<MermaidChartIcon />
|
||||
Edit
|
||||
{#key currentAction.label}
|
||||
<span
|
||||
class="-ml-1"
|
||||
in:slide={{ axis: 'x', easing: quintInOut, delay: 400 }}
|
||||
out:slide={{ axis: 'x', easing: quintInOut }}>
|
||||
{currentAction.label}
|
||||
</span>
|
||||
{/key}
|
||||
</Button>
|
||||
</McWrapper>
|
||||
{/if}
|
||||
@@ -1,7 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { asset } from '$app/paths';
|
||||
import type { ClassValue } from 'svelte/elements';
|
||||
|
||||
let { class: className }: { class?: ClassValue } = $props();
|
||||
</script>
|
||||
|
||||
<img class={['size-4', className]} src="/mermaidchart-logo.svg" alt="Mermaid Chart" />
|
||||
<img class={['size-4', className]} src={asset('/mermaidchart-logo.svg')} alt="Mermaid Chart" />
|
||||
|
||||
@@ -1,45 +1,66 @@
|
||||
<script>
|
||||
import ExternalLinkWrapper from '$/components/ExternalLinkWrapper.svelte';
|
||||
import * as Dialog from '$/components/ui/dialog';
|
||||
import { env } from '$/util/env';
|
||||
import { isOnMermaidLive } from '$/util/migration/domainMigration';
|
||||
import ShieldIcon from '~icons/material-symbols/shield-lock-outline-rounded';
|
||||
</script>
|
||||
|
||||
<Dialog.Root>
|
||||
<Dialog.Trigger>
|
||||
{#if env.privacyPolicyUrl}
|
||||
<a href={env.privacyPolicyUrl} target="_blank">
|
||||
<ShieldIcon />
|
||||
</Dialog.Trigger>
|
||||
<Dialog.Content class="max-h-full overflow-hidden overflow-y-auto p-12">
|
||||
<Dialog.Header>
|
||||
<Dialog.Title class="flex items-center gap-2 text-xl">
|
||||
<ShieldIcon class="size-8 text-green-700" />
|
||||
Data security
|
||||
</Dialog.Title>
|
||||
</Dialog.Header>
|
||||
</a>
|
||||
{:else}
|
||||
<Dialog.Root>
|
||||
<Dialog.Trigger>
|
||||
<ShieldIcon />
|
||||
</Dialog.Trigger>
|
||||
<Dialog.Content class="max-h-full overflow-hidden overflow-y-auto p-12">
|
||||
<Dialog.Header>
|
||||
<Dialog.Title class="flex items-center gap-2 text-xl">
|
||||
<ShieldIcon class="size-8 text-green-700" />
|
||||
Data security
|
||||
</Dialog.Title>
|
||||
</Dialog.Header>
|
||||
|
||||
<p class="text-xl font-semibold">Your diagrams never leave your browser.</p>
|
||||
<p>They're only stored in the URL and your browser's local storage.</p>
|
||||
<p>
|
||||
This is a fully open source, client-side app deployed on <a
|
||||
href="https://github.com/mermaid-js/mermaid-live-editor/deployments"
|
||||
class="underline"
|
||||
target="_blank">GitHub Pages</a>
|
||||
that works offline as a
|
||||
<a href="https://web.dev/explore/progressive-web-apps" target="_blank">Progressive Web App</a
|
||||
>.
|
||||
</p>
|
||||
<p>
|
||||
We use self hosted, privacy-friendly Plausible Analytics to collect anonymous usage metadata
|
||||
(diagram types, feature usage, etc.). All data is <a
|
||||
href="https://p.mermaid.live/mermaid.live"
|
||||
class="underline"
|
||||
target="_blank">publicly available</a
|
||||
>.
|
||||
</p>
|
||||
<ExternalLinkWrapper domain="example.com" isVisible>
|
||||
<p class="text-left">
|
||||
External services (PNG/SVG/Kroki exports, "Save to Mermaid Chart", "Repair with AI", etc)
|
||||
will share your diagram with those 3rd parties, and are highlighted in the UI on hover.
|
||||
</p>
|
||||
</ExternalLinkWrapper>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
{#if isOnMermaidLive()}
|
||||
<p class="text-xl font-semibold">Your diagrams never leave your browser.</p>
|
||||
<p>They're only stored in the URL and your browser's local storage.</p>
|
||||
<p>
|
||||
This is a fully open source, client-side app deployed on <a
|
||||
href="https://github.com/mermaid-js/mermaid-live-editor/deployments"
|
||||
class="underline"
|
||||
target="_blank">GitHub Pages</a>
|
||||
that works offline as a
|
||||
<a href="https://web.dev/explore/progressive-web-apps" target="_blank"
|
||||
>Progressive Web App</a
|
||||
>.
|
||||
</p>
|
||||
<p>
|
||||
We use self hosted, privacy-friendly Plausible Analytics to collect anonymous usage
|
||||
metadata (diagram types, feature usage, etc.). All data is <a
|
||||
href="https://p.mermaid.live/mermaid.live"
|
||||
class="underline"
|
||||
target="_blank">publicly available</a
|
||||
>.
|
||||
</p>
|
||||
<ExternalLinkWrapper domain="example.com" isVisible>
|
||||
<p class="text-left">
|
||||
External services (PNG/SVG/Kroki exports, "Save to Mermaid Chart", "Repair with AI",
|
||||
etc) will share your diagram with those 3rd parties, and are highlighted in the UI on
|
||||
hover.
|
||||
</p>
|
||||
</ExternalLinkWrapper>
|
||||
{:else}
|
||||
<p>No privacy policy has been configured for this deployment.</p>
|
||||
<p>
|
||||
If you are self-hosting the Mermaid Live Editor, set the
|
||||
<code class="rounded bg-muted px-1.5 py-0.5 text-sm">MERMAID_PRIVACY_POLICY_URL</code>
|
||||
environment variable at build time to link to your privacy policy, or set
|
||||
<code class="rounded bg-muted px-1.5 py-0.5 text-sm">MERMAID_HIDE_PRIVACY_POLICY</code>
|
||||
to <code class="rounded bg-muted px-1.5 py-0.5 text-sm">true</code> to hide this button.
|
||||
</p>
|
||||
{/if}
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
{/if}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { Separator } from '$/components/ui/separator';
|
||||
import { env } from '$/util/env';
|
||||
import { urlsStore } from '$/util/state';
|
||||
import { asset } from '$app/paths';
|
||||
import ShareIcon from '~icons/material-symbols/share';
|
||||
import CopyInput from './CopyInput.svelte';
|
||||
import MermaidChartIcon from './MermaidChartIcon.svelte';
|
||||
@@ -22,7 +23,7 @@
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-2">
|
||||
<h2 class="flex items-center gap-2">
|
||||
<img class="size-5" src="/favicon.svg" alt="Mermaid Live Editor" />
|
||||
<img class="size-5" src={asset('/favicon.svg')} alt="Mermaid Live Editor" />
|
||||
Mermaid Live Editor
|
||||
</h2>
|
||||
<CopyInput value={window.location.href} />
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { Button } from '$/components/ui/button';
|
||||
import { Separator } from '$/components/ui/separator';
|
||||
import { TID } from '$/constants';
|
||||
import { env } from '$/util/env';
|
||||
import { version } from 'mermaid/package.json';
|
||||
import { mode, setMode } from 'mode-watcher';
|
||||
import ThemeIcon from './ThemeIcon.svelte';
|
||||
@@ -11,11 +12,13 @@
|
||||
|
||||
<FloatingToolbar>
|
||||
<span class="text-sm font-semibold opacity-60">v{version}</span>
|
||||
<Button variant="ghost" size="icon" title="Privacy & Security">
|
||||
<Privacy />
|
||||
</Button>
|
||||
{#if !env.hidePrivacyPolicy}
|
||||
<Button variant="ghost" size="icon" title="Privacy & Security">
|
||||
<Privacy />
|
||||
</Button>
|
||||
|
||||
<Separator orientation="vertical" />
|
||||
<Separator orientation="vertical" />
|
||||
{/if}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { render as renderDiagram } from '$/util/mermaid';
|
||||
import { PanZoomState } from '$/util/panZoom';
|
||||
import { inputStateStore, stateStore, updateCodeStore } from '$/util/state';
|
||||
import { logEvent, saveStatistics } from '$/util/stats';
|
||||
import { saveStatistics } from '$/util/stats';
|
||||
import FontAwesome, { mayContainFontAwesome } from '$lib/components/FontAwesome.svelte';
|
||||
import uniqueID from 'lodash-es/uniqueId';
|
||||
import type { MermaidConfig } from 'mermaid';
|
||||
@@ -30,7 +30,6 @@
|
||||
const setupPanZoomObserver = () => {
|
||||
panZoomState.onPanZoomChange = (pan, zoom) => {
|
||||
updateCodeStore({ pan, zoom });
|
||||
logEvent('panZoom');
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import { logEvent, logMermaidChartClick } from '$/util/stats';
|
||||
import { getCheckoutUrl } from '$/util/util';
|
||||
import CodeIcon from '~icons/custom/code';
|
||||
import ArrowIcon from '~icons/material-symbols/arrow-forward-rounded';
|
||||
import OpenSourceIcon from '~icons/material-symbols/book-2-outline-rounded';
|
||||
import ChatIcon from '~icons/material-symbols/chat-outline-rounded';
|
||||
import EditIcon from '~icons/material-symbols/edit-outline-rounded';
|
||||
@@ -39,6 +40,12 @@
|
||||
logEvent('chooseEditor', { choice: 'openSource' });
|
||||
close();
|
||||
};
|
||||
|
||||
const handleContinueToNewHome = () => {
|
||||
logEvent('chooseEditor', { choice: 'newHome' });
|
||||
close();
|
||||
window.open('https://mermaid.ai/live', '_blank');
|
||||
};
|
||||
</script>
|
||||
|
||||
<Dialog.Root
|
||||
@@ -46,15 +53,15 @@
|
||||
onOpenChange={(v) => {
|
||||
if (!v) handleStartFree();
|
||||
}}>
|
||||
<Dialog.Content class="max-w-2xl bg-pink-50 p-0 dark:bg-background">
|
||||
<Dialog.Header class="px-8 pt-8 pb-0">
|
||||
<Dialog.Content class="flex max-w-2xl flex-col gap-6 bg-pink-50 p-6 dark:bg-background">
|
||||
<Dialog.Header>
|
||||
<Dialog.Title class="text-center text-2xl font-semibold">Choose your editor</Dialog.Title>
|
||||
<Dialog.Description class="-mt-2 text-center text-sm font-light">
|
||||
<Dialog.Description class="text-center text-sm font-light">
|
||||
You'll never see this again
|
||||
</Dialog.Description>
|
||||
</Dialog.Header>
|
||||
|
||||
<div class="grid gap-4 px-6 pt-4 pb-8 sm:grid-cols-2">
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<!-- Mermaid Plus Card -->
|
||||
<div
|
||||
class="relative flex flex-col overflow-hidden rounded-xl border-2 border-accent bg-white shadow dark:bg-card">
|
||||
@@ -62,20 +69,24 @@
|
||||
Recommended
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col p-6">
|
||||
<h3 class="text-xl font-bold">Mermaid Plus</h3>
|
||||
<p class="mb-4 text-sm text-muted-foreground">Unlock AI, storage and collaboration</p>
|
||||
|
||||
<div class="mb-2 flex justify-center">
|
||||
<span
|
||||
class="rounded-full bg-pink-100 px-3 py-0.5 text-xs font-semibold text-pink-700 dark:bg-pink-950 dark:text-pink-300">
|
||||
10% off with code JS26
|
||||
</span>
|
||||
<div class="flex flex-col gap-4 p-6">
|
||||
<div>
|
||||
<h3 class="text-xl font-bold">Mermaid Plus</h3>
|
||||
<p class="text-sm text-muted-foreground">Unlock AI, storage and collaboration</p>
|
||||
</div>
|
||||
|
||||
<Button variant="accent" class="mb-6 w-full" onclick={handleStartTrial}>
|
||||
Start free trial
|
||||
</Button>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex justify-center">
|
||||
<span
|
||||
class="rounded-full bg-pink-100 px-3 py-0.5 text-xs font-semibold text-pink-700 dark:bg-pink-950 dark:text-pink-300">
|
||||
10% off with code JS26
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Button variant="accent" class="w-full" onclick={handleStartTrial}>
|
||||
Start free trial
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<ul class="space-y-3 text-sm">
|
||||
<li class="flex items-center gap-2">
|
||||
@@ -103,13 +114,22 @@
|
||||
</div>
|
||||
|
||||
<!-- Open Source Card -->
|
||||
<div class="flex flex-col rounded-xl border bg-white p-6 shadow dark:bg-card">
|
||||
<h3 class="mt-10 text-xl font-bold">Open Source</h3>
|
||||
<p class="mb-4 text-sm text-muted-foreground">Code only, no login, always free</p>
|
||||
<div class="flex flex-col gap-4 rounded-xl border bg-white p-6 shadow dark:bg-card">
|
||||
<div class="flex flex-col justify-end pt-10">
|
||||
<h3 class="text-xl font-bold">Open Source</h3>
|
||||
<p class="text-sm text-muted-foreground">Code only, no login, always free</p>
|
||||
</div>
|
||||
|
||||
<Button variant="outline" class="mb-6 w-full border-accent" onclick={handleStartFree}>
|
||||
Start free
|
||||
</Button>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="mt-2 text-sm text-muted-foreground">Mermaid has a new home</p>
|
||||
<Button variant="outline" class="w-full border-accent" onclick={handleContinueToNewHome}>
|
||||
Continue to mermaid.ai/live
|
||||
<ArrowIcon class="ml-1 size-4" />
|
||||
</Button>
|
||||
<Button variant="outline" class="w-full" onclick={handleStartFree}>
|
||||
Stay on mermaid.live
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<ul class="space-y-3 text-sm">
|
||||
<li class="flex items-center gap-2">
|
||||
@@ -131,5 +151,14 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<a
|
||||
href="https://mermaid.ai/privacy-policy"
|
||||
target="_blank"
|
||||
class="text-sm text-foreground underline hover:text-accent">
|
||||
mermaid.ai Privacy Policy
|
||||
</a>
|
||||
</div>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
|
||||
@@ -2,7 +2,9 @@ export const env = {
|
||||
analyticsUrl: import.meta.env.MERMAID_ANALYTICS_URL ?? '',
|
||||
docsUrl: import.meta.env.MERMAID_DOCS_URL ?? 'https://mermaid.js.org',
|
||||
domain: import.meta.env.MERMAID_DOMAIN ?? '',
|
||||
hidePrivacyPolicy: import.meta.env.MERMAID_HIDE_PRIVACY_POLICY === 'true',
|
||||
isEnabledMermaidChartLinks: import.meta.env.MERMAID_IS_ENABLED_MERMAID_CHART_LINKS === 'true',
|
||||
krokiRendererUrl: import.meta.env.MERMAID_KROKI_RENDERER_URL ?? '',
|
||||
privacyPolicyUrl: import.meta.env.MERMAID_PRIVACY_POLICY_URL ?? '',
|
||||
rendererUrl: import.meta.env.MERMAID_RENDERER_URL ?? ''
|
||||
} as const;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { C } from '$/constants';
|
||||
import { env } from '$/util/env';
|
||||
|
||||
const mermaidAiDomain = 'mermaid.ai';
|
||||
const mermaidLiveDomain = 'mermaid.live';
|
||||
|
||||
/**
|
||||
* Check if we're on mermaid.ai
|
||||
@@ -11,25 +12,12 @@ export const isOnMermaidAI = (): boolean => {
|
||||
return domain === mermaidAiDomain || domain.endsWith(`.${mermaidAiDomain}`);
|
||||
};
|
||||
|
||||
// localStorage keys that indicate a returning user.
|
||||
// Note: codeStore is excluded because it's always populated with the default state on first load.
|
||||
const userDataStorageKeys = [
|
||||
'manualHistoryStore', // Manual history entries
|
||||
'autoHistoryStore' // Auto history entries
|
||||
];
|
||||
|
||||
/**
|
||||
* Check if user has any stored data in localStorage.
|
||||
* This includes saved diagrams, history entries, etc.
|
||||
* Check if we're on mermaid.live
|
||||
*/
|
||||
const hasStoredUserData = (): boolean => {
|
||||
for (const key of userDataStorageKeys) {
|
||||
const value = window.localStorage.getItem(key);
|
||||
if (value && value !== '[]' && value !== 'null' && value !== '{}') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
export const isOnMermaidLive = (): boolean => {
|
||||
const domain = window.location.hostname;
|
||||
return domain === mermaidLiveDomain || domain.endsWith(`.${mermaidLiveDomain}`);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -54,7 +42,9 @@ const isReferredFromMermaid = (): boolean => {
|
||||
hostname === 'mermaid.ai' ||
|
||||
hostname.endsWith('.mermaid.ai') ||
|
||||
hostname === 'mermaid.js.org' ||
|
||||
hostname.endsWith('.mermaid.js.org')
|
||||
hostname.endsWith('.mermaid.js.org') ||
|
||||
hostname === 'mermaid.live' ||
|
||||
hostname.endsWith('.mermaid.live')
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
@@ -64,11 +54,13 @@ const isReferredFromMermaid = (): boolean => {
|
||||
/**
|
||||
* Check if the editor chooser modal should be shown.
|
||||
* Shows for new users who haven't dismissed it and aren't viewing a shared link.
|
||||
* Not shown on mobile (viewport width < 640px).
|
||||
*/
|
||||
export const shouldShowEditorChooser = (): boolean => {
|
||||
if (!env.isEnabledMermaidChartLinks) return false;
|
||||
if (!isOnMermaidAI() && !isOnMermaidLive()) return false;
|
||||
if (window.innerWidth < 640) return false;
|
||||
if (window.localStorage.getItem(C.editorChooserDismissedKey) === 'true') return false;
|
||||
if (hasStoredUserData()) return false;
|
||||
if (hasPakoData()) return false;
|
||||
if (isReferredFromMermaid()) return false;
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildRedirectUrl } from './redirect';
|
||||
|
||||
const mockLocation = (url: string): Location => {
|
||||
const parsed = new URL(url);
|
||||
return { hash: parsed.hash, search: parsed.search } as Location;
|
||||
};
|
||||
|
||||
describe('buildRedirectUrl', () => {
|
||||
it('should redirect to /edit by default when hash is empty', () => {
|
||||
expect(buildRedirectUrl(mockLocation('https://mermaid.live/'))).toBe('/edit');
|
||||
});
|
||||
|
||||
it('should preserve search params', () => {
|
||||
expect(buildRedirectUrl(mockLocation('https://mermaid.live/?utm_source=github'))).toBe(
|
||||
'/edit?utm_source=github'
|
||||
);
|
||||
});
|
||||
|
||||
it('should extract route and fragment from old hash format', () => {
|
||||
expect(buildRedirectUrl(mockLocation('https://mermaid.live/#/edit/pako:abc123'))).toBe(
|
||||
'/edit#pako:abc123'
|
||||
);
|
||||
});
|
||||
|
||||
it('should place search params before the hash fragment', () => {
|
||||
expect(
|
||||
buildRedirectUrl(mockLocation('https://mermaid.live/?utm_source=twitter#/edit/pako:abc123'))
|
||||
).toBe('/edit?utm_source=twitter#pako:abc123');
|
||||
});
|
||||
|
||||
it('should handle hash with view route', () => {
|
||||
expect(buildRedirectUrl(mockLocation('https://mermaid.live/#/view/pako:xyz'))).toBe(
|
||||
'/view#pako:xyz'
|
||||
);
|
||||
});
|
||||
|
||||
it('should default to edit when hash has no route', () => {
|
||||
expect(buildRedirectUrl(mockLocation('https://mermaid.live/#somethingelse'))).toBe('/edit');
|
||||
});
|
||||
|
||||
it('should handle multiple search params with hash', () => {
|
||||
expect(
|
||||
buildRedirectUrl(
|
||||
mockLocation(
|
||||
'https://mermaid.live/?utm_source=gh&utm_medium=link&utm_campaign=test#/edit/pako:data'
|
||||
)
|
||||
)
|
||||
).toBe('/edit?utm_source=gh&utm_medium=link&utm_campaign=test#pako:data');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import { resolve } from '$app/paths';
|
||||
|
||||
/**
|
||||
* Build the redirect URL for legacy root-path links.
|
||||
* Extracts the route and fragment from the old hash-based URL format,
|
||||
* and ensures search params (e.g. UTM) come before the hash fragment.
|
||||
*/
|
||||
export const buildRedirectUrl = (location: Location): string => {
|
||||
const parts = location.hash.split('/');
|
||||
let path = 'edit';
|
||||
let fragment = '';
|
||||
if (parts.length > 2) {
|
||||
path = parts[1];
|
||||
fragment = `#${parts[2]}`;
|
||||
}
|
||||
return `${resolve(`/${path}`, {})}${location.search}${fragment}`;
|
||||
};
|
||||
+15
-4
@@ -80,7 +80,7 @@ const processState = async (state: State) => {
|
||||
processed.error = error as Error;
|
||||
errorDebug();
|
||||
console.error(error);
|
||||
if ('hash' in error) {
|
||||
if (error && typeof error === 'object' && 'hash' in error) {
|
||||
try {
|
||||
let errorString = processed.error.toString();
|
||||
const errorLineText = extractErrorLineText(errorString);
|
||||
@@ -137,14 +137,25 @@ export const urlsStore = derived([stateStore], ([{ code, serialized }]) => {
|
||||
? `[](${window.location.protocol}//${window.location.host}${window.location.pathname}#${serialized})`
|
||||
: '',
|
||||
mermaidChart: ({
|
||||
medium
|
||||
medium,
|
||||
campaign
|
||||
}: {
|
||||
medium: 'ai_repair' | 'main_menu' | 'save_diagram' | 'share' | 'vibe_diagramming';
|
||||
medium:
|
||||
| 'ai_repair'
|
||||
| 'ai_edit'
|
||||
| 'main_menu'
|
||||
| 'save_diagram'
|
||||
| 'share'
|
||||
| 'vibe_diagramming'
|
||||
| 'visual_edit'
|
||||
| 'voice_edit';
|
||||
campaign?: string;
|
||||
}) => {
|
||||
const utmSource = getUTMSource();
|
||||
const params = new URLSearchParams({
|
||||
utm_source: utmSource,
|
||||
utm_medium: medium
|
||||
utm_medium: medium,
|
||||
...(campaign ? { utm_campaign: campaign } : {})
|
||||
}).toString();
|
||||
return {
|
||||
save: `${MCBaseURL}/app/plugin/save?state=${serialized}&${params}`,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
import { getAnalyticsSafeUrl } from './stats';
|
||||
|
||||
describe('getAnalyticsUrl', () => {
|
||||
beforeEach(() => {
|
||||
// Reset location to a clean state before each test
|
||||
window.history.replaceState(null, '', '/');
|
||||
});
|
||||
|
||||
it('should return origin and pathname for a simple URL', () => {
|
||||
window.history.replaceState(null, '', '/edit');
|
||||
const url = getAnalyticsSafeUrl();
|
||||
expect(url).toBe(`${window.location.origin}/edit`);
|
||||
});
|
||||
|
||||
it('should include search/query params (UTM parameters)', () => {
|
||||
window.history.replaceState(null, '', '/edit?utm_source=github&utm_medium=docs');
|
||||
const url = getAnalyticsSafeUrl();
|
||||
expect(url).toBe(`${window.location.origin}/edit?utm_source=github&utm_medium=docs`);
|
||||
});
|
||||
|
||||
it('should never include the hash', () => {
|
||||
window.history.replaceState(null, '', '/edit#pako:someDiagramData');
|
||||
// replaceState doesn't set hash, so set it via location
|
||||
window.location.hash = '#pako:someDiagramData';
|
||||
const url = getAnalyticsSafeUrl();
|
||||
expect(url).not.toContain('#');
|
||||
expect(url).not.toContain('pako:');
|
||||
expect(url).toBe(`${window.location.origin}/edit`);
|
||||
});
|
||||
|
||||
it('should include search params but exclude hash when both are present', () => {
|
||||
window.history.replaceState(null, '', '/edit?utm_campaign=launch');
|
||||
window.location.hash = '#pako:diagramDataHere';
|
||||
const url = getAnalyticsSafeUrl();
|
||||
expect(url).not.toContain('#');
|
||||
expect(url).not.toContain('pako:');
|
||||
expect(url).toContain('utm_campaign=launch');
|
||||
expect(url).toBe(`${window.location.origin}/edit?utm_campaign=launch`);
|
||||
});
|
||||
|
||||
it('should return just origin for root path with no params', () => {
|
||||
window.history.replaceState(null, '', '/');
|
||||
const url = getAnalyticsSafeUrl();
|
||||
expect(url).toBe(`${window.location.origin}/`);
|
||||
});
|
||||
});
|
||||
+10
-6
@@ -23,6 +23,15 @@ export const initAnalytics = async (): Promise<void> => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Build the current page URL for analytics tracking.
|
||||
* Includes origin, pathname, and search (for UTM params),
|
||||
* but never the hash (which contains diagram data).
|
||||
*/
|
||||
export const getAnalyticsSafeUrl = (): string => {
|
||||
return window.location.origin + window.location.pathname + window.location.search;
|
||||
};
|
||||
|
||||
export const countLines = (code: string): number => {
|
||||
return (code.match(/\n/g)?.length ?? 0) + 1;
|
||||
};
|
||||
@@ -91,7 +100,6 @@ const delaysPerEvent = {
|
||||
mermaidChartClick: noDelay,
|
||||
migration: defaultDelay,
|
||||
mobileViewToggle: defaultDelay,
|
||||
panZoom: minutesToMilliSeconds(10),
|
||||
pwaInstalled: defaultDelay,
|
||||
render: minutesToMilliSeconds(5),
|
||||
renderDiagram: defaultDelay,
|
||||
@@ -112,11 +120,7 @@ export const logEvent = (
|
||||
if (timeouts.has(key)) {
|
||||
clearTimeout(timeouts.get(key));
|
||||
} else {
|
||||
plausible.trackEvent(
|
||||
name,
|
||||
{ props: data },
|
||||
{ url: window.location.origin + window.location.pathname }
|
||||
);
|
||||
plausible.trackEvent(name, { props: data }, { url: getAnalyticsSafeUrl() });
|
||||
}
|
||||
timeouts.set(
|
||||
key,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { initLoading } from './loading';
|
||||
import { isOnMermaidAI } from './migration/domainMigration';
|
||||
import { applyMigrations } from './migrations';
|
||||
import { initURLSubscription, loadState, updateCodeStore, verifyState } from './state';
|
||||
import { initAnalytics, plausible } from './stats';
|
||||
import { getAnalyticsSafeUrl, initAnalytics, plausible } from './stats';
|
||||
|
||||
export const getDomain = (url?: string): string => {
|
||||
if (!url) return '';
|
||||
@@ -30,7 +30,9 @@ export const initHandler = async (): Promise<void> => {
|
||||
syncDiagram();
|
||||
initURLSubscription();
|
||||
await initAnalytics();
|
||||
plausible?.trackPageview({ url: window.location.origin + window.location.pathname });
|
||||
plausible?.trackPageview({
|
||||
url: getAnalyticsSafeUrl()
|
||||
});
|
||||
verifyState();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { buildRedirectUrl } from '$lib/util/redirect';
|
||||
import { onMount } from 'svelte';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
onMount(async () => {
|
||||
// Handle old live editor links and redirect to new version
|
||||
const hash = window.location.hash.split('/');
|
||||
let newURL = 'edit';
|
||||
if (hash.length > 2) {
|
||||
newURL = `${hash[1]}#${hash[2]}`;
|
||||
}
|
||||
await goto(`${base}/${newURL}`, {
|
||||
await goto(buildRedirectUrl(window.location), {
|
||||
replaceState: true
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import Card from '$/components/Card/Card.svelte';
|
||||
import DiagramDocButton from '$/components/DiagramDocumentationButton.svelte';
|
||||
import Editor from '$/components/Editor.svelte';
|
||||
import EnhancedEditsButton from '$/components/EnhancedEditsButton.svelte';
|
||||
import History from '$/components/History/History.svelte';
|
||||
import McWrapper from '$/components/McWrapper.svelte';
|
||||
import MermaidChartIcon from '$/components/MermaidChartIcon.svelte';
|
||||
@@ -136,6 +137,7 @@
|
||||
<Resizable.Handle class="mr-1 hidden opacity-0 sm:block" />
|
||||
<Resizable.Pane minSize={15} class="relative flex h-full flex-1 flex-col overflow-hidden">
|
||||
<View {panZoomState} shouldShowGrid={$stateStore.grid} />
|
||||
<div class="absolute top-0 left-5 hidden md:block"><EnhancedEditsButton /></div>
|
||||
<div class="absolute top-0 right-0"><PanZoomToolbar {panZoomState} /></div>
|
||||
<div class="absolute right-0 bottom-0"><VersionSecurityToolbar /></div>
|
||||
<div class="absolute bottom-0 left-0 sm:left-5"><SyncRoughToolbar /></div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
import 'dotenv/config';
|
||||
import { sveltePreprocess } from 'svelte-preprocess';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
@@ -10,6 +11,9 @@ const config = {
|
||||
alias: {
|
||||
'$/*': './src/lib/*'
|
||||
},
|
||||
paths: {
|
||||
base: process.env.MERMAID_BASE_PATH ?? ''
|
||||
},
|
||||
adapter: adapter({
|
||||
pages: 'docs',
|
||||
fallback: '404.html'
|
||||
|
||||
Reference in New Issue
Block a user