@reffy/infinite-canvas 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-KcoKIUJZ.js +281 -0
- package/dist/index.html +54 -0
- package/esm/Canvas.js +100 -112
- package/esm/Canvas.js.map +1 -1
- package/esm/Component.d.ts.map +1 -1
- package/esm/Component.js +273 -308
- package/esm/Component.js.map +1 -1
- package/esm/manager/ContextMenu.js +4 -17
- package/esm/manager/ContextMenu.js.map +1 -1
- package/esm/manager/Selection.js +87 -100
- package/esm/manager/Selection.js.map +1 -1
- package/esm/serializer/serializer.d.ts.map +1 -1
- package/esm/serializer/serializer.js +11 -5
- package/esm/serializer/serializer.js.map +1 -1
- package/esm/shapes/Shape.js +1 -1
- package/esm/shapes/Shape.js.map +1 -1
- package/lib/Canvas.js +100 -112
- package/lib/Canvas.js.map +1 -1
- package/lib/Component.d.ts.map +1 -1
- package/lib/Component.js +273 -308
- package/lib/Component.js.map +1 -1
- package/lib/manager/ContextMenu.js +4 -17
- package/lib/manager/ContextMenu.js.map +1 -1
- package/lib/manager/Selection.js +87 -100
- package/lib/manager/Selection.js.map +1 -1
- package/lib/serializer/serializer.d.ts.map +1 -1
- package/lib/serializer/serializer.js +11 -5
- package/lib/serializer/serializer.js.map +1 -1
- package/lib/shapes/Shape.js +1 -1
- package/lib/shapes/Shape.js.map +1 -1
- package/package.json +3 -2
- package/dist/index.js +0 -4114
- package/dist/index.js.map +0 -1
- package/dist/index.umd.js +0 -276
- package/dist/index.umd.js.map +0 -1
package/dist/index.umd.js
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
(function(w,p){typeof exports=="object"&&typeof module<"u"?p(exports,require("mobx"),require("lit"),require("dexie"),require("uuid"),require("eventemitter3"),require("stats.js")):typeof define=="function"&&define.amd?define(["exports","mobx","lit","dexie","uuid","eventemitter3","stats.js"],p):(w=typeof globalThis<"u"?globalThis:w||self,p(w.ReffyInfiniteCanvas={},w.mobx,w.Lit,w.Dexie,w.uuid,w.EventEmitter3,w.Stats))})(this,(function(w,p,z,k,Xe,Ne,He){"use strict";var Fe=w=>{throw TypeError(w)};var Ge=(w,p,z)=>p.has(w)||Fe("Cannot "+z);var f=(w,p,z)=>(Ge(w,p,"read from private field"),z?z.call(w):p.get(w)),B=(w,p,z)=>p.has(w)?Fe("Cannot add the same private member more than once"):p instanceof WeakSet?p.add(w):p.set(w,z),A=(w,p,z,k)=>(Ge(w,p,"write to private field"),k?k.call(w,z):p.set(w,z),z);var G,H,et,ct,v,Y,dt,it,$,Z,P,lt,Ft,ut;const ft=["TOP","BOTTOM","LEFT","RIGHT"],St=["TOPLEFT","TOPRIGHT","BOTTOMLEFT","BOTTOMRIGHT"],ee={TOPLEFT:"TOPRIGHT",TOPRIGHT:"TOPLEFT",BOTTOMLEFT:"BOTTOMRIGHT",BOTTOMRIGHT:"BOTTOMLEFT"};function ie(s){return ee[s]?ee[s]:s}const se=8,Xt=2,b={identity:function(){return[1,0,0,0,1,0,0,0,1]},translation:function(s,t){return[1,0,0,0,1,0,s,t,1]},rotation:function(s){var t=Math.cos(s),e=Math.sin(s);return[t,-e,0,e,t,0,0,0,1]},scaling:function(s,t){return[s,0,0,0,t,0,0,0,1]},multiply:function(s,t){var e=s[0],i=s[1],r=s[2],n=s[3],a=s[4],o=s[5],h=s[6],c=s[7],l=s[8],u=t[0],m=t[1],g=t[2],C=t[3],x=t[4],E=t[5],S=t[6],L=t[7],R=t[8];return[u*e+m*n+g*h,u*i+m*a+g*c,u*r+m*o+g*l,C*e+x*n+E*h,C*i+x*a+E*c,C*r+x*o+E*l,S*e+L*n+R*h,S*i+L*a+R*c,S*r+L*o+R*l]},inverse(s){const t=[9],e=s[0],i=s[1],r=s[2],n=s[3],a=s[4],o=s[5],h=s[6],c=s[7],l=s[8],u=l*a-o*c,m=-l*n+o*h,g=c*n-a*h,x=1/(e*u+i*m+r*g);return t[0]=u*x,t[1]=(-l*i+r*c)*x,t[2]=(o*i-r*a)*x,t[3]=m*x,t[4]=(l*e-r*h)*x,t[5]=(-o*e+r*n)*x,t[6]=g*x,t[7]=(-c*e+i*h)*x,t[8]=(a*e-i*n)*x,t},projection(s,t){const e=[9];return e[0]=2/s,e[1]=0,e[2]=0,e[3]=0,e[4]=-2/t,e[5]=0,e[6]=-1,e[7]=1,e[8]=1,e},transformPoint(s,t){var e=t[0],i=t[1],r=e*s[2]+i*s[5]+s[8];return[(e*s[0]+i*s[3]+s[6])/r,(e*s[1]+i*s[4]+s[7])/r]}};function Nt(s,t,e){const i=re(s,s.VERTEX_SHADER,t),r=re(s,s.FRAGMENT_SHADER,e),n=s.createProgram();if(s.attachShader(n,i),s.attachShader(n,r),s.linkProgram(n),!s.getProgramParameter(n,s.LINK_STATUS))throw s.deleteProgram(n),s.deleteShader(i),s.deleteShader(r),new Error("Program was not created or the link to shaders was not successful.");return s.detachShader(n,i),s.detachShader(n,r),n}function re(s,t,e){const i=s.createShader(t);if(s.shaderSource(i,e),s.compileShader(i),s.getShaderParameter(i,s.COMPILE_STATUS))return i;throw s.deleteShader(i),new Error("Shader was not created.")}function Ye(s,t,e,i,r,n){const a=r.getBoundingClientRect(),o=window.devicePixelRatio||1,h=(s-a.left)*o,c=(t-a.top)*o,l=h/e*2-1,u=c/i*-2+1,m=b.projection(e,i),g=b.multiply(m,n),C=b.inverse(g),[x,E]=b.transformPoint(C,[l,u]);return[x,E]}function K(s,t,e){const{gl:i,canvas:r}=e;return Ye(s,t,i.canvas.width,i.canvas.height,r,e.worldMatrix)}function U(s,t,e){const i=t??0,r=e??0;return[s[0]*i+s[3]*r+s[6],s[1]*i+s[4]*r+s[7]]}function $e(s){return Math.hypot(s[0],s[1])}function je(s){return Math.hypot(s[3],s[4])}function Q(s){return[$e(s),je(s)]}function ne(s){return s/Math.abs(s)}function bt(s){return[ne(s[0]),ne(s[4])]}const Mt=(s,t)=>Math.abs(s)<t?0:Math.sign(s),Et=(s,t,e)=>{const i=s*t;return Mt(s,e)!==Mt(i,e)};async function Ve(s){return new Promise((t,e)=>{let i=new FileReader;i.onload=r=>{t(r.target.result)},i.onerror=e,i.readAsDataURL(s)})}const qe=["image/webp","image/png","image/jpeg","image/jpg","image/svg+xml","image/avif","image/gif","image/apng"];function Ze(s){return qe.includes(s)}async function Ht(s){const e=new TextEncoder().encode(s),i=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(i)).map(n=>n.toString(16).padStart(2,"0")).join("")}function Ke(s){const t=/^data:([^;]+);base64,/.exec(s);return t?t[1]:void 0}async function Qe(s,t){const e=[];if(s.length>0)for(let i=0;i<s.length;i++){const r=s[i];if(Ze(r.type))try{const n=await Ve(r);typeof n=="string"?e.push(await t(n)):console.error("Image not added")}catch{console.error("Failed to copy image.")}}return e}function Je(s,t){const e=JSON.stringify(t,null,2),i=new Blob([e],{type:"application/json"}),r=URL.createObjectURL(i),n=document.createElement("a");n.href=r,n.download=s,document.body.appendChild(n),n.click(),n.remove(),URL.revokeObjectURL(r)}async function ti(s){const t=await s.text();return JSON.parse(t)}function ae(s,t=1){return new Promise((e,i)=>{const r=new Image;r.onload=()=>{const n=document.createElement("canvas");n.width=r.width,n.height=r.height;const a=n.getContext("2d");a.clearRect(0,0,n.width,n.height),a.drawImage(r,0,0);const o=n.toDataURL("image/png",t);e(o)},r.onerror=i,r.src=s})}const st=[.33,.6,.95,1],Tt=[.33,.6,.95,.6],ei=[.33,.6,.95,.4];function _t(s,t,e="Add Child"){return{label:e,do(){for(const i of t)s.appendChild(i)},undo(){for(const i of t)s.removeChild(i)}}}function ii(s,t,e="Remove Child"){let i=-1;return{label:e,do(){i=s.children.indexOf(t),i>=0&&s.children.splice(i,1)},undo(){if(i<0){s.children.push(t);return}s.children.splice(i,0,t)}}}function si(s,t,e="Remove Children"){let i=[];return{label:e,do(){const r=new Set(t);i=[],s.children.forEach((n,a)=>{r.has(n)&&i.push({child:n,idx:a})}),i.slice().sort((n,a)=>a.idx-n.idx).forEach(({child:n})=>{s.removeChild(n)})},undo(){i.slice().sort((r,n)=>r.idx-n.idx).forEach(({child:r,idx:n})=>{s.children.includes(r)||(s.children.splice(Math.min(n,s.children.length),0,r),r.addParent(s))}),s.markOrderDirty()}}}const ri=["image/","text/plain"],ni=()=>"clipboard"in navigator&&"writeText"in navigator.clipboard;async function oe(s,t){const e={type:"infinite_canvas",elements:s.map(n=>({src:n.src,x:n.x,y:n.y,sx:n.sx,sy:n.sy}))},i=JSON.stringify(e),r=new ClipboardItem({"text/plain":new Blob([i],{type:"text/plain"})});if(ni())try{await navigator.clipboard.write([r]);return}catch(n){console.error(n)}if(!ai(i))throw new Error("Error copying to clipboard.")}function ai(s){s||(s=" ");const t=document.documentElement.getAttribute("dir")==="rtl",e=document.createElement("textarea");e.style.border="0",e.style.padding="0",e.style.margin="0",e.style.position="absolute",e.style[t?"right":"left"]="-9999px";const i=window.pageYOffset||document.documentElement.scrollTop;e.style.top=`${i}px`,e.style.fontSize="12pt",e.setAttribute("readonly",""),e.value=s,document.body.appendChild(e);let r=!1;try{e.select(),e.setSelectionRange(0,e.value.length),r=document.execCommand("copy")}catch(n){console.error(n)}return e.remove(),r}async function he(s,t,e,i,r=!0){const n=await navigator.clipboard.read(),a=n[0].types,[o,h]=r?[s,t]:K(s,t,e);for(const c of a){if(!ri.find(g=>g.endsWith("/")?c.startsWith(g):c===g))continue;const u=await n[0].getType(c);try{if(c==="text/plain"){const g=JSON.parse(await u.text());if(g.elements.length===0)return;let C=1/0,x=1/0;for(const S of g.elements)S.x<C&&(C=S.x),S.y<x&&(x=S.y);const E=await Promise.all(g.elements.map(S=>e.addImageToCanvas(S.src,o+S.x-C,h+S.y-x,S.sx,S.sy)));i.push(_t(e,E));return}}catch(g){console.error("Failed to parse clipboard data",g);continue}let m;if(c.startsWith("image/svg"))try{const g=await u.text();m=await ae(`data:image/svg+xml;base64,${btoa(g)}`)}catch(g){console.error("SVG conversion failed",g);continue}else try{m=await new Promise((g,C)=>{const x=new FileReader;x.onloadend=()=>g(x.result),x.onerror=C,x.readAsDataURL(u)})}catch(g){console.error("Image read failed",g);continue}try{const g=await e.addImageToCanvas(m,o,h);i.push(_t(e,[g]));return}catch(g){console.error("Failed to add image to canvas",g);continue}}}const X={Open:"opencontextmenu",Close:"closecontextmenu"},N={Save:"save",Change:"statechange"},rt={start:"startloading",done:"completeloading"},nt={Save:"save",SaveCompleted:"savecompleted",SaveFailed:"savefailed"},oi=`
|
|
2
|
-
attribute vec2 a_position;
|
|
3
|
-
|
|
4
|
-
uniform vec2 u_resolution;
|
|
5
|
-
uniform mat3 u_matrix;
|
|
6
|
-
uniform float u_z;
|
|
7
|
-
|
|
8
|
-
// all shaders have a main function
|
|
9
|
-
void main() {
|
|
10
|
-
vec2 position = (u_matrix * vec3(a_position, 1)).xy;
|
|
11
|
-
|
|
12
|
-
vec2 zeroToOne = position / u_resolution;
|
|
13
|
-
vec2 zeroToTwo = zeroToOne * 2.0;
|
|
14
|
-
vec2 clipSpace = zeroToTwo - 1.0;
|
|
15
|
-
float z = mix(1.0, -1.0, u_z);
|
|
16
|
-
|
|
17
|
-
gl_Position = vec4(clipSpace * vec2(1, -1), z, 1);
|
|
18
|
-
}
|
|
19
|
-
`,hi=`
|
|
20
|
-
precision mediump float;
|
|
21
|
-
uniform vec4 u_color;
|
|
22
|
-
|
|
23
|
-
void main() {
|
|
24
|
-
gl_FragColor = u_color;
|
|
25
|
-
}
|
|
26
|
-
`,ci=`
|
|
27
|
-
#extension GL_OES_standard_derivatives : enable
|
|
28
|
-
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
29
|
-
precision highp float;
|
|
30
|
-
precision highp int;
|
|
31
|
-
#else
|
|
32
|
-
precision mediump float;
|
|
33
|
-
precision mediump int;
|
|
34
|
-
#endif
|
|
35
|
-
|
|
36
|
-
uniform mat3 u_ViewProjectionInvMatrix;
|
|
37
|
-
uniform float u_ZoomScale;
|
|
38
|
-
uniform float u_CheckboardStyle;
|
|
39
|
-
uniform float u_z;
|
|
40
|
-
|
|
41
|
-
attribute vec2 a_Position;
|
|
42
|
-
|
|
43
|
-
varying vec2 v_Position;
|
|
44
|
-
|
|
45
|
-
vec2 project_clipspace_to_world(vec2 p) {
|
|
46
|
-
return (u_ViewProjectionInvMatrix * vec3(p, 1.0)).xy;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
void main() {
|
|
50
|
-
v_Position = project_clipspace_to_world(a_Position);
|
|
51
|
-
float z = mix(1.0, -1.0, u_z);
|
|
52
|
-
gl_Position = vec4(a_Position, z, 1.0);
|
|
53
|
-
}
|
|
54
|
-
`,di=`
|
|
55
|
-
#extension GL_OES_standard_derivatives : enable
|
|
56
|
-
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
57
|
-
precision highp float;
|
|
58
|
-
precision highp int;
|
|
59
|
-
#else
|
|
60
|
-
precision mediump float;
|
|
61
|
-
precision mediump int;
|
|
62
|
-
#endif
|
|
63
|
-
|
|
64
|
-
uniform mat3 u_ViewProjectionInvMatrix;
|
|
65
|
-
uniform float u_ZoomScale;
|
|
66
|
-
uniform float u_CheckboardStyle;
|
|
67
|
-
|
|
68
|
-
varying vec2 v_Position;
|
|
69
|
-
|
|
70
|
-
const vec4 GRID_COLOR = vec4(0.87, 0.87, 0.87, 1.0);
|
|
71
|
-
const vec4 PAGE_COLOR = vec4(0.986, 0.986, 0.986, 1.0);
|
|
72
|
-
const int CHECKERBOARD_STYLE_NONE = 0;
|
|
73
|
-
const int CHECKERBOARD_STYLE_GRID = 1;
|
|
74
|
-
const int CHECKERBOARD_STYLE_DOTS = 2;
|
|
75
|
-
const float BASE_GRID_PIXEL_SIZE = 100.0;
|
|
76
|
-
|
|
77
|
-
vec2 scale_grid_size(float zoom) {
|
|
78
|
-
if (zoom < 0.125) return vec2(BASE_GRID_PIXEL_SIZE * 125.0, 0.125);
|
|
79
|
-
else if (zoom < 0.25) return vec2(BASE_GRID_PIXEL_SIZE * 25.0, 0.25);
|
|
80
|
-
else if (zoom < 0.5) return vec2(BASE_GRID_PIXEL_SIZE * 5.0, 0.5);
|
|
81
|
-
return vec2(BASE_GRID_PIXEL_SIZE, 4.0);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
vec4 render_grid_checkerboard(vec2 coord) {
|
|
85
|
-
float alpha = 0.0;
|
|
86
|
-
|
|
87
|
-
vec2 size = scale_grid_size(u_ZoomScale);
|
|
88
|
-
float gridSize1 = size.x;
|
|
89
|
-
float gridSize2 = gridSize1 / 10.0;
|
|
90
|
-
float zoomStep = size.y;
|
|
91
|
-
int checkboardStyle = int(floor(u_CheckboardStyle + 0.5));
|
|
92
|
-
|
|
93
|
-
if (checkboardStyle == CHECKERBOARD_STYLE_GRID) {
|
|
94
|
-
vec2 grid1 = abs(fract(coord / gridSize1 - 0.5) - 0.5) / fwidth(coord) * gridSize1 / 2.0;
|
|
95
|
-
vec2 grid2 = abs(fract(coord / gridSize2 - 0.5) - 0.5) / fwidth(coord) * gridSize2;
|
|
96
|
-
float v1 = 1.0 - min(min(grid1.x, grid1.y), 1.0);
|
|
97
|
-
float v2 = 1.0 - min(min(grid2.x, grid2.y), 1.0);
|
|
98
|
-
|
|
99
|
-
if (v1 > 0.0) {
|
|
100
|
-
alpha = v1;
|
|
101
|
-
} else {
|
|
102
|
-
alpha = v2 * clamp(u_ZoomScale / zoomStep, 0.0, 1.0);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return mix(PAGE_COLOR, GRID_COLOR, alpha);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
void main() {
|
|
110
|
-
gl_FragColor = render_grid_checkerboard(v_Position);
|
|
111
|
-
}
|
|
112
|
-
`,li=`
|
|
113
|
-
attribute vec2 a_position;
|
|
114
|
-
attribute vec2 a_texCoord;
|
|
115
|
-
|
|
116
|
-
uniform vec2 u_resolution;
|
|
117
|
-
uniform mat3 u_matrix;
|
|
118
|
-
uniform float u_z;
|
|
119
|
-
|
|
120
|
-
varying vec2 v_texCoord;
|
|
121
|
-
|
|
122
|
-
void main() {
|
|
123
|
-
vec2 position = (u_matrix * vec3(a_position, 1)).xy;
|
|
124
|
-
vec2 zeroToOne = position / u_resolution;
|
|
125
|
-
vec2 zeroToTwo = zeroToOne * 2.0;
|
|
126
|
-
vec2 clipSpace = zeroToTwo - 1.0;
|
|
127
|
-
float z = mix(1.0, -1.0, u_z);
|
|
128
|
-
|
|
129
|
-
gl_Position = vec4(clipSpace * vec2(1, -1), z, 1);
|
|
130
|
-
|
|
131
|
-
v_texCoord = a_texCoord;
|
|
132
|
-
}
|
|
133
|
-
`,ui=`
|
|
134
|
-
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
135
|
-
precision highp float;
|
|
136
|
-
#else
|
|
137
|
-
precision mediump float;
|
|
138
|
-
#endif
|
|
139
|
-
|
|
140
|
-
uniform sampler2D u_image;
|
|
141
|
-
|
|
142
|
-
varying vec2 v_texCoord;
|
|
143
|
-
|
|
144
|
-
void main() {
|
|
145
|
-
gl_FragColor = texture2D(u_image, v_texCoord);
|
|
146
|
-
}
|
|
147
|
-
`;var W=(s=>(s[s.ACTIVE=0]="ACTIVE",s[s.PASSIVE=1]="PASSIVE",s))(W||{});class ce{constructor(t,e){this.sides=new Map,this.corners=new Map,this.borderSize=0,this.boxSize=0,this.mode=W.ACTIVE,this.target=t,this.setDimension(),this.mode=e??W.ACTIVE,this.borderSize=Xt,this.boxSize=se/2,this.addSides(),this.mode===W.ACTIVE&&this.addCorners()}setDimension(){const t=this.target.getEdge();this.width=t.maxX-t.minX,this.height=t.maxY-t.minY}getSidesInScreenSpace(t,e){const[i,r]=e?Q(e):[1,1],{width:n,height:a,borderSize:o}=this,[h,c]=U(e),[l,u]=bt(e);return{TOP:{x:l>0?h:h-n*i,y:c,width:n*i,height:o},BOTTOM:{x:l>0?h:h-n*i,y:c+a*r*u,width:n*i,height:o},LEFT:{x:h,y:u>0?c:c-a*r,width:o,height:a*r},RIGHT:{x:h+n*i*l,y:u>0?c:c-a*r,width:o,height:a*r}}[t]}getCornersInScreenSpace(t,e){const[i,r]=e?Q(e):[1,1],{width:n,height:a,boxSize:o}=this,[h,c]=U(e),[l,u]=bt(e);return{TOPLEFT:{x:h-o,y:c-o,width:o*2,height:o*2},TOPRIGHT:{x:h-o+n*i*l,y:c-o,width:o*2,height:o*2},BOTTOMLEFT:{x:h-o,y:c-o+a*r*u,width:o*2,height:o*2},BOTTOMRIGHT:{x:h-o+n*i*l,y:c-o+a*r*u,width:o*2,height:o*2}}[t]}setPassive(){this.mode=W.PASSIVE,this.removeCorners()}setActive(){this.mode=W.ACTIVE,this.addCorners()}getPositions(){return this.target.getPositions()}hitTest(t,e,i){if(this.mode===W.PASSIVE)return;const[r,n]=Q(this.target.worldMatrix),[a,o]=bt(this.target.worldMatrix),[h,c]=U(i,t,e),l=4;for(const R of St){const T=this.getCornersInScreenSpace(R,this.target.worldMatrix);if(h>=T.x-l&&h<=T.x+T.width+l&&c>=T.y-l&&c<=T.y+T.height+l)return R}for(const R of ft){const T=this.getSidesInScreenSpace(R,this.target.worldMatrix);if(h>=T.x-l&&h<=T.x+T.width+l&&c>=T.y-l&&c<=T.y+T.height+l)return R}const[u,m]=U(this.target.worldMatrix),g=this.width*r*a,C=this.height*n*o,x=Math.min(u,u+g),E=Math.max(u,u+g),S=Math.min(m,m+C),L=Math.max(m,m+C);if(h>=x&&h<=E&&c>=S&&c<=L)return"CENTER"}update(){this.updateSides(),this.updateCorners()}render(t,e){this.update();for(const[i,r]of this.sides.entries())r.render(t,e);for(const[i,r]of this.corners.entries())r.render(t,e)}destroy(){for(const[t,e]of this.sides.entries())e.destroy();for(const[t,e]of this.corners.entries())e.destroy()}move(t,e){this.target.updateTranslation(t,e)}resize(t,e,i){if(this.target instanceof j){const r=Math.abs(this.width),n=Math.abs(this.height),a=r/n,o=this.target.sx,h=this.target.sy,c=1e-6,l=Math.abs(r*o)<c?c*Mt(r*o||1,c):r*o,u=Math.abs(n*h)<c?c*Mt(n*h||1,c):n*h,m=t/l,g=e/u,C=c,x=i==="LEFT"||i==="BOTTOMLEFT"||i==="TOPLEFT"?1-m:i==="RIGHT"||i==="BOTTOMRIGHT"||i==="TOPRIGHT"?1+m:i==="TOP"?1-g:1+g;if(Et(o,x,C)||Et(h,x,C))return;const E=r*o*x,S=n*h*x;if(Math.abs(E)<C||Math.abs(S)<C)return;if(this.target.updateScale(x,x),i==="LEFT"){const L=n*h,R=n*this.target.sy;this.target.updateTranslation(t,(L-R)/2)}else if(i==="RIGHT"){const L=n*h,R=n*this.target.sy;this.target.updateTranslation(0,(L-R)/2)}else if(i==="TOP"){const L=r*o,R=r*this.target.sx;this.target.updateTranslation((L-R)/2,e)}else if(i==="BOTTOM"){const L=r*o,R=r*this.target.sx;this.target.updateTranslation((L-R)/2,0)}else i==="BOTTOMLEFT"?this.target.updateTranslation(t,0):i==="TOPLEFT"?this.target.updateTranslation(t,t/a*Math.sign(this.target.sx)):i==="TOPRIGHT"&&this.target.updateTranslation(0,-t/a*Math.sign(this.target.sx))}}reset(){this.target.setScale(1,1)}flip(t){const{x:e,y:i,sx:r,sy:n}=this.target;return t==="vertical"?this.target.flipVertical(this.height):this.target.flipHorizontal(this.width),{ref:this.target,start:{x:e,y:i,sx:r,sy:n},end:{x:this.target.x,y:this.target.y,sx:this.target.sx,sy:this.target.sy}}}addCorners(){for(const t of St){const e=new j(this.getCornersInScreenSpace(t,this.target.worldMatrix));e.color=this.mode===W.ACTIVE?st:Tt,this.corners.set(t,e)}}removeCorners(){this.corners.clear()}updateCorners(){for(const t of St){const e=this.getCornersInScreenSpace(t,this.target.worldMatrix),i=this.corners.get(t);i&&(i.setTranslation(e.x,e.y),i.width=e.width,i.height=e.height,i.color=this.mode===W.ACTIVE?st:Tt)}}addSides(){for(const t of ft){const e=new j(this.getSidesInScreenSpace(t,this.target.worldMatrix));e.color=this.mode===W.ACTIVE?st:Tt,this.sides.set(t,e)}}updateSides(){for(const t of ft){const e=this.getSidesInScreenSpace(t,this.target.worldMatrix),i=this.sides.get(t);i&&(i.setTranslation(e.x,e.y),i.width=e.width,i.height=e.height,i.color=this.mode===W.ACTIVE?st:Tt)}}}const Yt=[...St,...ft];class fi{constructor(t){this.targets=[],this.handles=new Map,this.borderSize=0,this.boxSize=0,this.scale=[1,1],t&&t.forEach(e=>this.add(e)),this.addHandles()}add(t){this.targets.includes(t)||this.targets.push(t)}remove(t){const e=this.targets.indexOf(t);e!=-1&&this.targets.splice(e,1)}render(t,e){this.update();for(const[i,r]of this.handles.entries())r.render(t,e)}update(){this.borderSize=Xt,this.boxSize=se/2,this.recalculateBounds(),this.updateHandles()}destroy(){for(const[t,e]of this.handles.entries())e.destroy()}move(t,e){for(const i of this.targets)i.updateTranslation(t,e)}resize(t,e,i,r){const n=this.width,a=this.height,o=i.includes("TOP"),h=i.includes("BOTTOM"),c=i.includes("LEFT"),l=i.includes("RIGHT"),u=c?this.x+n:l?this.x:this.x+n/2,m=o?this.y+a:h?this.y:this.y+a/2,g=1e-6,C=Math.abs(n)<g?n<0?-g:g:n,x=Math.abs(a)<g?a<0?-g:g:a,[E,S]=Q(r),L=t*E/C,R=e*S/x,T=i.includes("LEFT")?1-L:i.includes("RIGHT")?1+L:i==="TOP"?1-R:1+R;if(Et(this.scale[0],T,g)||Et(this.scale[1],T,g))return;const cs=n*T,ds=a*T;if(!(Math.abs(cs)<g||Math.abs(ds)<g))for(const Gt of this.targets){const ls=Gt.x,us=Gt.y,[Ue,We]=U(r,ls,us),fs=u+(Ue-u)*T,gs=m+(We-m)*T,ms=fs-Ue,ps=gs-We,ys=Math.abs(E)<g?E<0?-g:g:E,xs=Math.abs(S)<g?S<0?-g:g:S,ws=ms/ys,vs=ps/xs;Gt.updateScale(T,T),Gt.updateTranslation(ws,vs)}}flip(t,e,i){Q(t);const r=[],[n,a]=i(this.x,this.y);for(const o of this.targets){const h={ref:o,start:{x:o.x,y:o.y,sx:o.sx,sy:o.sy}};if(e==="vertical"){const c=o.height*o.sy;o.setTranslation(o.x,-o.y-c),o.flipVertical(o.height)}else{const c=o.width*o.sx;o.setTranslation(-o.x-c,o.y),o.flipHorizontal(o.width)}h.end={x:o.x,y:o.y,sx:o.sx,sy:o.sy},r.push(h)}return r}align(t){if(this.targets.length<=1)return;const e=[],i=[t==="top"?1:t==="bottom"?-1:0,t==="left"?1:t==="right"?-1:0];let r=i[0]!==0?1/0*i[0]:1/0*i[1];for(const[n,a]of this.targets.entries()){const o=a.getBoundingBox();r=t==="top"||t==="left"?Math.min(t==="top"?o.minY:o.minX,r):Math.max(t==="bottom"?o.maxY:o.maxX,r)}for(const n of this.targets){const a={ref:n,start:{x:n.x,y:n.y,sx:n.sx,sy:n.sy}},o=n.getBoundingBox();n.updateTranslation(t==="top"||t==="bottom"?0:r-(t==="left"?o.minX:o.maxX),t==="top"||t==="bottom"?r-(t==="top"?o.minY:o.maxY):0),a.end={x:n.x,y:n.y,sx:n.sx,sy:n.sy},e.push(a)}return e}normalize(t,e){const i=[],r=this.targets[0],n=t==="height"?e==="first"?r.height*r.sy:this.targets.reduce((a,o)=>a+Math.abs(o.height*o.sy),0)/this.targets.length:t==="width"?e==="first"?r.width*r.sx:this.targets.reduce((a,o)=>a+Math.abs(o.width*o.sx),0)/this.targets.length:t==="scale"?e==="first"?r.sx:this.targets.reduce((a,o)=>a+Math.abs(o.sx),0)/this.targets.length:e==="first"?r.width*r.height*r.sx*r.sy:this.targets.reduce((a,o)=>a+Math.abs(o.sx*o.width*o.height*o.sy),0)/this.targets.length;for(const a of this.targets){const o={ref:a,start:{x:a.x,y:a.y,sx:a.sx,sy:a.sy}},h=[(a.x+a.width*a.sx)/2,(a.y+a.height*a.sy)/2];if(t==="height"){const l=a.height*a.sy,u=Math.abs(n/l);a.updateScale(u,u)}else if(t==="width"){const l=a.width*a.sx,u=Math.abs(n/l);a.updateScale(u,u)}else if(t==="scale"){const l=Math.sign(a.sx),u=Math.sign(a.sy);a.setScale(n*l,n*u)}else if(t==="size"){const l=a.width*a.height*a.sx*a.sy,u=Math.sqrt(Math.abs(n/l));a.updateScale(u,u)}const c=[(a.x+a.width*a.sx)/2,(a.y+a.height*a.sy)/2];a.updateTranslation(h[0]-c[0],h[1]-c[1]),o.end={x:a.x,y:a.y,sx:a.sx,sy:a.sy},i.push(o)}return i}getPositions(){return[this.x,this.y,this.x+this.width,this.y,this.x+this.width,this.y+this.height,this.x,this.y+this.height]}hitTest(t,e,i){const[r,n]=U(i,t,e),a=4;for(const u of Yt){const m=this.getHandleConfig(u);if(r>=m.x-a&&r<=m.x+m.width+a&&n>=m.y-a&&n<=m.y+m.height+a)return u}const o=Math.min(this.x,this.x+this.width),h=Math.max(this.x,this.x+this.width),c=Math.min(this.y,this.y+this.height),l=Math.max(this.y,this.y+this.height);if(r>=o&&r<=h&&n>=c&&n<=l)return"CENTER"}getBounds(){const t=Array.from(this.targets);let e=1/0,i=1/0,r=-1/0,n=-1/0;for(const a of t){const[o,h]=U(a.worldMatrix),[c,l]=U(a.worldMatrix,a.width,a.height);e=Math.min(e,a.sx<0?c:o),i=Math.min(i,a.sy<0?l:h),r=Math.max(r,a.sx<0?o:c),n=Math.max(n,a.sy<0?h:l)}return{minX:e,minY:i,maxX:r,maxY:n}}recalculateBounds(){const{minX:t,minY:e,maxX:i,maxY:r}=this.getBounds();this.x=this.scale[0]<0?i:t,this.y=this.scale[1]<0?r:e,this.width=this.scale[0]*(i-t),this.height=this.scale[1]*(r-e)}addHandles(){for(const t of Yt){const e=this.getHandleConfig(t),i=new j(e);i.color=st,this.handles.set(t,i)}}updateHandles(){for(const t of Yt){const e=this.handles.get(t),i=this.getHandleConfig(t);e&&(e.setTranslation(i.x,i.y),e.width=i.width,e.height=i.height)}}getHandleConfig(t){let{x:e,y:i,width:r,height:n,borderSize:a,boxSize:o}=this;return{TOP:{x:e,y:i,width:r,height:a},BOTTOM:{x:e,y:i+n,width:r,height:a},LEFT:{x:e,y:i,width:a,height:n},RIGHT:{x:e+r,y:i,width:a,height:n},TOPLEFT:{x:e-o,y:i-o,width:o*2,height:o*2},TOPRIGHT:{x:e-o+r,y:i-o,width:o*2,height:o*2},BOTTOMLEFT:{x:e-o,y:i-o+n,width:o*2,height:o*2},BOTTOMRIGHT:{x:e-o+r,y:i-o+n,width:o*2,height:o*2}}[t]}}class J{constructor(t,e,i,r){this.minX=t,this.minY=e,this.maxX=i,this.maxY=r}getArea(){return(this.maxY-this.minY)*(this.maxX-this.minX)}static isColliding(t,e){return t.minX<=e.maxX&&t.maxX>=e.minX&&t.minY<=e.maxY&&t.maxY>=e.minY}}const de=["CENTER",...ft];class gi{constructor(t,e,i){this.width=0,this.height=0,this.rects=new Map,this.borderSize=0;const[r,n]=U(i,t,e);this.x=r,this.y=n,this.addRects()}getRectConfig(t){let{x:e,y:i,width:r,height:n,borderSize:a}=this;return{TOP:{x:e,y:i,width:r<0?r:r+a,height:a},BOTTOM:{x:e,y:i+n,width:r<0?r:r+a,height:a},LEFT:{x:n<0&&r<0?e-a:e,y:i,width:a,height:n<0&&r<0?n:n+a},RIGHT:{x:e+r,y:i,width:a,height:n<0?n:n+a},CENTER:{x:e,y:i,width:r,height:n}}[t]}render(t,e){this.update();for(const[i,r]of this.rects.entries())r.render(t,e)}update(){this.borderSize=Xt,this.updateRects()}destroy(){for(const[t,e]of this.rects.entries())e.destroy()}getBoundingBox(t){const[e,i]=t(this.x,this.y),[r,n]=t(this.x+this.width,this.y+this.height),a=Math.min(e,r),o=Math.max(e,r),h=Math.min(i,n),c=Math.max(i,n);return new J(a,h,o,c)}resize(t,e,i){const[r,n]=Q(i);this.width+=t*r,this.height+=e*n}addRects(){for(const t of de){const e=this.getRectConfig(t),i=new j(e);i.color=st,this.rects.set(t,i)}}updateRects(){for(const t of de){const e=this.rects.get(t),i=this.getRectConfig(t);e&&(e.setTranslation(i.x,i.y),e.width=i.width,e.height=i.height,t==="CENTER"&&(e.color=ei))}}}class mi{constructor(t={}){const{x:e=0,y:i=0,width:r=0,height:n=0,rotation:a=0,zoom:o=1}=t;this.x=e,this.y=i,this.width=r,this.height=n,this.rotation=a,this.zoom=o,p.makeObservable(this,{x:p.observable,y:p.observable,width:p.observable,height:p.observable,rotation:p.observable,zoom:p.observable,setX:p.action,setY:p.action,setPosition:p.action,incrementPosition:p.action,setWidth:p.action,setHeight:p.action,setSize:p.action,setZoom:p.action,setRotation:p.action,stateVector:p.computed})}setX(t){this.x=t}setY(t){this.y=t}setPosition(t,e){this.x=t,this.y=e}incrementPosition(t,e){this.x+=t,this.y+=e}setWidth(t){this.width=t}setHeight(t){this.height=t}setSize(t,e){this.width=t,this.height=e}setZoom(t){this.zoom=t}setRotation(t){this.rotation=t}get dimension(){return[this.width,this.height]}get position(){return[this.x,this.y]}get stateVector(){return[this.x,this.y,this.width,this.height,this.rotation,this.zoom]}get translationMatrix(){return b.translation(this.x,this.y)}get rotationMatrix(){return b.rotation(this.rotation)}get scaleMatrix(){return b.scaling(this.zoom,this.zoom)}get cameraMatrix(){const t=b.multiply(this.translationMatrix,this.rotationMatrix);return b.multiply(t,this.scaleMatrix)}get canvasMatrix(){return b.inverse(this.cameraMatrix)}}function le(s,t){s.setTranslation(t.x,t.y),s.setScale(t.sx,t.sy)}function ue(s,t,e){return{label:"Flip",do(){for(const i of s)le(i.ref,i.end);e&&(e.scale[t==="horizontal"?0:1]*=-1)},undo(){for(const i of s)le(i.ref,i.start);e&&(e.scale[t==="horizontal"?0:1]*=-1)}}}function fe(s,t){s.setTranslation(t.x,t.y),s.setScale(t.sx,t.sy)}function $t(s,t="Transform"){return{label:t,do(){for(const e of s)fe(e.ref,e.end)},undo(){for(const e of s)fe(e.ref,e.start)}}}class pi{#s;#i=new Set;#e=new Set;#t;#r;#a;get multiBoundingBox(){return this.#t}get boundingBoxes(){return this.#e}#o=!0;#n;#h;get selected(){return Array.from(this.#i)}set selected(t){this.#i.clear(),t.forEach(e=>{this.#i.add(e),this.#e.add(new ce(e))})}get marqueeBox(){return this.#r}set marqueeBox(t){this.#r=new gi(t.x,t.y,this.getWorldMatrix())}constructor(t,e,i,r,n,a,o,h){this.#n=i,this.#h=r,this.#s=t,this.#a=e,this.getWorldMatrix=n,this.getCanvasChildren=a,this.getWorldCoords=o,this.getMarqueeCoords=h;const c=Object.getPrototypeOf(this);for(const l of Object.getOwnPropertyNames(c)){const u=this[l];typeof u=="function"&&l!=="constructor"&&(this[l]=u.bind(this))}}add(t){t.forEach(e=>{this.#i.has(e)||(this.#i.add(e),this.#e.add(new ce(e)))}),this.#e.size>1&&(this.#e.forEach(e=>e.setPassive()),this.#t||(this.#t=new fi([])),this.selected.forEach(e=>this.#t.add(e)))}remove(t){t.forEach(e=>{if(!this.#i.has(e))return;this.#i.delete(e);const i=Array.from(this.#e.values()).find(r=>r.target===e);i?this.#e.delete(i):console.error("No matching bounding box found"),this.#t&&this.#t.remove(e)}),this.#e.size<=1&&(this.#e.forEach(e=>e.setActive()),this.#t=null)}deleteSelected(t){const e=[...this.#i];this.remove(e);for(const i of e)i.destroy();this.#s.push(si(t,e))}hitTest(t,e){if(this.#t){const i=this.#t.hitTest(t,e,this.getWorldMatrix());if(i)return i}for(const i of this.#e.values()){const r=i.hitTest(t,e,this.getWorldMatrix());if(r)return r}return null}isMultiBoundingBoxHit(t,e){return this.#t&&this.#t.hitTest(t,e,this.getWorldMatrix())}isBoundingBoxHit(t,e){return this.#e.size===1&&Array.from(this.#e)[0].hitTest(t,e,this.getWorldMatrix())}hitTestAdjustedCorner(t,e){if(this.#t){const i=this.#t.hitTest(t,e,this.getWorldMatrix());if(i)return this.#t.scale[0]*this.#t.scale[1]<0?ie(i):i}for(const i of this.#e.values()){const r=i.hitTest(t,e,this.getWorldMatrix());if(r)return i.target.sx*i.target.sy<0?ie(r):r}}update(){this.#e.forEach(t=>t.update()),this.#t&&this.#t.update()}render(t){if(!this.#r&&!this.#t&&this.#e.size===0)return;this.#n.useProgram(t);const e=this.#n.getUniformLocation(t,"u_z");e&&this.#n.uniform1f(e,1),this.#o&&this.#e.forEach(i=>i.render(this.#n,t)),this.#t&&this.#t.render(this.#n,t),this.#r&&this.#r.render(this.#n,t)}isRectSelected(t){return this.#i.has(t)}clear(){this.#i.clear(),this.#e.clear(),this.#t=null}clearMarquee(){this.#r&&(this.#r=null)}move(t,e){if(this.#t)this.#t.move(t,e);else for(const i of this.#e)i.move(t,e);this.#a.emit(N.Change)}resize(t,e,i){this.multiBoundingBox&&this.multiBoundingBox.resize(t,e,i,this.getWorldMatrix());for(const r of this.boundingBoxes)this.multiBoundingBox?r.update():r.resize(t,e,i);this.#a.emit(N.Change)}flip(t){if(this.multiBoundingBox){const e=this.multiBoundingBox.flip(this.getWorldMatrix(),t,this.getWorldCoords);this.#s.push(ue(e,t,this.multiBoundingBox))}else{const e=[];for(const i of this.boundingBoxes)e.push(i.flip(t));this.#s.push(ue(e,t))}this.#a.emit(N.Change)}alignSelection(t){if(!this.multiBoundingBox)return;const e=this.multiBoundingBox.align(t);this.#s.push($t(e)),this.#a.emit(N.Change)}normalize(t,e="first"){if(!this.multiBoundingBox)return;const i=this.multiBoundingBox.normalize(t,e);this.#s.push($t(i)),this.#a.emit(N.Change)}onPointerMove(t,e,i,r,n,a,o,h){if(a())o(t,e);else if(n&&n!=="CENTER")this.resize(i,r,n);else if(this.marqueeBox){this.marqueeBox.resize(i,r,h());const c=this.getCanvasChildren(),l=this.marqueeBox.getBoundingBox(this.getMarqueeCoords);for(const u of c){const m=u.getBoundingBox();J.isColliding(m,l)&&!this.#i.has(u)?this.add([u]):!J.isColliding(m,l)&&this.#i.has(u)&&this.remove([u])}}else this.move(i,r)}onSelectionPointerDown(t,e,i,r){e?(t||this.clear(),this.add([e])):(this.clear(),this.marqueeBox?this.clearMarquee():this.marqueeBox={x:i,y:r})}}var gt=(s=>(s[s.SELECT=0]="SELECT",s[s.PAN=1]="PAN",s))(gt||{});const yi={TOP:"ns-resize",BOTTOM:"ns-resize",LEFT:"ew-resize",RIGHT:"ew-resize",TOPLEFT:"nwse-resize",BOTTOMRIGHT:"nwse-resize",TOPRIGHT:"nesw-resize",BOTTOMLEFT:"nesw-resize",CENTER:"grab"};class xi{constructor(t){for(const e in t)e in t&&t[e]!==void 0&&(this[e]=t[e]);this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMoveWhileDown=this.onPointerMoveWhileDown.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.addOnPointerMove(),this.addOnWheel(t.onWheel),this.addOnPointerDown(),window.addEventListener("copy",async e=>{e.preventDefault(),!this.isContextMenuActive()&&await oe(this.getSelected())}),window.addEventListener("paste",async e=>{e.preventDefault(),!this.isContextMenuActive()&&await t.paste(this.state.lastPointerPos.x,this.state.lastPointerPos.y)})}changeMode(){this.state.toggleMode()}addOnPointerDown(){this.assignEventListener("pointerdown",this.onPointerDown)}addOnPointerMove(){this.assignEventListener("pointermove",t=>{[this.state.lastPointerPos.x,this.state.lastPointerPos.y]=this.getWorldCoords(t.clientX,t.clientY);let e=this.hitTestAdjustedCorner(this.state.lastPointerPos.x,this.state.lastPointerPos.y);this.setCursorStyle(yi[e]||"default")})}addOnWheel(t){this.assignEventListener("wheel",e=>{this.isContextMenuActive()||t(e)},{passive:!1})}onPointerDown(t){t.stopPropagation(),t.preventDefault(),this.eventHub.emit(X.Close);const[e,i]=this.getWorldCoords(t.clientX,t.clientY);this.state.initialize(e,i),this.currentTransform=void 0,this.state.mode===1?this.handlePanPointerDown():this.state.mode===0&&this.handleSelectPointerDown(t,e,i),document.addEventListener("pointermove",this.onPointerMoveWhileDown),document.addEventListener("pointerup",this.onPointerUp)}handlePanPointerDown(){this.setCanvasGlobalClick(!0),this.clearSelection()}handleSelectPointerDown(t,e,i){this.setCanvasGlobalClick(!1);const r=this.checkCollidingChild(e,i),n=this.checkIfSelectionHit(e,i);if(t.button===2)n||this.clearSelection(),r&&!this.isSelection(r)&&this.addSelection([r]);else{n?this.state.resizingDirection=n:this.onSelectionPointerDown(t.shiftKey,r,e,i);const a=this.getSelected();a.length&&(this.currentTransform={targets:a.map(o=>({ref:o,start:{x:o.x,y:o.y,sx:o.sx,sy:o.sy}}))})}}onPointerMoveWhileDown(t){if(t.buttons===2)return;const[e,i]=this.getWorldCoords(t.clientX,t.clientY),r=e-this.state.lastWorldX,n=i-this.state.lastWorldY;this.selectionPointerMove(this.state.startWorldX-e,this.state.startWorldY-i,r,n,this.state.resizingDirection),this.state.updateLastWorldCoord(e,i),this.setCursorStyle("grabbing")}onPointerUp(){if(document.removeEventListener("pointermove",this.onPointerMoveWhileDown),document.removeEventListener("pointerup",this.onPointerUp),this.setCanvasGlobalClick(!0),this.setCursorStyle("default"),this.currentTransform){const t=this.currentTransform.targets.map(e=>({ref:e.ref,start:e.start,end:{x:e.ref.x,y:e.ref.y,sx:e.ref.sx,sy:e.ref.sy}})).filter(e=>e.start.x!==e.end.x||e.start.y!==e.end.y||e.start.sx!==e.end.sx||e.start.sy!==e.end.sy);t.length&&this.history.push($t(t))}this.currentTransform=void 0,this.state.resizingDirection=null,this.closeMarquee(),this.eventHub.emit("save")}checkCollidingChild(t,e){const i=this.getChildren();for(let r=i.length-1;r>=0;r--){const n=i[r];if(n instanceof at&&n.hitTest&&n.hitTest(t,e))return n}return null}}class wi{constructor(t,e,i,r){this.history=t,this.deleteSelected=i,this.save=()=>e.emit(N.Save),this.assignEventListener=r,this.onKeyPressed=this.onKeyPressed.bind(this),this.addOnKeyPressed()}addOnKeyPressed(){document.addEventListener("keydown",this.onKeyPressed)}onKeyPressed(t){if(this.isCtrlZ(t)){t.preventDefault(),this.history.undo();return}if(this.isCtrlY(t)){t.preventDefault(),this.history.redo();return}if(this.isDelete(t)){this.deleteSelected();return}if(this.isSave(t)){t.preventDefault(),this.save();return}}isCtrlZ(t){return t.key.toLowerCase()==="z"&&(t.ctrlKey||t.metaKey)&&!t.shiftKey}isCtrlY(t){return t.key.toLowerCase()==="y"&&(t.ctrlKey||t.metaKey)&&!t.shiftKey}isDelete(t){return t.key==="Delete"}isSave(t){return t.key.toLowerCase()==="s"&&t.ctrlKey}}class vi{#s=!1;get isActive(){return this.#s}constructor(t,e,i,r,n){this.customContextMenu=a=>{a.preventDefault(),a.stopPropagation();const[o,h]=r(a.clientX,a.clientY);e(o,h)?t.emit(X.Open,a.clientX,a.clientY,"multi"):i(o,h)?t.emit(X.Open,a.clientX,a.clientY):t.emit(X.Open,a.clientX,a.clientY,"canvas")},t.on(X.Open,()=>{this.#s=!0}),t.on(X.Close,()=>{this.#s=!1}),n("contextmenu",this.customContextMenu)}}function ge(s,t){s.renderOrder=t.renderOrder}function Ci(s,t="Order"){return{label:t,do(){for(const e of s)ge(e.ref,e.end)},undo(){for(const e of s)ge(e.ref,e.start)}}}class Si{constructor(t=gt.SELECT){this.lastPointerPos={x:0,y:0},this.startWorldX=0,this.startWorldY=0,this.lastWorldX=0,this.lastWorldY=0,this.resizingDirection=null,this.mode=t}get isResizing(){return this.resizingDirection!==null}get dragDXFromStart(){return this.lastWorldX-this.startWorldX}get dragDYFromStart(){return this.lastWorldY-this.startWorldY}setMode(t){this.mode=t}toggleMode(){this.mode=this.mode===gt.PAN?gt.SELECT:gt.PAN}setResizingDirection(t){this.resizingDirection=t}clearResizingDirection(){this.resizingDirection=null}initialize(t,e){this.startWorldX=t,this.startWorldY=e,this.lastWorldX=t,this.lastWorldY=e,this.resizingDirection=null}updateLastWorldCoord(t,e){this.lastWorldX=t,this.lastWorldY=e}}class bi{constructor(){this.translation=[0,0],this.angleRadians=0,this.scale=[1,1],this.localMatrix=b.identity(),this.worldMatrix=b.identity(),this.children=[],this.parent=null,this.renderDirtyFlag=!0,p.makeObservable(this,{translation:p.observable.struct,angleRadians:p.observable,scale:p.observable.struct,localMatrix:p.observable.ref,worldMatrix:p.observable.ref,children:p.observable.shallow,parent:p.observable.ref,renderDirtyFlag:p.observable,x:p.computed,y:p.computed,scaleX:p.computed,scaleY:p.computed,dirty:p.computed,setTranslation:p.action,setScale:p.action,flipVertical:p.action,setAngle:p.action,getChild:p.action,appendChild:p.action,appendChildren:p.action,removeChild:p.action,clearChildren:p.action,setParent:p.action,markDirty:p.action,clearDirty:p.action,updateLocalMatrix:p.action,updateWorldMatrix:p.action,setWorldMatrix:p.action}),this.updateLocalMatrix(),this.updateWorldMatrix()}get x(){return this.translation[0]}get y(){return this.translation[1]}get scaleX(){return this.scale[0]}get scaleY(){return this.scale[1]}get dirty(){return this.renderDirtyFlag}setTranslation(t,e){this.translation[0]=t,this.translation[1]=e,this.markDirty()}updateTranslation(t,e){this.translation[0]+=t,this.translation[1]+=e,this.markDirty()}setScale(t,e){t===this.scale[0]&&e===this.scale[1]||(this.scale[0]=t,this.scale[1]=e,this.markDirty())}updateScale(t,e){this.scale[0]*=t,this.scale[1]*=e,this.markDirty()}flipVertical(t){this.translation[1]+=this.scale[1]*t,this.scale[1]*=-1,this.markDirty()}flipHorizontal(t){this.translation[0]+=this.scale[0]*t,this.scale[0]*=-1,this.markDirty()}setAngle(t){const i=(360-t)*Math.PI/180;i!==this.angleRadians&&(this.angleRadians=i,this.markDirty())}getChild(t){return this.children[t]}appendChild(t){this.children.includes(t)||(this.children.push(t),this.markDirty())}appendChildren(t){for(const e of t){if(this.children.includes(e))return;this.children.push(e)}this.markDirty()}removeChild(t){const e=this.children.indexOf(t);if(e<0)return;const i=this.children.splice(e,1);return t.state.setParent(null),this.markDirty(),i[0]}clearChildren(){if(this.children){for(const t of this.children)t.destroy();this.children=[],this.markDirty()}}setParent(t){this.parent!==t&&(this.parent=t,this.markDirty())}markDirty(){this.renderDirtyFlag||(this.renderDirtyFlag=!0,this.updateLocalMatrix())}clearDirty(){this.renderDirtyFlag&&(this.renderDirtyFlag=!1,this.updateLocalMatrix())}updateLocalMatrix(){const t=b.translation(this.translation[0],this.translation[1]),e=b.rotation(this.angleRadians),i=b.scaling(this.scale[0],this.scale[1]);this.localMatrix=b.multiply(b.multiply(t,e),i)}updateWorldMatrix(t){this.worldMatrix=t?b.multiply(t,this.localMatrix):this.localMatrix.slice();const e=this.worldMatrix;this.children.forEach(i=>{i.updateWorldMatrix(e)})}setWorldMatrix(t){this.worldMatrix=t}}class me{get x(){return this.state.x}get y(){return this.state.y}get sx(){return this.state.scaleX}get sy(){return this.state.scaleY}get dirty(){return this.state.dirty}get localMatrix(){return this.state.localMatrix}get worldMatrix(){return this.state.worldMatrix}get children(){return this.state.children}get parent(){return this.state.parent}get angleRadians(){return this.state.angleRadians}updateTranslation(t,e){this.state.updateTranslation(t,e)}setTranslation(t,e){this.state.setTranslation(t,e)}updateScale(t,e){this.state.updateScale(t,e)}setScale(t,e){this.state.setScale(t,e)}setAngle(t){return this.state.setAngle(t)}flipVertical(t){this.state.flipVertical(t)}flipHorizontal(t){this.state.flipHorizontal(t)}markDirty(){this.state.markDirty()}clearDirty(){this.state.clearDirty()}updateLocalMatrix(){this.state.updateLocalMatrix()}setWorldMatrix(t){this.state.setWorldMatrix(t)}addChild(t){this.state.appendChild(t)}addParent(t){return this.state.setParent(t)}clearChildren(){return this.state.clearChildren()}constructor(){this.state=new bi,this.setWorldMatrix=this.setWorldMatrix.bind(this),this.updateWorldMatrix=this.updateWorldMatrix.bind(this)}appendChild(t){return t.setParent(this),!t._emitter&&this._emitter&&(t._emitter=this._emitter),t}setParent(t){if(this.parent){const e=this.parent.children.indexOf(this);e>=0&&this.parent.children.splice(e,1)}t&&t.addChild(this),this.addParent(t)}updateWorldMatrix(t){this.updateLocalMatrix(),this.state.updateWorldMatrix(t)}addEventListener(t,e,i){const r=typeof e=="function"?e:e.handleEvent.bind(e);this._emitter.on(t,r)}removeEventListener(t,e,i){}dispatchEvent(t){return this._emitter.emit(t.type,t),!t.defaultPrevented}}class pe extends me{constructor(){super(...arguments),this.initialized=!1}updateVertexData(t){const e=this.getPositions();(!this.vertexArray||this.vertexArray.length!==e.length)&&(this.vertexArray=new Float32Array(e.length)),this.vertexArray.set(e),t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer),t.bufferData(t.ARRAY_BUFFER,this.vertexArray,t.STATIC_DRAW)}setUpVertexData(t,e){this.positionBuffer||(this.positionBuffer=t.createBuffer()),this.attributeLocation=t.getAttribLocation(e,"a_position")}setUpUniforms(t,e){this.resolutionLocation=t.getUniformLocation(e,"u_resolution"),this.matrixLocation=t.getUniformLocation(e,"u_matrix")}updateUniforms(t){t.uniform2f(this.resolutionLocation,t.canvas.width,t.canvas.height),t.uniformMatrix3fv(this.matrixLocation,!1,this.worldMatrix)}}const Wt=class Wt extends pe{constructor(t,e,i=1,r=1){super(),this._seq=Wt._seqCounter++,this.culled=!1,this._renderOrder=0,this.color=[1,0,.5,1],this.setTranslation(t,e),this.setScale(i,r)}get renderOrder(){return this._renderOrder}set renderOrder(t){this._renderOrder!==t&&(this._renderOrder=t,this.markDirty())}get seq(){return this._seq}getZ(){const e=this.renderOrder*1e-4+.5;return Math.max(0,Math.min(1,e))}render(t,e){this.updateWorldMatrix(this.parent?this.parent.worldMatrix:void 0),t.useProgram(e),this.dirty&&!this.culled&&(this.initialized||(this.setUpVertexData(t,e),this.setUpUniforms(t,e),this.initialized=!0),this.updateVertexData(t),this.clearDirty()),this.updateUniforms(t);const i=t.getUniformLocation(e,"u_color");i&&t.uniform4fv(i,this.color),this.culled||this.draw(t)}draw(t){t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer);const e=2,i=t.FLOAT;t.vertexAttribPointer(this.attributeLocation,e,i,!1,0,0),t.enableVertexAttribArray(this.attributeLocation),t.drawArrays(t.TRIANGLES,0,this.getVertexCount()),t.bindBuffer(t.ARRAY_BUFFER,null),t.disableVertexAttribArray(this.attributeLocation)}destroy(){this.positionBuffer&&(this.positionBuffer=void 0),this.initialized=!1}};Wt._seqCounter=0;let at=Wt;class j extends at{constructor(t){super(t.x,t.y,t.sx,t.sy),this._width=t.width??100,this._height=t.height??100}get width(){return this._width}set width(t){this._width!==t&&(this._width=t,this.markDirty())}get height(){return this._height}set height(t){this._height!==t&&(this._height=t,this.markDirty())}getVertexCount(){return 6}getPositions(){const i=this.width,r=this.height;return[0,0,0,r,i,0,i,0,0,r,i,r]}getBoundingBox(){const t=this.state.translation[0],e=t+this.width*this.state.scaleX,i=this.state.translation[1],r=i+this.height*this.state.scaleY,n=Math.min(t,e),a=Math.max(t,e),o=Math.min(i,r),h=Math.max(i,r);return this.AABB=new J(n,o,a,h),this.AABB}getEdge(){const t=this.x,e=this.y;return{minX:Math.min(t,t+this.width),maxX:Math.max(t,t+this.width),minY:Math.min(e,e+this.height),maxY:Math.max(e,e+this.height)}}hitTest(t,e){const[i,r]=Q(this.worldMatrix),[n,a]=bt(this.worldMatrix),[o,h]=U(this.parent.worldMatrix,t,e),[c,l]=U(this.worldMatrix),u=this.width*i*n,m=this.height*r*a,g=Math.min(c,c+u),C=Math.max(c,c+u),x=Math.min(l,l+m),E=Math.max(l,l+m);return o>=g&&o<=C&&h>=x&&h<=E}}class mt extends j{constructor(t){super(t),this.texCoordArray=new Float32Array([0,0,0,1,1,0,1,0,0,1,1,1]),this.useLowRes=!1,this.lowResNeedsRefresh=!0,this._src=t.src,this.loadImage(t.src,t.width,t.height)}get src(){return this._src}set src(t){this._src!==t&&(this._src=t,this.updateImageTexture(t),this.markDirty())}get fileId(){return this._fileId}set fileId(t){this._fileId=t}determineIfLowRes(t,e,i=.1){const r=t.getArea();return this.getBoundingBox().getArea()/r<i/e}async setUseLowRes(t,e){this.useLowRes===t&&!this.lowResNeedsRefresh||(this.useLowRes=t,(t&&e||this.lowResNeedsRefresh)&&await this.ensureLowResUploaded(e),this.markDirty(),this.lowResNeedsRefresh=!1)}loadImage(t,e,i){this.culled||this.updateImageTexture(t,e,i)}updateImageTexture(t,e,i){this._image=new Image,this._image.crossOrigin="anonymous",this._image.onload=async()=>{this.width=e??this._image.naturalWidth,this.height=i??this._image.naturalHeight;try{if(this.bitmap){try{this.bitmap.close()}catch{}this.bitmap=void 0}typeof createImageBitmap=="function"&&(this.bitmap=await createImageBitmap(this._image))}catch(r){console.warn("createImageBitmap failed, falling back to HTMLImageElement",r),this.bitmap=void 0}if(this.gl&&this.program)try{this.texture&&this.gl&&(this.gl.deleteTexture(this.texture),this.texture=void 0),this.initialiseTexture(),this.initialized=!0,this.markDirty()}catch(r){console.error("Failed to initialise texture on image load",r)}this.lowResNeedsRefresh=!0},this._image.onerror=r=>{console.error("Failed to load image:",t,r)},this._image.src=t}async ensureLowResUploaded(t){if(!(this.lowResTexture&&!this.lowResNeedsRefresh)&&!(!this._image||!this._image.complete))try{const i=this._image.naturalWidth,r=this._image.naturalHeight,n=Math.min(1,256/Math.max(1,Math.max(i,r))),a=Math.max(1,Math.round(i*n)),o=Math.max(1,Math.round(r*n));let h;typeof OffscreenCanvas<"u"?h=new OffscreenCanvas(a,o):(h=document.createElement("canvas"),h.width=a,h.height=o);const c=h.getContext("2d");c.clearRect(0,0,a,o);const l=Math.min(a/i,o/r),u=Math.round(i*l),m=Math.round(r*l),g=Math.round((a-u)/2),C=Math.round((o-m)/2);c.drawImage(this._image,0,0,i,r,g,C,u,m),this.lowResBitmap=await createImageBitmap(h),this.setLowResTextureFromBitmap(t,this.lowResBitmap)}catch(e){console.error("Failed to create/upload low-res image",e)}}setLowResTextureFromBitmap(t,e){if(this.lowResTexture){try{t.deleteTexture(this.lowResTexture)}catch{}this.lowResTexture=void 0}this.lowResTexture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.lowResTexture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),t.bindTexture(t.TEXTURE_2D,null),this.markDirty()}initialiseTexture(){!this.gl||!this.program||!this._image||!this._image.complete||this._image.naturalWidth===0||(this.setUpVertexData(this.gl,this.program),this.setUpTexData(this.gl,this.program),this.setTexture(this.gl),super.setUpUniforms(this.gl,this.program),this.samplerLocation=this.gl.getUniformLocation(this.program,"u_image"),this.samplerLocation&&this.gl.uniform1i(this.samplerLocation,0))}setUpTexData(t,e){this.texcoordBuffer||(this.texcoordBuffer=t.createBuffer()),this.texcoordLocation=t.getAttribLocation(e,"a_texCoord")}setTexture(t){if(this.texture){try{try{t.deleteTexture(this.texture)}catch{}}catch{}this.texture=void 0}this.texture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR);const e=this.bitmap??this._image;e&&t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),t.bindTexture(t.TEXTURE_2D,null)}updateVertexData(t){super.updateVertexData(t),t.bindBuffer(t.ARRAY_BUFFER,this.texcoordBuffer),t.bufferData(t.ARRAY_BUFFER,this.texCoordArray,t.STATIC_DRAW)}getVertexCount(){return 6}render(t,e){if(this.dirty&&!this.culled){if(this.updateWorldMatrix(this.parent?this.parent.worldMatrix:void 0),!this.initialized)if(this.gl=t,this.program=e,this.initialiseTexture(),this._image.complete&&this._image.naturalWidth>0)this.initialized=!0;else return;this.updateVertexData(t),this.clearDirty()}super.updateUniforms(t),this.culled||this.draw(t)}draw(t){t.bindBuffer(t.ARRAY_BUFFER,this.positionBuffer);const e=2,i=t.FLOAT,r=!1,n=0,a=0;t.vertexAttribPointer(this.attributeLocation,e,i,r,n,a),t.enableVertexAttribArray(this.attributeLocation),t.bindBuffer(t.ARRAY_BUFFER,this.texcoordBuffer),t.vertexAttribPointer(this.texcoordLocation,e,i,r,n,a),t.enableVertexAttribArray(this.texcoordLocation),t.activeTexture(t.TEXTURE0);try{const o=this.useLowRes&&this.lowResTexture?this.lowResTexture:this.texture;t.bindTexture(t.TEXTURE_2D,o),t.drawArrays(t.TRIANGLES,0,this.getVertexCount()),t.bindBuffer(t.ARRAY_BUFFER,null),t.disableVertexAttribArray(this.attributeLocation),t.disableVertexAttribArray(this.texcoordLocation)}catch(o){console.error(o)}}destroy(){if(this.texcoordBuffer){try{this.gl.deleteBuffer(this.texcoordBuffer)}catch{}this.texcoordBuffer=void 0}if(this.texture){try{this.gl.deleteTexture(this.texture)}catch{}this.texture=void 0}if(this.lowResTexture){try{this.gl.deleteTexture(this.lowResTexture)}catch{}this.lowResTexture=void 0}if(this.bitmap){try{this.bitmap.close()}catch{}this.bitmap=void 0}if(this.lowResBitmap){try{this.lowResBitmap.close()}catch{}this.lowResBitmap=void 0}this.texcoordLocation=void 0,this.samplerLocation=void 0;try{super.destroy()}catch{}}}var It=(s=>(s[s.NONE=0]="NONE",s[s.GRID=1]="GRID",s))(It||{});class ye extends pe{constructor(){super(...arguments),this.buffer=null,this.vertexCount=0,this.gridType=1,this.zoom=1}getPositions(){return new Float32Array([-1,-1,3,-1,-1,3])}changeGridType(t){this.gridType=t}render(t,e){if(this.buffer)t.bindBuffer(t.ARRAY_BUFFER,this.buffer);else{if(this.buffer=t.createBuffer(),!this.buffer)throw new Error("Failed to create grid buffer");const c=this.getPositions();this.vertexCount=c.length/2,t.bindBuffer(t.ARRAY_BUFFER,this.buffer),t.bufferData(t.ARRAY_BUFFER,c,t.STATIC_DRAW)}this.initialized||(this.setUpVertexData(t,e),this.setUpUniforms(t,e),this.initialized=!0);const i=t.drawingBufferWidth,r=t.drawingBufferHeight,n=b.inverse(b.projection(i,r)),a=b.inverse(this.worldMatrix),o=b.multiply(a,n);this.viewProjectionInvLocation&&t.uniformMatrix3fv(this.viewProjectionInvLocation,!1,new Float32Array(o)),this.zoomScaleLocation&&t.uniform1f(this.zoomScaleLocation,this.zoom),this.checkboardStyleLocation&&t.uniform1f(this.checkboardStyleLocation,this.gridType);const h=t.getAttribLocation(e,"a_Position");if(h===-1)throw new Error("Attribute a_Position not found in grid program");t.vertexAttribPointer(h,2,t.FLOAT,!1,0,0),t.enableVertexAttribArray(h),t.drawArrays(t.TRIANGLES,0,this.vertexCount),t.bindBuffer(t.ARRAY_BUFFER,null),t.disableVertexAttribArray(h)}destroy(){this.buffer&&(this.buffer=null)}hitTest(t,e){return!1}setUpUniforms(t,e){const i=new Float32Array([1,0,0,0,1,0,0,0,1]);this.viewProjectionInvLocation=t.getUniformLocation(e,"u_ViewProjectionInvMatrix"),this.zoomScaleLocation=t.getUniformLocation(e,"u_ZoomScale"),this.checkboardStyleLocation=t.getUniformLocation(e,"u_CheckboardStyle"),t.uniformMatrix3fv(this.viewProjectionInvLocation,!1,i),t.uniform1f(this.zoomScaleLocation,this.zoom),t.uniform1f(this.checkboardStyleLocation,1)}}const xe=.02,we=20;class ve{constructor(t,e,i,r){this.viewportX=0,this.viewportY=0,this.state=t,this.updateCameraPos=this.updateCameraPos.bind(this),this.updateZoom=this.updateZoom.bind(this),this.onWheel=this.onWheel.bind(this),this.worldToCamera=this.worldToCamera.bind(this),this.getWorldCoords=r,this.setWorldMatrix=e,this.updateWorldMatrix=i,this.updateReaction=p.reaction(()=>this.state.stateVector,()=>this.updateViewMatrix()),this.updateViewMatrix()}updateViewMatrix(){this.setWorldMatrix(this.state.canvasMatrix),this.updateWorldMatrix()}setViewPortDimension(t,e){this.state.width!==t&&this.state.setWidth(t),this.state.height!==e&&this.state.setHeight(e)}getBoundingBox(){const[t,e]=this.getWorldCoords(this.viewportX,this.viewportY),[i,r]=this.getWorldCoords(this.state.width+this.viewportX,this.state.height+this.viewportY);return new J(t,e,i,r)}onWheel(t){t.preventDefault();const i=Math.exp(-t.deltaY*.003);this.updateZoom(t.clientX,t.clientY,i)}updateCameraPos(t,e){this.state.incrementPosition(t,e)}updateZoom(t,e,i){const[r,n]=this.getWorldCoords(t,e);this.state.setZoom(Math.min(we,Math.max(xe,this.state.zoom*i)));const[a,o]=this.getWorldCoords(t,e);this.state.incrementPosition(r-a,n-o)}worldToCamera(t,e){const i=this.state.cameraMatrix,r=i[0]*t+i[1]*e+i[2],n=i[3]*t+i[4]*e+i[5];return[r,n]}dispose(){this.updateReaction&&(this.updateReaction(),this.updateReaction=void 0)}}const Ce="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjYjNiM2IzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xLjUgNmEyLjI1IDIuMjUgMCAwIDEgMi4yNS0yLjI1aDE2LjVBMi4yNSAyLjI1IDAgMCAxIDIyLjUgNnYxMmEyLjI1IDIuMjUgMCAwIDEtMi4yNSAyLjI1SDMuNzVBMi4yNSAyLjI1IDAgMCAxIDEuNSAxOHpNMyAxNi4wNlYxOGMwIC40MTQuMzM2Ljc1Ljc1Ljc1aDE2LjVBLjc1Ljc1IDAgMCAwIDIxIDE4di0xLjk0bC0yLjY5LTIuNjg5YTEuNSAxLjUgMCAwIDAtMi4xMiAwbC0uODguODc5bC45Ny45N2EuNzUuNzUgMCAxIDEtMS4wNiAxLjA2bC01LjE2LTUuMTU5YTEuNSAxLjUgMCAwIDAtMi4xMiAwem0xMC4xMjUtNy44MWExLjEyNSAxLjEyNSAwIDEgMSAyLjI1IDBhMS4xMjUgMS4xMjUgMCAwIDEtMi4yNSAwIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=",ot=240;function Se(s){return{x:s.x??0,y:s.y??0,sx:s.sx??1,sy:s.sy??1}}function jt(s){return s.children.map(be)}function be(s){return s instanceof mt?{type:"Img",id:s.seq,renderOrder:s.renderOrder,transform:Se(s),width:s.width,height:s.height,fileId:s.fileId,children:s.children?.length?jt(s):void 0}:s instanceof j?{type:"Rect",id:s.seq,renderOrder:s.renderOrder,transform:Se(s),width:s.width,height:s.height,color:s.color,children:s.children?.length?jt(s):void 0}:s instanceof ye?{type:"Grid",style:s.gridType}:{type:"Renderable",children:s.children?.length?jt(s):void 0}}function Vt(s,t){const{gl:e}=s;return{version:1,canvas:{width:e.canvas.width,height:e.canvas.height,dpr:window.devicePixelRatio||1},camera:{x:s.camera.state.x,y:s.camera.state.y,zoom:s.camera.state.zoom},root:be(s),files:t}}async function qt(s,t,e,i){t.children.length=0,s.camera&&(t.camera.state.setZoom(s.camera.zoom),t.camera.state.setX(s.camera.x),t.camera.state.setY(s.camera.y));async function r(n,a){let o;switch(n.type){case"Rect":o=new j({x:n.transform.x,y:n.transform.y,width:n.width,height:n.height}),o.setScale(n.transform.sx,n.transform.sy),t.appendChild(o);break;case"Img":let h;try{h=s.files&&Array.isArray(s.files)?s.files.find(g=>g.id===n.fileId)?.dataURL??Ce:Ce,i&&i(h);const c=n.width,l=n.height,u=await Ei(h,c*n.transform.sx,l*n.transform.sy);o=new mt({x:n.transform.x,y:n.transform.y,src:u,width:c,height:l}),e(n.fileId).then(m=>{o.src=m.dataURL}).catch(m=>console.error("Image not loaded",m)),o.fileId=n.fileId??await Ht(h),o.setScale(n.transform.sx,n.transform.sy),t.appendChild(o),typeof n.renderOrder=="number"&&(o.renderOrder=n.renderOrder)}catch{console.error(`Failed to match image to restore with source: ${h}`)}finally{break}case"Grid":a instanceof pt&&(a.grid.gridType=n.style);break}if(n.children)for(const h of n.children)await r(h,o)}return await r(s.root,t),t}async function Mi(s){const t=new Image;return t.crossOrigin="anonymous",new Promise((e,i)=>{t.onload=()=>e(t),t.onerror=r=>i(r),t.src=s})}async function Ei(s,t,e,i="#d6d6d6ff"){let r=null,n;s instanceof Blob?(r=URL.createObjectURL(s),n=r):n=s;try{let a=null;try{a=await Mi(n)}catch{}const o=t&&t>0?t:a?.naturalWidth??ot,h=e&&e>0?e:a?.naturalHeight??ot,c=document.createElement("canvas");c.width=o,c.height=h;const l=c.getContext("2d");if(l.fillStyle=i,l.fillRect(0,0,o,h),a){const u=Math.min(o/a.naturalWidth,h/a.naturalHeight),m=a.naturalHeight*u,g=a.naturalWidth*u;let C=ot,x=ot;(ot>m||ot>g)&&(C=g,x=m);const E=Math.round((o-C)/2),S=Math.round((h-x)/2);l.drawImage(a,0,0,a.naturalWidth,a.naturalHeight,E,S,C,x)}return c.toDataURL("image/png")}finally{r&&URL.revokeObjectURL(r)}}const I=class I extends me{constructor(e,i,r,n,a,o){super();B(this,G);B(this,H);B(this,et);B(this,ct);B(this,v);B(this,Y);B(this,dt);B(this,it);B(this,$);B(this,Z);B(this,P);B(this,lt);B(this,Ft);B(this,ut);A(this,Z,!0),this.orderDirty=!0,this.renderList=[],A(this,G,e),A(this,H,r),A(this,et,i),A(this,$,new ye),A(this,v,e.getContext("webgl",{alpha:!0,premultipliedAlpha:!1})),f(this,v).enable(f(this,v).BLEND),f(this,v).blendFunc(f(this,v).SRC_ALPHA,f(this,v).ONE_MINUS_SRC_ALPHA),f(this,v).getExtension("OES_standard_derivatives"),f(this,v).enable(f(this,v).DEPTH_TEST),f(this,v).depthFunc(f(this,v).LEQUAL),A(this,Y,Nt(f(this,v),oi,hi)),A(this,dt,Nt(f(this,v),li,ui)),A(this,it,Nt(f(this,v),ci,di)),this.writeToStorage=n,this.saveImgFileToStorage=a,this.getContainerDimension=o,this.engine=this.engine.bind(this),this.getBoundingClientRect=this.getBoundingClientRect.bind(this),this.appendChild=this.appendChild.bind(this),this.addImageToCanvas=this.addImageToCanvas.bind(this),this.setShapeZOrder=this.setShapeZOrder.bind(this),this.toggleGrid=this.toggleGrid.bind(this),this.changeMode=this.changeMode.bind(this),this.getSelected=this.getSelected.bind(this),this.updateZoomByFixedAmount=this.updateZoomByFixedAmount.bind(this),this.assignEventListener=this.assignEventListener.bind(this),this.getWorldsCoordsFromCanvas=(m,g)=>K(m,g,this);const h=(m,g)=>K(m+this.camera.viewportX,g+this.camera.viewportY,this);this.exportState=this.exportState.bind(this),this.importState=this.importState.bind(this),this.clearChildren=this.clearChildren.bind(this),A(this,P,new pi(i,r,this.gl,f(this,Y),()=>this.worldMatrix,()=>this.children,this.getWorldsCoordsFromCanvas,h));const c=new mi({});A(this,ct,new ve(c,this.setWorldMatrix,this.updateWorldMatrix,this.getWorldsCoordsFromCanvas)),A(this,Ft,new wi(i,r,()=>this.selectionManager.deleteSelected(this),this.assignEventListener)),A(this,ut,new vi(r,this.selectionManager.isMultiBoundingBoxHit,this.selectionManager.isBoundingBoxHit,this.getWorldsCoordsFromCanvas,this.assignEventListener));const l=new Si,u={history:i,eventHub:r,state:l,isContextMenuActive:()=>f(this,ut).isActive,getSelected:()=>f(this,P).selected,getChildren:()=>this.children,getWorldMatrix:()=>this.worldMatrix,getCanvasGlobalClick:()=>this.isGlobalClick,setCanvasGlobalClick:m=>this.isGlobalClick=m,getWorldCoords:this.getWorldsCoordsFromCanvas,updateCameraPos:this.camera.updateCameraPos,onWheel:this.camera.onWheel,setCursorStyle:m=>e.style.cursor=m,paste:(m,g)=>he(m,g,this,i),assignEventListener:this.assignEventListener,closeMarquee:f(this,P).clearMarquee,selectionPointerMove:(m,g,C,x,E)=>f(this,P).onPointerMove(m,g,C,x,E,()=>this.isGlobalClick,this.camera.updateCameraPos,()=>this.worldMatrix),onSelectionPointerDown:this.selectionManager.onSelectionPointerDown,checkIfSelectionHit:this.selectionManager.hitTest,addSelection:this.selectionManager.add,clearSelection:this.selectionManager.clear,isSelection:this.selectionManager.isRectSelected,hitTestAdjustedCorner:this.selectionManager.hitTestAdjustedCorner};A(this,lt,new xi(u)),f(this,H).on("save",this.writeToStorage)}markOrderDirty(){this.orderDirty=!0}get gl(){return f(this,v)}get grid(){return f(this,$)}get history(){return f(this,et)}get eventHub(){return f(this,H)}get pointerEventManager(){return f(this,lt)}get selectionManager(){return f(this,P)}get contextMenuManager(){return f(this,ut)}get canvas(){return f(this,G)}get camera(){return f(this,ct)}get isGlobalClick(){return f(this,Z)}set isGlobalClick(e){A(this,Z,e)}get basicShapeProgram(){return f(this,Y)}engine(){return this}get totalNumberOfChildren(){return this.children.length}get numberOfChildrenRendered(){return this.renderList.length}appendChild(e){if(super.appendChild(e),e instanceof at){const i=this.children.map(n=>n.renderOrder),r=i.length?Math.max(...i):0;e.renderOrder=r+1}return this.markOrderDirty(),e}removeChild(e){this.state.removeChild(e),f(this,P)&&f(this,P).remove([e]),e.destroy(),this.markOrderDirty()}getChild(e){return this.state.getChild(e)}updateWorldMatrix(){f(this,$).updateWorldMatrix(this.worldMatrix),this.children.forEach(e=>{e.updateWorldMatrix(this.worldMatrix)}),f(this,P).update()}render(){f(this,v).clearColor(0,0,0,0),f(this,v).clear(f(this,v).COLOR_BUFFER_BIT|f(this,v).DEPTH_BUFFER_BIT),f(this,v).viewport(0,0,f(this,v).canvas.width,f(this,v).canvas.height);const e=this.canvas.parentElement.getBoundingClientRect();this.camera.setViewPortDimension(e.width,e.height),f(this,v).useProgram(f(this,it));const i=f(this,v).getUniformLocation(f(this,it),"u_z");f(this,v).uniform1f(i,0),f(this,$).render(f(this,v),f(this,it));const r=this.camera.getBoundingBox();this.renderList=[];for(const l of this.children)J.isColliding(r,l.getBoundingBox())?(this.renderList.push(l),l.culled=!1):l.culled=!0;const[n,a]=K(0,0,this),[o,h]=K(window.screen.width,window.screen.height,this),c=new J(n,a,o,h);this.renderList.forEach(l=>{if(l instanceof mt){const u=l.determineIfLowRes(c,this.camera.state.zoom);l.setUseLowRes(u,this.gl)}});for(const l of this.renderList){let u;l instanceof mt?u=f(this,dt):l instanceof at&&(u=f(this,Y)),f(this,v).useProgram(u);const m=f(this,v).getUniformLocation(u,"u_z");f(this,v).uniform1f(m,l.getZ()),l.render(f(this,v),u)}f(this,P).render(f(this,Y))}destroy(){f(this,v).deleteProgram(f(this,Y)),f(this,v).deleteProgram(f(this,dt)),this.children.forEach(e=>{"destroy"in e&&e.destroy()}),this.clearChildren()}getDOM(){return f(this,G)}assignEventListener(e,i,r){f(this,G).addEventListener(e,i,r)}hitTest(e,i){return A(this,Z,!0),f(this,Z)}async addImageToCanvas(e,i,r,n=1,a=1,o=!1){const h=new mt({x:i,y:r,src:e,sx:n,sy:a});if(this.saveImgFileToStorage(e).then(c=>h.fileId=c),o){const c=new Image;c.src=e.startsWith("data:image/png")?e:await ae(e),c.onload=()=>{const l=c.naturalWidth||c.width||0,u=c.naturalHeight||c.height||0;(l||u)&&h.updateTranslation(-l/2,-u/2),h.src=c.src,this.appendChild(h)}}return f(this,H).emit("save"),f(this,H).emit(N.Change),h}exportState(){return Vt(this)}async importState(e,i){return await qt(e,this,i)}clearChildren(){this.selectionManager.clear(),this.state.clearChildren(),f(this,et).clear()}toggleGrid(){f(this,$).changeGridType(f(this,$).gridType===It.GRID?It.NONE:It.GRID)}getSelected(){return f(this,P).selected}setShapeZOrder(e=!0){if(f(this,P).multiBoundingBox||f(this,P).boundingBoxes.size!=1)return;const i=Array.from(f(this,P).boundingBoxes)[0].target,r={ref:i,start:{renderOrder:i.renderOrder}},n=this.children.map(h=>h.renderOrder);if(n.length===0)throw new Error("Order unexpected missing.");const a=Math.max(...n),o=Math.min(...n);i.renderOrder=e?a+1:o-1,r.end={renderOrder:i.renderOrder},this.markOrderDirty(),f(this,et).push(Ci([r])),f(this,H).emit(N.Change)}changeMode(){f(this,lt).changeMode(),f(this,P).clear()}updateZoomByFixedAmount(e=1){f(this,ct).updateZoom(f(this,G).width/2,f(this,G).height/2,Math.exp(.5*.3*e))}getBoundingClientRect(){return f(this,G).getBoundingClientRect()}wrapWebGLContext(e){const i=e.createTexture.bind(e);e.createTexture=()=>(I.webglStats.texturesCreated++,console.log(`Textures created: ${I.webglStats.texturesCreated}`),i());const r=e.deleteTexture.bind(e);e.deleteTexture=o=>(o&&(I.webglStats.texturesDeleted++,console.log(`Textures deleted: ${I.webglStats.texturesDeleted}`)),r(o));const n=e.createShader.bind(e);e.createShader=o=>(I.webglStats.shadersCreated++,console.log(`Shaders created: ${I.webglStats.shadersCreated}`),n(o));const a=e.deleteShader.bind(e);return e.deleteShader=o=>(o&&(I.webglStats.shadersDeleted++,console.log(`Shaders deleted: ${I.webglStats.shadersDeleted}`)),a(o)),e}static getWebGLStats(){return{...I.webglStats,buffersLeaked:I.webglStats.buffersCreated-I.webglStats.buffersDeleted,programsLeaked:I.webglStats.programsCreated-I.webglStats.programsDeleted,texturesLeaked:I.webglStats.texturesCreated-I.webglStats.texturesDeleted,shadersLeaked:I.webglStats.shadersCreated-I.webglStats.shadersDeleted}}};G=new WeakMap,H=new WeakMap,et=new WeakMap,ct=new WeakMap,v=new WeakMap,Y=new WeakMap,dt=new WeakMap,it=new WeakMap,$=new WeakMap,Z=new WeakMap,P=new WeakMap,lt=new WeakMap,Ft=new WeakMap,ut=new WeakMap,I.webglStats={buffersCreated:0,buffersDeleted:0,programsCreated:0,programsDeleted:0,texturesCreated:0,texturesDeleted:0,shadersCreated:0,shadersDeleted:0};let pt=I;const Me=25;class Ti{constructor(){this._undoStack=[],this._redoStack=[],this._openGroup=null}get undoStack(){return this._undoStack}begin(t){if(this._openGroup)throw new Error("History group already open");this._openGroup=[],this._openLabel=t}push(t){if(this._openGroup)this._openGroup.push(t);else{for(;this._undoStack.length>=Me;)this._undoStack.shift();this._undoStack.push([t]),t.do(),this._redoStack.length=0}}commit(){if(!this._openGroup)return;const t=this._openGroup;this._openGroup=null;for(const e of t)e.do();for(;this._undoStack.length>=Me;)this._undoStack.shift();this._undoStack.push(t),this._redoStack.length=0,this._openLabel=void 0}cancel(){this._openGroup=null,this._openLabel=void 0}canUndo(){return this._undoStack.length>0}canRedo(){return this._redoStack.length>0}undo(){const t=this._undoStack.pop();if(t){for(let e=t.length-1;e>=0;e--)t[e].undo();this._redoStack.push(t)}}redo(){const t=this._redoStack.pop();if(t){for(const e of t)e.do();this._undoStack.push(t)}}clear(){this._undoStack.length=0,this._redoStack.length=0,this._openGroup=null,this._openLabel=void 0}}const _i=s=>(t,e)=>{e!==void 0?e.addInitializer((()=>{customElements.define(s,t)})):customElements.define(s,t)};const Rt=globalThis,Zt=Rt.ShadowRoot&&(Rt.ShadyCSS===void 0||Rt.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,Ee=Symbol(),Te=new WeakMap;let Ii=class{constructor(t,e,i){if(this._$cssResult$=!0,i!==Ee)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const e=this.t;if(Zt&&t===void 0){const i=e!==void 0&&e.length===1;i&&(t=Te.get(e)),t===void 0&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),i&&Te.set(e,t))}return t}toString(){return this.cssText}};const Ri=s=>new Ii(typeof s=="string"?s:s+"",void 0,Ee),Pi=(s,t)=>{if(Zt)s.adoptedStyleSheets=t.map((e=>e instanceof CSSStyleSheet?e:e.styleSheet));else for(const e of t){const i=document.createElement("style"),r=Rt.litNonce;r!==void 0&&i.setAttribute("nonce",r),i.textContent=e.cssText,s.appendChild(i)}},_e=Zt?s=>s:s=>s instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return Ri(e)})(s):s;const{is:Ai,defineProperty:Oi,getOwnPropertyDescriptor:Li,getOwnPropertyNames:Di,getOwnPropertySymbols:Bi,getPrototypeOf:zi}=Object,Pt=globalThis,Ie=Pt.trustedTypes,ki=Ie?Ie.emptyScript:"",Ui=Pt.reactiveElementPolyfillSupport,yt=(s,t)=>s,Kt={toAttribute(s,t){switch(t){case Boolean:s=s?ki:null;break;case Object:case Array:s=s==null?s:JSON.stringify(s)}return s},fromAttribute(s,t){let e=s;switch(t){case Boolean:e=s!==null;break;case Number:e=s===null?null:Number(s);break;case Object:case Array:try{e=JSON.parse(s)}catch{e=null}}return e}},Re=(s,t)=>!Ai(s,t),Pe={attribute:!0,type:String,converter:Kt,reflect:!1,useDefault:!1,hasChanged:Re};Symbol.metadata??=Symbol("metadata"),Pt.litPropertyMetadata??=new WeakMap;class xt extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=Pe){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),r=this.getPropertyDescriptor(t,i,e);r!==void 0&&Oi(this.prototype,t,r)}}static getPropertyDescriptor(t,e,i){const{get:r,set:n}=Li(this.prototype,t)??{get(){return this[e]},set(a){this[e]=a}};return{get:r,set(a){const o=r?.call(this);n?.call(this,a),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??Pe}static _$Ei(){if(this.hasOwnProperty(yt("elementProperties")))return;const t=zi(this);t.finalize(),t.l!==void 0&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(yt("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(yt("properties"))){const e=this.properties,i=[...Di(e),...Bi(e)];for(const r of i)this.createProperty(r,e[r])}const t=this[Symbol.metadata];if(t!==null){const e=litPropertyMetadata.get(t);if(e!==void 0)for(const[i,r]of e)this.elementProperties.set(i,r)}this._$Eh=new Map;for(const[e,i]of this.elementProperties){const r=this._$Eu(e,i);r!==void 0&&this._$Eh.set(r,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const r of i)e.unshift(_e(r))}else t!==void 0&&e.push(_e(t));return e}static _$Eu(t,e){const i=e.attribute;return i===!1?void 0:typeof i=="string"?i:typeof t=="string"?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$EO??=new Set).add(t),this.renderRoot!==void 0&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return Pi(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),r=this.constructor._$Eu(t,i);if(r!==void 0&&i.reflect===!0){const n=(i.converter?.toAttribute!==void 0?i.converter:Kt).toAttribute(e,i.type);this._$Em=t,n==null?this.removeAttribute(r):this.setAttribute(r,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,r=i._$Eh.get(t);if(r!==void 0&&this._$Em!==r){const n=i.getPropertyOptions(r),a=typeof n.converter=="function"?{fromAttribute:n.converter}:n.converter?.fromAttribute!==void 0?n.converter:Kt;this._$Em=r;const o=a.fromAttribute(e,n.type);this[r]=o??this._$Ej?.get(r)??o,this._$Em=null}}requestUpdate(t,e,i){if(t!==void 0){const r=this.constructor,n=this[t];if(i??=r.getPropertyOptions(t),!((i.hasChanged??Re)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(r._$Eu(t,i))))return;this.C(t,e,i)}this.isUpdatePending===!1&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:r,wrapped:n},a){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,a??e??this[t]),n!==!0||a!==void 0)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),r===!0&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const t=this.scheduleUpdate();return t!=null&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[r,n]of this._$Ep)this[r]=n;this._$Ep=void 0}const i=this.constructor.elementProperties;if(i.size>0)for(const[r,n]of i){const{wrapped:a}=n,o=this[r];a!==!0||this._$AL.has(r)||o===void 0||this.C(r,void 0,n,o)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach((i=>i.hostUpdate?.())),this.update(e)):this._$EM()}catch(i){throw t=!1,this._$EM(),i}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach((e=>e.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach((e=>this._$ET(e,this[e]))),this._$EM()}updated(t){}firstUpdated(t){}}xt.elementStyles=[],xt.shadowRootOptions={mode:"open"},xt[yt("elementProperties")]=new Map,xt[yt("finalized")]=new Map,Ui?.({ReactiveElement:xt}),(Pt.reactiveElementVersions??=[]).push("2.1.1");class Ae{constructor(t,e){this.options=[],this.rootNode=e,this._el=document.createElement("div"),this._el.classList.add("context-menu"),t.options.forEach((i,r)=>{this.createOptionGroup(i),r!==t.options.length-1&&this.addDivider()}),this._el.addEventListener("contextmenu",i=>{i.preventDefault()})}get el(){return this._el}attachToParent(t){t.appendChild(this.el)}createOptionGroup(t){const e=new Wi(t,this.rootNode);this.options.push(e),this.el.appendChild(e.el)}addDivider(){const t=document.createElement("hr");t.classList.add("context-menu-divider"),this.el.appendChild(t)}}class Wi{constructor(t,e){this.childOptions=[],this.rootNode=e,this._el=document.createElement("div"),this.createOptionElement=this.createOptionElement.bind(this),t.childOptions.forEach(i=>this.createOptionElement(i))}get el(){return this._el}attachToParent(t){t.appendChild(this.el)}createOptionElement(t){t.parent=this;const e=new Fi(t,this.rootNode);this.childOptions.push(e)}}class Fi{get el(){return this._el}constructor(t,e){this.displayText=t.text,this.rootNode=e,this.parent=t.parent,this._el=document.createElement("button"),this._el.textContent=t.text,this._el.classList.add("context-menu-option"),this.parent.el.appendChild(this._el),"onClick"in t&&this._el.addEventListener("click",t.onClick),this._el.addEventListener("pointerenter",i=>Gi(i,t,this._el,this.rootNode)),this._el.addEventListener("contextmenu",i=>{i.preventDefault()})}}function Gi(s,t,e,i){if(!i)return;const r=i.querySelector(".sub-context-menu");if(r&&r.remove(),t.subMenu){const n=new Ae(t.subMenu,this);i.appendChild(n.el),n.el.id=`${t.text}-context-menu`,n.el.classList.add("sub-context-menu");const a=i.getBoundingClientRect(),o=e.getBoundingClientRect(),h=n.el.getBoundingClientRect(),c=a.right-a.left,l=a.bottom-a.top,u=o.right+h.width;o.top+h.height>l?n._el.style.top=`${o.bottom-h.height}px`:n._el.style.top=`${o.top}px`,u>c?n._el.style.left=`${o.left-h.width}px`:n._el.style.left=`${o.right}px`}}const At=5;function Ot(s){const t=this;return function(...e){const i=s.apply(t,e);return t.clearContextMenu(),i}}function Xi(s,t,e="single"){const i=new Ae(e==="single"?this.singleImageMenuOptions:e==="multi"?this.multiImageMenuOptions:this.canvasImageMenuOptions,this.rootDiv);if(!this.rootDiv){console.error("Can't add to parent div");return}i.attachToParent(this.rootDiv);const r=this.getBoundingClientRect(),n=s-r.left,a=t-r.top,o=r.right-r.left,h=r.bottom-r.top,c=i.el.getBoundingClientRect(),l=[n+c.width>o?1:0,a+c.height>h?1:0],u=c.height*l[1],m=c.width*l[0];if(u>h){const g=h-2*At;i._el.style.height=`${g}px`,i._el.style.top=`${At}px`}else i._el.style.top=`${a-u}px`;m>o?(i._el.style.width=`${o-2*At}px`,i._el.style.left=`${At}px`):i._el.style.left=`${n-m}px`}function Ni(){const s=this.renderRoot.querySelector(".context-menu");s&&(s.remove(),this.eventHub.emit(X.Close))}function Hi(){return this.renderRoot.querySelector(".context-menu")!==null}function Yi(){const s=Ot.bind(this);return{options:[{childOptions:[{text:"Cut",onClick:async()=>{await this.copyImage.bind(this)(),s(this.deleteSelectedImages.bind(this))()}},{text:"Copy",onClick:s(this.copyImage.bind(this))},{text:"Paste",onClick:t=>s(this.pasteImage.bind(this))(t)},{text:"Delete",onClick:s(this.deleteSelectedImages.bind(this))}]},{childOptions:[{text:"Flip Horizontal",onClick:s(this.flipHorizontal.bind(this))},{text:"Flip Vertical",onClick:s(this.flipVertical.bind(this))}]}]}}function $i(s){const t=Ot.bind(this);return{options:[...s??[],{childOptions:[{text:"Send to Front",onClick:()=>t(this.sendShapeToNewZOrder.bind(this))(!0)},{text:"Send to Back",onClick:()=>t(this.sendShapeToNewZOrder.bind(this))(!1)}]}]}}function ji(s){const t=Ot.bind(this);return{options:[...s??[],{childOptions:[{text:"Align",onHover:()=>{},subMenu:{options:[{childOptions:[{text:"Align Left",onClick:()=>t(this.align.bind(this))("left")},{text:"Align Right",onClick:()=>t(this.align.bind(this))("right")},{text:"Align Top",onClick:()=>t(this.align.bind(this))("top")},{text:"Align Bottom",onClick:()=>t(this.align.bind(this))("bottom")}]}]}},{text:"Normalize by First",onHover:()=>{},subMenu:{options:[{childOptions:[{text:"Height",onClick:()=>t(this.normalizeSelection.bind(this))("height","first")},{text:"Width",onClick:()=>t(this.normalizeSelection.bind(this))("width","first")},{text:"Size",onClick:()=>t(this.normalizeSelection.bind(this))("size","first")},{text:"Scale",onClick:()=>t(this.normalizeSelection.bind(this))("scale","first")}]}]}},{text:"Normalize by Average",onHover:()=>{},subMenu:{options:[{childOptions:[{text:"Height",onClick:()=>t(this.normalizeSelection.bind(this))("height","average")},{text:"Width",onClick:()=>t(this.normalizeSelection.bind(this))("width","average")},{text:"Size",onClick:()=>t(this.normalizeSelection.bind(this))("size","average")},{text:"Scale",onClick:()=>t(this.normalizeSelection.bind(this))("scale","average")}]}]}}]}]}}function Vi(s){const t=Ot.bind(this);return{options:[...s??[],{childOptions:[{text:"Change mode",onClick:()=>t(this.togglePointerMode.bind(this))()},{text:"Toggle Grid",onClick:()=>t(this.toggleGrid.bind(this))()}]},{childOptions:[{text:"Save",onClick:()=>t(this.saveToCanvasStorage.bind(this))()},{text:"Paste",onClick:e=>t(this.pasteImage.bind(this))(e)}]}]}}class Qt{_touch(){this._lastRetrieved=Date.now()}get id(){return this._touch(),this._id}get dataURL(){return this._touch(),this._dataURL}get mimetype(){return this._touch(),this._mimetype}get created(){return this._touch(),this._created}get lastRetrieved(){return this._lastRetrieved}constructor(t){this._dataURL=t,this._mimetype=Ke(t),this._created=Date.now(),this._lastRetrieved=Date.now()}static async create(t){const e=new Qt(t);return e._id=await Ht(t),e}}class qi{}class Zi{}function Oe(s){s.Version.prototype._parseStoresSpec=k.override(s.Version.prototype._parseStoresSpec,Ki),s.open=k.override(s.open,Ji(s))}function Ki(s){return function(t,e){s.call(this,t,e),Object.keys(e).forEach(function(i){let r=e[i];r.primKey.name.indexOf("$$")===0&&(r.primKey.uuid=!0,r.primKey.name=r.primKey.name.substr(2),r.primKey.keyPath=r.primKey.keyPath.substr(2))})}}function Qi(s){return function(e,i){let r;return e===void 0&&s.schema.primKey.uuid&&(e=r=Xe.v4(),s.schema.primKey.keyPath&&k.setByKeyPath(i,s.schema.primKey.keyPath,e)),r}}function Ji(s){return function(e){return function(){return Object.keys(s._allTables).forEach(i=>{let r=s._allTables[i];r.hook("creating").subscribe(Qi(r))}),e.apply(this,arguments)}}}k.UUIDPrimaryKey=Oe,k.addons.push(Oe),k.UUIDPrimaryKey;const ts={files:"$$id, mimetype, created, lastRetrieved"},Le={MAX_IMAGE_ENTRIES:1e3};class Lt extends qi{constructor(){super(),this.dbQueue=new Be,this.cache=new Map,this.CACHE_LIMIT=500,this.dbQueue=new Be,this.dbPromise=this.initDb()}async initDb(){return V(async()=>{let t=new k("InfiniteCanvas");return k.UUIDPrimaryKey(t),t.version(1).stores(ts),await t.open(),t})}async getIndexDb(){return this.dbPromise}async write(t){const e=await Qt.create(t),i=ss(e.dataURL);return this.dbQueue.add(()=>V(async()=>{const r=await this.getIndexDb();return await r.transaction("rw",r.files,async()=>(await is(r),await r.files.add({id:e.id,blob:i,dataURL:e.dataURL,mimetype:e.mimetype,created:e.created,lastRetrieved:e.lastRetrieved}))).catch(n=>{throw console.error("Failed to save image blob to local DB:",n),n})}))}async readAll(){return V(async()=>await(await this.getIndexDb()).files.toArray())}async readPage(t,e){return V(async()=>await(await this.getIndexDb()).files.offset(t).limit(e).toArray())}async read(t){return V(async()=>{const e=await this.getIndexDb();if(this.cache.has(t))return this.cache.get(t);const i=await e.files.get(t);if(!i)return null;if(this.dbQueue.add(async()=>{try{await e.files.update(t,{lastRetrieved:Date.now()})}catch(r){console.error("Failed to update lastRetrieved",r)}}).catch(()=>{}),this.cache.set(t,i),this.cache.size>this.CACHE_LIMIT){const r=this.cache.keys().next().value;this.cache.delete(r)}return i})}async delete(t){return this.dbQueue.add(()=>V(async()=>{const e=await this.getIndexDb();return await e.transaction("rw",e.files,async()=>{const i=await e.files.where("id").equals(t).first();return await e.files.delete(i.id),i}).catch(i=>{throw console.error("Failed to save image blob to local DB:",i),i})}))}async update(t){return this.dbQueue.add(()=>V(async()=>{const e=await this.getIndexDb();return await e.transaction("rw",e.files,async()=>{await e.files.update(t.id,{dataURL:t.dataURL,mimetype:t.mimetype,lastRetrieved:Date.now()})}),await e.files.where("id").equals(t.id).first()}))}async checkIfImageStored(t){return V(async()=>{const i=await(await this.getIndexDb()).files.where("id").equals(t).first();return i?i.id:null})}}class Jt extends Zi{constructor(t){super(),this.key="infinite_canvas",this.key=t}async write(t){return new Promise((e,i)=>{try{localStorage.setItem(this.key,JSON.stringify(t)),e()}catch(r){i(r)}})}async read(){return new Promise((t,e)=>{try{t(localStorage.getItem(this.key))}catch(i){e(i)}})}async delete(){return new Promise((t,e)=>{try{localStorage.removeItem(this.key),t()}catch(i){e(i)}})}async update(t){return this.write(t)}}class De extends Error{constructor(t){super(t),this.name="QuotaExceededError"}}class es extends Error{constructor(t){super(t),this.name="DatabaseLimitError"}}class Be{constructor(){this.queue=Promise.resolve()}async add(t){const e=this.queue.then(()=>t());return this.queue=e.catch(()=>{}),e}}const V=async s=>{try{return await s()}catch(t){throw t instanceof DOMException&&t.name==="QuotaExceededError"?new De("Storage quota exceeded. Please free up space."):t instanceof k.QuotaExceededError?new De("Database quota exceeded. Please free up space."):t}};async function is(s){if(await s.files.count()>=Le.MAX_IMAGE_ENTRIES)throw new es(`Cannot save image: limit of ${Le.MAX_IMAGE_ENTRIES} reached`)}function ss(s){const t=s.split(","),e=t[0],i=t[1],r=e.match(/:(.*?);/),n=r?r[1]:"application/octet-stream",a=atob(i),o=a.length,h=new Uint8Array(o);for(let c=0;c<o;c++)h[c]=a.charCodeAt(c);return new Blob([h],{type:n})}class rs{get el(){return this._el}constructor(t){this.type=t.type,this.message=t.message,this._el=document.createElement("div"),this._el.classList.add("canvas-loader"),this.render()}render(){if(this._el.innerHTML="",this.type==="spinner"){const t=document.createElement("div");if(t.classList.add("canvas-loader-spinner"),this._el.appendChild(t),this.message){const e=document.createElement("div");e.classList.add("canvas-loader-message"),e.textContent=this.message,this._el.appendChild(e)}}else if(this.type==="message"){const t=document.createElement("div");t.classList.add("canvas-loader-message"),t.textContent=this.message??"",this._el.appendChild(t)}}setMessage(t){this.message=t,this.render()}setProgress(t){this.progress=t,this.render()}attachToParent(t){t.appendChild(this.el)}remove(){this._el.parentNode&&this._el.parentNode.removeChild(this._el)}}function ns(s,t){const e=new rs({type:s,message:t});e.attachToParent(this.renderRoot);const i=this.getBoundingClientRect();return e.el.style.width=`${i.right}px`,e.el.style.height=`${i.bottom}px`,e._el.style.top=`${-i.bottom}px`,e}function as(){const s=this.renderRoot.querySelector(".canvas-loader");s&&s.remove()}var os=Object.getOwnPropertyDescriptor,ze=s=>{throw TypeError(s)},hs=(s,t,e,i)=>{for(var r=i>1?void 0:i?os(t,e):t,n=s.length-1,a;n>=0;n--)(a=s[n])&&(r=a(r)||r);return r},ke=(s,t,e)=>t.has(s)||ze("Cannot "+e),d=(s,t,e)=>(ke(s,t,"read from private field"),e?e.call(s):t.get(s)),D=(s,t,e)=>t.has(s)?ze("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(s):t.set(s,e),M=(s,t,e,i)=>(ke(s,t,"write to private field"),t.set(s,e),e),y,_,Dt,q,O,F,wt,Bt,vt,Ct,tt,ht,zt,kt,Ut;w.InfiniteCanvasElement=class extends z.LitElement{constructor(){super(...arguments),this.name="Reffy",this.displayMode="fullscreen",D(this,y),D(this,_),D(this,Dt),D(this,q),D(this,O),D(this,F),D(this,wt,3e5),D(this,Bt),D(this,vt),D(this,Ct),D(this,tt),D(this,ht),D(this,zt),D(this,kt),D(this,Ut),this.handleGlobalPointerDown=t=>{!this.contains(t.target)&&!this.renderRoot.contains(t.target)&&this.clearContextMenu()}}get singleImageMenuOptions(){return d(this,zt)}get multiImageMenuOptions(){return d(this,kt)}get canvasImageMenuOptions(){return d(this,Ut)}get canvas(){return d(this,y)}get onCanvasChange(){return d(this,ht)}set onCanvasChange(t){M(this,ht,t)}get eventHub(){return d(this,_)}get rootDiv(){return d(this,tt)}connectedCallback(){super.connectedCallback(),this.handleGlobalPointerDown=this.handleGlobalPointerDown.bind(this),document.addEventListener("pointerdown",this.handleGlobalPointerDown,!0)}disconnectedCallback(){document.removeEventListener("pointerdown",this.handleGlobalPointerDown,!0),window.removeEventListener("resize",d(this,Ct)),d(this,Dt)?.disconnect(),M(this,Dt,void 0),d(this,y).destroy(),super.disconnectedCallback()}firstUpdated(t){try{this.initCanvas()}catch(e){throw console.error(e),e}}updated(t){if(!(t.has("width")||t.has("height")||t.has("displayMode")))return;const i=d(this,tt),r=this.renderRoot.querySelector("canvas");i&&r&&this.resizeCanvas(i,r)}async initCanvas(){await this.warmUpStorage(),M(this,q,new Ti),M(this,_,new Ne);const t=document.createElement("div");t.style.overflow="hidden",this.renderRoot.appendChild(t),M(this,tt,t);const e=document.createElement("canvas");this.assignFileStorage=this.assignFileStorage.bind(this),this.getImageFileMetadata=this.getImageFileMetadata.bind(this),this.getAllImageFileMetdata=this.getAllImageFileMetdata.bind(this),this.saveImageFileMetadata=this.saveImageFileMetadata.bind(this),this.restoreStateFromCanvasStorage=this.restoreStateFromCanvasStorage.bind(this),this.assignCanvasStorage=this.assignCanvasStorage.bind(this),this.saveToCanvasStorage=this.saveToCanvasStorage.bind(this),this.debounceSaveToCanvasStorage=this.debounceSaveToCanvasStorage.bind(this),this.importCanvas=this.importCanvas.bind(this),this.exportCanvas=this.exportCanvas.bind(this),this.addContextMenu=Xi.bind(this),this.clearContextMenu=Ni.bind(this),this.isContextMenuActive=Hi.bind(this),this.getContainerSize=this.getContainerSize.bind(this),t.contains(e)||t.appendChild(e),this.registerSignal(),M(this,y,new pt(e,d(this,q),d(this,_),this.debounceSaveToCanvasStorage,this.saveImageFileMetadata,this.getContainerSize));try{await this.restoreStateFromCanvasStorage()}catch{console.error("Failed to restore canvas")}this.resizeCanvas(t,e),M(this,Ct,()=>this.resizeCanvas(t,e)),window.addEventListener("resize",d(this,Ct));const i=Yi.bind(this)();M(this,zt,$i.bind(this)(i.options)),M(this,Ut,Vi.bind(this)()),M(this,kt,ji.bind(this)(i.options)),this.dispatchEvent(new Event("load"));const r=new He;r.showPanel(0),this.renderRoot.contains(r.dom)||this.renderRoot.appendChild(r.dom);const n=()=>{r&&r.update(),d(this,y).render(),requestAnimationFrame(n)};n()}normalizeCssSize(t){if(!t)return t;const e=String(t).trim();return/^\d+$/.test(e)?`${e}px`:e}resizeCanvas(t,e){t.style.width=this.displayMode==="fullscreen"?"100vw":this.normalizeCssSize(this.width),t.style.height=this.displayMode==="fullscreen"?"100vh":this.normalizeCssSize(this.height),t.style.overflow="hidden";const i=window.devicePixelRatio||1;let r=window.screen.width,n=window.screen.height;const a=t.getBoundingClientRect(),o=Math.round(r*i),h=Math.round(n*i);(e.width!==o||e.height!==h)&&(e.width=o,e.height=h),e.style.width=`${r}px`,e.style.height=`${n}px`,this.canvas.camera.viewportX=a.x,this.canvas.camera.viewportY=a.y,this.canvas.camera.state.setHeight(a.height),this.canvas.camera.state.setWidth(a.width)}registerSignal(){d(this,_).on(rt.start,ns.bind(this),"spinner"),d(this,_).on(rt.done,as.bind(this)),d(this,_).on(X.Open,this.addContextMenu),d(this,_).on(X.Close,this.clearContextMenu),d(this,_).on(N.Change,()=>{d(this,ht)&&d(this,ht).call(this)}),d(this,_).on(nt.Save,this.saveToCanvasStorage),d(this,_).on(nt.SaveCompleted,()=>{}),d(this,_).on(nt.SaveFailed,()=>console.error("Failed to Save!"))}async warmUpStorage(){d(this,O)||M(this,O,new Lt);try{await d(this,O).readAll()}catch(t){console.error("Storage warm-up failed",t)}}getContainerSize(){if(!d(this,tt))return;const t=d(this,tt).getBoundingClientRect();return[t.width,t.height]}assignCanvasStorage(t,e=d(this,wt)){M(this,F,t),M(this,wt,e),d(this,vt)&&clearInterval(d(this,vt)),M(this,vt,setInterval(this.saveToCanvasStorage,d(this,wt)))}assignFileStorage(t){M(this,O,t)}async saveImageFileMetadata(t){d(this,O)||M(this,O,new Lt);try{const e=await Ht(t);return await d(this,O).checkIfImageStored(e)?e:await d(this,O).write(t)}catch(e){console.error(e)}}async getImageFileMetadata(t){d(this,O)||M(this,O,new Lt);try{return await d(this,O).read(t)}catch(e){console.error(e)}}async getAllImageFileMetdata(){d(this,O)||M(this,O,new Lt);try{return await d(this,O).readAll()}catch(t){console.error(t)}}debounceSaveToCanvasStorage(t=1e3){d(this,F)||M(this,F,new Jt(this.name)),clearTimeout(d(this,Bt)),M(this,Bt,setTimeout(this.saveToCanvasStorage,t))}async saveToCanvasStorage(){d(this,F)||M(this,F,new Jt(this.name)),d(this,F).write(Vt(d(this,y))).then(()=>d(this,_).emit(nt.SaveCompleted)).catch(()=>d(this,_).emit(nt.SaveFailed))}async restoreStateFromCanvasStorage(){d(this,F)||M(this,F,new Jt(this.name));const t=await d(this,F).read(),e=JSON.parse(t);e&&await qt(e,d(this,y),this.getImageFileMetadata)}togglePointerMode(){d(this,y)&&d(this,y).changeMode()}toggleGrid(){d(this,y)&&d(this,y).toggleGrid()}zoomIn(){d(this,y)&&d(this,y).updateZoomByFixedAmount(-1)}zoomOut(){d(this,y)&&d(this,y).updateZoomByFixedAmount()}async addImages(t){if(!d(this,y))return;const e=d(this,y).getBoundingClientRect(),i=e.left+e.width/2,r=e.top+e.height/2,[n,a]=K(i,r,d(this,y)),o=await Qe(t,h=>d(this,y).addImageToCanvas(h,n,a,1,1,!0));d(this,q).push(_t(d(this,y),o))}async removeImage(t){if(!d(this,y))return;const e=d(this,y).getChild(t);d(this,y).removeChild(e),d(this,q).push(ii(d(this,y),e))}async addImageFromUrl(t){if(!d(this,y))return;const e=d(this,y).getBoundingClientRect(),i=e.left+e.width/2,r=e.top+e.height/2,[n,a]=K(i,r,d(this,y)),o=await d(this,y).addImageToCanvas(t,n,a,1,1,!0);d(this,q).push(_t(d(this,y),[o]))}async copyImage(){d(this,y)&&await oe(d(this,y).getSelected())}async pasteImage(t){d(this,y)&&await he(t.clientX,t.clientY,d(this,y),d(this,q),!1)}flipVertical(){d(this,y)&&d(this,y).selectionManager.flip("vertical")}flipHorizontal(){d(this,y)&&d(this,y).selectionManager.flip("horizontal")}align(t){d(this,y)&&d(this,y).selectionManager.alignSelection(t)}normalizeSelection(t,e){d(this,y)&&d(this,y).selectionManager.normalize(t,e)}sendShapeToNewZOrder(t){d(this,y)&&d(this,y).setShapeZOrder(t)}deleteSelectedImages(){d(this,y)&&d(this,y).selectionManager.deleteSelected(d(this,y))}async exportCanvas(t="infinite-canvas.json"){if(!d(this,y))return;d(this,_).emit(rt.start,"spinner");const e=await this.getAllImageFileMetdata(),i=Vt(d(this,y),e);Je(t,i),d(this,_).emit(rt.done)}async importCanvas(t){if(d(this,_).emit(rt.start,"spinner"),!d(this,y)||!t||t.length!==1)return;const e=t[0];if(!e.type||!e.type.includes("json")&&!e.name.toLowerCase().endsWith(".json"))return;const i=await ti(e);await qt(i,d(this,y),this.getImageFileMetadata,this.saveImageFileMetadata),d(this,_).emit(nt.Save),d(this,_).emit(rt.done)}clearCanvas(){d(this,y)&&d(this,y).clearChildren()}getTotalNumberOfChildren(){if(d(this,y))return d(this,y).totalNumberOfChildren}getNumberOfChildrenRendered(){if(d(this,y))return d(this,y).numberOfChildrenRendered}},y=new WeakMap,_=new WeakMap,Dt=new WeakMap,q=new WeakMap,O=new WeakMap,F=new WeakMap,wt=new WeakMap,Bt=new WeakMap,vt=new WeakMap,Ct=new WeakMap,tt=new WeakMap,ht=new WeakMap,zt=new WeakMap,kt=new WeakMap,Ut=new WeakMap,w.InfiniteCanvasElement.properties={name:{type:String,reflect:!0},width:{type:String,reflect:!0},height:{type:String,reflect:!0},displayMode:{type:String,reflect:!0}},w.InfiniteCanvasElement.styles=z.css`
|
|
148
|
-
:host {
|
|
149
|
-
position: relative;
|
|
150
|
-
overflow: hidden;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.context-menu {
|
|
154
|
-
position: absolute;
|
|
155
|
-
background: white;
|
|
156
|
-
min-width: 180px;
|
|
157
|
-
background: var(--menu-bg, #fff);
|
|
158
|
-
border-radius: 6px;
|
|
159
|
-
border: 1px solid var(--menu-border, #9f9f9fff);
|
|
160
|
-
box-sizing: border-box;
|
|
161
|
-
padding: 6px 0;
|
|
162
|
-
display: flex;
|
|
163
|
-
gap: 2px;
|
|
164
|
-
flex-direction: column;
|
|
165
|
-
font-family: system-ui, sans-serif;
|
|
166
|
-
animation: fadeInMenu 0.13s cubic-bezier(0.4, 0, 0.2, 1);
|
|
167
|
-
overflow: scroll;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
@keyframes fadeInMenu {
|
|
171
|
-
from {
|
|
172
|
-
opacity: 0;
|
|
173
|
-
transform: translateY(8px);
|
|
174
|
-
}
|
|
175
|
-
to {
|
|
176
|
-
opacity: 1;
|
|
177
|
-
transform: none;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
.context-menu button {
|
|
182
|
-
all: unset;
|
|
183
|
-
display: flex;
|
|
184
|
-
align-items: center;
|
|
185
|
-
box-sizing: border-box;
|
|
186
|
-
width: 100%;
|
|
187
|
-
padding: 8px 18px;
|
|
188
|
-
font-size: 15px;
|
|
189
|
-
color: var(--menu-fg, #222);
|
|
190
|
-
background: none;
|
|
191
|
-
cursor: pointer;
|
|
192
|
-
transition:
|
|
193
|
-
background 0.1s,
|
|
194
|
-
color 0.1s;
|
|
195
|
-
user-select: none;
|
|
196
|
-
outline: none;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
.context-menu button:hover,
|
|
200
|
-
.context-menu button:focus-visible {
|
|
201
|
-
background: var(--menu-hover, #c7d5eaff);
|
|
202
|
-
color: var(--menu-accent, #155290ff);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.context-menu button:active {
|
|
206
|
-
background: var(--menu-active, #e3eaf3);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.context-menu button[disabled] {
|
|
210
|
-
color: #aaa;
|
|
211
|
-
cursor: not-allowed;
|
|
212
|
-
background: none;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
.context-menu-divider {
|
|
216
|
-
height: 1px;
|
|
217
|
-
background: var(--menu-divider, #c7d5eaff);
|
|
218
|
-
margin: 6px 12px;
|
|
219
|
-
border: none;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
canvas {
|
|
223
|
-
width: 100%;
|
|
224
|
-
height: 100%;
|
|
225
|
-
outline: none;
|
|
226
|
-
padding: 0;
|
|
227
|
-
margin: 0;
|
|
228
|
-
touch-action: none;
|
|
229
|
-
display: block;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
.canvas-loader {
|
|
233
|
-
position: absolute;
|
|
234
|
-
top: 0;
|
|
235
|
-
left: 0;
|
|
236
|
-
display: flex;
|
|
237
|
-
flex-direction: column;
|
|
238
|
-
align-items: center;
|
|
239
|
-
justify-content: center;
|
|
240
|
-
background: rgba(255, 255, 255, 0.7);
|
|
241
|
-
z-index: 1000;
|
|
242
|
-
pointer-events: all;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.canvas-loader-spinner {
|
|
246
|
-
width: 48px;
|
|
247
|
-
height: 48px;
|
|
248
|
-
border: 6px solid #e0e0e0;
|
|
249
|
-
border-top: 6px solid #1976d2;
|
|
250
|
-
border-radius: 50%;
|
|
251
|
-
animation: canvas-loader-spin 1s linear infinite;
|
|
252
|
-
margin-bottom: 16px;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
@keyframes canvas-loader-spin {
|
|
256
|
-
0% {
|
|
257
|
-
transform: rotate(0deg);
|
|
258
|
-
}
|
|
259
|
-
100% {
|
|
260
|
-
transform: rotate(360deg);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
.canvas-loader-message {
|
|
265
|
-
font-size: 1.1rem;
|
|
266
|
-
color: #333;
|
|
267
|
-
background: rgba(255, 255, 255, 0.9);
|
|
268
|
-
padding: 8px 16px;
|
|
269
|
-
border-radius: 4px;
|
|
270
|
-
margin-top: 8px;
|
|
271
|
-
text-align: center;
|
|
272
|
-
max-width: 80%;
|
|
273
|
-
word-break: break-word;
|
|
274
|
-
}
|
|
275
|
-
`,w.InfiniteCanvasElement=hs([_i("infinite-canvas")],w.InfiniteCanvasElement);class te{constructor(t){if(!t)throw new Error("InfiniteCanvasElement is required");this.el=t,this.assignCanvasStorage=this.assignCanvasStorage.bind(this),this.zoomIn=this.zoomIn.bind(this),this.zoomOut=this.zoomOut.bind(this),this.toggleMode=this.toggleMode.bind(this),this.addImageFromLocal=this.addImageFromLocal.bind(this),this.exportCanvas=this.exportCanvas.bind(this),this.importCanvas=this.importCanvas.bind(this),this.clearCanvas=this.clearCanvas.bind(this)}static async forElement(t){let e;if(typeof t=="string"?(await customElements.whenDefined("infinite-canvas"),e=document.querySelector(t)):e=t,!e)throw new Error("infinite-canvas element not found");return e.canvas||await new Promise(i=>e.addEventListener("load",()=>i(),{once:!0})),new te(e)}assignCanvasStorage(t,e=3e3){return this.el.assignCanvasStorage(t,e),this}async zoomIn(){console.log("zooming"),this.el.zoomIn()}async zoomOut(){this.el.zoomOut()}async toggleMode(){this.el.togglePointerMode()}async addImageFromLocal(t){if(!(!t||t.length===0)){for(let e=0;e<t.length;e++){const i=t[e];if(!i||!i.type||!i.type.startsWith("image/"))throw new Error("Only specific image files are supported. Please select image files only.")}await this.el.addImages(t)}}async exportCanvas(t){this.el.exportCanvas(t)}async importCanvas(t){!t||t.length!==1||await this.el.importCanvas(t)}async clearCanvas(){this.el.clearCanvas()}}w.Camera=ve,w.Canvas=pt,w.InfiniteCanvasAPI=te,w.ZOOM_MAX=we,w.ZOOM_MIN=xe,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})}));
|
|
276
|
-
//# sourceMappingURL=index.umd.js.map
|