@zenuml/core 3.41.0 → 3.41.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/zenuml.esm.mjs
CHANGED
|
@@ -74397,7 +74397,7 @@ const tK = (n, e) => {
|
|
|
74397
74397
|
]
|
|
74398
74398
|
}
|
|
74399
74399
|
);
|
|
74400
|
-
}, aK = "3.41.
|
|
74400
|
+
}, aK = "3.41.2";
|
|
74401
74401
|
function sK(n) {
|
|
74402
74402
|
const e = Math.floor(n / 1e3), t = Math.floor(n % 1e3), i = Math.floor((n % 1e3 - t) * 1e3);
|
|
74403
74403
|
return e + "s " + t + "ms " + i + "μs";
|
package/dist/zenuml.js
CHANGED
|
@@ -3400,7 +3400,7 @@ https://github.com/highlightjs/highlight.js/issues/2277`),d4=d2,se=v2);const B1=
|
|
|
3400
3400
|
`+d).trim(),this.textStyle={...f,...L,...p},this.classNames=[...h,..._,...m],this.commentStyle={...f,...L},this.messageStyle={...f,...p},this.commentClassNames=[...h,..._],this.messageClassNames=[...h,...m]}}const uY=n=>{const e=n.context.getComment()||"",t=new cY(e),i={className:z2("text-left text-sm text-skin-message",{hidden:n.collapsed&&!n.context.ret()}),context:n.context,origin:n.origin,comment:e,commentObj:t,number:n.number};switch(!0){case!!n.context.loop():return T.jsx(FH,{...i});case!!n.context.alt():return T.jsx(UH,{...i});case!!n.context.par():return T.jsx(ZH,{...i});case!!n.context.opt():return T.jsx(BH,{...i});case!!n.context.section():return T.jsx(zH,{...i});case!!n.context.critical():return T.jsx(HH,{...i});case!!n.context.tcf():return T.jsx(YH,{...i});case!!n.context.ref():return T.jsx(VH,{...i});case!!n.context.creation():return T.jsx(jH,{...i});case!!n.context.message():return T.jsx(JH,{...i});case!!n.context.asyncMessage():return T.jsx(tY,{...i});case!!n.context.divider():return T.jsx(sY,{...i});case!!n.context.ret():return T.jsx(oY,{...i,className:"text-left text-sm text-skin-message"})}},T3=n=>{var i;const e=((i=n.context)==null?void 0:i.stat())||[],t=s=>n.number?n.incremental?uZ(n.number,s):`${n.number}.${s+1}`:String(s+1);return T.jsx("div",{className:z2("block",n.className),style:n.style,"data-origin":n.origin,children:e.map((s,l)=>T.jsx("div",{className:z2("statement-container my-4",l===e.length-1&&"[&>.return]:-mb-4 [&>.return]:bottom-[-1px]"),"data-origin":n.origin,children:T.jsx(uY,{origin:n.origin||"",context:s,collapsed:!!n.collapsed,number:t(l)})},l))})};var dY=typeof document<"u",LY=function(){},tc=dY?b.useLayoutEffect:LY;const CY={...wn}.useInsertionEffect||(n=>n());function _Y(n){const e=b.useRef(()=>{});return CY(()=>{e.current=n}),b.useCallback(function(){for(var t=arguments.length,i=new Array(t),s=0;s<t;s++)i[s]=arguments[s];return e.current==null?void 0:e.current(...i)},[])}const gY={...wn};let hE=!1,pY=0;const fE=()=>"floating-ui-"+Math.random().toString(36).slice(2,6)+pY++;function mY(){const[n,e]=b.useState(()=>hE?fE():void 0);return tc(()=>{n==null&&e(fE())},[]),b.useEffect(()=>{hE=!0},[]),n}const hY=gY.useId||mY;function fY(){const n=new Map;return{emit(e,t){var i;(i=n.get(e))==null||i.forEach(s=>s(t))},on(e,t){n.has(e)||n.set(e,new Set),n.get(e).add(t)},off(e,t){var i;(i=n.get(e))==null||i.delete(t)}}}const EY=b.createContext(null),SY=b.createContext(null),TY=()=>{var n;return((n=b.useContext(EY))==null?void 0:n.id)||null},vY=()=>b.useContext(SY);function RY(n){const{open:e=!1,onOpenChange:t,elements:i}=n,s=hY(),l=b.useRef({}),[c]=b.useState(()=>fY()),d=TY()!=null,[L,_]=b.useState(i.reference),p=_Y((h,v,R)=>{l.current.openEvent=h?v:void 0,c.emit("openchange",{open:h,event:v,reason:R,nested:d}),t==null||t(h,v,R)}),m=b.useMemo(()=>({setPositionReference:_}),[]),f=b.useMemo(()=>({reference:L||i.reference||null,floating:i.floating||null,domReference:i.reference}),[L,i.reference,i.floating]);return b.useMemo(()=>({dataRef:l,open:e,onOpenChange:p,elements:f,events:c,floatingId:s,refs:m}),[e,p,f,c,s,m])}function bY(n){n===void 0&&(n={});const{nodeId:e}=n,t=RY({...n,elements:{reference:null,floating:null,...n.elements}}),i=n.rootContext||t,s=i.elements,[l,c]=b.useState(null),[d,L]=b.useState(null),p=(s==null?void 0:s.domReference)||l,m=b.useRef(null),f=vY();tc(()=>{p&&(m.current=p)},[p]);const h=UF({...n,elements:{...s,...d&&{reference:d}}}),v=b.useCallback(D=>{const A=Qe(D)?{getBoundingClientRect:()=>D.getBoundingClientRect(),getClientRects:()=>D.getClientRects(),contextElement:D}:D;L(A),h.refs.setReference(A)},[h.refs]),R=b.useCallback(D=>{(Qe(D)||D===null)&&(m.current=D,c(D)),(Qe(h.refs.reference.current)||h.refs.reference.current===null||D!==null&&!Qe(D))&&h.refs.setReference(D)},[h.refs]),w=b.useMemo(()=>({...h.refs,setReference:R,setPositionReference:v,domReference:m}),[h.refs,R,v]),M=b.useMemo(()=>({...h.elements,domReference:p}),[h.elements,p]),N=b.useMemo(()=>({...h,...i,refs:w,elements:M,nodeId:e}),[h,w,M,e,i]);return tc(()=>{i.dataRef.current.floatingContext=N;const D=f==null?void 0:f.nodesRef.current.find(A=>A.id===e);D&&(D.context=N)}),b.useMemo(()=>({...h,context:N,refs:w,elements:M}),[h,w,M,N])}function xY(n){const e=b.useRef(n);return b.useEffect(()=>{e.current=n},[n]),e}function wY(n,e,t){const i=xY(e);b.useEffect(()=>{function s(l){i.current(l)}return document.addEventListener(n,s,t),()=>document.removeEventListener(n,s,t)},[n,t,i])}const MY=(n,e)=>{wY("click",t=>{n&&(n.contains(t.target)||e(t))},{capture:!0})},AY=[{name:"bold",content:"B",class:"font-bold"},{name:"italic",content:"I",class:"italic"},{name:"underline",content:"U",class:"underline"},{name:"strikethrough",content:"S",class:"line-through"}],yY=()=>{const[n,e]=r4(r9),t=Q2(J0),i=I9(ur),[s,l]=b.useState(!1),[c,d]=b.useState([]),[L,_]=b.useState(""),p=R=>{e(R),t(R)},m=b.useRef({start:0,lineHead:0,prevLine:"",leadingSpaces:"",prevLineIsComment:!1,hasStyleBrackets:!1}),{refs:f,floatingStyles:h}=bY({open:s,onOpenChange:l}),v=R=>{var M;if(l(!1),!L)return;const w=m.current;if(w.prevLineIsComment){let N="";if(w.hasStyleBrackets){let D;c.includes(R)?D=c.filter(A=>A!==R):D=[...c,R],N=`${w.leadingSpaces}// [${D.filter(Boolean).join(", ")}] ${w.prevLine.slice(w.prevLine.indexOf("]")+1).trimStart()}`}else N=`${w.leadingSpaces}// [${R}] ${w.prevLine.slice((((M=w.prevLine.match(/\/\/*/))==null?void 0:M.index)||-2)+2).trimStart()}`;N.endsWith(`
|
|
3401
3401
|
`)||(N+=`
|
|
3402
3402
|
`),p(n.slice(0,tC(n,w.start))+N+n.slice(w.lineHead))}else p(n.slice(0,w.lineHead)+`${w.leadingSpaces}// [${R}]
|
|
3403
|
-
`+n.slice(w.lineHead))};return MY(f.floating.current,()=>{l(!1)}),b.useEffect(()=>{i((R,w)=>{setTimeout(()=>{var N;const M=m.current;if(M.start=R.start.start,M.lineHead=nr(n,M.start),M.prevLine=$b(n,M.start),M.leadingSpaces=((N=n.slice(M.lineHead).match(/^\s*/))==null?void 0:N[0])||"",M.prevLineIsComment=M.prevLine.trim().startsWith("//"),M.prevLineIsComment){const D=M.prevLine.trimStart().slice(2).trimStart(),A=D.indexOf("["),P=D.indexOf("]");M.hasStyleBrackets=!!(A===0&&P),M.hasStyleBrackets?d(D.slice(A+1,P).split(",").map(W=>W.trim())):d([])}f.setReference(w),_(R),l(!0)},0)})},[n,f,i]),T.jsx("div",{id:"style-panel",ref:f.setFloating,style:h,children:s&&T.jsx("div",{className:"flex bg-white shadow-md z-10 rounded-md p-1",children:AY.map(R=>T.jsx("div",{onClick:()=>v(R.class),children:T.jsx("div",{className:z2("w-6 mx-1 py-1 rounded-md text-black text-center cursor-pointer hover:bg-gray-200",[R.class,{"bg-gray-100":c.includes(R.class)}]),children:R.content})},R.name))})})},EE=d7.child({name:"MessageLayer"}),SE=n=>{const e=Q2(V9),t=Q2(B3),i=b.useMemo(()=>{const d=a8(e);return d.length===0?Pe:d[0].from||Pe},[e]),s=z3(t,i)+1,[l,c]=b.useState(!1);return l&&EE.debug("MessageLayer updated"),b.useEffect(()=>{c(!0),EE.debug("MessageLayer mounted")},[]),T.jsxs("div",{className:"message-layer relative z-30 pt-14 pb-10",style:n.style,children:[T.jsx(T3,{context:n.context,style:{paddingLeft:`${s}px`},origin:i}),T.jsx(yY,{})]})},TE=n=>{const e=Q2(q9),t=Q2(Z4),i=Q2(V9),s=Q2(B3),l=I9(lr),c=b.useRef(null);b.useEffect(()=>{l(c.current)}),b.useImperativeHandle(n.ref,()=>c.current);const d=b.useMemo(()=>{const _=s.orderedParticipantNames(),m=new G8(_).getFrame(i);return m?z8(m).left:0},[s,i]),L=b.useMemo(()=>rp(i,s)-d,[i,s,d]);return T.jsx("div",{className:z2("zenuml sequence-diagram relative box-border text-left overflow-visible px-2.5",e,n.className),style:n.style,ref:c,children:T.jsx("div",{style:{paddingLeft:`${d}px`},className:"relative z-container",children:t===Z3.Dynamic?T.jsxs(T.Fragment,{children:[T.jsx(ca,{leftGap:d,context:i==null?void 0:i.head(),renderLifeLine:!0}),T.jsx(SE,{context:i==null?void 0:i.block(),style:{width:`${L}px`}}),T.jsx(ca,{leftGap:d,context:i==null?void 0:i.head(),renderParticipants:!0})]}):T.jsxs(T.Fragment,{children:[T.jsx(ca,{leftGap:d,context:i==null?void 0:i.head(),renderParticipants:!0,renderLifeLine:!0}),T.jsx(SE,{context:i==null?void 0:i.block(),style:{width:`${L}px`}})]})})})},i6={backgroundColor:"white",filter:n=>{var e;return!((e=n==null?void 0:n.classList)!=null&&e.contains("hide-export"))}},NY=({ref:n,children:e})=>{const t=b.useRef(null),i=b.useRef(null),s=Q2(V9),[l,c]=r4(_C),[d,L]=r4(CC),[_,p]=r4(q9),[m,f]=r4(gC),h=Q2(LC),v=Q2(Z4),R=s==null?void 0:s.title(),w=()=>{c(!0)},M=async()=>{if(t.current)return PC(t.current,i6)},N=async()=>{if(t.current)return pr(t.current,i6)},D=async()=>{if(t.current)return cw(t.current,i6)},A=async()=>{if(t.current)return lw(t.current,i6)},P=()=>{const K=Math.min(1,d+.1);L(K)},W=()=>{L(d-.1)},k=K=>{const n2="zenuml-style";let a2;a2=document.createElement("style"),a2.id=n2,document.head.append(a2),a2.textContent=K},G=K=>{const n2=new URL(K).hostname;if(n2==="https://github.com"||n2==="https://githubusercontent.com"){fetch(K.replace("github.com","raw.githubusercontent.com").replace("blob/","")).then(_2=>_2.text()).then(_2=>{k(_2)});return}const a2="zenuml-remote-css";let r2;r2=document.createElement("link"),r2.id=a2,r2.rel="stylesheet",document.head.append(r2),r2.href=K};return b.useImperativeHandle(n,()=>({toPng:M,toSvg:N,toBlob:D,toJpeg:A,zoomIn:P,zoomOut:W,setTheme:p,setRemoteCss:G})),T.jsxs("div",{ref:t,className:z2("p-1 bg-skin-canvas inline-block",_),children:[T.jsx(Vw,{}),T.jsxs("div",{className:"frame text-skin-base bg-skin-frame border-skin-frame relative m-1 origin-top-left whitespace-nowrap border rounded",children:[T.jsxs("div",{ref:i,children:[T.jsxs("div",{className:"header text-skin-title bg-skin-title border-skin-frame border-b p-1 flex justify-between rounded-t",children:[T.jsx("div",{className:"left hide-export",children:e}),T.jsxs("div",{className:"right flex-grow flex justify-between",children:[T.jsx(Ww,{context:R}),T.jsx(qw,{className:"hide-export flex items-center"})]})]}),l&&T.jsx("div",{className:"fixed z-40 inset-0 overflow-y-auto","aria-labelledby":"modal-title",role:"dialog","aria-modal":"true",children:T.jsx(_k,{})}),T.jsx(TE,{className:"origin-top-left",style:{transform:`scale(${d})`}})]}),T.jsx("div",{className:"footer rounded text-skin-control bg-skin-title px-4 py-1 flex justify-between items-center gap-3",children:v===Z3.Dynamic&&T.jsxs(T.Fragment,{children:[T.jsxs("div",{className:"flex items-center gap-3 color-base",children:[T.jsx("button",{className:"bottom-1 flex items-center left-1 hide-export",onClick:w,children:T.jsx(_e,{name:"tip",className:"filter grayscale w-4 h-4"})}),h&&T.jsx(WU,{}),T.jsxs("div",{className:"flex items-center",children:[T.jsx("input",{type:"checkbox",id:"order-display",className:"mr-1",checked:!!m,onChange:()=>f(!m)}),T.jsx("label",{htmlFor:"order-display",title:"Numbering the diagram",className:"select-none",children:T.jsx(_e,{name:"numbering",className:"w-6 h-6"})})]})]}),T.jsxs("div",{className:"zoom-controls flex hide-export gap-1",children:[T.jsx("button",{className:"zoom-in",onClick:P,children:T.jsx(_e,{name:"zoom-in",className:"w-4 h-4"})}),T.jsxs("label",{className:"w-12 block text-center",children:[Number(d*100).toFixed(0),"%"]}),T.jsx("button",{className:"zoom-out",onClick:W,children:T.jsx(_e,{name:"zoom-out",className:"w-4 h-4"})})]}),T.jsx("a",{target:"_blank",href:"https://zenuml.com",className:"brand text-xs hover:underline",children:"ZenUML.com"})]})})]})]})},OY="3.41.
|
|
3403
|
+
`+n.slice(w.lineHead))};return MY(f.floating.current,()=>{l(!1)}),b.useEffect(()=>{i((R,w)=>{setTimeout(()=>{var N;const M=m.current;if(M.start=R.start.start,M.lineHead=nr(n,M.start),M.prevLine=$b(n,M.start),M.leadingSpaces=((N=n.slice(M.lineHead).match(/^\s*/))==null?void 0:N[0])||"",M.prevLineIsComment=M.prevLine.trim().startsWith("//"),M.prevLineIsComment){const D=M.prevLine.trimStart().slice(2).trimStart(),A=D.indexOf("["),P=D.indexOf("]");M.hasStyleBrackets=!!(A===0&&P),M.hasStyleBrackets?d(D.slice(A+1,P).split(",").map(W=>W.trim())):d([])}f.setReference(w),_(R),l(!0)},0)})},[n,f,i]),T.jsx("div",{id:"style-panel",ref:f.setFloating,style:h,children:s&&T.jsx("div",{className:"flex bg-white shadow-md z-10 rounded-md p-1",children:AY.map(R=>T.jsx("div",{onClick:()=>v(R.class),children:T.jsx("div",{className:z2("w-6 mx-1 py-1 rounded-md text-black text-center cursor-pointer hover:bg-gray-200",[R.class,{"bg-gray-100":c.includes(R.class)}]),children:R.content})},R.name))})})},EE=d7.child({name:"MessageLayer"}),SE=n=>{const e=Q2(V9),t=Q2(B3),i=b.useMemo(()=>{const d=a8(e);return d.length===0?Pe:d[0].from||Pe},[e]),s=z3(t,i)+1,[l,c]=b.useState(!1);return l&&EE.debug("MessageLayer updated"),b.useEffect(()=>{c(!0),EE.debug("MessageLayer mounted")},[]),T.jsxs("div",{className:"message-layer relative z-30 pt-14 pb-10",style:n.style,children:[T.jsx(T3,{context:n.context,style:{paddingLeft:`${s}px`},origin:i}),T.jsx(yY,{})]})},TE=n=>{const e=Q2(q9),t=Q2(Z4),i=Q2(V9),s=Q2(B3),l=I9(lr),c=b.useRef(null);b.useEffect(()=>{l(c.current)}),b.useImperativeHandle(n.ref,()=>c.current);const d=b.useMemo(()=>{const _=s.orderedParticipantNames(),m=new G8(_).getFrame(i);return m?z8(m).left:0},[s,i]),L=b.useMemo(()=>rp(i,s)-d,[i,s,d]);return T.jsx("div",{className:z2("zenuml sequence-diagram relative box-border text-left overflow-visible px-2.5",e,n.className),style:n.style,ref:c,children:T.jsx("div",{style:{paddingLeft:`${d}px`},className:"relative z-container",children:t===Z3.Dynamic?T.jsxs(T.Fragment,{children:[T.jsx(ca,{leftGap:d,context:i==null?void 0:i.head(),renderLifeLine:!0}),T.jsx(SE,{context:i==null?void 0:i.block(),style:{width:`${L}px`}}),T.jsx(ca,{leftGap:d,context:i==null?void 0:i.head(),renderParticipants:!0})]}):T.jsxs(T.Fragment,{children:[T.jsx(ca,{leftGap:d,context:i==null?void 0:i.head(),renderParticipants:!0,renderLifeLine:!0}),T.jsx(SE,{context:i==null?void 0:i.block(),style:{width:`${L}px`}})]})})})},i6={backgroundColor:"white",filter:n=>{var e;return!((e=n==null?void 0:n.classList)!=null&&e.contains("hide-export"))}},NY=({ref:n,children:e})=>{const t=b.useRef(null),i=b.useRef(null),s=Q2(V9),[l,c]=r4(_C),[d,L]=r4(CC),[_,p]=r4(q9),[m,f]=r4(gC),h=Q2(LC),v=Q2(Z4),R=s==null?void 0:s.title(),w=()=>{c(!0)},M=async()=>{if(t.current)return PC(t.current,i6)},N=async()=>{if(t.current)return pr(t.current,i6)},D=async()=>{if(t.current)return cw(t.current,i6)},A=async()=>{if(t.current)return lw(t.current,i6)},P=()=>{const K=Math.min(1,d+.1);L(K)},W=()=>{L(d-.1)},k=K=>{const n2="zenuml-style";let a2;a2=document.createElement("style"),a2.id=n2,document.head.append(a2),a2.textContent=K},G=K=>{const n2=new URL(K).hostname;if(n2==="https://github.com"||n2==="https://githubusercontent.com"){fetch(K.replace("github.com","raw.githubusercontent.com").replace("blob/","")).then(_2=>_2.text()).then(_2=>{k(_2)});return}const a2="zenuml-remote-css";let r2;r2=document.createElement("link"),r2.id=a2,r2.rel="stylesheet",document.head.append(r2),r2.href=K};return b.useImperativeHandle(n,()=>({toPng:M,toSvg:N,toBlob:D,toJpeg:A,zoomIn:P,zoomOut:W,setTheme:p,setRemoteCss:G})),T.jsxs("div",{ref:t,className:z2("p-1 bg-skin-canvas inline-block",_),children:[T.jsx(Vw,{}),T.jsxs("div",{className:"frame text-skin-base bg-skin-frame border-skin-frame relative m-1 origin-top-left whitespace-nowrap border rounded",children:[T.jsxs("div",{ref:i,children:[T.jsxs("div",{className:"header text-skin-title bg-skin-title border-skin-frame border-b p-1 flex justify-between rounded-t",children:[T.jsx("div",{className:"left hide-export",children:e}),T.jsxs("div",{className:"right flex-grow flex justify-between",children:[T.jsx(Ww,{context:R}),T.jsx(qw,{className:"hide-export flex items-center"})]})]}),l&&T.jsx("div",{className:"fixed z-40 inset-0 overflow-y-auto","aria-labelledby":"modal-title",role:"dialog","aria-modal":"true",children:T.jsx(_k,{})}),T.jsx(TE,{className:"origin-top-left",style:{transform:`scale(${d})`}})]}),T.jsx("div",{className:"footer rounded text-skin-control bg-skin-title px-4 py-1 flex justify-between items-center gap-3",children:v===Z3.Dynamic&&T.jsxs(T.Fragment,{children:[T.jsxs("div",{className:"flex items-center gap-3 color-base",children:[T.jsx("button",{className:"bottom-1 flex items-center left-1 hide-export",onClick:w,children:T.jsx(_e,{name:"tip",className:"filter grayscale w-4 h-4"})}),h&&T.jsx(WU,{}),T.jsxs("div",{className:"flex items-center",children:[T.jsx("input",{type:"checkbox",id:"order-display",className:"mr-1",checked:!!m,onChange:()=>f(!m)}),T.jsx("label",{htmlFor:"order-display",title:"Numbering the diagram",className:"select-none",children:T.jsx(_e,{name:"numbering",className:"w-6 h-6"})})]})]}),T.jsxs("div",{className:"zoom-controls flex hide-export gap-1",children:[T.jsx("button",{className:"zoom-in",onClick:P,children:T.jsx(_e,{name:"zoom-in",className:"w-4 h-4"})}),T.jsxs("label",{className:"w-12 block text-center",children:[Number(d*100).toFixed(0),"%"]}),T.jsx("button",{className:"zoom-out",onClick:W,children:T.jsx(_e,{name:"zoom-out",className:"w-4 h-4"})})]}),T.jsx("a",{target:"_blank",href:"https://zenuml.com",className:"brand text-xs hover:underline",children:"ZenUML.com"})]})})]})]})},OY="3.41.2";function IY(n){const e=Math.floor(n/1e3),t=Math.floor(n%1e3),i=Math.floor((n%1e3-t)*1e3);return e+"s "+t+"ms "+i+"μs"}const DY=(n,e)=>{const i=vE()-e;return console.debug(n+" cost: "+IY(i)),i},vE=()=>performance.now();var nc={exports:{}},w5={},ic={exports:{}},rc={};/**
|
|
3404
3404
|
* @license React
|
|
3405
3405
|
* scheduler.production.js
|
|
3406
3406
|
*
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# 🌐 ZenUML Now Supports Unicode Characters!
|
|
2
|
+
|
|
3
|
+
*September 2025 Newsletter*
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
We're excited to announce a major enhancement to ZenUML: **full Unicode character support** for identifiers! You can now create sequence diagrams using native characters from Chinese, Japanese, Korean, Arabic, Cyrillic, and many other languages.
|
|
8
|
+
|
|
9
|
+
## ✨ What's New
|
|
10
|
+
|
|
11
|
+
### Native Language Support
|
|
12
|
+
|
|
13
|
+
No more workarounds or quoted strings for basic identifiers. You can now write ZenUML diagrams in your native language:
|
|
14
|
+
|
|
15
|
+
**Chinese Example:**
|
|
16
|
+
```zenuml
|
|
17
|
+
用户 订单服务 数据库
|
|
18
|
+
|
|
19
|
+
用户.登录()
|
|
20
|
+
订单服务.创建订单()
|
|
21
|
+
数据库.保存数据()
|
|
22
|
+
return 成功
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Japanese Example:**
|
|
26
|
+
```zenuml
|
|
27
|
+
ユーザー システム データベース
|
|
28
|
+
|
|
29
|
+
ユーザー.ログイン()
|
|
30
|
+
システム.認証()
|
|
31
|
+
データベース.検索()
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Mixed Languages:**
|
|
35
|
+
```zenuml
|
|
36
|
+
UserService 数据库 CacheManager
|
|
37
|
+
|
|
38
|
+
UserService.获取用户()
|
|
39
|
+
数据库.query("SELECT * FROM users")
|
|
40
|
+
CacheManager.缓存结果()
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Supported Languages
|
|
44
|
+
|
|
45
|
+
The new Unicode support includes:
|
|
46
|
+
- **Chinese** (Simplified & Traditional)
|
|
47
|
+
- **Japanese** (Hiragana, Katakana, Kanji)
|
|
48
|
+
- **Korean** (Hangul)
|
|
49
|
+
- **Arabic**
|
|
50
|
+
- **Cyrillic** (Russian, Bulgarian, etc.)
|
|
51
|
+
- **And many more Unicode languages!**
|
|
52
|
+
|
|
53
|
+
## 🔧 Technical Implementation
|
|
54
|
+
|
|
55
|
+
### Grammar Enhancement
|
|
56
|
+
|
|
57
|
+
We've updated the ANTLR lexer to use Unicode property classes:
|
|
58
|
+
|
|
59
|
+
```antlr
|
|
60
|
+
ID : [\p{L}_] [\p{L}\p{Nd}_]* ;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- `\p{L}` matches any Unicode letter
|
|
64
|
+
- `\p{Nd}` matches any Unicode decimal digit
|
|
65
|
+
- Maintains backward compatibility with ASCII identifiers
|
|
66
|
+
|
|
67
|
+
### Backward Compatibility
|
|
68
|
+
|
|
69
|
+
**All existing ZenUML code continues to work unchanged.** This is a purely additive feature that expands what's possible without breaking existing diagrams.
|
|
70
|
+
|
|
71
|
+
## 📋 Usage Guidelines
|
|
72
|
+
|
|
73
|
+
### Simple Identifiers
|
|
74
|
+
Use Unicode characters directly for participant names, method names, and variables:
|
|
75
|
+
- ✅ `用户.登录()`
|
|
76
|
+
- ✅ `ユーザー.データ取得()`
|
|
77
|
+
- ✅ `사용자.인증()`
|
|
78
|
+
|
|
79
|
+
### With Spaces
|
|
80
|
+
For identifiers containing spaces, use quotes:
|
|
81
|
+
- ✅ `"用户 服务".获取信息()`
|
|
82
|
+
- ✅ `"Order Management".processOrder()`
|
|
83
|
+
|
|
84
|
+
### Rules
|
|
85
|
+
- Must start with a Unicode letter or underscore
|
|
86
|
+
- Can contain Unicode letters, numbers, and underscores
|
|
87
|
+
- Keywords (if, while, return) remain in English
|
|
88
|
+
|
|
89
|
+
## 📊 Before vs After: See the Difference
|
|
90
|
+
|
|
91
|
+
| Scenario | Before (Workarounds) | After (Native Unicode) |
|
|
92
|
+
|----------|---------------------|------------------------|
|
|
93
|
+
| **Chinese participants** | `"用户" "订单服务" "数据库"` | `用户 订单服务 数据库` |
|
|
94
|
+
| **Japanese methods** | `User."ログイン"()` | `ユーザー.ログイン()` |
|
|
95
|
+
| **Mixed languages** | `"UserService" "数据库" "CacheManager"` | `UserService 数据库 CacheManager` |
|
|
96
|
+
| **Korean business logic** | `"사용자"."인증"()` | `사용자.인증()` |
|
|
97
|
+
| **Arabic identifiers** | `"المستخدم"."تسجيل_الدخول"()` | `المستخدم.تسجيل_الدخول()` |
|
|
98
|
+
|
|
99
|
+
### Real Impact Examples
|
|
100
|
+
|
|
101
|
+
**E-commerce Team (Chinese):**
|
|
102
|
+
```zenuml
|
|
103
|
+
// Before: Mixed English/quoted Chinese
|
|
104
|
+
User "订单服务" Database
|
|
105
|
+
User."创建订单"()
|
|
106
|
+
"订单服务".validateOrder()
|
|
107
|
+
|
|
108
|
+
// After: Pure Chinese business language
|
|
109
|
+
用户 订单服务 数据库
|
|
110
|
+
用户.创建订单()
|
|
111
|
+
订单服务.验证订单()
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Banking System (Japanese):**
|
|
115
|
+
```zenuml
|
|
116
|
+
// Before: Awkward English mapping
|
|
117
|
+
Customer "AccountService" "TransactionDB"
|
|
118
|
+
Customer."残高照会"()
|
|
119
|
+
|
|
120
|
+
// After: Natural Japanese terminology
|
|
121
|
+
顧客 口座サービス 取引データベース
|
|
122
|
+
顧客.残高照会()
|
|
123
|
+
口座サービス.残高取得()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 🚀 Try It Now
|
|
127
|
+
|
|
128
|
+
Visit https://app.zenuml.com
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
**Happy Diagramming in Your Language!** 🎉
|
|
133
|
+
|
|
134
|
+
*Have feedback or found an issue? [Open an issue on GitHub](https://github.com/mermaid-js/zenuml-core/issues) or join our community discussions.*
|