anniedrawing 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +1 -1
  3. package/dist/agent/index.js +1 -1
  4. package/dist/agent/index.js.map +1 -1
  5. package/dist/core/catalog.d.ts +1 -1
  6. package/dist/core/index.js +1 -1
  7. package/dist/core/textFit.d.ts +13 -0
  8. package/dist/docs/agents-repository.md +1 -1
  9. package/dist/docs/agents.md +2 -2
  10. package/dist/docs/api.md +3 -3
  11. package/dist/docs/board-js.md +16 -16
  12. package/dist/docs/decisions.md +15 -1
  13. package/dist/docs/format.md +2 -2
  14. package/dist/docs/index.html +15 -7
  15. package/dist/docs/llms-full.txt +16 -16
  16. package/dist/docs/llms.txt +10 -10
  17. package/dist/docs/mcp.md +1 -1
  18. package/dist/fellow.js +1 -1
  19. package/dist/index.js +1 -1
  20. package/dist/shared/board-OPwsZ2_V.js +2 -0
  21. package/dist/shared/board-OPwsZ2_V.js.map +1 -0
  22. package/dist/shared/{cards-DF0uI4-I.js → cards-D_9Lly1d.js} +2 -2
  23. package/dist/shared/{cards-DF0uI4-I.js.map → cards-D_9Lly1d.js.map} +1 -1
  24. package/dist/shared/defaults-DZEoAeRz.js +2 -0
  25. package/dist/shared/defaults-DZEoAeRz.js.map +1 -0
  26. package/dist/shared/describe-o3vER0cL.js +3 -0
  27. package/dist/shared/{describe-DaWyf3qV.js.map → describe-o3vER0cL.js.map} +1 -1
  28. package/dist/shared/{paste-B8nZA2Gh.js → paste-B4b0C9Jh.js} +2 -2
  29. package/dist/shared/{paste-B8nZA2Gh.js.map → paste-B4b0C9Jh.js.map} +1 -1
  30. package/dist/shared/picker-ciuPQvRn.js +2 -0
  31. package/dist/shared/picker-ciuPQvRn.js.map +1 -0
  32. package/dist/shared/textFit-BrGz6lhQ.js +2 -0
  33. package/dist/shared/textFit-BrGz6lhQ.js.map +1 -0
  34. package/dist/shared/ui-c98N8xEV.js +2 -0
  35. package/dist/shared/ui-c98N8xEV.js.map +1 -0
  36. package/dist/shared/{urlPaste-Oc4kZ0P7.js → urlPaste-BqcpeQ-c.js} +2 -2
  37. package/dist/shared/{urlPaste-Oc4kZ0P7.js.map → urlPaste-BqcpeQ-c.js.map} +1 -1
  38. package/dist/style.css +1 -1
  39. package/dist/ui/index.js +1 -1
  40. package/dist/ui/version.d.ts +1 -1
  41. package/llms-full.txt +16 -16
  42. package/llms.txt +10 -10
  43. package/package.json +1 -1
  44. package/dist/shared/board-p60lv7As.js +0 -2
  45. package/dist/shared/board-p60lv7As.js.map +0 -1
  46. package/dist/shared/defaults-C-aC_B4z.js +0 -2
  47. package/dist/shared/defaults-C-aC_B4z.js.map +0 -1
  48. package/dist/shared/describe-DaWyf3qV.js +0 -3
  49. package/dist/shared/picker-DZpEpkED.js +0 -2
  50. package/dist/shared/picker-DZpEpkED.js.map +0 -1
  51. package/dist/shared/ui-DWQtW0zJ.js +0 -2
  52. package/dist/shared/ui-DWQtW0zJ.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ import{g as e,t}from"./defaults-DZEoAeRz.js";import{n}from"./textFit-BrGz6lhQ.js";var{PI:o}=Math,a=o+1e-4,i=[1,1];function r(e,t,n,o=e=>e){return e*o(.5-t*(.5-n))}var{min:s}=Math;function d(e,t,n){let o=s(1,t/n);return s(1,e+(s(1,1-o)-e)*(.275*o))}function l(e,t){return[e[0]+t[0],e[1]+t[1]]}function c(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e}function p(e,t){return[e[0]-t[0],e[1]-t[1]]}function u(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e}function h(e,t){return[e[0]*t,e[1]*t]}function f(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e}function g(e){return[e[1],-e[0]]}function m(e,t){let n=t[0];return e[0]=t[1],e[1]=-n,e}function v(e,t){return e[0]*t[0]+e[1]*t[1]}function y(e,t){return e[0]===t[0]&&e[1]===t[1]}function b(e,t){let n=e[0]-t[0],o=e[1]-t[1];return n*n+o*o}function k(e){return function(e,t){return[e[0]/t,e[1]/t]}(e,function(e){return Math.hypot(e[0],e[1])}(e))}function x(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function M(e,t,n){let o=Math.sin(n),a=Math.cos(n),i=e[0]-t[0],r=e[1]-t[1],s=i*o+r*a;return[i*a-r*o+t[0],s+t[1]]}function A(e,t,n,o){let a=Math.sin(o),i=Math.cos(o),r=t[0]-n[0],s=t[1]-n[1],d=r*i-s*a,l=r*a+s*i;return e[0]=d+n[0],e[1]=l+n[1],e}function w(e,t,n){return l(e,h(p(t,e),n))}function L(e,t,n,o){let a=n[0]-t[0],i=n[1]-t[1];return e[0]=t[0]+a*o,e[1]=t[1]+i*o,e}function $(e,t,n){return l(e,h(t,n))}var S=[0,0],E=[0,0],C=[0,0];function F(e,t){let n=$(e,k(g(p(e,l(e,[1,1])))),-t),o=[],i=1/13;for(let r=i;r<=1;r+=i)o.push(M(n,e,2*a*r));return o}function R(e,t,n){let o=[],i=1/n;for(let r=i;r<=1;r+=i)o.push(M(t,e,a*r));return o}function T(e,t,n){let o=p(t,n),a=h(o,.5),i=h(o,.51);return[p(e,a),p(e,i),l(e,i),l(e,a)]}function H(e,t,n,o){let i=[],r=$(e,t,n),s=1/o;for(let d=s;d<1;d+=s)i.push(M(r,e,3*a*d));return i}function D(e,t,n){return[l(e,h(t,n)),l(e,h(t,.99*n)),p(e,h(t,.99*n)),p(e,h(t,n))]}function z(e,t,n){return!1===e||void 0===e?0:!0===e?Math.max(t,n):e}function U(e,t={}){let{size:n=16,smoothing:o=.5,thinning:i=.5,simulatePressure:s=!0,easing:h=e=>e,start:y={},end:k={},last:x=!1}=t,{cap:M=!0,easing:w=e=>e*(2-e)}=y,{cap:$=!0,easing:U=e=>--e*e*e+1}=k;if(0===e.length||n<=0)return[];let B,P=e[e.length-1].runningLength,Z=z(y.taper,n,P),j=z(k.taper,n,P),V=(n*o)**2,I=[],q=[],W=function(e,t,n){return e.slice(0,10).reduce((e,o)=>{let a=o.pressure;return t&&(a=d(e,o.distance,n)),(e+a)/2},e[0].pressure)}(e,s,n),O=r(n,i,e[e.length-1].pressure,h),N=e[0].vector,G=e[0].point,Y=G,_=G,X=Y,Q=!1;for(let g=0;g<e.length;g++){let{pressure:t}=e[g],{point:o,vector:y,distance:k,runningLength:x}=e[g],M=g===e.length-1;if(!M&&P-x<3)continue;i?(s&&(t=d(W,k,n)),O=r(n,i,t,h)):O=n/2,void 0===B&&(B=O);let $=x<Z?w(x/Z):1,F=P-x<j?U((P-x)/j):1;O=Math.max(.01,O*Math.min($,F));let R=(M?e[g]:e[g+1]).vector,T=M?1:v(y,R),H=null!==T&&T<0;if(v(y,N)<0&&!Q||H){m(S,N),f(S,S,O);for(let e=0;e<=1;e+=.07692307692307693)u(E,o,S),A(E,E,o,a*e),_=[E[0],E[1]],I.push(_),c(C,o,S),A(C,C,o,a*-e),X=[C[0],C[1]],q.push(X);G=_,Y=X,H&&(Q=!0)}else Q=!1,M?(m(S,y),f(S,S,O),I.push(p(o,S)),q.push(l(o,S))):(L(S,R,y,T),m(S,S),f(S,S,O),u(E,o,S),_=[E[0],E[1]],(g<=1||b(G,_)>V)&&(I.push(_),G=_),c(C,o,S),X=[C[0],C[1]],(g<=1||b(Y,X)>V)&&(q.push(X),Y=X),W=t,N=y)}let J=[e[0].point[0],e[0].point[1]],K=e.length>1?[e[e.length-1].point[0],e[e.length-1].point[1]]:l(e[0].point,[1,1]),ee=[],te=[];if(1===e.length){if(!Z&&!j||x)return F(J,B||O)}else{Z||j&&1===e.length||(M?ee.push(...R(J,q[0],13)):ee.push(...T(J,I[0],q[0])));let t=g(function(e){return[-e[0],-e[1]]}(e[e.length-1].vector));j||Z&&1===e.length?te.push(K):$?te.push(...H(K,t,O,29)):te.push(...D(K,t,O))}return I.concat(te,q.reverse(),ee)}var B=[0,0];function P(e){return null!=e&&e>=0}function Z(e,t={}){return U(function(e,t={}){let{streamline:n=.5,size:o=16,last:a=!1}=t;if(0===e.length)return[];let r=.15+.85*(1-n),s=Array.isArray(e[0])?e:e.map(({x:e,y:t,pressure:n=.5})=>[e,t,n]);if(2===s.length){let e=s[1];s=s.slice(0,-1);for(let t=1;t<5;t++)s.push(w(s[0],e,t/4))}1===s.length&&(s=[...s,[...l(s[0],i),...s[0].slice(2)]]);let d=[{point:[s[0][0],s[0][1]],pressure:P(s[0][2])?s[0][2]:.25,vector:[...i],distance:0,runningLength:0}],c=!1,p=0,h=d[0],f=s.length-1;for(let i=1;i<s.length;i++){let e=a&&i===f?[s[i][0],s[i][1]]:w(h.point,s[i],r);if(y(h.point,e))continue;let t=x(e,h.point);if(p+=t,i<f&&!c){if(p<o)continue;c=!0}u(B,h.point,e),h={point:e,pressure:P(s[i][2])?s[i][2]:.5,vector:k(B),distance:t,runningLength:p},d.push(h)}return d[0].vector=d[1]?.vector||[0,0],d}(e,t),t)}var j="http://www.w3.org/2000/svg",V={sans:"Nunito Variable, Nunito, ui-rounded, system-ui, sans-serif",serif:"Georgia, serif",mono:"ui-monospace, SFMono-Regular, Menlo, monospace",hand:"Comic Sans MS, Chalkboard SE, cursive"};function I(e){return V[e??"hand"]}var q={ink:"#103639",slate:"#606062",coral:"#FF9302",amber:"#FFC68A",moss:"#AAF1AC",teal:"#05D9AB",sky:"#92CAFF",violet:"#8F93F9",rose:"#F89B97",paper:"#FFFFFF"},W={...q,ink:"#E9F7F3",slate:"#B6C5C1",paper:"#173D40"};function O(e="ink",t="light"){return("dark"===t?W:q)[e]??e}function N(e){if(e={black:"#000000",white:"#ffffff",red:"#ff0000",blue:"#0000ff",green:"#008000",yellow:"#ffff00",transparent:"#00000000"}[e.toLowerCase()]??e,/^#[\da-f]{3,4}$/i.test(e)&&(e=`#${[...e.slice(1)].map(e=>e+e).join("")}`),/^#[\da-f]{6}([\da-f]{2})?$/i.test(e))return[1,3,5].map(t=>parseInt(e.slice(t,t+2),16)).concat(9===e.length?parseInt(e.slice(7,9),16)/255:1);if(!/^rgba?\(/i.test(e))return;const t=e.match(/[\d.]+%?/g);return!t||t.length<3?void 0:t.slice(0,3).map(e=>parseFloat(e)*(e.endsWith("%")?2.55:1)).concat(void 0===t[3]?1:parseFloat(t[3])/(t[3].endsWith("%")?100:1))}function G(e){return e.slice(0,3).map(e=>{const t=e/255;return t<=.04045?t/12.92:((t+.055)/1.055)**2.4}).reduce((e,t,n)=>e+t*[.2126,.7152,.0722][n],0)}function Y(e,t){if("text"===e.kind)return O(e.style?.stroke??"ink",t);const n=O("ink",t),o=ee(e,t);if(["connector","line"].includes(e.kind)||"solid"!==o.fillMode)return n;const a=N(o.fill);if(!a)return n;const i=N(O("paper",t)),r=G(a.slice(0,3).map((e,t)=>e*a[3]+i[t]*(1-a[3]))),s=e=>{const t=G(N(e));return(Math.max(r,t)+.05)/(Math.min(r,t)+.05)};for(const d of[n,O("ink","dark"===t?"light":"dark")])if(s(d)>=4.5)return d;return s("#0F0B0A")>=s("#FFFFFF")?"#0F0B0A":"#FFFFFF"}function _(e){return n(e)}function X(e){return String(e??"").replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[e]))}function Q(e){return Math.round(1e3*e)/1e3}function J(e,t=!1){return e.map((e,t)=>`${t?"L":"M"}${Q(e.x)},${Q(e.y)}`).join(" ")+(t?" Z":"")}function K(e){const t=e.w,n=e.h;if("ellipse"===e.kind)return`M${t},${n/2}a${t/2},${n/2} 0 1 0 ${-t},0a${t/2},${n/2} 0 1 0 ${t},0Z`;if("diamond"===e.kind)return`M${t/2},0L${t},${n/2}L${t/2},${n}L0,${n/2}Z`;if("line"===e.kind)return J((e.points??[[0,0],[t,n]]).map(([e,t])=>({x:e,y:t})));if("path"===e.kind)return function(e){const t=e.points??[];if(!t.length)return"";if(e.closed)return J(t.map(([e,t])=>({x:e,y:t})),!0);const n=Z(t.map(([e,t,n])=>({x:e,y:t,pressure:n})),{size:2.2*(e.style?.strokeWidth??2),thinning:.45,smoothing:.6,streamline:.45,simulatePressure:t.every(e=>void 0===e[2]),last:!0});return n.length?`M${n.map(e=>`${Q(e[0])},${Q(e[1])}`).join(" L")} Z`:""}(e);const o=Math.max(0,Math.min(e.style?.corner??12,t/2,n/2));return`M${o},0H${t-o}Q${t},0 ${t},${o}V${n-o}Q${t},${n} ${t-o},${n}H${o}Q0,${n} 0,${n-o}V${o}Q0,0 ${o},0Z`}function ee(e,t){const n=e.style?.fill??("note"===e.kind?"moss":"none");return{stroke:O(e.style?.stroke??"ink",t),strokeWidth:e.style?.strokeWidth??("note"===e.kind?0:2),dash:e.style?.dash??"solid",fill:O(n,t),fillMode:e.style?.fillMode??"solid",corner:e.style?.corner??12,opacity:e.style?.opacity??1}}function te(e,t,n,o=K(e)){const a=ee(e,t),i="dashed"===a.dash?"8 6":"dotted"===a.dash?"1 6":"",r="path"===e.kind,s="line"===e.kind||"connector"===e.kind?"none":r?e.closed&&"none"!==a.fill?a.fill:a.stroke:a.fill,d=`ad_h_${n.replace(/[^a-z0-9_-]/gi,"_")}`,l="hatch"===a.fillMode&&"none"!==s&&!r,c=l?`url(#${d})`:s;return`${l?`<defs><pattern id="${d}" width="8" height="8" patternUnits="userSpaceOnUse"><path d="M-2 2L2-2M0 8L8 0M6 10L10 6" fill="none" stroke="${X(s)}" stroke-opacity="0.5" stroke-width="1.3"/></pattern></defs>`:""}<path d="${X(o)}" fill="${X(c)}"${"tint"!==a.fillMode||r?"":' fill-opacity="0.22"'} stroke="${r&&!e.closed?"none":X(a.stroke)}" stroke-width="${a.strokeWidth}" stroke-linecap="round" stroke-linejoin="round"${i?` stroke-dasharray="${i}"`:""}/>`}function ne(e,t,n,o,a){if(!n||"none"===n)return"";if("dot"===n)return`<circle cx="${Q(e.x)}" cy="${Q(e.y)}" r="${Math.max(3,2*a)}" fill="${X(o)}"/>`;const i=Math.atan2(e.y-t.y,e.x-t.x),r=Math.max(10,4.5*a),s=Math.PI/6;return`<path d="${J([{x:e.x-Math.cos(i-s)*r,y:e.y-Math.sin(i-s)*r},e,{x:e.x-Math.cos(i+s)*r,y:e.y-Math.sin(i+s)*r}])}" fill="none" stroke="${X(o)}" stroke-width="${a}" stroke-linecap="round" stroke-linejoin="round"/>`}function oe(e,t,n){if(e.length<2)return"";const o=ee(t,n);return ne(e[0],e[1],t.heads?.start,o.stroke,o.strokeWidth)+ne(e[e.length-1],e[e.length-2],t.heads?.end??("connector"===t.kind?"arrow":"none"),o.stroke,o.strokeWidth)}var ae="application/vnd.anniedrawing+json";function ie(e){return JSON.stringify(e,null,2)}var re={select:'<path d="M5.8 3.8c-1-.4-1.7.4-1.4 1.4l4.9 14.4c.4 1.1 1.8 1.1 2.2 0l2.2-5.8 5.8-2.2c1.1-.4 1.1-1.8 0-2.2Z"/>',hand:'<path d="M8 12V6a2 2 0 0 1 4 0v5-7a2 2 0 0 1 4 0v8-5a2 2 0 0 1 4 0v8c0 5-4 7-7 7-3 0-4-2-6-5l-3-4c-1-2 1-4 3-2l2 2"/>',rect:'<rect x="3.75" y="4.75" width="16.5" height="14.5" rx="4"/>',ellipse:'<ellipse cx="12" cy="12" rx="8.25" ry="7.25"/>',diamond:'<path d="m13.4 3.8 6.8 6.8a2 2 0 0 1 0 2.8l-6.8 6.8a2 2 0 0 1-2.8 0l-6.8-6.8a2 2 0 0 1 0-2.8l6.8-6.8a2 2 0 0 1 2.8 0Z"/>',line:'<path d="m5.5 18.5 13-13"/><circle cx="5" cy="19" r="1.5" fill="currentColor" stroke="none"/><circle cx="19" cy="5" r="1.5" fill="currentColor" stroke="none"/>',connector:'<path d="M4 18h5a3 3 0 0 0 3-3V9a3 3 0 0 1 3-3h5m-4-4 4 4-4 4"/>',path:'<path d="M3.5 17.5c1.8-5 3.2-11 6-11 4 0-1 12 3 12 2.8 0 3.2-8 5.5-8 1.6 0 2.3 2 2.5 4"/>',text:'<path d="M5 7V4.5h14V7M12 4.5v15M8.5 19.5h7"/>',note:'<path d="M7 3.75h10a3.25 3.25 0 0 1 3.25 3.25v7.1a2 2 0 0 1-.6 1.4l-4.2 4.2a2 2 0 0 1-1.4.6H7A3.25 3.25 0 0 1 3.75 17V7A3.25 3.25 0 0 1 7 3.75Z"/><path d="M20 14h-3.5a2.5 2.5 0 0 0-2.5 2.5V20"/>',lock:'<rect x="5" y="10" width="14" height="11" rx="3.5"/><path d="M8 10V7a4 4 0 0 1 8 0v3M12 14v3"/>',unlock:'<rect x="5" y="10" width="14" height="11" rx="3.5"/><path d="M8 10V7a4 4 0 0 1 7.5-2M12 14v3"/>',opacity:'<circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 1 0 17Z" fill="currentColor" stroke="none"/>',front:'<rect x="8" y="3.5" width="12.5" height="12.5" rx="3.5"/><path d="M15.5 16v1A3.5 3.5 0 0 1 12 20.5H7A3.5 3.5 0 0 1 3.5 17v-5A3.5 3.5 0 0 1 7 8.5h1"/>',back:'<rect x="3.5" y="8" width="12.5" height="12.5" rx="3.5"/><path d="M8.5 8V7A3.5 3.5 0 0 1 12 3.5h5A3.5 3.5 0 0 1 20.5 7v5A3.5 3.5 0 0 1 17 15.5h-1"/>',eraser:'<path d="m13.2 4.3-9 9a2.4 2.4 0 0 0 0 3.4L7.5 20h4l8.2-8.2a2.4 2.4 0 0 0 0-3.4l-4.1-4.1a1.7 1.7 0 0 0-2.4 0ZM8 10.5l6 6M11.5 20H21"/>',undo:'<path d="m8 5-4.5 4.5L8 14M4 9.5h9.5a5.5 5.5 0 0 1 0 11H11"/>',redo:'<path d="m16 5 4.5 4.5L16 14m4-4.5h-9.5a5.5 5.5 0 0 0 0 11H13"/>',plus:'<path d="M12 5.5v13M5.5 12h13"/>',minus:'<path d="M5.5 12h13"/>',fit:'<path d="M8.5 3.75h-3a1.75 1.75 0 0 0-1.75 1.75v3m11.75-4.75h3a1.75 1.75 0 0 1 1.75 1.75v3M3.75 15.5v3a1.75 1.75 0 0 0 1.75 1.75h3m11.75-4.75v3a1.75 1.75 0 0 1-1.75 1.75h-3"/>',chevron:'<path d="m7 9.5 3.6 3.6a2 2 0 0 0 2.8 0L17 9.5"/>',download:'<path d="M12 3.5v11m-4-4 4 4 4-4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2"/>',upload:'<path d="M12 15V4m-4 4 4-4 4 4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2"/>',code:'<path d="m7 7-4 4a1.4 1.4 0 0 0 0 2l4 4m10-10 4 4a1.4 1.4 0 0 1 0 2l-4 4M14 4l-4 16"/>',close:'<path d="m6.5 6.5 11 11m-11 0 11-11"/>',more:'<circle cx="5" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="19" cy="12" r="1.6" fill="currentColor" stroke="none"/>',image:'<rect x="3.5" y="3.5" width="17" height="17" rx="4"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m4 17 3.6-3.6a1.3 1.3 0 0 1 1.8 0l2.1 2.1 3.4-5.1a1.3 1.3 0 0 1 2.2 0L20 15"/>',sun:'<circle cx="12" cy="12" r="4"/><path d="M12 2.5v1M12 20.5v1M2.5 12h1m17 0h1M5.3 5.3l.7.7m12 12 .7.7M5.3 18.7l.7-.7M18 6l.7-.7"/>',moon:'<path d="M20 14.5a8.2 8.2 0 0 1-10.5-10c-3.9.7-6.4 3.7-6.4 7.5a8.1 8.1 0 0 0 16.9 2.5Z"/>',trash:'<path d="M4 6.5h16M9 6.5V5a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 5v1.5m-9 0 .7 11.2A3 3 0 0 0 9.7 20.5h4.6a3 3 0 0 0 3-2.8L18 6.5M10 10.5v6m4-6v6"/>',copy:'<rect x="8" y="8" width="12.5" height="12.5" rx="3.5"/><path d="M15.5 8V7A3.5 3.5 0 0 0 12 3.5H7A3.5 3.5 0 0 0 3.5 7v5A3.5 3.5 0 0 0 7 15.5h1"/>',grid:'<rect x="3.5" y="3.5" width="17" height="17" rx="4"/><path d="M9 4v16m6-16v16M4 9h16M4 15h16"/>',book:'<path d="M12 5.5c-2.6-2-5.2-2.5-8-2v15c2.8-.5 5.4 0 8 2 2.6-2 5.2-2.5 8-2v-15c-2.8-.5-5.4 0-8 2Zm0 0v15"/>',github:'<path fill="currentColor" stroke="none" d="M12 1C5.922 1 1 5.922 1 12c0 4.867 3.149 8.979 7.521 10.437.55.096.75-.232.75-.546 0-.262-.013-1.13-.013-2.049-3.06.56-3.703-1.31-3.703-1.31-.498-1.316-1.216-1.667-1.216-1.667-.991-.68.075-.668.075-.668 1.109.075 1.688 1.264 1.688 1.264.982 1.686 2.573 1.2 3.201.907.096-.699.381-1.2.695-1.478-2.448-.282-5.022-1.226-5.022-5.451 0-1.2.426-2.187 1.12-2.953-.113-.275-.487-1.392.107-2.9 0 0 .917-.292 3.011 1.12.873-.24 1.809-.36 2.74-.36.93 0 1.867.12 2.74.36 2.077-1.413 3.01-1.12 3.01-1.12.596 1.508.221 2.625.108 2.9.697.766 1.12 1.748 1.12 2.953 0 4.237-2.578 5.163-5.034 5.437.39.338.746 1.016.746 2.056 0 1.478-.014 2.666-.014 3.025 0 .304.202.655.753.545C19.854 20.979 23 16.859 23 12c0-6.078-4.922-11-11-11Z"/>',alignLeft:'<path d="M4 5h16M4 12h10M4 19h16"/>',alignCenter:'<path d="M4 5h16M7 12h10M4 19h16"/>',alignRight:'<path d="M4 5h16M10 12h10M4 19h16"/>',align:'<path d="M4 3.5v17"/><rect x="8" y="5" width="12.5" height="5" rx="1.75"/><rect x="8" y="14" width="8.5" height="5" rx="1.75"/>',shapes:'<rect x="3" y="3" width="8.5" height="8.5" rx="2.5"/><circle cx="17.3" cy="6.7" r="3.7"/><path d="m6 14-3.5 6h8L7 14a.6.6 0 0 0-1 0Z"/><rect x="13.5" y="13.5" width="7" height="7" rx="2" transform="rotate(45 17 17)"/>',link:'<path d="M10 14.5 8.8 15.7a3.6 3.6 0 1 1-5.1-5.1l3.2-3.2a3.6 3.6 0 0 1 5.1 0"/><path d="m14 9.5 1.2-1.2a3.6 3.6 0 0 1 5.1 5.1l-3.2 3.2a3.6 3.6 0 0 1-5.1 0"/>'};function se(e){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${re[e]??re.select}</svg>`}function de(e,t,n,o="ad-icon-button"){const a=document.createElement("button");return a.type="button",a.className=o,a.title=e,a.setAttribute("aria-label",e),a.innerHTML=se(t),a.addEventListener("click",()=>{a.focus(),n()}),a}var le="0.4.0",ce="https://github.com/Frontierz-AI/AnnieDrawing",pe=["png","svg"];var ue=[["select","Select","V"],["hand","Hand","H"],["rect","Rectangle","R"],["ellipse","Ellipse","O"],["diamond","Diamond","D"],["connector","Arrow","A"],["line","Line","L"],["path","Draw","P"],["text","Text","T"],["note","Sticky note","N"],["eraser","Eraser","E"]],he=[["ink","Ink"],["paper","Paper"],["teal","Frontierz green"],["moss","Soft green"],["coral","Orange"],["violet","Lavender"],["slate","Slate"],["amber","Peach"],["sky","Sky blue"],["rose","Rose"],["none","No fill"]];function fe(e,t){return e<=700||e<=1023&&t<=640}function ge(e,t="",n){const o=document.createElement(e);return o.className=t,n&&(o.textContent=n),o}function me(e,t,n="ad-button"){const o=ge("button",n,e);return o.type="button",o.addEventListener("click",()=>{o.focus(),t()}),o}function ve(e,t){const n=ge("label","ad-field");return n.append(ge("span","ad-field-label",e),t),n}function ye(e,t,n){const o=ge("select");if(e.forEach(([e,t])=>{const n=ge("option","",t);n.value=e,o.append(n)}),!e.some(([e])=>e===t)){const e=ge("option","",t);e.value=t,o.append(e)}return o.value=t,o.onchange=()=>n(o.value),o}function be(t,n={}){const o=ge("div","ad-ui"),a=!1!==n.menu,i=!1!==n.pages;a&&o.classList.add("ad-ui-menu"),i&&o.classList.add("ad-ui-pages"),(a||i)&&o.classList.add("ad-ui-bars"),t.stage.root.append(o);const r=[];let s,d,l,c;function p(e){u(),s?.close();const n=document.activeElement,a=ge("dialog","ad-dialog"),i=ge("div","ad-dialog-head"),r=ge("div");return r.append(ge("h2","",e)),i.append(r,de("Close","close",()=>a.close())),a.append(i),a.addEventListener("click",e=>{if(e.target===a){const t=a.getBoundingClientRect();(e.clientX<t.left||e.clientX>t.right||e.clientY<t.top||e.clientY>t.bottom)&&a.close()}}),a.addEventListener("close",()=>{a.remove(),s===a&&(s=void 0),s||(we(),n?.isConnected?n.focus():t.focus())}),o.append(a),s=a,a.showModal(),a}function u(){d?.hidePopover(),d?.remove(),d=void 0,l?.setAttribute("aria-expanded","false"),l&&(l.popoverTargetElement=null),l=void 0}function h(e,n){if(e&&l===e&&d?.matches(":popover-open"))return void u();u();const a=ge("div","ad-popover");a.popover="auto",a.setAttribute("role","group"),a.setAttribute("aria-label",n);const i=document.activeElement;return e&&(e.setAttribute("aria-expanded","true"),e.popoverTargetElement=a,e.popoverTargetAction="show"),d=a,l=e,a.addEventListener("toggle",()=>{d!==a||a.matches(":popover-open")||e?.setAttribute("aria-expanded","false")}),a.addEventListener("keydown",e=>{if(e.stopPropagation(),"Escape"===e.key||"Tab"===e.key&&"manual"===a.popover)"Escape"===e.key&&e.preventDefault(),u(),i?.isConnected?i.focus():t.focus();else if(!(e.target instanceof HTMLInputElement)&&["ArrowDown","ArrowUp","ArrowLeft","ArrowRight","Home","End"].includes(e.key)){const t=g(a),n=t.indexOf(document.activeElement),o="Home"===e.key?0:"End"===e.key?t.length-1:(n+("ArrowDown"===e.key||"ArrowRight"===e.key?1:-1)+t.length)%t.length;e.preventDefault(),t[o]?.focus()}}),o.append(a),a}function f(e,n,o=n){e.showPopover();const a=o.getBoundingClientRect(),i=t.stage.root.getBoundingClientRect(),r=fe(i.width,i.height),s=Math.min(228,i.width-24);e.style.width=`${s}px`;const d=e.getBoundingClientRect().height,l=n.closest(".ad-toolbar")&&!r,c=l?a.right+12:n.closest(".ad-header")&&a.left<i.left+i.width/2?a.left:a.right-s,p=l?a.top:a.top>i.top+i.height/2?a.top-d-10:a.bottom+10;e.style.left=`${Math.max(i.left+12,Math.min(c,i.right-s-12))}px`,e.style.top=`${Math.max(i.top+12,Math.min(p,i.bottom-d-12))}px`,g(e)[0]?.focus()}function g(e){return[...e.querySelectorAll("button:not(:disabled), a[href]")]}function m(e,n){const o=h(void 0,e);o.popover="manual",o.classList.add("ad-context-menu"),o.setAttribute("role","menu"),o.tabIndex=-1;return{panel:o,add:(e,n,a,i=!1)=>{const r=me(e,()=>{u(),t.focus(),a()},"ad-tool-option");r.insertAdjacentHTML("afterbegin",se(n)),r.setAttribute("role","menuitem"),r.disabled=t.readonly||i,"trash"===n&&r.classList.add("ad-danger"),o.append(r)},show:()=>{o.showPopover();const e=t.stage.root.getBoundingClientRect(),a=Math.min(228,e.width-24);o.style.width=`${a}px`;const i=o.getBoundingClientRect().height;o.style.left=`${Math.max(e.left+12,Math.min(n.x,e.right-a-12))}px`,o.style.top=`${Math.max(e.top+12,Math.min(n.y,e.bottom-i-12))}px`,(o.querySelector("button:not(:disabled)")??o).focus()}}}const v=()=>u(),y=e=>{"manual"!==d?.popover||d.contains(e.target)||u()};window.addEventListener("resize",v),window.addEventListener("pointerdown",y,!0),r.push(()=>{window.removeEventListener("resize",v),window.removeEventListener("pointerdown",y,!0)});const b=function(e){if(!1===e)return[];if(!Array.isArray(e))return[...pe];const t=/* @__PURE__ */new Set,n=[];for(const o of e)"png"!==o&&"svg"!==o&&"json"!==o||t.has(o)||(t.add(o),n.push(o));return n}(n.export),k={png:["PNG Image","image"],svg:["SVG Image","image"],json:["AnnieDoc format","code"]},x=ge("header","ad-header");let M,A,w,L;a&&(M=de("Board menu","chevron",function(){if(!M)return;const e=h(M,"Board menu");if(!e)return;e.classList.add("ad-tool-options");const n=(t,n,o,a=!1)=>{const i=de(t,n,()=>{u(),o()},"ad-tool-option");i.innerHTML+=`<span>${t}</span>`,i.disabled=a,e.append(i)};n("Open a drawing","upload",()=>A?.click(),t.readonly),fe(t.stage.root.clientWidth,t.stage.root.clientHeight)&&n("Hand","hand",()=>{t.setTool("hand"),t.focus()});n(t.grid?"Hide grid":"Show grid","grid",()=>t.setGrid(!t.grid));const o="dark"===t.stage.resolvedTheme;n(o?"Light appearance":"Dark appearance",o?"sun":"moon",()=>t.setTheme(o?"light":"dark")),n("Documentation","book",()=>{window.open("./docs/index.html","_blank","noopener")});const a=ge("a","ad-tool-option");a.href=ce,a.target="_blank",a.rel="noopener noreferrer",a.title="GitHub",a.innerHTML=`${se("github")}<span>GitHub</span>`,a.addEventListener("click",()=>u());const i=ge("div","ad-menu-separator");i.setAttribute("role","separator"),e.append(a,i,ge("p","ad-menu-version",`v${le}`)),f(e,M)},"ad-brand"),M.innerHTML='<span class="ad-brand-mark" aria-hidden="true"><svg viewBox="0 0 40 40"><path d="M9 29 20 8l11 21M14 22h12" fill="none" stroke="currentColor" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="32" cy="9" r="2.5" fill="currentColor"/></svg></span><span class="ad-brand-name">AnnieDrawing</span>'+se("chevron"),M.setAttribute("aria-haspopup","true"),M.setAttribute("aria-expanded","false"),A=ge("input"),A.type="file",A.accept=".annie,.json,application/json",A.hidden=!0,A.onchange=()=>{const e=A?.files?.[0];A&&(A.value=""),e&&e.text().then(e=>t.load(JSON.parse(e))).catch(()=>{})},x.append(M));const $=ge("div","ad-header-actions");b.length&&(w=me("Export",function(){if(1===b.length)return void Ae(b[0]);if(!w)return;const e=h(w,"Export");if(!e)return;e.classList.add("ad-tool-options");for(const t of b){const[n,o]=k[t],a=de(n,o,()=>{u(),Ae(t)},"ad-tool-option");a.innerHTML+=`<span>${n}</span>`,e.append(a)}f(e,w)},"ad-button ad-primary ad-header-export"),w.insertAdjacentHTML("afterbegin",se("download")),b.length>1&&(w.setAttribute("aria-haspopup","true"),w.setAttribute("aria-expanded","false")),$.append(w)),L=de("Board controls","more",function(){const e=h(L,"Board controls");if(!e)return;e.classList.add("ad-chrome-popover");const n=ge("div","ad-chrome-history"),o=de("Undo","undo",()=>{t.undo(),o.disabled=!t.canUndo,a.disabled=!t.canRedo}),a=de("Redo","redo",()=>{t.redo(),o.disabled=!t.canUndo,a.disabled=!t.canRedo});if(o.disabled=!t.canUndo,a.disabled=!t.canRedo,n.append(o,a),e.append(n),i){const n=ge("section","ad-chrome-section");n.append(ge("p","ad-chrome-label","Pages"));const o=ge("div","ad-chrome-pages");for(const e of t.read().pages)o.append(Y(e.id,e.name));const a=de("Add page","plus",K,"ad-tool-option");a.innerHTML+="<span>Add page</span>",a.disabled=t.readonly,n.append(o,a),e.append(n)}const r=ge("section","ad-chrome-section");r.append(ge("p","ad-chrome-label","View"));const s=ge("div","ad-zoom-controls"),d=me(`${Math.round(100*t.view.zoom)}%`,()=>{t.view.zoom=1,d.textContent="100%"},"ad-zoom-value");d.setAttribute("aria-label","Reset zoom");const l=()=>{d.textContent=`${Math.round(100*t.view.zoom)}%`};if(s.append(de("Zoom out","minus",()=>{t.view.zoom/=1.2,l()}),d,de("Zoom in","plus",()=>{t.view.zoom*=1.2,l()}),de("Fit drawing","fit",()=>{t.view.fit(),l()})),r.append(s),e.append(r),b.length){const t=ge("section","ad-chrome-section");t.append(ge("p","ad-chrome-label","Export"));for(const e of b){const[n,o]=k[e],a=de(n,o,()=>{u(),Ae(e)},"ad-tool-option");a.innerHTML+=`<span>${n}</span>`,t.append(a)}e.append(t)}f(e,L)}),L.classList.add("ad-chrome"),L.setAttribute("aria-haspopup","true"),L.setAttribute("aria-expanded","false"),$.append(L),x.append($),a||x.classList.add("ad-header-end"),o.append(x),A&&o.append(A);const S=ge("nav","ad-toolbar");function E(e,n=!1){const[,o,a]=ue.find(t=>t[0]===e),i=de(o,e,()=>{u(),t.setTool(e),t.focus()},n?"ad-tool-option":"ad-icon-button");return i.dataset.tool=e,i.setAttribute("aria-keyshortcuts",a),i.setAttribute("aria-pressed",String(t.tool===e)),i.innerHTML+=n?`<span>${o}</span>`:`<span class="ad-tooltip">${o}</span>`,t.readonly&&"hand"!==e&&"select"!==e&&(i.disabled=!0),i}S.setAttribute("aria-label","Drawing tools");const C=["rect","ellipse","diamond","line","connector"],F=de("Shapes","shapes",()=>{const e=h(F,"Shapes");e&&(e.classList.add("ad-tool-options"),e.append(...C.map(e=>E(e,!0))),f(e,F))});F.setAttribute("aria-haspopup","true"),F.setAttribute("aria-expanded","false"),F.innerHTML+='<span class="ad-tool-corner"></span><span class="ad-tooltip">Shapes</span>';const R=ge("input");R.type="file",R.accept="image/png,image/jpeg,image/webp,image/gif,image/avif",R.hidden=!0,R.onchange=()=>{R.files?.[0]&&t.addImage(R.files[0]).catch(()=>{}),R.value=""};const T=de("Add image","image",()=>{u(),R.click()});T.innerHTML+='<span class="ad-tooltip">Add image</span>',T.disabled=t.readonly;const H=E("hand");a&&H.classList.add("ad-desktop-tool"),S.append(E("select"),H,E("eraser"),ge("div","ad-toolbar-divider"),F,E("path"),E("text"),E("note"),T,R),o.append(S);const D=ge("aside","ad-style-dock");D.setAttribute("aria-label","Selection style"),D.hidden=!0;const z=ge("div","ad-style-panel"),U=de("Deselect","chevron",()=>t.select([]));U.classList.add("ad-style-dismiss"),D.append(U,z),o.append(D);const B=ge("footer","ad-footer"),P=de("Undo","undo",()=>t.undo()),Z=de("Redo","redo",()=>t.redo());P.setAttribute("aria-keyshortcuts","Meta+Z Control+Z"),Z.setAttribute("aria-keyshortcuts","Meta+Shift+Z Control+Shift+Z");const j=ge("nav","ad-pages");j.setAttribute("aria-label","Pages");const I=ge("div","ad-page-tabs");I.setAttribute("role","tablist"),I.setAttribute("aria-label","Pages");const q=de("All pages","more",function(){const e=h(q,"All pages");if(!e)return;e.classList.add("ad-pages-popover");for(const n of t.read().pages){const t=ge("div","ad-page-row");t.append(Y(n.id,n.name));const o=de(`Actions for ${n.name}`,"more",()=>{const e=o.getBoundingClientRect();G(n.id,n.name,{x:e.left,y:e.top})});t.append(o),e.append(t)}f(e,q),e.querySelector('[aria-current="true"]')?.scrollIntoView({block:"nearest"})});q.setAttribute("aria-haspopup","true"),q.setAttribute("aria-expanded","false"),q.hidden=!0;const W=de("Add page","plus",K);W.disabled=t.readonly,j.append(I,q,W);let N="";function G(e,n,o){const a=m("Page actions",o);a.add("Rename page","text",()=>function(e,n){if(t.readonly)return;const o=p("Name this page"),a=ge("input");a.value=n,a.maxLength=100,o.append(ve("Page name",a),me("Save name",()=>{a.value.trim()&&t.apply([{op:"page.set",id:e,patch:{name:a.value.trim()}}],{origin:"user",label:"Rename page"}),o.close()},"ad-button ad-primary")),a.addEventListener("keydown",e=>{"Enter"===e.key&&o.querySelector(".ad-primary")?.click()}),o.addEventListener("close",()=>{const t=I.querySelector(`[data-page-id="${CSS.escape(e)}"]`);t&&!t.hidden?t.focus():q.hidden||q.focus()},{once:!0}),a.focus(),a.select()}(e,n)),a.add("Delete page","trash",()=>{t.apply([{op:"page.remove",id:e}],{origin:"user",label:"Delete page"})},1===t.read().pages.length),a.show()}function Y(e,n,o=!1){const a=me(n,()=>{u(),t.setPage(e),I.querySelector('[aria-selected="true"]')?.focus()},o?"ad-page-tab":"ad-tool-option");a.title=n,a.dataset.pageId=e;let i,r=!1;a.addEventListener("pointerdown",t=>{r=!1,"touch"===t.pointerType&&(i={x:t.clientX,y:t.clientY},clearTimeout(c),c=setTimeout(()=>{r=!0,G(e,n,i)},500))}),a.addEventListener("pointermove",e=>{i&&Math.hypot(e.clientX-i.x,e.clientY-i.y)>10&&clearTimeout(c)});for(const t of["pointerup","pointercancel"])a.addEventListener(t,()=>clearTimeout(c));return a.addEventListener("click",e=>{r&&(e.preventDefault(),e.stopImmediatePropagation())},!0),o?(a.setAttribute("role","tab"),a.setAttribute("aria-selected",String(t.pageId===e)),a.tabIndex=t.pageId===e?0:-1):a.setAttribute("aria-current",String(t.pageId===e)),a.addEventListener("contextmenu",t=>{t.preventDefault(),G(e,n,{x:t.clientX,y:t.clientY})}),a.addEventListener("keydown",i=>{if("ContextMenu"===i.key||i.shiftKey&&"F10"===i.key){i.preventDefault();const t=a.getBoundingClientRect();G(e,n,{x:t.left,y:t.top})}else if(o&&["ArrowLeft","ArrowRight","Home","End"].includes(i.key)){i.preventDefault();const n=t.read().pages,o=n.findIndex(t=>t.id===e),a="Home"===i.key?0:"End"===i.key?n.length-1:(o+("ArrowRight"===i.key?1:-1)+n.length)%n.length;u(),t.setPage(n[a].id),I.querySelector('[aria-selected="true"]')?.focus()}}),a}let X=!1;function Q(){if(X)return;X=!0;const e=ge("div","ad-page-tabs");try{const t=[...I.querySelectorAll("button")];e.style.cssText="position:absolute;visibility:hidden;pointer-events:none;width:max-content";const n=t.map(e=>{const t=e.cloneNode(!0);return t.hidden=!1,t.style.maxWidth="",t}),a=q.cloneNode(!0);a.hidden=!1,e.append(...n,a),o.append(e);const i=n.map(e=>e.getBoundingClientRect().width),r=a.offsetWidth;e.remove();const s=i.reduce((e,t)=>e+t+4,0)+W.offsetWidth+14,d=j.offsetTop===te.offsetTop?B.clientWidth-te.offsetWidth-16:j.clientWidth,l=Math.min(d,520),c=s<=l,p=t.map(()=>!1),u=t.map(()=>"");if(!c){let e=Math.max(40,l-W.offsetWidth-14-r-4);const n=t.findIndex(e=>"true"===e.getAttribute("aria-selected"));for(const o of[n,...t.map((e,t)=>t).filter(e=>e!==n)])o<0||(o===n?(u[o]=`${e}px`,e-=Math.min(e,i[o])+4):(p[o]=i[o]>e,p[o]||(e-=i[o]+4)))}q.hidden=c,t.forEach((e,t)=>{e.hidden=p[t],e.style.maxWidth=u[t]})}finally{e.remove(),X=!1}}const J=new ResizeObserver(Q);function K(){u();const n=e(),o=t.read().pages;let a=o.length+1;for(;o.some(e=>e.name===`Page ${a}`);)a++;t.apply([{op:"page.add",page:{id:n,name:`Page ${a}`,items:[]}}],{origin:"user",label:"Add page"}).ok&&t.setPage(n)}i&&(J.observe(o),r.push(()=>J.disconnect()));const te=ge("div","ad-footer-right"),ne=ge("div","ad-zoom"),oe=me("100%",()=>{const e=h(oe,"Zoom controls");if(!e)return;const n=ge("div","ad-zoom-controls");n.append(de("Zoom out","minus",()=>t.view.zoom/=1.2),me("100%",()=>t.view.zoom=1,"ad-zoom-value"),de("Zoom in","plus",()=>t.view.zoom*=1.2)),e.append(n),f(e,oe,ie)},"ad-zoom-value");oe.setAttribute("aria-label","Zoom controls"),oe.setAttribute("aria-haspopup","true"),oe.setAttribute("aria-expanded","false");const ie=de("Fit drawing","fit",()=>t.view.fit());function re(e){return"video"===e?"Edit Video URL":"Edit URL"}function be(e){if(t.readonly||t.isLocked(e))return;const n=t.get(e);if(!n||"video"!==n.kind&&"link"!==n.kind)return;const o="video"===n.kind,a=p(o?"Edit video URL":"Edit URL"),i=ge("input");i.type="text",i.inputMode="url",i.setAttribute("autocomplete","url"),i.spellcheck=!1,i.maxLength=2e3,i.value=n.href??"",i.setAttribute("aria-label",o?"Video URL":"URL");const r=ge("p","ad-dialog-error");r.setAttribute("role","alert"),r.hidden=!0;const s=me(o?"Save video URL":"Save URL",()=>{(async()=>{s.disabled=!0;const n=await t.setHref(e,i.value);if(s.disabled=!1,!n.ok){const e=n.errors[0]?.code;return r.textContent="LOCKED"===e||"READONLY"===e?n.errors[0]?.message??"This cannot be edited.":o?"Use a YouTube or Vimeo URL.":"Use an http(s) URL.",r.hidden=!1,i.setAttribute("aria-invalid","true"),void i.focus()}a.close()})()},"ad-button ad-primary");a.append(ve(o?"Video URL":"URL",i),r,s),i.addEventListener("input",()=>{r.hidden=!0,i.removeAttribute("aria-invalid")}),i.addEventListener("keydown",e=>{"Enter"===e.key&&a.querySelector(".ad-primary")?.click()}),i.focus(),i.select()}ne.append(oe,ie,P,Z),te.append(ne),i?B.append(j,te):B.append(te),o.append(B);let ke="";function xe(){const e=t.selection.some(e=>t.isLocked(e));if("select"!==t.tool)return l&&D.contains(l)&&u(),void(D.hidden=!0);if(s||!e&&document.activeElement instanceof HTMLInputElement&&"range"===document.activeElement.type&&(D.contains(document.activeElement)||d?.contains(document.activeElement)))return;const n=D.contains(document.activeElement)?document.activeElement:void 0,o=l&&D.contains(l)?{label:l.getAttribute("aria-label"),focused:d?.contains(document.activeElement)}:void 0,a=n?.getAttribute("aria-label")??(o?.focused?o.label:void 0),i=n?.closest("label")?.querySelector(".ad-field-label")?.textContent;o&&u();const r=t.selection.map(e=>t.get(e)).filter(Boolean),c=r.map(e=>e.id).join(",");if(ke!==c&&u(),ke=c,z.replaceChildren(),D.hidden=0===r.length,!r.length)return void(o?.focused&&t.focus());const p=r[0],g=1===r.length,m=r.every(e=>["rect","ellipse","diamond","note"].includes(e.kind)),v=r.every(e=>!["image","html","video","link","group","text","note"].includes(e.kind)),y=r.every(e=>"text"===e.kind),b=r.every(e=>!["image","path","line","group","html","video","link"].includes(e.kind)),k=ge("div","ad-color-controls");function x(e,n){const o=p.style?.[n]??("fill"===n?"note"===p.kind?"moss":"none":"ink"),a=me(e,()=>{const i=h(a,`${e} color`);if(i){i.classList.add("ad-color-popover");for(const[a,r]of he){const s=ge("button","ad-swatch "+("none"===a?"ad-swatch-none":""));s.type="button",s.style.setProperty("--swatch",O(a,t.stage.resolvedTheme)),s.setAttribute("aria-label",`${e}: ${r}`),s.title=r,s.setAttribute("aria-pressed",String(o===a)),s.onclick=()=>{u(),t.defaultStyle[n]=a,t.updateSelection({style:{[n]:a}}),z.querySelector(`[aria-label="${e}"]`)?.focus()},i.append(s)}f(i,a)}},"ad-color-control");a.setAttribute("aria-label",e),a.setAttribute("aria-haspopup","true"),a.setAttribute("aria-expanded","false");const i=ge("span","ad-color-preview "+("none"===o?"ad-swatch-none":""));i.style.setProperty("--swatch",O(o,t.stage.resolvedTheme)),a.prepend(i),k.append(a)}m&&x("Fill","fill"),v&&x("Line","stroke"),y&&x("Color","stroke");const M=me("Opacity",()=>{const e=h(M,"Opacity controls");if(!e)return;e.classList.add("ad-opacity-popover");const n=ge("input");n.type="range",n.setAttribute("aria-label","Opacity"),n.min="0",n.max="100",n.value=String(Math.round(100*(t.get(p.id)?.style?.opacity??1)));const o=ge("output","",`${n.value}%`),a=ve("Opacity",n);a.querySelector(".ad-field-label").append(o);let i=!0;n.oninput=()=>{o.textContent=`${n.value}%`,t.apply(r.map(({id:e})=>({op:"set",id:e,patch:{style:{opacity:Number(n.value)/100}}})),{origin:"user",label:"Change opacity",merge:!i}),i=!1},n.onchange=()=>{i=!0},e.append(a),f(e,M),n.focus()},"ad-color-control");M.insertAdjacentHTML("afterbegin",se("opacity")),M.setAttribute("aria-label","Opacity"),M.setAttribute("aria-haspopup","true"),M.setAttribute("aria-expanded","false"),r.every(e=>"group"!==e.kind)&&k.append(M),k.childElementCount&&z.append(k);const A=e=>t.apply(r.map(t=>({op:"set",id:t.id,patch:{text:{value:t.text?.value??"",...e}}})),{origin:"user",label:"Text style"});function w(e){const t=ge("div","ad-style-row"),n=ge("div","ad-segments");return n.setAttribute("role","group"),n.setAttribute("aria-label",e),t.append(ge("span","ad-style-label",e),n),z.append(t),n}function L(e,t,n,o){return t.map(([t,a,i])=>{const s=me(a,()=>o(t),"ad-segment");return s.setAttribute("aria-label",a),s.title=a,s.setAttribute("aria-pressed",String(r.every(e=>n(e)===t))),s.innerHTML=i,e.append(s),s})}function $(e,t=""){return`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 12h18" fill="none" stroke="currentColor" stroke-width="${e}" stroke-linecap="round"${t?` stroke-dasharray="${t}"`:""}/></svg>`}if(b){L(w("Text"),[["s","Text size: Small","S"],["m","Text size: Medium","M"],["l","Text size: Large","L"],["xl","Text size: Extra large","XL"]],e=>({14:"s",18:"m",26:"l",36:"xl"}[_(e.text)]??""),e=>A({size:e})),L(w("Align"),[["start","Align text left",se("alignLeft")],["center","Align text center",se("alignCenter")],["end","Align text right",se("alignRight")]],e=>e.text?.align??("text"===e.kind?"start":"center"),e=>A({align:e}));const e=[["sans","Font: Friendly","Aa"],["serif","Font: Serif","Aa"],["mono","Font: Mono","Aa"],["hand","Font: Handwritten","Aa"]];L(w("Font"),e,e=>e.text?.font??"hand",e=>A({font:e})).forEach((t,n)=>{t.style.fontFamily=V[e[n][0]]})}if(v&&(L(w("Line"),[["1","Line: Fine",$(1)],["2","Line: Regular",$(2)],["4","Line: Bold",$(4)],["8","Line: Extra bold",$(6)]],e=>String(ee(e,t.stage.resolvedTheme).strokeWidth),e=>t.updateSelection({style:{strokeWidth:Number(e)}})),r.every(e=>"path"!==e.kind||e.closed)&&L(w("Pattern"),[["solid","Pattern: Solid",$(2)],["dashed","Pattern: Dashed",$(2,"5 4")],["dotted","Pattern: Dotted",$(2,"1 5")]],e=>e.style?.dash??"solid",e=>t.updateSelection({style:{dash:e}}))),g&&"connector"===p.kind&&z.append(ve("Route",ye([["straight","Straight"],["elbow","Elbow"],["curve","Curve"]],p.route??"elbow",e=>t.updateSelection({route:e})))),g&&"connector"===p.kind&&z.append(ve("Arrowhead",ye([["arrow","Arrow"],["dot","Dot"],["none","None"]],p.heads?.end??"arrow",e=>t.updateSelection({heads:{...p.heads,end:e}})))),g&&("video"===p.kind||"link"===p.kind)){const e=re(p.kind),t=me(e,()=>be(p.id),"ad-button ad-href-edit");t.setAttribute("aria-label",e),z.append(t)}const S=de(e?"Unlock selection":"Lock selection",e?"lock":"unlock",()=>t.updateSelection({locked:!e}));S.setAttribute("aria-pressed",String(e));const E=ge("div","ad-selection-actions");E.append(de("Duplicate selection","copy",()=>t.duplicate()),de("More arrangement options","align",Me),S,de("Delete selection","trash",()=>t.deleteSelection())),z.append(E),(t.readonly||e)&&z.querySelectorAll("button,input,select").forEach(e=>e.disabled=e!==U&&(e!==S||t.readonly)),"Unlock selection"===a||"Lock selection"===a?S.focus():"Deselect"===a?U.focus():a?z.querySelector(`[aria-label="${CSS.escape(a)}"]`)?.focus():i&&[...z.querySelectorAll("label")].find(e=>e.querySelector(".ad-field-label")?.textContent===i)?.querySelector("input,select")?.focus(),(n||o?.focused)&&(!e||t.readonly||D.contains(document.activeElement)||S.focus())}function Me(){const e=p("Give it a little order"),n=ge("div","ad-action-grid");if((1===t.selection.length?t.get(t.selection[0]):void 0)&&n.append(me("Duplicate",()=>{t.duplicate(),e.close()}),me("Delete",()=>{t.deleteSelection(),e.close()})),t.selection.length>1)for(const o of["left","center","right","top","middle","bottom","horizontal","vertical"])n.append(me("horizontal"===o||"vertical"===o?`Distribute ${o}`:`Align ${o}`,()=>{t.align(o),e.close()}));t.selection.length>1&&n.append(me("Group",()=>{t.group(),e.close()})),t.selection.some(e=>"group"===t.get(e)?.kind)&&n.append(me("Ungroup",()=>{t.ungroup(),e.close()})),n.append(me("Bring to front",()=>{t.apply(t.selection.map(e=>({op:"order",id:e,to:"front"})),{origin:"user",label:"Bring to front"}),e.close()}),me("Send to back",()=>{t.apply(t.selection.map(e=>({op:"order",id:e,to:"back"})),{origin:"user",label:"Send to back"}),e.close()})),t.readonly&&n.querySelectorAll("button").forEach(e=>e.disabled=!0),e.append(n)}function Ae(e){t.export(e,{scope:"page",padding:40,background:!0,..."png"===e?{scale:2}:{}}).then(n=>{!function(e,t,n){const o=URL.createObjectURL("string"==typeof e?new Blob([e],{type:n}):e),a=ge("a");a.href=o,a.download=t,a.click(),setTimeout(()=>URL.revokeObjectURL(o),1e3)}(n,`${t.read().meta.title.replace(/[^a-z0-9 _-]/gi,"").trim()||"drawing"}.${"json"===e?"annie":e}`,"json"===e?ae:"svg"===e?"image/svg+xml":"image/png")}).catch(()=>{})}function we(){P.disabled=!t.canUndo,Z.disabled=!t.canRedo,function(){if(!i)return;const e=t.read().pages,n=JSON.stringify([t.pageId,e.map(({id:e,name:t})=>[e,t])]);n!==N&&(N=n,I.replaceChildren(...e.map(e=>Y(e.id,e.name,!0))),Q())}(),xe()}const Le=e=>{const{x:n,y:o,id:a}=e.detail,i=a?t.get(a):void 0;if(!i)return void u();const r=t.stage.root.getBoundingClientRect(),s=m("Element actions",{x:r.left+n,y:r.top+o}),d=t.isLocked(i.id);"video"!==i.kind&&"link"!==i.kind||s.add(re(i.kind),"link",()=>be(i.id),d),["image","path","line","group","html","video","link"].includes(i.kind)||s.add("Edit text","text",()=>t.editText(i.id),d);const l=e=>t.apply([{op:"order",id:i.id,to:e}],{origin:"user",label:"front"===e?"Bring to front":"Send to back"});s.add("Bring to front","front",()=>l("front"),d),s.add("Send to back","back",()=>l("back"),d),s.add("Duplicate","copy",()=>{t.select([i.id]),t.duplicate()},d);const c=ge("div","ad-menu-separator");c.setAttribute("role","separator"),s.panel.append(c),s.add("Delete","trash",()=>{t.select([i.id]),t.deleteSelection()},d),s.show()};return t.host.addEventListener("ad-context",Le),r.push(t.on("change",we),t.on("select",()=>{xe()}),t.on("page",we),t.on("view",e=>{"manual"===d?.popover&&u(),oe.textContent=`${Math.round(100*e.zoom)}%`}),t.on("tool",e=>{for(const t of o.querySelectorAll("[data-tool]"))t.setAttribute("aria-pressed",String(e===t.dataset.tool));F.setAttribute("aria-pressed",String(C.includes(e))),t.stage.root.dataset.adTool=e,xe()})),we(),()=>{clearTimeout(c),u(),r.forEach(e=>e()),s?.close(),t.host.removeEventListener("ad-context",Le),o.remove()}}export{O as a,_ as c,Y as d,J as f,j as i,V as l,te as m,ae as n,X as o,Q as p,ie as r,I as s,be as t,oe as u};
2
+ //# sourceMappingURL=ui-c98N8xEV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-c98N8xEV.js","names":[],"sources":["../../node_modules/perfect-freehand/dist/esm/index.mjs","../../src/stage/paint.ts","../../src/porter/json.ts","../../src/ui/icons.ts","../../src/ui/version.ts","../../src/ui/index.ts"],"sourcesContent":["const{PI:e}=Math,t=e+1e-4,n=.5,r=[1,1];function i(e,t,n,r=e=>e){return e*r(.5-t*(.5-n))}const{min:a}=Math;function o(e,t,n){let r=a(1,t/n);return a(1,e+(a(1,1-r)-e)*(r*.275))}function s(e){return[-e[0],-e[1]]}function c(e,t){return[e[0]+t[0],e[1]+t[1]]}function l(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e}function u(e,t){return[e[0]-t[0],e[1]-t[1]]}function d(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e}function f(e,t){return[e[0]*t,e[1]*t]}function p(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e}function m(e,t){return[e[0]/t,e[1]/t]}function h(e){return[e[1],-e[0]]}function g(e,t){let n=t[0];return e[0]=t[1],e[1]=-n,e}function ee(e,t){return e[0]*t[0]+e[1]*t[1]}function _(e,t){return e[0]===t[0]&&e[1]===t[1]}function v(e){return Math.hypot(e[0],e[1])}function y(e,t){let n=e[0]-t[0],r=e[1]-t[1];return n*n+r*r}function b(e){return m(e,v(e))}function x(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function S(e,t,n){let r=Math.sin(n),i=Math.cos(n),a=e[0]-t[0],o=e[1]-t[1],s=a*i-o*r,c=a*r+o*i;return[s+t[0],c+t[1]]}function C(e,t,n,r){let i=Math.sin(r),a=Math.cos(r),o=t[0]-n[0],s=t[1]-n[1],c=o*a-s*i,l=o*i+s*a;return e[0]=c+n[0],e[1]=l+n[1],e}function w(e,t,n){return c(e,f(u(t,e),n))}function te(e,t,n,r){let i=n[0]-t[0],a=n[1]-t[1];return e[0]=t[0]+i*r,e[1]=t[1]+a*r,e}function T(e,t,n){return c(e,f(t,n))}const E=[0,0],D=[0,0],O=[0,0];function k(e,n){let r=T(e,b(h(u(e,c(e,[1,1])))),-n),i=[],a=1/13;for(let n=a;n<=1;n+=a)i.push(S(r,e,t*2*n));return i}function A(e,n,r){let i=[],a=1/r;for(let r=a;r<=1;r+=a)i.push(S(n,e,t*r));return i}function j(e,t,n){let r=u(t,n),i=f(r,.5),a=f(r,.51);return[u(e,i),u(e,a),c(e,a),c(e,i)]}function M(e,n,r,i){let a=[],o=T(e,n,r),s=1/i;for(let n=s;n<1;n+=s)a.push(S(o,e,t*3*n));return a}function ne(e,t,n){return[c(e,f(t,n)),c(e,f(t,n*.99)),u(e,f(t,n*.99)),u(e,f(t,n))]}function N(e,t,n){return e===!1||e===void 0?0:e===!0?Math.max(t,n):e}function re(e,t,n){return e.slice(0,10).reduce((e,r)=>{let i=r.pressure;return t&&(i=o(e,r.distance,n)),(e+i)/2},e[0].pressure)}function P(e,n={}){let{size:r=16,smoothing:a=.5,thinning:f=.5,simulatePressure:m=!0,easing:_=e=>e,start:v={},end:b={},last:x=!1}=n,{cap:S=!0,easing:w=e=>e*(2-e)}=v,{cap:T=!0,easing:P=e=>--e*e*e+1}=b;if(e.length===0||r<=0)return[];let F=e[e.length-1].runningLength,I=N(v.taper,r,F),L=N(b.taper,r,F),R=(r*a)**2,z=[],B=[],V=re(e,m,r),H=i(r,f,e[e.length-1].pressure,_),U,W=e[0].vector,G=e[0].point,K=G,q=G,J=K,Y=!1;for(let n=0;n<e.length;n++){let{pressure:a}=e[n],{point:s,vector:h,distance:v,runningLength:b}=e[n],x=n===e.length-1;if(!x&&F-b<3)continue;f?(m&&(a=o(V,v,r)),H=i(r,f,a,_)):H=r/2,U===void 0&&(U=H);let S=b<I?w(b/I):1,T=F-b<L?P((F-b)/L):1;H=Math.max(.01,H*Math.min(S,T));let k=(x?e[n]:e[n+1]).vector,A=x?1:ee(h,k),j=ee(h,W)<0&&!Y,M=A!==null&&A<0;if(j||M){g(E,W),p(E,E,H);for(let e=0;e<=1;e+=.07692307692307693)d(D,s,E),C(D,D,s,t*e),q=[D[0],D[1]],z.push(q),l(O,s,E),C(O,O,s,t*-e),J=[O[0],O[1]],B.push(J);G=q,K=J,M&&(Y=!0);continue}if(Y=!1,x){g(E,h),p(E,E,H),z.push(u(s,E)),B.push(c(s,E));continue}te(E,k,h,A),g(E,E),p(E,E,H),d(D,s,E),q=[D[0],D[1]],(n<=1||y(G,q)>R)&&(z.push(q),G=q),l(O,s,E),J=[O[0],O[1]],(n<=1||y(K,J)>R)&&(B.push(J),K=J),V=a,W=h}let X=[e[0].point[0],e[0].point[1]],Z=e.length>1?[e[e.length-1].point[0],e[e.length-1].point[1]]:c(e[0].point,[1,1]),Q=[],$=[];if(e.length===1){if(!(I||L)||x)return k(X,U||H)}else{I||L&&e.length===1||(S?Q.push(...A(X,B[0],13)):Q.push(...j(X,z[0],B[0])));let t=h(s(e[e.length-1].vector));L||I&&e.length===1?$.push(Z):T?$.push(...M(Z,t,H,29)):$.push(...ne(Z,t,H))}return z.concat($,B.reverse(),Q)}const F=[0,0];function I(e){return e!=null&&e>=0}function L(e,t={}){let{streamline:i=.5,size:a=16,last:o=!1}=t;if(e.length===0)return[];let s=.15+(1-i)*.85,l=Array.isArray(e[0])?e:e.map(({x:e,y:t,pressure:r=n})=>[e,t,r]);if(l.length===2){let e=l[1];l=l.slice(0,-1);for(let t=1;t<5;t++)l.push(w(l[0],e,t/4))}l.length===1&&(l=[...l,[...c(l[0],r),...l[0].slice(2)]]);let u=[{point:[l[0][0],l[0][1]],pressure:I(l[0][2])?l[0][2]:.25,vector:[...r],distance:0,runningLength:0}],f=!1,p=0,m=u[0],h=l.length-1;for(let e=1;e<l.length;e++){let t=o&&e===h?[l[e][0],l[e][1]]:w(m.point,l[e],s);if(_(m.point,t))continue;let r=x(t,m.point);if(p+=r,e<h&&!f){if(p<a)continue;f=!0}d(F,m.point,t),m={point:t,pressure:I(l[e][2])?l[e][2]:n,vector:b(F),distance:r,runningLength:p},u.push(m)}return u[0].vector=u[1]?.vector||[0,0],u}function R(e,t={}){return P(L(e,t),t)}var z=R;export{z as default,R as getStroke,P as getStrokeOutlinePoints,L as getStrokePoints};\n//# sourceMappingURL=index.mjs.map","import { getStroke } from 'perfect-freehand';\nimport { CARD_CORNER } from '../core/defaults';\nimport { textFontSize } from '../core/textFit';\nimport type { Item, ItemText, Point, Style } from '../core/types';\n\nexport const SVG_NS = 'http://www.w3.org/2000/svg';\nexport const fonts = {\n sans: 'Nunito Variable, Nunito, ui-rounded, system-ui, sans-serif',\n serif: 'Georgia, serif',\n mono: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n hand: 'Comic Sans MS, Chalkboard SE, cursive',\n};\nexport const DEFAULT_FONT = 'hand' satisfies keyof typeof fonts;\nexport function fontFamily(font?: ItemText['font']): string {\n return fonts[font ?? DEFAULT_FONT];\n}\nconst light: Record<string, string> = {\n ink: '#103639',\n slate: '#606062',\n coral: '#FF9302',\n amber: '#FFC68A',\n moss: '#AAF1AC',\n teal: '#05D9AB',\n sky: '#92CAFF',\n violet: '#8F93F9',\n rose: '#F89B97',\n paper: '#FFFFFF',\n};\nconst dark: Record<string, string> = {\n ...light,\n ink: '#E9F7F3',\n slate: '#B6C5C1',\n paper: '#173D40',\n};\nexport function color(value = 'ink', theme: 'light' | 'dark' = 'light'): string {\n return (theme === 'dark' ? dark : light)[value] ?? value;\n}\nfunction rgb(value: string): number[] | undefined {\n const named: Record<string, string> = {\n black: '#000000',\n white: '#ffffff',\n red: '#ff0000',\n blue: '#0000ff',\n green: '#008000',\n yellow: '#ffff00',\n transparent: '#00000000',\n };\n value = named[value.toLowerCase()] ?? value;\n if (/^#[\\da-f]{3,4}$/i.test(value))\n value = `#${[...value.slice(1)].map((channel) => channel + channel).join('')}`;\n if (/^#[\\da-f]{6}([\\da-f]{2})?$/i.test(value))\n return [1, 3, 5]\n .map((index) => parseInt(value.slice(index, index + 2), 16))\n .concat(value.length === 9 ? parseInt(value.slice(7, 9), 16) / 255 : 1);\n if (!/^rgba?\\(/i.test(value)) return undefined;\n const channels = value.match(/[\\d.]+%?/g);\n if (!channels || channels.length < 3) return undefined;\n return channels\n .slice(0, 3)\n .map((channel) => parseFloat(channel) * (channel.endsWith('%') ? 2.55 : 1))\n .concat(\n channels[3] === undefined\n ? 1\n : parseFloat(channels[3]) / (channels[3].endsWith('%') ? 100 : 1),\n );\n}\nfunction luminance(channels: number[]): number {\n return channels\n .slice(0, 3)\n .map((channel) => {\n const value = channel / 255;\n return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;\n })\n .reduce((sum, channel, index) => sum + channel * [0.2126, 0.7152, 0.0722][index], 0);\n}\n/** Preserve explicit text colors and keep labels legible on opaque shape fills. */\nexport function labelColor(item: Item, theme: 'light' | 'dark'): string {\n if (item.kind === 'text') return color(item.style?.stroke ?? 'ink', theme);\n const ink = color('ink', theme),\n style = styleFor(item, theme);\n if (['connector', 'line'].includes(item.kind) || style.fillMode !== 'solid') return ink;\n const fill = rgb(style.fill);\n if (!fill) return ink;\n const paper = rgb(color('paper', theme))!;\n const background = luminance(\n fill.slice(0, 3).map((channel, index) => channel * fill[3] + paper[index] * (1 - fill[3])),\n );\n const contrast = (value: string) => {\n const foreground = luminance(rgb(value)!);\n return (Math.max(background, foreground) + 0.05) / (Math.min(background, foreground) + 0.05);\n };\n for (const candidate of [ink, color('ink', theme === 'dark' ? 'light' : 'dark')])\n if (contrast(candidate) >= 4.5) return candidate;\n return contrast('#0F0B0A') >= contrast('#FFFFFF') ? '#0F0B0A' : '#FFFFFF';\n}\nexport function fontSize(text?: ItemText): number {\n return textFontSize(text);\n}\nexport function esc(value: unknown): string {\n return String(value ?? '').replace(\n /[&<>\"']/g,\n (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char]!,\n );\n}\nexport function round(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\nexport function pathFromPoints(points: Point[], closed = false): string {\n return (\n points\n .map((point, index) => `${index ? 'L' : 'M'}${round(point.x)},${round(point.y)}`)\n .join(' ') + (closed ? ' Z' : '')\n );\n}\nexport function freehandPath(item: Item): string {\n const points = item.points ?? [];\n if (!points.length) return '';\n if (item.closed)\n return pathFromPoints(\n points.map(([x, y]) => ({ x, y })),\n true,\n );\n const stroke = getStroke(\n points.map(([x, y, pressure]) => ({ x, y, pressure })),\n {\n size: (item.style?.strokeWidth ?? 2) * 2.2,\n thinning: 0.45,\n smoothing: 0.6,\n streamline: 0.45,\n simulatePressure: points.every((point) => point[2] === undefined),\n last: true,\n },\n );\n if (!stroke.length) return '';\n return `M${stroke.map((point) => `${round(point[0])},${round(point[1])}`).join(' L')} Z`;\n}\nexport function shapePath(item: Item): string {\n const w = item.w,\n h = item.h;\n if (item.kind === 'ellipse')\n return `M${w},${h / 2}a${w / 2},${h / 2} 0 1 0 ${-w},0a${w / 2},${h / 2} 0 1 0 ${w},0Z`;\n if (item.kind === 'diamond') return `M${w / 2},0L${w},${h / 2}L${w / 2},${h}L0,${h / 2}Z`;\n if (item.kind === 'line')\n return pathFromPoints(\n (\n item.points ?? [\n [0, 0],\n [w, h],\n ]\n ).map(([x, y]) => ({ x, y })),\n );\n if (item.kind === 'path') return freehandPath(item);\n const corner = Math.max(0, Math.min(item.style?.corner ?? CARD_CORNER, w / 2, h / 2));\n return `M${corner},0H${w - corner}Q${w},0 ${w},${corner}V${h - corner}Q${w},${h} ${w - corner},${h}H${corner}Q0,${h} 0,${h - corner}V${corner}Q0,0 ${corner},0Z`;\n}\nexport function styleFor(item: Item, theme: 'light' | 'dark'): Required<Style> {\n const fill = item.style?.fill ?? (item.kind === 'note' ? 'moss' : 'none');\n return {\n stroke: color(item.style?.stroke ?? 'ink', theme),\n strokeWidth: item.style?.strokeWidth ?? (item.kind === 'note' ? 0 : 2),\n dash: item.style?.dash ?? 'solid',\n fill: color(fill, theme),\n fillMode: item.style?.fillMode ?? 'solid',\n corner: item.style?.corner ?? CARD_CORNER,\n opacity: item.style?.opacity ?? 1,\n };\n}\nexport function shapeMarkup(\n item: Item,\n theme: 'light' | 'dark',\n uid: string,\n path = shapePath(item),\n): string {\n const style = styleFor(item, theme);\n const dash = style.dash === 'dashed' ? '8 6' : style.dash === 'dotted' ? '1 6' : '';\n const isPath = item.kind === 'path';\n const fill =\n item.kind === 'line' || item.kind === 'connector'\n ? 'none'\n : isPath\n ? item.closed && style.fill !== 'none'\n ? style.fill\n : style.stroke\n : style.fill;\n const hatchId = `ad_h_${uid.replace(/[^a-z0-9_-]/gi, '_')}`;\n const hatch = style.fillMode === 'hatch' && fill !== 'none' && !isPath;\n const defs = hatch\n ? `<defs><pattern id=\"${hatchId}\" width=\"8\" height=\"8\" patternUnits=\"userSpaceOnUse\"><path d=\"M-2 2L2-2M0 8L8 0M6 10L10 6\" fill=\"none\" stroke=\"${esc(fill)}\" stroke-opacity=\"0.5\" stroke-width=\"1.3\"/></pattern></defs>`\n : '';\n const fillAttr = hatch ? `url(#${hatchId})` : fill;\n const geometry = `<path d=\"${esc(path)}\" fill=\"${esc(fillAttr)}\"${style.fillMode === 'tint' && !isPath ? ' fill-opacity=\"0.22\"' : ''} stroke=\"${isPath && !item.closed ? 'none' : esc(style.stroke)}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"${dash ? ` stroke-dasharray=\"${dash}\"` : ''}/>`;\n return `${defs}${geometry}`;\n}\nexport function headMarkup(\n point: Point,\n previous: Point,\n kind: 'arrow' | 'dot' | 'none' | undefined,\n stroke: string,\n width: number,\n): string {\n if (!kind || kind === 'none') return '';\n if (kind === 'dot')\n return `<circle cx=\"${round(point.x)}\" cy=\"${round(point.y)}\" r=\"${Math.max(3, width * 2)}\" fill=\"${esc(stroke)}\"/>`;\n const angle = Math.atan2(point.y - previous.y, point.x - previous.x);\n const length = Math.max(10, width * 4.5);\n const spread = Math.PI / 6;\n const a = {\n x: point.x - Math.cos(angle - spread) * length,\n y: point.y - Math.sin(angle - spread) * length,\n };\n const b = {\n x: point.x - Math.cos(angle + spread) * length,\n y: point.y - Math.sin(angle + spread) * length,\n };\n return `<path d=\"${pathFromPoints([a, point, b])}\" fill=\"none\" stroke=\"${esc(stroke)}\" stroke-width=\"${width}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`;\n}\nexport function headsMarkup(points: Point[], item: Item, theme: 'light' | 'dark'): string {\n if (points.length < 2) return '';\n const style = styleFor(item, theme);\n return (\n headMarkup(points[0], points[1], item.heads?.start, style.stroke, style.strokeWidth) +\n headMarkup(\n points[points.length - 1],\n points[points.length - 2],\n item.heads?.end ?? (item.kind === 'connector' ? 'arrow' : 'none'),\n style.stroke,\n style.strokeWidth,\n )\n );\n}\n","import type { AnnieDoc } from '../core/types';\nexport const ANNIE_MIME = 'application/vnd.anniedrawing+json';\nexport function exportJSON(doc: AnnieDoc): string {\n return JSON.stringify(doc, null, 2);\n}\n","const paths: Record<string, string> = {\n select:\n '<path d=\"M5.8 3.8c-1-.4-1.7.4-1.4 1.4l4.9 14.4c.4 1.1 1.8 1.1 2.2 0l2.2-5.8 5.8-2.2c1.1-.4 1.1-1.8 0-2.2Z\"/>',\n hand: '<path d=\"M8 12V6a2 2 0 0 1 4 0v5-7a2 2 0 0 1 4 0v8-5a2 2 0 0 1 4 0v8c0 5-4 7-7 7-3 0-4-2-6-5l-3-4c-1-2 1-4 3-2l2 2\"/>',\n rect: '<rect x=\"3.75\" y=\"4.75\" width=\"16.5\" height=\"14.5\" rx=\"4\"/>',\n ellipse: '<ellipse cx=\"12\" cy=\"12\" rx=\"8.25\" ry=\"7.25\"/>',\n diamond:\n '<path d=\"m13.4 3.8 6.8 6.8a2 2 0 0 1 0 2.8l-6.8 6.8a2 2 0 0 1-2.8 0l-6.8-6.8a2 2 0 0 1 0-2.8l6.8-6.8a2 2 0 0 1 2.8 0Z\"/>',\n line: '<path d=\"m5.5 18.5 13-13\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"5\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/>',\n connector: '<path d=\"M4 18h5a3 3 0 0 0 3-3V9a3 3 0 0 1 3-3h5m-4-4 4 4-4 4\"/>',\n path: '<path d=\"M3.5 17.5c1.8-5 3.2-11 6-11 4 0-1 12 3 12 2.8 0 3.2-8 5.5-8 1.6 0 2.3 2 2.5 4\"/>',\n text: '<path d=\"M5 7V4.5h14V7M12 4.5v15M8.5 19.5h7\"/>',\n note: '<path d=\"M7 3.75h10a3.25 3.25 0 0 1 3.25 3.25v7.1a2 2 0 0 1-.6 1.4l-4.2 4.2a2 2 0 0 1-1.4.6H7A3.25 3.25 0 0 1 3.75 17V7A3.25 3.25 0 0 1 7 3.75Z\"/><path d=\"M20 14h-3.5a2.5 2.5 0 0 0-2.5 2.5V20\"/>',\n lock: '<rect x=\"5\" y=\"10\" width=\"14\" height=\"11\" rx=\"3.5\"/><path d=\"M8 10V7a4 4 0 0 1 8 0v3M12 14v3\"/>',\n unlock:\n '<rect x=\"5\" y=\"10\" width=\"14\" height=\"11\" rx=\"3.5\"/><path d=\"M8 10V7a4 4 0 0 1 7.5-2M12 14v3\"/>',\n opacity:\n '<circle cx=\"12\" cy=\"12\" r=\"8.5\"/><path d=\"M12 3.5a8.5 8.5 0 0 1 0 17Z\" fill=\"currentColor\" stroke=\"none\"/>',\n front:\n '<rect x=\"8\" y=\"3.5\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M15.5 16v1A3.5 3.5 0 0 1 12 20.5H7A3.5 3.5 0 0 1 3.5 17v-5A3.5 3.5 0 0 1 7 8.5h1\"/>',\n back: '<rect x=\"3.5\" y=\"8\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M8.5 8V7A3.5 3.5 0 0 1 12 3.5h5A3.5 3.5 0 0 1 20.5 7v5A3.5 3.5 0 0 1 17 15.5h-1\"/>',\n eraser:\n '<path d=\"m13.2 4.3-9 9a2.4 2.4 0 0 0 0 3.4L7.5 20h4l8.2-8.2a2.4 2.4 0 0 0 0-3.4l-4.1-4.1a1.7 1.7 0 0 0-2.4 0ZM8 10.5l6 6M11.5 20H21\"/>',\n undo: '<path d=\"m8 5-4.5 4.5L8 14M4 9.5h9.5a5.5 5.5 0 0 1 0 11H11\"/>',\n redo: '<path d=\"m16 5 4.5 4.5L16 14m4-4.5h-9.5a5.5 5.5 0 0 0 0 11H13\"/>',\n plus: '<path d=\"M12 5.5v13M5.5 12h13\"/>',\n minus: '<path d=\"M5.5 12h13\"/>',\n fit: '<path d=\"M8.5 3.75h-3a1.75 1.75 0 0 0-1.75 1.75v3m11.75-4.75h3a1.75 1.75 0 0 1 1.75 1.75v3M3.75 15.5v3a1.75 1.75 0 0 0 1.75 1.75h3m11.75-4.75v3a1.75 1.75 0 0 1-1.75 1.75h-3\"/>',\n chevron: '<path d=\"m7 9.5 3.6 3.6a2 2 0 0 0 2.8 0L17 9.5\"/>',\n download: '<path d=\"M12 3.5v11m-4-4 4 4 4-4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2\"/>',\n upload: '<path d=\"M12 15V4m-4 4 4-4 4 4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2\"/>',\n code: '<path d=\"m7 7-4 4a1.4 1.4 0 0 0 0 2l4 4m10-10 4 4a1.4 1.4 0 0 1 0 2l-4 4M14 4l-4 16\"/>',\n close: '<path d=\"m6.5 6.5 11 11m-11 0 11-11\"/>',\n more: '<circle cx=\"5\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/>',\n image:\n '<rect x=\"3.5\" y=\"3.5\" width=\"17\" height=\"17\" rx=\"4\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"m4 17 3.6-3.6a1.3 1.3 0 0 1 1.8 0l2.1 2.1 3.4-5.1a1.3 1.3 0 0 1 2.2 0L20 15\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2.5v1M12 20.5v1M2.5 12h1m17 0h1M5.3 5.3l.7.7m12 12 .7.7M5.3 18.7l.7-.7M18 6l.7-.7\"/>',\n moon: '<path d=\"M20 14.5a8.2 8.2 0 0 1-10.5-10c-3.9.7-6.4 3.7-6.4 7.5a8.1 8.1 0 0 0 16.9 2.5Z\"/>',\n trash:\n '<path d=\"M4 6.5h16M9 6.5V5a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 5v1.5m-9 0 .7 11.2A3 3 0 0 0 9.7 20.5h4.6a3 3 0 0 0 3-2.8L18 6.5M10 10.5v6m4-6v6\"/>',\n copy: '<rect x=\"8\" y=\"8\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M15.5 8V7A3.5 3.5 0 0 0 12 3.5H7A3.5 3.5 0 0 0 3.5 7v5A3.5 3.5 0 0 0 7 15.5h1\"/>',\n grid: '<rect x=\"3.5\" y=\"3.5\" width=\"17\" height=\"17\" rx=\"4\"/><path d=\"M9 4v16m6-16v16M4 9h16M4 15h16\"/>',\n book: '<path d=\"M12 5.5c-2.6-2-5.2-2.5-8-2v15c2.8-.5 5.4 0 8 2 2.6-2 5.2-2.5 8-2v-15c-2.8-.5-5.4 0-8 2Zm0 0v15\"/>',\n github:\n '<path fill=\"currentColor\" stroke=\"none\" d=\"M12 1C5.922 1 1 5.922 1 12c0 4.867 3.149 8.979 7.521 10.437.55.096.75-.232.75-.546 0-.262-.013-1.13-.013-2.049-3.06.56-3.703-1.31-3.703-1.31-.498-1.316-1.216-1.667-1.216-1.667-.991-.68.075-.668.075-.668 1.109.075 1.688 1.264 1.688 1.264.982 1.686 2.573 1.2 3.201.907.096-.699.381-1.2.695-1.478-2.448-.282-5.022-1.226-5.022-5.451 0-1.2.426-2.187 1.12-2.953-.113-.275-.487-1.392.107-2.9 0 0 .917-.292 3.011 1.12.873-.24 1.809-.36 2.74-.36.93 0 1.867.12 2.74.36 2.077-1.413 3.01-1.12 3.01-1.12.596 1.508.221 2.625.108 2.9.697.766 1.12 1.748 1.12 2.953 0 4.237-2.578 5.163-5.034 5.437.39.338.746 1.016.746 2.056 0 1.478-.014 2.666-.014 3.025 0 .304.202.655.753.545C19.854 20.979 23 16.859 23 12c0-6.078-4.922-11-11-11Z\"/>',\n alignLeft: '<path d=\"M4 5h16M4 12h10M4 19h16\"/>',\n alignCenter: '<path d=\"M4 5h16M7 12h10M4 19h16\"/>',\n alignRight: '<path d=\"M4 5h16M10 12h10M4 19h16\"/>',\n align:\n '<path d=\"M4 3.5v17\"/><rect x=\"8\" y=\"5\" width=\"12.5\" height=\"5\" rx=\"1.75\"/><rect x=\"8\" y=\"14\" width=\"8.5\" height=\"5\" rx=\"1.75\"/>',\n shapes:\n '<rect x=\"3\" y=\"3\" width=\"8.5\" height=\"8.5\" rx=\"2.5\"/><circle cx=\"17.3\" cy=\"6.7\" r=\"3.7\"/><path d=\"m6 14-3.5 6h8L7 14a.6.6 0 0 0-1 0Z\"/><rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"2\" transform=\"rotate(45 17 17)\"/>',\n link: '<path d=\"M10 14.5 8.8 15.7a3.6 3.6 0 1 1-5.1-5.1l3.2-3.2a3.6 3.6 0 0 1 5.1 0\"/><path d=\"m14 9.5 1.2-1.2a3.6 3.6 0 0 1 5.1 5.1l-3.2 3.2a3.6 3.6 0 0 1-5.1 0\"/>',\n};\nexport function icon(name: string) {\n return `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths[name] ?? paths.select}</svg>`;\n}\nexport function button(\n label: string,\n name: string,\n handler: () => void,\n className = 'ad-icon-button',\n) {\n const el = document.createElement('button');\n el.type = 'button';\n el.className = className;\n el.title = label;\n el.setAttribute('aria-label', label);\n el.innerHTML = icon(name);\n el.addEventListener('click', () => {\n el.focus();\n handler();\n });\n return el;\n}\n","/** npm package version shown in the AnnieDrawing menu. Keep in sync with package.json. */\nexport const PACKAGE_VERSION = '0.4.0';\nexport const SITE_URL = 'https://anniedrawing.com';\nexport const GITHUB_REPO_URL = 'https://github.com/Frontierz-AI/AnnieDrawing';\n","import type { Board } from '../board';\nimport type { Item, Point } from '../core/types';\nimport { button, icon } from './icons';\nimport { GITHUB_REPO_URL, PACKAGE_VERSION } from './version';\nimport { color as resolveColor, DEFAULT_FONT, fonts, fontSize, styleFor } from '../stage/paint';\nimport { pageId } from '../core/ids';\nimport { ANNIE_MIME } from '../porter/json';\n/** PNG, SVG, or AnnieDoc (`json`, saved as `.annie`). */\nexport type UiExportFormat = 'png' | 'svg' | 'json';\n/** Header controls. Pass `ui: false` to `createBoard` to omit all editor chrome. */\nexport interface UiOptions {\n /** AnnieDrawing control. Default `true`. */\n menu?: boolean;\n /**\n * Export control. Default `['png', 'svg']`. `false` hides it. Include `'json'` for AnnieDoc.\n * One format downloads on click; two or more open a menu.\n */\n export?: boolean | UiExportFormat[];\n /** Page chips, add-page, and All pages. Default true. */\n pages?: boolean;\n}\nconst defaultExportFormats: UiExportFormat[] = ['png', 'svg'];\nfunction exportFormats(value: UiOptions['export']): UiExportFormat[] {\n if (value === false) return [];\n if (!Array.isArray(value)) return [...defaultExportFormats];\n const seen = new Set<UiExportFormat>();\n const formats: UiExportFormat[] = [];\n for (const format of value) {\n if (format !== 'png' && format !== 'svg' && format !== 'json') continue;\n if (seen.has(format)) continue;\n seen.add(format);\n formats.push(format);\n }\n return formats;\n}\nconst tools = [\n ['select', 'Select', 'V'],\n ['hand', 'Hand', 'H'],\n ['rect', 'Rectangle', 'R'],\n ['ellipse', 'Ellipse', 'O'],\n ['diamond', 'Diamond', 'D'],\n ['connector', 'Arrow', 'A'],\n ['line', 'Line', 'L'],\n ['path', 'Draw', 'P'],\n ['text', 'Text', 'T'],\n ['note', 'Sticky note', 'N'],\n ['eraser', 'Eraser', 'E'],\n];\nconst palette = [\n ['ink', 'Ink'],\n ['paper', 'Paper'],\n ['teal', 'Frontierz green'],\n ['moss', 'Soft green'],\n ['coral', 'Orange'],\n ['violet', 'Lavender'],\n ['slate', 'Slate'],\n ['amber', 'Peach'],\n ['sky', 'Sky blue'],\n ['rose', 'Rose'],\n ['none', 'No fill'],\n];\n/** Narrow hosts, or a short tablet / phone-landscape host. */\nfunction phoneChrome(width: number, height: number) {\n return width <= 700 || (width <= 1023 && height <= 640);\n}\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, className = '', text?: string) {\n const node = document.createElement(tag);\n node.className = className;\n if (text) node.textContent = text;\n return node;\n}\nfunction textButton(label: string, action: () => void, kind = 'ad-button') {\n const b = el('button', kind, label);\n b.type = 'button';\n b.addEventListener('click', () => {\n b.focus();\n action();\n });\n return b;\n}\nfunction field(label: string, input: HTMLElement) {\n const wrapper = el('label', 'ad-field');\n wrapper.append(el('span', 'ad-field-label', label), input);\n return wrapper;\n}\nfunction select(values: [string, string][], value: string, change: (value: string) => void) {\n const input = el('select');\n values.forEach(([v, text]) => {\n const o = el('option', '', text);\n o.value = v;\n input.append(o);\n });\n if (!values.some(([v]) => v === value)) {\n const custom = el('option', '', value);\n custom.value = value;\n input.append(custom);\n }\n input.value = value;\n input.onchange = () => change(input.value);\n return input;\n}\nfunction download(content: string | Blob, name: string, type: string) {\n const url = URL.createObjectURL(\n typeof content === 'string' ? new Blob([content], { type }) : content,\n );\n const link = el('a');\n link.href = url;\n link.download = name;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\nexport function mountUI(board: Board, options: UiOptions = {}): () => void {\n const ui = el('div', 'ad-ui');\n const showMenu = options.menu !== false;\n const showPages = options.pages !== false;\n if (showMenu) ui.classList.add('ad-ui-menu');\n if (showPages) ui.classList.add('ad-ui-pages');\n if (showMenu || showPages) ui.classList.add('ad-ui-bars');\n board.stage.root.append(ui);\n const unsubs: (() => void)[] = [];\n let activeDialog: HTMLDialogElement | undefined;\n function dialog(title: string) {\n closePopover();\n activeDialog?.close();\n const previous = document.activeElement as HTMLElement;\n const d = el('dialog', 'ad-dialog');\n const head = el('div', 'ad-dialog-head');\n const copy = el('div');\n copy.append(el('h2', '', title));\n head.append(\n copy,\n button('Close', 'close', () => d.close()),\n );\n d.append(head);\n d.addEventListener('click', (e) => {\n if (e.target === d) {\n const r = d.getBoundingClientRect();\n if (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom)\n d.close();\n }\n });\n d.addEventListener('close', () => {\n d.remove();\n if (activeDialog === d) activeDialog = undefined;\n if (!activeDialog) {\n refresh();\n if (previous?.isConnected) previous.focus();\n else board.focus();\n }\n });\n ui.append(d);\n activeDialog = d;\n d.showModal();\n return d;\n }\n let activePopover: HTMLElement | undefined;\n let popoverTrigger: HTMLButtonElement | undefined;\n let pagePressTimer: ReturnType<typeof setTimeout> | undefined;\n function closePopover() {\n activePopover?.hidePopover();\n activePopover?.remove();\n activePopover = undefined;\n popoverTrigger?.setAttribute('aria-expanded', 'false');\n if (popoverTrigger) popoverTrigger.popoverTargetElement = null;\n popoverTrigger = undefined;\n }\n function popover(trigger: HTMLButtonElement | undefined, label: string) {\n if (trigger && popoverTrigger === trigger && activePopover?.matches(':popover-open')) {\n closePopover();\n return;\n }\n closePopover();\n const panel = el('div', 'ad-popover');\n panel.popover = 'auto';\n panel.setAttribute('role', 'group');\n panel.setAttribute('aria-label', label);\n const previous = document.activeElement as HTMLElement;\n if (trigger) {\n trigger.setAttribute('aria-expanded', 'true');\n trigger.popoverTargetElement = panel;\n trigger.popoverTargetAction = 'show';\n }\n activePopover = panel;\n popoverTrigger = trigger;\n panel.addEventListener('toggle', () => {\n if (activePopover === panel && !panel.matches(':popover-open'))\n trigger?.setAttribute('aria-expanded', 'false');\n });\n panel.addEventListener('keydown', (event) => {\n event.stopPropagation();\n if (event.key === 'Escape' || (event.key === 'Tab' && panel.popover === 'manual')) {\n if (event.key === 'Escape') event.preventDefault();\n closePopover();\n if (previous?.isConnected) previous.focus();\n else board.focus();\n } else if (\n !(event.target instanceof HTMLInputElement) &&\n ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)\n ) {\n const items = popoverItems(panel);\n const current = items.indexOf(document.activeElement as HTMLElement);\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? items.length - 1\n : (current +\n (event.key === 'ArrowDown' || event.key === 'ArrowRight' ? 1 : -1) +\n items.length) %\n items.length;\n event.preventDefault();\n items[next]?.focus();\n }\n });\n ui.append(panel);\n return panel;\n }\n function showPopover(\n panel: HTMLElement,\n trigger: HTMLButtonElement,\n alignTo: HTMLElement = trigger,\n ) {\n panel.showPopover();\n const anchor = alignTo.getBoundingClientRect(),\n bounds = board.stage.root.getBoundingClientRect();\n const mobile = phoneChrome(bounds.width, bounds.height),\n width = Math.min(228, bounds.width - 24);\n panel.style.width = `${width}px`;\n const height = panel.getBoundingClientRect().height;\n const besideToolbar = trigger.closest('.ad-toolbar') && !mobile;\n const left = besideToolbar\n ? anchor.right + 12\n : trigger.closest('.ad-header') && anchor.left < bounds.left + bounds.width / 2\n ? anchor.left\n : anchor.right - width;\n const top = besideToolbar\n ? anchor.top\n : anchor.top > bounds.top + bounds.height / 2\n ? anchor.top - height - 10\n : anchor.bottom + 10;\n panel.style.left = `${Math.max(bounds.left + 12, Math.min(left, bounds.right - width - 12))}px`;\n panel.style.top = `${Math.max(bounds.top + 12, Math.min(top, bounds.bottom - height - 12))}px`;\n popoverItems(panel)[0]?.focus();\n }\n function popoverItems(panel: HTMLElement) {\n return [...panel.querySelectorAll<HTMLElement>('button:not(:disabled), a[href]')];\n }\n function contextMenu(label: string, point: Point) {\n const panel = popover(undefined, label)!;\n // A native auto popover dismisses on the right-button release that opened it.\n panel.popover = 'manual';\n panel.classList.add('ad-context-menu');\n panel.setAttribute('role', 'menu');\n panel.tabIndex = -1;\n const add = (label: string, glyph: string, action: () => void, disabled = false) => {\n const option = textButton(\n label,\n () => {\n closePopover();\n board.focus();\n action();\n },\n 'ad-tool-option',\n );\n option.insertAdjacentHTML('afterbegin', icon(glyph));\n option.setAttribute('role', 'menuitem');\n option.disabled = board.readonly || disabled;\n if (glyph === 'trash') option.classList.add('ad-danger');\n panel.append(option);\n };\n const show = () => {\n panel.showPopover();\n const bounds = board.stage.root.getBoundingClientRect();\n const width = Math.min(228, bounds.width - 24);\n panel.style.width = `${width}px`;\n const height = panel.getBoundingClientRect().height;\n panel.style.left = `${Math.max(bounds.left + 12, Math.min(point.x, bounds.right - width - 12))}px`;\n panel.style.top = `${Math.max(bounds.top + 12, Math.min(point.y, bounds.bottom - height - 12))}px`;\n (panel.querySelector<HTMLButtonElement>('button:not(:disabled)') ?? panel).focus();\n };\n return { panel, add, show };\n }\n const hideOnResize = () => closePopover();\n const dismissContext = (event: PointerEvent) => {\n if (activePopover?.popover === 'manual' && !activePopover.contains(event.target as Node))\n closePopover();\n };\n window.addEventListener('resize', hideOnResize);\n window.addEventListener('pointerdown', dismissContext, true);\n unsubs.push(() => {\n window.removeEventListener('resize', hideOnResize);\n window.removeEventListener('pointerdown', dismissContext, true);\n });\n const formats = exportFormats(options.export);\n const exportChoices: Record<UiExportFormat, [string, string]> = {\n png: ['PNG Image', 'image'],\n svg: ['SVG Image', 'image'],\n json: ['AnnieDoc format', 'code'],\n };\n const header = el('header', 'ad-header');\n let brand: HTMLButtonElement | undefined;\n let drawingInput: HTMLInputElement | undefined;\n let exportButton: HTMLButtonElement | undefined;\n let chromeButton: HTMLButtonElement;\n if (showMenu) {\n brand = button('Board menu', 'chevron', openMenu, 'ad-brand');\n brand.innerHTML =\n '<span class=\"ad-brand-mark\" aria-hidden=\"true\"><svg viewBox=\"0 0 40 40\"><path d=\"M9 29 20 8l11 21M14 22h12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"32\" cy=\"9\" r=\"2.5\" fill=\"currentColor\"/></svg></span><span class=\"ad-brand-name\">AnnieDrawing</span>' +\n icon('chevron');\n brand.setAttribute('aria-haspopup', 'true');\n brand.setAttribute('aria-expanded', 'false');\n drawingInput = el('input');\n drawingInput.type = 'file';\n drawingInput.accept = '.annie,.json,application/json';\n drawingInput.hidden = true;\n drawingInput.onchange = () => {\n const file = drawingInput?.files?.[0];\n if (drawingInput) drawingInput.value = '';\n if (file)\n void file\n .text()\n .then((value) => board.load(JSON.parse(value)))\n .catch(() => undefined);\n };\n header.append(brand);\n }\n const actions = el('div', 'ad-header-actions');\n if (formats.length) {\n exportButton = textButton('Export', openExport, 'ad-button ad-primary ad-header-export');\n exportButton.insertAdjacentHTML('afterbegin', icon('download'));\n if (formats.length > 1) {\n exportButton.setAttribute('aria-haspopup', 'true');\n exportButton.setAttribute('aria-expanded', 'false');\n }\n actions.append(exportButton);\n }\n chromeButton = button('Board controls', 'more', openChrome);\n chromeButton.classList.add('ad-chrome');\n chromeButton.setAttribute('aria-haspopup', 'true');\n chromeButton.setAttribute('aria-expanded', 'false');\n actions.append(chromeButton);\n header.append(actions);\n if (!showMenu) header.classList.add('ad-header-end');\n ui.append(header);\n if (drawingInput) ui.append(drawingInput);\n const toolbar = el('nav', 'ad-toolbar');\n toolbar.setAttribute('aria-label', 'Drawing tools');\n function toolButton(id: string, expanded = false) {\n const [, label, key] = tools.find((tool) => tool[0] === id)!;\n const b = button(\n label,\n id,\n () => {\n closePopover();\n board.setTool(id);\n board.focus();\n },\n expanded ? 'ad-tool-option' : 'ad-icon-button',\n );\n b.dataset.tool = id;\n b.setAttribute('aria-keyshortcuts', key);\n b.setAttribute('aria-pressed', String(board.tool === id));\n b.innerHTML += expanded ? `<span>${label}</span>` : `<span class=\"ad-tooltip\">${label}</span>`;\n if (board.readonly && id !== 'hand' && id !== 'select') b.disabled = true;\n return b;\n }\n const shapeKinds = ['rect', 'ellipse', 'diamond', 'line', 'connector'];\n const shapeButton = button('Shapes', 'shapes', () => {\n const panel = popover(shapeButton, 'Shapes');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n panel.append(...shapeKinds.map((id) => toolButton(id, true)));\n showPopover(panel, shapeButton);\n });\n shapeButton.setAttribute('aria-haspopup', 'true');\n shapeButton.setAttribute('aria-expanded', 'false');\n shapeButton.innerHTML +=\n '<span class=\"ad-tool-corner\"></span><span class=\"ad-tooltip\">Shapes</span>';\n const imageInput = el('input');\n imageInput.type = 'file';\n imageInput.accept = 'image/png,image/jpeg,image/webp,image/gif,image/avif';\n imageInput.hidden = true;\n imageInput.onchange = () => {\n if (imageInput.files?.[0]) void board.addImage(imageInput.files[0]).catch(() => undefined);\n imageInput.value = '';\n };\n const imageButton = button('Add image', 'image', () => {\n closePopover();\n imageInput.click();\n });\n imageButton.innerHTML += '<span class=\"ad-tooltip\">Add image</span>';\n imageButton.disabled = board.readonly;\n const hand = toolButton('hand');\n if (showMenu) hand.classList.add('ad-desktop-tool');\n toolbar.append(\n toolButton('select'),\n hand,\n toolButton('eraser'),\n el('div', 'ad-toolbar-divider'),\n shapeButton,\n toolButton('path'),\n toolButton('text'),\n toolButton('note'),\n imageButton,\n imageInput,\n );\n ui.append(toolbar);\n const styleDock = el('aside', 'ad-style-dock');\n styleDock.setAttribute('aria-label', 'Selection style');\n styleDock.hidden = true;\n const stylePanel = el('div', 'ad-style-panel');\n const deselect = button('Deselect', 'chevron', () => board.select([]));\n deselect.classList.add('ad-style-dismiss');\n styleDock.append(deselect, stylePanel);\n ui.append(styleDock);\n const footer = el('footer', 'ad-footer');\n const undo = button('Undo', 'undo', () => board.undo()),\n redo = button('Redo', 'redo', () => board.redo());\n undo.setAttribute('aria-keyshortcuts', 'Meta+Z Control+Z');\n redo.setAttribute('aria-keyshortcuts', 'Meta+Shift+Z Control+Shift+Z');\n const pagesBar = el('nav', 'ad-pages');\n pagesBar.setAttribute('aria-label', 'Pages');\n const pageTabs = el('div', 'ad-page-tabs');\n pageTabs.setAttribute('role', 'tablist');\n pageTabs.setAttribute('aria-label', 'Pages');\n const overflow = button('All pages', 'more', openPages);\n overflow.setAttribute('aria-haspopup', 'true');\n overflow.setAttribute('aria-expanded', 'false');\n overflow.hidden = true;\n const newPage = button('Add page', 'plus', addPage);\n newPage.disabled = board.readonly;\n pagesBar.append(pageTabs, overflow, newPage);\n let pageState = '';\n function pageContext(id: string, name: string, point: Point) {\n const menu = contextMenu('Page actions', point);\n menu.add('Rename page', 'text', () => renamePage(id, name));\n menu.add(\n 'Delete page',\n 'trash',\n () => {\n board.apply([{ op: 'page.remove', id }], { origin: 'user', label: 'Delete page' });\n },\n board.read().pages.length === 1,\n );\n menu.show();\n }\n function pageButton(id: string, name: string, tab = false) {\n const pick = textButton(\n name,\n () => {\n closePopover();\n board.setPage(id);\n pageTabs.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]')?.focus();\n },\n tab ? 'ad-page-tab' : 'ad-tool-option',\n );\n pick.title = name;\n pick.dataset.pageId = id;\n let held = false;\n let start: Point;\n pick.addEventListener('pointerdown', (event) => {\n held = false;\n if (event.pointerType !== 'touch') return;\n start = { x: event.clientX, y: event.clientY };\n clearTimeout(pagePressTimer);\n pagePressTimer = setTimeout(() => {\n held = true;\n pageContext(id, name, start);\n }, 500);\n });\n pick.addEventListener('pointermove', (event) => {\n if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > 10)\n clearTimeout(pagePressTimer);\n });\n for (const type of ['pointerup', 'pointercancel'])\n pick.addEventListener(type, () => clearTimeout(pagePressTimer));\n pick.addEventListener(\n 'click',\n (event) => {\n if (held) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n },\n true,\n );\n if (tab) {\n pick.setAttribute('role', 'tab');\n pick.setAttribute('aria-selected', String(board.pageId === id));\n pick.tabIndex = board.pageId === id ? 0 : -1;\n } else pick.setAttribute('aria-current', String(board.pageId === id));\n pick.addEventListener('contextmenu', (event) => {\n event.preventDefault();\n pageContext(id, name, { x: event.clientX, y: event.clientY });\n });\n pick.addEventListener('keydown', (event) => {\n if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) {\n event.preventDefault();\n const bounds = pick.getBoundingClientRect();\n pageContext(id, name, { x: bounds.left, y: bounds.top });\n } else if (tab && ['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n const pages = board.read().pages;\n const index = pages.findIndex((page) => page.id === id);\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? pages.length - 1\n : (index + (event.key === 'ArrowRight' ? 1 : -1) + pages.length) % pages.length;\n closePopover();\n board.setPage(pages[next].id);\n pageTabs.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]')?.focus();\n }\n });\n return pick;\n }\n let fittingPages = false;\n function fitPageTabs() {\n if (fittingPages) return;\n fittingPages = true;\n const probe = el('div', 'ad-page-tabs');\n try {\n const tabs = [...pageTabs.querySelectorAll<HTMLButtonElement>('button')];\n probe.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;width:max-content';\n const samples = tabs.map((tab) => {\n const sample = tab.cloneNode(true) as HTMLButtonElement;\n sample.hidden = false;\n sample.style.maxWidth = '';\n return sample;\n });\n const overflowSample = overflow.cloneNode(true) as HTMLButtonElement;\n overflowSample.hidden = false;\n probe.append(...samples, overflowSample);\n ui.append(probe);\n const widths = samples.map((sample) => sample.getBoundingClientRect().width);\n const overflowWidth = overflowSample.offsetWidth;\n probe.remove();\n const needed = widths.reduce((sum, width) => sum + width + 4, 0) + newPage.offsetWidth + 14;\n const room =\n pagesBar.offsetTop === footerRight.offsetTop\n ? footer.clientWidth - footerRight.offsetWidth - 16\n : pagesBar.clientWidth;\n const cap = Math.min(room, 520);\n const hideOverflow = needed <= cap;\n const nextHidden = tabs.map(() => false);\n const nextMax = tabs.map(() => '');\n if (!hideOverflow) {\n let remaining = Math.max(40, cap - newPage.offsetWidth - 14 - overflowWidth - 4);\n const selected = tabs.findIndex((tab) => tab.getAttribute('aria-selected') === 'true');\n for (const index of [\n selected,\n ...tabs.map((_, index) => index).filter((index) => index !== selected),\n ]) {\n if (index < 0) continue;\n if (index === selected) {\n nextMax[index] = `${remaining}px`;\n remaining -= Math.min(remaining, widths[index]) + 4;\n } else {\n nextHidden[index] = widths[index] > remaining;\n if (!nextHidden[index]) remaining -= widths[index] + 4;\n }\n }\n }\n overflow.hidden = hideOverflow;\n tabs.forEach((tab, index) => {\n tab.hidden = nextHidden[index];\n tab.style.maxWidth = nextMax[index];\n });\n } finally {\n probe.remove();\n fittingPages = false;\n }\n }\n function renderPages() {\n if (!showPages) return;\n const pages = board.read().pages;\n const state = JSON.stringify([board.pageId, pages.map(({ id, name }) => [id, name])]);\n if (state === pageState) return;\n pageState = state;\n pageTabs.replaceChildren(...pages.map((page) => pageButton(page.id, page.name, true)));\n fitPageTabs();\n }\n const pagesObserver = new ResizeObserver(fitPageTabs);\n if (showPages) {\n pagesObserver.observe(ui);\n unsubs.push(() => pagesObserver.disconnect());\n }\n function addPage() {\n closePopover();\n const id = pageId();\n const pages = board.read().pages;\n let number = pages.length + 1;\n while (pages.some((page) => page.name === `Page ${number}`)) number++;\n const result = board.apply(\n [{ op: 'page.add', page: { id, name: `Page ${number}`, items: [] } }],\n { origin: 'user', label: 'Add page' },\n );\n if (result.ok) board.setPage(id);\n }\n function openPages() {\n const panel = popover(overflow, 'All pages');\n if (!panel) return;\n panel.classList.add('ad-pages-popover');\n for (const page of board.read().pages) {\n const row = el('div', 'ad-page-row');\n row.append(pageButton(page.id, page.name));\n const actions = button(`Actions for ${page.name}`, 'more', () => {\n const bounds = actions.getBoundingClientRect();\n pageContext(page.id, page.name, { x: bounds.left, y: bounds.top });\n });\n row.append(actions);\n panel.append(row);\n }\n showPopover(panel, overflow);\n panel.querySelector<HTMLElement>('[aria-current=\"true\"]')?.scrollIntoView({ block: 'nearest' });\n }\n const footerRight = el('div', 'ad-footer-right');\n const zoom = el('div', 'ad-zoom');\n const percentage = textButton(\n '100%',\n () => {\n const panel = popover(percentage, 'Zoom controls');\n if (!panel) return;\n const row = el('div', 'ad-zoom-controls');\n row.append(\n button('Zoom out', 'minus', () => (board.view.zoom /= 1.2)),\n textButton('100%', () => (board.view.zoom = 1), 'ad-zoom-value'),\n button('Zoom in', 'plus', () => (board.view.zoom *= 1.2)),\n );\n panel.append(row);\n showPopover(panel, percentage, fitButton);\n },\n 'ad-zoom-value',\n );\n percentage.setAttribute('aria-label', 'Zoom controls');\n percentage.setAttribute('aria-haspopup', 'true');\n percentage.setAttribute('aria-expanded', 'false');\n const fitButton = button('Fit drawing', 'fit', () => board.view.fit());\n zoom.append(percentage, fitButton, undo, redo);\n footerRight.append(zoom);\n if (showPages) footer.append(pagesBar, footerRight);\n else footer.append(footerRight);\n ui.append(footer);\n function renamePage(id: string, name: string) {\n if (board.readonly) return;\n const d = dialog('Name this page');\n const input = el('input');\n input.value = name;\n input.maxLength = 100;\n d.append(\n field('Page name', input),\n textButton(\n 'Save name',\n () => {\n if (input.value.trim())\n board.apply([{ op: 'page.set', id, patch: { name: input.value.trim() } }], {\n origin: 'user',\n label: 'Rename page',\n });\n d.close();\n },\n 'ad-button ad-primary',\n ),\n );\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') d.querySelector<HTMLButtonElement>('.ad-primary')?.click();\n });\n d.addEventListener(\n 'close',\n () => {\n const tab = pageTabs.querySelector<HTMLButtonElement>(`[data-page-id=\"${CSS.escape(id)}\"]`);\n if (tab && !tab.hidden) tab.focus();\n else if (!overflow.hidden) overflow.focus();\n },\n { once: true },\n );\n input.focus();\n input.select();\n }\n function hrefAction(kind: string) {\n return kind === 'video' ? 'Edit Video URL' : 'Edit URL';\n }\n function editHref(id: string) {\n if (board.readonly || board.isLocked(id)) return;\n const item = board.get(id);\n if (!item || (item.kind !== 'video' && item.kind !== 'link')) return;\n const video = item.kind === 'video';\n const d = dialog(video ? 'Edit video URL' : 'Edit URL');\n const input = el('input');\n input.type = 'text';\n input.inputMode = 'url';\n input.setAttribute('autocomplete', 'url');\n input.spellcheck = false;\n input.maxLength = 2000;\n input.value = item.href ?? '';\n input.setAttribute('aria-label', video ? 'Video URL' : 'URL');\n const error = el('p', 'ad-dialog-error');\n error.setAttribute('role', 'alert');\n error.hidden = true;\n const save = textButton(\n video ? 'Save video URL' : 'Save URL',\n () => {\n void (async () => {\n save.disabled = true;\n const result = await board.setHref(id, input.value);\n save.disabled = false;\n if (!result.ok) {\n const code = result.errors[0]?.code;\n error.textContent =\n code === 'LOCKED' || code === 'READONLY'\n ? (result.errors[0]?.message ?? 'This cannot be edited.')\n : video\n ? 'Use a YouTube or Vimeo URL.'\n : 'Use an http(s) URL.';\n error.hidden = false;\n input.setAttribute('aria-invalid', 'true');\n input.focus();\n return;\n }\n d.close();\n })();\n },\n 'ad-button ad-primary',\n );\n d.append(field(video ? 'Video URL' : 'URL', input), error, save);\n input.addEventListener('input', () => {\n error.hidden = true;\n input.removeAttribute('aria-invalid');\n });\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') d.querySelector<HTMLButtonElement>('.ad-primary')?.click();\n });\n input.focus();\n input.select();\n }\n let styleSelection = '';\n function renderStyle() {\n const locked = board.selection.some((id) => board.isLocked(id));\n if (board.tool !== 'select') {\n if (popoverTrigger && styleDock.contains(popoverTrigger)) closePopover();\n styleDock.hidden = true;\n return;\n }\n if (\n activeDialog ||\n (!locked &&\n document.activeElement instanceof HTMLInputElement &&\n document.activeElement.type === 'range' &&\n (styleDock.contains(document.activeElement) ||\n activePopover?.contains(document.activeElement)))\n )\n return;\n const focused = styleDock.contains(document.activeElement)\n ? (document.activeElement as HTMLElement)\n : undefined;\n const stylePopup =\n popoverTrigger && styleDock.contains(popoverTrigger)\n ? {\n label: popoverTrigger.getAttribute('aria-label'),\n focused: activePopover?.contains(document.activeElement),\n }\n : undefined;\n const focusLabel =\n focused?.getAttribute('aria-label') ?? (stylePopup?.focused ? stylePopup.label : undefined);\n const focusField = focused?.closest('label')?.querySelector('.ad-field-label')?.textContent;\n if (stylePopup) closePopover();\n const items = board.selection.map((id) => board.get(id)!).filter(Boolean);\n const selectedKey = items.map((item) => item.id).join(',');\n if (styleSelection !== selectedKey) {\n closePopover();\n }\n styleSelection = selectedKey;\n stylePanel.replaceChildren();\n styleDock.hidden = items.length === 0;\n if (!items.length) {\n if (stylePopup?.focused) board.focus();\n return;\n }\n const item = items[0],\n single = items.length === 1;\n const fillable = items.every((i) => ['rect', 'ellipse', 'diamond', 'note'].includes(i.kind));\n const stroked = items.every(\n (i) => !['image', 'html', 'video', 'link', 'group', 'text', 'note'].includes(i.kind),\n );\n const textOnly = items.every((i) => i.kind === 'text');\n const hasText = items.every(\n (i) => !['image', 'path', 'line', 'group', 'html', 'video', 'link'].includes(i.kind),\n );\n const colorControls = el('div', 'ad-color-controls');\n function colorControl(label: string, key: 'fill' | 'stroke') {\n const current =\n item.style?.[key] ?? (key === 'fill' ? (item.kind === 'note' ? 'moss' : 'none') : 'ink');\n const trigger = textButton(\n label,\n () => {\n const panel = popover(trigger, `${label} color`);\n if (!panel) return;\n panel.classList.add('ad-color-popover');\n for (const [token, name] of palette) {\n const b = el('button', `ad-swatch ${token === 'none' ? 'ad-swatch-none' : ''}`);\n b.type = 'button';\n b.style.setProperty('--swatch', resolveColor(token, board.stage.resolvedTheme));\n b.setAttribute('aria-label', `${label}: ${name}`);\n b.title = name;\n b.setAttribute('aria-pressed', String(current === token));\n b.onclick = () => {\n closePopover();\n board.defaultStyle[key] = token;\n board.updateSelection({ style: { [key]: token } });\n stylePanel.querySelector<HTMLButtonElement>(`[aria-label=\"${label}\"]`)?.focus();\n };\n panel.append(b);\n }\n showPopover(panel, trigger);\n },\n 'ad-color-control',\n );\n trigger.setAttribute('aria-label', label);\n trigger.setAttribute('aria-haspopup', 'true');\n trigger.setAttribute('aria-expanded', 'false');\n const swatch = el('span', `ad-color-preview ${current === 'none' ? 'ad-swatch-none' : ''}`);\n swatch.style.setProperty('--swatch', resolveColor(current, board.stage.resolvedTheme));\n trigger.prepend(swatch);\n colorControls.append(trigger);\n }\n if (fillable) colorControl('Fill', 'fill');\n if (stroked) colorControl('Line', 'stroke');\n if (textOnly) colorControl('Color', 'stroke');\n const opacityButton = textButton(\n 'Opacity',\n () => {\n const panel = popover(opacityButton, 'Opacity controls');\n if (!panel) return;\n panel.classList.add('ad-opacity-popover');\n const input = el('input');\n input.type = 'range';\n input.setAttribute('aria-label', 'Opacity');\n input.min = '0';\n input.max = '100';\n input.value = String(Math.round((board.get(item.id)?.style?.opacity ?? 1) * 100));\n const value = el('output', '', `${input.value}%`);\n const label = field('Opacity', input);\n label.querySelector('.ad-field-label')!.append(value);\n let first = true;\n input.oninput = () => {\n value.textContent = `${input.value}%`;\n board.apply(\n items.map(({ id }) => ({\n op: 'set',\n id,\n patch: { style: { opacity: Number(input.value) / 100 } },\n })),\n { origin: 'user', label: 'Change opacity', merge: !first },\n );\n first = false;\n };\n input.onchange = () => {\n first = true;\n };\n panel.append(label);\n showPopover(panel, opacityButton);\n input.focus();\n },\n 'ad-color-control',\n );\n opacityButton.insertAdjacentHTML('afterbegin', icon('opacity'));\n opacityButton.setAttribute('aria-label', 'Opacity');\n opacityButton.setAttribute('aria-haspopup', 'true');\n opacityButton.setAttribute('aria-expanded', 'false');\n if (items.every((item) => item.kind !== 'group')) colorControls.append(opacityButton);\n if (colorControls.childElementCount) stylePanel.append(colorControls);\n const updateText = (patch: Partial<NonNullable<Item['text']>>) =>\n board.apply(\n items.map((item) => ({\n op: 'set',\n id: item.id,\n patch: { text: { value: item.text?.value ?? '', ...patch } },\n })),\n { origin: 'user', label: 'Text style' },\n );\n function styleRow(label: string) {\n const row = el('div', 'ad-style-row');\n const group = el('div', 'ad-segments');\n group.setAttribute('role', 'group');\n group.setAttribute('aria-label', label);\n row.append(el('span', 'ad-style-label', label), group);\n stylePanel.append(row);\n return group;\n }\n function choices(\n group: HTMLElement,\n values: [string, string, string][],\n current: (item: Item) => string,\n change: (value: string) => void,\n ) {\n return values.map(([value, label, content]) => {\n const b = textButton(label, () => change(value), 'ad-segment');\n b.setAttribute('aria-label', label);\n b.title = label;\n b.setAttribute('aria-pressed', String(items.every((item) => current(item) === value)));\n b.innerHTML = content;\n group.append(b);\n return b;\n });\n }\n function lineIcon(width: number, dash = '') {\n return `<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M3 12h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"${width}\" stroke-linecap=\"round\"${dash ? ` stroke-dasharray=\"${dash}\"` : ''}/></svg>`;\n }\n if (hasText) {\n choices(\n styleRow('Text'),\n [\n ['s', 'Text size: Small', 'S'],\n ['m', 'Text size: Medium', 'M'],\n ['l', 'Text size: Large', 'L'],\n ['xl', 'Text size: Extra large', 'XL'],\n ],\n (item) => ({ 14: 's', 18: 'm', 26: 'l', 36: 'xl' })[fontSize(item.text)] ?? '',\n (value) => updateText({ size: value as 'm' }),\n );\n choices(\n styleRow('Align'),\n [\n ['start', 'Align text left', icon('alignLeft')],\n ['center', 'Align text center', icon('alignCenter')],\n ['end', 'Align text right', icon('alignRight')],\n ],\n (item) => item.text?.align ?? (item.kind === 'text' ? 'start' : 'center'),\n (value) => updateText({ align: value as 'start' }),\n );\n const fontChoices: [keyof typeof fonts, string, string][] = [\n ['sans', 'Font: Friendly', 'Aa'],\n ['serif', 'Font: Serif', 'Aa'],\n ['mono', 'Font: Mono', 'Aa'],\n ['hand', 'Font: Handwritten', 'Aa'],\n ];\n choices(\n styleRow('Font'),\n fontChoices,\n (item) => item.text?.font ?? DEFAULT_FONT,\n (value) => updateText({ font: value as 'sans' }),\n ).forEach((button, index) => {\n button.style.fontFamily = fonts[fontChoices[index][0]];\n });\n }\n if (stroked) {\n choices(\n styleRow('Line'),\n [\n ['1', 'Line: Fine', lineIcon(1)],\n ['2', 'Line: Regular', lineIcon(2)],\n ['4', 'Line: Bold', lineIcon(4)],\n ['8', 'Line: Extra bold', lineIcon(6)],\n ],\n (item) => String(styleFor(item, board.stage.resolvedTheme).strokeWidth),\n (value) => board.updateSelection({ style: { strokeWidth: Number(value) } }),\n );\n if (items.every((item) => item.kind !== 'path' || item.closed)) {\n choices(\n styleRow('Pattern'),\n [\n ['solid', 'Pattern: Solid', lineIcon(2)],\n ['dashed', 'Pattern: Dashed', lineIcon(2, '5 4')],\n ['dotted', 'Pattern: Dotted', lineIcon(2, '1 5')],\n ],\n (item) => item.style?.dash ?? 'solid',\n (value) => board.updateSelection({ style: { dash: value as 'solid' } }),\n );\n }\n }\n if (single && item.kind === 'connector')\n stylePanel.append(\n field(\n 'Route',\n select(\n [\n ['straight', 'Straight'],\n ['elbow', 'Elbow'],\n ['curve', 'Curve'],\n ],\n item.route ?? 'elbow',\n (v) => board.updateSelection({ route: v as 'elbow' }),\n ),\n ),\n );\n if (single && item.kind === 'connector')\n stylePanel.append(\n field(\n 'Arrowhead',\n select(\n [\n ['arrow', 'Arrow'],\n ['dot', 'Dot'],\n ['none', 'None'],\n ],\n item.heads?.end ?? 'arrow',\n (value) => board.updateSelection({ heads: { ...item.heads, end: value as 'arrow' } }),\n ),\n ),\n );\n if (single && (item.kind === 'video' || item.kind === 'link')) {\n const label = hrefAction(item.kind);\n const edit = textButton(label, () => editHref(item.id), 'ad-button ad-href-edit');\n edit.setAttribute('aria-label', label);\n stylePanel.append(edit);\n }\n const lock = button(\n locked ? 'Unlock selection' : 'Lock selection',\n locked ? 'lock' : 'unlock',\n () => board.updateSelection({ locked: !locked }),\n );\n lock.setAttribute('aria-pressed', String(locked));\n const row = el('div', 'ad-selection-actions');\n row.append(\n button('Duplicate selection', 'copy', () => board.duplicate()),\n button('More arrangement options', 'align', openArrange),\n lock,\n button('Delete selection', 'trash', () => board.deleteSelection()),\n );\n stylePanel.append(row);\n if (board.readonly || locked)\n stylePanel\n .querySelectorAll('button,input,select')\n .forEach(\n (e) =>\n ((e as HTMLButtonElement).disabled = e !== deselect && (e !== lock || board.readonly)),\n );\n if (focusLabel === 'Unlock selection' || focusLabel === 'Lock selection') lock.focus();\n else if (focusLabel === 'Deselect') deselect.focus();\n else if (focusLabel)\n stylePanel.querySelector<HTMLElement>(`[aria-label=\"${CSS.escape(focusLabel)}\"]`)?.focus();\n else if (focusField)\n [...stylePanel.querySelectorAll('label')]\n .find((label) => label.querySelector('.ad-field-label')?.textContent === focusField)\n ?.querySelector<HTMLElement>('input,select')\n ?.focus();\n if (focused || stylePopup?.focused)\n if (locked && !board.readonly && !styleDock.contains(document.activeElement)) lock.focus();\n }\n function openArrange() {\n const d = dialog('Give it a little order');\n const actions = el('div', 'ad-action-grid');\n const item = board.selection.length === 1 ? board.get(board.selection[0]) : undefined;\n if (item) {\n actions.append(\n textButton('Duplicate', () => {\n board.duplicate();\n d.close();\n }),\n textButton('Delete', () => {\n board.deleteSelection();\n d.close();\n }),\n );\n }\n if (board.selection.length > 1)\n for (const mode of [\n 'left',\n 'center',\n 'right',\n 'top',\n 'middle',\n 'bottom',\n 'horizontal',\n 'vertical',\n ] as const)\n actions.append(\n textButton(\n mode === 'horizontal' || mode === 'vertical' ? `Distribute ${mode}` : `Align ${mode}`,\n () => {\n board.align(mode);\n d.close();\n },\n ),\n );\n if (board.selection.length > 1)\n actions.append(\n textButton('Group', () => {\n board.group();\n d.close();\n }),\n );\n if (board.selection.some((id) => board.get(id)?.kind === 'group'))\n actions.append(\n textButton('Ungroup', () => {\n board.ungroup();\n d.close();\n }),\n );\n actions.append(\n textButton('Bring to front', () => {\n board.apply(\n board.selection.map((id) => ({ op: 'order', id, to: 'front' })),\n { origin: 'user', label: 'Bring to front' },\n );\n d.close();\n }),\n textButton('Send to back', () => {\n board.apply(\n board.selection.map((id) => ({ op: 'order', id, to: 'back' })),\n { origin: 'user', label: 'Send to back' },\n );\n d.close();\n }),\n );\n if (board.readonly)\n actions.querySelectorAll('button').forEach((action) => (action.disabled = true));\n d.append(actions);\n }\n function openChrome() {\n const panel = popover(chromeButton, 'Board controls');\n if (!panel) return;\n panel.classList.add('ad-chrome-popover');\n const history = el('div', 'ad-chrome-history');\n const chromeUndo = button('Undo', 'undo', () => {\n board.undo();\n chromeUndo.disabled = !board.canUndo;\n chromeRedo.disabled = !board.canRedo;\n });\n const chromeRedo = button('Redo', 'redo', () => {\n board.redo();\n chromeUndo.disabled = !board.canUndo;\n chromeRedo.disabled = !board.canRedo;\n });\n chromeUndo.disabled = !board.canUndo;\n chromeRedo.disabled = !board.canRedo;\n history.append(chromeUndo, chromeRedo);\n panel.append(history);\n if (showPages) {\n const section = el('section', 'ad-chrome-section');\n section.append(el('p', 'ad-chrome-label', 'Pages'));\n const list = el('div', 'ad-chrome-pages');\n for (const page of board.read().pages) list.append(pageButton(page.id, page.name));\n const add = button('Add page', 'plus', addPage, 'ad-tool-option');\n add.innerHTML += '<span>Add page</span>';\n add.disabled = board.readonly;\n section.append(list, add);\n panel.append(section);\n }\n const view = el('section', 'ad-chrome-section');\n view.append(el('p', 'ad-chrome-label', 'View'));\n const zoomRow = el('div', 'ad-zoom-controls');\n const zoomLabel = textButton(\n `${Math.round(board.view.zoom * 100)}%`,\n () => {\n board.view.zoom = 1;\n zoomLabel.textContent = '100%';\n },\n 'ad-zoom-value',\n );\n zoomLabel.setAttribute('aria-label', 'Reset zoom');\n const syncZoom = () => {\n zoomLabel.textContent = `${Math.round(board.view.zoom * 100)}%`;\n };\n zoomRow.append(\n button('Zoom out', 'minus', () => {\n board.view.zoom /= 1.2;\n syncZoom();\n }),\n zoomLabel,\n button('Zoom in', 'plus', () => {\n board.view.zoom *= 1.2;\n syncZoom();\n }),\n button('Fit drawing', 'fit', () => {\n board.view.fit();\n syncZoom();\n }),\n );\n view.append(zoomRow);\n panel.append(view);\n if (formats.length) {\n const exported = el('section', 'ad-chrome-section');\n exported.append(el('p', 'ad-chrome-label', 'Export'));\n for (const format of formats) {\n const [label, glyph] = exportChoices[format];\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n saveExport(format);\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n exported.append(option);\n }\n panel.append(exported);\n }\n showPopover(panel, chromeButton);\n }\n function saveExport(format: UiExportFormat) {\n void board\n .export(format, {\n scope: 'page',\n padding: 40,\n background: true,\n ...(format === 'png' ? { scale: 2 } : {}),\n })\n .then((content) => {\n const name =\n board\n .read()\n .meta.title.replace(/[^a-z0-9 _-]/gi, '')\n .trim() || 'drawing';\n download(\n content,\n `${name}.${format === 'json' ? 'annie' : format}`,\n format === 'json' ? ANNIE_MIME : format === 'svg' ? 'image/svg+xml' : 'image/png',\n );\n })\n .catch(() => undefined);\n }\n function openExport() {\n if (formats.length === 1) {\n saveExport(formats[0]);\n return;\n }\n if (!exportButton) return;\n const panel = popover(exportButton, 'Export');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n for (const format of formats) {\n const [label, glyph] = exportChoices[format];\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n saveExport(format);\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n panel.append(option);\n }\n showPopover(panel, exportButton);\n }\n function openMenu() {\n if (!brand) return;\n const panel = popover(brand, 'Board menu');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n const add = (label: string, glyph: string, action: () => void, disabled = false) => {\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n action();\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n option.disabled = disabled;\n panel.append(option);\n };\n add('Open a drawing', 'upload', () => drawingInput?.click(), board.readonly);\n if (phoneChrome(board.stage.root.clientWidth, board.stage.root.clientHeight)) {\n add('Hand', 'hand', () => {\n board.setTool('hand');\n board.focus();\n });\n }\n add(board.grid ? 'Hide grid' : 'Show grid', 'grid', () => board.setGrid(!board.grid));\n const dark = board.stage.resolvedTheme === 'dark';\n add(dark ? 'Light appearance' : 'Dark appearance', dark ? 'sun' : 'moon', () =>\n board.setTheme(dark ? 'light' : 'dark'),\n );\n add('Documentation', 'book', () => {\n window.open('./docs/index.html', '_blank', 'noopener');\n });\n const github = el('a', 'ad-tool-option');\n github.href = GITHUB_REPO_URL;\n github.target = '_blank';\n github.rel = 'noopener noreferrer';\n github.title = 'GitHub';\n github.innerHTML = `${icon('github')}<span>GitHub</span>`;\n github.addEventListener('click', () => closePopover());\n const separator = el('div', 'ad-menu-separator');\n separator.setAttribute('role', 'separator');\n panel.append(github, separator, el('p', 'ad-menu-version', `v${PACKAGE_VERSION}`));\n showPopover(panel, brand);\n }\n function refresh() {\n undo.disabled = !board.canUndo;\n redo.disabled = !board.canRedo;\n renderPages();\n renderStyle();\n }\n const context = (event: Event) => {\n const { x, y, id } = (event as CustomEvent<Point & { id?: string }>).detail;\n const item = id ? board.get(id) : undefined;\n if (!item) {\n closePopover();\n return;\n }\n const bounds = board.stage.root.getBoundingClientRect();\n const menu = contextMenu('Element actions', { x: bounds.left + x, y: bounds.top + y });\n const locked = board.isLocked(item.id);\n if (item.kind === 'video' || item.kind === 'link')\n menu.add(hrefAction(item.kind), 'link', () => editHref(item.id), locked);\n if (!['image', 'path', 'line', 'group', 'html', 'video', 'link'].includes(item.kind))\n menu.add('Edit text', 'text', () => board.editText(item.id), locked);\n const order = (to: 'front' | 'back') =>\n board.apply([{ op: 'order', id: item.id, to }], {\n origin: 'user',\n label: to === 'front' ? 'Bring to front' : 'Send to back',\n });\n menu.add('Bring to front', 'front', () => order('front'), locked);\n menu.add('Send to back', 'back', () => order('back'), locked);\n menu.add(\n 'Duplicate',\n 'copy',\n () => {\n board.select([item.id]);\n board.duplicate();\n },\n locked,\n );\n const separator = el('div', 'ad-menu-separator');\n separator.setAttribute('role', 'separator');\n menu.panel.append(separator);\n menu.add(\n 'Delete',\n 'trash',\n () => {\n board.select([item.id]);\n board.deleteSelection();\n },\n locked,\n );\n menu.show();\n };\n board.host.addEventListener('ad-context', context);\n unsubs.push(\n board.on('change', refresh),\n board.on('select', () => {\n renderStyle();\n }),\n board.on('page', refresh),\n board.on('view', (state) => {\n if (activePopover?.popover === 'manual') closePopover();\n percentage.textContent = `${Math.round(state.zoom * 100)}%`;\n }),\n board.on('tool', (id) => {\n for (const b of ui.querySelectorAll<HTMLElement>('[data-tool]'))\n b.setAttribute('aria-pressed', String(id === b.dataset.tool));\n shapeButton.setAttribute('aria-pressed', String(shapeKinds.includes(id)));\n board.stage.root.dataset.adTool = id;\n renderStyle();\n }),\n );\n refresh();\n return () => {\n clearTimeout(pagePressTimer);\n closePopover();\n unsubs.forEach((fn) => fn());\n activeDialog?.close();\n board.host.removeEventListener('ad-context', context);\n ui.remove();\n };\n}\n"],"x_google_ignoreList":[0],"mappings":"kFAAA,IAAM,GAAG,GAAG,KAAK,EAAE,EAAE,KAAU,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC,IAAM,IAAI,GAAG,KAAK,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,IAAM,KAAF,GAAQ,CAAmC,SAAS,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAuC,SAAS,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAA4C,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,OAA7U,SAAW,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,CAA+S,CAAE,EAA7H,SAAW,GAAG,OAAO,KAAK,MAAM,EAAE,GAAG,EAAE,GAAG,CAAqF,CAAE,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,OAAO,KAAK,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAa,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,CAAxB,EAAE,EAAE,EAAE,EAAqB,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,SAAS,EAAG,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,IAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAI,EAAF,EAAI,IAAI,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAI,EAAF,EAAI,IAAI,OAAO,CAAC,CAAC,SAAS,EAAG,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAI,IAAF,IAAQ,EAAE,EAAE,EAAE,EAAI,IAAF,IAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAW,IAAJ,QAAiB,IAAT,EAAW,GAAM,IAAJ,EAAO,KAAK,IAAI,EAAE,GAAG,CAAC,CAAiI,SAAS,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,EAAE,GAAG,UAAU,EAAE,GAAG,SAAS,EAAE,GAAG,iBAAiB,GAAE,EAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,GAAE,GAAI,GAAG,IAAI,GAAE,EAAG,OAAO,EAAE,GAAG,GAAG,EAAE,IAAI,GAAG,IAAI,GAAE,EAAG,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,GAAc,IAAX,EAAE,QAAY,GAAG,EAAE,MAAM,GAAG,IAAuI,EAAnI,EAAE,EAAE,EAAE,OAAO,GAAG,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAA/b,SAAY,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,IAAI,OAAA,CAAQ,EAAE,KAAK,IAAI,EAAE,EAAE,SAAS,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,KAAK,EAAE,GAAG,GAAG,EAAE,GAAG,SAAS,CAAkU,CAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,GAAG,SAAS,GAAK,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAE,EAAG,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,IAAI,CAAC,IAAI,SAAS,GAAG,EAAE,IAAI,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,OAAW,IAAT,IAAa,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,IAAI,IAAI,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,OAAO,EAAE,EAAE,EAAE,EAAG,EAAE,GAAmB,EAAM,OAAJ,GAAU,EAAE,EAAE,GAA9B,EAAG,EAAE,GAAG,IAAI,GAAwB,EAAN,CAAS,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAE,EAAY,MAAI,GAAE,EAAG,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAa,EAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAC,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,MAAM,GAAG,EAAE,GAAG,MAAM,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,EAAE,EAAE,OAAO,GAAG,MAAM,IAAI,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,GAAE,GAAG,GAAE,GAAG,GAAc,IAAX,EAAE,QAAe,IAAE,IAAG,GAAI,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,GAAc,IAAX,EAAE,SAAa,EAAE,GAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,KAAK,GAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,IAAI,EAAE,EAAhrG,SAAW,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,GAAG,CAAipG,CAAE,EAAE,EAAE,OAAO,GAAG,SAAS,GAAG,GAAc,IAAX,EAAE,OAAW,GAAE,KAAK,GAAG,EAAE,GAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,GAAE,QAAQ,EAAG,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,GAAE,EAAE,UAAU,GAAE,CAAC,IAAM,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,GAAG,OAAU,MAAH,GAAS,GAAG,CAAC,CAAwvB,SAAS,EAAE,EAAE,EAAE,CAAC,GAAG,OAAO,EAAjxB,SAAW,EAAE,EAAE,CAAC,GAAG,IAAI,WAAW,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,GAAE,GAAI,EAAE,GAAc,IAAX,EAAE,OAAW,MAAM,GAAG,IAAI,EAAE,IAAU,KAAL,EAAE,GAAO,EAAE,MAAM,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAA,EAAM,EAAE,EAAE,EAAE,EAAE,SAAS,EAAvpH,MAA8pH,CAAC,EAAE,EAAE,IAAI,GAAc,IAAX,EAAE,OAAW,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,MAAM,GAAE,GAAI,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,CAAY,IAAX,EAAE,SAAa,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,IAAI,OAAO,IAAI,GAAG,SAAS,EAAE,cAAc,IAAI,GAAE,EAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,MAAM,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,GAAG,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,GAAE,CAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,GAAlpI,GAAupI,OAAO,EAAE,GAAG,SAAS,EAAE,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,IAAI,QAAQ,CAAC,EAAE,GAAG,CAAC,CAA6B,CAAE,EAAE,GAAG,EAAE,CCKnzI,IAAa,EAAS,6BACT,EAAQ,CACnB,KAAM,6DACN,MAAO,iBACP,KAAM,iDACN,KAAM,yCAGR,SAAgB,EAAW,GACzB,OAAO,EAAM,GAAA,OACf,CACA,IAAM,EAAgC,CACpC,IAAK,UACL,MAAO,UACP,MAAO,UACP,MAAO,UACP,KAAM,UACN,KAAM,UACN,IAAK,UACL,OAAQ,UACR,KAAM,UACN,MAAO,WAEH,EAA+B,IAChC,EACH,IAAK,UACL,MAAO,UACP,MAAO,WAET,SAAgB,EAAM,EAAQ,MAAO,EAA0B,SAC7D,OAAkB,SAAV,EAAmB,EAAO,GAAO,IAAU,CACrD,CACA,SAAS,EAAI,GAaX,GAHA,EAAQ,CARN,MAAO,UACP,MAAO,UACP,IAAK,UACL,KAAM,UACN,MAAO,UACP,OAAQ,UACR,YAAa,aAED,EAAM,gBAAkB,EAClC,mBAAmB,KAAK,KAC1B,EAAQ,IAAI,IAAI,EAAM,MAAM,IAAI,IAAK,GAAY,EAAU,GAAS,KAAK,OACvE,8BAA8B,KAAK,GACrC,MAAO,CAAC,EAAG,EAAG,GACX,IAAK,GAAU,SAAS,EAAM,MAAM,EAAO,EAAQ,GAAI,KACvD,OAAwB,IAAjB,EAAM,OAAe,SAAS,EAAM,MAAM,EAAG,GAAI,IAAM,IAAM,GACzE,IAAK,YAAY,KAAK,GAAQ,OAC9B,MAAM,EAAW,EAAM,MAAM,aAC7B,OAAK,GAAY,EAAS,OAAS,OAAnC,EACO,EACJ,MAAM,EAAG,GACT,IAAK,GAAY,WAAW,IAAY,EAAQ,SAAS,KAAO,KAAO,IACvE,YACiB,IAAhB,EAAS,GACL,EACA,WAAW,EAAS,KAAO,EAAS,GAAG,SAAS,KAAO,IAAM,GAEvE,CACA,SAAS,EAAU,GACjB,OAAO,EACJ,MAAM,EAAG,GACT,IAAK,IACJ,MAAM,EAAQ,EAAU,IACxB,OAAO,GAAS,OAAU,EAAQ,QAAU,EAAQ,MAAS,QAAU,MAExE,OAAA,CAAQ,EAAK,EAAS,IAAU,EAAM,EAAU,CAAC,MAAQ,MAAQ,OAAQ,GAAQ,EACtF,CAEA,SAAgB,EAAW,EAAY,GACrC,GAAkB,SAAd,EAAK,KAAiB,OAAO,EAAM,EAAK,OAAO,QAAU,MAAO,GACpE,MAAM,EAAM,EAAM,MAAO,GACvB,EAAQ,GAAS,EAAM,GACzB,GAAI,CAAC,YAAa,QAAQ,SAAS,EAAK,OAA4B,UAAnB,EAAM,SAAsB,OAAO,EACpF,MAAM,EAAO,EAAI,EAAM,MACvB,IAAK,EAAM,OAAO,EAClB,MAAM,EAAQ,EAAI,EAAM,QAAS,IAC3B,EAAa,EACjB,EAAK,MAAM,EAAG,GAAG,IAAA,CAAK,EAAS,IAAU,EAAU,EAAK,GAAK,EAAM,IAAU,EAAI,EAAK,MAElF,EAAY,IAChB,MAAM,EAAa,EAAU,EAAI,IACjC,OAAQ,KAAK,IAAI,EAAY,GAAc,MAAS,KAAK,IAAI,EAAY,GAAc,MAEzF,IAAK,MAAM,IAAa,CAAC,EAAK,EAAM,MAAiB,SAAV,EAAmB,QAAU,SACtE,GAAI,EAAS,IAAc,IAAK,OAAO,EACzC,OAAO,EAAS,YAAc,EAAS,WAAa,UAAY,SAClE,CACA,SAAgB,EAAS,GACvB,OAAO,EAAa,EACtB,CACA,SAAgB,EAAI,GAClB,OAAO,OAAO,GAAS,IAAI,QACzB,WACC,IAAA,CAAY,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,IAAK,SAAU,IAAK,SAAW,IAExF,CACA,SAAgB,EAAM,GACpB,OAAO,KAAK,MAAc,IAAR,GAAgB,GACpC,CACA,SAAgB,EAAe,EAAiB,GAAS,GACvD,OACE,EACG,IAAA,CAAK,EAAO,IAAU,GAAG,EAAQ,IAAM,MAAM,EAAM,EAAM,MAAM,EAAM,EAAM,MAC3E,KAAK,MAAQ,EAAS,KAAO,GAEpC,CAuBA,SAAgB,EAAU,GACxB,MAAM,EAAI,EAAK,EACb,EAAI,EAAK,EACX,GAAkB,YAAd,EAAK,KACP,MAAO,IAAI,KAAK,EAAI,KAAK,EAAI,KAAK,EAAI,YAAY,OAAO,EAAI,KAAK,EAAI,WAAW,OACnF,GAAkB,YAAd,EAAK,KAAoB,MAAO,IAAI,EAAI,OAAO,KAAK,EAAI,KAAK,EAAI,KAAK,OAAO,EAAI,KACrF,GAAkB,SAAd,EAAK,KACP,OAAO,GAEH,EAAK,QAAU,CACb,CAAC,EAAG,GACJ,CAAC,EAAG,KAEN,IAAA,EAAM,EAAG,MAAA,CAAU,IAAG,QAE5B,GAAkB,SAAd,EAAK,KAAiB,OArC5B,SAA6B,GAC3B,MAAM,EAAS,EAAK,QAAU,GAC9B,IAAK,EAAO,OAAQ,MAAO,GAC3B,GAAI,EAAK,OACP,OAAO,EACL,EAAO,IAAA,EAAM,EAAG,MAAA,CAAU,IAAG,QAC7B,GAEJ,MAAM,EAAS,EACb,EAAO,IAAA,EAAM,EAAG,EAAG,MAAA,CAAiB,IAAG,IAAG,cAC1C,CACE,KAAuC,KAAhC,EAAK,OAAO,aAAe,GAClC,SAAU,IACV,UAAW,GACX,WAAY,IACZ,iBAAkB,EAAO,MAAO,QAAuB,IAAb,EAAM,IAChD,MAAM,IAGV,OAAK,EAAO,OACL,IAAI,EAAO,IAAK,GAAU,GAAG,EAAM,EAAM,OAAO,EAAM,EAAM,OAAO,KAAK,UADpD,EAE7B,CAgBmC,CAAa,GAC9C,MAAM,EAAS,KAAK,IAAI,EAAG,KAAK,IAAI,EAAK,OAAO,QAAA,GAAuB,EAAI,EAAG,EAAI,IAClF,MAAO,IAAI,OAAY,EAAI,KAAU,OAAO,KAAK,KAAU,EAAI,KAAU,KAAK,KAAK,EAAI,KAAU,KAAK,OAAY,OAAO,EAAI,KAAU,SAAc,MACvJ,CACA,SAAgB,GAAS,EAAY,GACnC,MAAM,EAAO,EAAK,OAAO,OAAuB,SAAd,EAAK,KAAkB,OAAS,QAClE,MAAO,CACL,OAAQ,EAAM,EAAK,OAAO,QAAU,MAAO,GAC3C,YAAa,EAAK,OAAO,cAA8B,SAAd,EAAK,KAAkB,EAAI,GACpE,KAAM,EAAK,OAAO,MAAQ,QAC1B,KAAM,EAAM,EAAM,GAClB,SAAU,EAAK,OAAO,UAAY,QAClC,OAAQ,EAAK,OAAO,QAAA,GACpB,QAAS,EAAK,OAAO,SAAW,EAEpC,CACA,SAAgB,GACd,EACA,EACA,EACA,EAAO,EAAU,IAEjB,MAAM,EAAQ,GAAS,EAAM,GACvB,EAAsB,WAAf,EAAM,KAAoB,MAAuB,WAAf,EAAM,KAAoB,MAAQ,GAC3E,EAAuB,SAAd,EAAK,KACd,EACU,SAAd,EAAK,MAAiC,cAAd,EAAK,KACzB,OACA,EACE,EAAK,QAAyB,SAAf,EAAM,KACnB,EAAM,KACN,EAAM,OACR,EAAM,KACR,EAAU,QAAQ,EAAI,QAAQ,gBAAiB,OAC/C,EAA2B,UAAnB,EAAM,UAAiC,SAAT,IAAoB,EAI1D,EAAW,EAAQ,QAAQ,KAAa,EAE9C,MAAO,GALM,EACT,sBAAsB,mHAAyH,EAAI,iEACnJ,cAEyB,EAAI,aAAgB,EAAI,MAAgC,SAAnB,EAAM,UAAwB,EAAkC,GAAzB,kCAAuC,IAAW,EAAK,OAAS,OAAS,EAAI,EAAM,0BAA0B,EAAM,8DAA8D,EAAO,sBAAsB,KAAU,MAEnU,CACA,SAAgB,GACd,EACA,EACA,EACA,EACA,GAEA,IAAK,GAAiB,SAAT,EAAiB,MAAO,GACrC,GAAa,QAAT,EACF,MAAO,eAAe,EAAM,EAAM,WAAW,EAAM,EAAM,UAAU,KAAK,IAAI,EAAW,EAAR,aAAqB,EAAI,QAC1G,MAAM,EAAQ,KAAK,MAAM,EAAM,EAAI,EAAS,EAAG,EAAM,EAAI,EAAS,GAC5D,EAAS,KAAK,IAAI,GAAY,IAAR,GACtB,EAAS,KAAK,GAAK,EASzB,MAAO,YAAY,EAAe,CAAC,CAPjC,EAAG,EAAM,EAAI,KAAK,IAAI,EAAQ,GAAU,EACxC,EAAG,EAAM,EAAI,KAAK,IAAI,EAAQ,GAAU,GAMJ,EAAO,CAH3C,EAAG,EAAM,EAAI,KAAK,IAAI,EAAQ,GAAU,EACxC,EAAG,EAAM,EAAI,KAAK,IAAI,EAAQ,GAAU,6BAE+B,EAAI,qBAA0B,qDACzG,CACA,SAAgB,GAAY,EAAiB,EAAY,GACvD,GAAI,EAAO,OAAS,EAAG,MAAO,GAC9B,MAAM,EAAQ,GAAS,EAAM,GAC7B,OACE,GAAW,EAAO,GAAI,EAAO,GAAI,EAAK,OAAO,MAAO,EAAM,OAAQ,EAAM,aACxE,GACE,EAAO,EAAO,OAAS,GACvB,EAAO,EAAO,OAAS,GACvB,EAAK,OAAO,MAAsB,cAAd,EAAK,KAAuB,QAAU,QAC1D,EAAM,OACN,EAAM,YAGZ,CCpOA,IAAa,GAAa,oCAC1B,SAAgB,GAAW,GACzB,OAAO,KAAK,UAAU,EAAK,KAAM,EACnC,CCJA,IAAM,GAAgC,CACpC,OACE,+GACF,KAAM,wHACN,KAAM,8DACN,QAAS,iDACT,QACE,2HACF,KAAM,kKACN,UAAW,mEACX,KAAM,4FACN,KAAM,iDACN,KAAM,qMACN,KAAM,kGACN,OACE,kGACF,QACE,6GACF,MACE,wJACF,KAAM,uJACN,OACE,yIACF,KAAM,gEACN,KAAM,mEACN,KAAM,mCACN,MAAO,yBACP,IAAK,kLACL,QAAS,oDACT,SAAU,uFACV,OAAQ,qFACR,KAAM,yFACN,MAAO,yCACP,KAAM,2MACN,MACE,kLACF,IAAK,mIACL,KAAM,4FACN,MACE,0JACF,KAAM,mJACN,KAAM,kGACN,KAAM,6GACN,OACE,2vBACF,UAAW,sCACX,YAAa,sCACb,WAAY,uCACZ,MACE,kIACF,OACE,4NACF,KAAM,iKAER,SAAgB,GAAK,GACnB,MAAO,mJAAmJ,GAAM,IAAS,GAAM,cACjL,CACA,SAAgB,GACd,EACA,EACA,EACA,EAAY,kBAEZ,MAAM,EAAK,SAAS,cAAc,UAUlC,OATA,EAAG,KAAO,SACV,EAAG,UAAY,EACf,EAAG,MAAQ,EACX,EAAG,aAAa,aAAc,GAC9B,EAAG,UAAY,GAAK,GACpB,EAAG,iBAAiB,QAAA,KAClB,EAAG,QACH,MAEK,CACT,CCzEA,IAAa,GAAkB,QAElB,GAAkB,+CCkBzB,GAAyC,CAAC,MAAO,OAcvD,IAAM,GAAQ,CACZ,CAAC,SAAU,SAAU,KACrB,CAAC,OAAQ,OAAQ,KACjB,CAAC,OAAQ,YAAa,KACtB,CAAC,UAAW,UAAW,KACvB,CAAC,UAAW,UAAW,KACvB,CAAC,YAAa,QAAS,KACvB,CAAC,OAAQ,OAAQ,KACjB,CAAC,OAAQ,OAAQ,KACjB,CAAC,OAAQ,OAAQ,KACjB,CAAC,OAAQ,cAAe,KACxB,CAAC,SAAU,SAAU,MAEjB,GAAU,CACd,CAAC,MAAO,OACR,CAAC,QAAS,SACV,CAAC,OAAQ,mBACT,CAAC,OAAQ,cACT,CAAC,QAAS,UACV,CAAC,SAAU,YACX,CAAC,QAAS,SACV,CAAC,QAAS,SACV,CAAC,MAAO,YACR,CAAC,OAAQ,QACT,CAAC,OAAQ,YAGX,SAAS,GAAY,EAAe,GAClC,OAAO,GAAS,KAAQ,GAAS,MAAQ,GAAU,GACrD,CACA,SAAS,GAA0C,EAAQ,EAAY,GAAI,GACzE,MAAM,EAAO,SAAS,cAAc,GAGpC,OAFA,EAAK,UAAY,EACb,IAAM,EAAK,YAAc,GACtB,CACT,CACA,SAAS,GAAW,EAAe,EAAoB,EAAO,aAC5D,MAAM,EAAI,GAAG,SAAU,EAAM,GAM7B,OALA,EAAE,KAAO,SACT,EAAE,iBAAiB,QAAA,KACjB,EAAE,QACF,MAEK,CACT,CACA,SAAS,GAAM,EAAe,GAC5B,MAAM,EAAU,GAAG,QAAS,YAE5B,OADA,EAAQ,OAAO,GAAG,OAAQ,iBAAkB,GAAQ,GAC7C,CACT,CACA,SAAS,GAAO,EAA4B,EAAe,GACzD,MAAM,EAAQ,GAAG,UAMjB,GALA,EAAO,QAAA,EAAU,EAAG,MAClB,MAAM,EAAI,GAAG,SAAU,GAAI,GAC3B,EAAE,MAAQ,EACV,EAAM,OAAO,MAEV,EAAO,KAAA,EAAO,KAAO,IAAM,GAAQ,CACtC,MAAM,EAAS,GAAG,SAAU,GAAI,GAChC,EAAO,MAAQ,EACf,EAAM,OAAO,EACf,CAGA,OAFA,EAAM,MAAQ,EACd,EAAM,SAAA,IAAiB,EAAO,EAAM,OAC7B,CACT,CAWA,SAAgB,GAAQ,EAAc,EAAqB,CAAC,GAC1D,MAAM,EAAK,GAAG,MAAO,SACf,GAA4B,IAAjB,EAAQ,KACnB,GAA8B,IAAlB,EAAQ,MACtB,GAAU,EAAG,UAAU,IAAI,cAC3B,GAAW,EAAG,UAAU,IAAI,gBAC5B,GAAY,IAAW,EAAG,UAAU,IAAI,cAC5C,EAAM,MAAM,KAAK,OAAO,GACxB,MAAM,EAAyB,GAC/B,IAAI,EAmCA,EACA,EACA,EApCJ,SAAS,EAAO,GACd,IACA,GAAc,QACd,MAAM,EAAW,SAAS,cACpB,EAAI,GAAG,SAAU,aACjB,EAAO,GAAG,MAAO,kBACjB,EAAO,GAAG,OA0BhB,OAzBA,EAAK,OAAO,GAAG,KAAM,GAAI,IACzB,EAAK,OACH,EACA,GAAO,QAAS,QAAA,IAAe,EAAE,UAEnC,EAAE,OAAO,GACT,EAAE,iBAAiB,QAAU,IAC3B,GAAI,EAAE,SAAW,EAAG,CAClB,MAAM,EAAI,EAAE,yBACR,EAAE,QAAU,EAAE,MAAQ,EAAE,QAAU,EAAE,OAAS,EAAE,QAAU,EAAE,KAAO,EAAE,QAAU,EAAE,SAClF,EAAE,OACN,IAEF,EAAE,iBAAiB,QAAA,KACjB,EAAE,SACE,IAAiB,IAAG,OAAe,GAClC,IACH,KACI,GAAU,YAAa,EAAS,QAC/B,EAAM,WAGf,EAAG,OAAO,GACV,EAAe,EACf,EAAE,YACK,CACT,CAIA,SAAS,IACP,GAAe,cACf,GAAe,SACf,OAAgB,EAChB,GAAgB,aAAa,gBAAiB,SAC1C,IAAgB,EAAe,qBAAuB,MAC1D,OAAiB,CACnB,CACA,SAAS,EAAQ,EAAwC,GACvD,GAAI,GAAW,IAAmB,GAAW,GAAe,QAAQ,iBAElE,YADA,IAGF,IACA,MAAM,EAAQ,GAAG,MAAO,cACxB,EAAM,QAAU,OAChB,EAAM,aAAa,OAAQ,SAC3B,EAAM,aAAa,aAAc,GACjC,MAAM,EAAW,SAAS,cAuC1B,OAtCI,IACF,EAAQ,aAAa,gBAAiB,QACtC,EAAQ,qBAAuB,EAC/B,EAAQ,oBAAsB,QAEhC,EAAgB,EAChB,EAAiB,EACjB,EAAM,iBAAiB,SAAA,KACjB,IAAkB,GAAU,EAAM,QAAQ,kBAC5C,GAAS,aAAa,gBAAiB,WAE3C,EAAM,iBAAiB,UAAY,IAEjC,GADA,EAAM,kBACY,WAAd,EAAM,KAAmC,QAAd,EAAM,KAAmC,WAAlB,EAAM,QACxC,WAAd,EAAM,KAAkB,EAAM,iBAClC,IACI,GAAU,YAAa,EAAS,QAC/B,EAAM,aACN,KACH,EAAM,kBAAkB,mBAC1B,CAAC,YAAa,UAAW,YAAa,aAAc,OAAQ,OAAO,SAAS,EAAM,KAClF,CACA,MAAM,EAAQ,EAAa,GACrB,EAAU,EAAM,QAAQ,SAAS,eACjC,EACU,SAAd,EAAM,IACF,EACc,QAAd,EAAM,IACJ,EAAM,OAAS,GACd,GACgB,cAAd,EAAM,KAAqC,eAAd,EAAM,IAAuB,GAAI,GAC/D,EAAM,QACR,EAAM,OACd,EAAM,iBACN,EAAM,IAAO,OACf,IAEF,EAAG,OAAO,GACH,CACT,CACA,SAAS,EACP,EACA,EACA,EAAuB,GAEvB,EAAM,cACN,MAAM,EAAS,EAAQ,wBACrB,EAAS,EAAM,MAAM,KAAK,wBACtB,EAAS,GAAY,EAAO,MAAO,EAAO,QAC9C,EAAQ,KAAK,IAAI,IAAK,EAAO,MAAQ,IACvC,EAAM,MAAM,MAAQ,GAAG,MACvB,MAAM,EAAS,EAAM,wBAAwB,OACvC,EAAgB,EAAQ,QAAQ,iBAAmB,EACnD,EAAO,EACT,EAAO,MAAQ,GACf,EAAQ,QAAQ,eAAiB,EAAO,KAAO,EAAO,KAAO,EAAO,MAAQ,EAC1E,EAAO,KACP,EAAO,MAAQ,EACf,EAAM,EACR,EAAO,IACP,EAAO,IAAM,EAAO,IAAM,EAAO,OAAS,EACxC,EAAO,IAAM,EAAS,GACtB,EAAO,OAAS,GACtB,EAAM,MAAM,KAAO,GAAG,KAAK,IAAI,EAAO,KAAO,GAAI,KAAK,IAAI,EAAM,EAAO,MAAQ,EAAQ,SACvF,EAAM,MAAM,IAAM,GAAG,KAAK,IAAI,EAAO,IAAM,GAAI,KAAK,IAAI,EAAK,EAAO,OAAS,EAAS,SACtF,EAAa,GAAO,IAAI,OAC1B,CACA,SAAS,EAAa,GACpB,MAAO,IAAI,EAAM,iBAA8B,kCACjD,CACA,SAAS,EAAY,EAAe,GAClC,MAAM,EAAQ,OAAQ,EAAW,GAEjC,EAAM,QAAU,SAChB,EAAM,UAAU,IAAI,mBACpB,EAAM,aAAa,OAAQ,QAC3B,EAAM,UAAW,EA2BjB,MAAO,CAAE,QAAO,IA1BV,CAAO,EAAe,EAAe,EAAoB,GAAW,KACxE,MAAM,EAAS,GACb,EAAA,KAEE,IACA,EAAM,QACN,KAEF,kBAEF,EAAO,mBAAmB,aAAc,GAAK,IAC7C,EAAO,aAAa,OAAQ,YAC5B,EAAO,SAAW,EAAM,UAAY,EACtB,UAAV,GAAmB,EAAO,UAAU,IAAI,aAC5C,EAAM,OAAO,IAYM,KAVf,KACJ,EAAM,cACN,MAAM,EAAS,EAAM,MAAM,KAAK,wBAC1B,EAAQ,KAAK,IAAI,IAAK,EAAO,MAAQ,IAC3C,EAAM,MAAM,MAAQ,GAAG,MACvB,MAAM,EAAS,EAAM,wBAAwB,OAC7C,EAAM,MAAM,KAAO,GAAG,KAAK,IAAI,EAAO,KAAO,GAAI,KAAK,IAAI,EAAM,EAAG,EAAO,MAAQ,EAAQ,SAC1F,EAAM,MAAM,IAAM,GAAG,KAAK,IAAI,EAAO,IAAM,GAAI,KAAK,IAAI,EAAM,EAAG,EAAO,OAAS,EAAS,UACzF,EAAM,cAAiC,0BAA4B,GAAO,SAG/E,CACA,MAAM,EAAA,IAAqB,IACrB,EAAkB,IACS,WAA3B,GAAe,SAAyB,EAAc,SAAS,EAAM,SACvE,KAEJ,OAAO,iBAAiB,SAAU,GAClC,OAAO,iBAAiB,cAAe,GAAgB,GACvD,EAAO,KAAA,KACL,OAAO,oBAAoB,SAAU,GACrC,OAAO,oBAAoB,cAAe,GAAgB,KAE5D,MAAM,EA/QR,SAAuB,GACrB,IAAc,IAAV,EAAiB,MAAO,GAC5B,IAAK,MAAM,QAAQ,GAAQ,MAAO,IAAI,IACtC,MAAM,iBAAO,IAAI,IACX,EAA4B,GAClC,IAAK,MAAM,KAAU,EACJ,QAAX,GAA+B,QAAX,GAA+B,SAAX,GACxC,EAAK,IAAI,KACb,EAAK,IAAI,GACT,EAAQ,KAAK,IAEf,OAAO,CACT,CAmQkB,CAAc,EAAQ,QAChC,EAA0D,CAC9D,IAAK,CAAC,YAAa,SACnB,IAAK,CAAC,YAAa,SACnB,KAAM,CAAC,kBAAmB,SAEtB,EAAS,GAAG,SAAU,aAC5B,IAAI,EACA,EACA,EACA,EACA,IACF,EAAQ,GAAO,aAAc,UAw6B/B,WACE,IAAK,EAAO,OACZ,MAAM,EAAQ,EAAQ,EAAO,cAC7B,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,mBACpB,MAAM,EAAA,CAAO,EAAe,EAAe,EAAoB,GAAW,KACxE,MAAM,EAAS,GACb,EACA,EAAA,KAEE,IACA,KAEF,kBAEF,EAAO,WAAa,SAAS,WAC7B,EAAO,SAAW,EAClB,EAAM,OAAO,IAEf,EAAI,iBAAkB,SAAA,IAAgB,GAAc,QAAS,EAAM,UAC/D,GAAY,EAAM,MAAM,KAAK,YAAa,EAAM,MAAM,KAAK,eAC7D,EAAI,OAAQ,OAAA,KACV,EAAM,QAAQ,QACd,EAAM,UAGV,EAAI,EAAM,KAAO,YAAc,YAAa,OAAA,IAAc,EAAM,SAAS,EAAM,OAC/E,MAAM,EAAqC,SAA9B,EAAM,MAAM,cACzB,EAAI,EAAO,mBAAqB,kBAAmB,EAAO,MAAQ,OAAA,IAChE,EAAM,SAAS,EAAO,QAAU,SAElC,EAAI,gBAAiB,OAAA,KACnB,OAAO,KAAK,oBAAqB,SAAU,cAE7C,MAAM,EAAS,GAAG,IAAK,kBACvB,EAAO,KAAO,GACd,EAAO,OAAS,SAChB,EAAO,IAAM,sBACb,EAAO,MAAQ,SACf,EAAO,UAAY,GAAG,GAAK,+BAC3B,EAAO,iBAAiB,QAAA,IAAe,KACvC,MAAM,EAAY,GAAG,MAAO,qBAC5B,EAAU,aAAa,OAAQ,aAC/B,EAAM,OAAO,EAAQ,EAAW,GAAG,IAAK,kBAAmB,IAAI,OAC/D,EAAY,EAAO,EACrB,EAr9BoD,YAClD,EAAM,UACJ,oUACA,GAAK,WACP,EAAM,aAAa,gBAAiB,QACpC,EAAM,aAAa,gBAAiB,SACpC,EAAe,GAAG,SAClB,EAAa,KAAO,OACpB,EAAa,OAAS,gCACtB,EAAa,QAAS,EACtB,EAAa,SAAA,KACX,MAAM,EAAO,GAAc,QAAQ,GAC/B,IAAc,EAAa,MAAQ,IACnC,GACF,EACG,OACA,KAAM,GAAU,EAAM,KAAK,KAAK,MAAM,KACtC,MAAA,SAEP,EAAO,OAAO,IAEhB,MAAM,EAAU,GAAG,MAAO,qBACtB,EAAQ,SACV,EAAe,GAAW,SAw3B5B,WACE,GAAuB,IAAnB,EAAQ,OAEV,YADA,GAAW,EAAQ,IAGrB,IAAK,EAAc,OACnB,MAAM,EAAQ,EAAQ,EAAc,UACpC,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,mBACpB,IAAK,MAAM,KAAU,EAAS,CAC5B,MAAO,EAAO,GAAS,EAAc,GAC/B,EAAS,GACb,EACA,EAAA,KAEE,IACA,GAAW,IAEb,kBAEF,EAAO,WAAa,SAAS,WAC7B,EAAM,OAAO,EACf,CACA,EAAY,EAAO,EACrB,EAh5BkD,yCAChD,EAAa,mBAAmB,aAAc,GAAK,aAC/C,EAAQ,OAAS,IACnB,EAAa,aAAa,gBAAiB,QAC3C,EAAa,aAAa,gBAAiB,UAE7C,EAAQ,OAAO,IAEjB,EAAe,GAAO,iBAAkB,OAuwBxC,WACE,MAAM,EAAQ,EAAQ,EAAc,kBACpC,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,qBACpB,MAAM,EAAU,GAAG,MAAO,qBACpB,EAAa,GAAO,OAAQ,OAAA,KAChC,EAAM,OACN,EAAW,UAAY,EAAM,QAC7B,EAAW,UAAY,EAAM,UAEzB,EAAa,GAAO,OAAQ,OAAA,KAChC,EAAM,OACN,EAAW,UAAY,EAAM,QAC7B,EAAW,UAAY,EAAM,UAM/B,GAJA,EAAW,UAAY,EAAM,QAC7B,EAAW,UAAY,EAAM,QAC7B,EAAQ,OAAO,EAAY,GAC3B,EAAM,OAAO,GACT,EAAW,CACb,MAAM,EAAU,GAAG,UAAW,qBAC9B,EAAQ,OAAO,GAAG,IAAK,kBAAmB,UAC1C,MAAM,EAAO,GAAG,MAAO,mBACvB,IAAK,MAAM,KAAQ,EAAM,OAAO,MAAO,EAAK,OAAO,EAAW,EAAK,GAAI,EAAK,OAC5E,MAAM,EAAM,GAAO,WAAY,OAAQ,EAAS,kBAChD,EAAI,WAAa,wBACjB,EAAI,SAAW,EAAM,SACrB,EAAQ,OAAO,EAAM,GACrB,EAAM,OAAO,EACf,CACA,MAAM,EAAO,GAAG,UAAW,qBAC3B,EAAK,OAAO,GAAG,IAAK,kBAAmB,SACvC,MAAM,EAAU,GAAG,MAAO,oBACpB,EAAY,GAChB,GAAG,KAAK,MAAwB,IAAlB,EAAM,KAAK,SAAY,KAEnC,EAAM,KAAK,KAAO,EAClB,EAAU,YAAc,QAE1B,iBAEF,EAAU,aAAa,aAAc,cACrC,MAAM,EAAA,KACJ,EAAU,YAAc,GAAG,KAAK,MAAwB,IAAlB,EAAM,KAAK,UAmBnD,GAjBA,EAAQ,OACN,GAAO,WAAY,QAAA,KACjB,EAAM,KAAK,MAAQ,IACnB,MAEF,EACA,GAAO,UAAW,OAAA,KAChB,EAAM,KAAK,MAAQ,IACnB,MAEF,GAAO,cAAe,MAAA,KACpB,EAAM,KAAK,MACX,OAGJ,EAAK,OAAO,GACZ,EAAM,OAAO,GACT,EAAQ,OAAQ,CAClB,MAAM,EAAW,GAAG,UAAW,qBAC/B,EAAS,OAAO,GAAG,IAAK,kBAAmB,WAC3C,IAAK,MAAM,KAAU,EAAS,CAC5B,MAAO,EAAO,GAAS,EAAc,GAC/B,EAAS,GACb,EACA,EAAA,KAEE,IACA,GAAW,IAEb,kBAEF,EAAO,WAAa,SAAS,WAC7B,EAAS,OAAO,EAClB,CACA,EAAM,OAAO,EACf,CACA,EAAY,EAAO,EACrB,GAx1BA,EAAa,UAAU,IAAI,aAC3B,EAAa,aAAa,gBAAiB,QAC3C,EAAa,aAAa,gBAAiB,SAC3C,EAAQ,OAAO,GACf,EAAO,OAAO,GACT,GAAU,EAAO,UAAU,IAAI,iBACpC,EAAG,OAAO,GACN,GAAc,EAAG,OAAO,GAC5B,MAAM,EAAU,GAAG,MAAO,cAE1B,SAAS,EAAW,EAAY,GAAW,GACzC,MAAM,CAAG,EAAO,GAAO,GAAM,KAAM,GAAS,EAAK,KAAO,GAClD,EAAI,GACR,EACA,EAAA,KAEE,IACA,EAAM,QAAQ,GACd,EAAM,SAER,EAAW,iBAAmB,kBAOhC,OALA,EAAE,QAAQ,KAAO,EACjB,EAAE,aAAa,oBAAqB,GACpC,EAAE,aAAa,eAAgB,OAAO,EAAM,OAAS,IACrD,EAAE,WAAa,EAAW,SAAS,WAAiB,4BAA4B,WAC5E,EAAM,UAAmB,SAAP,GAAwB,WAAP,IAAiB,EAAE,UAAW,GAC9D,CACT,CAnBA,EAAQ,aAAa,aAAc,iBAoBnC,MAAM,EAAa,CAAC,OAAQ,UAAW,UAAW,OAAQ,aACpD,EAAc,GAAO,SAAU,SAAA,KACnC,MAAM,EAAQ,EAAQ,EAAa,UAC9B,IACL,EAAM,UAAU,IAAI,mBACpB,EAAM,UAAU,EAAW,IAAK,GAAO,EAAW,GAAI,KACtD,EAAY,EAAO,MAErB,EAAY,aAAa,gBAAiB,QAC1C,EAAY,aAAa,gBAAiB,SAC1C,EAAY,WACV,6EACF,MAAM,EAAa,GAAG,SACtB,EAAW,KAAO,OAClB,EAAW,OAAS,uDACpB,EAAW,QAAS,EACpB,EAAW,SAAA,KACL,EAAW,QAAQ,IAAI,EAAW,SAAS,EAAW,MAAM,IAAI,MAAA,QACpE,EAAW,MAAQ,IAErB,MAAM,EAAc,GAAO,YAAa,QAAA,KACtC,IACA,EAAW,UAEb,EAAY,WAAa,4CACzB,EAAY,SAAW,EAAM,SAC7B,MAAM,EAAO,EAAW,QACpB,GAAU,EAAK,UAAU,IAAI,mBACjC,EAAQ,OACN,EAAW,UACX,EACA,EAAW,UACX,GAAG,MAAO,sBACV,EACA,EAAW,QACX,EAAW,QACX,EAAW,QACX,EACA,GAEF,EAAG,OAAO,GACV,MAAM,EAAY,GAAG,QAAS,iBAC9B,EAAU,aAAa,aAAc,mBACrC,EAAU,QAAS,EACnB,MAAM,EAAa,GAAG,MAAO,kBACvB,EAAW,GAAO,WAAY,UAAA,IAAiB,EAAM,OAAO,KAClE,EAAS,UAAU,IAAI,oBACvB,EAAU,OAAO,EAAU,GAC3B,EAAG,OAAO,GACV,MAAM,EAAS,GAAG,SAAU,aACtB,EAAO,GAAO,OAAQ,OAAA,IAAc,EAAM,QAC9C,EAAO,GAAO,OAAQ,OAAA,IAAc,EAAM,QAC5C,EAAK,aAAa,oBAAqB,oBACvC,EAAK,aAAa,oBAAqB,gCACvC,MAAM,EAAW,GAAG,MAAO,YAC3B,EAAS,aAAa,aAAc,SACpC,MAAM,EAAW,GAAG,MAAO,gBAC3B,EAAS,aAAa,OAAQ,WAC9B,EAAS,aAAa,aAAc,SACpC,MAAM,EAAW,GAAO,YAAa,OAgLrC,WACE,MAAM,EAAQ,EAAQ,EAAU,aAChC,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,oBACpB,IAAK,MAAM,KAAQ,EAAM,OAAO,MAAO,CACrC,MAAM,EAAM,GAAG,MAAO,eACtB,EAAI,OAAO,EAAW,EAAK,GAAI,EAAK,OACpC,MAAM,EAAU,GAAO,eAAe,EAAK,OAAQ,OAAA,KACjD,MAAM,EAAS,EAAQ,wBACvB,EAAY,EAAK,GAAI,EAAK,KAAM,CAAE,EAAG,EAAO,KAAM,EAAG,EAAO,QAE9D,EAAI,OAAO,GACX,EAAM,OAAO,EACf,CACA,EAAY,EAAO,GACnB,EAAM,cAA2B,0BAA0B,eAAe,CAAE,MAAO,WACrF,GA/LA,EAAS,aAAa,gBAAiB,QACvC,EAAS,aAAa,gBAAiB,SACvC,EAAS,QAAS,EAClB,MAAM,EAAU,GAAO,WAAY,OAAQ,GAC3C,EAAQ,SAAW,EAAM,SACzB,EAAS,OAAO,EAAU,EAAU,GACpC,IAAI,EAAY,GAChB,SAAS,EAAY,EAAY,EAAc,GAC7C,MAAM,EAAO,EAAY,eAAgB,GACzC,EAAK,IAAI,cAAe,OAAA,IAkN1B,SAAoB,EAAY,GAC9B,GAAI,EAAM,SAAU,OACpB,MAAM,EAAI,EAAO,kBACX,EAAQ,GAAG,SACjB,EAAM,MAAQ,EACd,EAAM,UAAY,IAClB,EAAE,OACA,GAAM,YAAa,GACnB,GACE,YAAA,KAEM,EAAM,MAAM,QACd,EAAM,MAAM,CAAC,CAAE,GAAI,WAAY,KAAI,MAAO,CAAE,KAAM,EAAM,MAAM,UAAa,CACzE,OAAQ,OACR,MAAO,gBAEX,EAAE,SAEJ,yBAGJ,EAAM,iBAAiB,UAAY,IACf,UAAd,EAAM,KAAiB,EAAE,cAAiC,gBAAgB,UAEhF,EAAE,iBACA,QAAA,KAEE,MAAM,EAAM,EAAS,cAAiC,kBAAkB,IAAI,OAAO,QAC/E,IAAQ,EAAI,OAAQ,EAAI,QAClB,EAAS,QAAQ,EAAS,SAEtC,CAAE,MAAM,IAEV,EAAM,QACN,EAAM,QACR,CArPwC,CAAW,EAAI,IACrD,EAAK,IACH,cACA,QAAA,KAEE,EAAM,MAAM,CAAC,CAAE,GAAI,cAAe,OAAO,CAAE,OAAQ,OAAQ,MAAO,iBAEtC,IAA9B,EAAM,OAAO,MAAM,QAErB,EAAK,MACP,CACA,SAAS,EAAW,EAAY,EAAc,GAAM,GAClD,MAAM,EAAO,GACX,EAAA,KAEE,IACA,EAAM,QAAQ,GACd,EAAS,cAAiC,2BAA2B,SAEvE,EAAM,cAAgB,kBAExB,EAAK,MAAQ,EACb,EAAK,QAAQ,OAAS,EACtB,IACI,EADA,GAAO,EAEX,EAAK,iBAAiB,cAAgB,IACpC,GAAO,EACmB,UAAtB,EAAM,cACV,EAAQ,CAAE,EAAG,EAAM,QAAS,EAAG,EAAM,SACrC,aAAa,GACb,EAAiB,WAAA,KACf,GAAO,EACP,EAAY,EAAI,EAAM,IACrB,QAEL,EAAK,iBAAiB,cAAgB,IAChC,GAAS,KAAK,MAAM,EAAM,QAAU,EAAM,EAAG,EAAM,QAAU,EAAM,GAAK,IAC1E,aAAa,KAEjB,IAAK,MAAM,IAAQ,CAAC,YAAa,iBAC/B,EAAK,iBAAiB,EAAA,IAAY,aAAa,IAwCjD,OAvCA,EAAK,iBACH,QACC,IACK,IACF,EAAM,iBACN,EAAM,8BAGV,GAEE,GACF,EAAK,aAAa,OAAQ,OAC1B,EAAK,aAAa,gBAAiB,OAAO,EAAM,SAAW,IAC3D,EAAK,SAAW,EAAM,SAAW,EAAK,GAAI,GACrC,EAAK,aAAa,eAAgB,OAAO,EAAM,SAAW,IACjE,EAAK,iBAAiB,cAAgB,IACpC,EAAM,iBACN,EAAY,EAAI,EAAM,CAAE,EAAG,EAAM,QAAS,EAAG,EAAM,YAErD,EAAK,iBAAiB,UAAY,IAChC,GAAkB,gBAAd,EAAM,KAA0B,EAAM,UAA0B,QAAd,EAAM,IAAgB,CAC1E,EAAM,iBACN,MAAM,EAAS,EAAK,wBACpB,EAAY,EAAI,EAAM,CAAE,EAAG,EAAO,KAAM,EAAG,EAAO,KACpD,MAAO,GAAI,GAAO,CAAC,YAAa,aAAc,OAAQ,OAAO,SAAS,EAAM,KAAM,CAChF,EAAM,iBACN,MAAM,EAAQ,EAAM,OAAO,MACrB,EAAQ,EAAM,UAAW,GAAS,EAAK,KAAO,GAC9C,EACU,SAAd,EAAM,IACF,EACc,QAAd,EAAM,IACJ,EAAM,OAAS,GACd,GAAuB,eAAd,EAAM,IAAuB,GAAI,GAAM,EAAM,QAAU,EAAM,OAC/E,IACA,EAAM,QAAQ,EAAM,GAAM,IAC1B,EAAS,cAAiC,2BAA2B,OACvE,IAEK,CACT,CACA,IAAI,GAAe,EACnB,SAAS,IACP,GAAI,EAAc,OAClB,GAAe,EACf,MAAM,EAAQ,GAAG,MAAO,gBACxB,IACE,MAAM,EAAO,IAAI,EAAS,iBAAoC,WAC9D,EAAM,MAAM,QACV,4EACF,MAAM,EAAU,EAAK,IAAK,IACxB,MAAM,EAAS,EAAI,WAAU,GAG7B,OAFA,EAAO,QAAS,EAChB,EAAO,MAAM,SAAW,GACjB,IAEH,EAAiB,EAAS,WAAU,GAC1C,EAAe,QAAS,EACxB,EAAM,UAAU,EAAS,GACzB,EAAG,OAAO,GACV,MAAM,EAAS,EAAQ,IAAK,GAAW,EAAO,wBAAwB,OAChE,EAAgB,EAAe,YACrC,EAAM,SACN,MAAM,EAAS,EAAO,OAAA,CAAQ,EAAK,IAAU,EAAM,EAAQ,EAAG,GAAK,EAAQ,YAAc,GACnF,EACJ,EAAS,YAAc,GAAY,UAC/B,EAAO,YAAc,GAAY,YAAc,GAC/C,EAAS,YACT,EAAM,KAAK,IAAI,EAAM,KACrB,EAAe,GAAU,EACzB,EAAa,EAAK,IAAA,KAAU,GAC5B,EAAU,EAAK,IAAA,IAAU,IAC/B,IAAK,EAAc,CACjB,IAAI,EAAY,KAAK,IAAI,GAAI,EAAM,EAAQ,YAAc,GAAK,EAAgB,GAC9E,MAAM,EAAW,EAAK,UAAW,GAA8C,SAAtC,EAAI,aAAa,kBAC1D,IAAK,MAAM,IAAS,CAClB,KACG,EAAK,IAAA,CAAK,EAAG,IAAU,GAAO,OAAQ,GAAU,IAAU,IAEzD,EAAQ,IACR,IAAU,GACZ,EAAQ,GAAS,GAAG,MACpB,GAAa,KAAK,IAAI,EAAW,EAAO,IAAU,IAElD,EAAW,GAAS,EAAO,GAAS,EAC/B,EAAW,KAAQ,GAAa,EAAO,GAAS,IAG3D,CACA,EAAS,OAAS,EAClB,EAAK,QAAA,CAAS,EAAK,KACjB,EAAI,OAAS,EAAW,GACxB,EAAI,MAAM,SAAW,EAAQ,IAEjC,CAAA,QACE,EAAM,SACN,GAAe,CACjB,CACF,CAUA,MAAM,EAAgB,IAAI,eAAe,GAKzC,SAAS,IACP,IACA,MAAM,EAAK,IACL,EAAQ,EAAM,OAAO,MAC3B,IAAI,EAAS,EAAM,OAAS,EAC5B,KAAO,EAAM,KAAM,GAAS,EAAK,OAAS,QAAQ,MAAW,IAC9C,EAAM,MACnB,CAAC,CAAE,GAAI,WAAY,KAAM,CAAE,KAAI,KAAM,QAAQ,IAAU,MAAO,MAC9D,CAAE,OAAQ,OAAQ,MAAO,aAEhB,IAAI,EAAM,QAAQ,EAC/B,CAfI,IACF,EAAc,QAAQ,GACtB,EAAO,KAAA,IAAW,EAAc,eA+BlC,MAAM,GAAc,GAAG,MAAO,mBACxB,GAAO,GAAG,MAAO,WACjB,GAAa,GACjB,OAAA,KAEE,MAAM,EAAQ,EAAQ,GAAY,iBAClC,IAAK,EAAO,OACZ,MAAM,EAAM,GAAG,MAAO,oBACtB,EAAI,OACF,GAAO,WAAY,QAAA,IAAgB,EAAM,KAAK,MAAQ,KACtD,GAAW,OAAA,IAAe,EAAM,KAAK,KAAO,EAAI,iBAChD,GAAO,UAAW,OAAA,IAAe,EAAM,KAAK,MAAQ,MAEtD,EAAM,OAAO,GACb,EAAY,EAAO,GAAY,KAEjC,iBAEF,GAAW,aAAa,aAAc,iBACtC,GAAW,aAAa,gBAAiB,QACzC,GAAW,aAAa,gBAAiB,SACzC,MAAM,GAAY,GAAO,cAAe,MAAA,IAAa,EAAM,KAAK,OA0ChE,SAAS,GAAW,GAClB,MAAgB,UAAT,EAAmB,iBAAmB,UAC/C,CACA,SAAS,GAAS,GAChB,GAAI,EAAM,UAAY,EAAM,SAAS,GAAK,OAC1C,MAAM,EAAO,EAAM,IAAI,GACvB,IAAK,GAAuB,UAAd,EAAK,MAAkC,SAAd,EAAK,KAAkB,OAC9D,MAAM,EAAsB,UAAd,EAAK,KACb,EAAI,EAAO,EAAQ,iBAAmB,YACtC,EAAQ,GAAG,SACjB,EAAM,KAAO,OACb,EAAM,UAAY,MAClB,EAAM,aAAa,eAAgB,OACnC,EAAM,YAAa,EACnB,EAAM,UAAY,IAClB,EAAM,MAAQ,EAAK,MAAQ,GAC3B,EAAM,aAAa,aAAc,EAAQ,YAAc,OACvD,MAAM,EAAQ,GAAG,IAAK,mBACtB,EAAM,aAAa,OAAQ,SAC3B,EAAM,QAAS,EACf,MAAM,EAAO,GACX,EAAQ,iBAAmB,WAAA,KAEzB,WACE,EAAK,UAAW,EAChB,MAAM,QAAe,EAAM,QAAQ,EAAI,EAAM,OAE7C,GADA,EAAK,UAAW,GACX,EAAO,GAAI,CACd,MAAM,EAAO,EAAO,OAAO,IAAI,KAU/B,OATA,EAAM,YACK,WAAT,GAA8B,aAAT,EAChB,EAAO,OAAO,IAAI,SAAW,yBAC9B,EACE,8BACA,sBACR,EAAM,QAAS,EACf,EAAM,aAAa,eAAgB,aACnC,EAAM,OAER,CACA,EAAE,OACJ,EAlBA,IAoBF,wBAEF,EAAE,OAAO,GAAM,EAAQ,YAAc,MAAO,GAAQ,EAAO,GAC3D,EAAM,iBAAiB,QAAA,KACrB,EAAM,QAAS,EACf,EAAM,gBAAgB,kBAExB,EAAM,iBAAiB,UAAY,IACf,UAAd,EAAM,KAAiB,EAAE,cAAiC,gBAAgB,UAEhF,EAAM,QACN,EAAM,QACR,CAhGA,GAAK,OAAO,GAAY,GAAW,EAAM,GACzC,GAAY,OAAO,IACf,EAAW,EAAO,OAAO,EAAU,IAClC,EAAO,OAAO,IACnB,EAAG,OAAO,GA6FV,IAAI,GAAiB,GACrB,SAAS,KACP,MAAM,EAAS,EAAM,UAAU,KAAM,GAAO,EAAM,SAAS,IAC3D,GAAmB,WAAf,EAAM,KAGR,OAFI,GAAkB,EAAU,SAAS,IAAiB,SAC1D,EAAU,QAAS,GAGrB,GACE,IACE,GACA,SAAS,yBAAyB,kBACF,UAAhC,SAAS,cAAc,OACtB,EAAU,SAAS,SAAS,gBAC3B,GAAe,SAAS,SAAS,gBAErC,OACF,MAAM,EAAU,EAAU,SAAS,SAAS,eACvC,SAAS,mBACV,EACE,EACJ,GAAkB,EAAU,SAAS,GACjC,CACE,MAAO,EAAe,aAAa,cACnC,QAAS,GAAe,SAAS,SAAS,qBAE5C,EACA,EACJ,GAAS,aAAa,gBAAkB,GAAY,QAAU,EAAW,WAAQ,GAC7E,EAAa,GAAS,QAAQ,UAAU,cAAc,oBAAoB,YAC5E,GAAY,IAChB,MAAM,EAAQ,EAAM,UAAU,IAAK,GAAO,EAAM,IAAI,IAAM,OAAO,SAC3D,EAAc,EAAM,IAAK,GAAS,EAAK,IAAI,KAAK,KAOtD,GANI,KAAmB,GACrB,IAEF,GAAiB,EACjB,EAAW,kBACX,EAAU,OAA0B,IAAjB,EAAM,QACpB,EAAM,OAET,YADI,GAAY,SAAS,EAAM,SAGjC,MAAM,EAAO,EAAM,GACjB,EAA0B,IAAjB,EAAM,OACX,EAAW,EAAM,MAAO,GAAM,CAAC,OAAQ,UAAW,UAAW,QAAQ,SAAS,EAAE,OAChF,EAAU,EAAM,MACnB,IAAO,CAAC,QAAS,OAAQ,QAAS,OAAQ,QAAS,OAAQ,QAAQ,SAAS,EAAE,OAE3E,EAAW,EAAM,MAAO,GAAiB,SAAX,EAAE,MAChC,EAAU,EAAM,MACnB,IAAO,CAAC,QAAS,OAAQ,OAAQ,QAAS,OAAQ,QAAS,QAAQ,SAAS,EAAE,OAE3E,EAAgB,GAAG,MAAO,qBAChC,SAAS,EAAa,EAAe,GACnC,MAAM,EACJ,EAAK,QAAQ,KAAiB,SAAR,EAAgC,SAAd,EAAK,KAAkB,OAAS,OAAU,OAC9E,EAAU,GACd,EAAA,KAEE,MAAM,EAAQ,EAAQ,EAAS,GAAG,WAClC,GAAK,EAAL,CACA,EAAM,UAAU,IAAI,oBACpB,IAAK,MAAO,EAAO,KAAS,GAAS,CACnC,MAAM,EAAI,GAAG,SAAU,cAAuB,SAAV,EAAmB,iBAAmB,KAC1E,EAAE,KAAO,SACT,EAAE,MAAM,YAAY,WAAY,EAAa,EAAO,EAAM,MAAM,gBAChE,EAAE,aAAa,aAAc,GAAG,MAAU,KAC1C,EAAE,MAAQ,EACV,EAAE,aAAa,eAAgB,OAAO,IAAY,IAClD,EAAE,QAAA,KACA,IACA,EAAM,aAAa,GAAO,EAC1B,EAAM,gBAAgB,CAAE,MAAO,CAAA,CAAG,GAAM,KACxC,EAAW,cAAiC,gBAAgB,QAAY,SAE1E,EAAM,OAAO,EACf,CACA,EAAY,EAAO,EAjBP,GAmBd,oBAEF,EAAQ,aAAa,aAAc,GACnC,EAAQ,aAAa,gBAAiB,QACtC,EAAQ,aAAa,gBAAiB,SACtC,MAAM,EAAS,GAAG,OAAQ,qBAAgC,SAAZ,EAAqB,iBAAmB,KACtF,EAAO,MAAM,YAAY,WAAY,EAAa,EAAS,EAAM,MAAM,gBACvE,EAAQ,QAAQ,GAChB,EAAc,OAAO,EACvB,CACI,GAAU,EAAa,OAAQ,QAC/B,GAAS,EAAa,OAAQ,UAC9B,GAAU,EAAa,QAAS,UACpC,MAAM,EAAgB,GACpB,UAAA,KAEE,MAAM,EAAQ,EAAQ,EAAe,oBACrC,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,sBACpB,MAAM,EAAQ,GAAG,SACjB,EAAM,KAAO,QACb,EAAM,aAAa,aAAc,WACjC,EAAM,IAAM,IACZ,EAAM,IAAM,MACZ,EAAM,MAAQ,OAAO,KAAK,MAAkD,KAA3C,EAAM,IAAI,EAAK,KAAK,OAAO,SAAW,KACvE,MAAM,EAAQ,GAAG,SAAU,GAAI,GAAG,EAAM,UAClC,EAAQ,GAAM,UAAW,GAC/B,EAAM,cAAc,mBAAoB,OAAO,GAC/C,IAAI,GAAQ,EACZ,EAAM,QAAA,KACJ,EAAM,YAAc,GAAG,EAAM,SAC7B,EAAM,MACJ,EAAM,IAAA,EAAO,SAAA,CACX,GAAI,MACJ,KACA,MAAO,CAAE,MAAO,CAAE,QAAS,OAAO,EAAM,OAAS,SAEnD,CAAE,OAAQ,OAAQ,MAAO,iBAAkB,OAAQ,IAErD,GAAQ,GAEV,EAAM,SAAA,KACJ,GAAQ,GAEV,EAAM,OAAO,GACb,EAAY,EAAO,GACnB,EAAM,SAER,oBAEF,EAAc,mBAAmB,aAAc,GAAK,YACpD,EAAc,aAAa,aAAc,WACzC,EAAc,aAAa,gBAAiB,QAC5C,EAAc,aAAa,gBAAiB,SACxC,EAAM,MAAO,GAAuB,UAAd,EAAK,OAAmB,EAAc,OAAO,GACnE,EAAc,mBAAmB,EAAW,OAAO,GACvD,MAAM,EAAc,GAClB,EAAM,MACJ,EAAM,IAAK,IAAA,CACT,GAAI,MACJ,GAAI,EAAK,GACT,MAAO,CAAE,KAAM,CAAE,MAAO,EAAK,MAAM,OAAS,MAAO,OAErD,CAAE,OAAQ,OAAQ,MAAO,eAE7B,SAAS,EAAS,GAChB,MAAM,EAAM,GAAG,MAAO,gBAChB,EAAQ,GAAG,MAAO,eAKxB,OAJA,EAAM,aAAa,OAAQ,SAC3B,EAAM,aAAa,aAAc,GACjC,EAAI,OAAO,GAAG,OAAQ,iBAAkB,GAAQ,GAChD,EAAW,OAAO,GACX,CACT,CACA,SAAS,EACP,EACA,EACA,EACA,GAEA,OAAO,EAAO,IAAA,EAAM,EAAO,EAAO,MAChC,MAAM,EAAI,GAAW,EAAA,IAAa,EAAO,GAAQ,cAMjD,OALA,EAAE,aAAa,aAAc,GAC7B,EAAE,MAAQ,EACV,EAAE,aAAa,eAAgB,OAAO,EAAM,MAAO,GAAS,EAAQ,KAAU,KAC9E,EAAE,UAAY,EACd,EAAM,OAAO,GACN,GAEX,CACA,SAAS,EAAS,EAAe,EAAO,IACtC,MAAO,kHAAkH,4BAAgC,EAAO,sBAAsB,KAAU,YAClM,CACA,GAAI,EAAS,CACX,EACE,EAAS,QACT,CACE,CAAC,IAAK,mBAAoB,KAC1B,CAAC,IAAK,oBAAqB,KAC3B,CAAC,IAAK,mBAAoB,KAC1B,CAAC,KAAM,yBAA0B,OAElC,IAAA,CAAY,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,GAAI,MAAQ,EAAS,EAAK,QAAU,IAC3E,GAAU,EAAW,CAAE,KAAM,KAEhC,EACE,EAAS,SACT,CACE,CAAC,QAAS,kBAAmB,GAAK,cAClC,CAAC,SAAU,oBAAqB,GAAK,gBACrC,CAAC,MAAO,mBAAoB,GAAK,gBAElC,GAAS,EAAK,MAAM,QAAwB,SAAd,EAAK,KAAkB,QAAU,UAC/D,GAAU,EAAW,CAAE,MAAO,KAEjC,MAAM,EAAsD,CAC1D,CAAC,OAAQ,iBAAkB,MAC3B,CAAC,QAAS,cAAe,MACzB,CAAC,OAAQ,aAAc,MACvB,CAAC,OAAQ,oBAAqB,OAEhC,EACE,EAAS,QACT,EACC,GAAS,EAAK,MAAM,MAAA,OACpB,GAAU,EAAW,CAAE,KAAM,KAC9B,QAAA,CAAS,EAAQ,KACjB,EAAO,MAAM,WAAa,EAAM,EAAY,GAAO,KAEvD,CAwDA,GAvDI,IACF,EACE,EAAS,QACT,CACE,CAAC,IAAK,aAAc,EAAS,IAC7B,CAAC,IAAK,gBAAiB,EAAS,IAChC,CAAC,IAAK,aAAc,EAAS,IAC7B,CAAC,IAAK,mBAAoB,EAAS,KAEpC,GAAS,OAAO,GAAS,EAAM,EAAM,MAAM,eAAe,aAC1D,GAAU,EAAM,gBAAgB,CAAE,MAAO,CAAE,YAAa,OAAO,OAE9D,EAAM,MAAO,GAAuB,SAAd,EAAK,MAAmB,EAAK,SACrD,EACE,EAAS,WACT,CACE,CAAC,QAAS,iBAAkB,EAAS,IACrC,CAAC,SAAU,kBAAmB,EAAS,EAAG,QAC1C,CAAC,SAAU,kBAAmB,EAAS,EAAG,SAE3C,GAAS,EAAK,OAAO,MAAQ,QAC7B,GAAU,EAAM,gBAAgB,CAAE,MAAO,CAAE,KAAM,OAIpD,GAAwB,cAAd,EAAK,MACjB,EAAW,OACT,GACE,QACA,GACE,CACE,CAAC,WAAY,YACb,CAAC,QAAS,SACV,CAAC,QAAS,UAEZ,EAAK,OAAS,QACb,GAAM,EAAM,gBAAgB,CAAE,MAAO,OAI1C,GAAwB,cAAd,EAAK,MACjB,EAAW,OACT,GACE,YACA,GACE,CACE,CAAC,QAAS,SACV,CAAC,MAAO,OACR,CAAC,OAAQ,SAEX,EAAK,OAAO,KAAO,QAClB,GAAU,EAAM,gBAAgB,CAAE,MAAO,IAAK,EAAK,MAAO,IAAK,QAIpE,IAAyB,UAAd,EAAK,MAAkC,SAAd,EAAK,MAAkB,CAC7D,MAAM,EAAQ,GAAW,EAAK,MACxB,EAAO,GAAW,EAAA,IAAa,GAAS,EAAK,IAAK,0BACxD,EAAK,aAAa,aAAc,GAChC,EAAW,OAAO,EACpB,CACA,MAAM,EAAO,GACX,EAAS,mBAAqB,iBAC9B,EAAS,OAAS,SAAA,IACZ,EAAM,gBAAgB,CAAE,QAAS,KAEzC,EAAK,aAAa,eAAgB,OAAO,IACzC,MAAM,EAAM,GAAG,MAAO,wBACtB,EAAI,OACF,GAAO,sBAAuB,OAAA,IAAc,EAAM,aAClD,GAAO,2BAA4B,QAAS,IAC5C,EACA,GAAO,mBAAoB,QAAA,IAAe,EAAM,oBAElD,EAAW,OAAO,IACd,EAAM,UAAY,IACpB,EACG,iBAAiB,uBACjB,QACE,GACE,EAAyB,SAAW,IAAM,IAAa,IAAM,GAAQ,EAAM,WAEjE,qBAAf,GAAoD,mBAAf,EAAiC,EAAK,QACvD,aAAf,EAA2B,EAAS,QACpC,EACP,EAAW,cAA2B,gBAAgB,IAAI,OAAO,SAAkB,QAC5E,GACP,IAAI,EAAW,iBAAiB,UAC7B,KAAM,GAAU,EAAM,cAAc,oBAAoB,cAAgB,IACvE,cAA2B,iBAC3B,SACF,GAAW,GAAY,YACrB,GAAW,EAAM,UAAa,EAAU,SAAS,SAAS,gBAAgB,EAAK,QACvF,CACA,SAAS,KACP,MAAM,EAAI,EAAO,0BACX,EAAU,GAAG,MAAO,kBAc1B,IAbwC,IAA3B,EAAM,UAAU,OAAe,EAAM,IAAI,EAAM,UAAU,SAAM,IAE1E,EAAQ,OACN,GAAW,YAAA,KACT,EAAM,YACN,EAAE,UAEJ,GAAW,SAAA,KACT,EAAM,kBACN,EAAE,WAIJ,EAAM,UAAU,OAAS,EAC3B,IAAK,MAAM,IAAQ,CACjB,OACA,SACA,QACA,MACA,SACA,SACA,aACA,YAEA,EAAQ,OACN,GACW,eAAT,GAAkC,aAAT,EAAsB,cAAc,IAAS,SAAS,IAAA,KAE7E,EAAM,MAAM,GACZ,EAAE,WAIR,EAAM,UAAU,OAAS,GAC3B,EAAQ,OACN,GAAW,QAAA,KACT,EAAM,QACN,EAAE,WAGJ,EAAM,UAAU,KAAM,GAA+B,UAAxB,EAAM,IAAI,IAAK,OAC9C,EAAQ,OACN,GAAW,UAAA,KACT,EAAM,UACN,EAAE,WAGR,EAAQ,OACN,GAAW,iBAAA,KACT,EAAM,MACJ,EAAM,UAAU,IAAK,IAAA,CAAU,GAAI,QAAS,KAAI,GAAI,WACpD,CAAE,OAAQ,OAAQ,MAAO,mBAE3B,EAAE,UAEJ,GAAW,eAAA,KACT,EAAM,MACJ,EAAM,UAAU,IAAK,IAAA,CAAU,GAAI,QAAS,KAAI,GAAI,UACpD,CAAE,OAAQ,OAAQ,MAAO,iBAE3B,EAAE,WAGF,EAAM,UACR,EAAQ,iBAAiB,UAAU,QAAS,GAAY,EAAO,UAAW,GAC5E,EAAE,OAAO,EACX,CAoFA,SAAS,GAAW,GAClB,EACG,OAAO,EAAQ,CACd,MAAO,OACP,QAAS,GACT,YAAY,KACG,QAAX,EAAmB,CAAE,MAAO,GAAM,CAAC,IAExC,KAAM,KA7kCb,SAAkB,EAAwB,EAAc,GACtD,MAAM,EAAM,IAAI,gBACK,iBAAZ,EAAuB,IAAI,KAAK,CAAC,GAAU,CAAE,SAAU,GAE1D,EAAO,GAAG,KAChB,EAAK,KAAO,EACZ,EAAK,SAAW,EAChB,EAAK,QACL,WAAA,IAAiB,IAAI,gBAAgB,GAAM,IAC7C,CA0kCQ,CACE,EACA,GANA,EACG,OACA,KAAK,MAAM,QAAQ,iBAAkB,IACrC,QAAU,aAGS,SAAX,EAAoB,QAAU,IAC9B,SAAX,EAAoB,GAAwB,QAAX,EAAmB,gBAAkB,eAGzE,MAAA,OACL,CAwEA,SAAS,KACP,EAAK,UAAY,EAAM,QACvB,EAAK,UAAY,EAAM,QA1sBzB,WACE,IAAK,EAAW,OAChB,MAAM,EAAQ,EAAM,OAAO,MACrB,EAAQ,KAAK,UAAU,CAAC,EAAM,OAAQ,EAAM,IAAA,EAAO,KAAI,UAAW,CAAC,EAAI,MACzE,IAAU,IACd,EAAY,EACZ,EAAS,mBAAmB,EAAM,IAAK,GAAS,EAAW,EAAK,GAAI,EAAK,MAAM,KAC/E,IACF,CAmsBE,GACA,IACF,CACA,MAAM,GAAW,IACf,MAAM,EAAE,EAAA,EAAG,EAAA,GAAG,GAAQ,EAA+C,OAC/D,EAAO,EAAK,EAAM,IAAI,QAAM,EAClC,IAAK,EAEH,YADA,IAGF,MAAM,EAAS,EAAM,MAAM,KAAK,wBAC1B,EAAO,EAAY,kBAAmB,CAAE,EAAG,EAAO,KAAO,EAAG,EAAG,EAAO,IAAM,IAC5E,EAAS,EAAM,SAAS,EAAK,IACjB,UAAd,EAAK,MAAkC,SAAd,EAAK,MAChC,EAAK,IAAI,GAAW,EAAK,MAAO,OAAA,IAAc,GAAS,EAAK,IAAK,GAC9D,CAAC,QAAS,OAAQ,OAAQ,QAAS,OAAQ,QAAS,QAAQ,SAAS,EAAK,OAC7E,EAAK,IAAI,YAAa,OAAA,IAAc,EAAM,SAAS,EAAK,IAAK,GAC/D,MAAM,EAAS,GACb,EAAM,MAAM,CAAC,CAAE,GAAI,QAAS,GAAI,EAAK,GAAI,OAAO,CAC9C,OAAQ,OACR,MAAc,UAAP,EAAiB,iBAAmB,iBAE/C,EAAK,IAAI,iBAAkB,QAAA,IAAe,EAAM,SAAU,GAC1D,EAAK,IAAI,eAAgB,OAAA,IAAc,EAAM,QAAS,GACtD,EAAK,IACH,YACA,OAAA,KAEE,EAAM,OAAO,CAAC,EAAK,KACnB,EAAM,aAER,GAEF,MAAM,EAAY,GAAG,MAAO,qBAC5B,EAAU,aAAa,OAAQ,aAC/B,EAAK,MAAM,OAAO,GAClB,EAAK,IACH,SACA,QAAA,KAEE,EAAM,OAAO,CAAC,EAAK,KACnB,EAAM,mBAER,GAEF,EAAK,QAsBP,OApBA,EAAM,KAAK,iBAAiB,aAAc,IAC1C,EAAO,KACL,EAAM,GAAG,SAAU,IACnB,EAAM,GAAG,SAAA,KACP,OAEF,EAAM,GAAG,OAAQ,IACjB,EAAM,GAAG,OAAS,IACe,WAA3B,GAAe,SAAsB,IACzC,GAAW,YAAc,GAAG,KAAK,MAAmB,IAAb,EAAM,WAE/C,EAAM,GAAG,OAAS,IAChB,IAAK,MAAM,KAAK,EAAG,iBAA8B,eAC/C,EAAE,aAAa,eAAgB,OAAO,IAAO,EAAE,QAAQ,OACzD,EAAY,aAAa,eAAgB,OAAO,EAAW,SAAS,KACpE,EAAM,MAAM,KAAK,QAAQ,OAAS,EAClC,QAGJ,KACA,KACE,aAAa,GACb,IACA,EAAO,QAAS,GAAO,KACvB,GAAc,QACd,EAAM,KAAK,oBAAoB,aAAc,IAC7C,EAAG,SAEP"}
@@ -1,2 +1,2 @@
1
- import{c as e}from"./picker-DZpEpkED.js";import{h as t,u as i}from"./defaults-C-aC_B4z.js";import{a as n,c as a,i as r,t as o}from"./paste-B8nZA2Gh.js";function s(e,t,n,a){const[r,o]=a??i(t),s=n??e.view.center;let d=s.x-r/2,c=s.y-o/2;if(!n)for(;e.items.some(e=>Math.abs(e.x-d)<4&&Math.abs(e.y-c)<4);)d+=24,c+=24;return{x:d,y:c,w:r,h:o}}function d(e,t,i,a){const r="link"===t?n(i):void 0,o=e.apply([{op:"add",page:e.pageId,item:{kind:t,href:i,...s(e,t,a),...r?{name:r.host,description:r.description,text:{value:r.title,font:"sans"}}:{}}}],{origin:"user",label:"video"===t?"Paste video":"Paste link"});o.ok&&(e.select(o.created),"link"===t&&o.created[0]&&c(e,o.created[0],i))}async function c(e,i,n,o="Paste link"){if(!1!==e.unfurl)try{const s=await(e.unfurl??a)(n);if(!s||e.destroyed||!e.get(i))return;const d=[],c={};if(s.title&&(c.text={value:s.title,font:"sans"}),s.image){const e=t();d.push({op:"media.set",id:e,media:{src:s.image,mime:r(s.image),w:1200,h:630}}),c.media=e}Object.keys(c).length&&d.push({op:"set",id:i,patch:c}),d.length&&e.apply(d,{origin:"user",label:o,merge:!0})}catch{}}function l(e){return{ok:!1,created:[],errors:[{index:0,code:"INVALID_OP",message:e}],warnings:[]}}function m(e,t,i){const a=e.get(t);if(!a||"video"!==a.kind&&"link"!==a.kind)return l(`Item ${t} is not a video or link.`);const r=o(i),s="text"===r.kind?void 0:r.href;if(!s||s.startsWith("data:"))return l("video"===a.kind?`Bad video (${t}).`:`Bad href (${t}).`);if("video"===a.kind&&"video"!==r.kind)return l(`Bad video (${t}).`);if(s===a.href)return{ok:!0,created:[],errors:[],warnings:[]};const d="link"===a.kind?n(s):void 0,m="video"===a.kind?"Edit video URL":"Edit URL",u=e.apply([{op:"set",id:t,patch:{href:s,...d?{name:d.host,description:d.description,text:{value:d.title,font:"sans"},media:void 0}:{}}}],{origin:"user",label:m});return u.ok&&"link"===a.kind&&c(e,t,s,m),u}async function u(i,n,a){try{const[o,d]=await function(e){return new Promise((t,i)=>{const n=new Image,a=e=>{clearTimeout(r),n.onload=n.onerror=null,e&&n.naturalWidth?t([n.naturalWidth,n.naturalHeight]):i(/* @__PURE__ */new Error("image"))},r=setTimeout(()=>a(!!n.naturalWidth),2500);n.onload=()=>a(!0),n.onerror=()=>a(!1),n.src=e})}(n),c=Math.min(1,480/o,360/d),l=t(),m=i.apply([{op:"media.set",id:l,media:{src:n,mime:r(n),w:o,h:d}},{op:"add",page:i.pageId,item:{kind:"image",...s(i,"image",a,[o*c,d*c]),media:l,name:e(n)}}],{origin:"user",label:"Paste image"});m.ok&&i.select(m.created)}catch{d(i,"link",n,a)}}function p(e,t,i){const n=o(t);if("video"===n.kind||"link"===n.kind)d(e,n.kind,n.href,i);else if("image"===n.kind)u(e,n.href,i).catch(t=>function(e,t){e.host.dispatchEvent(new CustomEvent("ad-error",{detail:String(t)}))}(e,t));else{const n=i??e.view.center,a=e.apply([{op:"add",page:e.pageId,item:{kind:"text",x:n.x,y:n.y,w:300,h:100,text:{value:t,size:"m"}}}],{origin:"user",label:"Paste text"});a.ok&&e.select(a.created)}}export{p as pastePlain,m as updateHref};
2
- //# sourceMappingURL=urlPaste-Oc4kZ0P7.js.map
1
+ import{c as e}from"./picker-ciuPQvRn.js";import{h as t,u as i}from"./defaults-DZEoAeRz.js";import{a as n,c as a,i as r,t as o}from"./paste-B4b0C9Jh.js";function s(e,t,n,a){const[r,o]=a??i(t),s=n??e.view.center;let d=s.x-r/2,c=s.y-o/2;if(!n)for(;e.items.some(e=>Math.abs(e.x-d)<4&&Math.abs(e.y-c)<4);)d+=24,c+=24;return{x:d,y:c,w:r,h:o}}function d(e,t,i,a){const r="link"===t?n(i):void 0,o=e.apply([{op:"add",page:e.pageId,item:{kind:t,href:i,...s(e,t,a),...r?{name:r.host,description:r.description,text:{value:r.title,font:"sans"}}:{}}}],{origin:"user",label:"video"===t?"Paste video":"Paste link"});o.ok&&(e.select(o.created),"link"===t&&o.created[0]&&c(e,o.created[0],i))}async function c(e,i,n,o="Paste link"){if(!1!==e.unfurl)try{const s=await(e.unfurl??a)(n);if(!s||e.destroyed||!e.get(i))return;const d=[],c={};if(s.title&&(c.text={value:s.title,font:"sans"}),s.image){const e=t();d.push({op:"media.set",id:e,media:{src:s.image,mime:r(s.image),w:1200,h:630}}),c.media=e}Object.keys(c).length&&d.push({op:"set",id:i,patch:c}),d.length&&e.apply(d,{origin:"user",label:o,merge:!0})}catch{}}function l(e){return{ok:!1,created:[],errors:[{index:0,code:"INVALID_OP",message:e}],warnings:[]}}function m(e,t,i){const a=e.get(t);if(!a||"video"!==a.kind&&"link"!==a.kind)return l(`Item ${t} is not a video or link.`);const r=o(i),s="text"===r.kind?void 0:r.href;if(!s||s.startsWith("data:"))return l("video"===a.kind?`Bad video (${t}).`:`Bad href (${t}).`);if("video"===a.kind&&"video"!==r.kind)return l(`Bad video (${t}).`);if(s===a.href)return{ok:!0,created:[],errors:[],warnings:[]};const d="link"===a.kind?n(s):void 0,m="video"===a.kind?"Edit video URL":"Edit URL",u=e.apply([{op:"set",id:t,patch:{href:s,...d?{name:d.host,description:d.description,text:{value:d.title,font:"sans"},media:void 0}:{}}}],{origin:"user",label:m});return u.ok&&"link"===a.kind&&c(e,t,s,m),u}async function u(i,n,a){try{const[o,d]=await function(e){return new Promise((t,i)=>{const n=new Image,a=e=>{clearTimeout(r),n.onload=n.onerror=null,e&&n.naturalWidth?t([n.naturalWidth,n.naturalHeight]):i(/* @__PURE__ */new Error("image"))},r=setTimeout(()=>a(!!n.naturalWidth),2500);n.onload=()=>a(!0),n.onerror=()=>a(!1),n.src=e})}(n),c=Math.min(1,480/o,360/d),l=t(),m=i.apply([{op:"media.set",id:l,media:{src:n,mime:r(n),w:o,h:d}},{op:"add",page:i.pageId,item:{kind:"image",...s(i,"image",a,[o*c,d*c]),media:l,name:e(n)}}],{origin:"user",label:"Paste image"});m.ok&&i.select(m.created)}catch{d(i,"link",n,a)}}function p(e,t,i){const n=o(t);if("video"===n.kind||"link"===n.kind)d(e,n.kind,n.href,i);else if("image"===n.kind)u(e,n.href,i).catch(t=>function(e,t){e.host.dispatchEvent(new CustomEvent("ad-error",{detail:String(t)}))}(e,t));else{const n=i??e.view.center,a=e.apply([{op:"add",page:e.pageId,item:{kind:"text",x:n.x,y:n.y,w:300,h:100,text:{value:t,size:"m"}}}],{origin:"user",label:"Paste text"});a.ok&&e.select(a.created)}}export{p as pastePlain,m as updateHref};
2
+ //# sourceMappingURL=urlPaste-BqcpeQ-c.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"urlPaste-Oc4kZ0P7.js","names":[],"sources":["../../src/input/urlPaste.ts"],"sourcesContent":["import { sizeOf } from '../core/defaults';\nimport { mediaId } from '../core/ids';\nimport { hostnameOf, type LinkPreview } from '../core/links';\nimport { classifyPaste, imageMime, linkFallback, unfurlPage } from '../core/paste';\nimport type { ApplyOptions, ApplyResult, Item, Op, Point } from '../core/types';\n\nexport interface PasteHost {\n pageId: string;\n items: Item[];\n destroyed: boolean;\n unfurl?: false | ((url: string) => Promise<LinkPreview | undefined>);\n view: { center: Point };\n host: HTMLElement;\n apply(ops: Op[], options?: ApplyOptions): ApplyResult;\n select(ids: string[]): void;\n get(id: string): Item | undefined;\n}\n\nfunction place(\n host: PasteHost,\n kind: 'video' | 'link' | 'image',\n point?: Point,\n size?: [number, number],\n) {\n const [w, h] = size ?? sizeOf(kind);\n const p = point ?? host.view.center;\n let x = p.x - w / 2,\n y = p.y - h / 2;\n if (!point)\n while (host.items.some((item) => Math.abs(item.x - x) < 4 && Math.abs(item.y - y) < 4)) {\n x += 24;\n y += 24;\n }\n return { x, y, w, h };\n}\n\nfunction fail(host: PasteHost, error: unknown) {\n host.host.dispatchEvent(new CustomEvent('ad-error', { detail: String(error) }));\n}\n\nfunction addHref(host: PasteHost, kind: 'video' | 'link', href: string, point?: Point) {\n const preview = kind === 'link' ? linkFallback(href) : undefined;\n const result = host.apply(\n [\n {\n op: 'add',\n page: host.pageId,\n item: {\n kind,\n href,\n ...place(host, kind, point),\n ...(preview\n ? {\n name: preview.host,\n description: preview.description,\n text: { value: preview.title, font: 'sans' as const },\n }\n : {}),\n },\n },\n ],\n { origin: 'user', label: kind === 'video' ? 'Paste video' : 'Paste link' },\n );\n if (result.ok) {\n host.select(result.created);\n if (kind === 'link' && result.created[0]) void enrich(host, result.created[0], href);\n }\n}\n\nasync function enrich(host: PasteHost, id: string, href: string, label = 'Paste link') {\n if (host.unfurl === false) return;\n try {\n const preview = await (host.unfurl ?? unfurlPage)(href);\n if (!preview || host.destroyed || !host.get(id)) return;\n const ops: Op[] = [];\n const patch: Partial<Item> = {};\n if (preview.title) patch.text = { value: preview.title, font: 'sans' };\n if (preview.image) {\n const mid = mediaId();\n ops.push({\n op: 'media.set',\n id: mid,\n media: { src: preview.image, mime: imageMime(preview.image), w: 1200, h: 630 },\n });\n patch.media = mid;\n }\n if (Object.keys(patch).length) ops.push({ op: 'set', id, patch });\n if (ops.length) host.apply(ops, { origin: 'user', label, merge: true });\n } catch {\n /* Keep the hostname card when the page cannot be read. */\n }\n}\n\nfunction reject(message: string): ApplyResult {\n return {\n ok: false,\n created: [],\n errors: [{ index: 0, code: 'INVALID_OP', message }],\n warnings: [],\n };\n}\n\n/** Replace the href on an existing video or link item. */\nexport function updateHref(host: PasteHost, id: string, value: string): ApplyResult {\n const item = host.get(id);\n if (!item || (item.kind !== 'video' && item.kind !== 'link'))\n return reject(`Item ${id} is not a video or link.`);\n const pasted = classifyPaste(value);\n const href = pasted.kind === 'text' ? undefined : pasted.href;\n if (!href || href.startsWith('data:'))\n return reject(item.kind === 'video' ? `Bad video (${id}).` : `Bad href (${id}).`);\n if (item.kind === 'video' && pasted.kind !== 'video') return reject(`Bad video (${id}).`);\n if (href === item.href) return { ok: true, created: [], errors: [], warnings: [] };\n const preview = item.kind === 'link' ? linkFallback(href) : undefined;\n const label = item.kind === 'video' ? 'Edit video URL' : 'Edit URL';\n const result = host.apply(\n [\n {\n op: 'set',\n id,\n patch: {\n href,\n ...(preview\n ? {\n name: preview.host,\n description: preview.description,\n text: { value: preview.title, font: 'sans' as const },\n media: undefined,\n }\n : {}),\n },\n },\n ],\n { origin: 'user', label },\n );\n if (result.ok && item.kind === 'link') void enrich(host, id, href, label);\n return result;\n}\n\nfunction readImageSize(src: string): Promise<[number, number]> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n const done = (ok: boolean) => {\n clearTimeout(timer);\n image.onload = image.onerror = null;\n if (ok && image.naturalWidth) resolve([image.naturalWidth, image.naturalHeight]);\n else reject(new Error('image'));\n };\n const timer = setTimeout(() => done(!!image.naturalWidth), 2500);\n image.onload = () => done(true);\n image.onerror = () => done(false);\n image.src = src;\n });\n}\n\nasync function addRemoteImage(host: PasteHost, src: string, point?: Point) {\n try {\n const [width, height] = await readImageSize(src);\n const scale = Math.min(1, 480 / width, 360 / height),\n id = mediaId();\n const result = host.apply(\n [\n {\n op: 'media.set',\n id,\n media: { src, mime: imageMime(src), w: width, h: height },\n },\n {\n op: 'add',\n page: host.pageId,\n item: {\n kind: 'image',\n ...place(host, 'image', point, [width * scale, height * scale]),\n media: id,\n name: hostnameOf(src),\n },\n },\n ],\n { origin: 'user', label: 'Paste image' },\n );\n if (result.ok) host.select(result.created);\n } catch {\n addHref(host, 'link', src, point);\n }\n}\n\nexport function pastePlain(host: PasteHost, value: string, point?: Point) {\n const pasted = classifyPaste(value);\n if (pasted.kind === 'video' || pasted.kind === 'link')\n addHref(host, pasted.kind, pasted.href, point);\n else if (pasted.kind === 'image')\n void addRemoteImage(host, pasted.href, point).catch((error) => fail(host, error));\n else {\n const p = point ?? host.view.center;\n const result = host.apply(\n [\n {\n op: 'add',\n page: host.pageId,\n item: { kind: 'text', x: p.x, y: p.y, w: 300, h: 100, text: { value, size: 'm' } },\n },\n ],\n { origin: 'user', label: 'Paste text' },\n );\n if (result.ok) host.select(result.created);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"urlPaste-BqcpeQ-c.js","names":[],"sources":["../../src/input/urlPaste.ts"],"sourcesContent":["import { sizeOf } from '../core/defaults';\nimport { mediaId } from '../core/ids';\nimport { hostnameOf, type LinkPreview } from '../core/links';\nimport { classifyPaste, imageMime, linkFallback, unfurlPage } from '../core/paste';\nimport type { ApplyOptions, ApplyResult, Item, Op, Point } from '../core/types';\n\nexport interface PasteHost {\n pageId: string;\n items: Item[];\n destroyed: boolean;\n unfurl?: false | ((url: string) => Promise<LinkPreview | undefined>);\n view: { center: Point };\n host: HTMLElement;\n apply(ops: Op[], options?: ApplyOptions): ApplyResult;\n select(ids: string[]): void;\n get(id: string): Item | undefined;\n}\n\nfunction place(\n host: PasteHost,\n kind: 'video' | 'link' | 'image',\n point?: Point,\n size?: [number, number],\n) {\n const [w, h] = size ?? sizeOf(kind);\n const p = point ?? host.view.center;\n let x = p.x - w / 2,\n y = p.y - h / 2;\n if (!point)\n while (host.items.some((item) => Math.abs(item.x - x) < 4 && Math.abs(item.y - y) < 4)) {\n x += 24;\n y += 24;\n }\n return { x, y, w, h };\n}\n\nfunction fail(host: PasteHost, error: unknown) {\n host.host.dispatchEvent(new CustomEvent('ad-error', { detail: String(error) }));\n}\n\nfunction addHref(host: PasteHost, kind: 'video' | 'link', href: string, point?: Point) {\n const preview = kind === 'link' ? linkFallback(href) : undefined;\n const result = host.apply(\n [\n {\n op: 'add',\n page: host.pageId,\n item: {\n kind,\n href,\n ...place(host, kind, point),\n ...(preview\n ? {\n name: preview.host,\n description: preview.description,\n text: { value: preview.title, font: 'sans' as const },\n }\n : {}),\n },\n },\n ],\n { origin: 'user', label: kind === 'video' ? 'Paste video' : 'Paste link' },\n );\n if (result.ok) {\n host.select(result.created);\n if (kind === 'link' && result.created[0]) void enrich(host, result.created[0], href);\n }\n}\n\nasync function enrich(host: PasteHost, id: string, href: string, label = 'Paste link') {\n if (host.unfurl === false) return;\n try {\n const preview = await (host.unfurl ?? unfurlPage)(href);\n if (!preview || host.destroyed || !host.get(id)) return;\n const ops: Op[] = [];\n const patch: Partial<Item> = {};\n if (preview.title) patch.text = { value: preview.title, font: 'sans' };\n if (preview.image) {\n const mid = mediaId();\n ops.push({\n op: 'media.set',\n id: mid,\n media: { src: preview.image, mime: imageMime(preview.image), w: 1200, h: 630 },\n });\n patch.media = mid;\n }\n if (Object.keys(patch).length) ops.push({ op: 'set', id, patch });\n if (ops.length) host.apply(ops, { origin: 'user', label, merge: true });\n } catch {\n /* Keep the hostname card when the page cannot be read. */\n }\n}\n\nfunction reject(message: string): ApplyResult {\n return {\n ok: false,\n created: [],\n errors: [{ index: 0, code: 'INVALID_OP', message }],\n warnings: [],\n };\n}\n\n/** Replace the href on an existing video or link item. */\nexport function updateHref(host: PasteHost, id: string, value: string): ApplyResult {\n const item = host.get(id);\n if (!item || (item.kind !== 'video' && item.kind !== 'link'))\n return reject(`Item ${id} is not a video or link.`);\n const pasted = classifyPaste(value);\n const href = pasted.kind === 'text' ? undefined : pasted.href;\n if (!href || href.startsWith('data:'))\n return reject(item.kind === 'video' ? `Bad video (${id}).` : `Bad href (${id}).`);\n if (item.kind === 'video' && pasted.kind !== 'video') return reject(`Bad video (${id}).`);\n if (href === item.href) return { ok: true, created: [], errors: [], warnings: [] };\n const preview = item.kind === 'link' ? linkFallback(href) : undefined;\n const label = item.kind === 'video' ? 'Edit video URL' : 'Edit URL';\n const result = host.apply(\n [\n {\n op: 'set',\n id,\n patch: {\n href,\n ...(preview\n ? {\n name: preview.host,\n description: preview.description,\n text: { value: preview.title, font: 'sans' as const },\n media: undefined,\n }\n : {}),\n },\n },\n ],\n { origin: 'user', label },\n );\n if (result.ok && item.kind === 'link') void enrich(host, id, href, label);\n return result;\n}\n\nfunction readImageSize(src: string): Promise<[number, number]> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n const done = (ok: boolean) => {\n clearTimeout(timer);\n image.onload = image.onerror = null;\n if (ok && image.naturalWidth) resolve([image.naturalWidth, image.naturalHeight]);\n else reject(new Error('image'));\n };\n const timer = setTimeout(() => done(!!image.naturalWidth), 2500);\n image.onload = () => done(true);\n image.onerror = () => done(false);\n image.src = src;\n });\n}\n\nasync function addRemoteImage(host: PasteHost, src: string, point?: Point) {\n try {\n const [width, height] = await readImageSize(src);\n const scale = Math.min(1, 480 / width, 360 / height),\n id = mediaId();\n const result = host.apply(\n [\n {\n op: 'media.set',\n id,\n media: { src, mime: imageMime(src), w: width, h: height },\n },\n {\n op: 'add',\n page: host.pageId,\n item: {\n kind: 'image',\n ...place(host, 'image', point, [width * scale, height * scale]),\n media: id,\n name: hostnameOf(src),\n },\n },\n ],\n { origin: 'user', label: 'Paste image' },\n );\n if (result.ok) host.select(result.created);\n } catch {\n addHref(host, 'link', src, point);\n }\n}\n\nexport function pastePlain(host: PasteHost, value: string, point?: Point) {\n const pasted = classifyPaste(value);\n if (pasted.kind === 'video' || pasted.kind === 'link')\n addHref(host, pasted.kind, pasted.href, point);\n else if (pasted.kind === 'image')\n void addRemoteImage(host, pasted.href, point).catch((error) => fail(host, error));\n else {\n const p = point ?? host.view.center;\n const result = host.apply(\n [\n {\n op: 'add',\n page: host.pageId,\n item: { kind: 'text', x: p.x, y: p.y, w: 300, h: 100, text: { value, size: 'm' } },\n },\n ],\n { origin: 'user', label: 'Paste text' },\n );\n if (result.ok) host.select(result.created);\n }\n}\n"],"mappings":"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"}
package/dist/style.css CHANGED
@@ -1,2 +1,2 @@
1
- .ad-root{isolation:isolate;touch-action:none;--ad-cs:drop-shadow(0 8px 18px #1036391f);background:var(--ad-paper,#fbfcfa);width:100%;height:100%;color:var(--ad-ink,#103639);-webkit-user-select:none;user-select:none;outline:none;font-family:Nunito Variable,Nunito,ui-rounded,system-ui,sans-serif;position:relative;overflow:hidden}.ad-root[data-theme=dark]{--ad-paper:#122f32;--ad-ink:#e9f7f3;--ad-grid-color:#426160;--ad-focus:#05d9ab}.ad-grid,.ad-world,.ad-overlay{transform-origin:0 0;position:absolute;inset:0}.ad-grid{pointer-events:none;background-image:radial-gradient(circle, var(--ad-grid-color,#dce6df) 1px, transparent 1px);background-size:24px 24px}.ad-world{contain:layout style;width:0;height:0;overflow:visible}.ad-item{transform-origin:50%;box-sizing:border-box;outline:none;position:absolute;top:0;left:0;overflow:visible}.ad-item:focus-visible{outline:2px solid var(--ad-focus,#007d65);outline-offset:6px}.ad-agent-pending{visibility:hidden;pointer-events:none}.ad-agent-cursor{z-index:4;pointer-events:none;transform-origin:7px 7px;will-change:transform;width:36px;height:36px;position:absolute;top:0;left:0}.ad-agent-cursor svg{transform-origin:7px 7px;fill:#8f93f9;stroke:#fff;stroke-width:2px;stroke-linejoin:round;filter:drop-shadow(0 2px 4px #10363926);display:block}.ad-agent-cursor span{color:#103639;white-space:nowrap;background:#8f93f9;border-radius:9px;padding:3px 8px;font-size:11px;font-weight:800;line-height:16px;position:absolute;top:26px;left:25px}.ad-root[data-theme=dark] .ad-agent-cursor svg{filter:none;stroke:#122f32}.ad-shape{pointer-events:none;display:block;position:absolute;top:0;left:0;overflow:visible}.ad-text{box-sizing:border-box;white-space:pre-wrap;overflow-wrap:anywhere;word-break:normal;pointer-events:none;flex-direction:column;padding:12px;font-family:Comic Sans MS,Chalkboard SE,cursive;line-height:1.35;display:flex;position:absolute;inset:0}.ad-item[data-ad-kind=diamond] .ad-text{padding:20%}.ad-item[data-ad-kind=ellipse] .ad-text{padding:15%}.ad-item[data-ad-kind=text] .ad-text{padding:0}.ad-item[data-ad-kind=note] .ad-text{padding:20px;line-height:1.5}.ad-item[data-ad-kind=note] .ad-shape{filter:var(--ad-cs)}.ad-item[data-ad-kind=connector] .ad-text{border-radius:5px;width:max-content;max-width:240px;height:auto;padding:3px 8px;font-size:14px;line-height:1.25;bottom:auto;right:auto;transform:translate(-50%,-50%)}.ad-text[contenteditable=plaintext-only],.ad-text[contenteditable=true]{pointer-events:auto;-webkit-user-select:text;user-select:text;cursor:text;background:#fffc;border-radius:4px;outline:2px solid #05d9ab;min-width:20px}.ad-auxiliary{pointer-events:none;position:absolute;inset:0}.ad-auxiliary img{object-fit:fill;pointer-events:none;width:100%;height:100%;position:absolute}.ad-card{filter:var(--ad-cs);border-radius:12px;overflow:hidden}.ad-html-content{white-space:pre-wrap;box-sizing:border-box;border:1px solid #d9e3df;border-radius:8px;padding:12px;overflow:auto}.ad-item[data-ad-interactive=true] .ad-html-content{pointer-events:auto;-webkit-user-select:text;user-select:text}.ad-placeholder{box-sizing:border-box;text-align:center;background:#8f93f912;border:1.5px dashed #8f93f9;border-radius:8px;justify-content:center;align-items:center;gap:8px;width:100%;height:100%;padding:8px;font-size:13px;display:flex}.ad-overlay{pointer-events:none;width:100%;height:100%;overflow:visible}.ad-selection-outline{fill:none;stroke:var(--ad-focus,#00876c);stroke-width:1.4px;vector-effect:non-scaling-stroke}.ad-selection-handle{fill:var(--ad-paper,#fff);stroke:var(--ad-focus,#00876c);stroke-width:1.5px;pointer-events:all}.ad-selection-handle:hover{fill:#aaf1ac}.ad-marquee{fill:#05d9ab16;stroke:#00876c;stroke-width:1px}.ad-no-grid .ad-grid{display:none}.ad-custom-handle{fill:#05d9ab;stroke:#103639}.ad-root *{box-sizing:inherit}.ad-root :is(button,input,select,textarea){font:inherit}.ad-root button{cursor:pointer}.ad-root button:disabled,.ad-root :is(input,select):disabled{opacity:.38;cursor:not-allowed}.ad-root :is(button,input,select,textarea,a,summary){-webkit-tap-highlight-color:transparent}.ad-root :focus-visible{outline-offset:3px;outline:3px solid #05b48f}.ad-root button:focus:not(:focus-visible){outline:none}.ad-root{box-sizing:border-box;--ad-font-sans:"Nunito Variable", "Nunito", "Trebuchet MS", sans-serif;--ad-font-hand:"Comic Sans MS", "Chalkboard SE", cursive;--ad-ui-bg:#fff;--ad-ui-surface:#f3f8f5;--ad-ui-border:#10363912;--ad-ui-text:#103639;--ad-ui-muted:#5e716b;--ad-ui-accent:#05d9ab;--ad-shadow:0 4px 20px #10363907, 0 1px 3px #10363905;font-family:var(--ad-font-sans);color:var(--ad-ui-text);isolation:isolate;container:board/size;background:#fcfdfb!important}.ad-root[data-theme=dark]{--ad-ui-bg:#193638;--ad-ui-surface:#214447;--ad-ui-border:#ffffff16;--ad-ui-text:#ecf8f2;--ad-ui-muted:#bacfc7;--ad-shadow:none;background:#10282b!important}.ad-ui{z-index:5;pointer-events:none;--ad-inset:24px;--ad-edge:20px;--ad-tool:44px;--ad-tool-pad:7px;--ad-tool-gap:4px;--ad-tool-icon:24px;--ad-ctrl:38px;--ad-ctrl-icon:20px;--ad-panel-pad:14px;--ad-dock-clearance:174px;font-size:13px;line-height:1.4;position:absolute;inset:0}.ad-ui>*{pointer-events:auto}.ad-ui svg{flex-shrink:0;width:24px;height:24px}.ad-header{left:max(var(--ad-inset), env(safe-area-inset-left,0px));right:max(var(--ad-inset), env(safe-area-inset-right,0px));top:max(var(--ad-edge), env(safe-area-inset-top,0px));pointer-events:none;justify-content:space-between;align-items:center;gap:16px;min-width:0;display:flex;position:absolute}.ad-header>*{pointer-events:auto}.ad-header-end{justify-content:flex-end}.ad-brand{color:var(--ad-ui-text);background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);box-shadow:var(--ad-shadow);border-radius:16px;align-items:center;gap:9px;padding:6px 10px 6px 6px;display:flex}.ad-brand:hover{background:var(--ad-ui-surface)}.ad-brand>svg{width:16px;height:16px;color:var(--ad-ui-muted);margin-left:3px}.ad-brand-mark{color:#103639;background:#05d9ab;border-radius:11px;place-items:center;width:32px;height:32px;display:grid}.ad-brand-mark svg{width:28px;height:28px}.ad-brand-name{letter-spacing:-.55px;white-space:nowrap;font-size:16px;font-weight:800}.ad-header-actions{align-items:center;display:flex}.ad-button{border:1px solid var(--ad-ui-border);background:var(--ad-ui-bg);color:var(--ad-ui-text);white-space:nowrap;border-radius:11px;justify-content:center;align-items:center;gap:8px;height:38px;padding:0 12px;font-size:13px;font-weight:700;display:inline-flex}.ad-button:hover{background:var(--ad-ui-surface)}.ad-button:active{transform:translateY(1px)}.ad-primary{color:#103639;background:#05d9ab;border-color:#05d9ab}.ad-primary:hover{background:#04c49a;border-color:#04c49a}.ad-secondary{color:#fff;background:#103639;border-color:#103639}.ad-secondary:hover{background:#1a4a4e}.ad-danger{background:var(--ad-ui-surface);color:#b5283c}.ad-subtle{background:var(--ad-ui-surface);border-color:#0000}.ad-button-icon{display:flex}.ad-button svg{width:20px;height:20px}.ad-icon-button{width:var(--ad-ctrl);height:var(--ad-ctrl);color:var(--ad-ui-text);background:0 0;border:0;border-radius:11px;flex-shrink:0;justify-content:center;align-items:center;padding:7px;display:inline-flex;position:relative}.ad-icon-button:hover{background:var(--ad-ui-surface)}.ad-icon-button[aria-pressed=true],.ad-icon-button[aria-expanded=true]{color:var(--ad-ui-text);background:#05d9ab25}.ad-toolbar{left:max(var(--ad-inset), env(safe-area-inset-left,0px));padding:var(--ad-tool-pad);background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);box-shadow:var(--ad-shadow);gap:var(--ad-tool-gap);max-height:calc(100% - var(--ad-dock-clearance));border-radius:19px;flex-direction:column;align-items:center;display:flex;position:absolute;top:50%;transform:translateY(-50%)}.ad-toolbar .ad-icon-button{width:var(--ad-tool);height:var(--ad-tool);border-radius:12px}.ad-toolbar svg{width:var(--ad-tool-icon);height:var(--ad-tool-icon)}.ad-toolbar .ad-icon-button[aria-pressed=true]{color:var(--ad-ui-text);background:#05d9ab30}.ad-toolbar-divider{background:var(--ad-ui-border);width:24px;height:1px;margin:3px 0}.ad-tool-corner{opacity:.5;border-bottom:1.5px solid;border-right:1.5px solid;border-radius:0 0 2px;width:4px;height:4px;position:absolute;bottom:7px;right:7px}.ad-tooltip{white-space:nowrap;background:var(--ad-ui-text);color:var(--ad-ui-bg);pointer-events:none;visibility:hidden;border-radius:9px;padding:8px 12px;font-size:12px;font-weight:650;position:absolute;top:50%;left:calc(100% + 16px);transform:translateY(-50%)}.ad-icon-button:hover>.ad-tooltip,.ad-icon-button:focus-visible>.ad-tooltip{visibility:visible}.ad-popover{background:var(--ad-ui-bg);max-height:calc(100dvh - 24px);color:var(--ad-ui-text);border:1px solid var(--ad-ui-border);font-family:var(--ad-font-sans);border-radius:17px;margin:0;padding:8px;font-size:14px;position:fixed;inset:auto;overflow:auto;box-shadow:0 8px 32px #10363914,0 2px 5px #10363908}.ad-root[data-theme=dark] .ad-popover{box-shadow:none}.ad-tool-option{width:100%;min-height:44px;color:var(--ad-ui-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:10px;align-items:center;gap:13px;padding:8px 12px;font-weight:650;text-decoration:none;display:flex}.ad-tool-option:hover{background:var(--ad-ui-surface)}.ad-tool-option:focus:not(:focus-visible){outline:none}.ad-menu-version{color:var(--ad-ui-muted);font-variant-numeric:tabular-nums;text-align:center;margin:0;padding:6px 12px 4px;font-size:12px}.ad-tool-option[aria-pressed=true]{background:#05d9ab25}.ad-ui>.ad-style-dock{max-height:calc(100cqb - var(--ad-dock-clearance));pointer-events:none;flex-direction:row-reverse;align-items:center;display:flex;position:absolute;top:50%;right:0;transform:translateY(-50%)}.ad-style-dock>*{pointer-events:auto}.ad-style-panel{width:248px;max-width:calc(100cqi - 48px);max-height:calc(100cqb - var(--ad-dock-clearance));scrollbar-width:thin;background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);padding:var(--ad-panel-pad);box-shadow:var(--ad-shadow);border-radius:18px;overflow:auto}.ad-style-dismiss{width:24px;height:44px;color:var(--ad-ui-muted);border-radius:0;padding:0}.ad-style-dismiss:after{content:"";position:absolute;inset:-2px -4px -2px -16px}.ad-style-dismiss:hover{color:var(--ad-ui-text);background:0 0}.ad-style-dismiss svg{width:16px;height:16px;transform:rotate(-90deg)}.ad-color-controls{flex-wrap:nowrap;gap:6px;margin-bottom:12px;display:flex}.ad-color-control{border:1px solid var(--ad-ui-border);min-width:0;height:40px;color:var(--ad-ui-text);white-space:nowrap;background:0 0;border-radius:11px;flex:1 1 0;justify-content:center;align-items:center;gap:5px;padding:6px 5px;font-size:11px;font-weight:700;display:flex}.ad-color-control:hover{background:var(--ad-ui-surface)}.ad-color-preview{background:var(--swatch);border:1px solid #10363920;border-radius:6px;flex-shrink:0;width:16px;height:16px}.ad-color-popover:popover-open{grid-template-columns:repeat(4,1fr);gap:5px;padding:12px;display:grid}.ad-swatch{background:var(--swatch);border:1px solid #10363922;border-radius:12px;width:44px;height:44px;padding:0;position:relative}.ad-swatch[aria-pressed=true]{outline:2px solid var(--ad-ui-text);outline-offset:2px}.ad-swatch-none{background:linear-gradient(135deg,#0000 46%,#c14745 47% 54%,#0000 55%)}.ad-field-label{color:var(--ad-ui-muted);margin-bottom:6px;font-size:12px;font-weight:650;display:block}.ad-field{min-width:0;margin-bottom:12px;display:block}.ad-field input:not([type=range]),.ad-field select,.ad-dialog input:not([type=file]){background:var(--ad-ui-surface);border:1px solid var(--ad-ui-border);width:100%;min-width:0;height:36px;color:var(--ad-ui-text);border-radius:9px;padding:5px 8px;font-size:13px}.ad-field input[type=range]{accent-color:#05b48f;width:100%}.ad-style-row{grid-template-columns:57.6px minmax(0,1fr);align-items:center;gap:8px;margin-bottom:12px;display:grid}.ad-style-label{color:var(--ad-ui-muted);white-space:nowrap;font-size:12px;font-weight:650}.ad-segments{background:var(--ad-ui-surface);border-radius:12px;align-items:center;gap:1px;min-width:0;padding:3px;display:flex}.ad-segment{min-width:32px;height:36px;color:var(--ad-ui-text);background:0 0;border:1px solid #0000;border-radius:9px;flex:1 1 0;justify-content:center;align-items:center;padding:4px;font-size:13px;font-weight:700;transition:background .12s,box-shadow .12s;display:flex}.ad-segment:hover{background:var(--ad-ui-bg)}.ad-segment[aria-pressed=true]{background:var(--ad-ui-bg);border-color:var(--ad-ui-border);box-shadow:0 1px 3px #1036390d}.ad-segment svg{width:20px;height:20px}.ad-href-edit{width:100%;margin-bottom:12px}.ad-dialog-error{color:#c14745;margin:-4px 0 12px;font-size:13px;font-weight:650}.ad-selection-actions{border-top:1px solid var(--ad-ui-border);justify-content:space-between;padding-top:8px;display:flex}.ad-selection-actions .ad-icon-button{width:38px;height:38px}.ad-footer{left:max(var(--ad-inset), env(safe-area-inset-left,0px));right:max(var(--ad-inset), env(safe-area-inset-right,0px));bottom:max(var(--ad-edge), env(safe-area-inset-bottom,0px));pointer-events:none;justify-content:space-between;align-items:center;gap:16px;min-width:0;display:flex;position:absolute}.ad-footer>*{pointer-events:auto}.ad-zoom{border:1px solid var(--ad-ui-border);background:var(--ad-ui-bg);box-shadow:var(--ad-shadow);border-radius:15px;flex-shrink:0;align-items:center;gap:2px;padding:5px;display:flex}.ad-zoom svg{width:var(--ad-ctrl-icon);height:var(--ad-ctrl-icon)}.ad-footer-right{align-items:center;margin-left:auto;display:flex}.ad-zoom-value{color:var(--ad-ui-text);height:var(--ad-ctrl);font-variant-numeric:tabular-nums;background:0 0;border:0;border-radius:10px;width:56px;font-size:12px;font-weight:700}.ad-zoom-value:hover{background:var(--ad-ui-surface)}.ad-zoom-controls{justify-content:space-between;align-items:center;gap:8px;display:flex}.ad-pages{background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);min-width:0;max-width:min(520px,100% - 272px);box-shadow:var(--ad-shadow);border-radius:15px;flex:0 auto;align-items:center;gap:4px;padding:5px;display:flex}.ad-page-tabs{flex:1;gap:4px;min-width:0;display:flex;overflow:hidden}.ad-page-tab{min-width:40px;max-width:140px;height:var(--ad-ctrl);color:var(--ad-ui-muted);white-space:nowrap;text-overflow:ellipsis;background:0 0;border:0;border-radius:11px;flex:none;padding:8px 14px;font-size:13px;font-weight:700;overflow:hidden}.ad-page-tab:hover{background:var(--ad-ui-surface)}.ad-page-tab[aria-selected=true],.ad-pages-popover [aria-current=true]{color:var(--ad-ui-text);background:#05d9ab25}.ad-page-row{align-items:center;gap:4px;display:flex}.ad-page-row .ad-tool-option{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.ad-pages-popover{max-height:min(360px,100dvh - 24px)}.ad-pages svg{width:var(--ad-ctrl-icon);height:var(--ad-ctrl-icon)}.ad-context-menu .ad-tool-option{gap:10px;font-size:13px}.ad-context-menu svg{width:20px;height:20px}.ad-menu-separator{background:var(--ad-ui-border);height:1px;margin:5px 10px}.ad-context-menu .ad-danger{color:#c14745}.ad-context-menu .ad-danger:hover{background:#c1474510}.ad-color-control>svg{flex-shrink:0;width:16px;height:16px}.ad-opacity-popover{padding:16px}.ad-opacity-popover .ad-field{margin:0}.ad-opacity-popover .ad-field-label{justify-content:space-between;display:flex}.ad-opacity-popover input{min-height:28px}.ad-dialog{color:var(--ad-ui-text);background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);border-radius:22px;width:560px;max-width:calc(100vw - 32px);max-height:85dvh;padding:28px;font-size:13px;line-height:1.5;overflow:auto;box-shadow:0 20px 90px #10363918}.ad-dialog::backdrop{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background:#10363938}.ad-dialog-head{justify-content:space-between;align-items:flex-start;gap:15px;margin-bottom:25px;display:flex}.ad-dialog h2{letter-spacing:-.75px;margin:2px 0 8px;font-size:23px;font-weight:750;line-height:1.2}.ad-action-grid{grid-template-columns:1fr 1fr;gap:9px;display:grid}.ad-action-grid .ad-button{white-space:normal;text-align:left;justify-content:flex-start;font-size:11px}.ad-text{font-family:var(--ad-font-hand)}.ad-editing{outline-offset:3px;min-width:30px;min-height:1em;-webkit-user-select:text!important;user-select:text!important;cursor:text!important;outline:2px solid #05d9ab!important}.ad-root [hidden]{display:none!important}@container board (height<=640px) and (width>=1024px){.ad-ui{--ad-inset:12px;--ad-edge:10px;--ad-tool:34px;--ad-tool-pad:4px;--ad-tool-gap:1px;--ad-tool-icon:18px;--ad-ctrl:32px;--ad-ctrl-icon:16px;--ad-panel-pad:10px;--ad-dock-clearance:120px}.ad-header{gap:10px}.ad-brand{gap:6px;padding:4px 8px 4px 4px}.ad-brand-mark{border-radius:9px;width:26px;height:26px}.ad-brand-mark svg{width:22px;height:22px}.ad-brand-name{font-size:15px}.ad-header-actions .ad-button{height:var(--ad-ctrl);padding:0 10px}.ad-button svg{width:var(--ad-ctrl-icon);height:var(--ad-ctrl-icon)}.ad-icon-button{width:var(--ad-ctrl);height:var(--ad-ctrl);padding:4px}.ad-toolbar .ad-icon-button{width:var(--ad-tool);height:var(--ad-tool)}.ad-zoom,.ad-pages{padding:3px}.ad-toolbar-divider{width:18px;margin:1px 0}.ad-tool-corner{bottom:5px;right:5px}}@container board (height<=480px) and (width>=1024px){.ad-ui{--ad-inset:8px;--ad-edge:8px;--ad-tool:30px;--ad-tool-pad:3px;--ad-tool-gap:0px;--ad-tool-icon:16px;--ad-ctrl:28px;--ad-ctrl-icon:15px;--ad-panel-pad:8px;--ad-dock-clearance:96px}}@container board (width<=700px) or ((width<=1023px) and (height<=640px)){.ad-ui{--ad-inset:12px;--ad-edge:12px;--ad-tool:48px;--ad-tool-pad:5px;--ad-tool-gap:0px;--ad-tool-icon:24px;--ad-ctrl:44px;--ad-ctrl-icon:20px;--ad-panel-pad:12px;--ad-dock-clearance:220px}.ad-header{gap:8px}.ad-brand{border-radius:15px;gap:7px;height:48px;padding:6px 9px 6px 6px}.ad-brand-name{font-size:15px}.ad-brand>svg{margin:0}.ad-header-actions .ad-button{border-radius:13px;height:48px;padding:0 12px;font-size:14px}.ad-toolbar{top:auto;bottom:max(12px, env(safe-area-inset-bottom,0px));border-radius:18px;flex-direction:row;width:max-content;max-width:calc(100% - 16px);max-height:none;left:50%;right:auto;overflow-x:auto;transform:translate(-50%)}.ad-toolbar .ad-icon-button{border-radius:12px}.ad-toolbar .ad-desktop-tool,.ad-toolbar-divider,.ad-tooltip{display:none}.ad-ui>.ad-style-dock{top:calc(var(--ad-edge) + 56px);bottom:calc(72px + var(--ad-ctrl) + 8px + env(safe-area-inset-bottom,0px));max-height:none;transform:none}.ad-style-panel{max-height:100%}.ad-footer{bottom:calc(72px + env(safe-area-inset-bottom,0px));flex-wrap:wrap;gap:8px}.ad-zoom{border-radius:14px;padding:3px}.ad-zoom-value{width:52px;font-size:13px}.ad-pages{flex:0 auto;min-width:120px;max-width:100%;padding:3px}.ad-page-tab{font-size:14px}.ad-style-label{font-size:13px}.ad-segment{min-width:36px;height:44px;font-size:14px}.ad-color-control{min-height:44px;font-size:12px}.ad-field input:not([type=range]),.ad-field select,.ad-dialog input:not([type=file]){min-height:44px;font-size:16px}.ad-selection-actions .ad-icon-button{width:48px;height:48px}.ad-style-panel .ad-button{height:44px;font-size:14px}.ad-style-dismiss{height:48px}.ad-tool-option{min-height:48px;font-size:16px}.ad-dialog{border-radius:19px;max-height:88dvh;padding:22px;font-size:16px}.ad-dialog h2{font-size:22px}.ad-dialog .ad-button{height:auto;min-height:48px;padding-block:10px;font-size:15px}.ad-dialog .ad-icon-button{width:48px;height:48px}.ad-action-grid{grid-template-columns:1fr}}@container board (width<=1023px) and (height<=620px){.ad-ui{--ad-inset:8px;--ad-edge:8px;--ad-tool:40px;--ad-tool-pad:4px;--ad-tool-icon:20px;--ad-ctrl:36px;--ad-ctrl-icon:18px;--ad-panel-pad:10px;--ad-dock-clearance:170px}.ad-brand,.ad-header-actions .ad-button{height:40px}.ad-footer{bottom:calc(60px + env(safe-area-inset-bottom,0px));flex-wrap:nowrap}.ad-zoom-value{width:44px}.ad-ui>.ad-style-dock{top:calc(var(--ad-edge) + 48px);bottom:calc(60px + var(--ad-ctrl) + 8px + env(safe-area-inset-bottom,0px))}.ad-segment{height:36px}}@container board (width<=360px){.ad-ui{--ad-tool:42px}}@container board (width<=350px){.ad-brand-name{font-size:14px}.ad-brand-mark{border-radius:9px;width:28px;height:28px}.ad-brand-mark svg{width:24px;height:24px}.ad-header-actions .ad-button{padding:0 10px}}@media (max-width:1023px){.ad-popover,.ad-tool-option{font-size:16px}.ad-tool-option{min-height:48px}.ad-menu-version{padding-block:8px;font-size:14px}.ad-dialog{font-size:16px}.ad-field input:not([type=range]),.ad-field select,.ad-dialog input:not([type=file]){min-height:44px;font-size:16px}}@media (pointer:coarse){.ad-toolbar .ad-icon-button:after,.ad-zoom .ad-icon-button:after,.ad-pages .ad-icon-button:after,.ad-selection-actions .ad-icon-button:after{content:"";width:max(100%,48px);height:max(100%,48px);position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}@container board (width>=1024px) and (height>=641px){.ad-toolbar .ad-icon-button{width:48px;height:48px}}}@media (prefers-reduced-motion:reduce){.ad-root,.ad-root *{scroll-behavior:auto!important;transition:none!important;animation:none!important}}
1
+ .ad-root{isolation:isolate;touch-action:none;--ad-cs:drop-shadow(0 8px 18px #1036391f);background:var(--ad-paper,#fbfcfa);width:100%;height:100%;color:var(--ad-ink,#103639);-webkit-user-select:none;user-select:none;outline:none;font-family:Nunito Variable,Nunito,ui-rounded,system-ui,sans-serif;position:relative;overflow:hidden}.ad-root[data-theme=dark]{--ad-paper:#122f32;--ad-ink:#e9f7f3;--ad-grid-color:#426160;--ad-focus:#05d9ab}.ad-grid,.ad-world,.ad-overlay{transform-origin:0 0;position:absolute;inset:0}.ad-grid{pointer-events:none;background-image:radial-gradient(circle, var(--ad-grid-color,#dce6df) 1px, transparent 1px);background-size:24px 24px}.ad-world{contain:layout style;width:0;height:0;overflow:visible}.ad-item{transform-origin:50%;box-sizing:border-box;outline:none;position:absolute;top:0;left:0;overflow:visible}.ad-item:focus-visible{outline:2px solid var(--ad-focus,#007d65);outline-offset:6px}.ad-agent-pending{visibility:hidden;pointer-events:none}.ad-agent-cursor{z-index:4;pointer-events:none;transform-origin:7px 7px;will-change:transform;width:36px;height:36px;position:absolute;top:0;left:0}.ad-agent-cursor svg{transform-origin:7px 7px;fill:#8f93f9;stroke:#fff;stroke-width:2px;stroke-linejoin:round;filter:drop-shadow(0 2px 4px #10363926);display:block}.ad-agent-cursor span{color:#103639;white-space:nowrap;background:#8f93f9;border-radius:9px;padding:3px 8px;font-size:11px;font-weight:800;line-height:16px;position:absolute;top:26px;left:25px}.ad-root[data-theme=dark] .ad-agent-cursor svg{filter:none;stroke:#122f32}.ad-shape{pointer-events:none;display:block;position:absolute;top:0;left:0;overflow:visible}.ad-text{box-sizing:border-box;white-space:pre-wrap;overflow-wrap:anywhere;word-break:normal;pointer-events:none;flex-direction:column;padding:12px;font-family:Comic Sans MS,Chalkboard SE,cursive;line-height:1.35;display:flex;position:absolute;inset:0}.ad-item[data-ad-kind=diamond] .ad-text{padding:20%}.ad-item[data-ad-kind=ellipse] .ad-text{padding:15%}.ad-item[data-ad-kind=text] .ad-text{padding:0}.ad-item[data-ad-kind=note] .ad-text{padding:20px;line-height:1.5}.ad-item[data-ad-kind=note] .ad-shape{filter:var(--ad-cs)}.ad-item[data-ad-kind=connector] .ad-text{border-radius:5px;width:max-content;max-width:240px;height:auto;padding:3px 8px;font-size:14px;line-height:1.25;bottom:auto;right:auto;transform:translate(-50%,-50%)}.ad-text[contenteditable=plaintext-only],.ad-text[contenteditable=true]{pointer-events:auto;-webkit-user-select:text;user-select:text;cursor:text;background:#fffc;border-radius:4px;outline:2px solid #05d9ab;min-width:20px}.ad-auxiliary{pointer-events:none;position:absolute;inset:0}.ad-auxiliary img{object-fit:fill;pointer-events:none;width:100%;height:100%;position:absolute}.ad-card{filter:var(--ad-cs);border-radius:12px;overflow:hidden}.ad-html-content{white-space:pre-wrap;box-sizing:border-box;border:1px solid #d9e3df;border-radius:8px;padding:12px;overflow:auto}.ad-item[data-ad-interactive=true] .ad-html-content{pointer-events:auto;-webkit-user-select:text;user-select:text}.ad-placeholder{box-sizing:border-box;text-align:center;background:#8f93f912;border:1.5px dashed #8f93f9;border-radius:8px;justify-content:center;align-items:center;gap:8px;width:100%;height:100%;padding:8px;font-size:13px;display:flex}.ad-overlay{pointer-events:none;width:100%;height:100%;overflow:visible}.ad-selection-outline{fill:none;stroke:var(--ad-focus,#00876c);stroke-width:1.4px;vector-effect:non-scaling-stroke}.ad-selection-handle{fill:var(--ad-paper,#fff);stroke:var(--ad-focus,#00876c);stroke-width:1.5px;pointer-events:all}.ad-selection-handle:hover{fill:#aaf1ac}.ad-marquee{fill:#05d9ab16;stroke:#00876c;stroke-width:1px}.ad-no-grid .ad-grid{display:none}.ad-custom-handle{fill:#05d9ab;stroke:#103639}.ad-root *{box-sizing:inherit}.ad-root :is(button,input,select,textarea){font:inherit}.ad-root button{cursor:pointer}.ad-root button:disabled,.ad-root :is(input,select):disabled{opacity:.38;cursor:not-allowed}.ad-root :is(button,input,select,textarea,a,summary){-webkit-tap-highlight-color:transparent}.ad-root :focus-visible{outline-offset:3px;outline:3px solid #05b48f}.ad-root button:focus:not(:focus-visible){outline:none}.ad-root{box-sizing:border-box;--ad-font-sans:"Nunito Variable", "Nunito", "Trebuchet MS", sans-serif;--ad-font-hand:"Comic Sans MS", "Chalkboard SE", cursive;--ad-ui-bg:#fff;--ad-ui-surface:#f3f8f5;--ad-ui-border:#10363912;--ad-ui-text:#103639;--ad-ui-muted:#5e716b;--ad-ui-accent:#05d9ab;--ad-shadow:0 4px 20px #10363907, 0 1px 3px #10363905;font-family:var(--ad-font-sans);color:var(--ad-ui-text);isolation:isolate;container:board/size;background:#fcfdfb!important}.ad-root[data-theme=dark]{--ad-ui-bg:#193638;--ad-ui-surface:#214447;--ad-ui-border:#ffffff16;--ad-ui-text:#ecf8f2;--ad-ui-muted:#bacfc7;--ad-shadow:none;background:#10282b!important}.ad-ui{z-index:5;pointer-events:none;--ad-inset:24px;--ad-edge:20px;--ad-tool:44px;--ad-tool-pad:7px;--ad-tool-gap:4px;--ad-tool-icon:24px;--ad-ctrl:38px;--ad-ctrl-icon:20px;--ad-panel-pad:14px;--ad-dock-clearance:174px;font-size:13px;line-height:1.4;position:absolute;inset:0}.ad-ui>*{pointer-events:auto}.ad-ui svg{flex-shrink:0;width:24px;height:24px}.ad-header{left:max(var(--ad-inset), env(safe-area-inset-left,0px));right:max(var(--ad-inset), env(safe-area-inset-right,0px));top:max(var(--ad-edge), env(safe-area-inset-top,0px));pointer-events:none;justify-content:space-between;align-items:center;gap:16px;min-width:0;display:flex;position:absolute}.ad-header>*{pointer-events:auto}.ad-header-end{justify-content:flex-end}.ad-brand{color:var(--ad-ui-text);background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);box-shadow:var(--ad-shadow);border-radius:16px;align-items:center;gap:9px;padding:6px 10px 6px 6px;display:flex}.ad-brand:hover{background:var(--ad-ui-surface)}.ad-brand>svg{width:16px;height:16px;color:var(--ad-ui-muted);margin-left:3px}.ad-brand-mark{color:#103639;background:#05d9ab;border-radius:11px;place-items:center;width:32px;height:32px;display:grid}.ad-brand-mark svg{width:28px;height:28px}.ad-brand-name{letter-spacing:-.55px;white-space:nowrap;font-size:16px;font-weight:800}.ad-header-actions{align-items:center;gap:8px;display:flex}.ad-icon-button.ad-chrome{background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);box-shadow:var(--ad-shadow);display:none}.ad-button{border:1px solid var(--ad-ui-border);background:var(--ad-ui-bg);color:var(--ad-ui-text);white-space:nowrap;border-radius:11px;justify-content:center;align-items:center;gap:8px;height:38px;padding:0 12px;font-size:13px;font-weight:700;display:inline-flex}.ad-button:hover{background:var(--ad-ui-surface)}.ad-button:active{transform:translateY(1px)}.ad-primary{color:#103639;background:#05d9ab;border-color:#05d9ab}.ad-primary:hover{background:#04c49a;border-color:#04c49a}.ad-secondary{color:#fff;background:#103639;border-color:#103639}.ad-secondary:hover{background:#1a4a4e}.ad-danger{background:var(--ad-ui-surface);color:#b5283c}.ad-subtle{background:var(--ad-ui-surface);border-color:#0000}.ad-button-icon{display:flex}.ad-button svg{width:20px;height:20px}.ad-icon-button{width:var(--ad-ctrl);height:var(--ad-ctrl);color:var(--ad-ui-text);background:0 0;border:0;border-radius:11px;flex-shrink:0;justify-content:center;align-items:center;padding:7px;display:inline-flex;position:relative}.ad-icon-button:hover{background:var(--ad-ui-surface)}.ad-icon-button[aria-pressed=true],.ad-icon-button[aria-expanded=true]{color:var(--ad-ui-text);background:#05d9ab25}.ad-toolbar{left:max(var(--ad-inset), env(safe-area-inset-left,0px));padding:var(--ad-tool-pad);background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);box-shadow:var(--ad-shadow);gap:var(--ad-tool-gap);max-height:calc(100% - var(--ad-dock-clearance));border-radius:19px;flex-direction:column;align-items:center;display:flex;position:absolute;top:50%;transform:translateY(-50%)}.ad-toolbar .ad-icon-button{width:var(--ad-tool);height:var(--ad-tool);border-radius:12px}.ad-toolbar svg{width:var(--ad-tool-icon);height:var(--ad-tool-icon)}.ad-toolbar .ad-icon-button[aria-pressed=true]{color:var(--ad-ui-text);background:#05d9ab30}.ad-toolbar-divider{background:var(--ad-ui-border);width:24px;height:1px;margin:3px 0}.ad-tool-corner{opacity:.5;border-bottom:1.5px solid;border-right:1.5px solid;border-radius:0 0 2px;width:4px;height:4px;position:absolute;bottom:7px;right:7px}.ad-tooltip{white-space:nowrap;background:var(--ad-ui-text);color:var(--ad-ui-bg);pointer-events:none;visibility:hidden;border-radius:9px;padding:8px 12px;font-size:12px;font-weight:650;position:absolute;top:50%;left:calc(100% + 16px);transform:translateY(-50%)}.ad-icon-button:hover>.ad-tooltip,.ad-icon-button:focus-visible>.ad-tooltip{visibility:visible}.ad-popover{background:var(--ad-ui-bg);max-height:calc(100dvh - 24px);color:var(--ad-ui-text);border:1px solid var(--ad-ui-border);font-family:var(--ad-font-sans);border-radius:17px;margin:0;padding:8px;font-size:14px;position:fixed;inset:auto;overflow:auto;box-shadow:0 8px 32px #10363914,0 2px 5px #10363908}.ad-root[data-theme=dark] .ad-popover{box-shadow:none}.ad-tool-option{width:100%;min-height:44px;color:var(--ad-ui-text);font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:10px;align-items:center;gap:13px;padding:8px 12px;font-weight:650;text-decoration:none;display:flex}.ad-tool-option:hover{background:var(--ad-ui-surface)}.ad-tool-option:focus:not(:focus-visible){outline:none}.ad-menu-version{color:var(--ad-ui-muted);font-variant-numeric:tabular-nums;text-align:center;margin:0;padding:6px 12px 4px;font-size:12px}.ad-tool-option[aria-pressed=true]{background:#05d9ab25}.ad-ui>.ad-style-dock{max-height:calc(100cqb - var(--ad-dock-clearance));pointer-events:none;flex-direction:row-reverse;align-items:center;display:flex;position:absolute;top:50%;right:0;transform:translateY(-50%)}.ad-style-dock>*{pointer-events:auto}.ad-style-panel{width:248px;max-width:calc(100cqi - 48px);max-height:calc(100cqb - var(--ad-dock-clearance));scrollbar-width:thin;background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);padding:var(--ad-panel-pad);box-shadow:var(--ad-shadow);border-radius:18px;overflow:auto}.ad-style-dismiss{width:24px;height:44px;color:var(--ad-ui-muted);border-radius:0;padding:0}.ad-style-dismiss:after{content:"";position:absolute;inset:-2px -4px -2px -16px}.ad-style-dismiss:hover{color:var(--ad-ui-text);background:0 0}.ad-style-dismiss svg{width:16px;height:16px;transform:rotate(-90deg)}.ad-color-controls{flex-wrap:nowrap;gap:6px;margin-bottom:12px;display:flex}.ad-color-control{border:1px solid var(--ad-ui-border);min-width:0;height:40px;color:var(--ad-ui-text);white-space:nowrap;background:0 0;border-radius:11px;flex:1 1 0;justify-content:center;align-items:center;gap:5px;padding:6px 5px;font-size:11px;font-weight:700;display:flex}.ad-color-control:hover{background:var(--ad-ui-surface)}.ad-color-preview{background:var(--swatch);border:1px solid #10363920;border-radius:6px;flex-shrink:0;width:16px;height:16px}.ad-color-popover:popover-open{grid-template-columns:repeat(4,1fr);gap:5px;padding:12px;display:grid}.ad-swatch{background:var(--swatch);border:1px solid #10363922;border-radius:12px;width:44px;height:44px;padding:0;position:relative}.ad-swatch[aria-pressed=true]{outline:2px solid var(--ad-ui-text);outline-offset:2px}.ad-swatch-none{background:linear-gradient(135deg,#0000 46%,#c14745 47% 54%,#0000 55%)}.ad-field-label{color:var(--ad-ui-muted);margin-bottom:6px;font-size:12px;font-weight:650;display:block}.ad-field{min-width:0;margin-bottom:12px;display:block}.ad-field input:not([type=range]),.ad-field select,.ad-dialog input:not([type=file]){background:var(--ad-ui-surface);border:1px solid var(--ad-ui-border);width:100%;min-width:0;height:36px;color:var(--ad-ui-text);border-radius:9px;padding:5px 8px;font-size:13px}.ad-field input[type=range]{accent-color:#05b48f;width:100%}.ad-style-row{grid-template-columns:57.6px minmax(0,1fr);align-items:center;gap:8px;margin-bottom:12px;display:grid}.ad-style-label{color:var(--ad-ui-muted);white-space:nowrap;font-size:12px;font-weight:650}.ad-segments{background:var(--ad-ui-surface);border-radius:12px;align-items:center;gap:1px;min-width:0;padding:3px;display:flex}.ad-segment{min-width:32px;height:36px;color:var(--ad-ui-text);background:0 0;border:1px solid #0000;border-radius:9px;flex:1 1 0;justify-content:center;align-items:center;padding:4px;font-size:13px;font-weight:700;transition:background .12s,box-shadow .12s;display:flex}.ad-segment:hover{background:var(--ad-ui-bg)}.ad-segment[aria-pressed=true]{background:var(--ad-ui-bg);border-color:var(--ad-ui-border);box-shadow:0 1px 3px #1036390d}.ad-segment svg{width:20px;height:20px}.ad-href-edit{width:100%;margin-bottom:12px}.ad-dialog-error{color:#c14745;margin:-4px 0 12px;font-size:13px;font-weight:650}.ad-selection-actions{border-top:1px solid var(--ad-ui-border);justify-content:space-between;padding-top:8px;display:flex}.ad-selection-actions .ad-icon-button{width:38px;height:38px}.ad-footer{left:max(var(--ad-inset), env(safe-area-inset-left,0px));right:max(var(--ad-inset), env(safe-area-inset-right,0px));bottom:max(var(--ad-edge), env(safe-area-inset-bottom,0px));pointer-events:none;justify-content:space-between;align-items:center;gap:16px;min-width:0;display:flex;position:absolute}.ad-footer>*{pointer-events:auto}.ad-zoom{border:1px solid var(--ad-ui-border);background:var(--ad-ui-bg);box-shadow:var(--ad-shadow);border-radius:15px;flex-shrink:0;align-items:center;gap:2px;padding:5px;display:flex}.ad-zoom svg{width:var(--ad-ctrl-icon);height:var(--ad-ctrl-icon)}.ad-footer-right{align-items:center;margin-left:auto;display:flex}.ad-zoom-value{color:var(--ad-ui-text);height:var(--ad-ctrl);font-variant-numeric:tabular-nums;background:0 0;border:0;border-radius:10px;width:56px;font-size:12px;font-weight:700}.ad-zoom-value:hover{background:var(--ad-ui-surface)}.ad-zoom-controls{justify-content:space-between;align-items:center;gap:8px;display:flex}.ad-pages{background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);min-width:0;max-width:min(520px,100% - 272px);box-shadow:var(--ad-shadow);border-radius:15px;flex:0 auto;align-items:center;gap:4px;padding:5px;display:flex}.ad-page-tabs{flex:1;gap:4px;min-width:0;display:flex;overflow:hidden}.ad-page-tab{min-width:40px;max-width:140px;height:var(--ad-ctrl);color:var(--ad-ui-muted);white-space:nowrap;text-overflow:ellipsis;background:0 0;border:0;border-radius:11px;flex:none;padding:8px 14px;font-size:13px;font-weight:700;overflow:hidden}.ad-page-tab:hover{background:var(--ad-ui-surface)}.ad-page-tab[aria-selected=true],.ad-pages-popover [aria-current=true]{color:var(--ad-ui-text);background:#05d9ab25}.ad-page-row{align-items:center;gap:4px;display:flex}.ad-page-row .ad-tool-option{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.ad-pages-popover{max-height:min(360px,100dvh - 24px)}.ad-pages svg{width:var(--ad-ctrl-icon);height:var(--ad-ctrl-icon)}.ad-context-menu .ad-tool-option{gap:10px;font-size:13px}.ad-context-menu svg{width:20px;height:20px}.ad-chrome-popover{flex-direction:column;gap:12px;width:min(280px,100cqi - 24px);padding:12px;display:flex}.ad-chrome-section{min-width:0}.ad-chrome-label{color:var(--ad-ui-muted);letter-spacing:.02em;margin:0 0 6px;padding:0 4px;font-size:12px;font-weight:800}.ad-chrome-pages{flex-direction:column;gap:2px;max-height:28dvh;display:flex;overflow:auto}.ad-chrome-history,.ad-chrome-popover .ad-zoom-controls{background:var(--ad-ui-surface);border-radius:14px;justify-content:space-between;align-items:center;gap:4px;padding:4px;display:flex}.ad-chrome-popover .ad-zoom-value{flex:1;width:auto}.ad-menu-separator{background:var(--ad-ui-border);height:1px;margin:5px 10px}.ad-context-menu .ad-danger{color:#c14745}.ad-context-menu .ad-danger:hover{background:#c1474510}.ad-color-control>svg{flex-shrink:0;width:16px;height:16px}.ad-opacity-popover{padding:16px}.ad-opacity-popover .ad-field{margin:0}.ad-opacity-popover .ad-field-label{justify-content:space-between;display:flex}.ad-opacity-popover input{min-height:28px}.ad-dialog{color:var(--ad-ui-text);background:var(--ad-ui-bg);border:1px solid var(--ad-ui-border);border-radius:22px;width:560px;max-width:calc(100vw - 32px);max-height:85dvh;padding:28px;font-size:13px;line-height:1.5;overflow:auto;box-shadow:0 20px 90px #10363918}.ad-dialog::backdrop{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background:#10363938}.ad-dialog-head{justify-content:space-between;align-items:flex-start;gap:15px;margin-bottom:25px;display:flex}.ad-dialog h2{letter-spacing:-.75px;margin:2px 0 8px;font-size:23px;font-weight:750;line-height:1.2}.ad-action-grid{grid-template-columns:1fr 1fr;gap:9px;display:grid}.ad-action-grid .ad-button{white-space:normal;text-align:left;justify-content:flex-start;font-size:11px}.ad-text{font-family:var(--ad-font-hand)}.ad-editing{outline-offset:3px;min-width:30px;min-height:1em;-webkit-user-select:text!important;user-select:text!important;cursor:text!important;outline:2px solid #05d9ab!important}.ad-root [hidden]{display:none!important}@container board (height<=640px) and (width>=1024px){.ad-ui{--ad-inset:12px}.ad-ui:not(.ad-ui-bars){--ad-tool:41px;--ad-tool-pad:5px;--ad-tool-gap:2px;--ad-tool-icon:21px;--ad-ctrl:35px;--ad-ctrl-icon:18px;--ad-panel-pad:12px;--ad-dock-clearance:148px}.ad-ui:not(.ad-ui-bars) .ad-icon-button{width:var(--ad-ctrl);height:var(--ad-ctrl);padding:5px}.ad-ui:not(.ad-ui-bars) .ad-toolbar .ad-icon-button{width:var(--ad-tool);height:var(--ad-tool)}.ad-ui:not(.ad-ui-bars) .ad-toolbar-divider{width:21px;margin:2px 0}.ad-ui-bars{--ad-edge:10px;--ad-tool:37px;--ad-tool-pad:4px;--ad-tool-gap:1px;--ad-tool-icon:18px;--ad-ctrl:32px;--ad-ctrl-icon:16px;--ad-panel-pad:10px;--ad-dock-clearance:120px}.ad-ui-bars .ad-header{gap:10px}.ad-ui-bars .ad-brand{gap:6px;padding:4px 8px 4px 4px}.ad-ui-bars .ad-brand-mark{border-radius:9px;width:26px;height:26px}.ad-ui-bars .ad-brand-mark svg{width:22px;height:22px}.ad-ui-bars .ad-brand-name{font-size:15px}.ad-ui-bars .ad-header-actions .ad-button{height:var(--ad-ctrl);padding:0 10px}.ad-ui-bars .ad-button svg{width:var(--ad-ctrl-icon);height:var(--ad-ctrl-icon)}.ad-ui-bars .ad-icon-button{width:var(--ad-ctrl);height:var(--ad-ctrl);padding:4px}.ad-ui-bars .ad-toolbar .ad-icon-button{width:var(--ad-tool);height:var(--ad-tool)}.ad-ui-bars .ad-zoom,.ad-ui-bars .ad-pages{padding:3px}.ad-ui-bars .ad-toolbar-divider{width:18px;margin:1px 0}.ad-ui-bars .ad-tool-corner{bottom:5px;right:5px}}@container board (height<=500px) and (width>=1024px){.ad-ui:not(.ad-ui-bars){--ad-edge:10px;--ad-tool:37px;--ad-tool-pad:4px;--ad-tool-gap:1px;--ad-tool-icon:18px;--ad-ctrl:32px;--ad-ctrl-icon:16px;--ad-panel-pad:10px;--ad-dock-clearance:120px}.ad-ui:not(.ad-ui-bars) .ad-icon-button{width:var(--ad-ctrl);height:var(--ad-ctrl);padding:4px}.ad-ui:not(.ad-ui-bars) .ad-toolbar .ad-icon-button{width:var(--ad-tool);height:var(--ad-tool)}.ad-ui:not(.ad-ui-bars) .ad-zoom{padding:3px}.ad-ui:not(.ad-ui-bars) .ad-toolbar-divider{width:18px;margin:1px 0}.ad-ui:not(.ad-ui-bars) .ad-tool-corner{bottom:5px;right:5px}}@container board (height<=480px) and (width>=1024px){.ad-ui{--ad-inset:8px;--ad-edge:8px;--ad-tool:30px;--ad-tool-pad:3px;--ad-tool-gap:0px;--ad-tool-icon:16px;--ad-ctrl:28px;--ad-ctrl-icon:15px;--ad-panel-pad:8px;--ad-dock-clearance:96px}}@container board (width<=700px) or ((width<=1023px) and (height<=640px)){.ad-ui{--ad-inset:12px;--ad-edge:12px;--ad-tool:44px;--ad-tool-pad:4px;--ad-tool-gap:0px;--ad-tool-icon:21px;--ad-ctrl:44px;--ad-ctrl-icon:20px;--ad-panel-pad:12px;--ad-dock-clearance:220px}.ad-header{gap:8px}.ad-brand{border-radius:15px;gap:7px;height:48px;padding:6px 9px 6px 6px}.ad-brand-name{font-size:15px}.ad-brand>svg{margin:0}.ad-header-actions .ad-button{border-radius:13px;height:48px;padding:0 12px;font-size:14px}.ad-icon-button.ad-chrome{border-radius:13px;width:48px;height:48px;display:inline-flex}.ad-header-export,.ad-footer{display:none}.ad-toolbar{top:auto;bottom:max(12px, env(safe-area-inset-bottom,0px));border-radius:18px;flex-direction:row;width:max-content;max-width:calc(100% - 16px);max-height:none;left:50%;right:auto;overflow-x:auto;transform:translate(-50%)}.ad-toolbar .ad-icon-button{border-radius:12px}.ad-toolbar .ad-desktop-tool,.ad-toolbar-divider,.ad-tooltip{display:none}.ad-ui>.ad-style-dock{top:calc(var(--ad-edge) + 56px);bottom:calc(var(--ad-tool) + var(--ad-tool-pad) * 2 + 24px + env(safe-area-inset-bottom,0px));max-height:none;transform:none}.ad-style-panel{max-height:100%}.ad-zoom{border-radius:14px;padding:3px}.ad-zoom-value{width:52px;font-size:13px}.ad-pages{flex:0 auto;min-width:120px;max-width:100%;padding:3px}.ad-page-tab{font-size:14px}.ad-style-label{font-size:13px}.ad-segment{min-width:36px;height:44px;font-size:14px}.ad-color-control{min-height:44px;font-size:12px}.ad-field input:not([type=range]),.ad-field select,.ad-dialog input:not([type=file]){min-height:44px;font-size:16px}.ad-selection-actions .ad-icon-button{width:48px;height:48px}.ad-style-panel .ad-button{height:44px;font-size:14px}.ad-style-dismiss{height:48px}.ad-tool-option{min-height:48px;font-size:16px}.ad-dialog{border-radius:19px;max-height:88dvh;padding:22px;font-size:16px}.ad-dialog h2{font-size:22px}.ad-dialog .ad-button{height:auto;min-height:48px;padding-block:10px;font-size:15px}.ad-dialog .ad-icon-button{width:48px;height:48px}.ad-action-grid{grid-template-columns:1fr}}@container board (width<=1023px) and (height<=620px){.ad-ui{--ad-inset:8px;--ad-edge:8px;--ad-tool:40px;--ad-tool-pad:4px;--ad-tool-icon:20px;--ad-ctrl:36px;--ad-ctrl-icon:18px;--ad-panel-pad:10px;--ad-dock-clearance:170px}.ad-brand,.ad-header-actions .ad-button,.ad-icon-button.ad-chrome{height:40px}.ad-icon-button.ad-chrome{width:40px}.ad-zoom-value{width:44px}.ad-ui>.ad-style-dock{top:calc(var(--ad-edge) + 48px);bottom:calc(var(--ad-tool) + var(--ad-tool-pad) * 2 + 16px + env(safe-area-inset-bottom,0px))}.ad-segment{height:36px}}@container board (width<=360px){.ad-ui{--ad-tool:42px}}@container board (width<=350px){.ad-brand-name{font-size:14px}.ad-brand-mark{border-radius:9px;width:28px;height:28px}.ad-brand-mark svg{width:24px;height:24px}.ad-header-actions .ad-button{padding:0 10px}}@media (max-width:1023px){.ad-popover,.ad-tool-option{font-size:16px}.ad-tool-option{min-height:48px}.ad-menu-version{padding-block:8px;font-size:14px}.ad-dialog{font-size:16px}.ad-field input:not([type=range]),.ad-field select,.ad-dialog input:not([type=file]){min-height:44px;font-size:16px}}@media (pointer:coarse){.ad-toolbar .ad-icon-button:after,.ad-chrome:after,.ad-chrome-popover .ad-icon-button:after,.ad-zoom .ad-icon-button:after,.ad-pages .ad-icon-button:after,.ad-selection-actions .ad-icon-button:after{content:"";width:max(100%,48px);height:max(100%,48px);position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}@container board (width>=1024px) and (height>=641px){.ad-toolbar .ad-icon-button{width:48px;height:48px}}}@media (prefers-reduced-motion:reduce){.ad-root,.ad-root *{scroll-behavior:auto!important;transition:none!important;animation:none!important}}
2
2
  /*$vite$:1*/