Merge branch 'master-holder'

* master-holder: (72 commits)
  Release 1.22.10
  Clipboard icon
  Release 1.22.10
  Space for tabs
  Release 1.22.10
  Nojekyll
  Release 1.22.10
  Fix path
  Release 1.22.10
  Disable jekyll
  Release 1.22.10
  Fix base path
  Release 1.22.10
  Hide editor on mobile
  Remove netlify
  Remove doce
  Try netlify
  Release 1.22.10
  Rename branch
  Deploy
  ...
This commit is contained in:
Sidharth Vinod
2021-05-23 00:55:03 +05:30
82 changed files with 4609 additions and 8 deletions
+20
View File
@@ -0,0 +1,20 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2019
},
env: {
browser: true,
es2017: true,
node: true
}
};
+2 -1
View File
@@ -19,7 +19,8 @@ jobs:
npm i -g yarn
yarn install
yarn version --patch --no-git-tag-version
yarn release
export CI=true
yarn build
git config user.name github-actions
git config user.email github-actions@github.com
git add .
+4 -1
View File
@@ -4,4 +4,7 @@ coverage/
build/
yarn-error.log
.npmrc
*node_modules*
.DS_Store
/.svelte-kit
/build
/functions
View File
+1
View File
@@ -0,0 +1 @@
engine-strict=true
+5 -1
View File
@@ -1 +1,5 @@
dist/
docs/**
.svelte-kit/**
static/**
build/**
node_modules/**
+6 -3
View File
@@ -1,5 +1,8 @@
{
"singleQuote": true,
"svelteSortOrder": "scripts-styles-markup",
"svelteBracketNewLine": false
"singleQuote": true,
"svelteSortOrder": "scripts-styles-markup",
"svelteBracketNewLine": false,
"useTabs": true,
"trailingComma": "none",
"printWidth": 100
}
+1 -2
View File
@@ -46,8 +46,7 @@ registry=https://registry.npmjs.com/
## Development
```
yarn dev
open http://localhost:8080
yarn dev -- --open
```
This app is created with Svelte + svelte-spa-router.
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
#menu-toggle.svelte-1q1rl80:checked+#menu.svelte-1q1rl80{display:block}.nav-btn.svelte-1q1rl80.svelte-1q1rl80{border-color:transparent}.nav-btn.svelte-1q1rl80.svelte-1q1rl80:hover{--tw-border-opacity:1;border-color:rgba(255,255,255,var(--tw-border-opacity))}.nav-btn.svelte-1q1rl80.svelte-1q1rl80{border-bottom-width:2px;display:block;padding:.75rem 0}@media(min-width:1024px){.nav-btn.svelte-1q1rl80.svelte-1q1rl80{padding:.5rem}}.isOpen.svelte-1j9xzww{transform:rotate(-90deg);transition-duration:.5s}.btn.svelte-1ygdo6x{background-color:rgba(129,140,248,var(--tw-bg-opacity))}.btn.svelte-1ygdo6x,.btn.svelte-1ygdo6x:hover{--tw-bg-opacity:1}.btn.svelte-1ygdo6x:hover{background-color:rgba(99,102,241,var(--tw-bg-opacity))}.btn.svelte-1ygdo6x{--tw-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06);--tw-text-opacity:1;border-radius:.25rem;box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow);color:rgba(255,255,255,var(--tw-text-opacity));flex:1 1 auto;padding:.5rem}.btn.svelte-15pcoti{background-color:rgba(99,102,241,var(--tw-bg-opacity))}.btn.svelte-15pcoti,.btn.svelte-15pcoti:hover{--tw-bg-opacity:1}.btn.svelte-15pcoti:hover{background-color:rgba(67,56,202,var(--tw-bg-opacity))}.btn.svelte-15pcoti{--tw-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06);border-radius:.25rem;box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow);padding-left:1rem;padding-right:1rem}
+1
View File
@@ -0,0 +1 @@
#svelte-announcer.svelte-1pdgbjn{clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;left:0;overflow:hidden;position:absolute;top:0;white-space:nowrap;width:1px}
+1
View File
@@ -0,0 +1 @@
#view.svelte-7vvt6c{border:1px #8b0000;flex:1}.error.svelte-7vvt6c,.outOfSync.svelte-7vvt6c{opacity:.5}
+1
View File
@@ -0,0 +1 @@
import{r as o}from"./singletons-bb9012b7.js";const n=async function(n,s){return o.goto(n,s,[])};export{n as g};
+1
View File
@@ -0,0 +1 @@
let s="",a="/.";function e(e){({base:s,assets:a}=e)}export{s as b,e as s};
+1
View File
@@ -0,0 +1 @@
let t;function a(a){t=a}export{a as i,t as r};
+1
View File
@@ -0,0 +1 @@
var e=Object.defineProperty,a=Object.prototype.hasOwnProperty,t=Object.getOwnPropertySymbols,n=Object.prototype.propertyIsEnumerable,o=(a,t,n)=>t in a?e(a,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[t]=n,r=(e,r)=>{for(var s in r||(r={}))a.call(r,s)&&o(e,s,r[s]);if(t)for(var s of t(r))n.call(r,s)&&o(e,s,r[s]);return e};import{a2 as s,a3 as i,C as c,a4 as l,a0 as d,a6 as u,a9 as p,S as f,i as h,s as m,e as y,c as g,a as v,d as b,b as w,O,f as S,F as E,G as x,a7 as D,z as C,a8 as T,J as j}from"./vendor-a9bf48e1.js";const J=s(c({code:"graph TD\n A[Christmas] --\x3e|Get money| B(Go shopping)\n B --\x3e C{Let me think}\n C --\x3e|One| D[Laptop]\n C --\x3e|Two| E[iPhone]\n C --\x3e|Three| F[fa:fa-car Car]\n ",mermaid:JSON.stringify({theme:"default"},null,2),updateEditor:!1,autoSync:!0,updateDiagram:!0}),i(),"codeStore"),N=l([J],(([e],a)=>{a(d(JSON.stringify(e),!0))})),P=e=>{J.update((a=>r(r({},a),e)))};let I=!1;const L=(e,a,t=!1)=>{if((e.match(/\n/g)||"").length+1>50&&!I&&u(J).autoSync){const e=confirm("Long diagram deteced. Turn off Auto Sync? Click the sync logo to manually sync.");I=!0,e&&P({autoSync:!1})}J.update((n=>r(r({},n),{code:e,updateEditor:a,updateDiagram:t})))},G=(e,a)=>{J.update((t=>r(r({},t),{mermaid:e,updateEditor:a})))},V=()=>JSON.stringify(u(J)),k=c(void 0);function z(e){let a,t;return{c(){a=y("div"),t=y("div"),this.h()},l(e){a=g(e,"DIV",{id:!0,class:!0});var n=v(a);t=g(n,"DIV",{id:!0,class:!0}),v(t).forEach(b),n.forEach(b),this.h()},h(){w(t,"id","container"),w(t,"class","flex-1 overflow-auto"),w(a,"id","view"),w(a,"class","p-2 svelte-7vvt6c"),O(a,"error",e[1]),O(a,"outOfSync",e[2])},m(n,o){S(n,a,o),E(a,t),e[3](t)},p(e,[t]){2&t&&O(a,"error",e[1]),4&t&&O(a,"outOfSync",e[2])},i:x,o:x,d(t){t&&b(a),e[3](null)}}}function A(e,a,t){let n;D(e,J,(e=>t(6,n=e)));var o=this&&this.__awaiter||function(e,a,t,n){return new(t||(t=Promise))((function(o,r){function s(e){try{c(n.next(e))}catch(a){r(a)}}function i(e){try{c(n.throw(e))}catch(a){r(a)}}function c(e){var a;e.done?o(e.value):(a=e.value,a instanceof t?a:new t((function(e){e(a)}))).then(s,i)}c((n=n.apply(e,a||[])).next())}))};const r=window.mermaid;let s,i="",c=!1,l=!1,d=!0;C((()=>o(void 0,void 0,void 0,(function*(){J.subscribe((e=>{try{if(s&&e&&(e.updateDiagram||e.autoSync)){e.autoSync||T(J,n.updateDiagram=!1,n),t(2,l=!1),d=!0,i=e.code;const a=s.parentElement.parentElement.parentElement.scrollTop;t(0,s.innerHTML=i,s),delete s.dataset.processed,r.initialize(Object.assign({},JSON.parse(e.mermaid))),r.init(s),r.render("graph-div",i,u),t(0,s.parentElement.parentElement.parentElement.scrollTop=a,s)}else d?d=!1:t(2,l=!0)}catch(a){console.log("view fail",a),t(1,c=!0)}})),k.subscribe((e=>{void 0===e?t(1,c=!1):(t(1,c=!0),console.log("Error: ",e))}))}))));const u=(e,a)=>{};return[s,c,l,function(e){j[e?"unshift":"push"]((()=>{s=e,t(0,s)}))}]}class B extends f{constructor(e){super(),h(this,e,A,z,m,{})}}const F=()=>{(e=>{let a;try{const t=p(e);console.log(`Tring to load state: ${t}`),a=JSON.parse(t)}catch(t){e&&console.error("Init error",t),a=u(J),console.log(a)}P(r(r({},a),{updateEditor:!0}))})(window.location.hash.slice(1))},_=()=>{P({updateDiagram:!0})},H=()=>{F(),_(),N.subscribe((e=>{window.location.hash=e}))};export{B as V,G as a,N as b,J as c,k as e,V as g,H as i,_ as s,L as u};
+1
View File
@@ -0,0 +1 @@
var e=Object.defineProperty,a=Object.prototype.hasOwnProperty,t=Object.getOwnPropertySymbols,n=Object.prototype.propertyIsEnumerable,o=(a,t,n)=>t in a?e(a,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[t]=n,r=(e,r)=>{for(var s in r||(r={}))a.call(r,s)&&o(e,s,r[s]);if(t)for(var s of t(r))n.call(r,s)&&o(e,s,r[s]);return e};import{a2 as s,a3 as i,C as c,a4 as l,a0 as d,a6 as u,a9 as p,S as f,i as h,s as m,e as y,c as v,a as g,d as b,b as w,O,f as S,F as E,G as x,a7 as D,z as C,a8 as T,J as j}from"./vendor-a9bf48e1.js";const J=s(c({code:"graph TD\n A[Christmas] --\x3e|Get money| B(Go shopping)\n B --\x3e C{Let me think}\n C --\x3e|One| D[Laptop]\n C --\x3e|Two| E[iPhone]\n C --\x3e|Three| F[fa:fa-car Car]\n ",mermaid:JSON.stringify({theme:"default"}),updateEditor:!1,autoSync:!0,updateDiagram:!0}),i(),"codeStore"),N=l([J],(([e],a)=>{a(d(JSON.stringify(e),!0))})),P=e=>{J.update((a=>r(r({},a),e)))};let I=!1;const L=(e,a,t=!1)=>{if((e.match(/\n/g)||"").length+1>50&&!I&&u(J).autoSync){const e=confirm("Long diagram deteced. Turn off Auto Sync? Click the sync logo to manually sync.");I=!0,e&&P({autoSync:!1})}J.update((n=>r(r({},n),{code:e,updateEditor:a,updateDiagram:t})))},G=(e,a)=>{J.update((t=>r(r({},t),{mermaid:e,updateEditor:a})))},V=()=>JSON.stringify(u(J)),k=c(void 0);function z(e){let a,t;return{c(){a=y("div"),t=y("div"),this.h()},l(e){a=v(e,"DIV",{id:!0,class:!0});var n=g(a);t=v(n,"DIV",{id:!0,class:!0}),g(t).forEach(b),n.forEach(b),this.h()},h(){w(t,"id","container"),w(t,"class","flex-1 overflow-auto"),w(a,"id","view"),w(a,"class","p-2 svelte-7vvt6c"),O(a,"error",e[1]),O(a,"outOfSync",e[2])},m(n,o){S(n,a,o),E(a,t),e[3](t)},p(e,[t]){2&t&&O(a,"error",e[1]),4&t&&O(a,"outOfSync",e[2])},i:x,o:x,d(t){t&&b(a),e[3](null)}}}function A(e,a,t){let n;D(e,J,(e=>t(6,n=e)));var o=this&&this.__awaiter||function(e,a,t,n){return new(t||(t=Promise))((function(o,r){function s(e){try{c(n.next(e))}catch(a){r(a)}}function i(e){try{c(n.throw(e))}catch(a){r(a)}}function c(e){var a;e.done?o(e.value):(a=e.value,a instanceof t?a:new t((function(e){e(a)}))).then(s,i)}c((n=n.apply(e,a||[])).next())}))};const r=window.mermaid;let s,i="",c=!1,l=!1,d=!0;C((()=>o(void 0,void 0,void 0,(function*(){J.subscribe((e=>{try{if(s&&e&&(e.updateDiagram||e.autoSync)){e.autoSync||T(J,n.updateDiagram=!1,n),t(2,l=!1),d=!0,i=e.code;const a=s.parentElement.parentElement.parentElement.scrollTop;t(0,s.innerHTML=i,s),delete s.dataset.processed,r.initialize(Object.assign({},JSON.parse(e.mermaid))),r.init(s),r.render("graph-div",i,u),t(0,s.parentElement.parentElement.parentElement.scrollTop=a,s)}else d?d=!1:t(2,l=!0)}catch(a){console.log("view fail",a),t(1,c=!0)}})),k.subscribe((e=>{void 0===e?t(1,c=!1):(t(1,c=!0),console.log("Error: ",e))}))}))));const u=(e,a)=>{};return[s,c,l,function(e){j[e?"unshift":"push"]((()=>{s=e,t(0,s)}))}]}class B extends f{constructor(e){super(),h(this,e,A,z,m,{})}}const F=()=>{(e=>{let a;try{const t=p(e);a=JSON.parse(t)}catch(t){console.error("Init error",t),a=u(J)}P(r(r({},a),{updateEditor:!0}))})(window.location.hash.slice(1))},_=()=>{P({updateDiagram:!0})},H=()=>{F(),_(),N.subscribe((e=>{window.location.hash=e}))};export{B as V,G as a,N as b,J as c,k as e,V as g,H as i,_ as s,L as u};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{S as s,i as r,s as a,e as t,t as e,c as o,a as n,g as c,d as u,f as p,F as f,h as l,k as i,l as d,n as m,G as h}from"./chunks/vendor-a9bf48e1.js";function k(s){let r,a,i=s[1].stack+"";return{c(){r=t("pre"),a=e(i)},l(s){r=o(s,"PRE",{});var t=n(r);a=c(t,i),t.forEach(u)},m(s,t){p(s,r,t),f(r,a)},p(s,r){2&r&&i!==(i=s[1].stack+"")&&l(a,i)},d(s){s&&u(r)}}}function v(s){let r,a,v,E,g,x,P,$=s[1].message+"",b=s[1].stack&&k(s);return{c(){r=t("h1"),a=e(s[0]),v=i(),E=t("p"),g=e($),x=i(),b&&b.c(),P=d()},l(t){r=o(t,"H1",{});var e=n(r);a=c(e,s[0]),e.forEach(u),v=m(t),E=o(t,"P",{});var p=n(E);g=c(p,$),p.forEach(u),x=m(t),b&&b.l(t),P=d()},m(s,t){p(s,r,t),f(r,a),p(s,v,t),p(s,E,t),f(E,g),p(s,x,t),b&&b.m(s,t),p(s,P,t)},p(s,[r]){1&r&&l(a,s[0]),2&r&&$!==($=s[1].message+"")&&l(g,$),s[1].stack?b?b.p(s,r):(b=k(s),b.c(),b.m(P.parentNode,P)):b&&(b.d(1),b=null)},i:h,o:h,d(s){s&&u(r),s&&u(v),s&&u(E),s&&u(x),b&&b.d(s),s&&u(P)}}}function E({error:s,status:r}){return{props:{error:s,status:r}}}function g(s,r,a){let{status:t}=r,{error:e}=r;return s.$$set=s=>{"status"in s&&a(0,t=s.status),"error"in s&&a(1,e=s.error)},[t,e]}export default class extends s{constructor(s){super(),r(this,s,g,v,a,{status:0,error:1})}}export{E as load};
@@ -0,0 +1 @@
import{S as s,i as a,s as e,D as t,e as l,c as n,a as c,d as o,b as r,f as u,E as i,v as $,r as h}from"../chunks/vendor-a9bf48e1.js";function f(s){let a,e;const f=s[1].default,p=t(f,s,s[0],null);return{c(){a=l("main"),p&&p.c(),this.h()},l(s){a=n(s,"MAIN",{class:!0});var e=c(a);p&&p.l(e),e.forEach(o),this.h()},h(){r(a,"class","h-screen")},m(s,t){u(s,a,t),p&&p.m(a,null),e=!0},p(s,[a]){p&&p.p&&(!e||1&a)&&i(p,f,s,s[0],a,null,null)},i(s){e||($(p,s),e=!0)},o(s){h(p,s),e=!1},d(s){s&&o(a),p&&p.d(s)}}}function p(s,a,e){let{$$slots:t={},$$scope:l}=a;return s.$$set=s=>{"$$scope"in s&&e(0,l=s.$$scope)},[l,t]}export default class extends s{constructor(s){super(),a(this,s,p,f,e,{})}}
@@ -0,0 +1 @@
import{S as s,i as a,s as e,D as t,e as l,c as n,a as c,d as o,b as r,f as u,E as i,v as $,r as h}from"../chunks/vendor-a9bf48e1.js";function f(s){let a,e;const f=s[1].default,p=t(f,s,s[0],null);return{c(){a=l("main"),p&&p.c(),this.h()},l(s){a=n(s,"MAIN",{class:!0});var e=c(a);p&&p.l(e),e.forEach(o),this.h()},h(){r(a,"class","h-screen")},m(s,t){u(s,a,t),p&&p.m(a,null),e=!0},p(s,[a]){p&&p.p&&(!e||1&a)&&i(p,f,s,s[0],a,null,null)},i(s){e||($(p,s),e=!0)},o(s){h(p,s),e=!1},d(s){s&&o(a),p&&p.d(s)}}}function p(s,a,e){let{$$slots:t={},$$scope:l}=a;return s.$$set=s=>{"$$scope"in s&&e(0,l=s.$$scope)},[l,t]}export default class extends s{constructor(s){super(),a(this,s,p,f,e,{})}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{S as t,i as n,s as e,H as i,d as o,G as s,z as a}from"../chunks/vendor-a9bf48e1.js";import{g as c}from"../chunks/navigation-20968cc5.js";import{b as r}from"../chunks/paths-45dac81d.js";import"../chunks/singletons-bb9012b7.js";function u(t){return{c(){this.h()},l(t){i('[data-svelte="svelte-wtz6kg"]',document.head).forEach(o),this.h()},h(){document.title="Mermaid Live Editor"},m:s,p:s,i:s,o:s,d:s}}function h(t){var n=this&&this.__awaiter||function(t,n,e,i){return new(e||(e=Promise))((function(o,s){function a(t){try{r(i.next(t))}catch(n){s(n)}}function c(t){try{r(i.throw(t))}catch(n){s(n)}}function r(t){var n;t.done?o(t.value):(n=t.value,n instanceof e?n:new e((function(t){t(n)}))).then(a,c)}r((i=i.apply(t,n||[])).next())}))};return a((()=>n(void 0,void 0,void 0,(function*(){const t=window.location.hash.split("/");let n="edit";t.length>2&&(n=`${t[1]}#${t[2]}`),yield c(`${r}/${n}`,{replaceState:!0})})))),[]}export default class extends t{constructor(t){super(),n(this,t,h,u,e,{})}}
+1
View File
@@ -0,0 +1 @@
import{S as t,i as n,s as e,H as i,d as o,G as s,z as a}from"../chunks/vendor-a9bf48e1.js";import{g as c}from"../chunks/navigation-20968cc5.js";import"../chunks/singletons-bb9012b7.js";function r(t){return{c(){this.h()},l(t){i('[data-svelte="svelte-wtz6kg"]',document.head).forEach(o),this.h()},h(){document.title="Mermaid Live Editor"},m:s,p:s,i:s,o:s,d:s}}function u(t){var n=this&&this.__awaiter||function(t,n,e,i){return new(e||(e=Promise))((function(o,s){function a(t){try{r(i.next(t))}catch(n){s(n)}}function c(t){try{r(i.throw(t))}catch(n){s(n)}}function r(t){var n;t.done?o(t.value):(n=t.value,n instanceof e?n:new e((function(t){t(n)}))).then(a,c)}r((i=i.apply(t,n||[])).next())}))};return a((()=>n(void 0,void 0,void 0,(function*(){const t=window.location.hash.split("/");let n="/edit";t.length>2&&(n=`/${t[1]}#${t[2]}`),yield c(n,{replaceState:!0})})))),[]}export default class extends t{constructor(t){super(),n(this,t,u,r,e,{})}}
+1
View File
@@ -0,0 +1 @@
import{S as s,i as a,s as r,j as t,m as n,o as e,G as o,v as f,r as m,w as u,z as i}from"../chunks/vendor-a9bf48e1.js";import{V as c,i as $}from"../chunks/util-bfd89a15.js";function d(s){let a,r;return a=new c({}),{c(){t(a.$$.fragment)},l(s){n(a.$$.fragment,s)},m(s,t){e(a,s,t),r=!0},p:o,i(s){r||(f(a.$$.fragment,s),r=!0)},o(s){m(a.$$.fragment,s),r=!1},d(s){u(a,s)}}}function l(s){return i($),[]}export default class extends s{constructor(s){super(),a(this,s,l,d,r,{})}}
+1
View File
@@ -0,0 +1 @@
import{S as s,i as a,s as r,j as t,m as e,o as n,G as f,v as o,r as m,w as u,z as i}from"../chunks/vendor-a9bf48e1.js";import{V as c,i as $}from"../chunks/util-fb52efd4.js";function d(s){let a,r;return a=new c({}),{c(){t(a.$$.fragment)},l(s){e(a.$$.fragment,s)},m(s,t){n(a,s,t),r=!0},p:f,i(s){r||(o(a.$$.fragment,s),r=!0)},o(s){m(a.$$.fragment,s),r=!1},d(s){u(a,s)}}}function l(s){return i($),[]}export default class extends s{constructor(s){super(),a(this,s,l,d,r,{})}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Online FlowChart &amp; Diagrams Editor - Mermaid Live Editor</title>
<meta
name="og:image"
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png"
/>
<link rel="canonical" href="https://mermaid-js.github.io/mermaid-live-editor/" />
<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."
/>
<link rel="icon" type="image/png" href="favicon.png" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
/>
<script
src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js"
integrity="sha256-aQCGsx3/OLAXwNyOUrAedielIQAjIrMFkcWdXMlIkGc="
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css"
integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<script>
var require = {
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }
};
</script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js"
integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.nls.min.js"
integrity="sha512-3aAqsDS5ClTlwyzxufRhW9WMwZlYn3V8GLRl324pMIftp+CA6kvxfjlm8TG7Wi53eBcerEdX0YfXm3QLvf1Pqg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.js"
integrity="sha512-sOJZBKiSvh/6vxIimdXkjO45Nd3v2n3ZYtrwktgj5SJh0+PCqNQ5oqzxEr6c/o4ULczn1Wo2yh1qrz+ghduDUA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/start-6a449612.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/vendor-a9bf48e1.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/singletons-bb9012b7.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/paths-45dac81d.js">
<link rel="stylesheet" href="/mermaid-svelte-kit/_app/assets/start-0826e215.css">
<script type="module">
import { start } from "/mermaid-svelte-kit/_app/start-6a449612.js";
start({
target: document.querySelector("#svelte"),
paths: {"base":"/mermaid-svelte-kit","assets":"/mermaid-svelte-kit"},
session: {},
host: location.host,
route: true,
spa: true,
hydrate: null
});
</script>
</head>
<body>
<div id="svelte">
</div>
</body>
</html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Online FlowChart &amp; Diagrams Editor - Mermaid Live Editor</title>
<meta
name="og:image"
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png"
/>
<link rel="canonical" href="https://mermaid-js.github.io/mermaid-live-editor/" />
<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."
/>
<link rel="icon" type="image/png" href="favicon.png" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
/>
<script
src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js"
integrity="sha256-aQCGsx3/OLAXwNyOUrAedielIQAjIrMFkcWdXMlIkGc="
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css"
integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<script>
var require = {
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }
};
</script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js"
integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.nls.min.js"
integrity="sha512-3aAqsDS5ClTlwyzxufRhW9WMwZlYn3V8GLRl324pMIftp+CA6kvxfjlm8TG7Wi53eBcerEdX0YfXm3QLvf1Pqg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.js"
integrity="sha512-sOJZBKiSvh/6vxIimdXkjO45Nd3v2n3ZYtrwktgj5SJh0+PCqNQ5oqzxEr6c/o4ULczn1Wo2yh1qrz+ghduDUA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/start-6a449612.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/vendor-a9bf48e1.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/singletons-bb9012b7.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/paths-45dac81d.js">
<link rel="stylesheet" href="/mermaid-svelte-kit/_app/assets/start-0826e215.css">
<script type="module">
import { start } from "/mermaid-svelte-kit/_app/start-6a449612.js";
start({
target: document.querySelector("#svelte"),
paths: {"base":"/mermaid-svelte-kit","assets":"/mermaid-svelte-kit"},
session: {},
host: location.host,
route: true,
spa: true,
hydrate: null
});
</script>
</head>
<body>
<div id="svelte">
</div>
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Online FlowChart &amp; Diagrams Editor - Mermaid Live Editor</title>
<meta
name="og:image"
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png"
/>
<link rel="canonical" href="https://mermaid-js.github.io/mermaid-live-editor/" />
<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."
/>
<link rel="icon" type="image/png" href="favicon.png" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
/>
<script
src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js"
integrity="sha256-aQCGsx3/OLAXwNyOUrAedielIQAjIrMFkcWdXMlIkGc="
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css"
integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<script>
var require = {
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }
};
</script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js"
integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.nls.min.js"
integrity="sha512-3aAqsDS5ClTlwyzxufRhW9WMwZlYn3V8GLRl324pMIftp+CA6kvxfjlm8TG7Wi53eBcerEdX0YfXm3QLvf1Pqg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.js"
integrity="sha512-sOJZBKiSvh/6vxIimdXkjO45Nd3v2n3ZYtrwktgj5SJh0+PCqNQ5oqzxEr6c/o4ULczn1Wo2yh1qrz+ghduDUA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/start-6a449612.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/vendor-a9bf48e1.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/singletons-bb9012b7.js">
<link rel="modulepreload" href="/mermaid-svelte-kit/_app/chunks/paths-45dac81d.js">
<link rel="stylesheet" href="/mermaid-svelte-kit/_app/assets/start-0826e215.css">
<script type="module">
import { start } from "/mermaid-svelte-kit/_app/start-6a449612.js";
start({
target: document.querySelector("#svelte"),
paths: {"base":"/mermaid-svelte-kit","assets":"/mermaid-svelte-kit"},
session: {},
host: location.host,
route: true,
spa: true,
hydrate: null
});
</script>
</head>
<body>
<div id="svelte">
</div>
</body>
</html>
+46
View File
@@ -0,0 +1,46 @@
{
"name": "~TODO~",
"version": "0.0.9",
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build",
"preview": "svelte-kit preview",
"lint": "prettier --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
"format": "prettier --write --plugin-search-dir=. ."
},
"devDependencies": {
"@sveltejs/adapter-static": "^1.0.0-next.11",
"@sveltejs/kit": "next",
"@types/mermaid": "^8.2.5",
"@typescript-eslint/eslint-plugin": "^4.19.0",
"@typescript-eslint/parser": "^4.19.0",
"autoprefixer": "^10.2.5",
"cssnano": "^5.0.1",
"eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-svelte3": "^3.2.0",
"postcss": "^8.2.10",
"postcss-load-config": "^3.0.1",
"prettier": "~2.2.1",
"prettier-plugin-svelte": "^2.2.0",
"svelte": "^3.34.0",
"svelte-preprocess": "^4.7.1",
"tailwindcss": "^2.1.1",
"tslib": "^2.0.0",
"typescript": "^4.0.0"
},
"type": "module",
"dependencies": {
"@fontsource/fira-mono": "^4.2.2",
"@lukeed/uuid": "^2.0.0",
"@macfja/svelte-persistent-store": "^1.1.0",
"@tailwindcss/forms": "^0.3.2",
"cookie": "^0.4.1",
"js-base64": "https://github.com/sidharthv96/js-base64#patch-1",
"mermaid": "^8.10.1",
"moment": "^2.29.1",
"monaco-editor": "^0.24.0",
"random-word-slugs": "^0.0.2",
"svelte-watch-resize": "^1.0.3"
}
}
+22
View File
@@ -0,0 +1,22 @@
const tailwindcss = require("tailwindcss");
const autoprefixer = require("autoprefixer");
const cssnano = require("cssnano");
const mode = process.env.NODE_ENV;
const dev = mode === "development";
module.exports = {
plugins: [
// Some plugins, like postcss-nested, need to run before Tailwind
tailwindcss,
// But others, like autoprefixer, need to run after
autoprefixer,
!dev && cssnano({
preset: "default",
}),
],
};
+61
View File
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Online FlowChart &amp; Diagrams Editor - Mermaid Live Editor</title>
<meta
name="og:image"
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png"
/>
<link rel="canonical" href="https://mermaid-js.github.io/mermaid-live-editor/" />
<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."
/>
<link rel="icon" type="image/png" href="favicon.png" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
/>
<script
src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js"
integrity="sha256-aQCGsx3/OLAXwNyOUrAedielIQAjIrMFkcWdXMlIkGc="
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css"
integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<script>
var require = {
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }
};
</script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js"
integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.nls.min.js"
integrity="sha512-3aAqsDS5ClTlwyzxufRhW9WMwZlYn3V8GLRl324pMIftp+CA6kvxfjlm8TG7Wi53eBcerEdX0YfXm3QLvf1Pqg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.js"
integrity="sha512-sOJZBKiSvh/6vxIimdXkjO45Nd3v2n3ZYtrwktgj5SJh0+PCqNQ5oqzxEr6c/o4ULczn1Wo2yh1qrz+ghduDUA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
%svelte.head%
</head>
<body>
<div id="svelte">%svelte.body%</div>
</body>
</html>
+4
View File
@@ -0,0 +1,4 @@
@import '@fontsource/fira-mono';
@tailwind base;
@tailwind components;
@tailwind utilities;
+33
View File
@@ -0,0 +1,33 @@
/// <reference types="@sveltejs/kit" />
interface EditorUpdateEvent {
text: string;
}
interface EditorEvents {
update: EditorUpdateEvent;
}
interface TabEvents {
select: Tab;
}
interface Tab {
id: string;
title: string;
icon: string;
}
interface State {
code: string;
mermaid: string;
updateEditor: boolean;
updateDiagram: boolean;
autoSync: boolean;
}
interface HistoryEntry {
state: State;
time: number;
name?: string;
auto: boolean;
}
+23
View File
@@ -0,0 +1,23 @@
import cookie from 'cookie';
import { v4 as uuid } from '@lukeed/uuid';
import type { Handle } from '@sveltejs/kit';
export const handle: Handle = async ({ request, render }) => {
const cookies = cookie.parse(request.headers.cookie || '');
request.locals.userid = cookies.userid || uuid();
// TODO https://github.com/sveltejs/kit/issues/1046
if (request.query.has('_method')) {
request.method = request.query.get('_method').toUpperCase();
}
const response = await render(request);
if (!cookies.userid) {
// if this is the first time the user has visited this app,
// set a cookie so that we recognise them when they return
response.headers['set-cookie'] = `userid=${request.locals.userid}; Path=/; HttpOnly`;
}
return response;
};
+168
View File
@@ -0,0 +1,168 @@
<script lang="ts">
import Card from '$lib/components/card/card.svelte';
import { base64State } from '$lib/util/state';
import { toBase64 } from 'js-base64';
import moment from 'moment';
type Exporter = (
canvas: HTMLCanvasElement,
context: CanvasRenderingContext2D,
image: HTMLImageElement
) => () => void;
const getBase64SVG = (): string => {
const container: HTMLElement = document.getElementById('container');
const svg = container.innerHTML.replaceAll('<br>', '<br/>');
return toBase64(svg);
};
const exportImage = (event: Event, exporter: Exporter) => {
const canvas: HTMLCanvasElement = document.createElement('canvas');
const svg: HTMLElement = document.querySelector('#container svg');
debugger;
const box: DOMRect = svg.getBoundingClientRect();
canvas.width = box.width;
canvas.height = box.height;
if (imagemodeselected === 'width') {
const ratio = box.height / box.width;
canvas.width = userimagesize;
canvas.height = userimagesize * ratio;
} else if (imagemodeselected === 'height') {
const ratio = box.width / box.height;
canvas.width = userimagesize * ratio;
canvas.height = userimagesize;
}
const context = canvas.getContext('2d');
context.fillStyle = 'white';
context.fillRect(0, 0, canvas.width, canvas.height);
const image = new Image();
image.onload = exporter(canvas, context, image);
image.src = `data:image/svg+xml;base64,${getBase64SVG()}`;
event.stopPropagation();
event.preventDefault();
};
const simulateDownload = (download: string, href: string): void => {
const a = document.createElement('a');
a.download = download;
a.href = href;
a.click();
a.remove();
};
const downloadImage: Exporter = (canvas, context, image) => {
return () => {
context.drawImage(image, 0, 0, canvas.width, canvas.height);
simulateDownload(
`mermaid-diagram-${moment().format('YYYYMMDDHHmmss')}.png`,
canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')
);
};
};
const isClipboardAvailable = () => {
return window?.hasOwnProperty('ClipboardItem');
};
const clipboardCopy: Exporter = (canvas, context, image) => {
return () => {
context.drawImage(image, 0, 0, canvas.width, canvas.height);
canvas.toBlob((blob) => {
try {
// @ts-ignore
navigator.clipboard.write([
// @ts-ignore
new ClipboardItem({
[blob.type]: blob
})
]);
} catch (error) {
console.error(error);
}
});
};
};
const onCopyClipboard = (event) => {
exportImage(event, clipboardCopy);
};
const onDownloadPNG = (event) => {
exportImage(event, downloadImage);
};
const onDownloadSVG = (event) => {
simulateDownload(
`mermaid-diagram-${moment().format('YYYYMMDDHHmmss')}.svg`,
`data:image/svg+xml;base64,${getBase64SVG()}`
);
};
const onCopyMarkdown = (event) => {
event.target.select();
document.execCommand('Copy');
};
let iUrl;
let svgUrl;
let mdCode;
let imagemodeselected = 'auto';
let userimagesize = 1080;
const unsubscribe = base64State.subscribe((b64Code) => {
iUrl = `https://mermaid.ink/img/${b64Code}`;
svgUrl = `https://mermaid.ink/svg/${b64Code}`;
mdCode = `[![](${iUrl})](${window.location.protocol}//${window.location.host}${window.location.pathname}/edit#${b64Code})`;
});
</script>
<Card title="Actions" isOpen={false}>
<div class="flex flex-wrap gap-2 m-2">
{#if isClipboardAvailable()}
<button class="btn w-full" on:click={onCopyClipboard}
><i class="far fa-copy" /> Copy Image to clipboard
</button>
{/if}
<button class="btn flex-auto" on:click={onDownloadPNG}>
<i class="fas fa-download" /> PNG
</button>
<button class="btn flex-auto" on:click={onDownloadSVG}>
<i class="fas fa-download" /> SVG
</button>
<button class="btn flex-auto">
<a class="link-style" target="_blank" href={iUrl}
><i class="fas fa-external-link-alt" /> PNG</a>
</button>
<button class="btn flex-auto">
<a class="link-style" target="_blank" href={svgUrl}
><i class="fas fa-external-link-alt" /> SVG</a>
</button>
<div class="flex gap-2 items-center">
PNG size
<input type="radio" value="auto" id="autosize" bind:group={imagemodeselected} />
<label for="autosize">Auto</label>
<input type="radio" value="width" id="width-active" bind:group={imagemodeselected} />
<label for="width">Width</label>
<input type="radio" value="height" id="height-active" bind:group={imagemodeselected} />
<label for="height">Height</label>
{#if imagemodeselected !== 'auto'}
<input id="height" type="number" min="3" max="10000" bind:value={userimagesize} />
{/if}
</div>
<div class="w-full flex gap-2 items-center">
<label for="markdown">Copy Markdown</label>
<input class="flex-1" id="markdown" type="text" value={mdCode} on:click={onCopyMarkdown} />
</div>
</div>
</Card>
<style>
.btn {
@apply rounded p-2 bg-indigo-400 shadow flex-auto text-white hover:bg-indigo-500;
}
</style>
+25
View File
@@ -0,0 +1,25 @@
<script lang="ts">
import { slide } from 'svelte/transition';
import Tabs from './tabs.svelte';
export let isCloseable: boolean = true;
export let isOpen: boolean = true;
export let tabs: Tab[] = [];
export let title: string;
$: isOpen = isCloseable ? isOpen : true;
</script>
<div class={`bg-white rounded overflow-hidden shadow m-2 flex-grow flex flex-col `}>
<div class="bg-indigo-400 border-gray-400 p-2 flex-none" on:click={() => (isOpen = !isOpen)}>
<div class="flex justify-between">
<Tabs on:select {tabs} bind:isOpen {title} {isCloseable} />
<div class="flex gap-x-4 items-center text-white">
<slot name="actions" />
</div>
</div>
</div>
{#if isOpen}
<div class="flex-grow overflow-auto" transition:slide>
<slot />
</div>
{/if}
</div>
+64
View File
@@ -0,0 +1,64 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
export let isCloseable: boolean = true;
export let tabs: Tab[] = [];
export let title: string;
export let isOpen = false;
let activeTabID: string = tabs[0]?.id;
const dispatch = createEventDispatcher<TabEvents>();
const toggleTabs = (tab: Tab) => {
activeTabID = tab.id;
dispatch('select', tab);
};
</script>
<div class="flex cursor-default">
<span class="text-white mr-2 font-semibold" on:click|stopPropagation={() => (isOpen = !isOpen)}>
{#if isCloseable}
<svg
class="inline"
class:isOpen
xmlns="http://www.w3.org/2000/svg"
width="12"
height="7"
viewBox="0 0 12 7"
><defs
><style>
.cls-1 {
fill: #fff;
fill-rule: evenodd;
}
</style></defs
><path
class="cls-1"
d="M10.38.45,6,4.83,1.56.39h0A.84.84,0,0,0,.38,1.57h0l5,5h0a.83.83,0,0,0,.6.26H6a.83.83,0,0,0,.6-.26h0l5-5h0A.84.84,0,1,0,10.38.45Z" /></svg>
{/if}
{title}</span>
{#if isOpen && tabs}
<ul class="flex flex-wrap flex-row" transition:fade>
{#each tabs as tab}
<li class="mr-2 last:mr-0 w-28 flex-auto text-center">
<div
class="text cursor-pointer font-semibold min-w-16 w-auto px-2 py-1 -mb-4 rounded-t block leading-normal {activeTabID ===
tab.id
? 'text-indigo-500 bg-white border-white'
: 'text-white bg-indigo-500 border-indigo-500 hover:bg-indigo-600'}"
on:click|stopPropagation={() => toggleTabs(tab)}>
<i class={tab.icon} />
{tab.title}
</div>
</li>
{/each}
</ul>
{/if}
</div>
<style>
.isOpen {
transform: rotate(-90deg);
transition-duration: 0.5s;
}
</style>
+56
View File
@@ -0,0 +1,56 @@
<script lang="ts">
import type monaco from 'monaco-editor';
import { createEventDispatcher, onMount } from 'svelte';
import { initEditor } from './util';
let divEl: HTMLDivElement = null;
let editor: monaco.editor.IStandaloneCodeEditor;
let Monaco;
export let text: string;
export let language: string;
export let editorOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
value: text,
language: language,
scrollBeyondLastLine: false,
minimap: {
enabled: false
},
overviewRulerLanes: 0
};
export let errorMarkers: monaco.editor.IMarkerData[] = [];
$: Monaco?.editor.setModelLanguage(editor.getModel(), language);
$: editor?.setValue(text);
$: {
Monaco?.editor.setModelMarkers(editor.getModel(), 'test', errorMarkers);
}
const dispatch = createEventDispatcher<EditorEvents>();
onMount(async () => {
//@ts-ignore
Monaco = monaco; // This is a hack to handle a svelte-kit error when importing monaco.
initEditor(Monaco);
editor = Monaco.editor.create(divEl, editorOptions);
editor.onDidChangeModelContent(async () => {
dispatch('update', {
text: editor.getValue()
});
});
const resizeObserver = new ResizeObserver((entries) => {
editor.layout({
height: entries[0].contentRect.height,
width: entries[0].contentRect.width
});
});
resizeObserver.observe(divEl.parentElement);
return () => {
editor.dispose();
};
});
</script>
<div bind:this={divEl} class="overflow-hidden" />
+71
View File
@@ -0,0 +1,71 @@
export const initEditor = (monaco) => {
monaco.languages.register({ id: 'mermaid' });
// Register a tokens provider for the language
monaco.languages.setMonarchTokensProvider('mermaid', {
typeKeywords: [
'graph',
'stateDiagram',
'sequenceDiagram',
'classDiagram',
'pie',
'flowchart',
'gantt'
],
keywords: ['patricipant', 'as'],
arrows: ['---', '===', '-->', '==>'],
tokenizer: {
root: [
[/[{}]/, 'delimiter.bracket'],
[/[a-z_$][\w$]*/, { cases: { '@typeKeywords': 'keyword', '@keywords': 'keyword' } }],
[/[-=>ox]+/, { cases: { '@arrows': 'transition' } }],
[/[\[\{\(}]+.+?[\)\]\}]+/, 'string'],
[/\".*\"/, 'string']
]
},
whitespace: [
[/[ \t\r\n]+/, 'white'],
[/\%\%.*$/, 'comment']
]
});
monaco.editor.defineTheme('myCoolTheme', {
base: 'vs',
inherit: false,
rules: [
{ token: 'keyword', foreground: '880000', fontStyle: 'bold' },
{ token: 'custom-error', foreground: 'ff0000', fontStyle: 'bold' },
{ token: 'string', foreground: 'AA8500' },
{ token: 'transition', foreground: '008800', fontStyle: 'bold' },
{ token: 'delimiter.bracket', foreground: '000000', fontStyle: 'bold' }
]
});
// Register a completion item provider for the new language
monaco.languages.registerCompletionItemProvider('mermaid', {
provideCompletionItems: () => {
var suggestions = [
{
label: 'simpleText',
kind: monaco.languages.CompletionItemKind.Text,
insertText: 'simpleText'
},
{
label: 'testing',
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: 'testing(${1:condition})',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
},
{
label: 'ifelse',
kind: monaco.languages.CompletionItemKind.Snippet,
insertText: ['if (${1:condition}) {', '\t$0', '} else {', '\t', '}'].join('\n'),
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
documentation: 'If-Else Statement'
}
];
return { suggestions: suggestions };
}
});
};
+110
View File
@@ -0,0 +1,110 @@
<script lang="ts">
import Card from '$lib/components/card/card.svelte';
import { codeStore, getStateString } from '$lib/util/state';
import {
addHistoryEntry,
autoHistoryMode,
clearHistoryData,
getPreviousState,
historyStore
} from './history';
import { notify, prompt } from '$lib/util/notify';
import { onMount } from 'svelte';
import moment from 'moment';
const HISTORY_SAVE_INTERVAL: number = 60000;
const tabSelectHandler = (message: CustomEvent<Tab>) => {
autoHistoryMode.set('timeline' === message.detail.id);
};
const tabs: Tab[] = [
{
id: 'saved',
title: 'Saved',
icon: 'far fa-bookmark'
},
{
id: 'timeline',
title: 'Timeline',
icon: 'fas fa-history'
}
];
const saveHistory = (auto = false) => {
const currentState: string = getStateString();
const previousState: string = getPreviousState(auto);
if (previousState !== currentState) {
addHistoryEntry({
state: $codeStore,
time: Date.now(),
auto
});
} else if (!auto) {
notify('State already saved.');
}
};
const clearHistory = (date?: number): void => {
if (!date && !prompt('Clear all saved items?')) {
return;
}
clearHistoryData(date);
};
const restoreHistory = (state: State): void => {
codeStore.set({ ...state, updateEditor: true, updateDiagram: true });
};
const relativeTime = (time: number) => {
const t = new Date(time);
return `${new Date(t).toLocaleString()} (${moment(t).fromNow()})`;
};
onMount(() => {
autoHistoryMode.set(false);
setInterval(() => {
saveHistory(true);
}, HISTORY_SAVE_INTERVAL);
});
let isOpen = true;
</script>
<Card on:select={tabSelectHandler} bind:isOpen {tabs} title="History">
<div slot="actions">
<button class="btn" on:click|stopPropagation={() => saveHistory()} title="Save current state"
><i class="far fa-save" /></button>
<button
class="btn text-red-400"
on:click|stopPropagation={() => clearHistory()}
title="Delete all saved states"><i class="fas fa-trash-alt" /></button>
</div>
<ul class="p-2 space-y-2 overflow-auto h-56">
{#each $historyStore as { state, time, name }}
<li class="rounded p-2 shadow flex-col">
<div class="flex">
<div class="flex-1">
<div class="flex flex-col">
<span>{name}</span>
<span class="text-gray-400 text-sm">{relativeTime(time)}</span>
</div>
</div>
<div class="flex gap-2 content-center">
<button
class="rounded px-2 w-24 bg-green-200 hover:bg-green-300"
on:click={() => restoreHistory(state)}><i class="fas fa-undo" /> Restore</button>
<button
class="rounded px-2 w-24 bg-red-200 hover:bg-red-300"
on:click={() => clearHistory(time)}><i class="fas fa-trash-alt" /> Delete</button>
</div>
</div>
</li>
{/each}
</ul>
</Card>
<style lang="postcss">
.btn {
@apply bg-indigo-500 hover:bg-indigo-700 rounded px-4 shadow;
}
</style>
+55
View File
@@ -0,0 +1,55 @@
import { derived, Readable, Writable, writable, get } from 'svelte/store';
import { persist, localStorage } from '@macfja/svelte-persistent-store';
import { generateSlug } from 'random-word-slugs';
const MAX_AUTO_HISTORY_LENGTH = 30;
export const autoHistoryMode: Writable<boolean> = persist(
writable(true),
localStorage(),
'autoHistoryMode'
);
const autoHistoryStore: Writable<HistoryEntry[]> = persist(
writable([]),
localStorage(),
'autoHistoryStore'
);
const manualHistoryStore: Writable<HistoryEntry[]> = persist(
writable([]),
localStorage(),
'manualHistoryStore'
);
export const historyStore: Readable<HistoryEntry[]> = derived(
[autoHistoryMode, autoHistoryStore, manualHistoryStore],
([autoMode, autoHistories, manualHistories], set) => {
set(autoMode ? autoHistories : manualHistories);
}
);
export const addHistoryEntry = (entry: HistoryEntry): void => {
entry.name = generateSlug(2);
if (!entry.auto) {
manualHistoryStore.update((entries) => [entry, ...entries]);
return;
}
autoHistoryStore.update((entries) => {
if (entries.length === MAX_AUTO_HISTORY_LENGTH) {
entries.pop();
}
return [entry, ...entries];
});
};
export const clearHistoryData = (time?: number): void => {
(get(autoHistoryMode) ? autoHistoryStore : manualHistoryStore).update((entries) =>
entries.filter((entry) => time && entry.time != time)
);
};
export const getPreviousState = (auto: boolean): string => {
const entries = get(auto ? autoHistoryStore : manualHistoryStore);
if (entries.length > 0) {
return JSON.stringify(entries[0].state);
}
return '';
};
+73
View File
@@ -0,0 +1,73 @@
<script lang="ts">
import { version } from 'mermaid/package.json';
interface Link {
title: string;
href: string;
icon?: string;
}
const links: Link[] = [
{
title: 'Documentation',
href: 'https://mermaid-js.github.io/mermaid/#/n00b-gettingStarted'
},
{
title: 'Tutorial',
href: 'https://github.com/mermaid-js/mermaid/blob/develop/docs/Tutorials.md'
},
{
title: 'Mermaid',
href: 'https://github.com/mermaid-js/mermaid'
},
{
title: 'CLI',
href: 'https://github.com/mermaid-js/mermaid-cli'
},
{
title: '',
href: 'https://github.com/mermaid-js/mermaid-live-editor',
icon: 'fab fa-github fa-lg'
}
];
</script>
<header class="p-2 bg-indigo-400 text-white font-bold flex flex-wrap items-center">
<div class="flex-1 flex justify-between items-center">
<a href="/">Mermaid<span class="text-xs font-thin">v{version}</span> Live Editor</a>
</div>
<label for="menu-toggle" class="pointer-cursor lg:hidden block"
><svg
class="fill-current text-gray-900"
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
><title>menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" /></svg
></label>
<input class="hidden" type="checkbox" id="menu-toggle" />
<div class="hidden lg:flex lg:items-center lg:w-auto w-full" id="menu">
<nav>
<ul class="lg:flex items-center justify-between text-base pt-4 lg:pt-0">
{#each links as { title, href, icon }}
<li>
<a class="nav-btn" target="_blank" {href}>
{#if icon}
<i class={icon} />
{/if}
{title}</a>
</li>
{/each}
</ul>
</nav>
</div>
</header>
<style lang="postcss">
#menu-toggle:checked + #menu {
display: block;
}
.nav-btn {
@apply lg:p-2 py-3 px-0 block border-b-2 border-transparent hover:border-white;
}
</style>
+116
View File
@@ -0,0 +1,116 @@
<script lang="ts">
import { updateCode } from '$lib/util/state';
import Card from '$lib/components/card/card.svelte';
const samples = {
'Flow Chart': `graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]`,
'Sequence Diagram': `sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!
`,
'Class Diagram': `classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
`,
'State Diagram': `stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
`,
'Gantt Chart': `gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d
`,
'Pie Chart': `pie title Pets adopted by volunteers
"Dogs" : 386
"Cats" : 85
"Rats" : 15
`,
'ER Diagram': `erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
`,
'Git Graph': `gitGraph:
options
{
"nodeSpacing": 150,
"nodeRadius": 10
}
end
commit
branch newbranch
checkout newbranch
commit
commit
checkout master
commit
commit
merge newbranch
`,
'User Journey': ` journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me
`
};
const loadSampleDiagram = (diagramType: string): void => {
updateCode(samples[diagramType], true, true);
};
</script>
<Card title="Presets" isOpen={false}>
<div class="flex gap-2 flex-wrap p-2">
{#each Object.keys(samples) as sample}
<button
class="rounded p-2 bg-indigo-400 shadow flex-auto text-white hover:bg-indigo-500"
on:click={() => loadSampleDiagram(sample)}>{sample}</button>
{/each}
</div>
</Card>
+67
View File
@@ -0,0 +1,67 @@
<script lang="ts">
import { errorStore } from '$lib/util/error';
import { codeStore } from '$lib/util/state';
import { onMount } from 'svelte';
import type { Mermaid } from 'mermaid';
const mermaid: Mermaid = (window.mermaid as unknown) as Mermaid;
let code: string = '';
let container: HTMLDivElement;
let error: boolean = false;
let outOfSync: boolean = false;
let manualUpdate: boolean = true;
onMount(async () => {
codeStore.subscribe((state) => {
try {
if (container && state && (state.updateDiagram || state.autoSync)) {
if (!state.autoSync) {
$codeStore.updateDiagram = false;
}
outOfSync = false;
manualUpdate = true;
// Replacing special characters '<' and '>' with encoded '&lt;' and '&gt;'
code = state.code; //.replace(/</g, '&lt;').replace(/>/g, '&gt;');
const scroll = container.parentElement.parentElement.parentElement.scrollTop;
container.innerHTML = code;
delete container.dataset.processed;
mermaid.initialize(Object.assign({}, JSON.parse(state.mermaid)));
mermaid.init(container);
mermaid.render('graph-div', code, insertSvg);
container.parentElement.parentElement.parentElement.scrollTop = scroll;
} else if (manualUpdate) {
manualUpdate = false;
} else {
outOfSync = true;
}
} catch (e) {
console.log('view fail', e);
error = true;
}
});
errorStore.subscribe((err) => {
if (typeof err === 'undefined') {
error = false;
} else {
error = true;
console.log('Error: ', err);
}
});
});
const insertSvg = (svgCode, bindFunctions) => {};
</script>
<div id="view" class="p-2" class:error class:outOfSync>
<div id="container" bind:this={container} class="flex-1 overflow-auto" />
</div>
<style>
#view {
border: 1px solor darkred;
flex: 1;
}
.error,
.outOfSync {
opacity: 0.5;
}
</style>
+60
View File
@@ -0,0 +1,60 @@
// this action (https://svelte.dev/tutorial/actions) allows us to
// progressively enhance a <form> that already works without JS
export function enhance(
form: HTMLFormElement,
{
pending,
error,
result
}: {
pending?: (data: FormData, form: HTMLFormElement) => void;
error?: (res: Response, error: Error, form: HTMLFormElement) => void;
result: (res: Response, form: HTMLFormElement) => void;
}
) {
let current_token: {};
async function handle_submit(e: Event) {
const token = (current_token = {});
e.preventDefault();
const body = new FormData(form);
if (pending) pending(body, form);
try {
const res = await fetch(form.action, {
method: form.method,
headers: {
accept: 'application/json'
},
body
});
if (token !== current_token) return;
if (res.ok) {
result(res, form);
} else if (error) {
error(res, null, form);
} else {
console.error(await res.text());
}
} catch (e) {
if (error) {
error(null, e, form);
} else {
throw e;
}
}
}
form.addEventListener('submit', handle_submit);
return {
destroy() {
form.removeEventListener('submit', handle_submit);
}
};
}
+7
View File
@@ -0,0 +1,7 @@
/**
* Can be made globally available by placing this
* inside `global.d.ts` and removing `export` keyword
*/
export interface Locals {
userid: string;
}
+3
View File
@@ -0,0 +1,3 @@
import { writable } from 'svelte/store';
export const errorStore = writable(undefined);
+7
View File
@@ -0,0 +1,7 @@
export const notify = (message: string): void => {
alert(message);
};
export const prompt = (message: string): boolean => {
return confirm(message);
};
+87
View File
@@ -0,0 +1,87 @@
import { writable, get, derived } from 'svelte/store';
import { toBase64, fromBase64 } from 'js-base64';
import { persist, localStorage } from '@macfja/svelte-persistent-store';
const defaultState: State = {
code: `graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
`,
mermaid: JSON.stringify(
{
theme: 'default'
},
null,
2
),
updateEditor: false,
autoSync: true,
updateDiagram: true
};
export const codeStore = persist(writable(defaultState), localStorage(), 'codeStore');
export const base64State = derived([codeStore], ([code], set) => {
set(toBase64(JSON.stringify(code), true));
});
export const loadState = (data: string): void => {
let state: State;
try {
const stateStr = fromBase64(data);
console.log(`Tring to load state: ${stateStr}`);
state = JSON.parse(stateStr);
} catch (e) {
if (data) {
console.error('Init error', e);
}
state = get(codeStore);
console.log(state);
}
updateCodeStore({ ...state, updateEditor: true });
};
export const updateCodeStore = (newState: State): void => {
codeStore.update((state) => {
return { ...state, ...newState };
});
};
let prompted = false;
export const updateCode = (code: string, updateEditor: boolean, updateDiagram = false): void => {
const lines = (code.match(/\n/g) || '').length + 1;
if (lines > 50 && !prompted && get(codeStore).autoSync) {
const turnOff = confirm(
'Long diagram deteced. Turn off Auto Sync? Click the sync logo to manually sync.'
);
prompted = true;
if (turnOff) {
updateCodeStore({
autoSync: false
} as State);
}
}
codeStore.update((state) => {
return { ...state, code, updateEditor, updateDiagram };
});
};
export const updateConfig = (config: string, updateEditor: boolean): void => {
codeStore.update((state) => {
return { ...state, mermaid: config, updateEditor };
});
};
export const initURLSubscription = (): void => {
base64State.subscribe((state: string) => {
window.location.hash = state;
});
};
export const getStateString = (): string => {
return JSON.stringify(get(codeStore));
};
+17
View File
@@ -0,0 +1,17 @@
import { initURLSubscription, loadState, updateCodeStore } from './state';
export const loadStateFromURL = (): void => {
loadState(window.location.hash.slice(1));
};
export const syncDiagram = (): void => {
updateCodeStore({
updateDiagram: true
} as State);
};
export const initHandler = (): void => {
loadStateFromURL();
syncDiagram();
initURLSubscription();
};
+10
View File
@@ -0,0 +1,10 @@
<script lang="ts">
import '../app.postcss';
</script>
<main class="h-screen">
<slot />
</main>
<style>
</style>
+149
View File
@@ -0,0 +1,149 @@
<script lang="ts">
import Editor from '$lib/components/editor/editor.svelte';
import Navbar from '$lib/components/navbar.svelte';
import Preset from '$lib/components/preset.svelte';
import Actions from '$lib/components/actions.svelte';
import View from '$lib/components/view.svelte';
import Card from '$lib/components/card/card.svelte';
import History from '$lib/components/history/history.svelte';
import { updateCode, updateConfig, codeStore, base64State } from '$lib/util/state';
import { initHandler, syncDiagram } from '$lib/util/util';
import { errorStore } from '$lib/util/error';
import { onMount } from 'svelte';
import type monaco from 'monaco-editor';
import type { Mermaid } from 'mermaid';
import { goto } from '$app/navigation';
const mermaid: Mermaid = (window.mermaid as unknown) as Mermaid;
let selectedMode = 'code';
const languageMap = {
code: 'mermaid',
config: 'json'
};
let text: string = '';
let language: 'mermaid' | 'json' = 'mermaid';
let errorMarkers: monaco.editor.IMarkerData[] = [];
$: language = languageMap[selectedMode];
$: {
if ($codeStore.updateEditor) {
if (selectedMode === 'code') {
text = $codeStore.code;
} else {
text = $codeStore.mermaid;
}
}
}
const tabSelectHandler = (message: CustomEvent<Tab>) => {
$codeStore.updateEditor = true;
selectedMode = message.detail.id;
};
const tabs: Tab[] = [
{
id: 'code',
title: 'Code',
icon: 'fas fa-code'
},
{
id: 'config',
title: 'Config',
icon: 'fas fa-cogs'
}
];
const handleCodeUpdate = async (code: string): Promise<void> => {
mermaid.parse(code);
updateCode(code, false);
};
const handleConfigUpdate = (config: string): void => {
JSON.parse(config);
updateConfig(config, false);
};
const updateHandler = async (message: CustomEvent<EditorUpdateEvent>) => {
try {
if (selectedMode === 'code') {
await handleCodeUpdate(message.detail.text);
} else {
handleConfigUpdate(message.detail.text);
}
errorStore.set(undefined);
errorMarkers = [];
} catch (e) {
errorStore.set(e);
if (e.hash) {
const marker: monaco.editor.IMarkerData = {
severity: 8, //Error
startLineNumber: e.hash.loc.first_line,
startColumn: e.hash.loc.first_column,
endLineNumber: e.hash.loc.last_line,
endColumn: e.hash.loc.last_column + 1,
message: e.str
};
errorMarkers.push(marker);
// Clear all previous errors before this error.
errorMarkers = errorMarkers.filter(
(m) => m.startLineNumber >= marker.startLineNumber && m.startColumn >= marker.startColumn
);
}
console.error(e);
}
};
const viewDiagram = async () => {
await goto(`/view#${$base64State}`, { replaceState: true });
};
onMount(initHandler);
</script>
<svelte:head>
<title>Edit</title>
</svelte:head>
<div class="h-full flex flex-col overflow-hidden bg-gray-100">
<Navbar />
<div class="flex-1 flex overflow-hidden">
<div class="w-2/5 hidden md:flex flex-col">
<Card on:select={tabSelectHandler} {tabs} isCloseable={false} title="Mermaid">
<div slot="actions">
{#if !$codeStore.autoSync}
<button
class="bg-indigo-500 hover:bg-indigo-700 rounded px-4 mx-2"
title="Sync Diagram"
on:click={syncDiagram}><i class="fas fa-sync" /></button>
{/if}
<label for="autoSync">
<input type="checkbox" name="autoSync" bind:checked={$codeStore.autoSync} />
Auto sync
</label>
</div>
<Editor on:update={updateHandler} {language} {text} {errorMarkers} />
</Card>
<div class="flex-1">
<Preset />
<History />
<Actions />
</div>
</div>
<div class="flex-1 flex flex-col overflow-hidden">
<Card title="Diagram" isCloseable={false}>
<button
slot="actions"
class="rounded shadow px-2 bg-indigo-500 hover:bg-indigo-700"
title="View diagram in new page"
on:click|stopPropagation={() => viewDiagram()}><i class="far fa-eye" /> View</button>
<div class="flex-1 overflow-auto">
<View />
</div>
</Card>
<div class="flex md:hidden bg-white rounded shadow p-2 mx-2">
Code editing not supported on mobile. Please use a desktop browser
</div>
</div>
</div>
</div>
+21
View File
@@ -0,0 +1,21 @@
<script lang="ts">
import { goto } from '$app/navigation';
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}`, {
replaceState: true
});
});
</script>
<svelte:head>
<title>Mermaid Live Editor</title>
</svelte:head>
+8
View File
@@ -0,0 +1,8 @@
<script lang="ts">
import View from '$lib/components/view.svelte';
import { initHandler } from '$lib/util/util';
import { onMount } from 'svelte';
onMount(initHandler);
</script>
<View />
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+3
View File
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
+29
View File
@@ -0,0 +1,29 @@
import preprocess from 'svelte-preprocess';
import adapter from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: [
preprocess({
postcss: true
})
],
kit: {
adapter: adapter({
pages: 'docs'
}),
paths: process.env['CI']
? {
base: '/mermaid-svelte-kit'
}
: {},
ssr: false,
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte'
}
};
export default config;
+26
View File
@@ -0,0 +1,26 @@
const { tailwindExtractor } = require('tailwindcss/lib/lib/purgeUnusedStyles');
module.exports = {
mode: 'aot',
purge: {
content: ['./src/**/*.{html,js,svelte,ts}'],
options: {
defaultExtractor: (content) => [
// If this stops working, please open an issue at https://github.com/svelte-add/tailwindcss/issues rather than bothering Tailwind Labs about it
...tailwindExtractor(content),
// Match Svelte class: directives (https://github.com/tailwindlabs/tailwindcss/discussions/1731)
...[...content.matchAll(/(?:class:)*([\w\d-/:%.]+)/gm)].map(
([_match, group, ..._rest]) => group
)
]
},
safelist: [/^svelte-[\d\w]+$/]
},
theme: {
extend: {}
},
variants: {
extend: {}
},
plugins: [require('@tailwindcss/forms')]
};
+30
View File
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"moduleResolution": "node",
"module": "es2020",
"lib": ["es2020", "ESNext"],
"target": "es2019",
/**
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
to enforce using \`import type\` instead of \`import\` for Types.
*/
"importsNotUsedAsValues": "error",
"isolatedModules": true,
"resolveJsonModule": true,
/**
To have warnings/errors of the Svelte compiler at the correct position,
enable source maps by default.
*/
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"allowJs": true,
"checkJs": true,
"paths": {
"$lib/*": ["src/lib/*"]
}
},
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"]
}
+2824
View File
File diff suppressed because it is too large Load Diff