@1agh/maude 0.60.4 → 0.60.6
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/apps/studio/annotations-layer.tsx +21 -12
- package/apps/studio/api.ts +54 -5
- package/apps/studio/build.ts +10 -0
- package/apps/studio/canvas-comment-mount.tsx +7 -1
- package/apps/studio/canvas-icons.tsx +30 -2
- package/apps/studio/canvas-lib.tsx +41 -6
- package/apps/studio/canvas-shell.tsx +39 -43
- package/apps/studio/client/app.jsx +20 -13
- package/apps/studio/dist/client.bundle.js +1 -1
- package/apps/studio/dist/comment-mount.js +2 -2
- package/apps/studio/dom-selection.ts +67 -0
- package/apps/studio/hmr-broadcast.ts +40 -2
- package/apps/studio/input-router.tsx +26 -2
- package/apps/studio/sync/agent.ts +64 -13
- package/apps/studio/sync/codec.ts +47 -0
- package/apps/studio/sync/cold-start.ts +96 -0
- package/apps/studio/sync/migrate-seed.ts +52 -7
- package/apps/studio/sync/projection.ts +10 -1
- package/apps/studio/test/canvas-meta-api.test.ts +114 -3
- package/apps/studio/test/canvas-wheel-delta.test.ts +42 -0
- package/apps/studio/test/canvas-zoom-floor.test.ts +73 -0
- package/apps/studio/test/comment-mount.test.ts +10 -1
- package/apps/studio/test/dom-selection.test.ts +69 -1
- package/apps/studio/test/hmr-broadcast.test.ts +6 -4
- package/apps/studio/test/hmr-classify.test.ts +18 -1
- package/apps/studio/test/input-router.test.ts +69 -0
- package/apps/studio/test/mode-toggle.test.tsx +226 -0
- package/apps/studio/test/sync-annotations-cold-start.test.ts +302 -0
- package/apps/studio/test/use-tool-mode.test.tsx +33 -3
- package/apps/studio/tool-palette.tsx +86 -24
- package/apps/studio/use-tool-mode.tsx +113 -14
- package/apps/studio/whats-new.json +45 -0
- package/package.json +8 -8
- package/plugins/design/templates/_shell.html +31 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Component as vQ,createElement as g,Fragment as CQ,useCallback as x7,useEffect as f,useMemo as SQ,useRef as p,useState as $7}from"react";import{createRoot as RQ}from"react-dom/client";import{useCallback as k,useEffect as S,useMemo as s,useRef as R,useState as u}from"react";function H7(){if(typeof window>"u")return;try{let J=window.location.pathname;if(J==="/_canvas-shell.html"||J==="/_canvas-shell"){let Q=new URLSearchParams(window.location.search),$=Q.get("canvas")??"",Z=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${Z}/${$}`:void 0}return decodeURIComponent(J).replace(/^\//,"")}catch{return}}function Z7(J){if(!J)return"";return(J.getAttribute("class")??"").trim().split(/\s+/).filter((Q)=>Q&&!Q.startsWith("dgn-")&&!Q.startsWith("dc-cv-")).join(" ")}function NJ(J,Q){if(!J)return"";let $=(J.innerText||J.textContent||"").replace(/\s+/g," ").trim();return $.length>Q?`${$.slice(0,Q-1)}…`:$}function _J(J){if(!J)return"";let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let Z=$.getAttribute?.("data-dc-element");if(Z){Q.unshift(`[data-dc-element="${Z}"]`);break}let q=$.getAttribute?.("data-dc-screen");if(q){Q.unshift(`[data-dc-screen="${q}"]`);break}let G=$.nodeName.toLowerCase();if($.id){G=`#${$.id}`,Q.unshift(G);break}let K=Z7($).split(/\s+/).filter(Boolean).slice(0,2);if(K.length)G+=`.${K.join(".")}`;let z=1,H=$.previousElementSibling;while(H)z++,H=H.previousElementSibling;G+=`:nth-child(${z})`,Q.unshift(G),$=$.parentElement}return Q.join(" > ")}function R7(J){let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let Z=$.nodeName.toLowerCase(),q=$.getAttribute?.("data-dc-element"),G=$.getAttribute?.("data-dc-screen");if(q)Z+=`[data-dc-element="${q}"]`;else if(G)Z+=`[data-dc-screen="${G}"]`;else if($.id)Z+=`#${$.id}`;let K=Z7($).split(/\s+/).filter(Boolean).slice(0,2);if(K.length&&!q&&!G)Z+=`.${K.join(".")}`;Q.unshift(Z),$=$.parentElement}return Q}function IJ(J){return J.replace(/[^a-zA-Z0-9_-]/g,(Q)=>`\\${Q}`)}function g7(J,Q){return Q?`[data-dc-screen="${Q}"] [data-cd-id="${J}"]`:`[data-cd-id="${J}"]`}function h7(J,Q,$){if(!$)return 0;try{let Z=J.querySelectorAll(Q);for(let q=0;q<Z.length;q++)if(Z[q]===$)return q}catch{}return 0}function f7(J,Q,$){if(!Q||!$)return 0;return h7(J,`[data-cd-id="${IJ(Q)}"]`,$)}function F7(J,Q){let $=(Z)=>{try{let q=J.querySelectorAll(Z);if(!q.length)return null;let G=Q.index&&Q.index>0&&Q.index<q.length?Q.index:0;return q[G]??q[0]}catch{return null}};if(Q.id){let Z=$(g7(Q.id,Q.artboardId));if(Z)return Z}if(Q.selector)return $(Q.selector);return null}function AJ(J,Q){let $=0,Z=Math.min(J.length,Q.length);for(let q=1;q<=Z;q++){if(J[J.length-q]!==Q[Q.length-q])break;$++}return $}function p7(J,Q){let $=Q.dom_path,Z=(Q.tag||"").toLowerCase();if(!$||$.length===0||!Z)return null;let q=J;if(Q.artboardId){let H=J.querySelector(`[data-dc-screen="${Q.artboardId}"]`);if(H)q=H}let G=(Q.classes||"").split(/\s+/).filter(Boolean),K=null,z=0;for(let H of Array.from(q.querySelectorAll("[data-cd-id]"))){if(H.tagName.toLowerCase()!==Z)continue;let j=AJ(R7(H),$);if(j===0)continue;let L=Z7(H).split(/\s+/).filter(Boolean),U=G.filter((F)=>L.includes(F)).length,B=j*10+U;if(B>z)z=B,K=H}return K}var S7=["display","flex-direction","flex-wrap","align-items","justify-content","gap","flex","flex-grow","flex-shrink","flex-basis","align-self","font-family","color","font-size","font-weight","line-height","letter-spacing","text-align","margin","margin-top","margin-right","margin-bottom","margin-left","padding","padding-top","padding-right","padding-bottom","padding-left","width","height","min-width","min-height","max-width","max-height","background-color","border-radius","border-top-left-radius","border-top-right-radius","border-bottom-left-radius","border-bottom-right-radius","border-width","border-style","border-color","box-shadow","opacity","position","top","right","bottom","left","z-index","transform","transform-origin","font-style","text-transform","text-decoration","white-space","overflow","object-fit","aspect-ratio","object-position"],OJ=/^(style|class|data-cd-id|data-dc-|data-dcid$)/;function TJ(J){if(!J||typeof window>"u"||!window.getComputedStyle)return{authored:{},computed:{},customStyles:{},attrs:{}};try{let Q=J.style,$=window.getComputedStyle(J),Z={},q={},G=new Set(S7);for(let B of S7){let F=Q.getPropertyValue(B);if(F)Z[B]=F.trim();let Y=$.getPropertyValue(B);if(Y)q[B]=Y.trim()}let K=/^(margin|padding|border)(-|$)/,z={};for(let B=0;B<Q.length;B++){let F=Q.item(B);if(!F||G.has(F)||K.test(F))continue;let Y=Q.getPropertyValue(F);if(Y)z[F]=Y.trim()}let H={};for(let B of Array.from(J.attributes)){if(OJ.test(B.name))continue;H[B.name]=B.value}if(J.hasAttribute("data-dc-screen")){for(let B of Array.from(J.attributes))if(B.name.startsWith("data-dc-")&&B.name!=="data-dcid")H[B.name]=B.value}let j=J.parentElement,L=j?window.getComputedStyle(j).display:"",U=j&&(L==="flex"||L==="inline-flex")?window.getComputedStyle(j).flexDirection:"";return{authored:Z,computed:q,customStyles:z,attrs:H,parentDisplay:L,parentFlexDirection:U}}catch{return{authored:{},computed:{},customStyles:{},attrs:{}}}}function P7(J,Q){let $=J.el,Z=$&&$.getBoundingClientRect?$.getBoundingClientRect():null,q=J.cdId,G=q?g7(q,J.artboardId):J.artboardId?`[data-dc-screen="${J.artboardId}"]`:_J($),K=q&&typeof document<"u"?h7(document,G,$):0;return{file:Q??H7(),id:q??void 0,selector:G,artboardId:J.artboardId,index:K,tag:$?.tagName.toLowerCase()??"",classes:Z7($),text:NJ($,240),dom_path:R7($),bounds:Z?{x:Math.round(Z.left),y:Math.round(Z.top),w:Math.round(Z.width),h:Math.round(Z.height)}:null,worldW:$ instanceof HTMLElement?Math.round($.offsetWidth):void 0,worldH:$ instanceof HTMLElement?Math.round($.offsetHeight):void 0,html:$?($.outerHTML??"").slice(0,4000):"",...(()=>{if($?.tagName?.toLowerCase()!=="img")return{};let z=/assets\/[0-9a-f]{8}\.[a-z0-9]+/i,H=$.getAttribute?.("data-photo-asset");if(H&&z.test(H))return{photoKind:"artboard-img",photoAsset:H};let j=$.getAttribute?.("src")||"",L=z.exec(j);return L?{photoKind:"artboard-img",photoAsset:L[0]}:{}})(),...TJ($)}}var q7=null;function G7(){if(typeof window>"u")return!1;if(q7===null)try{q7=new URLSearchParams(window.location.search).get("ro")==="1"}catch{q7=!1}return q7}import*as D7 from"lib0/decoding";import*as a from"lib0/encoding";import{createContext as wJ,useCallback as Q0,useContext as bJ,useEffect as $0,useMemo as V0,useReducer as Z0,useRef as q0,useState as G0}from"react";import{Awareness as W0,applyAwarenessUpdate as K0,encodeAwarenessUpdate as X0}from"y-protocols/awareness";import{readSyncMessage as U0,writeSyncStep1 as Y0,writeUpdate as H0}from"y-protocols/sync";import*as xJ from"yjs";import*as kJ from"yjs";var EJ=new WeakSet;function u7(J){return EJ.add(J),J}var oQ=u7(Object.freeze({maudeOrigin:"shell-edit"})),aQ=u7(Object.freeze({maudeOrigin:"sync-agent"}));import{jsx as D0}from"react/jsx-runtime";var yJ=wJ(null);function m7(){return bJ(yJ)}import{createContext as vJ,useCallback as l,useContext as j7,useEffect as CJ,useMemo as SJ,useRef as RJ,useState as gJ}from"react";import{jsx as M7,Fragment as pJ}from"react/jsx-runtime";var B7=vJ(null);function r(J){return J.id?`id:${J.id}`:`sel:${J.selector}`}function d7(J){let Q=[],$=new Set;for(let Z of J){let q=r(Z);if($.has(q))continue;$.add(q),Q.push(Z)}return Q}var hJ=50;function fJ({children:J,postTarget:Q}){let[$,Z]=gJ([]),q=RJ(null),G=l((B)=>{if(q.current)clearTimeout(q.current);q.current=setTimeout(()=>{q.current=null;let F=Q??(typeof window<"u"?window.parent:null);if(!F)return;let Y=B.length===0?null:B.length===1?B[0]??null:B;try{F.postMessage({dgn:"select-set",selection:Y},"*")}catch{}},hJ)},[Q]);CJ(()=>()=>{if(q.current)clearTimeout(q.current)},[]);let K=l((B)=>{let F=d7(Array.isArray(B)?B:[B]);Z(F),G(F)},[G]),z=l((B)=>{let F=Array.isArray(B)?B:[B];Z((Y)=>{let D=d7([...Y,...F]);return G(D),D})},[G]),H=l((B)=>{let F=r(B);Z((Y)=>{let D=Y.filter((_)=>r(_)!==F);return G(D),D})},[G]),j=l((B)=>{let F=r(B);Z((Y)=>{let D=Y.some((_)=>r(_)===F)?Y.filter((_)=>r(_)!==F):[...Y,B];return G(D),D})},[G]),L=l(()=>{Z([]),G([])},[G]),U=SJ(()=>({selected:$,replace:K,add:z,remove:H,toggle:j,clear:L}),[$,K,z,H,j,L]);return M7(B7.Provider,{value:U,children:J})}function i7({children:J}){if(j7(B7))return M7(pJ,{children:J});return M7(fJ,{children:J})}function W7(){let J=j7(B7);if(!J)throw Error("useSelectionSet must be used inside <SelectionSetProvider>");return J}function c7(){return j7(B7)}import{jsx as O,jsxs as x,Fragment as JQ}from"react/jsx-runtime";var uJ="/_client/comments-overlay.css";function mJ(){if(typeof document>"u")return;if(document.getElementById("cm-overlay-css"))return;let J=document.createElement("link");J.id="cm-overlay-css",J.rel="stylesheet",J.href=uJ,document.head.appendChild(J)}function dJ(){if(typeof window>"u")return null;try{let J=window.location.pathname;if(J==="/_canvas-shell.html"||J==="/_canvas-shell"){let Q=new URLSearchParams(window.location.search),$=Q.get("canvas")??"",Z=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${Z}/${$}`:null}return decodeURIComponent(J).replace(/^\//,"")}catch{return null}}function iJ(J){if(!J.selector)return null;let Q=null;try{let $=document.querySelectorAll(J.selector),Z=J.index&&J.index>0&&J.index<$.length?J.index:0;Q=$[Z]??$[0]??null}catch{Q=null}if(Q&&J.tag&&Q.tagName.toLowerCase()!==J.tag.toLowerCase())Q=null;if(!Q&&J.dom_path?.length){let $=J.selector.match(/data-dc-screen="([^"]+)"/)?.[1];Q=p7(document,{artboardId:$,tag:J.tag,classes:J.classes,dom_path:J.dom_path})}return Q}function N7(J){let Q=iJ(J);if(!Q?.isConnected)return null;let $=Q.getBoundingClientRect();if($.width===0&&$.height===0)return null;return{x:$.left,y:$.top,w:$.width,h:$.height}}function o7(J,Q){let Z=typeof window<"u"?window.innerWidth:J.x+Q.w,q=typeof window<"u"?window.innerHeight:J.y+Q.h,G=J.x;if(G+Q.w+8>Z){let z=J.x-Q.w;G=z>=8?z:Math.max(8,Z-Q.w-8)}let K=J.y;if(K+Q.h+8>q){let z=J.y-Q.h;K=z>=8?z:Math.max(8,q-Q.h-8)}return{x:G,y:K}}function a7(){mJ();let J=c7(),[Q,$]=u([]),[Z,q]=u(null),[G,K]=u(null),z=s(()=>dJ(),[]);S(()=>{if(typeof document>"u")return;let W=document.getElementById("dgn-pin-layer");if(!W)return;let P=W.style.display;return W.style.display="none",()=>{W.style.display=P}},[]);let H=k((W)=>{if(!J)return;if(!W?.selector){J.clear();return}let P=W.selector.match(/data-cd-id="([^"]+)"/),N=P?P[1]:void 0,I,A;try{let M=document.querySelector(W.selector);if(M)I=M.tagName.toLowerCase(),A=(M.getAttribute("class")??"").split(/\s+/).filter((T)=>T&&!T.startsWith("dgn-")&&!T.startsWith("dc-cv-")).join(" ")}catch{}J.replace({file:z??void 0,id:N,selector:W.selector,tag:I,classes:A,bounds:W.bounds??void 0})},[J,z]),j=R(Q);j.current=Q;let L=m7();S(()=>{if(!L)return;let W=L.doc.getArray("comments"),P=()=>{$(W.toArray())};if(W.length>0)P();return W.observe(P),()=>{try{W.unobserve(P)}catch{}}},[L]),S(()=>{if(typeof window>"u")return;let W=(P)=>{let N=P.data;if(!N||typeof N!=="object"||!N.dgn)return;if(N.dgn==="comments-set"&&Array.isArray(N.comments))$(N.comments);else if(N.dgn==="comment-focus"){let I=typeof N.id==="string"?N.id:null;q(I);let A=I?j.current.find((M)=>M.id===I):void 0;H(A)}};return window.addEventListener("message",W),()=>window.removeEventListener("message",W)},[H]),S(()=>{if(typeof document>"u")return;let W=(P)=>{let N=P.detail;if(!N?.selection)return;K({selection:N.selection,clientX:typeof N.clientX==="number"?N.clientX:0,clientY:typeof N.clientY==="number"?N.clientY:0})};return document.addEventListener("cm:open-composer",W),()=>document.removeEventListener("cm:open-composer",W)},[]);let U=k(()=>{if(K(null),typeof window>"u")return;try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},[]),B=k((W)=>{if(!G)return;let P=G.selection,N={file:P.file,selector:P.selector,index:P.index,dom_path:P.dom_path,tag:P.tag,classes:P.classes,bounds:P.bounds,html_excerpt:P.html,text:W};if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-submit",payload:N},"*")}catch{}U()},[G,U]);S(()=>{if(!z)return;let W=!1;return(async()=>{try{let P=await fetch(`/_comments?file=${encodeURIComponent(z)}`);if(!P.ok)return;let N=await P.json();if(W)return;if(Array.isArray(N.comments))$((I)=>I.length===0?N.comments??[]:I)}catch{}})(),()=>{W=!0}},[z]);let F=s(()=>{return Q.slice().sort((P,N)=>P.created.localeCompare(N.created)).filter((P)=>P.status!=="resolved")},[Q]),Y=s(()=>{let W=new Map;return Q.slice().sort((N,I)=>N.created.localeCompare(I.created)).forEach((N,I)=>{W.set(N.id,I+1)}),W},[Q]),D=k((W)=>{if(q(W),H(Q.find((P)=>P.id===W)),typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-click",id:W},"*")}catch{}},[Q,H]),_=k((W,P)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-patch",id:W,patch:P},"*")}catch{}},[]),V=k((W)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-delete",id:W},"*")}catch{}q((P)=>P===W?null:P)},[]),X=k(async(W,P)=>{if(typeof fetch>"u")return!1;try{let N=await fetch(`/_api/comments/${encodeURIComponent(W)}/reply`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:P})});if(!N.ok)return!1;let I=await N.json();return $((A)=>A.map((M)=>M.id===I.id?I:M)),!0}catch{return!1}},[]);return x("div",{className:"cm-layer","aria-hidden":!1,children:[F.map((W)=>{let P=Y.get(W.id)??0;return O(nJ,{comment:W,sequence:P,focused:Z===W.id,onClick:D,onOrphaned:V},W.id)}),G?O(oJ,{state:G,onSubmit:B,onCancel:U}):null,(()=>{if(!Z)return null;let W=F.find((P)=>P.id===Z);if(!W)return null;return O(aJ,{comment:W,sequence:Y.get(W.id)??0,onClose:()=>{q(null),J?.clear()},onPatch:(P)=>_(W.id,P),onDelete:()=>V(W.id),onReply:(P)=>X(W.id,P)})})()]})}var L7=null;async function cJ(){if(!L7)L7=(async()=>{try{let J=await fetch("/_api/git-committers");if(!J.ok)return[];let Q=await J.json();return Array.isArray(Q.committers)?Q.committers:[]}catch{return[]}})();return L7}function l7(J){return(J.trim().split(/\s+/)[0]??"").replace(/[^\w.-]/g,"").toLowerCase()}function lJ(J,Q){if(Q<=0||Q>J.length)return null;let $=Q-1;while($>=0){let Z=J[$]??"";if(Z==="@"){let q=$>0?J[$-1]:"";if($===0||/\s/.test(q??"")){let G=J.slice($+1,Q);return{start:$,end:Q,query:G}}return null}if(!/[\w.-]/.test(Z))return null;$-=1}return null}function s7({className:J,value:Q,onChange:$,onKeyDown:Z,placeholder:q,rows:G,disabled:K,textareaRef:z,ariaLabel:H}){let j=R(null),L=k((M)=>{if(j.current=M,z)z.current=M},[z]),[U,B]=u([]),[F,Y]=u(null),[D,_]=u(0),V=k(()=>{if(U.length>0)return;cJ().then((M)=>B(M))},[U.length]),X=s(()=>{if(!F)return[];let M=F.query.toLowerCase();return(!M?U:U.filter((E)=>E.name.toLowerCase().includes(M)||E.email.toLowerCase().includes(M))).slice(0,8)},[F,U]),W=k((M)=>{let T=M.selectionStart??M.value.length,E=lJ(M.value,T);Y(E),_(0)},[]),P=k((M)=>{$(M.target.value),W(M.target)},[$,W]),N=k((M)=>{if(!F)return;let T=j.current;if(!T)return;let E=`@${l7(M.name)}`,y=`${Q.slice(0,F.start)}${E} ${Q.slice(F.end)}`;$(y),Y(null);let w=F.start+E.length+1;requestAnimationFrame(()=>{T.focus(),T.setSelectionRange(w,w)})},[F,Q,$]),I=k((M)=>{if(F&&X.length>0){if(M.key==="ArrowDown"){M.preventDefault(),_((T)=>(T+1)%X.length);return}if(M.key==="ArrowUp"){M.preventDefault(),_((T)=>(T-1+X.length)%X.length);return}if(M.key==="Enter"||M.key==="Tab"){M.preventDefault();let T=X[D]??X[0];if(T)N(T);return}if(M.key==="Escape"){M.preventDefault(),Y(null);return}}Z?.(M)},[F,X,D,N,Z]),A=k((M)=>{W(M.currentTarget)},[W]);return x("div",{style:{position:"relative"},children:[O("textarea",{ref:L,className:J,value:Q,placeholder:q,rows:G,disabled:K,"aria-label":H,onChange:P,onKeyDown:I,onFocus:V,onSelect:A,onClick:A}),F&&X.length>0?O("ul",{className:"cm-mention-popup",role:"listbox","aria-label":"Mention suggestions",style:{left:0,top:"100%"},children:X.map((M,T)=>{return x("li",{role:"option","aria-selected":T===D,className:"cm-mention-popup__item",onMouseEnter:()=>_(T),onMouseDown:(y)=>{y.preventDefault(),N(M)},children:[x("span",{className:"cm-mention-popup__name",children:["@",l7(M.name)]}),O("span",{className:"cm-mention-popup__email",children:M.email})]},`${M.name}-${M.email}`)})}):null]})}var rJ=3000;function nJ({comment:J,sequence:Q,focused:$,onClick:Z,onOrphaned:q}){let G=R(null),K=R(null),z=R(null);S(()=>{let L=()=>{K.current=null;let U=G.current;if(!U)return;let B=N7(J);if(B)z.current=null;else{if(z.current==null)z.current=Date.now();else if(Date.now()-z.current>rJ)q(J.id);if(J.bounds)B={x:J.bounds.x,y:J.bounds.y,w:J.bounds.w,h:J.bounds.h}}if(!B){U.style.display="none",K.current=requestAnimationFrame(L);return}U.style.display="grid";let F=Math.round(B.x+B.w-12),Y=Math.round(B.y-12);U.style.left=`${F}px`,U.style.top=`${Y}px`,K.current=requestAnimationFrame(L)};return K.current=requestAnimationFrame(L),()=>{if(K.current!=null)cancelAnimationFrame(K.current)}},[J,q]);let H=J.author?.trim()||"unknown",j=`Comment ${Q} by ${H}`;return O("button",{ref:G,type:"button",className:"cm-pin","data-resolved":J.status==="resolved"?"true":"false","data-focused":$?"true":"false","data-comment-pin":J.id,"aria-label":j,"aria-expanded":$,title:J.text.slice(0,200),onClick:(L)=>{L.preventDefault(),L.stopPropagation(),Z(J.id)},children:Q})}function oJ({state:J,onSubmit:Q,onCancel:$}){let[Z,q]=u(""),G=R(null),K=R(null),z=R(null);S(()=>{let U=()=>{z.current=null;let B=K.current;if(!B)return;let F=eJ(J),Y=o7(F,{w:B.offsetWidth,h:B.offsetHeight});B.style.left=`${Math.round(Y.x)}px`,B.style.top=`${Math.round(Y.y)}px`,z.current=requestAnimationFrame(U)};return z.current=requestAnimationFrame(U),()=>{if(z.current!=null)cancelAnimationFrame(z.current)}},[J]),S(()=>{G.current?.focus()},[]);let H=k(()=>{let U=Z.trim();if(!U)return;Q(U)},[Z,Q]),j=k((U)=>{if(U.key==="Escape"){U.preventDefault(),$();return}if((U.metaKey||U.ctrlKey)&&U.key==="Enter")U.preventDefault(),H()},[$,H]),L=s(()=>{let U=J.selection.selector||"";if(!U)return J.selection.tag||"canvas";let B=U.match(/data-cd-id="([^"]+)"/);if(B)return`cd:${B[1]}`;return U.length>36?`${U.slice(0,33)}…`:U},[J.selection]);return x("div",{ref:K,className:"cm-composer",role:"dialog","aria-label":"New comment",onClick:(U)=>U.stopPropagation(),onPointerDown:(U)=>U.stopPropagation(),children:[x("div",{className:"cm-composer__head",children:[O("span",{children:"New comment"}),O("span",{className:"cm-composer__selector",children:L})]}),O(s7,{textareaRef:G,className:"cm-composer__textarea",value:Z,placeholder:"Type a comment. ⌘↵ to save · Esc to cancel · @name to tag",onChange:q,onKeyDown:j,rows:3,ariaLabel:"Comment body"}),x("div",{className:"cm-composer__actions",children:[O("button",{type:"button",className:"cm-btn",onClick:$,children:"Cancel"}),O("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!Z.trim(),onClick:H,children:"Save"})]})]})}function aJ({comment:J,sequence:Q,onClose:$,onPatch:Z,onDelete:q,onReply:G}){let K=R(null),z=R(null),H=R(null),[j,L]=u(""),[U,B]=u(!1);S(()=>{let V=()=>{H.current=null;let X=K.current;if(!X)return;let W=tJ(J),P=o7(W,{w:X.offsetWidth,h:X.offsetHeight});X.style.left=`${Math.round(P.x)}px`,X.style.top=`${Math.round(P.y)}px`,H.current=requestAnimationFrame(V)};return H.current=requestAnimationFrame(V),()=>{if(H.current!=null)cancelAnimationFrame(H.current)}},[J]),S(()=>{K.current?.focus();let V=J.id;return()=>{document.querySelector(`[data-comment-pin="${V}"]`)?.focus()}},[J.id]),S(()=>{if(typeof document>"u")return;let V=(X)=>{if(X.key!=="Escape")return;let W=K.current;if(!W)return;if(W.contains(X.target)||document.activeElement===W)X.preventDefault(),$()};return document.addEventListener("keydown",V),()=>document.removeEventListener("keydown",V)},[$]);let F=k(async()=>{let V=j.trim();if(!V||U)return;B(!0);let X=await G(V);if(B(!1),X)L(""),z.current?.focus()},[j,U,G]),Y=k((V)=>{if((V.metaKey||V.ctrlKey)&&V.key==="Enter")V.preventDefault(),F()},[F]),D=`cm-thread-head-${J.id}`,_=sJ(J.selector,"");return x("div",{ref:K,className:"cm-thread",role:"dialog","aria-labelledby":D,tabIndex:-1,onClick:(V)=>V.stopPropagation(),onPointerDown:(V)=>V.stopPropagation(),children:[x("div",{className:"cm-thread__head",id:D,children:[x("div",{className:"cm-thread__head-row",children:[O("span",{className:"cm-thread__seq","aria-hidden":"true",children:Q}),O("span",{className:"cm-thread__author",children:J.author?.trim()||"unknown"}),O("span",{className:"cm-thread__time",children:n7(J.created)}),O("button",{type:"button",className:"cm-thread__close","aria-label":"Close thread",title:"Close · Esc",onClick:$,children:"×"})]}),_?O("code",{className:"cm-thread__selector",children:_}):null]}),O("div",{className:"cm-thread__body",children:r7(J.text)}),(J.thread??[]).map((V)=>x("div",{className:"cm-thread__reply",children:[x("div",{className:"cm-thread__reply-head",children:[O("span",{className:"cm-thread__reply-author",children:V.author?.trim()||"unknown"}),O("span",{className:"cm-thread__reply-time",children:n7(V.created)})]}),O("div",{className:"cm-thread__reply-body",children:r7(V.body)})]},V.id)),!G7()&&x(JQ,{children:[x("div",{className:"cm-thread__reply-form",children:[O(s7,{textareaRef:z,className:"cm-thread__reply-textarea",value:j,placeholder:"Reply… ⌘↵ to send · @name to tag",onChange:L,onKeyDown:Y,rows:2,ariaLabel:"Reply",disabled:U}),O("div",{className:"cm-thread__reply-actions",children:O("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!j.trim()||U,onClick:()=>void F(),children:"Send"})})]}),x("div",{className:"cm-thread__actions",children:[J.status==="resolved"?O("button",{type:"button",className:"cm-btn",onClick:()=>Z({status:"open"}),children:"↺ Reopen"}):O("button",{type:"button",className:"cm-btn cm-btn--primary",onClick:()=>{Z({status:"resolved"}),$()},children:"✓ Resolve"}),O("button",{type:"button",className:"cm-btn cm-btn--danger",onClick:()=>{q(),$()},children:"Delete"})]})]})]})}function r7(J){if(!J)return null;let Q=/(@[\w][\w.-]*)/g;return J.split(Q).map((Z,q)=>{let G=`${q}:${Z}`;if(q%2===1)return O("strong",{"data-mention":"true",children:Z},G);return O("span",{children:Z},G)})}function n7(J){if(!J)return"";let Q=Date.parse(J);if(!Number.isFinite(Q))return"";let $=Math.round((Date.now()-Q)/1000);if($<60)return`${Math.max($,0)}s ago`;if($<3600)return`${Math.round($/60)}m ago`;if($<86400)return`${Math.round($/3600)}h ago`;return`${Math.round($/86400)}d ago`}function sJ(J,Q){if(!J)return Q;let $=J.match(/data-cd-id="([^"]+)"/);if($)return`cd:${$[1]}`;return J.length>36?`${J.slice(0,33)}…`:J}function tJ(J){let Q=J.selector?N7(J):null;if(Q)return{x:Q.x+Q.w-12,y:Q.y+16};if(J.bounds)return{x:J.bounds.x+J.bounds.w-12,y:J.bounds.y+16};return{x:16,y:16}}function eJ(J){if(J.clientX||J.clientY)return{x:J.clientX,y:J.clientY+8};if(J.selection.selector){let Q=N7(J.selection);if(Q)return{x:Q.x,y:Q.y+Q.h+8}}return{x:16,y:16}}import{useEffect as QQ}from"react";var $Q=new Set(["pen","highlighter","shape","rect","ellipse","arrow","sticky","text","section","eraser"]);function _7(J){return $Q.has(J)}var t=(J)=>!!(J.metaKey||J.ctrlKey);function e(J){if(J.type==="keydown"){if(J.isEditable)return{kind:"no-op"};if(J.metaKey||J.ctrlKey||J.altKey){if(J.key==="Escape")return{kind:"escape"};let $=(J.key||"").toLowerCase();if(!J.altKey&&(J.metaKey||J.ctrlKey)){if($==="z"&&J.shiftKey)return{kind:"redo"};if($==="z")return{kind:"undo"};if($==="y"&&!J.shiftKey)return{kind:"redo"}}return{kind:"no-op"}}let Q=(J.key||"").toLowerCase();if(Q==="v")return{kind:"tool",tool:"move"};if(Q==="h")return{kind:"tool",tool:"hand"};if(Q==="c")return{kind:"tool",tool:"comment"};if(Q==="b")return{kind:"tool",tool:"pen"};if(Q==="i")return{kind:"tool",tool:"highlighter"};if(Q==="r"||Q==="o")return{kind:"tool",tool:"shape"};if(Q==="a")return{kind:"tool",tool:"arrow"};if(Q==="n")return{kind:"tool",tool:"sticky"};if(Q==="t")return{kind:"tool",tool:"text"};if(Q==="s"&&J.shiftKey)return{kind:"tool",tool:"section"};if(Q==="e")return{kind:"tool",tool:"eraser"};if(J.key==="Escape")return{kind:"escape"};return{kind:"no-op"}}if(J.type==="contextmenu")return{kind:"context-menu",clientX:J.clientX??0,clientY:J.clientY??0};if(J.type==="pointermove"){if(_7(J.activeTool))return{kind:"no-op"};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!t(J))return{kind:"no-op"};return{kind:"hover",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0}}if(J.activeTool==="comment")return{kind:"hover",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0};return{kind:"hover",deep:t(J),clientX:J.clientX??0,clientY:J.clientY??0}}if(J.type==="pointerdown"){if(J.button===2)return{kind:"context-menu",clientX:J.clientX??0,clientY:J.clientY??0};if(J.button===1||J.spaceHeld)return{kind:"no-op"};if(J.button!==0)return{kind:"no-op"};if(_7(J.activeTool)&&!t(J))return{kind:"no-op"};if(J.activeTool==="comment")return{kind:"drop-comment",clientX:J.clientX??0,clientY:J.clientY??0};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!t(J))return{kind:"no-op"};return{kind:"select",mode:J.shiftKey?"add":"replace",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0}}let Q=t(J);return{kind:"select",mode:!!J.shiftKey?"add":"replace",deep:Q,clientX:J.clientX??0,clientY:J.clientY??0}}return{kind:"no-op"}}function K7(J){if(!J||!J.tagName)return!1;let Q=J,$=Q.tagName;if($==="INPUT"||$==="TEXTAREA"||$==="SELECT")return!0;if(Q.isContentEditable)return!0;let Z=Q.getAttribute?.("contenteditable");if(Z==="true"||Z==="plaintext-only"||Z==="")return!0;return!1}function J7(J){if(!J||!J.closest)return!1;return!!J.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mediaref-player]")}function e7(J){if(!J||typeof J.closest!=="function")return!1;let Q=J;return!!Q.closest("[data-dc-screen]")&&!Q.closest(".dc-artboard-body")}function t7(J,Q,$){return J.kind==="select"&&!$.metaKey&&!$.ctrlKey&&e7(Q)}function VQ(J,Q,$){return J==="select"&&!$.metaKey&&!$.ctrlKey&&e7(Q)}function JJ(J){let{hostRef:Q,getActiveTool:$,isSpaceHeld:Z,callbacks:q,enabled:G=!0,claimableActions:K}=J;QQ(()=>{if(!G)return;let z=Q.current;if(!z)return;let H=(V)=>K&&V.kind!=="no-op"&&!K.has(V.kind)?{kind:"no-op"}:V,j=(V)=>{switch(V.kind){case"hover":q.onHover?.(V);break;case"select":q.onSelect?.(V);break;case"drop-comment":q.onDropComment?.(V);break;case"context-menu":q.onContextMenu?.(V);break;case"tool":q.onTool?.(V);break;case"escape":q.onEscape?.();break;case"undo":q.onUndo?.();break;case"redo":q.onRedo?.();break;case"no-op":break}},L=(V)=>{let X=H(e({type:"pointermove",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()}));j(X)},U=(V)=>{if(J7(V.target))return;if(K7(V.target))return;let X=H(e({type:"pointerdown",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()})),W=t7(X,V.target,V);if(X.kind!=="no-op"){if(V.preventDefault(),!W)V.stopImmediatePropagation()}j(X)},B=(V)=>{if(J7(V.target))return;if(K7(V.target))return;let X=H(e({type:"pointerdown",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()})),W=t7(X,V.target,V);if(X.kind!=="no-op"){if(V.preventDefault(),!W)V.stopImmediatePropagation();if(X.kind==="select")try{window.focus()}catch{}}},F=(V)=>{if(J7(V.target))return;if(K7(V.target))return;let X=$(),W=V.metaKey||V.ctrlKey,P=X==="comment"?"drop-comment":X==="move"&&V.button===0?"select":(_7(X)||X==="browse")&&W&&V.button===0?"select":V.button===2?"context-menu":null;if(P&&(!K||K.has(P))){let N=VQ(P,V.target,V);if(V.preventDefault(),!N)V.stopImmediatePropagation()}},Y=(V)=>{let X=H(e({type:"contextmenu",clientX:V.clientX,clientY:V.clientY,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,activeTool:$()}));if(X.kind==="no-op")return;V.preventDefault(),V.stopImmediatePropagation(),j(X)},D=(V)=>{let X=H(e({type:"keydown",key:V.key,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,isEditable:K7(V.target),activeTool:$()}));if(X.kind==="tool"||X.kind==="escape"||X.kind==="undo"||X.kind==="redo")V.preventDefault();j(X)};z.addEventListener("pointermove",L,{passive:!0}),z.addEventListener("pointerdown",U,{capture:!0}),z.addEventListener("mousedown",B,{capture:!0}),z.addEventListener("click",F,{capture:!0}),z.addEventListener("contextmenu",Y,{capture:!0});let _=z.ownerDocument??document;return _.addEventListener("keydown",D,!0),()=>{z.removeEventListener("pointermove",L),z.removeEventListener("pointerdown",U,{capture:!0}),z.removeEventListener("mousedown",B,{capture:!0}),z.removeEventListener("click",F,{capture:!0}),z.removeEventListener("contextmenu",Y,{capture:!0}),_.removeEventListener("keydown",D,!0)}},[G,Q,$,Z,q,K])}function I7(J,Q,$,Z){let q=J.elementFromPoint(Q,$);if(!q)return null;if(q.closest?.(".dc-mm, .dc-zoom-tb, .dc-tool-palette, .dc-context-menu, .dc-cv-group-bbox"))return null;let G=q.closest?.("[data-dc-screen]")??null,K=G?.getAttribute("data-dc-screen")??null,z=q.closest?.(".dc-artboard-body")??null;if(!z){if(G&&K)return{el:G,cdId:null,artboardId:K};return null}if(q===z){if(G&&K)return{el:G,cdId:null,artboardId:K};return null}if(Z.deep){let B=q.getAttribute?.("data-cd-id")??null;return{el:q,cdId:B,artboardId:K}}let H=q,j=null;while(H&&H!==z){if(H.hasAttribute?.("data-cd-id"))j=H;H=H.parentElement}let L=j??q,U=L.getAttribute?.("data-cd-id")??null;return{el:L,cdId:U,artboardId:K}}import{useCallback as LQ,useEffect as GJ,useRef as z7}from"react";var ZQ=!1;function QJ(){return ZQ}import{createContext as YQ,useCallback as k7,useContext as ZJ,useEffect as HQ,useMemo as VJ,useState as E7}from"react";function m(J,Q,$,Z){return`url("data:image/svg+xml,${encodeURIComponent(J.trim())}") ${Q} ${$}, ${Z}`}var O7="width='24' height='24' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'",T7="#1f1f1f",A7="stroke='#ffffff' stroke-linejoin='round' stroke-linecap='round'";function i(J,Q,$){let Z=$?`<g transform='${$}'>`:"";return`<svg ${O7}>${Z}<path fill='#ffffff' d='${J}'/><path fill='${T7}' d='${Q}'/>${$?"</g>":""}</svg>`}var $J="translate(0,32) scale(1,-1)",qQ=m(i("M10.25 8.25 L10.05 8.65 10 9 10 23.1 10.05 23.4 10.25 23.75 10.8 24 11.45 23.85 11.6 23.7 11.75 23.45 14.65 19.8 14.85 19.65 14.95 19.5 15.4 19.2 15.95 19.1 21.05 19.1 21.2 19.1 21.35 19.05 21.65 18.9 21.9 18.6 22 18.3 22 17.9 21.9 17.65 21.75 17.35 21.65 17.3 21.55 17.15 11.5 8.25 11.25 8.05 10.95 8 10.6 8.05 10.25 8.25 M9.15 6.6 L9.7 6.25 10 6.15 10.95 6 11.9 6.15 13 6.9 22.9 15.65 23 15.8 23.2 15.95 23.75 16.75 24 17.9 24 18.3 23.9 18.95 23.8 19.25 23.6 19.7 23.1 20.35 22.75 20.6 22.1 20.9 22.05 20.95 22 20.95 21.2 21.1 21.05 21.1 16.2 21.1 16.1 21.25 16.05 21.25 13.4 24.6 13.05 25.15 12.9 25.3 12.55 25.55 Q11.6 26.15 10.55 26 L10.5 26 Q9.65 25.85 9 25.3 L8.45 24.65 8.4 24.5 8.15 24.05 8 23.1 8 9 Q8 8.45 8.15 8.05 L8.25 7.75 8.45 7.35 9.15 6.6","M10.25 8.25 L10.6 8.05 10.95 8 11.25 8.05 11.5 8.25 21.55 17.15 21.65 17.3 21.75 17.35 21.9 17.65 22 17.9 22 18.3 21.9 18.6 21.65 18.9 21.35 19.05 21.2 19.1 21.05 19.1 15.95 19.1 15.4 19.2 14.95 19.5 14.85 19.65 14.65 19.8 11.75 23.45 11.6 23.7 11.45 23.85 10.8 24 10.25 23.75 10.05 23.4 10 23.1 10 9 10.05 8.65 10.25 8.25"),8,5,"default"),GQ=m(i("M28.55 17.8 Q29.4 20.3 28.75 22.8 L28.7 23 28.15 24.55 28.05 24.75 Q26.4 28.2 22.75 29.4 L22.45 29.5 18 29.9 17.75 29.85 Q15.8 29.25 13.8 28.1 L13.45 27.95 Q12 27.05 10.35 26.8 L10.25 26.75 7.9 26.7 7.8 26.7 Q6.1 26.9 4.8 25.8 L4.75 25.8 4.65 25.7 4.6 25.65 Q3.25 24.5 3.05 22.85 L3 22.75 Q2.8 20.95 4 19.5 5.05 18.15 6.75 17.95 L8.4 17.9 7.5 15.55 7.3 15.2 7.2 15 5 10.95 Q3.9 9.15 4.3 7.75 L4.4 7.5 Q4.75 6.15 6.45 5.2 9 3.65 11 5 11.05 4.1 11.5 3.45 12.15 2.1 14.2 1.6 L14.35 1.6 Q18.05 0.6 19.6 4.4 L19.65 4.55 Q20.75 3.65 22.7 3.75 L22.75 3.75 Q26.75 4 27 8.15 L27 8.25 27 8.35 27 8.45 Q26.9 10.75 27.1 12.6 27.15 14.65 28.2 16.75 L28.55 17.8 M26.65 18.4 L26.1 16.8 26.1 16.85 Q24.8 13.7 25 8.35 L25 8.25 Q24.85 5.9 22.6 5.75 20.7 5.65 20.4 7.35 L20.1 7.95 19.5 8.2 18.85 8.05 18.45 7.5 17.75 5.15 Q16.85 2.95 14.7 3.55 L14.65 3.55 Q12.55 4.05 13.15 6.15 L13.85 8.75 13.75 9.45 13.25 9.95 12.55 9.95 12 9.55 10.9 7.7 Q9.5 5.7 7.45 6.9 6.5 7.45 6.25 8.15 6.1 8.9 6.7 9.85 9.2 13.9 10.8 18.65 L10.8 19.3 10.4 19.8 9.75 19.95 Q8.35 19.8 6.95 19.95 6.1 20.05 5.55 20.75 4.9 21.55 5 22.55 5.15 23.55 6 24.2 L6.05 24.25 Q6.75 24.85 7.65 24.7 L7.7 24.7 10.65 24.8 Q12.7 25.15 14.45 26.2 L14.5 26.2 Q16.4 27.35 18.3 27.9 L22.05 27.5 22.1 27.5 Q24.95 26.55 26.25 23.85 L26.8 22.3 Q27.3 20.35 26.65 18.4","M26.65 18.4 Q27.3 20.35 26.8 22.3 L26.25 23.85 Q24.95 26.55 22.1 27.5 L22.05 27.5 18.3 27.9 Q16.4 27.35 14.5 26.2 L14.45 26.2 Q12.7 25.15 10.65 24.8 L7.7 24.7 7.65 24.7 Q6.75 24.85 6.05 24.25 L6 24.2 Q5.15 23.55 5 22.55 4.9 21.55 5.55 20.75 6.1 20.05 6.95 19.95 8.35 19.8 9.75 19.95 L10.4 19.8 10.8 19.3 10.8 18.65 Q9.2 13.9 6.7 9.85 6.1 8.9 6.25 8.15 6.5 7.45 7.45 6.9 9.5 5.7 10.9 7.7 L12 9.55 12.55 9.95 13.25 9.95 13.75 9.45 13.85 8.75 13.15 6.15 Q12.55 4.05 14.65 3.55 L14.7 3.55 Q16.85 2.95 17.75 5.15 L18.45 7.5 18.85 8.05 19.5 8.2 20.1 7.95 20.4 7.35 Q20.7 5.65 22.6 5.75 24.85 5.9 25 8.25 L25 8.35 Q24.8 13.7 26.1 16.85 L26.1 16.8 26.65 18.4"),12,12,"grab"),BQ=m(i("M28 14 Q28 9.85 24.45 6.9 20.95 4 16 4 11.05 4 7.5 6.9 L7.45 7 Q4 9.9 4 14 4 18.15 7.55 21.05 L7.5 21.05 Q9.2 22.45 11.2 23.2 L15.3 27.3 16 27.6 16.7 27.3 20.85 23.2 Q22.7 22.45 24.3 21.15 L24.45 21.05 Q28 18.15 28 14 M25.75 5.35 Q30.05 8.95 30 14 30.05 19.05 25.75 22.6 L25.4 22.85 Q23.8 24.1 22 24.9 L18.1 28.75 18.15 28.75 Q17.2 29.6 16 29.6 14.8 29.6 13.85 28.75 L13.9 28.75 10 24.9 6.6 22.85 6.25 22.6 Q1.95 19.05 2 14 1.95 8.95 6.25 5.35 10.3 2 16 2 21.7 2 25.75 5.35","M28 14 Q28 18.15 24.45 21.05 L24.3 21.15 Q22.7 22.45 20.85 23.2 L16.7 27.3 16 27.6 15.3 27.3 11.2 23.2 Q9.2 22.45 7.5 21.05 L7.55 21.05 Q4 18.15 4 14 4 9.9 7.45 7 L7.5 6.9 Q11.05 4 16 4 20.95 4 24.45 6.9 28 9.85 28 14"),12,21,"crosshair"),WQ=m(i("M4 13.1 L4 6 Q4 5.15 4.6 4.6 5.15 4 6 4 L13.1 4 Q13.95 4 14.55 4.6 L28.65 18.75 Q29.8 19.9 29.75 21.45 L29.75 21.6 29.75 21.7 Q29.75 23.2 28.7 24.35 L24.45 28.65 24.35 28.75 Q23.15 29.85 21.65 29.8 L21.55 29.8 21.4 29.8 Q20.2 29.8 19.25 29.15 L18 29.35 Q16.6 29.4 15.25 28 L15.2 27.95 8.2 20.95 Q7.6 20.35 7.6 19.55 7.6 18.7 8.2 18.1 L4.6 14.5 Q4 13.9 4 13.1 M19.5 26.65 L20.1 27.25 Q20.7 27.85 21.5 27.8 22.35 27.85 23 27.25 L27.25 22.95 Q27.8 22.35 27.75 21.55 27.8 20.75 27.2 20.15 L13.1 6 6 6 6 13.1 12.35 19.45 9.6 19.5 16.65 26.55 Q18.05 28.05 19.5 26.65 M8.05 12.3 L8 8 12.25 8.05 13.8 9.6 9.6 13.85 8.05 12.3 M15.25 11.05 L23 18.8 18.8 23.05 11.05 15.3 15.25 11.05","M15.25 11.05 L11.05 15.3 18.8 23.05 23 18.8 15.25 11.05 M12.35 19.45 L6 13.1 6 6 13.1 6 27.2 20.15 Q27.8 20.75 27.75 21.55 27.8 22.35 27.25 22.95 L23 27.25 Q22.35 27.85 21.5 27.8 20.7 27.85 20.1 27.25 L19.5 26.65 12.35 19.45 M8.05 12.3 L9.6 13.85 13.8 9.6 12.25 8.05 8 8 8.05 12.3",$J),6,18,"crosshair"),KQ=m(i("M5.15 10.85 Q4 9.65 4 8.1 L4 7.95 4 7.85 Q3.95 6.2 5.1 5.15 6.25 4 7.85 4 L7.95 4 8.1 4 Q9.65 4 10.85 5.15 L11 5.3 14.3 5.25 Q15.15 5.25 15.75 5.85 L29.9 20 Q31 21.15 31 22.75 L31 22.85 31 23 Q31.05 24.5 29.9 25.7 L29.55 25.95 25.65 29.9 25.65 29.95 Q24.45 31.1 22.75 31.1 21.2 31.15 20 29.95 L5.85 15.8 Q5.25 15.2 5.25 14.35 L5.25 10.95 5.15 10.85 M19.95 24.2 L18.55 22.8 22.8 18.55 24.2 19.95 19.95 24.2 M28.45 21.4 L14.3 7.25 10.15 7.3 9.4 6.55 Q8.8 5.95 7.95 6 7.1 5.95 6.5 6.55 5.95 7.1 6 7.95 5.95 8.8 6.55 9.4 L7.25 10.1 7.25 14.35 21.4 28.5 Q22 29.1 22.75 29.1 23.6 29.1 24.2 28.5 L28.45 24.25 Q29.05 23.65 29 22.85 29.05 22 28.45 21.4 M9.25 13.5 L9.25 9.3 13.5 9.25 14.3 10.05 10.05 14.3 9.25 13.5 M17.15 21.4 L11.5 15.75 15.75 11.5 21.4 17.15 17.15 21.4","M17.15 21.4 L21.4 17.15 15.75 11.5 11.5 15.75 17.15 21.4 M28.45 21.4 Q29.05 22 29 22.85 29.05 23.65 28.45 24.25 L24.2 28.5 Q23.6 29.1 22.75 29.1 22 29.1 21.4 28.5 L7.25 14.35 7.25 10.1 6.55 9.4 Q5.95 8.8 6 7.95 5.95 7.1 6.5 6.55 7.1 5.95 7.95 6 8.8 5.95 9.4 6.55 L10.15 7.3 14.3 7.25 28.45 21.4 M19.95 24.2 L24.2 19.95 22.8 18.55 18.55 22.8 19.95 24.2 M9.25 13.5 L10.05 14.3 14.3 10.05 13.5 9.25 9.25 9.3 9.25 13.5",$J),6,18,"crosshair"),Q7=m(i("M17 2 Q18.2 2 19.15 2.9 20 3.8 20 5 L20 12 27 12 Q28.2 12 29.15 12.9 30 13.8 30 15 L30 17 Q30 18.2 29.15 19.15 28.2 20 27 20 L20 20 20 27 Q20 28.2 19.15 29.15 18.2 30 17 30 L15 30 Q13.8 30 12.9 29.15 12 28.2 12 27 L12 20 5 20 Q3.8 20 2.9 19.15 2 18.2 2 17 L2 15 Q2 13.8 2.9 12.9 3.8 12 5 12 L12 12 12 5 Q12 3.8 12.9 2.9 13.8 2 15 2 L17 2 M14 27 L14.3 27.7 Q14.6 28 15 28 L17 28 17.7 27.7 18 27 18 18.05 18.05 18 27 18 Q27.4 18 27.7 17.7 L28 17 28 15 27.7 14.3 Q27.4 14 27 14 L18 14 18 5 17.7 4.3 17 4 15 4 Q14.6 4 14.3 4.3 14 4.6 14 5 L14 14 5 14 Q4.6 14 4.3 14.3 4 14.6 4 15 L4 17 Q4 17.4 4.3 17.7 4.6 18 5 18 L14 18 14 27","M14 27 L14 18 5 18 Q4.6 18 4.3 17.7 4 17.4 4 17 L4 15 Q4 14.6 4.3 14.3 4.6 14 5 14 L14 14 14 5 Q14 4.6 14.3 4.3 14.6 4 15 4 L17 4 17.7 4.3 18 5 18 14 27 14 Q27.4 14 27.7 14.3 L28 15 28 17 27.7 17.7 Q27.4 18 27 18 L18.05 18 18 18.05 18 27 17.7 27.7 17 28 15 28 Q14.6 28 14.3 27.7 L14 27"),12,12,"crosshair"),XQ=m(i("M3.9 11.35 Q2.3 12.5 3.7 13.9 L16.4 26.65 Q17.85 28.05 19.45 26.9 L27.65 21.15 Q29.3 20 27.85 18.6 L15.15 5.85 Q13.75 4.45 12.1 5.6 L3.9 11.35 M1.05 12.4 Q1 10.95 2.75 9.75 L10.95 4 10.95 3.95 Q14 1.85 16.6 4.45 L29.3 17.2 Q30.8 18.65 30.55 20.1 30.55 21.55 28.8 22.8 L20.6 28.55 20.65 28.55 Q17.7 30.65 15 28.1 L15 28.05 2.3 15.3 2.3 15.35 Q0.8 13.85 1.05 12.4 M13.5 7 L19.85 13.35 11.65 19.15 5.3 12.75 13.5 7","M13.5 7 L5.3 12.75 11.65 19.15 19.85 13.35 13.5 7 M3.9 11.35 L12.1 5.6 Q13.75 4.45 15.15 5.85 L27.85 18.6 Q29.3 20 27.65 21.15 L19.45 26.9 Q17.85 28.05 16.4 26.65 L3.7 13.9 Q2.3 12.5 3.9 11.35"),6,14,"cell"),zQ=m(`<svg ${O7}><path d='M16 4V28M11 4H21M11 28H21' fill='none' ${A7} stroke-width='5'/><path d='M16 4V28M11 4H21M11 28H21' fill='none' stroke='${T7}' stroke-width='2.25' stroke-linecap='round'/></svg>`,12,12,"text"),UQ=m(`<svg ${O7}><path d='M6 5H21L26 10V27H6Z' fill='${T7}' ${A7} stroke-width='2.5'/><path d='M21 5V11H26' fill='none' ${A7} stroke-width='2.25'/></svg>`,5,5,"crosshair"),C=Object.freeze({browse:"default",move:qQ,hand:GQ,comment:BQ,pen:WQ,section:Q7,highlighter:KQ,shape:Q7,rect:Q7,ellipse:Q7,sticky:UQ,arrow:Q7,text:zQ,eraser:XQ});import{jsx as w7,Fragment as jQ}from"react/jsx-runtime";var FQ=Object.freeze([{id:"browse",label:"Browse",shortcut:"",cursor:C.browse},{id:"move",label:"Select",shortcut:"V",cursor:C.move},{id:"hand",label:"Hand",shortcut:"H",cursor:C.hand},{id:"comment",label:"Comment",shortcut:"C",cursor:C.comment},{id:"pen",label:"Pen",shortcut:"B",cursor:C.pen},{id:"highlighter",label:"Highlighter",shortcut:"I",cursor:C.highlighter},{id:"shape",label:"Shape",shortcut:"R",cursor:C.shape},{id:"sticky",label:"Sticky",shortcut:"N",cursor:C.sticky},{id:"section",label:"Section",shortcut:"⇧S",cursor:C.shape},{id:"arrow",label:"Arrow",shortcut:"A",cursor:C.arrow},{id:"text",label:"Text",shortcut:"T",cursor:C.text},{id:"eraser",label:"Eraser",shortcut:"E",cursor:C.eraser}]),PQ=new Set(["browse","move","hand"]);function DQ(J,Q){return Q?J.filter(($)=>PQ.has($.id)):J}var b7=YQ(null);function MQ({children:J,tools:Q=FQ,initial:$="browse"}){let Z=VJ(()=>DQ(Q,G7()),[Q]),[q,G]=E7($),[K,z]=E7(()=>({tool:null,locked:!1})),H=k7((Y)=>{if(!Z.some((D)=>D.id===Y))return;G(Y),z((D)=>D.locked&&D.tool===Y?D:{tool:null,locked:!1})},[Z]),j=k7((Y)=>{z((D)=>{if(D.locked&&D.tool===Y)return{tool:null,locked:!1};return{tool:Y,locked:!0}}),G(Y)},[]),L=k7(()=>{z({tool:null,locked:!1})},[]),[U,B]=E7("rounded");HQ(()=>{if(typeof document>"u")return;let Y=Z.find((V)=>V.id===q);if(!Y)return;let D=document.body.style.cursor,_=document.getElementById("dc-tool-cursor");if(!_)_=document.createElement("style"),_.id="dc-tool-cursor",document.head.appendChild(_);if(q==="browse"){if(document.body.style.cursor="",_.textContent="",typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:q},"*")}catch{}return()=>{document.body.style.cursor=D}}if(document.body.style.cursor=Y.cursor,_.textContent=`* { cursor: ${Y.cursor} !important; }`,typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:q},"*")}catch{}return()=>{document.body.style.cursor=D;let V=document.getElementById("dc-tool-cursor");if(V)V.textContent=""}},[q,Z]);let F=VJ(()=>({tool:q,setTool:H,tools:Z,sticky:K,toggleSticky:j,clearSticky:L,shapeKind:U,setShapeKind:B}),[q,H,Z,K,j,L,U]);return w7(b7.Provider,{value:F,children:J})}function qJ({children:J}){if(ZJ(b7))return w7(jQ,{children:J});return w7(MQ,{children:J})}function X7(){let J=ZJ(b7);if(!J)throw Error("useToolMode must be used inside <ToolProvider>");return J}import{jsx as yQ}from"react/jsx-runtime";var NQ=`
|
|
1
|
+
import{Component as RQ,createElement as h,Fragment as SQ,useCallback as b7,useEffect as f,useMemo as hQ,useRef as p,useState as V7}from"react";import{createRoot as gQ}from"react-dom/client";import{useCallback as T,useEffect as R,useMemo as s,useRef as S,useState as u}from"react";function P7(){if(typeof window>"u")return;try{let J=window.location.pathname;if(J==="/_canvas-shell.html"||J==="/_canvas-shell"){let Q=new URLSearchParams(window.location.search),$=Q.get("canvas")??"",Z=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${Z}/${$}`:void 0}return decodeURIComponent(J).replace(/^\//,"")}catch{return}}function q7(J){if(!J)return"";return(J.getAttribute("class")??"").trim().split(/\s+/).filter((Q)=>Q&&!Q.startsWith("dgn-")&&!Q.startsWith("dc-cv-")).join(" ")}function IJ(J,Q){if(!J)return"";let $=(J.innerText||J.textContent||"").replace(/\s+/g," ").trim();return $.length>Q?`${$.slice(0,Q-1)}…`:$}function AJ(J){if(!J)return"";let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let Z=$.getAttribute?.("data-dc-element");if(Z){Q.unshift(`[data-dc-element="${Z}"]`);break}let q=$.getAttribute?.("data-dc-screen");if(q){Q.unshift(`[data-dc-screen="${q}"]`);break}let G=$.nodeName.toLowerCase();if($.id){G=`#${$.id}`,Q.unshift(G);break}let z=q7($).split(/\s+/).filter(Boolean).slice(0,2);if(z.length)G+=`.${z.join(".")}`;let X=1,Y=$.previousElementSibling;while(Y)X++,Y=Y.previousElementSibling;G+=`:nth-child(${X})`,Q.unshift(G),$=$.parentElement}return Q.join(" > ")}function S7(J){let Q=[],$=J;while($&&$.nodeType===1&&Q.length<8){let Z=$.nodeName.toLowerCase(),q=$.getAttribute?.("data-dc-element"),G=$.getAttribute?.("data-dc-screen");if(q)Z+=`[data-dc-element="${q}"]`;else if(G)Z+=`[data-dc-screen="${G}"]`;else if($.id)Z+=`#${$.id}`;let z=q7($).split(/\s+/).filter(Boolean).slice(0,2);if(z.length&&!q&&!G)Z+=`.${z.join(".")}`;Q.unshift(Z),$=$.parentElement}return Q}function OJ(J){return J.replace(/[^a-zA-Z0-9_-]/g,(Q)=>`\\${Q}`)}function h7(J,Q){return Q?`[data-dc-screen="${Q}"] [data-cd-id="${J}"]`:`[data-cd-id="${J}"]`}function g7(J,Q,$){if(!$)return 0;try{let Z=J.querySelectorAll(Q);for(let q=0;q<Z.length;q++)if(Z[q]===$)return q}catch{}return 0}function f7(J,Q,$){if(!Q||!$)return 0;return g7(J,`[data-cd-id="${OJ(Q)}"]`,$)}function D7(J,Q){let $=(Z)=>{try{let q=J.querySelectorAll(Z);if(!q.length)return null;let G=Q.index&&Q.index>0&&Q.index<q.length?Q.index:0;return q[G]??q[0]}catch{return null}};if(Q.id){let Z=$(h7(Q.id,Q.artboardId));if(Z)return Z}if(Q.selector)return $(Q.selector);return null}function kJ(J,Q){let $=0,Z=Math.min(J.length,Q.length);for(let q=1;q<=Z;q++){if(J[J.length-q]!==Q[Q.length-q])break;$++}return $}function p7(J,Q){let $=Q.dom_path,Z=(Q.tag||"").toLowerCase();if(!$||$.length===0||!Z)return null;let q=J;if(Q.artboardId){let Y=J.querySelector(`[data-dc-screen="${Q.artboardId}"]`);if(Y)q=Y}let G=(Q.classes||"").split(/\s+/).filter(Boolean),z=null,X=0;for(let Y of Array.from(q.querySelectorAll("[data-cd-id]"))){if(Y.tagName.toLowerCase()!==Z)continue;let _=kJ(S7(Y),$);if(_===0)continue;let L=q7(Y).split(/\s+/).filter(Boolean),U=G.filter((P)=>L.includes(P)).length,W=_*10+U;if(W>X)X=W,z=Y}return z}var R7=["display","flex-direction","flex-wrap","align-items","justify-content","gap","flex","flex-grow","flex-shrink","flex-basis","align-self","font-family","color","font-size","font-weight","line-height","letter-spacing","text-align","margin","margin-top","margin-right","margin-bottom","margin-left","padding","padding-top","padding-right","padding-bottom","padding-left","width","height","min-width","min-height","max-width","max-height","background-color","border-radius","border-top-left-radius","border-top-right-radius","border-bottom-left-radius","border-bottom-right-radius","border-width","border-style","border-color","box-shadow","opacity","position","top","right","bottom","left","z-index","transform","transform-origin","font-style","text-transform","text-decoration","white-space","overflow","object-fit","aspect-ratio","object-position"],TJ=/^(style|class|data-cd-id|data-dc-|data-dcid$)/;function EJ(J){if(!J||typeof window>"u"||!window.getComputedStyle)return{authored:{},computed:{},customStyles:{},attrs:{}};try{let Q=J.style,$=window.getComputedStyle(J),Z={},q={},G=new Set(R7);for(let W of R7){let P=Q.getPropertyValue(W);if(P)Z[W]=P.trim();let H=$.getPropertyValue(W);if(H)q[W]=H.trim()}let z=/^(margin|padding|border)(-|$)/,X={};for(let W=0;W<Q.length;W++){let P=Q.item(W);if(!P||G.has(P)||z.test(P))continue;let H=Q.getPropertyValue(P);if(H)X[P]=H.trim()}let Y={};for(let W of Array.from(J.attributes)){if(TJ.test(W.name))continue;Y[W.name]=W.value}if(J.hasAttribute("data-dc-screen")){for(let W of Array.from(J.attributes))if(W.name.startsWith("data-dc-")&&W.name!=="data-dcid")Y[W.name]=W.value}let _=J.parentElement,L=_?window.getComputedStyle(_).display:"",U=_&&(L==="flex"||L==="inline-flex")?window.getComputedStyle(_).flexDirection:"";return{authored:Z,computed:q,customStyles:X,attrs:Y,parentDisplay:L,parentFlexDirection:U}}catch{return{authored:{},computed:{},customStyles:{},attrs:{}}}}function j7(J,Q){let $=J.el,Z=$&&$.getBoundingClientRect?$.getBoundingClientRect():null,q=J.cdId,G=q?h7(q,J.artboardId):J.artboardId?`[data-dc-screen="${J.artboardId}"]`:AJ($),z=q&&typeof document<"u"?g7(document,G,$):0;return{file:Q??P7(),id:q??void 0,selector:G,artboardId:J.artboardId,index:z,tag:$?.tagName.toLowerCase()??"",classes:q7($),text:IJ($,240),dom_path:S7($),bounds:Z?{x:Math.round(Z.left),y:Math.round(Z.top),w:Math.round(Z.width),h:Math.round(Z.height)}:null,worldW:$ instanceof HTMLElement?Math.round($.offsetWidth):void 0,worldH:$ instanceof HTMLElement?Math.round($.offsetHeight):void 0,html:$?($.outerHTML??"").slice(0,4000):"",...(()=>{if($?.tagName?.toLowerCase()!=="img")return{};let X=/assets\/[0-9a-f]{8}\.[a-z0-9]+/i,Y=$.getAttribute?.("data-photo-asset");if(Y&&X.test(Y))return{photoKind:"artboard-img",photoAsset:Y};let _=$.getAttribute?.("src")||"",L=X.exec(_);return L?{photoKind:"artboard-img",photoAsset:L[0]}:{}})(),...EJ($)}}var G7=null;function B7(){if(typeof window>"u")return!1;if(G7===null)try{G7=new URLSearchParams(window.location.search).get("ro")==="1"}catch{G7=!1}return G7}import*as L7 from"lib0/decoding";import*as o from"lib0/encoding";import{createContext as bJ,useCallback as V0,useContext as yJ,useEffect as Z0,useMemo as q0,useReducer as G0,useRef as B0,useState as W0}from"react";import{Awareness as z0,applyAwarenessUpdate as U0,encodeAwarenessUpdate as X0}from"y-protocols/awareness";import{readSyncMessage as H0,writeSyncStep1 as F0,writeUpdate as P0}from"y-protocols/sync";import*as vJ from"yjs";import*as wJ from"yjs";var xJ=new WeakSet;function u7(J){return xJ.add(J),J}var sQ=u7(Object.freeze({maudeOrigin:"shell-edit"})),tQ=u7(Object.freeze({maudeOrigin:"sync-agent"}));import{jsx as L0}from"react/jsx-runtime";var CJ=bJ(null);function m7(){return yJ(CJ)}import{createContext as RJ,useCallback as l,useContext as M7,useEffect as SJ,useMemo as hJ,useRef as gJ,useState as fJ}from"react";import{jsx as N7,Fragment as mJ}from"react/jsx-runtime";var W7=RJ(null);function n(J){return J.id?`id:${J.id}`:`sel:${J.selector}`}function d7(J){let Q=[],$=new Set;for(let Z of J){let q=n(Z);if($.has(q))continue;$.add(q),Q.push(Z)}return Q}var pJ=50;function uJ({children:J,postTarget:Q}){let[$,Z]=fJ([]),q=gJ(null),G=l((W)=>{if(q.current)clearTimeout(q.current);q.current=setTimeout(()=>{q.current=null;let P=Q??(typeof window<"u"?window.parent:null);if(!P)return;let H=W.length===0?null:W.length===1?W[0]??null:W;try{P.postMessage({dgn:"select-set",selection:H},"*")}catch{}},pJ)},[Q]);SJ(()=>()=>{if(q.current)clearTimeout(q.current)},[]);let z=l((W)=>{let P=d7(Array.isArray(W)?W:[W]);Z(P),G(P)},[G]),X=l((W)=>{let P=Array.isArray(W)?W:[W];Z((H)=>{let j=d7([...H,...P]);return G(j),j})},[G]),Y=l((W)=>{let P=n(W);Z((H)=>{let j=H.filter((I)=>n(I)!==P);return G(j),j})},[G]),_=l((W)=>{let P=n(W);Z((H)=>{let j=H.some((I)=>n(I)===P)?H.filter((I)=>n(I)!==P):[...H,W];return G(j),j})},[G]),L=l(()=>{Z([]),G([])},[G]),U=hJ(()=>({selected:$,replace:z,add:X,remove:Y,toggle:_,clear:L}),[$,z,X,Y,_,L]);return N7(W7.Provider,{value:U,children:J})}function i7({children:J}){if(M7(W7))return N7(mJ,{children:J});return N7(uJ,{children:J})}function K7(){let J=M7(W7);if(!J)throw Error("useSelectionSet must be used inside <SelectionSetProvider>");return J}function c7(){return M7(W7)}import{jsx as k,jsxs as b,Fragment as $Q}from"react/jsx-runtime";var dJ="/_client/comments-overlay.css";function iJ(){if(typeof document>"u")return;if(document.getElementById("cm-overlay-css"))return;let J=document.createElement("link");J.id="cm-overlay-css",J.rel="stylesheet",J.href=dJ,document.head.appendChild(J)}function cJ(){if(typeof window>"u")return null;try{let J=window.location.pathname;if(J==="/_canvas-shell.html"||J==="/_canvas-shell"){let Q=new URLSearchParams(window.location.search),$=Q.get("canvas")??"",Z=(Q.get("designRel")??".design").replace(/^\/+|\/+$/g,"");return $?`${Z}/${$}`:null}return decodeURIComponent(J).replace(/^\//,"")}catch{return null}}function lJ(J){if(!J.selector)return null;let Q=null;try{let $=document.querySelectorAll(J.selector),Z=J.index&&J.index>0&&J.index<$.length?J.index:0;Q=$[Z]??$[0]??null}catch{Q=null}if(Q&&J.tag&&Q.tagName.toLowerCase()!==J.tag.toLowerCase())Q=null;if(!Q&&J.dom_path?.length){let $=J.selector.match(/data-dc-screen="([^"]+)"/)?.[1];Q=p7(document,{artboardId:$,tag:J.tag,classes:J.classes,dom_path:J.dom_path})}return Q}function I7(J){let Q=lJ(J);if(!Q?.isConnected)return null;let $=Q.getBoundingClientRect();if($.width===0&&$.height===0)return null;return{x:$.left,y:$.top,w:$.width,h:$.height}}function a7(J,Q){let Z=typeof window<"u"?window.innerWidth:J.x+Q.w,q=typeof window<"u"?window.innerHeight:J.y+Q.h,G=J.x;if(G+Q.w+8>Z){let X=J.x-Q.w;G=X>=8?X:Math.max(8,Z-Q.w-8)}let z=J.y;if(z+Q.h+8>q){let X=J.y-Q.h;z=X>=8?X:Math.max(8,q-Q.h-8)}return{x:G,y:z}}function o7(){iJ();let J=c7(),[Q,$]=u([]),[Z,q]=u(null),[G,z]=u(null),X=s(()=>cJ(),[]);R(()=>{if(typeof document>"u")return;let B=document.getElementById("dgn-pin-layer");if(!B)return;let D=B.style.display;return B.style.display="none",()=>{B.style.display=D}},[]);let Y=T((B)=>{if(!J)return;if(!B?.selector){J.clear();return}let D=B.selector.match(/data-cd-id="([^"]+)"/),N=D?D[1]:void 0,M,A;try{let F=document.querySelector(B.selector);if(F)M=F.tagName.toLowerCase(),A=(F.getAttribute("class")??"").split(/\s+/).filter((O)=>O&&!O.startsWith("dgn-")&&!O.startsWith("dc-cv-")).join(" ")}catch{}J.replace({file:X??void 0,id:N,selector:B.selector,tag:M,classes:A,bounds:B.bounds??void 0})},[J,X]),_=S(Q);_.current=Q;let L=m7();R(()=>{if(!L)return;let B=L.doc.getArray("comments"),D=()=>{$(B.toArray())};if(B.length>0)D();return B.observe(D),()=>{try{B.unobserve(D)}catch{}}},[L]),R(()=>{if(typeof window>"u")return;let B=(D)=>{let N=D.data;if(!N||typeof N!=="object"||!N.dgn)return;if(N.dgn==="comments-set"&&Array.isArray(N.comments))$(N.comments);else if(N.dgn==="comment-focus"){let M=typeof N.id==="string"?N.id:null;q(M);let A=M?_.current.find((F)=>F.id===M):void 0;Y(A)}};return window.addEventListener("message",B),()=>window.removeEventListener("message",B)},[Y]),R(()=>{if(typeof document>"u")return;let B=(D)=>{let N=D.detail;if(!N?.selection)return;z({selection:N.selection,clientX:typeof N.clientX==="number"?N.clientX:0,clientY:typeof N.clientY==="number"?N.clientY:0})};return document.addEventListener("cm:open-composer",B),()=>document.removeEventListener("cm:open-composer",B)},[]);let U=T(()=>{if(z(null),typeof window>"u")return;try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},[]),W=T((B)=>{if(!G)return;let D=G.selection,N={file:D.file,selector:D.selector,index:D.index,dom_path:D.dom_path,tag:D.tag,classes:D.classes,bounds:D.bounds,html_excerpt:D.html,text:B};if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-submit",payload:N},"*")}catch{}U()},[G,U]);R(()=>{if(!X)return;let B=!1;return(async()=>{try{let D=await fetch(`/_comments?file=${encodeURIComponent(X)}`);if(!D.ok)return;let N=await D.json();if(B)return;if(Array.isArray(N.comments))$((M)=>M.length===0?N.comments??[]:M)}catch{}})(),()=>{B=!0}},[X]);let P=s(()=>{return Q.slice().sort((D,N)=>D.created.localeCompare(N.created)).filter((D)=>D.status!=="resolved")},[Q]),H=s(()=>{let B=new Map;return Q.slice().sort((N,M)=>N.created.localeCompare(M.created)).forEach((N,M)=>{B.set(N.id,M+1)}),B},[Q]),j=T((B)=>{if(q(B),Y(Q.find((D)=>D.id===B)),typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-click",id:B},"*")}catch{}},[Q,Y]),I=T((B,D)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-patch",id:B,patch:D},"*")}catch{}},[]),V=T((B)=>{if(typeof window>"u")return;try{window.parent.postMessage({dgn:"comment-delete",id:B},"*")}catch{}q((D)=>D===B?null:D)},[]),K=T(async(B,D)=>{if(typeof fetch>"u")return!1;try{let N=await fetch(`/_api/comments/${encodeURIComponent(B)}/reply`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({body:D})});if(!N.ok)return!1;let M=await N.json();return $((A)=>A.map((F)=>F.id===M.id?M:F)),!0}catch{return!1}},[]);return b("div",{className:"cm-layer","aria-hidden":!1,children:[P.map((B)=>{let D=H.get(B.id)??0;return k(oJ,{comment:B,sequence:D,focused:Z===B.id,onClick:j,onOrphaned:V},B.id)}),G?k(sJ,{state:G,onSubmit:W,onCancel:U}):null,(()=>{if(!Z)return null;let B=P.find((D)=>D.id===Z);if(!B)return null;return k(tJ,{comment:B,sequence:H.get(B.id)??0,onClose:()=>{q(null),J?.clear()},onPatch:(D)=>I(B.id,D),onDelete:()=>V(B.id),onReply:(D)=>K(B.id,D)})})()]})}var _7=null;async function nJ(){if(!_7)_7=(async()=>{try{let J=await fetch("/_api/git-committers");if(!J.ok)return[];let Q=await J.json();return Array.isArray(Q.committers)?Q.committers:[]}catch{return[]}})();return _7}function l7(J){return(J.trim().split(/\s+/)[0]??"").replace(/[^\w.-]/g,"").toLowerCase()}function rJ(J,Q){if(Q<=0||Q>J.length)return null;let $=Q-1;while($>=0){let Z=J[$]??"";if(Z==="@"){let q=$>0?J[$-1]:"";if($===0||/\s/.test(q??"")){let G=J.slice($+1,Q);return{start:$,end:Q,query:G}}return null}if(!/[\w.-]/.test(Z))return null;$-=1}return null}function s7({className:J,value:Q,onChange:$,onKeyDown:Z,placeholder:q,rows:G,disabled:z,textareaRef:X,ariaLabel:Y}){let _=S(null),L=T((F)=>{if(_.current=F,X)X.current=F},[X]),[U,W]=u([]),[P,H]=u(null),[j,I]=u(0),V=T(()=>{if(U.length>0)return;nJ().then((F)=>W(F))},[U.length]),K=s(()=>{if(!P)return[];let F=P.query.toLowerCase();return(!F?U:U.filter((E)=>E.name.toLowerCase().includes(F)||E.email.toLowerCase().includes(F))).slice(0,8)},[P,U]),B=T((F)=>{let O=F.selectionStart??F.value.length,E=rJ(F.value,O);H(E),I(0)},[]),D=T((F)=>{$(F.target.value),B(F.target)},[$,B]),N=T((F)=>{if(!P)return;let O=_.current;if(!O)return;let E=`@${l7(F.name)}`,y=`${Q.slice(0,P.start)}${E} ${Q.slice(P.end)}`;$(y),H(null);let w=P.start+E.length+1;requestAnimationFrame(()=>{O.focus(),O.setSelectionRange(w,w)})},[P,Q,$]),M=T((F)=>{if(P&&K.length>0){if(F.key==="ArrowDown"){F.preventDefault(),I((O)=>(O+1)%K.length);return}if(F.key==="ArrowUp"){F.preventDefault(),I((O)=>(O-1+K.length)%K.length);return}if(F.key==="Enter"||F.key==="Tab"){F.preventDefault();let O=K[j]??K[0];if(O)N(O);return}if(F.key==="Escape"){F.preventDefault(),H(null);return}}Z?.(F)},[P,K,j,N,Z]),A=T((F)=>{B(F.currentTarget)},[B]);return b("div",{style:{position:"relative"},children:[k("textarea",{ref:L,className:J,value:Q,placeholder:q,rows:G,disabled:z,"aria-label":Y,onChange:D,onKeyDown:M,onFocus:V,onSelect:A,onClick:A}),P&&K.length>0?k("ul",{className:"cm-mention-popup",role:"listbox","aria-label":"Mention suggestions",style:{left:0,top:"100%"},children:K.map((F,O)=>{return b("li",{role:"option","aria-selected":O===j,className:"cm-mention-popup__item",onMouseEnter:()=>I(O),onMouseDown:(y)=>{y.preventDefault(),N(F)},children:[b("span",{className:"cm-mention-popup__name",children:["@",l7(F.name)]}),k("span",{className:"cm-mention-popup__email",children:F.email})]},`${F.name}-${F.email}`)})}):null]})}var aJ=3000;function oJ({comment:J,sequence:Q,focused:$,onClick:Z,onOrphaned:q}){let G=S(null),z=S(null),X=S(null);R(()=>{let L=()=>{z.current=null;let U=G.current;if(!U)return;let W=I7(J);if(W)X.current=null;else{if(X.current==null)X.current=Date.now();else if(Date.now()-X.current>aJ)q(J.id);if(J.bounds)W={x:J.bounds.x,y:J.bounds.y,w:J.bounds.w,h:J.bounds.h}}if(!W){U.style.display="none",z.current=requestAnimationFrame(L);return}U.style.display="grid";let P=Math.round(W.x+W.w-12),H=Math.round(W.y-12);U.style.left=`${P}px`,U.style.top=`${H}px`,z.current=requestAnimationFrame(L)};return z.current=requestAnimationFrame(L),()=>{if(z.current!=null)cancelAnimationFrame(z.current)}},[J,q]);let Y=J.author?.trim()||"unknown",_=`Comment ${Q} by ${Y}`;return k("button",{ref:G,type:"button",className:"cm-pin","data-resolved":J.status==="resolved"?"true":"false","data-focused":$?"true":"false","data-comment-pin":J.id,"aria-label":_,"aria-expanded":$,title:J.text.slice(0,200),onClick:(L)=>{L.preventDefault(),L.stopPropagation(),Z(J.id)},children:Q})}function sJ({state:J,onSubmit:Q,onCancel:$}){let[Z,q]=u(""),G=S(null),z=S(null),X=S(null);R(()=>{let U=()=>{X.current=null;let W=z.current;if(!W)return;let P=QQ(J),H=a7(P,{w:W.offsetWidth,h:W.offsetHeight});W.style.left=`${Math.round(H.x)}px`,W.style.top=`${Math.round(H.y)}px`,X.current=requestAnimationFrame(U)};return X.current=requestAnimationFrame(U),()=>{if(X.current!=null)cancelAnimationFrame(X.current)}},[J]),R(()=>{G.current?.focus()},[]);let Y=T(()=>{let U=Z.trim();if(!U)return;Q(U)},[Z,Q]),_=T((U)=>{if(U.key==="Escape"){U.preventDefault(),$();return}if((U.metaKey||U.ctrlKey)&&U.key==="Enter")U.preventDefault(),Y()},[$,Y]),L=s(()=>{let U=J.selection.selector||"";if(!U)return J.selection.tag||"canvas";let W=U.match(/data-cd-id="([^"]+)"/);if(W)return`cd:${W[1]}`;return U.length>36?`${U.slice(0,33)}…`:U},[J.selection]);return b("div",{ref:z,className:"cm-composer",role:"dialog","aria-label":"New comment",onClick:(U)=>U.stopPropagation(),onPointerDown:(U)=>U.stopPropagation(),children:[b("div",{className:"cm-composer__head",children:[k("span",{children:"New comment"}),k("span",{className:"cm-composer__selector",children:L})]}),k(s7,{textareaRef:G,className:"cm-composer__textarea",value:Z,placeholder:"Type a comment. ⌘↵ to save · Esc to cancel · @name to tag",onChange:q,onKeyDown:_,rows:3,ariaLabel:"Comment body"}),b("div",{className:"cm-composer__actions",children:[k("button",{type:"button",className:"cm-btn",onClick:$,children:"Cancel"}),k("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!Z.trim(),onClick:Y,children:"Save"})]})]})}function tJ({comment:J,sequence:Q,onClose:$,onPatch:Z,onDelete:q,onReply:G}){let z=S(null),X=S(null),Y=S(null),[_,L]=u(""),[U,W]=u(!1);R(()=>{let V=()=>{Y.current=null;let K=z.current;if(!K)return;let B=JQ(J),D=a7(B,{w:K.offsetWidth,h:K.offsetHeight});K.style.left=`${Math.round(D.x)}px`,K.style.top=`${Math.round(D.y)}px`,Y.current=requestAnimationFrame(V)};return Y.current=requestAnimationFrame(V),()=>{if(Y.current!=null)cancelAnimationFrame(Y.current)}},[J]),R(()=>{z.current?.focus();let V=J.id;return()=>{document.querySelector(`[data-comment-pin="${V}"]`)?.focus()}},[J.id]),R(()=>{if(typeof document>"u")return;let V=(K)=>{if(K.key!=="Escape")return;let B=z.current;if(!B)return;if(B.contains(K.target)||document.activeElement===B)K.preventDefault(),$()};return document.addEventListener("keydown",V),()=>document.removeEventListener("keydown",V)},[$]);let P=T(async()=>{let V=_.trim();if(!V||U)return;W(!0);let K=await G(V);if(W(!1),K)L(""),X.current?.focus()},[_,U,G]),H=T((V)=>{if((V.metaKey||V.ctrlKey)&&V.key==="Enter")V.preventDefault(),P()},[P]),j=`cm-thread-head-${J.id}`,I=eJ(J.selector,"");return b("div",{ref:z,className:"cm-thread",role:"dialog","aria-labelledby":j,tabIndex:-1,onClick:(V)=>V.stopPropagation(),onPointerDown:(V)=>V.stopPropagation(),children:[b("div",{className:"cm-thread__head",id:j,children:[b("div",{className:"cm-thread__head-row",children:[k("span",{className:"cm-thread__seq","aria-hidden":"true",children:Q}),k("span",{className:"cm-thread__author",children:J.author?.trim()||"unknown"}),k("span",{className:"cm-thread__time",children:r7(J.created)}),k("button",{type:"button",className:"cm-thread__close","aria-label":"Close thread",title:"Close · Esc",onClick:$,children:"×"})]}),I?k("code",{className:"cm-thread__selector",children:I}):null]}),k("div",{className:"cm-thread__body",children:n7(J.text)}),(J.thread??[]).map((V)=>b("div",{className:"cm-thread__reply",children:[b("div",{className:"cm-thread__reply-head",children:[k("span",{className:"cm-thread__reply-author",children:V.author?.trim()||"unknown"}),k("span",{className:"cm-thread__reply-time",children:r7(V.created)})]}),k("div",{className:"cm-thread__reply-body",children:n7(V.body)})]},V.id)),!B7()&&b($Q,{children:[b("div",{className:"cm-thread__reply-form",children:[k(s7,{textareaRef:X,className:"cm-thread__reply-textarea",value:_,placeholder:"Reply… ⌘↵ to send · @name to tag",onChange:L,onKeyDown:H,rows:2,ariaLabel:"Reply",disabled:U}),k("div",{className:"cm-thread__reply-actions",children:k("button",{type:"button",className:"cm-btn cm-btn--primary",disabled:!_.trim()||U,onClick:()=>void P(),children:"Send"})})]}),b("div",{className:"cm-thread__actions",children:[J.status==="resolved"?k("button",{type:"button",className:"cm-btn",onClick:()=>Z({status:"open"}),children:"↺ Reopen"}):k("button",{type:"button",className:"cm-btn cm-btn--primary",onClick:()=>{Z({status:"resolved"}),$()},children:"✓ Resolve"}),k("button",{type:"button",className:"cm-btn cm-btn--danger",onClick:()=>{q(),$()},children:"Delete"})]})]})]})}function n7(J){if(!J)return null;let Q=/(@[\w][\w.-]*)/g;return J.split(Q).map((Z,q)=>{let G=`${q}:${Z}`;if(q%2===1)return k("strong",{"data-mention":"true",children:Z},G);return k("span",{children:Z},G)})}function r7(J){if(!J)return"";let Q=Date.parse(J);if(!Number.isFinite(Q))return"";let $=Math.round((Date.now()-Q)/1000);if($<60)return`${Math.max($,0)}s ago`;if($<3600)return`${Math.round($/60)}m ago`;if($<86400)return`${Math.round($/3600)}h ago`;return`${Math.round($/86400)}d ago`}function eJ(J,Q){if(!J)return Q;let $=J.match(/data-cd-id="([^"]+)"/);if($)return`cd:${$[1]}`;return J.length>36?`${J.slice(0,33)}…`:J}function JQ(J){let Q=J.selector?I7(J):null;if(Q)return{x:Q.x+Q.w-12,y:Q.y+16};if(J.bounds)return{x:J.bounds.x+J.bounds.w-12,y:J.bounds.y+16};return{x:16,y:16}}function QQ(J){if(J.clientX||J.clientY)return{x:J.clientX,y:J.clientY+8};if(J.selection.selector){let Q=I7(J.selection);if(Q)return{x:Q.x,y:Q.y+Q.h+8}}return{x:16,y:16}}import{useEffect as VQ}from"react";var ZQ=new Set(["pen","highlighter","shape","rect","ellipse","arrow","sticky","text","section","eraser"]);function A7(J){return ZQ.has(J)}var t=(J)=>!!(J.metaKey||J.ctrlKey);function e(J){if(J.type==="keydown"){if(J.isEditable)return{kind:"no-op"};if(J.metaKey||J.ctrlKey||J.altKey){if(J.key==="Escape")return{kind:"escape"};let $=(J.key||"").toLowerCase();if(!J.altKey&&(J.metaKey||J.ctrlKey)){if($==="z"&&J.shiftKey)return{kind:"redo"};if($==="z")return{kind:"undo"};if($==="y"&&!J.shiftKey)return{kind:"redo"}}return{kind:"no-op"}}let Q=(J.key||"").toLowerCase();if(Q==="v")return{kind:"tool",tool:"move"};if(Q==="h")return{kind:"tool",tool:"hand"};if(Q==="c")return{kind:"tool",tool:"comment"};if(Q==="b")return{kind:"tool",tool:"pen"};if(Q==="i")return{kind:"tool",tool:"highlighter"};if(Q==="r"||Q==="o")return{kind:"tool",tool:"shape"};if(Q==="a")return{kind:"tool",tool:"arrow"};if(Q==="n")return{kind:"tool",tool:"sticky"};if(Q==="t")return{kind:"tool",tool:"text"};if(Q==="s"&&J.shiftKey)return{kind:"tool",tool:"section"};if(Q==="e")return{kind:"tool",tool:"eraser"};if(J.key==="Escape")return{kind:"escape"};return{kind:"no-op"}}if(J.type==="contextmenu")return{kind:"context-menu",clientX:J.clientX??0,clientY:J.clientY??0};if(J.type==="pointermove"){if(A7(J.activeTool))return{kind:"no-op"};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!t(J))return{kind:"no-op"};return{kind:"hover",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0}}if(J.activeTool==="comment")return{kind:"hover",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0};return{kind:"hover",deep:t(J),clientX:J.clientX??0,clientY:J.clientY??0}}if(J.type==="pointerdown"){if(J.button===2)return{kind:"context-menu",clientX:J.clientX??0,clientY:J.clientY??0};if(J.button===1||J.spaceHeld)return{kind:"no-op"};if(J.button!==0)return{kind:"no-op"};if(A7(J.activeTool)&&!t(J))return{kind:"no-op"};if(J.activeTool==="comment")return{kind:"drop-comment",clientX:J.clientX??0,clientY:J.clientY??0};if(J.activeTool==="hand")return{kind:"no-op"};if(J.activeTool==="browse"){if(!t(J))return{kind:"no-op"};return{kind:"select",mode:J.shiftKey?"add":"replace",deep:!0,clientX:J.clientX??0,clientY:J.clientY??0}}let Q=t(J);return{kind:"select",mode:!!J.shiftKey?"add":"replace",deep:Q,clientX:J.clientX??0,clientY:J.clientY??0}}return{kind:"no-op"}}function z7(J){if(!J||!J.tagName)return!1;let Q=J,$=Q.tagName;if($==="INPUT"||$==="TEXTAREA"||$==="SELECT")return!0;if(Q.isContentEditable)return!0;let Z=Q.getAttribute?.("contenteditable");if(Z==="true"||Z==="plaintext-only"||Z==="")return!0;return!1}function J7(J){if(!J||!J.closest)return!1;let Q=J;if(Q.closest(".dc-world"))return!1;return!!Q.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mediaref-player], .dc-tool-palette, .dc-zoom-tb, .dc-mm, .dc-context-menu")}function e7(J){if(!J||typeof J.closest!=="function")return!1;let Q=J;return!!Q.closest("[data-dc-screen]")&&!Q.closest(".dc-artboard-body")}function t7(J,Q,$){return J.kind==="select"&&!$.metaKey&&!$.ctrlKey&&e7(Q)}function qQ(J,Q,$){return J==="select"&&!$.metaKey&&!$.ctrlKey&&e7(Q)}function JJ(J){let{hostRef:Q,getActiveTool:$,isSpaceHeld:Z,callbacks:q,enabled:G=!0,claimableActions:z}=J;VQ(()=>{if(!G)return;let X=Q.current;if(!X)return;let Y=(V)=>z&&V.kind!=="no-op"&&!z.has(V.kind)?{kind:"no-op"}:V,_=(V)=>{switch(V.kind){case"hover":q.onHover?.(V);break;case"select":q.onSelect?.(V);break;case"drop-comment":q.onDropComment?.(V);break;case"context-menu":q.onContextMenu?.(V);break;case"tool":q.onTool?.(V);break;case"escape":q.onEscape?.();break;case"undo":q.onUndo?.();break;case"redo":q.onRedo?.();break;case"no-op":break}},L=(V)=>{let K=Y(e({type:"pointermove",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()}));_(K)},U=(V)=>{if(J7(V.target))return;if(z7(V.target))return;let K=Y(e({type:"pointerdown",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()})),B=t7(K,V.target,V);if(K.kind!=="no-op"){if(V.preventDefault(),!B)V.stopImmediatePropagation()}_(K)},W=(V)=>{if(J7(V.target))return;if(z7(V.target))return;let K=Y(e({type:"pointerdown",button:V.button,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,clientX:V.clientX,clientY:V.clientY,spaceHeld:Z?.()??!1,activeTool:$()})),B=t7(K,V.target,V);if(K.kind!=="no-op"){if(V.preventDefault(),!B)V.stopImmediatePropagation();if(K.kind==="select")try{window.focus()}catch{}}},P=(V)=>{if(J7(V.target))return;if(z7(V.target))return;let K=$(),B=V.metaKey||V.ctrlKey,D=K==="comment"?"drop-comment":K==="move"&&V.button===0?"select":(A7(K)||K==="browse")&&B&&V.button===0?"select":V.button===2?"context-menu":null;if(D&&(!z||z.has(D))){let N=qQ(D,V.target,V);if(V.preventDefault(),!N)V.stopImmediatePropagation()}},H=(V)=>{let K=Y(e({type:"contextmenu",clientX:V.clientX,clientY:V.clientY,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,activeTool:$()}));if(K.kind==="no-op")return;V.preventDefault(),V.stopImmediatePropagation(),_(K)},j=(V)=>{let K=Y(e({type:"keydown",key:V.key,metaKey:V.metaKey,ctrlKey:V.ctrlKey,shiftKey:V.shiftKey,altKey:V.altKey,isEditable:z7(V.target),activeTool:$()}));if(K.kind==="tool"||K.kind==="escape"||K.kind==="undo"||K.kind==="redo")V.preventDefault();_(K)};X.addEventListener("pointermove",L,{passive:!0}),X.addEventListener("pointerdown",U,{capture:!0}),X.addEventListener("mousedown",W,{capture:!0}),X.addEventListener("click",P,{capture:!0}),X.addEventListener("contextmenu",H,{capture:!0});let I=X.ownerDocument??document;return I.addEventListener("keydown",j,!0),()=>{X.removeEventListener("pointermove",L),X.removeEventListener("pointerdown",U,{capture:!0}),X.removeEventListener("mousedown",W,{capture:!0}),X.removeEventListener("click",P,{capture:!0}),X.removeEventListener("contextmenu",H,{capture:!0}),I.removeEventListener("keydown",j,!0)}},[G,Q,$,Z,q,z])}function O7(J,Q,$,Z){let q=J.elementFromPoint(Q,$);if(!q)return null;if(q.closest?.(".dc-mm, .dc-zoom-tb, .dc-tool-palette, .dc-context-menu, .dc-cv-group-bbox"))return null;let G=q.closest?.("[data-dc-screen]")??null,z=G?.getAttribute("data-dc-screen")??null,X=q.closest?.(".dc-artboard-body")??null;if(!X){if(G&&z)return{el:G,cdId:null,artboardId:z};return null}if(q===X){if(G&&z)return{el:G,cdId:null,artboardId:z};return null}if(Z.deep){let W=q.getAttribute?.("data-cd-id")??null;return{el:q,cdId:W,artboardId:z}}let Y=q,_=null;while(Y&&Y!==X){if(Y.hasAttribute?.("data-cd-id"))_=Y;Y=Y.parentElement}let L=_??q,U=L.getAttribute?.("data-cd-id")??null;return{el:L,cdId:U,artboardId:z}}import{useCallback as _Q,useEffect as WJ,useRef as Y7}from"react";var GQ=!1;function QJ(){return GQ}import{createContext as FQ,useCallback as $7,useContext as GJ,useEffect as PQ,useMemo as VJ,useState as U7}from"react";function m(J,Q,$,Z){return`url("data:image/svg+xml,${encodeURIComponent(J.trim())}") ${Q} ${$}, ${Z}`}var T7="width='24' height='24' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'",E7="#1f1f1f",k7="stroke='#ffffff' stroke-linejoin='round' stroke-linecap='round'";function i(J,Q,$){let Z=$?`<g transform='${$}'>`:"";return`<svg ${T7}>${Z}<path fill='#ffffff' d='${J}'/><path fill='${E7}' d='${Q}'/>${$?"</g>":""}</svg>`}var $J="translate(0,32) scale(1,-1)",BQ=m(i("M10.25 8.25 L10.05 8.65 10 9 10 23.1 10.05 23.4 10.25 23.75 10.8 24 11.45 23.85 11.6 23.7 11.75 23.45 14.65 19.8 14.85 19.65 14.95 19.5 15.4 19.2 15.95 19.1 21.05 19.1 21.2 19.1 21.35 19.05 21.65 18.9 21.9 18.6 22 18.3 22 17.9 21.9 17.65 21.75 17.35 21.65 17.3 21.55 17.15 11.5 8.25 11.25 8.05 10.95 8 10.6 8.05 10.25 8.25 M9.15 6.6 L9.7 6.25 10 6.15 10.95 6 11.9 6.15 13 6.9 22.9 15.65 23 15.8 23.2 15.95 23.75 16.75 24 17.9 24 18.3 23.9 18.95 23.8 19.25 23.6 19.7 23.1 20.35 22.75 20.6 22.1 20.9 22.05 20.95 22 20.95 21.2 21.1 21.05 21.1 16.2 21.1 16.1 21.25 16.05 21.25 13.4 24.6 13.05 25.15 12.9 25.3 12.55 25.55 Q11.6 26.15 10.55 26 L10.5 26 Q9.65 25.85 9 25.3 L8.45 24.65 8.4 24.5 8.15 24.05 8 23.1 8 9 Q8 8.45 8.15 8.05 L8.25 7.75 8.45 7.35 9.15 6.6","M10.25 8.25 L10.6 8.05 10.95 8 11.25 8.05 11.5 8.25 21.55 17.15 21.65 17.3 21.75 17.35 21.9 17.65 22 17.9 22 18.3 21.9 18.6 21.65 18.9 21.35 19.05 21.2 19.1 21.05 19.1 15.95 19.1 15.4 19.2 14.95 19.5 14.85 19.65 14.65 19.8 11.75 23.45 11.6 23.7 11.45 23.85 10.8 24 10.25 23.75 10.05 23.4 10 23.1 10 9 10.05 8.65 10.25 8.25"),8,5,"default"),WQ=m(i("M28.55 17.8 Q29.4 20.3 28.75 22.8 L28.7 23 28.15 24.55 28.05 24.75 Q26.4 28.2 22.75 29.4 L22.45 29.5 18 29.9 17.75 29.85 Q15.8 29.25 13.8 28.1 L13.45 27.95 Q12 27.05 10.35 26.8 L10.25 26.75 7.9 26.7 7.8 26.7 Q6.1 26.9 4.8 25.8 L4.75 25.8 4.65 25.7 4.6 25.65 Q3.25 24.5 3.05 22.85 L3 22.75 Q2.8 20.95 4 19.5 5.05 18.15 6.75 17.95 L8.4 17.9 7.5 15.55 7.3 15.2 7.2 15 5 10.95 Q3.9 9.15 4.3 7.75 L4.4 7.5 Q4.75 6.15 6.45 5.2 9 3.65 11 5 11.05 4.1 11.5 3.45 12.15 2.1 14.2 1.6 L14.35 1.6 Q18.05 0.6 19.6 4.4 L19.65 4.55 Q20.75 3.65 22.7 3.75 L22.75 3.75 Q26.75 4 27 8.15 L27 8.25 27 8.35 27 8.45 Q26.9 10.75 27.1 12.6 27.15 14.65 28.2 16.75 L28.55 17.8 M26.65 18.4 L26.1 16.8 26.1 16.85 Q24.8 13.7 25 8.35 L25 8.25 Q24.85 5.9 22.6 5.75 20.7 5.65 20.4 7.35 L20.1 7.95 19.5 8.2 18.85 8.05 18.45 7.5 17.75 5.15 Q16.85 2.95 14.7 3.55 L14.65 3.55 Q12.55 4.05 13.15 6.15 L13.85 8.75 13.75 9.45 13.25 9.95 12.55 9.95 12 9.55 10.9 7.7 Q9.5 5.7 7.45 6.9 6.5 7.45 6.25 8.15 6.1 8.9 6.7 9.85 9.2 13.9 10.8 18.65 L10.8 19.3 10.4 19.8 9.75 19.95 Q8.35 19.8 6.95 19.95 6.1 20.05 5.55 20.75 4.9 21.55 5 22.55 5.15 23.55 6 24.2 L6.05 24.25 Q6.75 24.85 7.65 24.7 L7.7 24.7 10.65 24.8 Q12.7 25.15 14.45 26.2 L14.5 26.2 Q16.4 27.35 18.3 27.9 L22.05 27.5 22.1 27.5 Q24.95 26.55 26.25 23.85 L26.8 22.3 Q27.3 20.35 26.65 18.4","M26.65 18.4 Q27.3 20.35 26.8 22.3 L26.25 23.85 Q24.95 26.55 22.1 27.5 L22.05 27.5 18.3 27.9 Q16.4 27.35 14.5 26.2 L14.45 26.2 Q12.7 25.15 10.65 24.8 L7.7 24.7 7.65 24.7 Q6.75 24.85 6.05 24.25 L6 24.2 Q5.15 23.55 5 22.55 4.9 21.55 5.55 20.75 6.1 20.05 6.95 19.95 8.35 19.8 9.75 19.95 L10.4 19.8 10.8 19.3 10.8 18.65 Q9.2 13.9 6.7 9.85 6.1 8.9 6.25 8.15 6.5 7.45 7.45 6.9 9.5 5.7 10.9 7.7 L12 9.55 12.55 9.95 13.25 9.95 13.75 9.45 13.85 8.75 13.15 6.15 Q12.55 4.05 14.65 3.55 L14.7 3.55 Q16.85 2.95 17.75 5.15 L18.45 7.5 18.85 8.05 19.5 8.2 20.1 7.95 20.4 7.35 Q20.7 5.65 22.6 5.75 24.85 5.9 25 8.25 L25 8.35 Q24.8 13.7 26.1 16.85 L26.1 16.8 26.65 18.4"),12,12,"grab"),KQ=m(i("M28 14 Q28 9.85 24.45 6.9 20.95 4 16 4 11.05 4 7.5 6.9 L7.45 7 Q4 9.9 4 14 4 18.15 7.55 21.05 L7.5 21.05 Q9.2 22.45 11.2 23.2 L15.3 27.3 16 27.6 16.7 27.3 20.85 23.2 Q22.7 22.45 24.3 21.15 L24.45 21.05 Q28 18.15 28 14 M25.75 5.35 Q30.05 8.95 30 14 30.05 19.05 25.75 22.6 L25.4 22.85 Q23.8 24.1 22 24.9 L18.1 28.75 18.15 28.75 Q17.2 29.6 16 29.6 14.8 29.6 13.85 28.75 L13.9 28.75 10 24.9 6.6 22.85 6.25 22.6 Q1.95 19.05 2 14 1.95 8.95 6.25 5.35 10.3 2 16 2 21.7 2 25.75 5.35","M28 14 Q28 18.15 24.45 21.05 L24.3 21.15 Q22.7 22.45 20.85 23.2 L16.7 27.3 16 27.6 15.3 27.3 11.2 23.2 Q9.2 22.45 7.5 21.05 L7.55 21.05 Q4 18.15 4 14 4 9.9 7.45 7 L7.5 6.9 Q11.05 4 16 4 20.95 4 24.45 6.9 28 9.85 28 14"),12,21,"crosshair"),zQ=m(i("M4 13.1 L4 6 Q4 5.15 4.6 4.6 5.15 4 6 4 L13.1 4 Q13.95 4 14.55 4.6 L28.65 18.75 Q29.8 19.9 29.75 21.45 L29.75 21.6 29.75 21.7 Q29.75 23.2 28.7 24.35 L24.45 28.65 24.35 28.75 Q23.15 29.85 21.65 29.8 L21.55 29.8 21.4 29.8 Q20.2 29.8 19.25 29.15 L18 29.35 Q16.6 29.4 15.25 28 L15.2 27.95 8.2 20.95 Q7.6 20.35 7.6 19.55 7.6 18.7 8.2 18.1 L4.6 14.5 Q4 13.9 4 13.1 M19.5 26.65 L20.1 27.25 Q20.7 27.85 21.5 27.8 22.35 27.85 23 27.25 L27.25 22.95 Q27.8 22.35 27.75 21.55 27.8 20.75 27.2 20.15 L13.1 6 6 6 6 13.1 12.35 19.45 9.6 19.5 16.65 26.55 Q18.05 28.05 19.5 26.65 M8.05 12.3 L8 8 12.25 8.05 13.8 9.6 9.6 13.85 8.05 12.3 M15.25 11.05 L23 18.8 18.8 23.05 11.05 15.3 15.25 11.05","M15.25 11.05 L11.05 15.3 18.8 23.05 23 18.8 15.25 11.05 M12.35 19.45 L6 13.1 6 6 13.1 6 27.2 20.15 Q27.8 20.75 27.75 21.55 27.8 22.35 27.25 22.95 L23 27.25 Q22.35 27.85 21.5 27.8 20.7 27.85 20.1 27.25 L19.5 26.65 12.35 19.45 M8.05 12.3 L9.6 13.85 13.8 9.6 12.25 8.05 8 8 8.05 12.3",$J),6,18,"crosshair"),UQ=m(i("M5.15 10.85 Q4 9.65 4 8.1 L4 7.95 4 7.85 Q3.95 6.2 5.1 5.15 6.25 4 7.85 4 L7.95 4 8.1 4 Q9.65 4 10.85 5.15 L11 5.3 14.3 5.25 Q15.15 5.25 15.75 5.85 L29.9 20 Q31 21.15 31 22.75 L31 22.85 31 23 Q31.05 24.5 29.9 25.7 L29.55 25.95 25.65 29.9 25.65 29.95 Q24.45 31.1 22.75 31.1 21.2 31.15 20 29.95 L5.85 15.8 Q5.25 15.2 5.25 14.35 L5.25 10.95 5.15 10.85 M19.95 24.2 L18.55 22.8 22.8 18.55 24.2 19.95 19.95 24.2 M28.45 21.4 L14.3 7.25 10.15 7.3 9.4 6.55 Q8.8 5.95 7.95 6 7.1 5.95 6.5 6.55 5.95 7.1 6 7.95 5.95 8.8 6.55 9.4 L7.25 10.1 7.25 14.35 21.4 28.5 Q22 29.1 22.75 29.1 23.6 29.1 24.2 28.5 L28.45 24.25 Q29.05 23.65 29 22.85 29.05 22 28.45 21.4 M9.25 13.5 L9.25 9.3 13.5 9.25 14.3 10.05 10.05 14.3 9.25 13.5 M17.15 21.4 L11.5 15.75 15.75 11.5 21.4 17.15 17.15 21.4","M17.15 21.4 L21.4 17.15 15.75 11.5 11.5 15.75 17.15 21.4 M28.45 21.4 Q29.05 22 29 22.85 29.05 23.65 28.45 24.25 L24.2 28.5 Q23.6 29.1 22.75 29.1 22 29.1 21.4 28.5 L7.25 14.35 7.25 10.1 6.55 9.4 Q5.95 8.8 6 7.95 5.95 7.1 6.5 6.55 7.1 5.95 7.95 6 8.8 5.95 9.4 6.55 L10.15 7.3 14.3 7.25 28.45 21.4 M19.95 24.2 L24.2 19.95 22.8 18.55 18.55 22.8 19.95 24.2 M9.25 13.5 L10.05 14.3 14.3 10.05 13.5 9.25 9.25 9.3 9.25 13.5",$J),6,18,"crosshair"),Q7=m(i("M17 2 Q18.2 2 19.15 2.9 20 3.8 20 5 L20 12 27 12 Q28.2 12 29.15 12.9 30 13.8 30 15 L30 17 Q30 18.2 29.15 19.15 28.2 20 27 20 L20 20 20 27 Q20 28.2 19.15 29.15 18.2 30 17 30 L15 30 Q13.8 30 12.9 29.15 12 28.2 12 27 L12 20 5 20 Q3.8 20 2.9 19.15 2 18.2 2 17 L2 15 Q2 13.8 2.9 12.9 3.8 12 5 12 L12 12 12 5 Q12 3.8 12.9 2.9 13.8 2 15 2 L17 2 M14 27 L14.3 27.7 Q14.6 28 15 28 L17 28 17.7 27.7 18 27 18 18.05 18.05 18 27 18 Q27.4 18 27.7 17.7 L28 17 28 15 27.7 14.3 Q27.4 14 27 14 L18 14 18 5 17.7 4.3 17 4 15 4 Q14.6 4 14.3 4.3 14 4.6 14 5 L14 14 5 14 Q4.6 14 4.3 14.3 4 14.6 4 15 L4 17 Q4 17.4 4.3 17.7 4.6 18 5 18 L14 18 14 27","M14 27 L14 18 5 18 Q4.6 18 4.3 17.7 4 17.4 4 17 L4 15 Q4 14.6 4.3 14.3 4.6 14 5 14 L14 14 14 5 Q14 4.6 14.3 4.3 14.6 4 15 4 L17 4 17.7 4.3 18 5 18 14 27 14 Q27.4 14 27.7 14.3 L28 15 28 17 27.7 17.7 Q27.4 18 27 18 L18.05 18 18 18.05 18 27 17.7 27.7 17 28 15 28 Q14.6 28 14.3 27.7 L14 27"),12,12,"crosshair"),XQ=m(i("M3.9 11.35 Q2.3 12.5 3.7 13.9 L16.4 26.65 Q17.85 28.05 19.45 26.9 L27.65 21.15 Q29.3 20 27.85 18.6 L15.15 5.85 Q13.75 4.45 12.1 5.6 L3.9 11.35 M1.05 12.4 Q1 10.95 2.75 9.75 L10.95 4 10.95 3.95 Q14 1.85 16.6 4.45 L29.3 17.2 Q30.8 18.65 30.55 20.1 30.55 21.55 28.8 22.8 L20.6 28.55 20.65 28.55 Q17.7 30.65 15 28.1 L15 28.05 2.3 15.3 2.3 15.35 Q0.8 13.85 1.05 12.4 M13.5 7 L19.85 13.35 11.65 19.15 5.3 12.75 13.5 7","M13.5 7 L5.3 12.75 11.65 19.15 19.85 13.35 13.5 7 M3.9 11.35 L12.1 5.6 Q13.75 4.45 15.15 5.85 L27.85 18.6 Q29.3 20 27.65 21.15 L19.45 26.9 Q17.85 28.05 16.4 26.65 L3.7 13.9 Q2.3 12.5 3.9 11.35"),6,14,"cell"),YQ=m(`<svg ${T7}><path d='M16 4V28M11 4H21M11 28H21' fill='none' ${k7} stroke-width='5'/><path d='M16 4V28M11 4H21M11 28H21' fill='none' stroke='${E7}' stroke-width='2.25' stroke-linecap='round'/></svg>`,12,12,"text"),HQ=m(`<svg ${T7}><path d='M6 5H21L26 10V27H6Z' fill='${E7}' ${k7} stroke-width='2.5'/><path d='M21 5V11H26' fill='none' ${k7} stroke-width='2.25'/></svg>`,5,5,"crosshair"),C=Object.freeze({browse:"default",move:BQ,hand:WQ,comment:KQ,pen:zQ,section:Q7,highlighter:UQ,shape:Q7,rect:Q7,ellipse:Q7,sticky:HQ,arrow:Q7,text:YQ,eraser:XQ});import{jsx as w7,Fragment as MQ}from"react/jsx-runtime";var ZJ=Object.freeze({preview:"browse",edit:"move"});function qJ(J){if(J==="browse")return"preview";if(J==="move")return"edit";return null}var DQ=Object.freeze([{id:"browse",label:"Browse",shortcut:"",cursor:C.browse},{id:"move",label:"Select",shortcut:"V",cursor:C.move},{id:"hand",label:"Hand",shortcut:"H",cursor:C.hand},{id:"comment",label:"Comment",shortcut:"C",cursor:C.comment},{id:"pen",label:"Pen",shortcut:"B",cursor:C.pen},{id:"highlighter",label:"Highlighter",shortcut:"I",cursor:C.highlighter},{id:"shape",label:"Shape",shortcut:"R",cursor:C.shape},{id:"sticky",label:"Sticky",shortcut:"N",cursor:C.sticky},{id:"section",label:"Section",shortcut:"⇧S",cursor:C.shape},{id:"arrow",label:"Arrow",shortcut:"A",cursor:C.arrow},{id:"text",label:"Text",shortcut:"T",cursor:C.text},{id:"eraser",label:"Eraser",shortcut:"E",cursor:C.eraser}]),jQ=new Set(["browse","move","hand"]);function LQ(J,Q){return Q?J.filter(($)=>jQ.has($.id)):J}var x7=FQ(null);function NQ({children:J,tools:Q=DQ,initial:$,initialMode:Z}){let q=B7(),G=VJ(()=>LQ(Q,q),[Q,q]),z=$??(q?"browse":"move"),X=Z??qJ(z)??(q?"preview":"edit"),[Y,_]=U7(z),[L,U]=U7(X),[W,P]=U7(()=>({tool:null,locked:!1})),H=$7((M)=>{if(!G.some((F)=>F.id===M))return;_(M);let A=qJ(M);if(A)U(A);P((F)=>F.locked&&F.tool===M?F:{tool:null,locked:!1})},[G]),j=$7((M)=>{let A=ZJ[M];if(!G.some((F)=>F.id===A))return;U(M),_(A),P((F)=>F.locked&&F.tool===A?F:{tool:null,locked:!1})},[G]),I=$7(()=>{H(ZJ[L])},[L,H]),V=$7((M)=>{P((A)=>{if(A.locked&&A.tool===M)return{tool:null,locked:!1};return{tool:M,locked:!0}}),_(M)},[]),K=$7(()=>{P({tool:null,locked:!1})},[]),[B,D]=U7("rounded");PQ(()=>{if(typeof document>"u")return;let M=G.find((O)=>O.id===Y);if(!M)return;let A=document.body.style.cursor,F=document.getElementById("dc-tool-cursor");if(!F)F=document.createElement("style"),F.id="dc-tool-cursor",document.head.appendChild(F);if(Y==="browse"){if(document.body.style.cursor="",F.textContent="",typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:Y},"*")}catch{}return()=>{document.body.style.cursor=A}}if(document.body.style.cursor=M.cursor,F.textContent=`* { cursor: ${M.cursor} !important; }`,typeof window<"u"&&window.parent&&window.parent!==window)try{window.parent.postMessage({dgn:"tool-cursor",tool:Y},"*")}catch{}return()=>{document.body.style.cursor=A;let O=document.getElementById("dc-tool-cursor");if(O)O.textContent=""}},[Y,G]);let N=VJ(()=>({tool:Y,setTool:H,tools:G,mode:L,setMode:j,resetTool:I,sticky:W,toggleSticky:V,clearSticky:K,shapeKind:B,setShapeKind:D}),[Y,H,G,L,j,I,W,V,K,B]);return w7(x7.Provider,{value:N,children:J})}function BJ({children:J,initial:Q,initialMode:$}){if(GJ(x7))return w7(MQ,{children:J});return w7(NQ,{initial:Q,initialMode:$,children:J})}function X7(){let J=GJ(x7);if(!J)throw Error("useToolMode must be used inside <ToolProvider>");return J}import{jsx as CQ}from"react/jsx-runtime";var IQ=`
|
|
2
2
|
.dc-el-resize-handle {
|
|
3
3
|
position: fixed;
|
|
4
4
|
width: 8px;
|
|
@@ -56,4 +56,4 @@ import{Component as vQ,createElement as g,Fragment as CQ,useCallback as x7,useEf
|
|
|
56
56
|
@media (prefers-reduced-motion: reduce) {
|
|
57
57
|
.dc-el-resize-handle, .dc-el-resize-readout { transition-duration: 1ms; }
|
|
58
58
|
}
|
|
59
|
-
`.trim();function _Q(){if(typeof document>"u")return;if(document.getElementById("dc-el-resize-css"))return;let J=document.createElement("style");J.id="dc-el-resize-css",J.textContent=NQ,document.head.appendChild(J)}var IQ=["nw","n","ne","e","se","s","sw","w"];function AQ(J){return{movesLeft:J==="nw"||J==="w"||J==="sw",movesRight:J==="ne"||J==="e"||J==="se",movesTop:J==="nw"||J==="n"||J==="ne",movesBottom:J==="sw"||J==="s"||J==="se"}}var n=(J)=>Math.round(J*100)/100,U7=1;function OQ(J,Q,$,Z,q,G){let{movesLeft:K,movesRight:z,movesTop:H,movesBottom:j}=AQ(J),L=q.center,U=Q.w,B=Q.h;if(z)U=Q.w+(L?2*$:$);else if(K)U=Q.w-(L?2*$:$);if(j)B=Q.h+(L?2*Z:Z);else if(H)B=Q.h-(L?2*Z:Z);if(q.aspect&&Q.w>0&&Q.h>0){let Y=Q.w/Q.h;if((K||z)&&(H||j)){let _=Math.abs(U-Q.w)/Q.w,V=Math.abs(B-Q.h)/Q.h;if(_>=V)B=U/Y;else U=B*Y}else if(K||z)B=U/Y;else if(H||j)U=B*Y}if(U<U7)U=U7;if(B<U7)B=U7;let F={width:n(U),height:n(B)};if(L){if(G.canMoveLeft&&(K||z))F.left=n(Q.left+(Q.w-U)/2);if(G.canMoveTop&&(H||j))F.top=n(Q.top+(Q.h-B)/2)}else{if(G.canMoveLeft&&K)F.left=n(Q.left+Q.w-U);if(G.canMoveTop&&H)F.top=n(Q.top+Q.h-B)}return F}function BJ(J){if(!J||J==="none")return 0;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 0;let $=Q[1].split(",").map(Number),Z=$[0]??1,q=$[1]??0;return Math.round(Math.atan2(q,Z)*(180/Math.PI)*100)/100}function TQ(J){if(!J||J==="none")return 1;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 1;let $=Q[1].split(",").map(Number),Z=$[0]??1,q=$[1]??0,G=Math.hypot(Z,q);return G>0?G:1}function kQ(J){let Q=J.closest(".dc-world");if(!Q)return 1;let $=getComputedStyle(Q),Z=Number.parseFloat($.zoom||"1")||1;return TQ($.transform)*Z}function WJ(J,Q,$){let Z=$*Math.PI/180,q=Math.cos(Z),G=Math.sin(Z);return[J*q-Q*G,J*G+Q*q]}function KJ(J,Q,$,Z){return Math.atan2(Z-Q,$-J)}function EQ(J,Q,$,Z){let q=J+($-Q)*(180/Math.PI);while(q>180)q-=360;while(q<=-180)q+=360;if(Z)q=Math.round(q/15)*15;return Math.round(q*100)/100}function wQ(J,Q){let $={width:`${Q.width}px`,height:`${Q.height}px`};if(typeof Q.left==="number")$.left=`${Q.left}px`;if(typeof Q.top==="number")$.top=`${Q.top}px`;try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:$,before:J.before,idIndex:J.idIndex},"*")}catch{}}function bQ(J,Q){if(!J.artboardId)return;try{window.parent.postMessage({dgn:"resize-artboard-request",artboardId:J.artboardId,width:Q.width,height:Q.height},"*")}catch{}}function xQ(J,Q){try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:{transform:Q},before:J.before,idIndex:J.idIndex},"*")}catch{}}function XJ(){_Q();let{selected:J}=W7(),{tool:Q}=X7(),$=z7(null),Z=z7(null),q=z7(null),G=z7(null),K=J.length===1?J[0]:null,z=K&&typeof K.id==="string"?K.id:null,H=K&&!z&&typeof K.artboardId==="string"?K.artboardId:null,j=Q==="move"&&(!!z||!!H);GJ(()=>{let U=$.current;if(!U)return;let B=()=>{for(let Y of Array.from(U.children)){let D=Y;D.style.opacity="0",D.style.pointerEvents="none"}};if(!j||!K){B();return}let F=()=>{if(Z.current=null,QJ()){B(),Z.current=requestAnimationFrame(F);return}let Y=F7(document,K);if(!Y){B(),Z.current=requestAnimationFrame(F);return}let D=Y.getBoundingClientRect();if(D.width<=0&&D.height<=0){B(),Z.current=requestAnimationFrame(F);return}let _=H?["e","s","se"]:IQ,V=H?[]:["rot-nw","rot-ne","rot-sw","rot-se"],X=_.length+V.length+1;while(U.children.length<X)U.appendChild(document.createElement("div"));while(U.children.length>X)U.lastChild&&U.removeChild(U.lastChild);let W=D.left+D.width/2,P=D.top+D.height/2,N=BJ(getComputedStyle(Y).transform),I=kQ(Y),A=Y.offsetWidth*I/2,M=Y.offsetHeight*I/2,T={nw:[-A,-M],n:[0,-M],ne:[A,-M],e:[A,0],se:[A,M],s:[0,M],sw:[-A,M],w:[-A,0],"rot-nw":[-A,-M],"rot-ne":[A,-M],"rot-sw":[-A,M],"rot-se":[A,M]},E=[...V,..._];for(let h=0;h<E.length;h++){let b=E[h],v=U.children[h],[d,c]=T[b]??[0,0],[FJ,PJ]=WJ(d,c,N),DJ=W+FJ,MJ=P+PJ,Y7=b.startsWith("rot-"),v7=b==="n"||b==="s",C7=b==="e"||b==="w",jJ=Y7?10:v7?7:C7?3:4,LJ=Y7?10:v7?3:C7?7:4;v.className="dc-el-resize-handle",v.dataset.corner=b,v.style.opacity="1",v.style.pointerEvents="auto",v.style.left=`${Math.round(DJ-jJ)}px`,v.style.top=`${Math.round(MJ-LJ)}px`,v.style.transform=Y7?"":`rotate(${N}deg)`}let y=U.children[E.length],w=q.current;if(w&&w.el===Y&&!w.corner.startsWith("rot-")){let h=w.lastResult?.width??Y.offsetWidth,b=w.lastResult?.height??Y.offsetHeight,v=`${Math.round(h)} × ${Math.round(b)}`,d=w.lastResult?.left,c=w.lastResult?.top;if(typeof d==="number"||typeof c==="number")v+=` · ${Math.round(d??w.start.left)}, ${Math.round(c??w.start.top)}`;y.className="dc-el-resize-readout",y.textContent=v,y.style.opacity="1",y.style.left=`${Math.round(W)}px`,y.style.top=`${Math.round(P+M)}px`}else y.style.opacity="0";Z.current=requestAnimationFrame(F)};return Z.current=requestAnimationFrame(F),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[j,K,H]);let L=LQ((U,B)=>{if(U.el.style.width=`${B.width}px`,U.el.style.height=`${B.height}px`,typeof B.left==="number")U.el.style.left=`${B.left}px`;if(typeof B.top==="number")U.el.style.top=`${B.top}px`;U.lastResult=B},[]);return GJ(()=>{let U=$.current;if(!U)return;let B=(V,X)=>{let[W,P]=WJ(X.clientX-V.startClientX,X.clientY-V.startClientY,-V.angle);return OQ(V.corner,V.start,W/V.elZoom,P/V.elZoom,{aspect:!!X.shiftKey,center:!V.artboardId&&!!X.altKey},V.flags)},F=(V)=>{let X=V.target;if(!X?.classList.contains("dc-el-resize-handle"))return;let W=X.dataset.corner;if(!W||!K)return;let P=typeof K.id==="string"?K.id:null,N=!P&&typeof K.artboardId==="string"?K.artboardId:null;if(!P&&!N)return;let I=F7(document,K);if(!I)return;V.preventDefault(),V.stopPropagation();let A=I.getBoundingClientRect(),M=I.offsetWidth?A.width/I.offsetWidth:1,T=getComputedStyle(I),E=!N&&(T.position==="absolute"||T.position==="fixed"),y=N?Number.NaN:Number.parseFloat(I.style.left),w=N?Number.NaN:Number.parseFloat(I.style.top),h=N?0:BJ(T.transform),b=M>0?M:1,v=A.left+A.width/2,d=A.top+A.height/2,c={pointerId:V.pointerId,corner:W,el:I,cdId:P??"",artboardId:N,idIndex:P?f7(document,P,I):0,startClientX:V.clientX,startClientY:V.clientY,elZoom:b,angle:h,cx:v,cy:d,rotStartPointer:KJ(v,d,V.clientX,V.clientY),start:{w:(h?I.offsetWidth:A.width/b)||A.width/b,h:(h?I.offsetHeight:A.height/b)||A.height/b,left:y,top:w},flags:{canMoveLeft:E&&Number.isFinite(y),canMoveTop:E&&Number.isFinite(w)},before:{width:I.style.width||null,height:I.style.height||null,left:I.style.left||null,top:I.style.top||null,transform:I.style.transform||null},lastResult:null,lastTransform:null};q.current=c;try{X.setPointerCapture(V.pointerId)}catch{}},Y=(V)=>{let X=q.current;if(!X||V.pointerId!==X.pointerId)return;if(V.preventDefault(),X.corner.startsWith("rot-")){let P=`rotate(${EQ(X.angle,X.rotStartPointer,KJ(X.cx,X.cy,V.clientX,V.clientY),!!V.shiftKey)}deg)`;X.el.style.transform=P,X.lastTransform=P;return}L(X,B(X,V))},D=(V)=>{let X=q.current;if(!X||V.pointerId!==X.pointerId)return;if(q.current=null,X.corner.startsWith("rot-")){let N=X.lastTransform;if(!N||N===X.before.transform)return;G.current={el:X.el,before:X.before},xQ(X,N);return}let W=X.lastResult??B(X,V);if(!(`${W.width}px`!==X.before.width||`${W.height}px`!==X.before.height||typeof W.left==="number"&&`${W.left}px`!==X.before.left||typeof W.top==="number"&&`${W.top}px`!==X.before.top))return;if(G.current={el:X.el,before:X.before},X.artboardId)bQ(X,W);else wQ(X,W)},_=(V)=>{let X=V.data;if(X?.dgn!=="resize-failed"&&X?.dgn!=="resize-artboard-failed")return;if(V.source!==window.parent)return;let W=G.current;if(!W)return;if(W.el.style.width=W.before.width??"",W.el.style.height=W.before.height??"",W.before.left!==null||W.el.style.left)W.el.style.left=W.before.left??"";if(W.before.top!==null||W.el.style.top)W.el.style.top=W.before.top??"";if(W.before.transform!==null||W.el.style.transform)W.el.style.transform=W.before.transform??"";G.current=null};return U.addEventListener("pointerdown",F),window.addEventListener("pointermove",Y),window.addEventListener("pointerup",D),window.addEventListener("pointercancel",D),window.addEventListener("message",_),()=>{U.removeEventListener("pointerdown",F),window.removeEventListener("pointermove",Y),window.removeEventListener("pointerup",D),window.removeEventListener("pointercancel",D),window.removeEventListener("message",_)}},[K,L]),yQ("div",{ref:$,"aria-hidden":"true"})}import{jsx as o,jsxs as lQ}from"react/jsx-runtime";var gQ=new Set(["drop-comment","tool","escape","hover"]);function V7(){return typeof document<"u"&&!document.querySelector(".dc-canvas")}function y7(J,Q){if(typeof document>"u")return null;let $=document.elementFromPoint(J,Q);if(!$)return null;if($.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mc-hover-halo], [data-mc-selection-halo], .dc-el-resize-handle"))return null;let Z=$.tagName;if(Z==="HTML"||Z==="BODY")return null;return $}function hQ(J,Q){let $=y7(J,Q);if(!$)return null;return $.closest("[data-cd-id]")??$}function fQ({children:J,file:Q}){let{tool:$,setTool:Z}=X7(),q=W7(),G=p(null),[K,z]=$7(null),H=p($);H.current=$;let j=SQ(()=>()=>H.current,[]);f(()=>{if($!=="comment")z(null)},[$]);let[L,U]=$7(null),[B,F]=$7(!1);return f(()=>{let Y=()=>F(V7());Y();let D=requestAnimationFrame(Y),_=setTimeout(Y,120);return()=>{cancelAnimationFrame(D),clearTimeout(_)}},[]),f(()=>{if(typeof document>"u")return;let Y=(D)=>{if(D.button!==0||!(D.metaKey||D.ctrlKey))return;if(!V7())return;if(J7(D.target))return;let _=hQ(D.clientX,D.clientY);if(!_)return;D.preventDefault(),D.stopImmediatePropagation();let V=_.getAttribute("data-cd-id"),X=P7({el:_,cdId:V,artboardId:null});if(D.shiftKey)q.add(X);else q.replace(X);U(_)};return document.addEventListener("pointerdown",Y,!0),()=>document.removeEventListener("pointerdown",Y,!0)},[q]),f(()=>{if(q.selected.length===0)U(null)},[q.selected]),f(()=>{let Y=G.current;if(Y)Y.setAttribute("data-active-tool",$);if(typeof document<"u"&&document.body)document.body.setAttribute("data-active-tool",$);return()=>{Y?.removeAttribute("data-active-tool")}},[$]),f(()=>{if(typeof window>"u")return;let Y=(D)=>{let _=D.data;if(!_||typeof _!=="object"||_.dgn!=="tool-set")return;if(typeof _.tool==="string")Z(_.tool)};return window.addEventListener("message",Y),()=>window.removeEventListener("message",Y)},[Z]),JJ({hostRef:G,getActiveTool:j,claimableActions:gQ,callbacks:{onHover:({clientX:Y,clientY:D})=>{if(H.current!=="comment"||!V7()){z(null);return}let _=y7(Y,D);z((V)=>V===_?V:_)},onTool:({tool:Y})=>Z(Y),onEscape:()=>{if(H.current!=="move")Z("move");if(z(null),q.clear(),typeof window<"u")try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},onDropComment:({clientX:Y,clientY:D})=>mQ(Y,D,q,Q)}}),lQ("div",{"data-mc-host":!0,ref:G,style:{display:"contents"},children:[J,K?o(uQ,{el:K}):null,L?o(pQ,{el:L}):null,B?o(XJ,{}):null,o(a7,{})]})}function pQ({el:J}){let Q=p(null),$=p(J);$.current=J;let Z=p(null);return f(()=>{let q=()=>{Z.current=null;let G=Q.current,K=$.current;if(G&&K?.isConnected){let z=K.getBoundingClientRect();if(z.width===0&&z.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(z.left)}px`,G.style.top=`${Math.round(z.top)}px`,G.style.width=`${Math.round(z.width)}px`,G.style.height=`${Math.round(z.height)}px`}else if(G)G.style.display="none";Z.current=requestAnimationFrame(q)};return Z.current=requestAnimationFrame(q),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[]),o("div",{ref:Q,"aria-hidden":"true","data-mc-selection-halo":"",style:{position:"fixed",display:"none",pointerEvents:"none",zIndex:2147483645,border:"1.5px solid var(--maude-hud-accent, oklch(0.680 0.180 268))",borderRadius:"3px",boxSizing:"border-box"}})}function uQ({el:J}){let Q=p(null),$=p(J);$.current=J;let Z=p(null);return f(()=>{let q=()=>{Z.current=null;let G=Q.current,K=$.current;if(G&&K?.isConnected){let z=K.getBoundingClientRect();if(z.width===0&&z.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(z.left)}px`,G.style.top=`${Math.round(z.top)}px`,G.style.width=`${Math.round(z.width)}px`,G.style.height=`${Math.round(z.height)}px`}else if(G)G.style.display="none";Z.current=requestAnimationFrame(q)};return Z.current=requestAnimationFrame(q),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[]),o("div",{ref:Q,"aria-hidden":"true","data-mc-hover-halo":"",style:{position:"fixed",display:"none",pointerEvents:"none",zIndex:2147483646,border:"2px solid var(--maude-hud-accent, #d63b1f)",borderRadius:"3px",boxSizing:"border-box"}})}function mQ(J,Q,$,Z){if(typeof document>"u")return;let q=I7(document,J,Q,{deep:!0});if(!q)q=I7(document,J,Q,{deep:!1});if(!q&&!V7()&&typeof document.elementsFromPoint==="function"){let K=document.elementsFromPoint(J,Q);for(let z of K){let H=z.closest?.("[data-cd-id]");if(!H)continue;if(!H.closest(".dc-artboard-body"))continue;let j=H.closest("[data-dc-screen]");q={el:H,cdId:H.getAttribute("data-cd-id"),artboardId:j?.getAttribute("data-dc-screen")??null};break}}if(!q&&V7()){let K=y7(J,Q);if(K)q={el:K,cdId:K.getAttribute("data-cd-id"),artboardId:null}}if(!q){let K={file:Z,id:void 0,selector:"",artboardId:null,tag:"",classes:"",text:"",dom_path:[],bounds:{x:J-12,y:Q-12,w:24,h:24},html:""};zJ(K,J,Q);return}let G=P7(q,Z);$.replace(G),zJ(G,J,Q)}function zJ(J,Q,$){if(typeof document<"u")try{document.dispatchEvent(new CustomEvent("cm:open-composer",{detail:{selection:J,clientX:Q,clientY:$}}))}catch{}if(typeof window<"u")try{window.parent.postMessage({dgn:"comment-compose",selection:J},"*")}catch{}}function YJ(J,Q){return g(qJ,null,g(i7,null,g(fQ,{file:Q},g(J))))}function e0(J,Q){let $=RQ(Q.rootEl);if(!Q.commentsEnabled){$.render(g(J));return}let Z=Q.file??H7();$.render(g(cQ,{initialCanvas:J,file:Z}))}var UJ="__maudeCanvasRuntime";function dQ({Canvas:J,file:Q,onOk:$}){return f(()=>{$()},[]),YJ(J,Q)}class HJ extends vQ{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(){this.props.onError()}componentDidUpdate(J){if(J.attempt!==this.props.attempt&&this.state.hasError)this.setState({hasError:!1})}render(){if(this.state.hasError)return this.props.fallback();return this.props.children}}function iQ({message:J}){return g("div",{className:"dc-hmr-holding",role:"status","aria-live":"polite",title:J?`Holding last working render — ${J}`:"Holding last working render"},"⏸ build error — držím poslední funkční verzi")}function cQ({initialCanvas:J,file:Q}){let[{canvas:$,attempt:Z},q]=$7({canvas:J,attempt:0}),[G,K]=$7({on:!1}),z=p(null),H=p($);H.current=$,f(()=>{let B={remount:(F)=>q((Y)=>({canvas:F,attempt:Y.attempt+1})),setHolding:(F,Y)=>K(F?{on:!0,message:Y}:{on:!1})};return window[UJ]=B,()=>{window[UJ]=void 0}},[]);let j=x7(()=>{z.current=H.current,K((B)=>B.on?{on:!1}:B)},[]),L=x7(()=>{K({on:!0,message:"render error"})},[]),U=x7(()=>{let B=z.current;return B?YJ(B,Q):null},[Q]);return g(CQ,null,g(HJ,{attempt:Z,onError:L,fallback:U},g(dQ,{key:Z,Canvas:$,file:Q,onOk:j})),G.on?g(iQ,{message:G.message}):null)}export{hQ as pickSpecimenSelectEl,e0 as mountCanvas,V7 as isBareSpecimen,HJ as CanvasErrorBoundary};
|
|
59
|
+
`.trim();function AQ(){if(typeof document>"u")return;if(document.getElementById("dc-el-resize-css"))return;let J=document.createElement("style");J.id="dc-el-resize-css",J.textContent=IQ,document.head.appendChild(J)}var OQ=["nw","n","ne","e","se","s","sw","w"];function kQ(J){return{movesLeft:J==="nw"||J==="w"||J==="sw",movesRight:J==="ne"||J==="e"||J==="se",movesTop:J==="nw"||J==="n"||J==="ne",movesBottom:J==="sw"||J==="s"||J==="se"}}var r=(J)=>Math.round(J*100)/100,H7=1;function TQ(J,Q,$,Z,q,G){let{movesLeft:z,movesRight:X,movesTop:Y,movesBottom:_}=kQ(J),L=q.center,U=Q.w,W=Q.h;if(X)U=Q.w+(L?2*$:$);else if(z)U=Q.w-(L?2*$:$);if(_)W=Q.h+(L?2*Z:Z);else if(Y)W=Q.h-(L?2*Z:Z);if(q.aspect&&Q.w>0&&Q.h>0){let H=Q.w/Q.h;if((z||X)&&(Y||_)){let I=Math.abs(U-Q.w)/Q.w,V=Math.abs(W-Q.h)/Q.h;if(I>=V)W=U/H;else U=W*H}else if(z||X)W=U/H;else if(Y||_)U=W*H}if(U<H7)U=H7;if(W<H7)W=H7;let P={width:r(U),height:r(W)};if(L){if(G.canMoveLeft&&(z||X))P.left=r(Q.left+(Q.w-U)/2);if(G.canMoveTop&&(Y||_))P.top=r(Q.top+(Q.h-W)/2)}else{if(G.canMoveLeft&&z)P.left=r(Q.left+Q.w-U);if(G.canMoveTop&&Y)P.top=r(Q.top+Q.h-W)}return P}function KJ(J){if(!J||J==="none")return 0;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 0;let $=Q[1].split(",").map(Number),Z=$[0]??1,q=$[1]??0;return Math.round(Math.atan2(q,Z)*(180/Math.PI)*100)/100}function EQ(J){if(!J||J==="none")return 1;let Q=/matrix\(([^)]+)\)/.exec(J);if(!Q)return 1;let $=Q[1].split(",").map(Number),Z=$[0]??1,q=$[1]??0,G=Math.hypot(Z,q);return G>0?G:1}function wQ(J){let Q=J.closest(".dc-world");if(!Q)return 1;let $=getComputedStyle(Q),Z=Number.parseFloat($.zoom||"1")||1;return EQ($.transform)*Z}function zJ(J,Q,$){let Z=$*Math.PI/180,q=Math.cos(Z),G=Math.sin(Z);return[J*q-Q*G,J*G+Q*q]}function UJ(J,Q,$,Z){return Math.atan2(Z-Q,$-J)}function xQ(J,Q,$,Z){let q=J+($-Q)*(180/Math.PI);while(q>180)q-=360;while(q<=-180)q+=360;if(Z)q=Math.round(q/15)*15;return Math.round(q*100)/100}function bQ(J,Q){let $={width:`${Q.width}px`,height:`${Q.height}px`};if(typeof Q.left==="number")$.left=`${Q.left}px`;if(typeof Q.top==="number")$.top=`${Q.top}px`;try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:$,before:J.before,idIndex:J.idIndex},"*")}catch{}}function yQ(J,Q){if(!J.artboardId)return;try{window.parent.postMessage({dgn:"resize-artboard-request",artboardId:J.artboardId,width:Q.width,height:Q.height},"*")}catch{}}function vQ(J,Q){try{window.parent.postMessage({dgn:"resize-request",id:J.cdId,patch:{transform:Q},before:J.before,idIndex:J.idIndex},"*")}catch{}}function XJ(){AQ();let{selected:J}=K7(),{tool:Q}=X7(),$=Y7(null),Z=Y7(null),q=Y7(null),G=Y7(null),z=J.length===1?J[0]:null,X=z&&typeof z.id==="string"?z.id:null,Y=z&&!X&&typeof z.artboardId==="string"?z.artboardId:null,_=Q==="move"&&(!!X||!!Y);WJ(()=>{let U=$.current;if(!U)return;let W=()=>{for(let H of Array.from(U.children)){let j=H;j.style.opacity="0",j.style.pointerEvents="none"}};if(!_||!z){W();return}let P=()=>{if(Z.current=null,QJ()){W(),Z.current=requestAnimationFrame(P);return}let H=D7(document,z);if(!H){W(),Z.current=requestAnimationFrame(P);return}let j=H.getBoundingClientRect();if(j.width<=0&&j.height<=0){W(),Z.current=requestAnimationFrame(P);return}let I=Y?["e","s","se"]:OQ,V=Y?[]:["rot-nw","rot-ne","rot-sw","rot-se"],K=I.length+V.length+1;while(U.children.length<K)U.appendChild(document.createElement("div"));while(U.children.length>K)U.lastChild&&U.removeChild(U.lastChild);let B=j.left+j.width/2,D=j.top+j.height/2,N=KJ(getComputedStyle(H).transform),M=wQ(H),A=H.offsetWidth*M/2,F=H.offsetHeight*M/2,O={nw:[-A,-F],n:[0,-F],ne:[A,-F],e:[A,0],se:[A,F],s:[0,F],sw:[-A,F],w:[-A,0],"rot-nw":[-A,-F],"rot-ne":[A,-F],"rot-sw":[-A,F],"rot-se":[A,F]},E=[...V,...I];for(let g=0;g<E.length;g++){let x=E[g],v=U.children[g],[d,c]=O[x]??[0,0],[DJ,jJ]=zJ(d,c,N),LJ=B+DJ,NJ=D+jJ,F7=x.startsWith("rot-"),v7=x==="n"||x==="s",C7=x==="e"||x==="w",MJ=F7?10:v7?7:C7?3:4,_J=F7?10:v7?3:C7?7:4;v.className="dc-el-resize-handle",v.dataset.corner=x,v.style.opacity="1",v.style.pointerEvents="auto",v.style.left=`${Math.round(LJ-MJ)}px`,v.style.top=`${Math.round(NJ-_J)}px`,v.style.transform=F7?"":`rotate(${N}deg)`}let y=U.children[E.length],w=q.current;if(w&&w.el===H&&!w.corner.startsWith("rot-")){let g=w.lastResult?.width??H.offsetWidth,x=w.lastResult?.height??H.offsetHeight,v=`${Math.round(g)} × ${Math.round(x)}`,d=w.lastResult?.left,c=w.lastResult?.top;if(typeof d==="number"||typeof c==="number")v+=` · ${Math.round(d??w.start.left)}, ${Math.round(c??w.start.top)}`;y.className="dc-el-resize-readout",y.textContent=v,y.style.opacity="1",y.style.left=`${Math.round(B)}px`,y.style.top=`${Math.round(D+F)}px`}else y.style.opacity="0";Z.current=requestAnimationFrame(P)};return Z.current=requestAnimationFrame(P),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[_,z,Y]);let L=_Q((U,W)=>{if(U.el.style.width=`${W.width}px`,U.el.style.height=`${W.height}px`,typeof W.left==="number")U.el.style.left=`${W.left}px`;if(typeof W.top==="number")U.el.style.top=`${W.top}px`;U.lastResult=W},[]);return WJ(()=>{let U=$.current;if(!U)return;let W=(V,K)=>{let[B,D]=zJ(K.clientX-V.startClientX,K.clientY-V.startClientY,-V.angle);return TQ(V.corner,V.start,B/V.elZoom,D/V.elZoom,{aspect:!!K.shiftKey,center:!V.artboardId&&!!K.altKey},V.flags)},P=(V)=>{let K=V.target;if(!K?.classList.contains("dc-el-resize-handle"))return;let B=K.dataset.corner;if(!B||!z)return;let D=typeof z.id==="string"?z.id:null,N=!D&&typeof z.artboardId==="string"?z.artboardId:null;if(!D&&!N)return;let M=D7(document,z);if(!M)return;V.preventDefault(),V.stopPropagation();let A=M.getBoundingClientRect(),F=M.offsetWidth?A.width/M.offsetWidth:1,O=getComputedStyle(M),E=!N&&(O.position==="absolute"||O.position==="fixed"),y=N?Number.NaN:Number.parseFloat(M.style.left),w=N?Number.NaN:Number.parseFloat(M.style.top),g=N?0:KJ(O.transform),x=F>0?F:1,v=A.left+A.width/2,d=A.top+A.height/2,c={pointerId:V.pointerId,corner:B,el:M,cdId:D??"",artboardId:N,idIndex:D?f7(document,D,M):0,startClientX:V.clientX,startClientY:V.clientY,elZoom:x,angle:g,cx:v,cy:d,rotStartPointer:UJ(v,d,V.clientX,V.clientY),start:{w:(g?M.offsetWidth:A.width/x)||A.width/x,h:(g?M.offsetHeight:A.height/x)||A.height/x,left:y,top:w},flags:{canMoveLeft:E&&Number.isFinite(y),canMoveTop:E&&Number.isFinite(w)},before:{width:M.style.width||null,height:M.style.height||null,left:M.style.left||null,top:M.style.top||null,transform:M.style.transform||null},lastResult:null,lastTransform:null};q.current=c;try{K.setPointerCapture(V.pointerId)}catch{}},H=(V)=>{let K=q.current;if(!K||V.pointerId!==K.pointerId)return;if(V.preventDefault(),K.corner.startsWith("rot-")){let D=`rotate(${xQ(K.angle,K.rotStartPointer,UJ(K.cx,K.cy,V.clientX,V.clientY),!!V.shiftKey)}deg)`;K.el.style.transform=D,K.lastTransform=D;return}L(K,W(K,V))},j=(V)=>{let K=q.current;if(!K||V.pointerId!==K.pointerId)return;if(q.current=null,K.corner.startsWith("rot-")){let N=K.lastTransform;if(!N||N===K.before.transform)return;G.current={el:K.el,before:K.before},vQ(K,N);return}let B=K.lastResult??W(K,V);if(!(`${B.width}px`!==K.before.width||`${B.height}px`!==K.before.height||typeof B.left==="number"&&`${B.left}px`!==K.before.left||typeof B.top==="number"&&`${B.top}px`!==K.before.top))return;if(G.current={el:K.el,before:K.before},K.artboardId)yQ(K,B);else bQ(K,B)},I=(V)=>{let K=V.data;if(K?.dgn!=="resize-failed"&&K?.dgn!=="resize-artboard-failed")return;if(V.source!==window.parent)return;let B=G.current;if(!B)return;if(B.el.style.width=B.before.width??"",B.el.style.height=B.before.height??"",B.before.left!==null||B.el.style.left)B.el.style.left=B.before.left??"";if(B.before.top!==null||B.el.style.top)B.el.style.top=B.before.top??"";if(B.before.transform!==null||B.el.style.transform)B.el.style.transform=B.before.transform??"";G.current=null};return U.addEventListener("pointerdown",P),window.addEventListener("pointermove",H),window.addEventListener("pointerup",j),window.addEventListener("pointercancel",j),window.addEventListener("message",I),()=>{U.removeEventListener("pointerdown",P),window.removeEventListener("pointermove",H),window.removeEventListener("pointerup",j),window.removeEventListener("pointercancel",j),window.removeEventListener("message",I)}},[z,L]),CQ("div",{ref:$,"aria-hidden":"true"})}import{jsx as a,jsxs as rQ}from"react/jsx-runtime";var fQ=new Set(["drop-comment","tool","escape","hover"]);function Z7(){return typeof document<"u"&&!document.querySelector(".dc-canvas")}function y7(J,Q){if(typeof document>"u")return null;let $=document.elementFromPoint(J,Q);if(!$)return null;if($.closest(".cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mc-hover-halo], [data-mc-selection-halo], .dc-el-resize-handle"))return null;let Z=$.tagName;if(Z==="HTML"||Z==="BODY")return null;return $}function pQ(J,Q){let $=y7(J,Q);if(!$)return null;return $.closest("[data-cd-id]")??$}function uQ({children:J,file:Q}){let{tool:$,setTool:Z}=X7(),q=K7(),G=p(null),[z,X]=V7(null),Y=p($);Y.current=$;let _=hQ(()=>()=>Y.current,[]);f(()=>{if($!=="comment")X(null)},[$]);let[L,U]=V7(null),[W,P]=V7(!1);return f(()=>{let H=()=>P(Z7());H();let j=requestAnimationFrame(H),I=setTimeout(H,120);return()=>{cancelAnimationFrame(j),clearTimeout(I)}},[]),f(()=>{if(typeof document>"u")return;let H=(j)=>{if(j.button!==0||!(j.metaKey||j.ctrlKey))return;if(!Z7())return;if(J7(j.target))return;let I=pQ(j.clientX,j.clientY);if(!I)return;j.preventDefault(),j.stopImmediatePropagation();let V=I.getAttribute("data-cd-id"),K=j7({el:I,cdId:V,artboardId:null});if(j.shiftKey)q.add(K);else q.replace(K);U(I)};return document.addEventListener("pointerdown",H,!0),()=>document.removeEventListener("pointerdown",H,!0)},[q]),f(()=>{if(q.selected.length===0)U(null)},[q.selected]),f(()=>{let H=G.current;if(H)H.setAttribute("data-active-tool",$);if(typeof document<"u"&&document.body)document.body.setAttribute("data-active-tool",$);return()=>{H?.removeAttribute("data-active-tool")}},[$]),f(()=>{if(typeof window>"u")return;let H=(j)=>{let I=j.data;if(!I||typeof I!=="object"||I.dgn!=="tool-set")return;if(typeof I.tool==="string")Z(I.tool)};return window.addEventListener("message",H),()=>window.removeEventListener("message",H)},[Z]),JJ({hostRef:G,getActiveTool:_,claimableActions:fQ,callbacks:{onHover:({clientX:H,clientY:j})=>{if(Y.current!=="comment"||!Z7()){X(null);return}let I=y7(H,j);X((V)=>V===I?V:I)},onTool:({tool:H})=>Z(H),onEscape:()=>{if(Y.current!=="move")Z("move");if(X(null),q.clear(),typeof window<"u")try{window.parent.postMessage({dgn:"force-clear"},"*")}catch{}},onDropComment:({clientX:H,clientY:j})=>iQ(H,j,q,Q)}}),rQ("div",{"data-mc-host":!0,ref:G,style:{display:"contents"},children:[J,z?a(dQ,{el:z}):null,L?a(mQ,{el:L}):null,W?a(XJ,{}):null,a(o7,{})]})}function mQ({el:J}){let Q=p(null),$=p(J);$.current=J;let Z=p(null);return f(()=>{let q=()=>{Z.current=null;let G=Q.current,z=$.current;if(G&&z?.isConnected){let X=z.getBoundingClientRect();if(X.width===0&&X.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(X.left)}px`,G.style.top=`${Math.round(X.top)}px`,G.style.width=`${Math.round(X.width)}px`,G.style.height=`${Math.round(X.height)}px`}else if(G)G.style.display="none";Z.current=requestAnimationFrame(q)};return Z.current=requestAnimationFrame(q),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[]),a("div",{ref:Q,"aria-hidden":"true","data-mc-selection-halo":"",style:{position:"fixed",display:"none",pointerEvents:"none",zIndex:2147483645,border:"1.5px solid var(--maude-hud-accent, oklch(0.680 0.180 268))",borderRadius:"3px",boxSizing:"border-box"}})}function dQ({el:J}){let Q=p(null),$=p(J);$.current=J;let Z=p(null);return f(()=>{let q=()=>{Z.current=null;let G=Q.current,z=$.current;if(G&&z?.isConnected){let X=z.getBoundingClientRect();if(X.width===0&&X.height===0)G.style.display="none";else G.style.display="block",G.style.left=`${Math.round(X.left)}px`,G.style.top=`${Math.round(X.top)}px`,G.style.width=`${Math.round(X.width)}px`,G.style.height=`${Math.round(X.height)}px`}else if(G)G.style.display="none";Z.current=requestAnimationFrame(q)};return Z.current=requestAnimationFrame(q),()=>{if(Z.current!=null)cancelAnimationFrame(Z.current)}},[]),a("div",{ref:Q,"aria-hidden":"true","data-mc-hover-halo":"",style:{position:"fixed",display:"none",pointerEvents:"none",zIndex:2147483646,border:"2px solid var(--maude-hud-accent, #d63b1f)",borderRadius:"3px",boxSizing:"border-box"}})}function iQ(J,Q,$,Z){if(typeof document>"u")return;let q=O7(document,J,Q,{deep:!0});if(!q)q=O7(document,J,Q,{deep:!1});if(!q&&!Z7()&&typeof document.elementsFromPoint==="function"){let z=document.elementsFromPoint(J,Q);for(let X of z){let Y=X.closest?.("[data-cd-id]");if(!Y)continue;if(!Y.closest(".dc-artboard-body"))continue;let _=Y.closest("[data-dc-screen]");q={el:Y,cdId:Y.getAttribute("data-cd-id"),artboardId:_?.getAttribute("data-dc-screen")??null};break}}if(!q&&Z7()){let z=y7(J,Q);if(z)q={el:z,cdId:z.getAttribute("data-cd-id"),artboardId:null}}if(!q){let z={file:Z,id:void 0,selector:"",artboardId:null,tag:"",classes:"",text:"",dom_path:[],bounds:{x:J-12,y:Q-12,w:24,h:24},html:""};YJ(z,J,Q);return}let G=j7(q,Z);$.replace(G),YJ(G,J,Q)}function YJ(J,Q,$){if(typeof document<"u")try{document.dispatchEvent(new CustomEvent("cm:open-composer",{detail:{selection:J,clientX:Q,clientY:$}}))}catch{}if(typeof window<"u")try{window.parent.postMessage({dgn:"comment-compose",selection:J},"*")}catch{}}function FJ(J,Q){return h(BJ,{initial:"browse"},h(i7,null,h(uQ,{file:Q},h(J))))}function Q3(J,Q){let $=gQ(Q.rootEl);if(!Q.commentsEnabled){$.render(h(J));return}let Z=Q.file??P7();$.render(h(nQ,{initialCanvas:J,file:Z}))}var HJ="__maudeCanvasRuntime";function cQ({Canvas:J,file:Q,onOk:$}){return f(()=>{$()},[]),FJ(J,Q)}class PJ extends RQ{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(){this.props.onError()}componentDidUpdate(J){if(J.attempt!==this.props.attempt&&this.state.hasError)this.setState({hasError:!1})}render(){if(this.state.hasError)return this.props.fallback();return this.props.children}}function lQ({message:J}){return h("div",{className:"dc-hmr-holding",role:"status","aria-live":"polite",title:J?`Holding last working render — ${J}`:"Holding last working render"},"⏸ build error — držím poslední funkční verzi")}function nQ({initialCanvas:J,file:Q}){let[{canvas:$,attempt:Z},q]=V7({canvas:J,attempt:0}),[G,z]=V7({on:!1}),X=p(null),Y=p($);Y.current=$,f(()=>{let W={remount:(P)=>q((H)=>({canvas:P,attempt:H.attempt+1})),setHolding:(P,H)=>z(P?{on:!0,message:H}:{on:!1})};return window[HJ]=W,()=>{window[HJ]=void 0}},[]);let _=b7(()=>{X.current=Y.current,z((W)=>W.on?{on:!1}:W)},[]),L=b7(()=>{z({on:!0,message:"render error"})},[]),U=b7(()=>{let W=X.current;return W?FJ(W,Q):null},[Q]);return h(SQ,null,h(PJ,{attempt:Z,onError:L,fallback:U},h(cQ,{key:Z,Canvas:$,file:Q,onOk:_})),G.on?h(lQ,{message:G.message}):null)}export{pQ as pickSpecimenSelectEl,Q3 as mountCanvas,Z7 as isBareSpecimen,PJ as CanvasErrorBoundary};
|
|
@@ -511,3 +511,70 @@ export function hoverTargetToSelection(target: HoverTarget, file?: string): Sele
|
|
|
511
511
|
...styleMapsFor(el),
|
|
512
512
|
};
|
|
513
513
|
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Build the comment-composer Selection for a right-click "Add comment"
|
|
517
|
+
* (context-menu.tsx's `element` / `artboard-chrome` / `world` targets share
|
|
518
|
+
* this one builder). When an element was under the cursor, delegates to
|
|
519
|
+
* `hoverTargetToSelection` — the exact anchor a comment-tool CLICK on that
|
|
520
|
+
* same element would produce, so a menu-driven comment and a drop-comment
|
|
521
|
+
* pin resolve identically. When there wasn't (empty canvas background, or an
|
|
522
|
+
* artboard's chrome/border rather than its body), returns a FLOATING
|
|
523
|
+
* selection pinned to the click point — the same shape
|
|
524
|
+
* canvas-comment-mount.tsx's `dropComment` uses for its own no-target
|
|
525
|
+
* fallback (issue-90).
|
|
526
|
+
*/
|
|
527
|
+
export function buildComposeSelection(
|
|
528
|
+
target: { el: Element | null; cdId?: string | null; artboardId?: string | null },
|
|
529
|
+
clientX: number,
|
|
530
|
+
clientY: number,
|
|
531
|
+
file?: string
|
|
532
|
+
): Selection {
|
|
533
|
+
if (target.el) {
|
|
534
|
+
return hoverTargetToSelection(
|
|
535
|
+
{ el: target.el, cdId: target.cdId ?? null, artboardId: target.artboardId ?? null },
|
|
536
|
+
file
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
return {
|
|
540
|
+
file: file ?? deriveFile(),
|
|
541
|
+
selector: '',
|
|
542
|
+
artboardId: target.artboardId ?? null,
|
|
543
|
+
index: 0,
|
|
544
|
+
tag: '',
|
|
545
|
+
classes: '',
|
|
546
|
+
text: '',
|
|
547
|
+
dom_path: [],
|
|
548
|
+
bounds: { x: clientX - 12, y: clientY - 12, w: 24, h: 24 },
|
|
549
|
+
html: '',
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Open the in-place comment composer for `selection`, anchored at
|
|
555
|
+
* `(clientX, clientY)`. The single choke point for the two-part signal every
|
|
556
|
+
* "add a comment here" affordance must send: `cm:open-composer` is what
|
|
557
|
+
* ACTUALLY opens the composer (`comments-overlay.tsx`'s own listener); the
|
|
558
|
+
* `comment-compose` postMessage is a secondary mirror so the parent shell's
|
|
559
|
+
* StatusBar/sidebar reflect the target too. A caller that only sends the
|
|
560
|
+
* second half opens nothing — canvas-shell.tsx's context-menu "Add comment"
|
|
561
|
+
* did exactly that until issue-90.
|
|
562
|
+
*/
|
|
563
|
+
export function openCommentComposer(selection: Selection, clientX: number, clientY: number): void {
|
|
564
|
+
if (typeof document !== 'undefined') {
|
|
565
|
+
try {
|
|
566
|
+
document.dispatchEvent(
|
|
567
|
+
new CustomEvent('cm:open-composer', { detail: { selection, clientX, clientY } })
|
|
568
|
+
);
|
|
569
|
+
} catch {
|
|
570
|
+
/* CustomEvent unsupported — fall through */
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
if (typeof window !== 'undefined') {
|
|
574
|
+
try {
|
|
575
|
+
window.parent.postMessage({ dgn: 'comment-compose', selection }, '*');
|
|
576
|
+
} catch {
|
|
577
|
+
/* parent detached */
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
@@ -33,7 +33,7 @@ const DEBOUNCE_MS = 50;
|
|
|
33
33
|
|
|
34
34
|
export interface HmrMessage {
|
|
35
35
|
type: 'canvas-hmr';
|
|
36
|
-
mode: 'css' | 'module' | 'hard' | 'meta';
|
|
36
|
+
mode: 'css' | 'module' | 'hard' | 'meta' | 'asset';
|
|
37
37
|
/**
|
|
38
38
|
* Canvas-relative path of the file that changed, slash-normalised. Absent
|
|
39
39
|
* when mode === 'hard' (the change is global — every canvas reloads).
|
|
@@ -74,7 +74,13 @@ export function createHmrBroadcaster(
|
|
|
74
74
|
// meta is the lightest signal — it doesn't trigger a reload, just re-fetches
|
|
75
75
|
// the sidecar. CSS still ranks above it so a same-window CSS write wins over
|
|
76
76
|
// a meta echo; hard tops everything.
|
|
77
|
-
const rank: Record<HmrMessage['mode'], number> = {
|
|
77
|
+
const rank: Record<HmrMessage['mode'], number> = {
|
|
78
|
+
meta: 0,
|
|
79
|
+
asset: 0,
|
|
80
|
+
css: 1,
|
|
81
|
+
module: 2,
|
|
82
|
+
hard: 3,
|
|
83
|
+
};
|
|
78
84
|
|
|
79
85
|
function flush() {
|
|
80
86
|
// A pending `hard` supersedes the per-file queue — every open canvas does a
|
|
@@ -169,9 +175,41 @@ export function classifyChange(
|
|
|
169
175
|
if (ext === '.tsx' || ext === '.jsx' || ext === '.ts' || ext === '.js') {
|
|
170
176
|
return { type: 'canvas-hmr', mode: 'module', file: rel, version, scope: 'canvas' };
|
|
171
177
|
}
|
|
178
|
+
// 2026-08-15 annotations-assets RCA — a MEDIA file landing on disk (asset
|
|
179
|
+
// pull, file-plane pull, desktop push echo) is a heal signal, not a reload:
|
|
180
|
+
// any <img>/<image> that already 404'd on this name keeps the broken glyph
|
|
181
|
+
// forever (browsers never retry a failed load on their own). `mode:'asset'`
|
|
182
|
+
// tells open canvases to re-point matching, still-broken elements — no
|
|
183
|
+
// reload, no React state loss. Covers top-level `assets/` AND DS trees
|
|
184
|
+
// (`system/<ds>/assets/…`); `.part` staging files never match the ext set.
|
|
185
|
+
if (ASSET_MEDIA_EXTS.has(ext)) {
|
|
186
|
+
return { type: 'canvas-hmr', mode: 'asset', file: rel, version, scope: 'canvas' };
|
|
187
|
+
}
|
|
172
188
|
return null;
|
|
173
189
|
}
|
|
174
190
|
|
|
191
|
+
/** Media extensions worth a heal broadcast — the renderable subset of the
|
|
192
|
+
* asset lanes' vocabulary (fonts excluded: a font 404 heals only via a CSS
|
|
193
|
+
* re-evaluation, which is a reload — not worth forcing for the rare case). */
|
|
194
|
+
const ASSET_MEDIA_EXTS = new Set([
|
|
195
|
+
'.png',
|
|
196
|
+
'.jpg',
|
|
197
|
+
'.jpeg',
|
|
198
|
+
'.webp',
|
|
199
|
+
'.gif',
|
|
200
|
+
'.avif',
|
|
201
|
+
'.svg',
|
|
202
|
+
'.mp4',
|
|
203
|
+
'.webm',
|
|
204
|
+
'.mov',
|
|
205
|
+
'.m4v',
|
|
206
|
+
'.mp3',
|
|
207
|
+
'.wav',
|
|
208
|
+
'.m4a',
|
|
209
|
+
'.aac',
|
|
210
|
+
'.ogg',
|
|
211
|
+
]);
|
|
212
|
+
|
|
175
213
|
// ---------------------------------------------------------------------------
|
|
176
214
|
// Container write bridge — inspector-edits-live-render RCA.
|
|
177
215
|
|
|
@@ -398,12 +398,36 @@ export function isEditableTarget(t: EventTarget | null): boolean {
|
|
|
398
398
|
*/
|
|
399
399
|
export function isOverlayTarget(t: EventTarget | null): boolean {
|
|
400
400
|
if (!t || !(t as Element).closest) return false;
|
|
401
|
+
const el = t as Element;
|
|
402
|
+
// Security review (issue-90) — `.dc-world` is exactly the subtree the
|
|
403
|
+
// active canvas's own JSX renders into (`canvas-lib.tsx`'s
|
|
404
|
+
// `<div className="dc-world">{children}</div>`); every selector below is
|
|
405
|
+
// shell-owned chrome that NEVER renders inside it (ToolPalette/
|
|
406
|
+
// AnnotationsLayer/ContextMenuView are siblings of `.dc-canvas`,
|
|
407
|
+
// DCZoomToolbar/DCMiniMap are children of `.dc-canvas` but siblings of
|
|
408
|
+
// `.dc-world`). Since untrusted, AI/user-authored canvas content is the one
|
|
409
|
+
// thing that DOES render inside `.dc-world`, it could otherwise spoof one
|
|
410
|
+
// of these class names on its own element to make the router yield to it
|
|
411
|
+
// (skip `preventDefault`) instead of claiming the gesture — bail out first
|
|
412
|
+
// so a same-name imposter inside the canvas never qualifies.
|
|
413
|
+
if (el.closest('.dc-world')) return false;
|
|
401
414
|
// [data-mediaref-player] — the inline <video>/<audio controls> on a media
|
|
402
415
|
// reference chip (DDR-150 dogfood #8). The router must never claim (and
|
|
403
416
|
// preventDefault) pointerdowns over the player, or its native controls
|
|
404
417
|
// (play button, scrubber drag, volume) die under the move tool.
|
|
405
|
-
|
|
406
|
-
|
|
418
|
+
//
|
|
419
|
+
// .dc-tool-palette, .dc-zoom-tb, .dc-mm, .dc-context-menu (issue-90) — the
|
|
420
|
+
// shell's floating chrome renders as SIBLINGS of `.dc-canvas` but INSIDE
|
|
421
|
+
// this router's host (`[data-mc-host]` wraps the whole surface, chrome
|
|
422
|
+
// included). Without this exemption, once comment mode is armed every
|
|
423
|
+
// click on the palette/zoom-pill/minimap/context-menu was claimed as
|
|
424
|
+
// `drop-comment` (preventDefault + stopImmediatePropagation) and dropped a
|
|
425
|
+
// stray pin at the chrome's own coordinates instead of reaching its React
|
|
426
|
+
// onClick — `classifyContextKind` (canvas-shell.tsx) already treats these
|
|
427
|
+
// same selectors as `'overlay'`, non-canvas chrome; this router's claim
|
|
428
|
+
// gate was the one place that didn't.
|
|
429
|
+
return !!el.closest(
|
|
430
|
+
'.cm-composer, .cm-thread, .cm-mention-popup, .cm-pin, [data-mediaref-player], .dc-tool-palette, .dc-zoom-tb, .dc-mm, .dc-context-menu'
|
|
407
431
|
);
|
|
408
432
|
}
|
|
409
433
|
|
|
@@ -40,6 +40,7 @@ import type * as Y from 'yjs';
|
|
|
40
40
|
|
|
41
41
|
import { atomicWrite } from './atomic-write.ts';
|
|
42
42
|
import {
|
|
43
|
+
annotationsEditAtFromDoc,
|
|
43
44
|
annotationsFromDoc,
|
|
44
45
|
applyAnnotationsToDoc,
|
|
45
46
|
applyCommentsToDoc,
|
|
@@ -50,14 +51,21 @@ import {
|
|
|
50
51
|
commentsFromDoc,
|
|
51
52
|
cssFromDoc,
|
|
52
53
|
htmlFromDoc,
|
|
54
|
+
isEmptyAnnotationsSvg,
|
|
53
55
|
markSeeded,
|
|
54
56
|
mergeSharedMetaIntoLocal,
|
|
55
57
|
metaFromDoc,
|
|
56
58
|
seededByFromDoc,
|
|
59
|
+
stampAnnotationsEdit,
|
|
57
60
|
stampBodyEdit,
|
|
58
61
|
Y_SYNC_TYPES,
|
|
59
62
|
} from './codec.ts';
|
|
60
|
-
import {
|
|
63
|
+
import {
|
|
64
|
+
decideAnnotationsColdStart,
|
|
65
|
+
decideColdStart,
|
|
66
|
+
isExactRepeat,
|
|
67
|
+
unionCommentsById,
|
|
68
|
+
} from './cold-start.ts';
|
|
61
69
|
import { type EchoGuard, hashBytes } from './echo-guard.ts';
|
|
62
70
|
import type { SyncJournal } from './journal.ts';
|
|
63
71
|
|
|
@@ -364,7 +372,15 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
364
372
|
return changed;
|
|
365
373
|
}
|
|
366
374
|
if (evt.path === paths.annotations) {
|
|
367
|
-
|
|
375
|
+
// Apply + per-lane stamp in ONE transaction (mirrors the html branch) so
|
|
376
|
+
// peers receive a single update and the annotations newest-wins stamp
|
|
377
|
+
// rides the edit — this is what makes a deliberate delete-all (empty
|
|
378
|
+
// wrapper written by saveAnnotations) cold-start-safe on other peers.
|
|
379
|
+
let changed = false;
|
|
380
|
+
doc.transact(() => {
|
|
381
|
+
changed = applyAnnotationsToDoc(doc, str, origin);
|
|
382
|
+
if (changed) stampAnnotationsEdit(doc, origin);
|
|
383
|
+
}, origin);
|
|
368
384
|
if (changed) lastAnnotations = str;
|
|
369
385
|
return changed;
|
|
370
386
|
}
|
|
@@ -419,7 +435,15 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
419
435
|
const parsed = tryParseJsonArray(localComments);
|
|
420
436
|
if (parsed !== null) applyCommentsToDoc(doc, parsed, origin);
|
|
421
437
|
}
|
|
422
|
-
if (localAnnotations !== null)
|
|
438
|
+
if (localAnnotations !== null) {
|
|
439
|
+
doc.transact(() => {
|
|
440
|
+
if (applyAnnotationsToDoc(doc, localAnnotations, origin)) {
|
|
441
|
+
// Stamp with the FILE's mtime — adopt seeds pre-existing content,
|
|
442
|
+
// which must not claim apply-time freshness over a newer peer.
|
|
443
|
+
stampAnnotationsEdit(doc, origin, localMtimeMs(paths.annotations) ?? undefined);
|
|
444
|
+
}
|
|
445
|
+
}, origin);
|
|
446
|
+
}
|
|
423
447
|
if (paths.meta && localMeta !== null) applyMetaToDoc(doc, localMeta, origin);
|
|
424
448
|
if (paths.css && localCss !== null) applyCssToDoc(doc, localCss, origin);
|
|
425
449
|
lastHtml = localHtml ?? '';
|
|
@@ -574,14 +598,47 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
574
598
|
}
|
|
575
599
|
}
|
|
576
600
|
|
|
577
|
-
// ---- annotations
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
601
|
+
// ---- annotations: PER-LANE newest-wins (the 2026-08-14 eraser fix) -----
|
|
602
|
+
// Annotations used to blindly follow the body winner, but annotation edits
|
|
603
|
+
// don't move the body's edit time — so a hub with a newer body and a stale
|
|
604
|
+
// EMPTY-WRAPPER annotations lane (72 bytes, not '') erased newer local
|
|
605
|
+
// strokes on every cold start, taking the `assets/<sha8>` references the
|
|
606
|
+
// asset pull scans with them. decideAnnotationsColdStart owns the table;
|
|
607
|
+
// the rule that matters: unstamped emptiness never beats content.
|
|
608
|
+
{
|
|
609
|
+
const annDecision = decideAnnotationsColdStart({
|
|
610
|
+
local: localAnnotations,
|
|
611
|
+
doc: docAnnotations,
|
|
612
|
+
isEmpty: isEmptyAnnotationsSvg,
|
|
613
|
+
localMtimeMs: localMtimeMs(paths.annotations),
|
|
614
|
+
docEditAtMs: annotationsEditAtFromDoc(doc),
|
|
615
|
+
bodyWinner,
|
|
616
|
+
});
|
|
617
|
+
if (annDecision.winner === 'local' && localAnnotations !== null) {
|
|
618
|
+
console.warn(`[sync/${slug}] cold-start annotations: ${annDecision.reason}`);
|
|
619
|
+
doc.transact(() => {
|
|
620
|
+
if (applyAnnotationsToDoc(doc, localAnnotations, origin)) {
|
|
621
|
+
stampAnnotationsEdit(doc, origin, localMtimeMs(paths.annotations) ?? undefined);
|
|
622
|
+
}
|
|
623
|
+
}, origin);
|
|
581
624
|
lastAnnotations = localAnnotations;
|
|
625
|
+
} else if (annDecision.winner === 'hub' && localAnnotations !== docAnnotations) {
|
|
626
|
+
// Warn only when this overwrites real local content — the clean
|
|
627
|
+
// first-sync materialize (local empty/absent) is the common quiet path.
|
|
628
|
+
if (!isEmptyAnnotationsSvg(localAnnotations)) {
|
|
629
|
+
console.warn(`[sync/${slug}] cold-start annotations: ${annDecision.reason}`);
|
|
630
|
+
}
|
|
631
|
+
const hash = hashBytes(docAnnotations);
|
|
632
|
+
echoGuard.record(paths.annotations, hash);
|
|
633
|
+
writer(paths.annotations, docAnnotations);
|
|
634
|
+
lastAnnotations = docAnnotations;
|
|
582
635
|
} else {
|
|
583
636
|
lastAnnotations = docAnnotations;
|
|
584
637
|
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// ---- css: follow the body winner (visually coupled) --------------------
|
|
641
|
+
if (bodyWinner === 'local') {
|
|
585
642
|
if (paths.css && localCss !== null && localCss !== docCss) {
|
|
586
643
|
applyCssToDoc(doc, localCss, origin);
|
|
587
644
|
lastCss = localCss;
|
|
@@ -590,12 +647,6 @@ export function createCanvasSyncAgent(opts: CanvasSyncAgentOptions): CanvasSyncA
|
|
|
590
647
|
lastCss = docCss;
|
|
591
648
|
}
|
|
592
649
|
} else {
|
|
593
|
-
lastAnnotations = docAnnotations;
|
|
594
|
-
if (docAnnotations !== '' && localAnnotations !== docAnnotations) {
|
|
595
|
-
const hash = hashBytes(docAnnotations);
|
|
596
|
-
echoGuard.record(paths.annotations, hash);
|
|
597
|
-
writer(paths.annotations, docAnnotations);
|
|
598
|
-
}
|
|
599
650
|
lastCss = docCss;
|
|
600
651
|
if (paths.css && docCss !== null && localCss !== docCss) {
|
|
601
652
|
const hash = hashBytes(docCss);
|