kritzel-stencil 0.0.58 → 0.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/cjs/kritzel-brush-style_18.cjs.entry.js +1745 -1744
  2. package/dist/cjs/kritzel-brush-style_18.cjs.entry.js.map +1 -1
  3. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +139 -2
  4. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
  5. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +4 -137
  6. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js.map +1 -1
  7. package/dist/components/kritzel-controls.js +1 -1
  8. package/dist/components/kritzel-editor.js +135 -3
  9. package/dist/components/kritzel-editor.js.map +1 -1
  10. package/dist/components/kritzel-engine.js +1 -1
  11. package/dist/components/p-BLwMWTlT.js +2814 -0
  12. package/dist/components/p-BLwMWTlT.js.map +1 -0
  13. package/dist/components/{p-hrOnfdlW.js → p-q9lo4l1n.js} +6 -136
  14. package/dist/components/p-q9lo4l1n.js.map +1 -0
  15. package/dist/components/{p-Cfrjjjns.js → p-sGUp-TMH.js} +1883 -3405
  16. package/dist/components/p-sGUp-TMH.js.map +1 -0
  17. package/dist/esm/kritzel-brush-style_18.entry.js +1745 -1744
  18. package/dist/esm/kritzel-brush-style_18.entry.js.map +1 -1
  19. package/dist/stencil/p-6892d565.entry.js +2 -0
  20. package/dist/stencil/p-6892d565.entry.js.map +1 -0
  21. package/dist/stencil/stencil.esm.js +1 -1
  22. package/dist/types/components.d.ts +8 -2
  23. package/package.json +1 -1
  24. package/dist/components/p-BOXJ3Psd.js +0 -1292
  25. package/dist/components/p-BOXJ3Psd.js.map +0 -1
  26. package/dist/components/p-Cfrjjjns.js.map +0 -1
  27. package/dist/components/p-hrOnfdlW.js.map +0 -1
  28. package/dist/stencil/p-49e5a66c.entry.js +0 -2
  29. package/dist/stencil/p-49e5a66c.entry.js.map +0 -1
@@ -282,529 +282,114 @@ class KritzelBaseCommand {
282
282
  }
283
283
  }
284
284
 
285
- class RemoveSelectionGroupCommand extends KritzelBaseCommand {
286
- constructor(store, initiator) {
285
+ class AddObjectCommand extends KritzelBaseCommand {
286
+ constructor(store, initiator, object) {
287
287
  super(store, initiator);
288
- this.previousSelectionGroup = this._store.state.selectionGroup;
288
+ this.object = object;
289
289
  }
290
290
  execute() {
291
- this._store.state.objectsOctree.remove(object => object.id === this.previousSelectionGroup.id);
292
- this._store.state.selectionGroup = null;
291
+ this._store.state.objectsOctree.insert(this.object);
293
292
  }
294
293
  undo() {
295
- if (this.previousSelectionGroup) {
296
- this._store.state.objectsOctree.insert(this.previousSelectionGroup);
297
- this._store.state.selectionGroup = this.previousSelectionGroup;
298
- }
294
+ this._store.state.objectsOctree.remove(object => object.id === this.object.id);
299
295
  }
300
296
  }
301
297
 
302
- class MoveSelectionGroupCommand extends KritzelBaseCommand {
303
- constructor(store, initiator, startX, startY, endX, endY, skipFirstExecution = false) {
304
- super(store, initiator);
305
- this.startX = startX;
306
- this.startY = startY;
307
- this.endX = endX;
308
- this.endY = endY;
309
- this.skipExecution = skipFirstExecution;
310
- this.selectionGroup = this._store.state.selectionGroup;
311
- }
312
- execute() {
313
- if (this.skipExecution) {
314
- this.skipExecution = false;
315
- return;
316
- }
317
- this._store.state.selectionGroup = this.selectionGroup;
318
- this._store.state.selectionGroup.move(this.startX, this.startY, this.endX, this.endY);
319
- }
320
- undo() {
321
- this._store.state.selectionGroup = this.selectionGroup;
322
- this._store.state.selectionGroup.move(this.endX, this.endY, this.startX, this.startY);
323
- }
298
+ var cjs = {};
299
+
300
+ var hasRequiredCjs;
301
+
302
+ function requireCjs () {
303
+ if (hasRequiredCjs) return cjs;
304
+ hasRequiredCjs = 1;
305
+ (function (exports) {
306
+ var pe=Object.defineProperty;var ge=e=>pe(e,"__esModule",{value:true});var de=(e,t)=>{ge(e);for(var s in t)pe(e,s,{get:t[s],enumerable:true});};de(exports,{default:()=>ve,getStroke:()=>ne,getStrokeOutlinePoints:()=>te,getStrokePoints:()=>re});function $(e,t,s,x=h=>h){return e*x(.5-t*(.5-s))}function ce(e){return [-e[0],-e[1]]}function l(e,t){return [e[0]+t[0],e[1]+t[1]]}function a(e,t){return [e[0]-t[0],e[1]-t[1]]}function b(e,t){return [e[0]*t,e[1]*t]}function xe(e,t){return [e[0]/t,e[1]/t]}function R(e){return [e[1],-e[0]]}function B(e,t){return e[0]*t[0]+e[1]*t[1]}function me(e,t){return e[0]===t[0]&&e[1]===t[1]}function Se(e){return Math.hypot(e[0],e[1])}function Pe(e){return e[0]*e[0]+e[1]*e[1]}function A(e,t){return Pe(a(e,t))}function G(e){return xe(e,Se(e))}function ae(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function L(e,t,s){let x=Math.sin(s),h=Math.cos(s),y=e[0]-t[0],n=e[1]-t[1],f=y*h-n*x,d=y*x+n*h;return [f+t[0],d+t[1]]}function K(e,t,s){return l(e,b(a(t,e),s))}function ee(e,t,s){return l(e,b(t,s))}var{min:C,PI:ke}=Math,le=.275,V=ke+1e-4;function te(e,t={}){let{size:s=16,smoothing:x=.5,thinning:h=.5,simulatePressure:y=true,easing:n=r=>r,start:f={},end:d={},last:D=false}=t,{cap:S=true,easing:j=r=>r*(2-r)}=f,{cap:q=true,easing:c=r=>--r*r*r+1}=d;if(e.length===0||s<=0)return [];let p=e[e.length-1].runningLength,g=f.taper===false?0:f.taper===true?Math.max(s,p):f.taper,T=d.taper===false?0:d.taper===true?Math.max(s,p):d.taper,oe=Math.pow(s*x,2),_=[],M=[],H=e.slice(0,10).reduce((r,i)=>{let o=i.pressure;if(y){let u=C(1,i.distance/s),W=C(1,1-u);o=C(1,r+(W-r)*(u*le));}return (r+o)/2},e[0].pressure),m=$(s,h,e[e.length-1].pressure,n),U,X=e[0].vector,z=e[0].point,F=z,O=z,E=F,J=false;for(let r=0;r<e.length;r++){let{pressure:i}=e[r],{point:o,vector:u,distance:W,runningLength:I}=e[r];if(r<e.length-1&&p-I<3)continue;if(h){if(y){let v=C(1,W/s),Z=C(1,1-v);i=C(1,H+(Z-H)*(v*le));}m=$(s,h,i,n);}else m=s/2;U===void 0&&(U=m);let fe=I<g?j(I/g):1,be=p-I<T?c((p-I)/T):1;m=Math.max(.01,m*Math.min(fe,be));let se=(r<e.length-1?e[r+1]:e[r]).vector,Y=r<e.length-1?B(u,se):1,he=B(u,X)<0&&!J,ue=Y!==null&&Y<0;if(he||ue){let v=b(R(X),m);for(let Z=1/13,w=0;w<=1;w+=Z)O=L(a(o,v),o,V*w),_.push(O),E=L(l(o,v),o,V*-w),M.push(E);z=O,F=E,ue&&(J=true);continue}if(J=false,r===e.length-1){let v=b(R(u),m);_.push(a(o,v)),M.push(l(o,v));continue}let ie=b(R(K(se,u,Y)),m);O=a(o,ie),(r<=1||A(z,O)>oe)&&(_.push(O),z=O),E=l(o,ie),(r<=1||A(F,E)>oe)&&(M.push(E),F=E),H=i,X=u;}let P=e[0].point.slice(0,2),k=e.length>1?e[e.length-1].point.slice(0,2):l(e[0].point,[1,1]),Q=[],N=[];if(e.length===1){if(!(g||T)||D){let r=ee(P,G(R(a(P,k))),-(U||m)),i=[];for(let o=1/13,u=o;u<=1;u+=o)i.push(L(r,P,V*2*u));return i}}else {if(!(g||T&&e.length===1))if(S)for(let i=1/13,o=i;o<=1;o+=i){let u=L(M[0],P,V*o);Q.push(u);}else {let i=a(_[0],M[0]),o=b(i,.5),u=b(i,.51);Q.push(a(P,o),a(P,u),l(P,u),l(P,o));}let r=R(ce(e[e.length-1].vector));if(T||g&&e.length===1)N.push(k);else if(q){let i=ee(k,r,m);for(let o=1/29,u=o;u<1;u+=o)N.push(L(i,k,V*3*u));}else N.push(l(k,b(r,m)),l(k,b(r,m*.99)),a(k,b(r,m*.99)),a(k,b(r,m)));}return _.concat(N,M.reverse(),Q)}function re(e,t={}){var q;let{streamline:s=.5,size:x=16,last:h=false}=t;if(e.length===0)return [];let y=.15+(1-s)*.85,n=Array.isArray(e[0])?e:e.map(({x:c,y:p,pressure:g=.5})=>[c,p,g]);if(n.length===2){let c=n[1];n=n.slice(0,-1);for(let p=1;p<5;p++)n.push(K(n[0],c,p/4));}n.length===1&&(n=[...n,[...l(n[0],[1,1]),...n[0].slice(2)]]);let f=[{point:[n[0][0],n[0][1]],pressure:n[0][2]>=0?n[0][2]:.25,vector:[1,1],distance:0,runningLength:0}],d=false,D=0,S=f[0],j=n.length-1;for(let c=1;c<n.length;c++){let p=h&&c===j?n[c].slice(0,2):K(S.point,n[c],y);if(me(S.point,p))continue;let g=ae(p,S.point);if(D+=g,c<j&&!d){if(D<x)continue;d=true;}S={point:p,pressure:n[c][2]>=0?n[c][2]:.5,vector:G(a(S.point,p)),distance:g,runningLength:D},f.push(S);}return f[0].vector=((q=f[1])==null?void 0:q.vector)||[0,0],f}function ne(e,t={}){return te(re(e,t),t)}var ve=ne;
307
+ } (cjs));
308
+ return cjs;
324
309
  }
325
310
 
326
- class KritzelBaseHandler {
327
- constructor(store) {
328
- this._store = store;
311
+ var cjsExports = requireCjs();
312
+
313
+ class KritzelMathHelper {
314
+ static average(a, b) {
315
+ return (a + b) / 2;
329
316
  }
330
317
  }
331
318
 
332
- class KritzelMoveHandler extends KritzelBaseHandler {
333
- constructor(store) {
334
- super(store);
335
- }
336
- handleMouseDown(event) {
337
- var _a;
338
- if (KritzelEventHelper.isLeftClick(event)) {
339
- if (((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
340
- const clientX = event.clientX - this._store.offsetX;
341
- const clientY = event.clientY - this._store.offsetY;
342
- this._store.state.isDragging = true;
343
- this.dragStartX = clientX;
344
- this.dragStartY = clientY;
345
- this.startX = this.dragStartX;
346
- this.startY = this.dragStartY;
347
- }
348
- }
349
- }
350
- handleMouseMove(event) {
351
- if (this._store.state.isDragging && this._store.state.selectionGroup) {
352
- const clientX = event.clientX - this._store.offsetX;
353
- const clientY = event.clientY - this._store.offsetY;
354
- this.endX = clientX;
355
- this.endY = clientY;
356
- this._store.state.selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
357
- this.dragStartX = clientX;
358
- this.dragStartY = clientY;
359
- }
360
- }
361
- handleMouseUp(_event) {
362
- if (this._store.state.isDragging) {
363
- this._store.state.isDragging = false;
364
- this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
365
- }
366
- }
367
- handleTouchStart(event) {
368
- var _a;
369
- if (this._store.state.touchCount === 1) {
370
- if (((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
371
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
372
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
373
- this.dragStartX = x;
374
- this.dragStartY = y;
375
- this.startX = x;
376
- this.startY = y;
377
- }
378
- }
379
- }
380
- handleTouchMove(event) {
381
- if (this._store.state.touchCount === 1 && this._store.state.selectionGroup && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
382
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
383
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
384
- this._store.state.isDragging = true;
385
- this.endX = x;
386
- this.endY = y;
387
- const moveDeltaX = Math.abs(x - this.startX);
388
- const moveDeltaY = Math.abs(y - this.startY);
389
- const moveThreshold = 5;
390
- if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
391
- clearTimeout(this._store.state.longTouchTimeout);
392
- this._store.state.selectionGroup.move(x, y, this.dragStartX, this.dragStartY);
393
- this.dragStartX = x;
394
- this.dragStartY = y;
395
- }
396
- }
397
- }
398
- handleTouchEnd(_event) {
399
- if (this._store.state.isDragging) {
400
- this._store.state.isDragging = false;
401
- this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
402
- }
319
+ /** Detect free variable `global` from Node.js. */
320
+ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
321
+
322
+ /** Detect free variable `self`. */
323
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
324
+
325
+ /** Used as a reference to the global object. */
326
+ var root = freeGlobal || freeSelf || Function('return this')();
327
+
328
+ /** Built-in value references. */
329
+ var Symbol = root.Symbol;
330
+
331
+ /** Used for built-in method references. */
332
+ var objectProto$b = Object.prototype;
333
+
334
+ /** Used to check objects for own properties. */
335
+ var hasOwnProperty$8 = objectProto$b.hasOwnProperty;
336
+
337
+ /**
338
+ * Used to resolve the
339
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
340
+ * of values.
341
+ */
342
+ var nativeObjectToString$1 = objectProto$b.toString;
343
+
344
+ /** Built-in value references. */
345
+ var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
346
+
347
+ /**
348
+ * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
349
+ *
350
+ * @private
351
+ * @param {*} value The value to query.
352
+ * @returns {string} Returns the raw `toStringTag`.
353
+ */
354
+ function getRawTag(value) {
355
+ var isOwn = hasOwnProperty$8.call(value, symToStringTag$1),
356
+ tag = value[symToStringTag$1];
357
+
358
+ try {
359
+ value[symToStringTag$1] = undefined;
360
+ var unmasked = true;
361
+ } catch (e) {}
362
+
363
+ var result = nativeObjectToString$1.call(value);
364
+ if (unmasked) {
365
+ if (isOwn) {
366
+ value[symToStringTag$1] = tag;
367
+ } else {
368
+ delete value[symToStringTag$1];
403
369
  }
370
+ }
371
+ return result;
404
372
  }
405
373
 
406
- var KritzelHandleType;
407
- (function (KritzelHandleType) {
408
- KritzelHandleType["TopLeft"] = "top-left";
409
- KritzelHandleType["TopRight"] = "top-right";
410
- KritzelHandleType["BottomLeft"] = "bottom-left";
411
- KritzelHandleType["BottomRight"] = "bottom-right";
412
- })(KritzelHandleType || (KritzelHandleType = {}));
374
+ /** Used for built-in method references. */
375
+ var objectProto$a = Object.prototype;
413
376
 
414
- class ResizeSelectionGroupCommand extends KritzelBaseCommand {
415
- constructor(store, initiator, previousSize, newSize) {
416
- super(store, initiator);
417
- this.previousSize = previousSize;
418
- this.newSize = newSize;
419
- this.selectionGroup = this._store.state.selectionGroup;
420
- }
421
- execute() {
422
- this._store.state.selectionGroup = this.selectionGroup;
423
- this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
424
- }
425
- undo() {
426
- this._store.state.selectionGroup = this.selectionGroup;
427
- this._store.state.selectionGroup.resize(this.previousSize.x, this.previousSize.y, this.previousSize.width, this.previousSize.height);
428
- }
429
- }
430
-
431
- class KritzelResizeHandler extends KritzelBaseHandler {
432
- constructor(store) {
433
- super(store);
434
- this.initialMouseX = 0;
435
- this.initialMouseY = 0;
436
- this.initialSize = { x: 0, y: 0, width: 0, height: 0 };
437
- this.newSize = { x: 0, y: 0, width: 0, height: 0 };
438
- }
439
- handleMouseDown(event) {
440
- if (KritzelEventHelper.isLeftClick(event)) {
441
- if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
442
- const clientX = event.clientX - this._store.offsetX;
443
- const clientY = event.clientY - this._store.offsetY;
444
- this._store.state.isResizing = true;
445
- this.initialMouseX = clientX;
446
- this.initialMouseY = clientY;
447
- this.initialSize.width = this._store.state.selectionGroup.width;
448
- this.initialSize.height = this._store.state.selectionGroup.height;
449
- this.initialSize.x = this._store.state.selectionGroup.translateX;
450
- this.initialSize.y = this._store.state.selectionGroup.translateY;
451
- }
452
- }
453
- }
454
- handleMouseMove(event) {
455
- if (this._store.state.isResizing && this._store.state.selectionGroup) {
456
- const clientX = event.clientX - this._store.offsetX;
457
- const clientY = event.clientY - this._store.offsetY;
458
- const dx = clientX - this.initialMouseX;
459
- const dy = clientY - this.initialMouseY;
460
- switch (this._store.state.resizeHandleType) {
461
- case KritzelHandleType.TopLeft:
462
- this.newSize.width = this.initialSize.width - dx;
463
- this.newSize.height = this.initialSize.height - dy;
464
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
465
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
466
- break;
467
- case KritzelHandleType.TopRight:
468
- this.newSize.width = this.initialSize.width + dx;
469
- this.newSize.height = this.initialSize.height - dy;
470
- this.newSize.x = this.initialSize.x;
471
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
472
- break;
473
- case KritzelHandleType.BottomLeft:
474
- this.newSize.width = this.initialSize.width - dx;
475
- this.newSize.height = this.initialSize.height + dy;
476
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
477
- this.newSize.y = this.initialSize.y;
478
- break;
479
- case KritzelHandleType.BottomRight:
480
- this.newSize.width = this.initialSize.width + dx;
481
- this.newSize.height = this.initialSize.height + dy;
482
- this.newSize.x = this.initialSize.x;
483
- this.newSize.y = this.initialSize.y;
484
- break;
485
- }
486
- this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
487
- this._store.rerender();
488
- }
489
- }
490
- handleMouseUp(_event) {
491
- if (this._store.state.isResizing) {
492
- const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
493
- this._store.history.executeCommand(resizeSelectionGroupCommand);
494
- this._store.state.isResizing = false;
495
- this._store.rerender();
496
- }
497
- }
498
- handleTouchStart(event) {
499
- const firstTouch = event.touches[0];
500
- if (!firstTouch) {
501
- return;
502
- }
503
- if (this._store.state.touchCount === 1) {
504
- if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
505
- const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
506
- const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
507
- this._store.state.isResizing = true;
508
- this.initialMouseX = clientX;
509
- this.initialMouseY = clientY;
510
- this.initialSize.width = this._store.state.selectionGroup.width;
511
- this.initialSize.height = this._store.state.selectionGroup.height;
512
- this.initialSize.x = this._store.state.selectionGroup.translateX;
513
- this.initialSize.y = this._store.state.selectionGroup.translateY;
514
- clearTimeout(this._store.state.longTouchTimeout);
515
- }
516
- }
517
- }
518
- handleTouchMove(event) {
519
- const oneFingerTouch = event.touches[0];
520
- if (!oneFingerTouch) {
521
- return;
522
- }
523
- if (this._store.state.isResizing && this._store.state.selectionGroup) {
524
- const clientX = Math.round(oneFingerTouch.clientX - this._store.offsetX);
525
- const clientY = Math.round(oneFingerTouch.clientY - this._store.offsetY);
526
- const dx = clientX - this.initialMouseX;
527
- const dy = clientY - this.initialMouseY;
528
- switch (this._store.state.resizeHandleType) {
529
- case KritzelHandleType.TopLeft:
530
- this.newSize.width = this.initialSize.width - dx;
531
- this.newSize.height = this.initialSize.height - dy;
532
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
533
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
534
- break;
535
- case KritzelHandleType.TopRight:
536
- this.newSize.width = this.initialSize.width + dx;
537
- this.newSize.height = this.initialSize.height - dy;
538
- this.newSize.x = this.initialSize.x;
539
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
540
- break;
541
- case KritzelHandleType.BottomLeft:
542
- this.newSize.width = this.initialSize.width - dx;
543
- this.newSize.height = this.initialSize.height + dy;
544
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
545
- this.newSize.y = this.initialSize.y;
546
- break;
547
- case KritzelHandleType.BottomRight:
548
- this.newSize.width = this.initialSize.width + dx;
549
- this.newSize.height = this.initialSize.height + dy;
550
- this.newSize.x = this.initialSize.x;
551
- this.newSize.y = this.initialSize.y;
552
- break;
553
- }
554
- this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
555
- clearTimeout(this._store.state.longTouchTimeout);
556
- }
557
- }
558
- handleTouchEnd(_event) {
559
- if (this._store.state.isResizing) {
560
- const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
561
- this._store.history.executeCommand(resizeSelectionGroupCommand);
562
- this._store.state.isResizing = false;
563
- clearTimeout(this._store.state.longTouchTimeout);
564
- }
565
- }
566
- }
567
-
568
- class RotateSelectionGroupCommand extends KritzelBaseCommand {
569
- constructor(store, initiator, rotation) {
570
- super(store, initiator);
571
- this.rotation = rotation;
572
- this.initialRotation = this._store.state.selectionGroup.rotation;
573
- this.selectionGroup = this._store.state.selectionGroup;
574
- }
575
- execute() {
576
- this._store.state.selectionGroup = this.selectionGroup;
577
- this._store.state.selectionGroup.rotate(this.rotation);
578
- this._store.state.selectionGroup.objects.forEach(object => {
579
- this._store.state.objectsOctree.update(object);
580
- });
581
- }
582
- undo() {
583
- this._store.state.selectionGroup = this.selectionGroup;
584
- this._store.state.selectionGroup.rotate(this.rotation - this.initialRotation);
585
- this._store.state.selectionGroup.objects.forEach(object => {
586
- this._store.state.objectsOctree.update(object);
587
- });
588
- }
589
- }
590
-
591
- class KritzelRotationHandler extends KritzelBaseHandler {
592
- constructor(store) {
593
- super(store);
594
- this.initialRotation = 0;
595
- this.rotation = 0;
596
- }
597
- handleMouseDown(event) {
598
- if (KritzelEventHelper.isLeftClick(event)) {
599
- if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
600
- const clientX = event.clientX - this._store.offsetX;
601
- const clientY = event.clientY - this._store.offsetY;
602
- this._store.state.isRotating = true;
603
- const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
604
- const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
605
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
606
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
607
- this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
608
- }
609
- }
610
- }
611
- handleMouseMove(event) {
612
- if (this._store.state.isRotating && this._store.state.selectionGroup) {
613
- const clientX = event.clientX - this._store.offsetX;
614
- const clientY = event.clientY - this._store.offsetY;
615
- const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
616
- const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
617
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
618
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
619
- const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
620
- this.rotation = currentRotation - this.initialRotation;
621
- this._store.state.selectionGroup.rotate(this.rotation);
622
- this._store.rerender();
623
- }
624
- }
625
- handleMouseUp(_event) {
626
- if (this._store.state.isRotating) {
627
- this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
628
- this._store.state.isRotating = false;
629
- this.initialRotation = 0;
630
- this.rotation = 0;
631
- }
632
- }
633
- handleTouchStart(event) {
634
- const firstTouch = event.touches[0];
635
- if (!firstTouch) {
636
- return;
637
- }
638
- if (this._store.state.touchCount === 1) {
639
- if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
640
- const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
641
- const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
642
- this._store.state.isRotating = true;
643
- const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
644
- const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
645
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
646
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
647
- this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
648
- clearTimeout(this._store.state.longTouchTimeout);
649
- }
650
- }
651
- }
652
- handleTouchMove(event) {
653
- const firstTouch = event.touches[0];
654
- if (!firstTouch) {
655
- return;
656
- }
657
- if (this._store.state.isRotating && this._store.state.selectionGroup) {
658
- const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
659
- const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
660
- const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
661
- const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
662
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
663
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
664
- const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
665
- this.rotation = currentRotation - this.initialRotation;
666
- this._store.state.selectionGroup.rotate(this.rotation);
667
- clearTimeout(this._store.state.longTouchTimeout);
668
- }
669
- }
670
- handleTouchEnd(_event) {
671
- if (this._store.state.isRotating) {
672
- this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
673
- this._store.state.isRotating = false;
674
- this.initialRotation = 0;
675
- this.rotation = 0;
676
- clearTimeout(this._store.state.longTouchTimeout);
677
- }
678
- }
679
- }
680
-
681
- class KritzelGeometryHelper {
682
- static doPolygonsIntersect(polygon1, polygon2) {
683
- // 1. Convert polygons to array of points for easier processing
684
- const points1 = [polygon1.bottomLeft, polygon1.bottomRight, polygon1.topRight, polygon1.topLeft];
685
- const points2 = [polygon2.bottomLeft, polygon2.bottomRight, polygon2.topRight, polygon2.topLeft];
686
- // 2. Check if any point of polygon1 is inside polygon2
687
- for (const point of points1) {
688
- if (this.isPointInPolygon(point, points2)) {
689
- return true;
690
- }
691
- }
692
- // 3. Check if any point of polygon2 is inside polygon1
693
- for (const point of points2) {
694
- if (this.isPointInPolygon(point, points1)) {
695
- return true;
696
- }
697
- }
698
- // 4. Check for edge intersections (more complex)
699
- for (let i = 0; i < points1.length; i++) {
700
- const p1a = points1[i];
701
- const p1b = points1[(i + 1) % points1.length]; // Wrap around to the first point
702
- for (let j = 0; j < points2.length; j++) {
703
- const p2a = points2[j];
704
- const p2b = points2[(j + 1) % points2.length];
705
- if (this.intersectLines(p1a, p1b, p2a, p2b)) {
706
- return true;
707
- }
708
- }
709
- }
710
- return false; // No intersection found
711
- }
712
- static isPointInPolygon(point, polygon) {
713
- let inside = false;
714
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
715
- const xi = polygon[i].x, yi = polygon[i].y;
716
- const xj = polygon[j].x, yj = polygon[j].y;
717
- const intersect = yi > point.y !== yj > point.y && point.x < ((xj - xi) * (point.y - yi)) / (yj - yi) + xi;
718
- if (intersect)
719
- inside = !inside;
720
- }
721
- return inside;
722
- }
723
- static intersectLines(p1a, p1b, p2a, p2b) {
724
- const det = (p1b.x - p1a.x) * (p2b.y - p2a.y) - (p1b.y - p1a.y) * (p2b.x - p2a.x);
725
- if (det === 0) {
726
- return false; // Lines are parallel
727
- }
728
- const t = ((p2a.x - p1a.x) * (p2b.y - p2a.y) - (p2a.y - p1a.y) * (p2b.x - p2a.x)) / det;
729
- const u = -((p1a.x - p2a.x) * (p1b.y - p1a.y) - (p1a.y - p2a.y) * (p1b.x - p1a.x)) / det;
730
- return t >= 0 && t <= 1 && u >= 0 && u <= 1;
731
- }
732
- }
733
-
734
- /** Detect free variable `global` from Node.js. */
735
- var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
736
-
737
- /** Detect free variable `self`. */
738
- var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
739
-
740
- /** Used as a reference to the global object. */
741
- var root = freeGlobal || freeSelf || Function('return this')();
742
-
743
- /** Built-in value references. */
744
- var Symbol = root.Symbol;
745
-
746
- /** Used for built-in method references. */
747
- var objectProto$b = Object.prototype;
748
-
749
- /** Used to check objects for own properties. */
750
- var hasOwnProperty$8 = objectProto$b.hasOwnProperty;
751
-
752
- /**
753
- * Used to resolve the
754
- * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
755
- * of values.
756
- */
757
- var nativeObjectToString$1 = objectProto$b.toString;
758
-
759
- /** Built-in value references. */
760
- var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
761
-
762
- /**
763
- * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
764
- *
765
- * @private
766
- * @param {*} value The value to query.
767
- * @returns {string} Returns the raw `toStringTag`.
768
- */
769
- function getRawTag(value) {
770
- var isOwn = hasOwnProperty$8.call(value, symToStringTag$1),
771
- tag = value[symToStringTag$1];
772
-
773
- try {
774
- value[symToStringTag$1] = undefined;
775
- var unmasked = true;
776
- } catch (e) {}
777
-
778
- var result = nativeObjectToString$1.call(value);
779
- if (unmasked) {
780
- if (isOwn) {
781
- value[symToStringTag$1] = tag;
782
- } else {
783
- delete value[symToStringTag$1];
784
- }
785
- }
786
- return result;
787
- }
788
-
789
- /** Used for built-in method references. */
790
- var objectProto$a = Object.prototype;
791
-
792
- /**
793
- * Used to resolve the
794
- * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
795
- * of values.
796
- */
797
- var nativeObjectToString = objectProto$a.toString;
798
-
799
- /**
800
- * Converts `value` to a string using `Object.prototype.toString`.
801
- *
802
- * @private
803
- * @param {*} value The value to convert.
804
- * @returns {string} Returns the converted string.
805
- */
806
- function objectToString(value) {
807
- return nativeObjectToString.call(value);
377
+ /**
378
+ * Used to resolve the
379
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
380
+ * of values.
381
+ */
382
+ var nativeObjectToString = objectProto$a.toString;
383
+
384
+ /**
385
+ * Converts `value` to a string using `Object.prototype.toString`.
386
+ *
387
+ * @private
388
+ * @param {*} value The value to convert.
389
+ * @returns {string} Returns the converted string.
390
+ */
391
+ function objectToString(value) {
392
+ return nativeObjectToString.call(value);
808
393
  }
809
394
 
810
395
  /** `Object#toString` result references. */
@@ -2926,126 +2511,48 @@ class KritzelBaseObject {
2926
2511
  }
2927
2512
  isInViewport() {
2928
2513
  const viewportBounds = {
2929
- x: -this._store.state.translateX / this._store.state.scale,
2930
- y: -this._store.state.translateY / this._store.state.scale,
2931
- width: this._store.state.viewportWidth / this._store.state.scale,
2932
- height: this._store.state.viewportHeight / this._store.state.scale};
2933
- return this.boundingBox.x < viewportBounds.x + viewportBounds.width &&
2934
- this.boundingBox.x + this.boundingBox.width > viewportBounds.x &&
2935
- this.boundingBox.y < viewportBounds.y + viewportBounds.height &&
2936
- this.boundingBox.y + this.boundingBox.height > viewportBounds.y;
2937
- }
2938
- centerInViewport() {
2939
- const scale = this._store.state.scale;
2940
- this.translateX = (this._store.state.viewportWidth / 2 - this.totalWidth / 2 - this._store.state.translateX) / scale;
2941
- this.translateY = (this._store.state.viewportHeight / 2 - this.totalHeight / 2 - this._store.state.translateY) / scale;
2942
- }
2943
- move(startX, startY, endX, endY) {
2944
- const deltaX = (startX - endX) / this._store.state.scale;
2945
- const deltaY = (startY - endY) / this._store.state.scale;
2946
- this.translateX += deltaX;
2947
- this.translateY += deltaY;
2948
- }
2949
- resize(x, y, width, height) {
2950
- if (width <= 1 || height <= 1) {
2951
- return;
2952
- }
2953
- this.width = width;
2954
- this.height = height;
2955
- this.translateX = x;
2956
- this.translateY = y;
2957
- }
2958
- rotate(value) {
2959
- this.rotation = value;
2960
- }
2961
- copy() {
2962
- const copiedObject = Object.create(Object.getPrototypeOf(this));
2963
- Object.assign(copiedObject, this);
2964
- copiedObject.id = this.generateId();
2965
- copiedObject.isMounted = false;
2966
- return copiedObject;
2967
- }
2968
- revive(object) {
2969
- Object.assign(this, object);
2970
- return this;
2971
- }
2972
- }
2973
-
2974
- class KrtizelSelectionBox extends KritzelBaseObject {
2975
- constructor(store) {
2976
- super(store);
2977
- this.__class__ = 'KrtizelSelectionBox';
2978
- this.objects = [];
2979
- this.backgroundColor = 'var(--kritzel-selection-box-background-color)';
2980
- this.borderColor = 'var(--kritzel-selection-box-border-color)';
2981
- this.borderWidth = 2;
2982
- this.scale = this._store.state.scale;
2983
- this.height = 0;
2984
- this.width = 0;
2985
- this.zIndex = 9999;
2986
- }
2987
- }
2988
-
2989
- class AddSelectionGroupCommand extends KritzelBaseCommand {
2990
- constructor(store, initiator, selectionGroup) {
2991
- super(store, initiator);
2992
- this.selectionGroup = selectionGroup;
2993
- }
2994
- execute() {
2995
- this._store.state.objectsOctree.remove(object => object instanceof KrtizelSelectionBox);
2996
- this._store.state.objectsOctree.insert(this.selectionGroup);
2997
- this._store.state.selectionGroup = this.selectionGroup;
2514
+ x: -this._store.state.translateX / this._store.state.scale,
2515
+ y: -this._store.state.translateY / this._store.state.scale,
2516
+ width: this._store.state.viewportWidth / this._store.state.scale,
2517
+ height: this._store.state.viewportHeight / this._store.state.scale};
2518
+ return this.boundingBox.x < viewportBounds.x + viewportBounds.width &&
2519
+ this.boundingBox.x + this.boundingBox.width > viewportBounds.x &&
2520
+ this.boundingBox.y < viewportBounds.y + viewportBounds.height &&
2521
+ this.boundingBox.y + this.boundingBox.height > viewportBounds.y;
2998
2522
  }
2999
- undo() {
3000
- this._store.state.objectsOctree.remove(object => object.id === this.selectionGroup.id);
3001
- this._store.state.selectionGroup = null;
2523
+ centerInViewport() {
2524
+ const scale = this._store.state.scale;
2525
+ this.translateX = (this._store.state.viewportWidth / 2 - this.totalWidth / 2 - this._store.state.translateX) / scale;
2526
+ this.translateY = (this._store.state.viewportHeight / 2 - this.totalHeight / 2 - this._store.state.translateY) / scale;
3002
2527
  }
3003
- }
3004
-
3005
- class KritzelImage extends KritzelBaseObject {
3006
- constructor(store, img) {
3007
- super(store);
3008
- this.__class__ = 'KritzelImage';
3009
- this.debugInfoVisible = true;
3010
- this.img = img;
3011
- this.x = 0;
3012
- this.y = 0;
3013
- this.translateX = 0;
3014
- this.translateY = 0;
3015
- this.width = img.width;
3016
- this.height = img.height;
3017
- this.scale = this._store.state.scale;
2528
+ move(startX, startY, endX, endY) {
2529
+ const deltaX = (startX - endX) / this._store.state.scale;
2530
+ const deltaY = (startY - endY) / this._store.state.scale;
2531
+ this.translateX += deltaX;
2532
+ this.translateY += deltaY;
3018
2533
  }
3019
2534
  resize(x, y, width, height) {
3020
2535
  if (width <= 1 || height <= 1) {
3021
2536
  return;
3022
2537
  }
3023
- const scaleFactor = height / this.height;
3024
- this.width = this.width * scaleFactor;
3025
- this.height = this.height * scaleFactor;
2538
+ this.width = width;
2539
+ this.height = height;
3026
2540
  this.translateX = x;
3027
2541
  this.translateY = y;
3028
2542
  }
3029
- }
3030
-
3031
- var cjs = {};
3032
-
3033
- var hasRequiredCjs;
3034
-
3035
- function requireCjs () {
3036
- if (hasRequiredCjs) return cjs;
3037
- hasRequiredCjs = 1;
3038
- (function (exports) {
3039
- var pe=Object.defineProperty;var ge=e=>pe(e,"__esModule",{value:true});var de=(e,t)=>{ge(e);for(var s in t)pe(e,s,{get:t[s],enumerable:true});};de(exports,{default:()=>ve,getStroke:()=>ne,getStrokeOutlinePoints:()=>te,getStrokePoints:()=>re});function $(e,t,s,x=h=>h){return e*x(.5-t*(.5-s))}function ce(e){return [-e[0],-e[1]]}function l(e,t){return [e[0]+t[0],e[1]+t[1]]}function a(e,t){return [e[0]-t[0],e[1]-t[1]]}function b(e,t){return [e[0]*t,e[1]*t]}function xe(e,t){return [e[0]/t,e[1]/t]}function R(e){return [e[1],-e[0]]}function B(e,t){return e[0]*t[0]+e[1]*t[1]}function me(e,t){return e[0]===t[0]&&e[1]===t[1]}function Se(e){return Math.hypot(e[0],e[1])}function Pe(e){return e[0]*e[0]+e[1]*e[1]}function A(e,t){return Pe(a(e,t))}function G(e){return xe(e,Se(e))}function ae(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function L(e,t,s){let x=Math.sin(s),h=Math.cos(s),y=e[0]-t[0],n=e[1]-t[1],f=y*h-n*x,d=y*x+n*h;return [f+t[0],d+t[1]]}function K(e,t,s){return l(e,b(a(t,e),s))}function ee(e,t,s){return l(e,b(t,s))}var{min:C,PI:ke}=Math,le=.275,V=ke+1e-4;function te(e,t={}){let{size:s=16,smoothing:x=.5,thinning:h=.5,simulatePressure:y=true,easing:n=r=>r,start:f={},end:d={},last:D=false}=t,{cap:S=true,easing:j=r=>r*(2-r)}=f,{cap:q=true,easing:c=r=>--r*r*r+1}=d;if(e.length===0||s<=0)return [];let p=e[e.length-1].runningLength,g=f.taper===false?0:f.taper===true?Math.max(s,p):f.taper,T=d.taper===false?0:d.taper===true?Math.max(s,p):d.taper,oe=Math.pow(s*x,2),_=[],M=[],H=e.slice(0,10).reduce((r,i)=>{let o=i.pressure;if(y){let u=C(1,i.distance/s),W=C(1,1-u);o=C(1,r+(W-r)*(u*le));}return (r+o)/2},e[0].pressure),m=$(s,h,e[e.length-1].pressure,n),U,X=e[0].vector,z=e[0].point,F=z,O=z,E=F,J=false;for(let r=0;r<e.length;r++){let{pressure:i}=e[r],{point:o,vector:u,distance:W,runningLength:I}=e[r];if(r<e.length-1&&p-I<3)continue;if(h){if(y){let v=C(1,W/s),Z=C(1,1-v);i=C(1,H+(Z-H)*(v*le));}m=$(s,h,i,n);}else m=s/2;U===void 0&&(U=m);let fe=I<g?j(I/g):1,be=p-I<T?c((p-I)/T):1;m=Math.max(.01,m*Math.min(fe,be));let se=(r<e.length-1?e[r+1]:e[r]).vector,Y=r<e.length-1?B(u,se):1,he=B(u,X)<0&&!J,ue=Y!==null&&Y<0;if(he||ue){let v=b(R(X),m);for(let Z=1/13,w=0;w<=1;w+=Z)O=L(a(o,v),o,V*w),_.push(O),E=L(l(o,v),o,V*-w),M.push(E);z=O,F=E,ue&&(J=true);continue}if(J=false,r===e.length-1){let v=b(R(u),m);_.push(a(o,v)),M.push(l(o,v));continue}let ie=b(R(K(se,u,Y)),m);O=a(o,ie),(r<=1||A(z,O)>oe)&&(_.push(O),z=O),E=l(o,ie),(r<=1||A(F,E)>oe)&&(M.push(E),F=E),H=i,X=u;}let P=e[0].point.slice(0,2),k=e.length>1?e[e.length-1].point.slice(0,2):l(e[0].point,[1,1]),Q=[],N=[];if(e.length===1){if(!(g||T)||D){let r=ee(P,G(R(a(P,k))),-(U||m)),i=[];for(let o=1/13,u=o;u<=1;u+=o)i.push(L(r,P,V*2*u));return i}}else {if(!(g||T&&e.length===1))if(S)for(let i=1/13,o=i;o<=1;o+=i){let u=L(M[0],P,V*o);Q.push(u);}else {let i=a(_[0],M[0]),o=b(i,.5),u=b(i,.51);Q.push(a(P,o),a(P,u),l(P,u),l(P,o));}let r=R(ce(e[e.length-1].vector));if(T||g&&e.length===1)N.push(k);else if(q){let i=ee(k,r,m);for(let o=1/29,u=o;u<1;u+=o)N.push(L(i,k,V*3*u));}else N.push(l(k,b(r,m)),l(k,b(r,m*.99)),a(k,b(r,m*.99)),a(k,b(r,m)));}return _.concat(N,M.reverse(),Q)}function re(e,t={}){var q;let{streamline:s=.5,size:x=16,last:h=false}=t;if(e.length===0)return [];let y=.15+(1-s)*.85,n=Array.isArray(e[0])?e:e.map(({x:c,y:p,pressure:g=.5})=>[c,p,g]);if(n.length===2){let c=n[1];n=n.slice(0,-1);for(let p=1;p<5;p++)n.push(K(n[0],c,p/4));}n.length===1&&(n=[...n,[...l(n[0],[1,1]),...n[0].slice(2)]]);let f=[{point:[n[0][0],n[0][1]],pressure:n[0][2]>=0?n[0][2]:.25,vector:[1,1],distance:0,runningLength:0}],d=false,D=0,S=f[0],j=n.length-1;for(let c=1;c<n.length;c++){let p=h&&c===j?n[c].slice(0,2):K(S.point,n[c],y);if(me(S.point,p))continue;let g=ae(p,S.point);if(D+=g,c<j&&!d){if(D<x)continue;d=true;}S={point:p,pressure:n[c][2]>=0?n[c][2]:.5,vector:G(a(S.point,p)),distance:g,runningLength:D},f.push(S);}return f[0].vector=((q=f[1])==null?void 0:q.vector)||[0,0],f}function ne(e,t={}){return te(re(e,t),t)}var ve=ne;
3040
- } (cjs));
3041
- return cjs;
3042
- }
3043
-
3044
- var cjsExports = requireCjs();
3045
-
3046
- class KritzelMathHelper {
3047
- static average(a, b) {
3048
- return (a + b) / 2;
2543
+ rotate(value) {
2544
+ this.rotation = value;
2545
+ }
2546
+ copy() {
2547
+ const copiedObject = Object.create(Object.getPrototypeOf(this));
2548
+ Object.assign(copiedObject, this);
2549
+ copiedObject.id = this.generateId();
2550
+ copiedObject.isMounted = false;
2551
+ return copiedObject;
2552
+ }
2553
+ revive(object) {
2554
+ Object.assign(this, object);
2555
+ return this;
3049
2556
  }
3050
2557
  }
3051
2558
 
@@ -3206,16 +2713,209 @@ class KritzelBaseTool {
3206
2713
  }
3207
2714
  }
3208
2715
 
3209
- class AddObjectCommand extends KritzelBaseCommand {
3210
- constructor(store, initiator, object) {
3211
- super(store, initiator);
3212
- this.object = object;
2716
+ class KritzelBrushTool extends KritzelBaseTool {
2717
+ constructor(store) {
2718
+ super(store);
2719
+ this.type = 'pen';
2720
+ this.color = '#000000';
2721
+ this.size = 6;
2722
+ this.palettes = {
2723
+ pen: ['#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF', '#808080', '#C0C0C0', '#800000', '#008000', '#000080', '#808000', '#800080'],
2724
+ highlighter: ['#ffff00', '#ffb347', '#b4ffb4'],
2725
+ };
2726
+ }
2727
+ handleMouseDown(event) {
2728
+ if (KritzelEventHelper.isLeftClick(event)) {
2729
+ this._store.state.isDrawing = true;
2730
+ const x = event.clientX - this._store.offsetX;
2731
+ const y = event.clientY - this._store.offsetY;
2732
+ this._store.state.currentPath = new KritzelPath(this._store, {
2733
+ points: [[x, y]],
2734
+ translateX: -this._store.state.translateX,
2735
+ translateY: -this._store.state.translateY,
2736
+ scale: this._store.state.scale,
2737
+ fill: this.color,
2738
+ strokeWidth: this.size,
2739
+ });
2740
+ }
2741
+ }
2742
+ handleMouseMove(event) {
2743
+ if (this._store.state.isDrawing) {
2744
+ const x = event.clientX - this._store.offsetX;
2745
+ const y = event.clientY - this._store.offsetY;
2746
+ this._store.state.currentPath = new KritzelPath(this._store, {
2747
+ points: [...this._store.state.currentPath.points, [x, y]],
2748
+ translateX: -this._store.state.translateX,
2749
+ translateY: -this._store.state.translateY,
2750
+ scale: this._store.state.scale,
2751
+ fill: this.color,
2752
+ strokeWidth: this.size,
2753
+ });
2754
+ this._store.rerender();
2755
+ }
2756
+ }
2757
+ handleMouseUp(_event) {
2758
+ if (this._store.state.isDrawing) {
2759
+ this._store.state.isDrawing = false;
2760
+ if (this._store.state.currentPath) {
2761
+ this._store.state.currentPath.zIndex = this._store.currentZIndex;
2762
+ this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
2763
+ }
2764
+ this._store.state.currentPath = undefined;
2765
+ }
2766
+ }
2767
+ handleTouchStart(event) {
2768
+ if (this._store.state.touchCount === 1) {
2769
+ const x = Math.round(event.touches[0].clientX - this._store.offsetX);
2770
+ const y = Math.round(event.touches[0].clientY - this._store.offsetY);
2771
+ this._store.state.isDrawing = true;
2772
+ this._store.state.currentPath = new KritzelPath(this._store, {
2773
+ points: [[x, y]],
2774
+ translateX: -this._store.state.translateX,
2775
+ translateY: -this._store.state.translateY,
2776
+ scale: this._store.state.scale,
2777
+ fill: this.color,
2778
+ strokeWidth: this.size,
2779
+ });
2780
+ this._store.rerender();
2781
+ }
2782
+ }
2783
+ handleTouchMove(event) {
2784
+ if (this._store.state.touchCount === 1) {
2785
+ const x = Math.round(event.touches[0].clientX - this._store.offsetX);
2786
+ const y = Math.round(event.touches[0].clientY - this._store.offsetY);
2787
+ this._store.state.currentPath = new KritzelPath(this._store, {
2788
+ points: [...this._store.state.currentPath.points, [x, y]],
2789
+ translateX: -this._store.state.translateX,
2790
+ translateY: -this._store.state.translateY,
2791
+ scale: this._store.state.scale,
2792
+ fill: this.color,
2793
+ strokeWidth: this.size,
2794
+ });
2795
+ this._store.rerender();
2796
+ }
2797
+ }
2798
+ handleTouchEnd(_event) {
2799
+ if (this._store.state.isDrawing) {
2800
+ this._store.state.isDrawing = false;
2801
+ if (this._store.state.currentPath) {
2802
+ this._store.state.currentPath.zIndex = this._store.currentZIndex;
2803
+ this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
2804
+ }
2805
+ this._store.state.currentPath = undefined;
2806
+ this._store.rerender();
2807
+ }
2808
+ }
2809
+ }
2810
+
2811
+ class KritzelText extends KritzelBaseObject {
2812
+ get isReadonly() {
2813
+ return !(this._store.state.activeTool instanceof KritzelTextTool);
2814
+ }
2815
+ constructor(store, fontSize, fontFamily) {
2816
+ super(store);
2817
+ this.__class__ = 'KritzelText';
2818
+ this.value = '';
2819
+ this.fontFamily = 'Arial';
2820
+ this.fontSize = 8;
2821
+ this.fontColor = '#000000';
2822
+ this.initialWidth = 3;
2823
+ this.isNew = true;
2824
+ this.debugInfoVisible = true;
2825
+ this.rows = 1;
2826
+ this.fontSize = fontSize;
2827
+ this.fontFamily = fontFamily;
2828
+ this.translateX = 0;
2829
+ this.translateY = 0;
2830
+ this.width = this.initialWidth / (this._store.state.scale < 0 ? this._store.state.scale : 1);
2831
+ this.height = (this.fontSize * 1.2) / (this._store.state.scale < 0 ? this._store.state.scale : 1);
2832
+ this.padding = 5;
2833
+ this.backgroundColor = 'transparent';
2834
+ this.scale = this._store.state.scale;
2835
+ this.value = ' ';
2836
+ }
2837
+ mount(element) {
2838
+ if ((this.isMounted && this.elementRef === element) || this.isInViewport() === false) {
2839
+ return;
2840
+ }
2841
+ this.elementRef = element;
2842
+ this.isMounted = true;
2843
+ }
2844
+ resize(x, y, width, height) {
2845
+ if (width <= 1 || height <= 1) {
2846
+ return;
2847
+ }
2848
+ const scaleFactor = height / this.height;
2849
+ this.fontSize = this.fontSize * scaleFactor;
2850
+ this.width = this.width * scaleFactor;
2851
+ this.height = height;
2852
+ this.translateX = x;
2853
+ this.translateY = y;
2854
+ }
2855
+ handleKeyDown(event) {
2856
+ if (this.isReadonly) {
2857
+ event.preventDefault();
2858
+ event.stopPropagation();
2859
+ }
2860
+ }
2861
+ handleInput(event) {
2862
+ const target = event.target;
2863
+ if (target.value === '') {
2864
+ this.value = ' ';
2865
+ target.value = ' ';
2866
+ target.selectionStart = target.selectionEnd = target.value.length;
2867
+ }
2868
+ else {
2869
+ this.value = target.value.trim();
2870
+ }
2871
+ this.adjustTextareaSize();
2872
+ }
2873
+ adjustTextareaSize() {
2874
+ if (this.elementRef) {
2875
+ const span = document.createElement('span');
2876
+ span.style.position = 'absolute';
2877
+ span.style.whiteSpace = 'pre-wrap';
2878
+ span.style.visibility = 'hidden';
2879
+ span.style.fontSize = window.getComputedStyle(this.elementRef).fontSize;
2880
+ span.style.fontFamily = window.getComputedStyle(this.elementRef).fontFamily;
2881
+ span.innerHTML = this.elementRef.value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>') + '<br>';
2882
+ document.body.appendChild(span);
2883
+ const textWidth = span.offsetWidth;
2884
+ const textHeight = span.offsetHeight;
2885
+ document.body.removeChild(span);
2886
+ this.width = textWidth;
2887
+ this.height = textHeight;
2888
+ this._store.rerender();
2889
+ }
2890
+ }
2891
+ focus() {
2892
+ if (this.elementRef) {
2893
+ this.elementRef.focus();
2894
+ }
3213
2895
  }
3214
- execute() {
3215
- this._store.state.objectsOctree.insert(this.object);
2896
+ selectAll() {
2897
+ if (this.elementRef) {
2898
+ this.elementRef.select();
2899
+ }
3216
2900
  }
3217
- undo() {
3218
- this._store.state.objectsOctree.remove(object => object.id === this.object.id);
2901
+ insertFromClipboard() {
2902
+ if (this.elementRef) {
2903
+ this.elementRef.focus();
2904
+ try {
2905
+ navigator.clipboard.readText().then(text => {
2906
+ const start = this.elementRef.selectionStart;
2907
+ const end = this.elementRef.selectionEnd;
2908
+ const value = this.elementRef.value;
2909
+ this.elementRef.value = value.substring(0, start) + text + value.substring(end);
2910
+ this.elementRef.selectionStart = this.elementRef.selectionEnd = start + text.length;
2911
+ this.value = this.elementRef.value;
2912
+ this.adjustTextareaSize();
2913
+ });
2914
+ }
2915
+ catch (err) {
2916
+ console.error('Failed to read clipboard contents:', err);
2917
+ }
2918
+ }
3219
2919
  }
3220
2920
  }
3221
2921
 
@@ -3336,211 +3036,311 @@ class KritzelTextTool extends KritzelBaseTool {
3336
3036
  }
3337
3037
  }
3338
3038
 
3339
- class KritzelText extends KritzelBaseObject {
3340
- get isReadonly() {
3341
- return !(this._store.state.activeTool instanceof KritzelTextTool);
3039
+ const kritzelControlsCss = ":host{display:flex;flex-direction:column;user-select:none}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap);height:100%;padding:var(--kritzel-controls-padding);background-color:var(--kritzel-controls-background-color);border-radius:var(--kritzel-controls-border-radius);box-shadow:var(--kritzel-controls-box-shadow);border:var(--kritzel-controls-border);border-radius:var(--kritzel-controls-border-radius);z-index:10000;position:relative}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color);border-radius:var(--kritzel-controls-control-border-radius);padding:var(--kritzel-controls-control-padding);border:none;outline:none;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color)}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color)}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color);color:var(--kritzel-controls-control-selected-color)}.kritzel-divider{width:var(--kritzel-controls-divider-width);height:var(--kritzel-controls-divider-height);background-color:var(--kritzel-controls-divider-background-color)}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;width:40px;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:pointer}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color)}.font-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{position:fixed;bottom:66px;left:50%;transform:translateX(-50%);z-index:10001;}";
3040
+
3041
+ const KritzelControls = class {
3042
+ constructor(hostRef) {
3043
+ index.registerInstance(this, hostRef);
3044
+ this.controls = [];
3045
+ this.activeControl = null;
3046
+ this.firstConfig = null;
3047
+ this.tooltipVisible = false;
3048
+ this.kritzelEngine = null;
3342
3049
  }
3343
- constructor(store, fontSize, fontFamily) {
3344
- super(store);
3345
- this.__class__ = 'KritzelText';
3346
- this.value = '';
3347
- this.fontFamily = 'Arial';
3348
- this.fontSize = 8;
3349
- this.fontColor = '#000000';
3350
- this.initialWidth = 3;
3351
- this.isNew = true;
3352
- this.debugInfoVisible = true;
3353
- this.rows = 1;
3354
- this.fontSize = fontSize;
3355
- this.fontFamily = fontFamily;
3356
- this.translateX = 0;
3357
- this.translateY = 0;
3358
- this.width = this.initialWidth / (this._store.state.scale < 0 ? this._store.state.scale : 1);
3359
- this.height = (this.fontSize * 1.2) / (this._store.state.scale < 0 ? this._store.state.scale : 1);
3360
- this.padding = 5;
3361
- this.backgroundColor = 'transparent';
3362
- this.scale = this._store.state.scale;
3363
- this.value = ' ';
3050
+ get activeToolAsTextTool() {
3051
+ var _a;
3052
+ return (_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.tool;
3364
3053
  }
3365
- mount(element) {
3366
- if ((this.isMounted && this.elementRef === element) || this.isInViewport() === false) {
3367
- return;
3054
+ get activeToolAsBrushTool() {
3055
+ var _a;
3056
+ return (_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.tool;
3057
+ }
3058
+ async componentWillLoad() {
3059
+ await this.initializeEngine();
3060
+ await this.initializeTools();
3061
+ }
3062
+ async initializeEngine() {
3063
+ await customElements.whenDefined('kritzel-engine');
3064
+ this.kritzelEngine = this.host.parentElement.querySelector('kritzel-engine');
3065
+ if (!this.kritzelEngine) {
3066
+ throw new Error('kritzel-engine not found in parent element.');
3368
3067
  }
3369
- this.elementRef = element;
3370
- this.isMounted = true;
3371
3068
  }
3372
- resize(x, y, width, height) {
3373
- if (width <= 1 || height <= 1) {
3069
+ async initializeTools() {
3070
+ for (const c of this.controls) {
3071
+ if (c.type === 'tool' && c.tool) {
3072
+ c.tool = await this.kritzelEngine.registerTool(c.name, c.tool, c.config);
3073
+ }
3074
+ if (c.type === 'tool' && c.isDefault && c.tool) {
3075
+ await this.kritzelEngine.changeActiveTool(c.tool);
3076
+ this.activeControl = c;
3077
+ }
3078
+ if (c.type === 'config') {
3079
+ if (this.firstConfig === null) {
3080
+ this.firstConfig = c;
3081
+ }
3082
+ else {
3083
+ console.warn('Only one config control is allowed. The first one will be used.');
3084
+ }
3085
+ }
3086
+ }
3087
+ }
3088
+ async handleActiveToolChange(event) {
3089
+ var _a;
3090
+ this.activeControl = this.controls.find(control => control.tool === event.detail) || null;
3091
+ await ((_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.setFocus());
3092
+ }
3093
+ handleClick(event) {
3094
+ const element = event.target;
3095
+ if (!this.kritzelEngine || element.closest('.kritzel-tooltip')) {
3374
3096
  return;
3375
3097
  }
3376
- const scaleFactor = height / this.height;
3377
- this.fontSize = this.fontSize * scaleFactor;
3378
- this.width = this.width * scaleFactor;
3379
- this.height = height;
3380
- this.translateX = x;
3381
- this.translateY = y;
3098
+ this.tooltipVisible = false;
3099
+ this.kritzelEngine.enable();
3382
3100
  }
3383
- handleKeyDown(event) {
3384
- if (this.isReadonly) {
3101
+ preventDefault(event) {
3102
+ if (event.cancelable) {
3385
3103
  event.preventDefault();
3386
3104
  event.stopPropagation();
3387
3105
  }
3388
3106
  }
3389
- handleInput(event) {
3390
- const target = event.target;
3391
- if (target.value === '') {
3392
- this.value = ' ';
3393
- target.value = ' ';
3394
- target.selectionStart = target.selectionEnd = target.value.length;
3107
+ async handleControlClick(control) {
3108
+ this.activeControl = control;
3109
+ if (this.activeControl.type === 'tool') {
3110
+ await this.kritzelEngine.changeActiveTool(this.activeControl.tool);
3111
+ }
3112
+ }
3113
+ handleConfigClick(event) {
3114
+ event.stopPropagation();
3115
+ this.tooltipVisible = !this.tooltipVisible;
3116
+ this.kritzelEngine.disable();
3117
+ }
3118
+ async handleToolChange(event) {
3119
+ this.activeControl = Object.assign(Object.assign({}, this.activeControl), { tool: event.detail });
3120
+ await this.kritzelEngine.changeActiveTool(this.activeControl.tool);
3121
+ }
3122
+ render() {
3123
+ var _a, _b;
3124
+ const hasNoConfig = ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.config) === undefined || ((_b = this.activeControl) === null || _b === void 0 ? void 0 : _b.config) === null;
3125
+ return (index.h(index.Host, { key: '3231eaa82a3976c3c0868a3ff9d8ad57d75c3419' }, index.h("kritzel-utility-panel", { key: 'ec532bbb855cadef4ea71b70393b44a0b1c217dd', style: {
3126
+ position: 'absolute',
3127
+ bottom: '56px',
3128
+ left: '12px',
3129
+ }, onUndo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.undo(); }, onRedo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.redo(); }, onDelete: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.delete(); } }), index.h("div", { key: 'a8c8ad8acba208c9dd95d7e022f41194c80cd651', class: "kritzel-controls" }, this.controls.map(control => {
3130
+ var _a, _b, _c, _d, _e, _f, _g, _h;
3131
+ if (control.type === 'tool') {
3132
+ return (index.h("button", { class: {
3133
+ 'kritzel-control': true,
3134
+ 'selected': ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.name) === (control === null || control === void 0 ? void 0 : control.name),
3135
+ }, key: control.name, onClick: _event => { var _a; return (_a = this.handleControlClick) === null || _a === void 0 ? void 0 : _a.call(this, control); } }, index.h("kritzel-icon", { name: control.icon })));
3136
+ }
3137
+ if (control.type === 'divider') {
3138
+ return index.h("div", { class: "kritzel-divider", key: control.name });
3139
+ }
3140
+ if (control.type === 'config' && control.name === ((_b = this.firstConfig) === null || _b === void 0 ? void 0 : _b.name) && this.activeControl) {
3141
+ return (index.h("div", { class: "kritzel-config-container", key: control.name }, index.h("kritzel-tooltip", { isVisible: this.tooltipVisible, anchorElement: (_c = this.host.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.kritzel-config-container') }, index.h("div", { style: { width: '294px', height: '100%' } }, this.activeControl.name === 'brush' && (index.h("kritzel-control-brush-config", { tool: this.activeToolAsBrushTool, onToolChange: event => { var _a; return (_a = this.handleToolChange) === null || _a === void 0 ? void 0 : _a.call(this, event); } })), this.activeControl.name === 'text' && (index.h("kritzel-control-text-config", { tool: this.activeToolAsTextTool, onToolChange: event => { var _a; return (_a = this.handleToolChange) === null || _a === void 0 ? void 0 : _a.call(this, event); } })))), index.h("div", { class: "kritzel-config", onClick: event => { var _a; return (_a = this.handleConfigClick) === null || _a === void 0 ? void 0 : _a.call(this, event); }, style: {
3142
+ cursor: this.activeControl.config ? 'pointer' : 'default',
3143
+ pointerEvents: hasNoConfig ? 'none' : 'auto',
3144
+ } }, this.activeControl.tool instanceof KritzelBrushTool && (index.h("div", { class: "color-container" }, index.h("kritzel-color", { value: (_d = this.activeToolAsBrushTool) === null || _d === void 0 ? void 0 : _d.color, size: (_e = this.activeToolAsBrushTool) === null || _e === void 0 ? void 0 : _e.size, style: {
3145
+ borderRadius: '50%',
3146
+ border: 'none',
3147
+ } }))), this.activeControl.tool instanceof KritzelTextTool && (index.h("div", { class: "font-container" }, index.h("kritzel-font", { fontFamily: (_f = this.activeToolAsTextTool) === null || _f === void 0 ? void 0 : _f.fontFamily, size: (_g = this.activeToolAsTextTool) === null || _g === void 0 ? void 0 : _g.fontSize, color: (_h = this.activeToolAsTextTool) === null || _h === void 0 ? void 0 : _h.fontColor }))), hasNoConfig && index.h("div", { class: "no-config" }))));
3148
+ }
3149
+ }))));
3150
+ }
3151
+ static get assetsDirs() { return ["../assets"]; }
3152
+ get host() { return index.getElement(this); }
3153
+ };
3154
+ KritzelControls.style = kritzelControlsCss;
3155
+
3156
+ const kritzelCursorTrailCss = ":host{display:block;position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:9000}";
3157
+
3158
+ const KritzelCursorTrail = class {
3159
+ constructor(hostRef) {
3160
+ index.registerInstance(this, hostRef);
3161
+ this.cursorTrailPoints = [];
3162
+ this.isLeftButtonDown = false;
3163
+ this.TRAIL_DURATION_MS = 100;
3164
+ this.MAX_TRAIL_POINTS = 50;
3165
+ }
3166
+ componentDidLoad() {
3167
+ this.trailCleanupIntervalId = window.setInterval(() => {
3168
+ const now = Date.now();
3169
+ const newTrailPoints = this.cursorTrailPoints.filter(p => now - p.timestamp < this.TRAIL_DURATION_MS);
3170
+ if (newTrailPoints.length !== this.cursorTrailPoints.length) {
3171
+ this.cursorTrailPoints = newTrailPoints;
3172
+ }
3173
+ }, 50);
3174
+ }
3175
+ disconnectedCallback() {
3176
+ if (this.trailCleanupIntervalId) {
3177
+ window.clearInterval(this.trailCleanupIntervalId);
3178
+ }
3179
+ }
3180
+ handleMouseDown(ev) {
3181
+ if (ev.button === 0) {
3182
+ this.isLeftButtonDown = true;
3183
+ this.cursorTrailPoints = [];
3184
+ }
3185
+ }
3186
+ handleMouseMove(ev) {
3187
+ if (!this.isLeftButtonDown) {
3188
+ return;
3189
+ }
3190
+ const newPoint = { x: ev.clientX, y: ev.clientY, timestamp: Date.now() };
3191
+ const updatedTrail = [newPoint, ...this.cursorTrailPoints];
3192
+ if (updatedTrail.length > this.MAX_TRAIL_POINTS) {
3193
+ this.cursorTrailPoints = updatedTrail.slice(0, this.MAX_TRAIL_POINTS);
3395
3194
  }
3396
3195
  else {
3397
- this.value = target.value.trim();
3196
+ this.cursorTrailPoints = updatedTrail;
3398
3197
  }
3399
- this.adjustTextareaSize();
3400
3198
  }
3401
- adjustTextareaSize() {
3402
- if (this.elementRef) {
3403
- const span = document.createElement('span');
3404
- span.style.position = 'absolute';
3405
- span.style.whiteSpace = 'pre-wrap';
3406
- span.style.visibility = 'hidden';
3407
- span.style.fontSize = window.getComputedStyle(this.elementRef).fontSize;
3408
- span.style.fontFamily = window.getComputedStyle(this.elementRef).fontFamily;
3409
- span.innerHTML = this.elementRef.value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>') + '<br>';
3410
- document.body.appendChild(span);
3411
- const textWidth = span.offsetWidth;
3412
- const textHeight = span.offsetHeight;
3413
- document.body.removeChild(span);
3414
- this.width = textWidth;
3415
- this.height = textHeight;
3416
- this._store.rerender();
3199
+ handleMouseUp(ev) {
3200
+ if (ev.button === 0) {
3201
+ this.isLeftButtonDown = false;
3202
+ this.cursorTrailPoints = [];
3417
3203
  }
3418
3204
  }
3419
- focus() {
3420
- if (this.elementRef) {
3421
- this.elementRef.focus();
3205
+ handleTouchStart(ev) {
3206
+ if (ev.touches.length === 1) {
3207
+ this.isLeftButtonDown = true;
3208
+ this.cursorTrailPoints = [];
3209
+ }
3210
+ }
3211
+ handleTouchMove(ev) {
3212
+ if (!this.isLeftButtonDown) {
3213
+ return;
3214
+ }
3215
+ const touch = ev.touches[0];
3216
+ const newPoint = { x: touch.clientX, y: touch.clientY, timestamp: Date.now() };
3217
+ const updatedTrail = [newPoint, ...this.cursorTrailPoints];
3218
+ if (updatedTrail.length > this.MAX_TRAIL_POINTS) {
3219
+ this.cursorTrailPoints = updatedTrail.slice(0, this.MAX_TRAIL_POINTS);
3220
+ }
3221
+ else {
3222
+ this.cursorTrailPoints = updatedTrail;
3422
3223
  }
3423
3224
  }
3424
- selectAll() {
3425
- if (this.elementRef) {
3426
- this.elementRef.select();
3225
+ handleTouchEnd(ev) {
3226
+ if (ev.touches.length === 0) {
3227
+ this.isLeftButtonDown = false;
3228
+ this.cursorTrailPoints = [];
3427
3229
  }
3428
3230
  }
3429
- insertFromClipboard() {
3430
- if (this.elementRef) {
3431
- this.elementRef.focus();
3432
- try {
3433
- navigator.clipboard.readText().then(text => {
3434
- const start = this.elementRef.selectionStart;
3435
- const end = this.elementRef.selectionEnd;
3436
- const value = this.elementRef.value;
3437
- this.elementRef.value = value.substring(0, start) + text + value.substring(end);
3438
- this.elementRef.selectionStart = this.elementRef.selectionEnd = start + text.length;
3439
- this.value = this.elementRef.value;
3440
- this.adjustTextareaSize();
3441
- });
3442
- }
3443
- catch (err) {
3444
- console.error('Failed to read clipboard contents:', err);
3445
- }
3446
- }
3231
+ render() {
3232
+ return (index.h(index.Host, { key: '604f5c39a01f3aea870861de0a93cd162302d7b2' }, this.cursorTrailPoints.length > 1 && (index.h("svg", { key: '731229b4bceebff36a3292a4346d0f44495e3610', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
3233
+ position: 'absolute',
3234
+ left: '0',
3235
+ top: '0',
3236
+ width: '100%',
3237
+ height: '100%',
3238
+ pointerEvents: 'none',
3239
+ opacity: 'var(--kritzel-cursor-trail-opacity)',
3240
+ zIndex: '9000',
3241
+ } }, this.cursorTrailPoints.slice(1).map((point, index$1) => {
3242
+ const prevPoint = this.cursorTrailPoints[index$1];
3243
+ const now = Date.now();
3244
+ const age = now - point.timestamp;
3245
+ const progress = Math.max(0, Math.min(1, age / this.TRAIL_DURATION_MS));
3246
+ if (progress >= 1)
3247
+ return null;
3248
+ const baseStrokeWidth = Math.max(2, 15 * (1 - progress));
3249
+ return (index.h("line", { key: `trail-segment-${point.timestamp}`, x1: prevPoint.x.toString(), y1: prevPoint.y.toString(), x2: point.x.toString(), y2: point.y.toString(), stroke: "var(--kritzel-cursor-trail-color)", "stroke-width": baseStrokeWidth.toString(), "stroke-linecap": "round" }));
3250
+ })))));
3447
3251
  }
3448
- }
3252
+ };
3253
+ KritzelCursorTrail.style = kritzelCursorTrailCss;
3449
3254
 
3450
- class KritzelBrushTool extends KritzelBaseTool {
3451
- constructor(store) {
3452
- super(store);
3453
- this.type = 'pen';
3454
- this.color = '#000000';
3455
- this.size = 6;
3456
- this.palettes = {
3457
- pen: ['#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF', '#808080', '#C0C0C0', '#800000', '#008000', '#000080', '#808000', '#800080'],
3458
- highlighter: ['#ffff00', '#ffb347', '#b4ffb4'],
3255
+ const kritzelDropdownCss = ":host{display:inline-flex;vertical-align:middle;width:100%;}.dropdown-wrapper{display:flex;align-items:center;border:1px solid #333333;border-radius:var(--kritzel-controls-control-border-radius, 4px);overflow:hidden;height:32px;width:100%}.custom-select{padding:0 8px;padding-right:30px;height:100%;width:100%;box-sizing:border-box;border-radius:0;border:none;background-color:#fff;cursor:pointer;outline:none;font-size:inherit;color:var(--kritzel-controls-text-color, #333333);-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"%23333333\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"/></svg>');background-size:16px 16px;background-repeat:no-repeat;background-position:right 8px center}.custom-select.has-suffix-border{border-right:1px solid #333333}.custom-select.has-prefix-border{border-left:1px solid #333333}::slotted(*){height:100%;box-sizing:border-box}";
3256
+
3257
+ const KritzelDropdown = class {
3258
+ constructor(hostRef) {
3259
+ index.registerInstance(this, hostRef);
3260
+ this.valueChanged = index.createEvent(this, "valueChanged");
3261
+ this.options = [];
3262
+ this.selectStyles = {};
3263
+ this.hasSuffixContent = false;
3264
+ this.hasPrefixContent = false;
3265
+ this.handleSelectChange = (event) => {
3266
+ const newValue = event.target.value;
3267
+ if (this.internalValue !== newValue) {
3268
+ this.internalValue = newValue;
3269
+ this.valueChanged.emit(this.internalValue);
3270
+ }
3271
+ };
3272
+ this.evaluateSuffixContent = () => {
3273
+ if (this.suffixSlotElement) {
3274
+ const newHasContent = this.suffixSlotElement.assignedNodes({ flatten: true }).length > 0;
3275
+ if (this.hasSuffixContent !== newHasContent) {
3276
+ this.hasSuffixContent = newHasContent;
3277
+ }
3278
+ }
3279
+ else {
3280
+ if (this.hasSuffixContent !== false) {
3281
+ this.hasSuffixContent = false;
3282
+ }
3283
+ }
3284
+ };
3285
+ this.evaluatePrefixContent = () => {
3286
+ if (this.prefixSlotElement) {
3287
+ const newHasContent = this.prefixSlotElement.assignedNodes({ flatten: true }).length > 0;
3288
+ if (this.hasPrefixContent !== newHasContent) {
3289
+ this.hasPrefixContent = newHasContent;
3290
+ }
3291
+ }
3292
+ else {
3293
+ if (this.hasPrefixContent !== false) {
3294
+ this.hasPrefixContent = false;
3295
+ }
3296
+ }
3459
3297
  };
3460
3298
  }
3461
- handleMouseDown(event) {
3462
- if (KritzelEventHelper.isLeftClick(event)) {
3463
- this._store.state.isDrawing = true;
3464
- const x = event.clientX - this._store.offsetX;
3465
- const y = event.clientY - this._store.offsetY;
3466
- this._store.state.currentPath = new KritzelPath(this._store, {
3467
- points: [[x, y]],
3468
- translateX: -this._store.state.translateX,
3469
- translateY: -this._store.state.translateY,
3470
- scale: this._store.state.scale,
3471
- fill: this.color,
3472
- strokeWidth: this.size,
3473
- });
3474
- }
3299
+ componentWillLoad() {
3300
+ this.updateInternalValue(this.value, false);
3301
+ this.evaluateSuffixContent();
3302
+ this.evaluatePrefixContent();
3475
3303
  }
3476
- handleMouseMove(event) {
3477
- if (this._store.state.isDrawing) {
3478
- const x = event.clientX - this._store.offsetX;
3479
- const y = event.clientY - this._store.offsetY;
3480
- this._store.state.currentPath = new KritzelPath(this._store, {
3481
- points: [...this._store.state.currentPath.points, [x, y]],
3482
- translateX: -this._store.state.translateX,
3483
- translateY: -this._store.state.translateY,
3484
- scale: this._store.state.scale,
3485
- fill: this.color,
3486
- strokeWidth: this.size,
3487
- });
3488
- this._store.rerender();
3304
+ externalValueChanged(newValue) {
3305
+ if (newValue !== this.internalValue) {
3306
+ this.updateInternalValue(newValue, false);
3489
3307
  }
3490
3308
  }
3491
- handleMouseUp(_event) {
3492
- if (this._store.state.isDrawing) {
3493
- this._store.state.isDrawing = false;
3494
- if (this._store.state.currentPath) {
3495
- this._store.state.currentPath.zIndex = this._store.currentZIndex;
3496
- this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
3497
- }
3498
- this._store.state.currentPath = undefined;
3499
- }
3309
+ optionsChanged() {
3310
+ this.updateInternalValue(this.internalValue, true);
3500
3311
  }
3501
- handleTouchStart(event) {
3502
- if (this._store.state.touchCount === 1) {
3503
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
3504
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
3505
- this._store.state.isDrawing = true;
3506
- this._store.state.currentPath = new KritzelPath(this._store, {
3507
- points: [[x, y]],
3508
- translateX: -this._store.state.translateX,
3509
- translateY: -this._store.state.translateY,
3510
- scale: this._store.state.scale,
3511
- fill: this.color,
3512
- strokeWidth: this.size,
3513
- });
3514
- this._store.rerender();
3312
+ updateInternalValue(proposedValue, emitChange) {
3313
+ let finalValue = proposedValue;
3314
+ if (this.options && this.options.length > 0) {
3315
+ const isValidValue = this.options.some(opt => opt.value === finalValue);
3316
+ if (!finalValue || !isValidValue) {
3317
+ finalValue = this.options[0].value;
3318
+ }
3515
3319
  }
3516
- }
3517
- handleTouchMove(event) {
3518
- if (this._store.state.touchCount === 1) {
3519
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
3520
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
3521
- this._store.state.currentPath = new KritzelPath(this._store, {
3522
- points: [...this._store.state.currentPath.points, [x, y]],
3523
- translateX: -this._store.state.translateX,
3524
- translateY: -this._store.state.translateY,
3525
- scale: this._store.state.scale,
3526
- fill: this.color,
3527
- strokeWidth: this.size,
3528
- });
3529
- this._store.rerender();
3320
+ else {
3321
+ finalValue = undefined;
3530
3322
  }
3531
- }
3532
- handleTouchEnd(_event) {
3533
- if (this._store.state.isDrawing) {
3534
- this._store.state.isDrawing = false;
3535
- if (this._store.state.currentPath) {
3536
- this._store.state.currentPath.zIndex = this._store.currentZIndex;
3537
- this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
3323
+ if (this.internalValue !== finalValue) {
3324
+ this.internalValue = finalValue;
3325
+ if (emitChange || (proposedValue !== finalValue && proposedValue !== undefined)) {
3326
+ this.valueChanged.emit(this.internalValue);
3538
3327
  }
3539
- this._store.state.currentPath = undefined;
3540
- this._store.rerender();
3541
3328
  }
3542
3329
  }
3543
- }
3330
+ render() {
3331
+ const selectClasses = {
3332
+ 'custom-select': true,
3333
+ 'has-suffix-border': this.hasSuffixContent,
3334
+ 'has-prefix-border': this.hasPrefixContent,
3335
+ };
3336
+ return (index.h(index.Host, { key: '1e4df5425e205d3709d93d71f2e7a47844a5b0f2' }, index.h("div", { key: '6e0d6fa7b35d1d9d61cf2174828d0d0f0d242683', class: "dropdown-wrapper" }, index.h("slot", { key: '07565dc0982498a9b026bc36f285eb728b5c771b', name: "prefix", ref: el => this.prefixSlotElement = el, onSlotchange: this.evaluatePrefixContent }), index.h("select", { key: 'ba618a1166681f36aae554242192e375286ba7e8', class: selectClasses, style: Object.assign(Object.assign({}, this.selectStyles), { width: this.width }), onInput: this.handleSelectChange }, this.options.map(option => (index.h("option", { value: option.value, style: option.style, selected: option.value === this.internalValue }, option.label)))), index.h("slot", { key: '2731003fa214cb3aa968b48db36ab1816d563425', name: "suffix", ref: el => this.suffixSlotElement = el, onSlotchange: this.evaluateSuffixContent }))));
3337
+ }
3338
+ static get watchers() { return {
3339
+ "value": ["externalValueChanged"],
3340
+ "options": ["optionsChanged"]
3341
+ }; }
3342
+ };
3343
+ KritzelDropdown.style = kritzelDropdownCss;
3544
3344
 
3545
3345
  class BatchCommand extends KritzelBaseCommand {
3546
3346
  constructor(store, initiator, commands) {
@@ -3642,1097 +3442,1167 @@ class KritzelEraserTool extends KritzelBaseTool {
3642
3442
  }
3643
3443
  }
3644
3444
 
3645
- /**
3646
- * Browser Image Compression
3647
- * v2.0.2
3648
- * by Donald <donaldcwl@gmail.com>
3649
- * https://github.com/Donaldcwl/browser-image-compression
3650
- */
3651
-
3652
- function _mergeNamespaces$1(e,t){return t.forEach((function(t){t&&"string"!=typeof t&&!Array.isArray(t)&&Object.keys(t).forEach((function(r){if("default"!==r&&!(r in e)){var i=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,i.get?i:{enumerable:true,get:function(){return t[r]}});}}));})),Object.freeze(e)}function copyExifWithoutOrientation(e,t){return new Promise((function(r,i){let o;return getApp1Segment(e).then((function(e){try{return o=e,r(new Blob([t.slice(0,2),o,t.slice(2)],{type:"image/jpeg"}))}catch(e){return i(e)}}),i)}))}const getApp1Segment=e=>new Promise(((t,r)=>{const i=new FileReader;i.addEventListener("load",(({target:{result:e}})=>{const i=new DataView(e);let o=0;if(65496!==i.getUint16(o))return r("not a valid JPEG");for(o+=2;;){const a=i.getUint16(o);if(65498===a)break;const s=i.getUint16(o+2);if(65505===a&&1165519206===i.getUint32(o+4)){const a=o+10;let f;switch(i.getUint16(a)){case 18761:f=true;break;case 19789:f=false;break;default:return r("TIFF header contains invalid endian")}if(42!==i.getUint16(a+2,f))return r("TIFF header contains invalid version");const l=i.getUint32(a+4,f),c=a+l+2+12*i.getUint16(a+l,f);for(let e=a+l+2;e<c;e+=12){if(274==i.getUint16(e,f)){if(3!==i.getUint16(e+2,f))return r("Orientation data type is invalid");if(1!==i.getUint32(e+4,f))return r("Orientation data count is invalid");i.setUint16(e+8,1,f);break}}return t(e.slice(o,o+2+s))}o+=2+s;}return t(new Blob)})),i.readAsArrayBuffer(e);}));var e={},t={get exports(){return e},set exports(t){e=t;}};!function(e){var r,i,UZIP={};t.exports=UZIP,UZIP.parse=function(e,t){for(var r=UZIP.bin.readUshort,i=UZIP.bin.readUint,o=0,a={},s=new Uint8Array(e),f=s.length-4;101010256!=i(s,f);)f--;o=f;o+=4;var l=r(s,o+=4);r(s,o+=2);var c=i(s,o+=2),u=i(s,o+=4);o+=4,o=u;for(var h=0;h<l;h++){i(s,o),o+=4,o+=4,o+=4,i(s,o+=4);c=i(s,o+=4);var d=i(s,o+=4),A=r(s,o+=4),g=r(s,o+2),p=r(s,o+4);o+=6;var m=i(s,o+=8);o+=4,o+=A+g+p,UZIP._readLocal(s,m,a,c,d,t);}return a},UZIP._readLocal=function(e,t,r,i,o,a){var s=UZIP.bin.readUshort,f=UZIP.bin.readUint;f(e,t),s(e,t+=4),s(e,t+=2);var l=s(e,t+=2);f(e,t+=2),f(e,t+=4),t+=4;var c=s(e,t+=8),u=s(e,t+=2);t+=2;var h=UZIP.bin.readUTF8(e,t,c);if(t+=c,t+=u,a)r[h]={size:o,csize:i};else {var d=new Uint8Array(e.buffer,t);if(0==l)r[h]=new Uint8Array(d.buffer.slice(t,t+i));else {if(8!=l)throw "unknown compression method: "+l;var A=new Uint8Array(o);UZIP.inflateRaw(d,A),r[h]=A;}}},UZIP.inflateRaw=function(e,t){return UZIP.F.inflate(e,t)},UZIP.inflate=function(e,t){return UZIP.inflateRaw(new Uint8Array(e.buffer,e.byteOffset+2,e.length-6),t)},UZIP.deflate=function(e,t){null==t&&(t={level:6});var r=0,i=new Uint8Array(50+Math.floor(1.1*e.length));i[r]=120,i[r+1]=156,r+=2,r=UZIP.F.deflateRaw(e,i,r,t.level);var o=UZIP.adler(e,0,e.length);return i[r+0]=o>>>24&255,i[r+1]=o>>>16&255,i[r+2]=o>>>8&255,i[r+3]=o>>>0&255,new Uint8Array(i.buffer,0,r+4)},UZIP.deflateRaw=function(e,t){null==t&&(t={level:6});var r=new Uint8Array(50+Math.floor(1.1*e.length)),i=UZIP.F.deflateRaw(e,r,i,t.level);return new Uint8Array(r.buffer,0,i)},UZIP.encode=function(e,t){null==t&&(t=false);var r=0,i=UZIP.bin.writeUint,o=UZIP.bin.writeUshort,a={};for(var s in e){var f=!UZIP._noNeed(s)&&!t,l=e[s],c=UZIP.crc.crc(l,0,l.length);a[s]={cpr:f,usize:l.length,crc:c,file:f?UZIP.deflateRaw(l):l};}for(var s in a)r+=a[s].file.length+30+46+2*UZIP.bin.sizeUTF8(s);r+=22;var u=new Uint8Array(r),h=0,d=[];for(var s in a){var A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,0);}var g=0,p=h;for(var s in a){A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,1,d[g++]);}var m=h-p;return i(u,h,101010256),h+=4,o(u,h+=4,g),o(u,h+=2,g),i(u,h+=2,m),i(u,h+=4,p),h+=4,h+=2,u.buffer},UZIP._noNeed=function(e){var t=e.split(".").pop().toLowerCase();return -1!="png,jpg,jpeg,zip".indexOf(t)},UZIP._writeHeader=function(e,t,r,i,o,a){var s=UZIP.bin.writeUint,f=UZIP.bin.writeUshort,l=i.file;return s(e,t,0==o?67324752:33639248),t+=4,1==o&&(t+=2),f(e,t,20),f(e,t+=2,0),f(e,t+=2,i.cpr?8:0),s(e,t+=2,0),s(e,t+=4,i.crc),s(e,t+=4,l.length),s(e,t+=4,i.usize),f(e,t+=4,UZIP.bin.sizeUTF8(r)),f(e,t+=2,0),t+=2,1==o&&(t+=2,t+=2,s(e,t+=6,a),t+=4),t+=UZIP.bin.writeUTF8(e,t,r),0==o&&(e.set(l,t),t+=l.length),t},UZIP.crc={table:function(){for(var e=new Uint32Array(256),t=0;t<256;t++){for(var r=t,i=0;i<8;i++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r;}return e}(),update:function(e,t,r,i){for(var o=0;o<i;o++)e=UZIP.crc.table[255&(e^t[r+o])]^e>>>8;return e},crc:function(e,t,r){return 4294967295^UZIP.crc.update(4294967295,e,t,r)}},UZIP.adler=function(e,t,r){for(var i=1,o=0,a=t,s=t+r;a<s;){for(var f=Math.min(a+5552,s);a<f;)o+=i+=e[a++];i%=65521,o%=65521;}return o<<16|i},UZIP.bin={readUshort:function(e,t){return e[t]|e[t+1]<<8},writeUshort:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255;},readUint:function(e,t){return 16777216*e[t+3]+(e[t+2]<<16|e[t+1]<<8|e[t])},writeUint:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255,e[t+2]=r>>16&255,e[t+3]=r>>24&255;},readASCII:function(e,t,r){for(var i="",o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII:function(e,t,r){for(var i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i);},pad:function(e){return e.length<2?"0"+e:e},readUTF8:function(e,t,r){for(var i,o="",a=0;a<r;a++)o+="%"+UZIP.bin.pad(e[t+a].toString(16));try{i=decodeURIComponent(o);}catch(i){return UZIP.bin.readASCII(e,t,r)}return i},writeUTF8:function(e,t,r){for(var i=r.length,o=0,a=0;a<i;a++){var s=r.charCodeAt(a);if(0==(4294967168&s))e[t+o]=s,o++;else if(0==(4294965248&s))e[t+o]=192|s>>6,e[t+o+1]=128|s>>0&63,o+=2;else if(0==(4294901760&s))e[t+o]=224|s>>12,e[t+o+1]=128|s>>6&63,e[t+o+2]=128|s>>0&63,o+=3;else {if(0!=(4292870144&s))throw "e";e[t+o]=240|s>>18,e[t+o+1]=128|s>>12&63,e[t+o+2]=128|s>>6&63,e[t+o+3]=128|s>>0&63,o+=4;}}return o},sizeUTF8:function(e){for(var t=e.length,r=0,i=0;i<t;i++){var o=e.charCodeAt(i);if(0==(4294967168&o))r++;else if(0==(4294965248&o))r+=2;else if(0==(4294901760&o))r+=3;else {if(0!=(4292870144&o))throw "e";r+=4;}}return r}},UZIP.F={},UZIP.F.deflateRaw=function(e,t,r,i){var o=[[0,0,0,0,0],[4,4,8,4,0],[4,5,16,8,0],[4,6,16,16,0],[4,10,16,32,0],[8,16,32,32,0],[8,16,128,128,0],[8,32,128,256,0],[32,128,258,1024,1],[32,258,258,4096,1]][i],a=UZIP.F.U,s=UZIP.F._goodIndex;var f=UZIP.F._putsE,l=0,c=r<<3,u=0,h=e.length;if(0==i){for(;l<h;){f(t,c,l+(_=Math.min(65535,h-l))==h?1:0),c=UZIP.F._copyExact(e,l,_,t,c+8),l+=_;}return c>>>3}var d=a.lits,A=a.strt,g=a.prev,p=0,m=0,w=0,v=0,b=0,y=0;for(h>2&&(A[y=UZIP.F._hash(e,0)]=0),l=0;l<h;l++){if(b=y,l+1<h-2){y=UZIP.F._hash(e,l+1);var E=l+1&32767;g[E]=A[y],A[y]=E;}if(u<=l){(p>14e3||m>26697)&&h-l>100&&(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(l==h-1||u==h?1:0,d,p,v,e,w,l-w,t,c),p=m=v=0,w=l);var F=0;l<h-2&&(F=UZIP.F._bestMatch(e,l,g,b,Math.min(o[2],h-l),o[3]));var _=F>>>16,B=65535&F;if(0!=F){B=65535&F;var U=s(_=F>>>16,a.of0);a.lhst[257+U]++;var C=s(B,a.df0);a.dhst[C]++,v+=a.exb[U]+a.dxb[C],d[p]=_<<23|l-u,d[p+1]=B<<16|U<<8|C,p+=2,u=l+_;}else a.lhst[e[l]]++;m++;}}for(w==l&&0!=e.length||(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(1,d,p,v,e,w,l-w,t,c),p=0,m=0,p=m=v=0,w=l);0!=(7&c);)c++;return c>>>3},UZIP.F._bestMatch=function(e,t,r,i,o,a){var s=32767&t,f=r[s],l=s-f+32768&32767;if(f==s||i!=UZIP.F._hash(e,t-l))return 0;for(var c=0,u=0,h=Math.min(32767,t);l<=h&&0!=--a&&f!=s;){if(0==c||e[t+c]==e[t+c-l]){var d=UZIP.F._howLong(e,t,l);if(d>c){if(u=l,(c=d)>=o)break;l+2<d&&(d=l+2);for(var A=0,g=0;g<d-2;g++){var p=t-l+g+32768&32767,m=p-r[p]+32768&32767;m>A&&(A=m,f=p);}}}l+=(s=f)-(f=r[s])+32768&32767;}return c<<16|u},UZIP.F._howLong=function(e,t,r){if(e[t]!=e[t-r]||e[t+1]!=e[t+1-r]||e[t+2]!=e[t+2-r])return 0;var i=t,o=Math.min(e.length,t+258);for(t+=3;t<o&&e[t]==e[t-r];)t++;return t-i},UZIP.F._hash=function(e,t){return (e[t]<<8|e[t+1])+(e[t+2]<<4)&65535},UZIP.saved=0,UZIP.F._writeBlock=function(e,t,r,i,o,a,s,f,l){var c,u,h,d,A,g,p,m,w,v=UZIP.F.U,b=UZIP.F._putsF,y=UZIP.F._putsE;v.lhst[256]++,u=(c=UZIP.F.getTrees())[0],h=c[1],d=c[2],A=c[3],g=c[4],p=c[5],m=c[6],w=c[7];var E=32+(0==(l+3&7)?0:8-(l+3&7))+(s<<3),F=i+UZIP.F.contSize(v.fltree,v.lhst)+UZIP.F.contSize(v.fdtree,v.dhst),_=i+UZIP.F.contSize(v.ltree,v.lhst)+UZIP.F.contSize(v.dtree,v.dhst);_+=14+3*p+UZIP.F.contSize(v.itree,v.ihst)+(2*v.ihst[16]+3*v.ihst[17]+7*v.ihst[18]);for(var B=0;B<286;B++)v.lhst[B]=0;for(B=0;B<30;B++)v.dhst[B]=0;for(B=0;B<19;B++)v.ihst[B]=0;var U=E<F&&E<_?0:F<_?1:2;if(b(f,l,e),b(f,l+1,U),l+=3,0==U){for(;0!=(7&l);)l++;l=UZIP.F._copyExact(o,a,s,f,l);}else {var C,I;if(1==U&&(C=v.fltree,I=v.fdtree),2==U){UZIP.F.makeCodes(v.ltree,u),UZIP.F.revCodes(v.ltree,u),UZIP.F.makeCodes(v.dtree,h),UZIP.F.revCodes(v.dtree,h),UZIP.F.makeCodes(v.itree,d),UZIP.F.revCodes(v.itree,d),C=v.ltree,I=v.dtree,y(f,l,A-257),y(f,l+=5,g-1),y(f,l+=5,p-4),l+=4;for(var Q=0;Q<p;Q++)y(f,l+3*Q,v.itree[1+(v.ordr[Q]<<1)]);l+=3*p,l=UZIP.F._codeTiny(m,v.itree,f,l),l=UZIP.F._codeTiny(w,v.itree,f,l);}for(var M=a,x=0;x<r;x+=2){for(var S=t[x],R=S>>>23,T=M+(8388607&S);M<T;)l=UZIP.F._writeLit(o[M++],C,f,l);if(0!=R){var O=t[x+1],P=O>>16,H=O>>8&255,L=255&O;y(f,l=UZIP.F._writeLit(257+H,C,f,l),R-v.of0[H]),l+=v.exb[H],b(f,l=UZIP.F._writeLit(L,I,f,l),P-v.df0[L]),l+=v.dxb[L],M+=R;}}l=UZIP.F._writeLit(256,C,f,l);}return l},UZIP.F._copyExact=function(e,t,r,i,o){var a=o>>>3;return i[a]=r,i[a+1]=r>>>8,i[a+2]=255-i[a],i[a+3]=255-i[a+1],a+=4,i.set(new Uint8Array(e.buffer,t,r),a),o+(r+4<<3)},UZIP.F.getTrees=function(){for(var e=UZIP.F.U,t=UZIP.F._hufTree(e.lhst,e.ltree,15),r=UZIP.F._hufTree(e.dhst,e.dtree,15),i=[],o=UZIP.F._lenCodes(e.ltree,i),a=[],s=UZIP.F._lenCodes(e.dtree,a),f=0;f<i.length;f+=2)e.ihst[i[f]]++;for(f=0;f<a.length;f+=2)e.ihst[a[f]]++;for(var l=UZIP.F._hufTree(e.ihst,e.itree,7),c=19;c>4&&0==e.itree[1+(e.ordr[c-1]<<1)];)c--;return [t,r,l,o,s,c,i,a]},UZIP.F.getSecond=function(e){for(var t=[],r=0;r<e.length;r+=2)t.push(e[r+1]);return t},UZIP.F.nonZero=function(e){for(var t="",r=0;r<e.length;r+=2)0!=e[r+1]&&(t+=(r>>1)+",");return t},UZIP.F.contSize=function(e,t){for(var r=0,i=0;i<t.length;i++)r+=t[i]*e[1+(i<<1)];return r},UZIP.F._codeTiny=function(e,t,r,i){for(var o=0;o<e.length;o+=2){var a=e[o],s=e[o+1];i=UZIP.F._writeLit(a,t,r,i);var f=16==a?2:17==a?3:7;a>15&&(UZIP.F._putsE(r,i,s,f),i+=f);}return i},UZIP.F._lenCodes=function(e,t){for(var r=e.length;2!=r&&0==e[r-1];)r-=2;for(var i=0;i<r;i+=2){var o=e[i+1],a=i+3<r?e[i+3]:-1,s=i+5<r?e[i+5]:-1,f=0==i?-1:e[i-1];if(0==o&&a==o&&s==o){for(var l=i+5;l+2<r&&e[l+2]==o;)l+=2;(c=Math.min(l+1-i>>>1,138))<11?t.push(17,c-3):t.push(18,c-11),i+=2*c-2;}else if(o==f&&a==o&&s==o){for(l=i+5;l+2<r&&e[l+2]==o;)l+=2;var c=Math.min(l+1-i>>>1,6);t.push(16,c-3),i+=2*c-2;}else t.push(o,0);}return r>>>1},UZIP.F._hufTree=function(e,t,r){var i=[],o=e.length,a=t.length,s=0;for(s=0;s<a;s+=2)t[s]=0,t[s+1]=0;for(s=0;s<o;s++)0!=e[s]&&i.push({lit:s,f:e[s]});var f=i.length,l=i.slice(0);if(0==f)return 0;if(1==f){var c=i[0].lit;l=0==c?1:0;return t[1+(c<<1)]=1,t[1+(l<<1)]=1,1}i.sort((function(e,t){return e.f-t.f}));var u=i[0],h=i[1],d=0,A=1,g=2;for(i[0]={lit:-1,f:u.f+h.f,l:u,r:h,d:0};A!=f-1;)u=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],h=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],i[A++]={lit:-1,f:u.f+h.f,l:u,r:h};var p=UZIP.F.setDepth(i[A-1],0);for(p>r&&(UZIP.F.restrictDepth(l,r,p),p=r),s=0;s<f;s++)t[1+(l[s].lit<<1)]=l[s].d;return p},UZIP.F.setDepth=function(e,t){return -1!=e.lit?(e.d=t,t):Math.max(UZIP.F.setDepth(e.l,t+1),UZIP.F.setDepth(e.r,t+1))},UZIP.F.restrictDepth=function(e,t,r){var i=0,o=1<<r-t,a=0;for(e.sort((function(e,t){return t.d==e.d?e.f-t.f:t.d-e.d})),i=0;i<e.length&&e[i].d>t;i++){var s=e[i].d;e[i].d=t,a+=o-(1<<r-s);}for(a>>>=r-t;a>0;){(s=e[i].d)<t?(e[i].d++,a-=1<<t-s-1):i++;}for(;i>=0;i--)e[i].d==t&&a<0&&(e[i].d--,a++);0!=a&&console.log("debt left");},UZIP.F._goodIndex=function(e,t){var r=0;return t[16|r]<=e&&(r|=16),t[8|r]<=e&&(r|=8),t[4|r]<=e&&(r|=4),t[2|r]<=e&&(r|=2),t[1|r]<=e&&(r|=1),r},UZIP.F._writeLit=function(e,t,r,i){return UZIP.F._putsF(r,i,t[e<<1]),i+t[1+(e<<1)]},UZIP.F.inflate=function(e,t){var r=Uint8Array;if(3==e[0]&&0==e[1])return t||new r(0);var i=UZIP.F,o=i._bitsF,a=i._bitsE,s=i._decodeTiny,f=i.makeCodes,l=i.codes2map,c=i._get17,u=i.U,h=null==t;h&&(t=new r(e.length>>>2<<3));for(var d,A,g=0,p=0,m=0,w=0,v=0,b=0,y=0,E=0,F=0;0==g;)if(g=o(e,F,1),p=o(e,F+1,2),F+=3,0!=p){if(h&&(t=UZIP.F._check(t,E+(1<<17))),1==p&&(d=u.flmap,A=u.fdmap,b=511,y=31),2==p){m=a(e,F,5)+257,w=a(e,F+5,5)+1,v=a(e,F+10,4)+4,F+=14;for(var _=0;_<38;_+=2)u.itree[_]=0,u.itree[_+1]=0;var B=1;for(_=0;_<v;_++){var U=a(e,F+3*_,3);u.itree[1+(u.ordr[_]<<1)]=U,U>B&&(B=U);}F+=3*v,f(u.itree,B),l(u.itree,B,u.imap),d=u.lmap,A=u.dmap,F=s(u.imap,(1<<B)-1,m+w,e,F,u.ttree);var C=i._copyOut(u.ttree,0,m,u.ltree);b=(1<<C)-1;var I=i._copyOut(u.ttree,m,w,u.dtree);y=(1<<I)-1,f(u.ltree,C),l(u.ltree,C,d),f(u.dtree,I),l(u.dtree,I,A);}for(;;){var Q=d[c(e,F)&b];F+=15&Q;var M=Q>>>4;if(M>>>8==0)t[E++]=M;else {if(256==M)break;var x=E+M-254;if(M>264){var S=u.ldef[M-257];x=E+(S>>>3)+a(e,F,7&S),F+=7&S;}var R=A[c(e,F)&y];F+=15&R;var T=R>>>4,O=u.ddef[T],P=(O>>>4)+o(e,F,15&O);for(F+=15&O,h&&(t=UZIP.F._check(t,E+(1<<17)));E<x;)t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P];E=x;}}}else {0!=(7&F)&&(F+=8-(7&F));var H=4+(F>>>3),L=e[H-4]|e[H-3]<<8;h&&(t=UZIP.F._check(t,E+L)),t.set(new r(e.buffer,e.byteOffset+H,L),E),F=H+L<<3,E+=L;}return t.length==E?t:t.slice(0,E)},UZIP.F._check=function(e,t){var r=e.length;if(t<=r)return e;var i=new Uint8Array(Math.max(r<<1,t));return i.set(e,0),i},UZIP.F._decodeTiny=function(e,t,r,i,o,a){for(var s=UZIP.F._bitsE,f=UZIP.F._get17,l=0;l<r;){var c=e[f(i,o)&t];o+=15&c;var u=c>>>4;if(u<=15)a[l]=u,l++;else {var h=0,d=0;16==u?(d=3+s(i,o,2),o+=2,h=a[l-1]):17==u?(d=3+s(i,o,3),o+=3):18==u&&(d=11+s(i,o,7),o+=7);for(var A=l+d;l<A;)a[l]=h,l++;}}return o},UZIP.F._copyOut=function(e,t,r,i){for(var o=0,a=0,s=i.length>>>1;a<r;){var f=e[a+t];i[a<<1]=0,i[1+(a<<1)]=f,f>o&&(o=f),a++;}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},UZIP.F.makeCodes=function(e,t){for(var r,i,o,a,s=UZIP.F.U,f=e.length,l=s.bl_count,c=0;c<=t;c++)l[c]=0;for(c=1;c<f;c+=2)l[e[c]]++;var u=s.next_code;for(r=0,l[0]=0,i=1;i<=t;i++)r=r+l[i-1]<<1,u[i]=r;for(o=0;o<f;o+=2)0!=(a=e[o+1])&&(e[o]=u[a],u[a]++);},UZIP.F.codes2map=function(e,t,r){for(var i=e.length,o=UZIP.F.U.rev15,a=0;a<i;a+=2)if(0!=e[a+1])for(var s=a>>1,f=e[a+1],l=s<<4|f,c=t-f,u=e[a]<<c,h=u+(1<<c);u!=h;){r[o[u]>>>15-t]=l,u++;}},UZIP.F.revCodes=function(e,t){for(var r=UZIP.F.U.rev15,i=15-t,o=0;o<e.length;o+=2){var a=e[o]<<t-e[o+1];e[o]=r[a]>>>i;}},UZIP.F._putsE=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8;},UZIP.F._putsF=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16;},UZIP.F._bitsE=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},UZIP.F._bitsF=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},UZIP.F._get17=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},UZIP.F._get25=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},UZIP.F.U=(r=Uint16Array,i=Uint32Array,{next_code:new r(16),bl_count:new r(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new r(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new i(32),flmap:new r(512),fltree:[],fdmap:new r(32),fdtree:[],lmap:new r(32768),ltree:[],ttree:[],dmap:new r(32768),dtree:[],imap:new r(512),itree:[],rev15:new r(32768),lhst:new i(286),dhst:new i(30),ihst:new i(19),lits:new i(15e3),strt:new r(65536),prev:new r(32768)}),function(){for(var e=UZIP.F.U,t=0;t<32768;t++){var r=t;r=(4278255360&(r=(4042322160&(r=(3435973836&(r=(2863311530&r)>>>1|(1431655765&r)<<1))>>>2|(858993459&r)<<2))>>>4|(252645135&r)<<4))>>>8|(16711935&r)<<8,e.rev15[t]=(r>>>16|r<<16)>>>17;}function pushV(e,t,r){for(;0!=t--;)e.push(0,r);}for(t=0;t<32;t++)e.ldef[t]=e.of0[t]<<3|e.exb[t],e.ddef[t]=e.df0[t]<<4|e.dxb[t];pushV(e.fltree,144,8),pushV(e.fltree,112,9),pushV(e.fltree,24,7),pushV(e.fltree,8,8),UZIP.F.makeCodes(e.fltree,9),UZIP.F.codes2map(e.fltree,9,e.flmap),UZIP.F.revCodes(e.fltree,9),pushV(e.fdtree,32,5),UZIP.F.makeCodes(e.fdtree,5),UZIP.F.codes2map(e.fdtree,5,e.fdmap),UZIP.F.revCodes(e.fdtree,5),pushV(e.itree,19,0),pushV(e.ltree,286,0),pushV(e.dtree,30,0),pushV(e.ttree,320,0);}();}();var UZIP=_mergeNamespaces$1({__proto__:null,default:e},[e]);const UPNG=function(){var e={nextZero(e,t){for(;0!=e[t];)t++;return t},readUshort:(e,t)=>e[t]<<8|e[t+1],writeUshort(e,t,r){e[t]=r>>8&255,e[t+1]=255&r;},readUint:(e,t)=>16777216*e[t]+(e[t+1]<<16|e[t+2]<<8|e[t+3]),writeUint(e,t,r){e[t]=r>>24&255,e[t+1]=r>>16&255,e[t+2]=r>>8&255,e[t+3]=255&r;},readASCII(e,t,r){let i="";for(let o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII(e,t,r){for(let i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i);},readBytes(e,t,r){const i=[];for(let o=0;o<r;o++)i.push(e[t+o]);return i},pad:e=>e.length<2?`0${e}`:e,readUTF8(t,r,i){let o,a="";for(let o=0;o<i;o++)a+=`%${e.pad(t[r+o].toString(16))}`;try{o=decodeURIComponent(a);}catch(o){return e.readASCII(t,r,i)}return o}};function decodeImage(t,r,i,o){const a=r*i,s=_getBPP(o),f=Math.ceil(r*s/8),l=new Uint8Array(4*a),c=new Uint32Array(l.buffer),{ctype:u}=o,{depth:h}=o,d=e.readUshort;if(6==u){const e=a<<2;if(8==h)for(var A=0;A<e;A+=4)l[A]=t[A],l[A+1]=t[A+1],l[A+2]=t[A+2],l[A+3]=t[A+3];if(16==h)for(A=0;A<e;A++)l[A]=t[A<<1];}else if(2==u){const e=o.tabs.tRNS;if(null==e){if(8==h)for(A=0;A<a;A++){var g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g];}if(16==h)for(A=0;A<a;A++){g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g];}}else {var p=e[0];const r=e[1],i=e[2];if(8==h)for(A=0;A<a;A++){var m=A<<2;g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g],t[g]==p&&t[g+1]==r&&t[g+2]==i&&(l[m+3]=0);}if(16==h)for(A=0;A<a;A++){m=A<<2,g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g],d(t,g)==p&&d(t,g+2)==r&&d(t,g+4)==i&&(l[m+3]=0);}}}else if(3==u){const e=o.tabs.PLTE,s=o.tabs.tRNS,c=s?s.length:0;if(1==h)for(var w=0;w<i;w++){var v=w*f,b=w*r;for(A=0;A<r;A++){m=b+A<<2;var y=3*(E=t[v+(A>>3)]>>7-((7&A)<<0)&1);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}}if(2==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>2)]>>6-((3&A)<<1)&3);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}if(4==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>1)]>>4-((1&A)<<2)&15);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}if(8==h)for(A=0;A<a;A++){var E;m=A<<2,y=3*(E=t[A]);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}}else if(4==u){if(8==h)for(A=0;A<a;A++){m=A<<2;var F=t[_=A<<1];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+1];}if(16==h)for(A=0;A<a;A++){var _;m=A<<2,F=t[_=A<<2];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+2];}}else if(0==u)for(p=o.tabs.tRNS?o.tabs.tRNS:-1,w=0;w<i;w++){const e=w*f,i=w*r;if(1==h)for(var B=0;B<r;B++){var U=(F=255*(t[e+(B>>>3)]>>>7-(7&B)&1))==255*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(2==h)for(B=0;B<r;B++){U=(F=85*(t[e+(B>>>2)]>>>6-((3&B)<<1)&3))==85*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(4==h)for(B=0;B<r;B++){U=(F=17*(t[e+(B>>>1)]>>>4-((1&B)<<2)&15))==17*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(8==h)for(B=0;B<r;B++){U=(F=t[e+B])==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(16==h)for(B=0;B<r;B++){F=t[e+(B<<1)],U=d(t,e+(B<<1))==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}}return l}function _decompress(e,r,i,o){const a=_getBPP(e),s=Math.ceil(i*a/8),f=new Uint8Array((s+1+e.interlace)*o);return r=e.tabs.CgBI?t(r,f):_inflate(r,f),0==e.interlace?r=_filterZero(r,e,0,i,o):1==e.interlace&&(r=function _readInterlace(e,t){const r=t.width,i=t.height,o=_getBPP(t),a=o>>3,s=Math.ceil(r*o/8),f=new Uint8Array(i*s);let l=0;const c=[0,0,4,0,2,0,1],u=[0,4,0,2,0,1,0],h=[8,8,8,4,4,2,2],d=[8,8,4,4,2,2,1];let A=0;for(;A<7;){const p=h[A],m=d[A];let w=0,v=0,b=c[A];for(;b<i;)b+=p,v++;let y=u[A];for(;y<r;)y+=m,w++;const E=Math.ceil(w*o/8);_filterZero(e,t,l,w,v);let F=0,_=c[A];for(;_<i;){let t=u[A],i=l+F*E<<3;for(;t<r;){var g;if(1==o)g=(g=e[i>>3])>>7-(7&i)&1,f[_*s+(t>>3)]|=g<<7-((7&t)<<0);if(2==o)g=(g=e[i>>3])>>6-(7&i)&3,f[_*s+(t>>2)]|=g<<6-((3&t)<<1);if(4==o)g=(g=e[i>>3])>>4-(7&i)&15,f[_*s+(t>>1)]|=g<<4-((1&t)<<2);if(o>=8){const r=_*s+t*a;for(let t=0;t<a;t++)f[r+t]=e[(i>>3)+t];}i+=o,t+=m;}F++,_+=p;}w*v!=0&&(l+=v*(1+E)),A+=1;}return f}(r,e)),r}function _inflate(e,r){return t(new Uint8Array(e.buffer,2,e.length-6),r)}var t=function(){const e={H:{}};return e.H.N=function(t,r){const i=Uint8Array;let o,a,s=0,f=0,l=0,c=0,u=0,h=0,d=0,A=0,g=0;if(3==t[0]&&0==t[1])return r||new i(0);const p=e.H,m=p.b,w=p.e,v=p.R,b=p.n,y=p.A,E=p.Z,F=p.m,_=null==r;for(_&&(r=new i(t.length>>>2<<5));0==s;)if(s=m(t,g,1),f=m(t,g+1,2),g+=3,0!=f){if(_&&(r=e.H.W(r,A+(1<<17))),1==f&&(o=F.J,a=F.h,h=511,d=31),2==f){l=w(t,g,5)+257,c=w(t,g+5,5)+1,u=w(t,g+10,4)+4,g+=14;let e=1;for(var B=0;B<38;B+=2)F.Q[B]=0,F.Q[B+1]=0;for(B=0;B<u;B++){const r=w(t,g+3*B,3);F.Q[1+(F.X[B]<<1)]=r,r>e&&(e=r);}g+=3*u,b(F.Q,e),y(F.Q,e,F.u),o=F.w,a=F.d,g=v(F.u,(1<<e)-1,l+c,t,g,F.v);const r=p.V(F.v,0,l,F.C);h=(1<<r)-1;const i=p.V(F.v,l,c,F.D);d=(1<<i)-1,b(F.C,r),y(F.C,r,o),b(F.D,i),y(F.D,i,a);}for(;;){const e=o[E(t,g)&h];g+=15&e;const i=e>>>4;if(i>>>8==0)r[A++]=i;else {if(256==i)break;{let e=A+i-254;if(i>264){const r=F.q[i-257];e=A+(r>>>3)+w(t,g,7&r),g+=7&r;}const o=a[E(t,g)&d];g+=15&o;const s=o>>>4,f=F.c[s],l=(f>>>4)+m(t,g,15&f);for(g+=15&f;A<e;)r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l];A=e;}}}}else {0!=(7&g)&&(g+=8-(7&g));const o=4+(g>>>3),a=t[o-4]|t[o-3]<<8;_&&(r=e.H.W(r,A+a)),r.set(new i(t.buffer,t.byteOffset+o,a),A),g=o+a<<3,A+=a;}return r.length==A?r:r.slice(0,A)},e.H.W=function(e,t){const r=e.length;if(t<=r)return e;const i=new Uint8Array(r<<1);return i.set(e,0),i},e.H.R=function(t,r,i,o,a,s){const f=e.H.e,l=e.H.Z;let c=0;for(;c<i;){const e=t[l(o,a)&r];a+=15&e;const i=e>>>4;if(i<=15)s[c]=i,c++;else {let e=0,t=0;16==i?(t=3+f(o,a,2),a+=2,e=s[c-1]):17==i?(t=3+f(o,a,3),a+=3):18==i&&(t=11+f(o,a,7),a+=7);const r=c+t;for(;c<r;)s[c]=e,c++;}}return a},e.H.V=function(e,t,r,i){let o=0,a=0;const s=i.length>>>1;for(;a<r;){const r=e[a+t];i[a<<1]=0,i[1+(a<<1)]=r,r>o&&(o=r),a++;}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},e.H.n=function(t,r){const i=e.H.m,o=t.length;let a,s,f;let l;const c=i.j;for(var u=0;u<=r;u++)c[u]=0;for(u=1;u<o;u+=2)c[t[u]]++;const h=i.K;for(a=0,c[0]=0,s=1;s<=r;s++)a=a+c[s-1]<<1,h[s]=a;for(f=0;f<o;f+=2)l=t[f+1],0!=l&&(t[f]=h[l],h[l]++);},e.H.A=function(t,r,i){const o=t.length,a=e.H.m.r;for(let e=0;e<o;e+=2)if(0!=t[e+1]){const o=e>>1,s=t[e+1],f=o<<4|s,l=r-s;let c=t[e]<<l;const u=c+(1<<l);for(;c!=u;){i[a[c]>>>15-r]=f,c++;}}},e.H.l=function(t,r){const i=e.H.m.r,o=15-r;for(let e=0;e<t.length;e+=2){const a=t[e]<<r-t[e+1];t[e]=i[a]>>>o;}},e.H.M=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8;},e.H.I=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16;},e.H.e=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},e.H.b=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},e.H.Z=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},e.H.i=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},e.H.m=function(){const e=Uint16Array,t=Uint32Array;return {K:new e(16),j:new e(16),X:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],S:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],T:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],q:new e(32),p:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],z:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],c:new t(32),J:new e(512),_:[],h:new e(32),$:[],w:new e(32768),C:[],v:[],d:new e(32768),D:[],u:new e(512),Q:[],r:new e(32768),s:new t(286),Y:new t(30),a:new t(19),t:new t(15e3),k:new e(65536),g:new e(32768)}}(),function(){const t=e.H.m;for(var r=0;r<32768;r++){let e=r;e=(2863311530&e)>>>1|(1431655765&e)<<1,e=(3435973836&e)>>>2|(858993459&e)<<2,e=(4042322160&e)>>>4|(252645135&e)<<4,e=(4278255360&e)>>>8|(16711935&e)<<8,t.r[r]=(e>>>16|e<<16)>>>17;}function n(e,t,r){for(;0!=t--;)e.push(0,r);}for(r=0;r<32;r++)t.q[r]=t.S[r]<<3|t.T[r],t.c[r]=t.p[r]<<4|t.z[r];n(t._,144,8),n(t._,112,9),n(t._,24,7),n(t._,8,8),e.H.n(t._,9),e.H.A(t._,9,t.J),e.H.l(t._,9),n(t.$,32,5),e.H.n(t.$,5),e.H.A(t.$,5,t.h),e.H.l(t.$,5),n(t.Q,19,0),n(t.C,286,0),n(t.D,30,0),n(t.v,320,0);}(),e.H.N}();function _getBPP(e){return [1,null,3,1,2,null,4][e.ctype]*e.depth}function _filterZero(e,t,r,i,o){let a=_getBPP(t);const s=Math.ceil(i*a/8);let f,l;a=Math.ceil(a/8);let c=e[r],u=0;if(c>1&&(e[r]=[0,0,1][c-2]),3==c)for(u=a;u<s;u++)e[u+1]=e[u+1]+(e[u+1-a]>>>1)&255;for(let t=0;t<o;t++)if(f=r+t*s,l=f+t+1,c=e[l-1],u=0,0==c)for(;u<s;u++)e[f+u]=e[l+u];else if(1==c){for(;u<a;u++)e[f+u]=e[l+u];for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-a];}else if(2==c)for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-s];else if(3==c){for(;u<a;u++)e[f+u]=e[l+u]+(e[f+u-s]>>>1);for(;u<s;u++)e[f+u]=e[l+u]+(e[f+u-s]+e[f+u-a]>>>1);}else {for(;u<a;u++)e[f+u]=e[l+u]+_paeth(0,e[f+u-s],0);for(;u<s;u++)e[f+u]=e[l+u]+_paeth(e[f+u-a],e[f+u-s],e[f+u-a-s]);}return e}function _paeth(e,t,r){const i=e+t-r,o=i-e,a=i-t,s=i-r;return o*o<=a*a&&o*o<=s*s?e:a*a<=s*s?t:r}function _IHDR(t,r,i){i.width=e.readUint(t,r),r+=4,i.height=e.readUint(t,r),r+=4,i.depth=t[r],r++,i.ctype=t[r],r++,i.compress=t[r],r++,i.filter=t[r],r++,i.interlace=t[r],r++;}function _copyTile(e,t,r,i,o,a,s,f,l){const c=Math.min(t,o),u=Math.min(r,a);let h=0,d=0;for(let r=0;r<u;r++)for(let a=0;a<c;a++)if(s>=0&&f>=0?(h=r*t+a<<2,d=(f+r)*o+s+a<<2):(h=(-f+r)*t-s+a<<2,d=r*o+a<<2),0==l)i[d]=e[h],i[d+1]=e[h+1],i[d+2]=e[h+2],i[d+3]=e[h+3];else if(1==l){var A=e[h+3]*(1/255),g=e[h]*A,p=e[h+1]*A,m=e[h+2]*A,w=i[d+3]*(1/255),v=i[d]*w,b=i[d+1]*w,y=i[d+2]*w;const t=1-A,r=A+w*t,o=0==r?0:1/r;i[d+3]=255*r,i[d+0]=(g+v*t)*o,i[d+1]=(p+b*t)*o,i[d+2]=(m+y*t)*o;}else if(2==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];A==w&&g==v&&p==b&&m==y?(i[d]=0,i[d+1]=0,i[d+2]=0,i[d+3]=0):(i[d]=g,i[d+1]=p,i[d+2]=m,i[d+3]=A);}else if(3==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];if(A==w&&g==v&&p==b&&m==y)continue;if(A<220&&w>20)return false}return true}return {decode:function decode(r){const i=new Uint8Array(r);let o=8;const a=e,s=a.readUshort,f=a.readUint,l={tabs:{},frames:[]},c=new Uint8Array(i.length);let u,h=0,d=0;const A=[137,80,78,71,13,10,26,10];for(var g=0;g<8;g++)if(i[g]!=A[g])throw "The input is not a PNG file!";for(;o<i.length;){const e=a.readUint(i,o);o+=4;const r=a.readASCII(i,o,4);if(o+=4,"IHDR"==r)_IHDR(i,o,l);else if("iCCP"==r){for(var p=o;0!=i[p];)p++;a.readASCII(i,o,p-o);const s=i.slice(p+2,o+e);let f=null;try{f=_inflate(s);}catch(e){f=t(s);}l.tabs[r]=f;}else if("CgBI"==r)l.tabs[r]=i.slice(o,o+4);else if("IDAT"==r){for(g=0;g<e;g++)c[h+g]=i[o+g];h+=e;}else if("acTL"==r)l.tabs[r]={num_frames:f(i,o),num_plays:f(i,o+4)},u=new Uint8Array(i.length);else if("fcTL"==r){if(0!=d)(E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height),d=0;const e={x:f(i,o+12),y:f(i,o+16),width:f(i,o+4),height:f(i,o+8)};let t=s(i,o+22);t=s(i,o+20)/(0==t?100:t);const r={rect:e,delay:Math.round(1e3*t),dispose:i[o+24],blend:i[o+25]};l.frames.push(r);}else if("fdAT"==r){for(g=0;g<e-4;g++)u[d+g]=i[o+g+4];d+=e-4;}else if("pHYs"==r)l.tabs[r]=[a.readUint(i,o),a.readUint(i,o+4),i[o+8]];else if("cHRM"==r){l.tabs[r]=[];for(g=0;g<8;g++)l.tabs[r].push(a.readUint(i,o+4*g));}else if("tEXt"==r||"zTXt"==r){null==l.tabs[r]&&(l.tabs[r]={});var m=a.nextZero(i,o),w=a.readASCII(i,o,m-o),v=o+e-m-1;if("tEXt"==r)y=a.readASCII(i,m+1,v);else {var b=_inflate(i.slice(m+2,m+2+v));y=a.readUTF8(b,0,b.length);}l.tabs[r][w]=y;}else if("iTXt"==r){null==l.tabs[r]&&(l.tabs[r]={});m=0,p=o;m=a.nextZero(i,p);w=a.readASCII(i,p,m-p);const t=i[p=m+1];var y;p+=2,m=a.nextZero(i,p),a.readASCII(i,p,m-p),p=m+1,m=a.nextZero(i,p),a.readUTF8(i,p,m-p);v=e-((p=m+1)-o);if(0==t)y=a.readUTF8(i,p,v);else {b=_inflate(i.slice(p,p+v));y=a.readUTF8(b,0,b.length);}l.tabs[r][w]=y;}else if("PLTE"==r)l.tabs[r]=a.readBytes(i,o,e);else if("hIST"==r){const e=l.tabs.PLTE.length/3;l.tabs[r]=[];for(g=0;g<e;g++)l.tabs[r].push(s(i,o+2*g));}else if("tRNS"==r)3==l.ctype?l.tabs[r]=a.readBytes(i,o,e):0==l.ctype?l.tabs[r]=s(i,o):2==l.ctype&&(l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]);else if("gAMA"==r)l.tabs[r]=a.readUint(i,o)/1e5;else if("sRGB"==r)l.tabs[r]=i[o];else if("bKGD"==r)0==l.ctype||4==l.ctype?l.tabs[r]=[s(i,o)]:2==l.ctype||6==l.ctype?l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]:3==l.ctype&&(l.tabs[r]=i[o]);else if("IEND"==r)break;o+=e,a.readUint(i,o),o+=4;}var E;return 0!=d&&((E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height)),l.data=_decompress(l,c,l.width,l.height),delete l.compress,delete l.interlace,delete l.filter,l},toRGBA8:function toRGBA8(e){const t=e.width,r=e.height;if(null==e.tabs.acTL)return [decodeImage(e.data,t,r,e).buffer];const i=[];null==e.frames[0].data&&(e.frames[0].data=e.data);const o=t*r*4,a=new Uint8Array(o),s=new Uint8Array(o),f=new Uint8Array(o);for(let c=0;c<e.frames.length;c++){const u=e.frames[c],h=u.rect.x,d=u.rect.y,A=u.rect.width,g=u.rect.height,p=decodeImage(u.data,A,g,e);if(0!=c)for(var l=0;l<o;l++)f[l]=a[l];if(0==u.blend?_copyTile(p,A,g,a,t,r,h,d,0):1==u.blend&&_copyTile(p,A,g,a,t,r,h,d,1),i.push(a.buffer.slice(0)),0==u.dispose);else if(1==u.dispose)_copyTile(s,A,g,a,t,r,h,d,0);else if(2==u.dispose)for(l=0;l<o;l++)a[l]=f[l];}return i},_paeth:_paeth,_copyTile:_copyTile,_bin:e}}();!function(){const{_copyTile:e}=UPNG,{_bin:t}=UPNG,r=UPNG._paeth;var i={table:function(){const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r;}return e}(),update(e,t,r,o){for(let a=0;a<o;a++)e=i.table[255&(e^t[r+a])]^e>>>8;return e},crc:(e,t,r)=>4294967295^i.update(4294967295,e,t,r)};function addErr(e,t,r,i){t[r]+=e[0]*i>>4,t[r+1]+=e[1]*i>>4,t[r+2]+=e[2]*i>>4,t[r+3]+=e[3]*i>>4;}function N(e){return Math.max(0,Math.min(255,e))}function D(e,t){const r=e[0]-t[0],i=e[1]-t[1],o=e[2]-t[2],a=e[3]-t[3];return r*r+i*i+o*o+a*a}function dither(e,t,r,i,o,a,s){null==s&&(s=1);const f=i.length,l=[];for(var c=0;c<f;c++){const e=i[c];l.push([e>>>0&255,e>>>8&255,e>>>16&255,e>>>24&255]);}for(c=0;c<f;c++){let e=4294967295;for(var u=0,h=0;h<f;h++){var d=D(l[c],l[h]);h!=c&&d<e&&(e=d,u=h);}}const A=new Uint32Array(o.buffer),g=new Int16Array(t*r*4),p=[0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5];for(c=0;c<p.length;c++)p[c]=255*((p[c]+.5)/16-.5);for(let o=0;o<r;o++)for(let w=0;w<t;w++){var m;c=4*(o*t+w);if(2!=s)m=[N(e[c]+g[c]),N(e[c+1]+g[c+1]),N(e[c+2]+g[c+2]),N(e[c+3]+g[c+3])];else {d=p[4*(3&o)+(3&w)];m=[N(e[c]+d),N(e[c+1]+d),N(e[c+2]+d),N(e[c+3]+d)];}u=0;let v=16777215;for(h=0;h<f;h++){const e=D(m,l[h]);e<v&&(v=e,u=h);}const b=l[u],y=[m[0]-b[0],m[1]-b[1],m[2]-b[2],m[3]-b[3]];1==s&&(w!=t-1&&addErr(y,g,c+4,7),o!=r-1&&(0!=w&&addErr(y,g,c+4*t-4,3),addErr(y,g,c+4*t,5),w!=t-1&&addErr(y,g,c+4*t+4,1))),a[c>>2]=u,A[c>>2]=i[u];}}function _main(e,r,o,a,s){null==s&&(s={});const{crc:f}=i,l=t.writeUint,c=t.writeUshort,u=t.writeASCII;let h=8;const d=e.frames.length>1;let A,g=false,p=33+(d?20:0);if(null!=s.sRGB&&(p+=13),null!=s.pHYs&&(p+=21),null!=s.iCCP&&(A=pako.deflate(s.iCCP),p+=21+A.length+4),3==e.ctype){for(var m=e.plte.length,w=0;w<m;w++)e.plte[w]>>>24!=255&&(g=true);p+=8+3*m+4+(g?8+1*m+4:0);}for(var v=0;v<e.frames.length;v++){d&&(p+=38),p+=(F=e.frames[v]).cimg.length+12,0!=v&&(p+=4);}p+=12;const b=new Uint8Array(p),y=[137,80,78,71,13,10,26,10];for(w=0;w<8;w++)b[w]=y[w];if(l(b,h,13),h+=4,u(b,h,"IHDR"),h+=4,l(b,h,r),h+=4,l(b,h,o),h+=4,b[h]=e.depth,h++,b[h]=e.ctype,h++,b[h]=0,h++,b[h]=0,h++,b[h]=0,h++,l(b,h,f(b,h-17,17)),h+=4,null!=s.sRGB&&(l(b,h,1),h+=4,u(b,h,"sRGB"),h+=4,b[h]=s.sRGB,h++,l(b,h,f(b,h-5,5)),h+=4),null!=s.iCCP){const e=13+A.length;l(b,h,e),h+=4,u(b,h,"iCCP"),h+=4,u(b,h,"ICC profile"),h+=11,h+=2,b.set(A,h),h+=A.length,l(b,h,f(b,h-(e+4),e+4)),h+=4;}if(null!=s.pHYs&&(l(b,h,9),h+=4,u(b,h,"pHYs"),h+=4,l(b,h,s.pHYs[0]),h+=4,l(b,h,s.pHYs[1]),h+=4,b[h]=s.pHYs[2],h++,l(b,h,f(b,h-13,13)),h+=4),d&&(l(b,h,8),h+=4,u(b,h,"acTL"),h+=4,l(b,h,e.frames.length),h+=4,l(b,h,null!=s.loop?s.loop:0),h+=4,l(b,h,f(b,h-12,12)),h+=4),3==e.ctype){l(b,h,3*(m=e.plte.length)),h+=4,u(b,h,"PLTE"),h+=4;for(w=0;w<m;w++){const t=3*w,r=e.plte[w],i=255&r,o=r>>>8&255,a=r>>>16&255;b[h+t+0]=i,b[h+t+1]=o,b[h+t+2]=a;}if(h+=3*m,l(b,h,f(b,h-3*m-4,3*m+4)),h+=4,g){l(b,h,m),h+=4,u(b,h,"tRNS"),h+=4;for(w=0;w<m;w++)b[h+w]=e.plte[w]>>>24&255;h+=m,l(b,h,f(b,h-m-4,m+4)),h+=4;}}let E=0;for(v=0;v<e.frames.length;v++){var F=e.frames[v];d&&(l(b,h,26),h+=4,u(b,h,"fcTL"),h+=4,l(b,h,E++),h+=4,l(b,h,F.rect.width),h+=4,l(b,h,F.rect.height),h+=4,l(b,h,F.rect.x),h+=4,l(b,h,F.rect.y),h+=4,c(b,h,a[v]),h+=2,c(b,h,1e3),h+=2,b[h]=F.dispose,h++,b[h]=F.blend,h++,l(b,h,f(b,h-30,30)),h+=4);const t=F.cimg;l(b,h,(m=t.length)+(0==v?0:4)),h+=4;const r=h;u(b,h,0==v?"IDAT":"fdAT"),h+=4,0!=v&&(l(b,h,E++),h+=4),b.set(t,h),h+=m,l(b,h,f(b,r,h-r)),h+=4;}return l(b,h,0),h+=4,u(b,h,"IEND"),h+=4,l(b,h,f(b,h-4,4)),h+=4,b.buffer}function compressPNG(e,t,r){for(let i=0;i<e.frames.length;i++){const o=e.frames[i];const a=o.rect.height,s=new Uint8Array(a*o.bpl+a);o.cimg=_filterZero(o.img,a,o.bpp,o.bpl,s,t,r);}}function compress(t,r,i,o,a){const s=a[0],f=a[1],l=a[2],c=a[3],u=a[4],h=a[5];let d=6,A=8,g=255;for(var p=0;p<t.length;p++){const e=new Uint8Array(t[p]);for(var m=e.length,w=0;w<m;w+=4)g&=e[w+3];}const v=255!=g,b=function framize(t,r,i,o,a,s){const f=[];for(var l=0;l<t.length;l++){const h=new Uint8Array(t[l]),A=new Uint32Array(h.buffer);var c;let g=0,p=0,m=r,w=i,v=o?1:0;if(0!=l){const b=s||o||1==l||0!=f[l-2].dispose?1:2;let y=0,E=1e9;for(let e=0;e<b;e++){var u=new Uint8Array(t[l-1-e]);const o=new Uint32Array(t[l-1-e]);let s=r,f=i,c=-1,h=-1;for(let e=0;e<i;e++)for(let t=0;t<r;t++){A[d=e*r+t]!=o[d]&&(t<s&&(s=t),t>c&&(c=t),e<f&&(f=e),e>h&&(h=e));} -1==c&&(s=f=c=h=0),a&&(1==(1&s)&&s--,1==(1&f)&&f--);const v=(c-s+1)*(h-f+1);v<E&&(E=v,y=e,g=s,p=f,m=c-s+1,w=h-f+1);}u=new Uint8Array(t[l-1-y]);1==y&&(f[l-1].dispose=2),c=new Uint8Array(m*w*4),e(u,r,i,c,m,w,-g,-p,0),v=e(h,r,i,c,m,w,-g,-p,3)?1:0,1==v?_prepareDiff(h,r,i,c,{x:g,y:p,width:m,height:w}):e(h,r,i,c,m,w,-g,-p,0);}else c=h.slice(0);f.push({rect:{x:g,y:p,width:m,height:w},img:c,blend:v,dispose:0});}if(o)for(l=0;l<f.length;l++){if(1==(A=f[l]).blend)continue;const e=A.rect,o=f[l-1].rect,s=Math.min(e.x,o.x),c=Math.min(e.y,o.y),u={x:s,y:c,width:Math.max(e.x+e.width,o.x+o.width)-s,height:Math.max(e.y+e.height,o.y+o.height)-c};f[l-1].dispose=1,l-1!=0&&_updateFrame(t,r,i,f,l-1,u,a),_updateFrame(t,r,i,f,l,u,a);}let h=0;if(1!=t.length)for(var d=0;d<f.length;d++){var A;h+=(A=f[d]).rect.width*A.rect.height;}return f}(t,r,i,s,f,l),y={},E=[],F=[];if(0!=o){const e=[];for(w=0;w<b.length;w++)e.push(b[w].img.buffer);const t=function concatRGBA(e){let t=0;for(var r=0;r<e.length;r++)t+=e[r].byteLength;const i=new Uint8Array(t);let o=0;for(r=0;r<e.length;r++){const t=new Uint8Array(e[r]),a=t.length;for(let e=0;e<a;e+=4){let r=t[e],a=t[e+1],s=t[e+2];const f=t[e+3];0==f&&(r=a=s=0),i[o+e]=r,i[o+e+1]=a,i[o+e+2]=s,i[o+e+3]=f;}o+=a;}return i.buffer}(e),r=quantize(t,o);for(w=0;w<r.plte.length;w++)E.push(r.plte[w].est.rgba);let i=0;for(w=0;w<b.length;w++){const e=(B=b[w]).img.length;var _=new Uint8Array(r.inds.buffer,i>>2,e>>2);F.push(_);const t=new Uint8Array(r.abuf,i,e);h&&dither(B.img,B.rect.width,B.rect.height,E,t,_),B.img.set(t),i+=e;}}else for(p=0;p<b.length;p++){var B=b[p];const e=new Uint32Array(B.img.buffer);var U=B.rect.width;m=e.length,_=new Uint8Array(m);F.push(_);for(w=0;w<m;w++){const t=e[w];if(0!=w&&t==e[w-1])_[w]=_[w-1];else if(w>U&&t==e[w-U])_[w]=_[w-U];else {let e=y[t];if(null==e&&(y[t]=e=E.length,E.push(t),E.length>=300))break;_[w]=e;}}}const C=E.length;C<=256&&0==u&&(A=C<=2?1:C<=4?2:C<=16?4:8,A=Math.max(A,c));for(p=0;p<b.length;p++){(B=b[p]).rect.x;U=B.rect.width;const e=B.rect.height;let t=B.img;let r=4*U,i=4;if(C<=256&&0==u){r=Math.ceil(A*U/8);var I=new Uint8Array(r*e);const o=F[p];for(let t=0;t<e;t++){w=t*r;const e=t*U;if(8==A)for(var Q=0;Q<U;Q++)I[w+Q]=o[e+Q];else if(4==A)for(Q=0;Q<U;Q++)I[w+(Q>>1)]|=o[e+Q]<<4-4*(1&Q);else if(2==A)for(Q=0;Q<U;Q++)I[w+(Q>>2)]|=o[e+Q]<<6-2*(3&Q);else if(1==A)for(Q=0;Q<U;Q++)I[w+(Q>>3)]|=o[e+Q]<<7-1*(7&Q);}t=I,d=3,i=1;}else if(0==v&&1==b.length){I=new Uint8Array(U*e*3);const o=U*e;for(w=0;w<o;w++){const e=3*w,r=4*w;I[e]=t[r],I[e+1]=t[r+1],I[e+2]=t[r+2];}t=I,d=2,i=3,r=3*U;}B.img=t,B.bpl=r,B.bpp=i;}return {ctype:d,depth:A,plte:E,frames:b}}function _updateFrame(t,r,i,o,a,s,f){const l=Uint8Array,c=Uint32Array,u=new l(t[a-1]),h=new c(t[a-1]),d=a+1<t.length?new l(t[a+1]):null,A=new l(t[a]),g=new c(A.buffer);let p=r,m=i,w=-1,v=-1;for(let e=0;e<s.height;e++)for(let t=0;t<s.width;t++){const i=s.x+t,f=s.y+e,l=f*r+i,c=g[l];0==c||0==o[a-1].dispose&&h[l]==c&&(null==d||0!=d[4*l+3])||(i<p&&(p=i),i>w&&(w=i),f<m&&(m=f),f>v&&(v=f));} -1==w&&(p=m=w=v=0),f&&(1==(1&p)&&p--,1==(1&m)&&m--),s={x:p,y:m,width:w-p+1,height:v-m+1};const b=o[a];b.rect=s,b.blend=1,b.img=new Uint8Array(s.width*s.height*4),0==o[a-1].dispose?(e(u,r,i,b.img,s.width,s.height,-s.x,-s.y,0),_prepareDiff(A,r,i,b.img,s)):e(A,r,i,b.img,s.width,s.height,-s.x,-s.y,0);}function _prepareDiff(t,r,i,o,a){e(t,r,i,o,a.width,a.height,-a.x,-a.y,2);}function _filterZero(e,t,r,i,o,a,s){const f=[];let l,c=[0,1,2,3,4];-1!=a?c=[a]:(t*i>5e5||1==r)&&(c=[0]),s&&(l={level:0});const u=UZIP;for(var h=0;h<c.length;h++){for(let a=0;a<t;a++)_filterLine(o,e,a,i,r,c[h]);f.push(u.deflate(o,l));}let d,A=1e9;for(h=0;h<f.length;h++)f[h].length<A&&(d=h,A=f[h].length);return f[d]}function _filterLine(e,t,i,o,a,s){const f=i*o;let l=f+i;if(e[l]=s,l++,0==s)if(o<500)for(var c=0;c<o;c++)e[l+c]=t[f+c];else e.set(new Uint8Array(t.buffer,f,o),l);else if(1==s){for(c=0;c<a;c++)e[l+c]=t[f+c];for(c=a;c<o;c++)e[l+c]=t[f+c]-t[f+c-a]+256&255;}else if(0==i){for(c=0;c<a;c++)e[l+c]=t[f+c];if(2==s)for(c=a;c<o;c++)e[l+c]=t[f+c];if(3==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-(t[f+c-a]>>1)+256&255;if(4==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-r(t[f+c-a],0,0)+256&255;}else {if(2==s)for(c=0;c<o;c++)e[l+c]=t[f+c]+256-t[f+c-o]&255;if(3==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-(t[f+c-o]>>1)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-(t[f+c-o]+t[f+c-a]>>1)&255;}if(4==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-r(0,t[f+c-o],0)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-r(t[f+c-a],t[f+c-o],t[f+c-a-o])&255;}}}function quantize(e,t){const r=new Uint8Array(e),i=r.slice(0),o=new Uint32Array(i.buffer),a=getKDtree(i,t),s=a[0],f=a[1],l=r.length,c=new Uint8Array(l>>2);let u;if(r.length<2e7)for(var h=0;h<l;h+=4){u=getNearest(s,d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255)),c[h>>2]=u.ind,o[h>>2]=u.est.rgba;}else for(h=0;h<l;h+=4){var d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255);for(u=s;u.left;)u=planeDst(u.est,d,A,g,p)<=0?u.left:u.right;c[h>>2]=u.ind,o[h>>2]=u.est.rgba;}return {abuf:i.buffer,inds:c,plte:f}}function getKDtree(e,t,r){null==r&&(r=1e-4);const i=new Uint32Array(e.buffer),o={i0:0,i1:e.length,bst:null,est:null,tdst:0,left:null,right:null};o.bst=stats(e,o.i0,o.i1),o.est=estats(o.bst);const a=[o];for(;a.length<t;){let t=0,o=0;for(var s=0;s<a.length;s++)a[s].est.L>t&&(t=a[s].est.L,o=s);if(t<r)break;const f=a[o],l=splitPixels(e,i,f.i0,f.i1,f.est.e,f.est.eMq255);if(f.i0>=l||f.i1<=l){f.est.L=0;continue}const c={i0:f.i0,i1:l,bst:null,est:null,tdst:0,left:null,right:null};c.bst=stats(e,c.i0,c.i1),c.est=estats(c.bst);const u={i0:l,i1:f.i1,bst:null,est:null,tdst:0,left:null,right:null};u.bst={R:[],m:[],N:f.bst.N-c.bst.N};for(s=0;s<16;s++)u.bst.R[s]=f.bst.R[s]-c.bst.R[s];for(s=0;s<4;s++)u.bst.m[s]=f.bst.m[s]-c.bst.m[s];u.est=estats(u.bst),f.left=c,f.right=u,a[o]=c,a.push(u);}a.sort(((e,t)=>t.bst.N-e.bst.N));for(s=0;s<a.length;s++)a[s].ind=s;return [o,a]}function getNearest(e,t,r,i,o){if(null==e.left)return e.tdst=function dist(e,t,r,i,o){const a=t-e[0],s=r-e[1],f=i-e[2],l=o-e[3];return a*a+s*s+f*f+l*l}(e.est.q,t,r,i,o),e;const a=planeDst(e.est,t,r,i,o);let s=e.left,f=e.right;a>0&&(s=e.right,f=e.left);const l=getNearest(s,t,r,i,o);if(l.tdst<=a*a)return l;const c=getNearest(f,t,r,i,o);return c.tdst<l.tdst?c:l}function planeDst(e,t,r,i,o){const{e:a}=e;return a[0]*t+a[1]*r+a[2]*i+a[3]*o-e.eMq}function splitPixels(e,t,r,i,o,a){for(i-=4;r<i;){for(;vecDot(e,r,o)<=a;)r+=4;for(;vecDot(e,i,o)>a;)i-=4;if(r>=i)break;const s=t[r>>2];t[r>>2]=t[i>>2],t[i>>2]=s,r+=4,i-=4;}for(;vecDot(e,r,o)>a;)r-=4;return r+4}function vecDot(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]+e[t+3]*r[3]}function stats(e,t,r){const i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],o=[0,0,0,0],a=r-t>>2;for(let a=t;a<r;a+=4){const t=e[a]*(1/255),r=e[a+1]*(1/255),s=e[a+2]*(1/255),f=e[a+3]*(1/255);o[0]+=t,o[1]+=r,o[2]+=s,o[3]+=f,i[0]+=t*t,i[1]+=t*r,i[2]+=t*s,i[3]+=t*f,i[5]+=r*r,i[6]+=r*s,i[7]+=r*f,i[10]+=s*s,i[11]+=s*f,i[15]+=f*f;}return i[4]=i[1],i[8]=i[2],i[9]=i[6],i[12]=i[3],i[13]=i[7],i[14]=i[11],{R:i,m:o,N:a}}function estats(e){const{R:t}=e,{m:r}=e,{N:i}=e,a=r[0],s=r[1],f=r[2],l=r[3],c=0==i?0:1/i,u=[t[0]-a*a*c,t[1]-a*s*c,t[2]-a*f*c,t[3]-a*l*c,t[4]-s*a*c,t[5]-s*s*c,t[6]-s*f*c,t[7]-s*l*c,t[8]-f*a*c,t[9]-f*s*c,t[10]-f*f*c,t[11]-f*l*c,t[12]-l*a*c,t[13]-l*s*c,t[14]-l*f*c,t[15]-l*l*c],h=u,d=o;let A=[Math.random(),Math.random(),Math.random(),Math.random()],g=0,p=0;if(0!=i)for(let e=0;e<16&&(A=d.multVec(h,A),p=Math.sqrt(d.dot(A,A)),A=d.sml(1/p,A),!(0!=e&&Math.abs(p-g)<1e-9));e++)g=p;const m=[a*c,s*c,f*c,l*c];return {Cov:u,q:m,e:A,L:g,eMq255:d.dot(d.sml(255,m),A),eMq:d.dot(A,m),rgba:(Math.round(255*m[3])<<24|Math.round(255*m[2])<<16|Math.round(255*m[1])<<8|Math.round(255*m[0])<<0)>>>0}}var o={multVec:(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7]*t[3],e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11]*t[3],e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]*t[3]],dot:(e,t)=>e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],sml:(e,t)=>[e*t[0],e*t[1],e*t[2],e*t[3]]};UPNG.encode=function encode(e,t,r,i,o,a,s){null==i&&(i=0),null==s&&(s=false);const f=compress(e,t,r,i,[false,false,false,0,s,false]);return compressPNG(f,-1),_main(f,t,r,o,a)},UPNG.encodeLL=function encodeLL(e,t,r,i,o,a,s,f){const l={ctype:0+(1==i?0:2)+(0==o?0:4),depth:a,frames:[]},c=(i+o)*a,u=c*t;for(let i=0;i<e.length;i++)l.frames.push({rect:{x:0,y:0,width:t,height:r},img:new Uint8Array(e[i]),blend:0,dispose:1,bpp:Math.ceil(c/8),bpl:Math.ceil(u/8)});return compressPNG(l,0,true),_main(l,t,r,s,f)},UPNG.encode.compress=compress,UPNG.encode.dither=dither,UPNG.quantize=quantize,UPNG.quantize.getKDtree=getKDtree,UPNG.quantize.getNearest=getNearest;}();const r={toArrayBuffer(e,t){const i=e.width,o=e.height,a=i<<2,s=e.getContext("2d").getImageData(0,0,i,o),f=new Uint32Array(s.data.buffer),l=(32*i+31)/32<<2,c=l*o,u=122+c,h=new ArrayBuffer(u),d=new DataView(h),A=1<<20;let g,p,m,w,v=A,b=0,y=0,E=0;function set16(e){d.setUint16(y,e,true),y+=2;}function set32(e){d.setUint32(y,e,true),y+=4;}function seek(e){y+=e;}set16(19778),set32(u),seek(4),set32(122),set32(108),set32(i),set32(-o>>>0),set16(1),set16(32),set32(3),set32(c),set32(2835),set32(2835),seek(8),set32(16711680),set32(65280),set32(255),set32(4278190080),set32(1466527264),function convert(){for(;b<o&&v>0;){for(w=122+b*l,g=0;g<a;)v--,p=f[E++],m=p>>>24,d.setUint32(w+g,p<<8|m),g+=4;b++;}E<f.length?(v=A,setTimeout(convert,r._dly)):t(h);}();},toBlob(e,t){this.toArrayBuffer(e,(e=>{t(new Blob([e],{type:"image/bmp"}));}));},_dly:9};var i={CHROME:"CHROME",FIREFOX:"FIREFOX",DESKTOP_SAFARI:"DESKTOP_SAFARI",IE:"IE",IOS:"IOS",ETC:"ETC"},o={[i.CHROME]:16384,[i.FIREFOX]:11180,[i.DESKTOP_SAFARI]:16384,[i.IE]:8192,[i.IOS]:4096,[i.ETC]:8192};const a="undefined"!=typeof window,s="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,f=a&&window.cordova&&window.cordova.require&&window.cordova.require("cordova/modulemapper"),CustomFile=(a||s)&&(f&&f.getOriginalSymbol(window,"File")||"undefined"!=typeof File&&File),CustomFileReader=(a||s)&&(f&&f.getOriginalSymbol(window,"FileReader")||"undefined"!=typeof FileReader&&FileReader);function getFilefromDataUrl(e,t,r=Date.now()){return new Promise((i=>{const o=e.split(","),a=o[0].match(/:(.*?);/)[1],s=globalThis.atob(o[1]);let f=s.length;const l=new Uint8Array(f);for(;f--;)l[f]=s.charCodeAt(f);const c=new Blob([l],{type:a});c.name=t,c.lastModified=r,i(c);}))}function getDataUrlFromFile(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=()=>t(i.result),i.onerror=e=>r(e),i.readAsDataURL(e);}))}function loadImage(e){return new Promise(((t,r)=>{const i=new Image;i.onload=()=>t(i),i.onerror=e=>r(e),i.src=e;}))}function getBrowserName(){if(void 0!==getBrowserName.cachedResult)return getBrowserName.cachedResult;let e=i.ETC;const{userAgent:t}=navigator;return /Chrom(e|ium)/i.test(t)?e=i.CHROME:/iP(ad|od|hone)/i.test(t)&&/WebKit/i.test(t)?e=i.IOS:/Safari/i.test(t)?e=i.DESKTOP_SAFARI:/Firefox/i.test(t)?e=i.FIREFOX:(/MSIE/i.test(t)||true==!!document.documentMode)&&(e=i.IE),getBrowserName.cachedResult=e,getBrowserName.cachedResult}function approximateBelowMaximumCanvasSizeOfBrowser(e,t){const r=getBrowserName(),i=o[r];let a=e,s=t,f=a*s;const l=a>s?s/a:a/s;for(;f>i*i;){const e=(i+a)/2,t=(i+s)/2;e<t?(s=t,a=t*l):(s=e*l,a=e),f=a*s;}return {width:a,height:s}}function getNewCanvasAndCtx(e,t){let r,i;try{if(r=new OffscreenCanvas(e,t),i=r.getContext("2d"),null===i)throw new Error("getContext of OffscreenCanvas returns null")}catch(e){r=document.createElement("canvas"),i=r.getContext("2d");}return r.width=e,r.height=t,[r,i]}function drawImageInCanvas(e,t){const{width:r,height:i}=approximateBelowMaximumCanvasSizeOfBrowser(e.width,e.height),[o,a]=getNewCanvasAndCtx(r,i);return t&&/jpe?g/.test(t)&&(a.fillStyle="white",a.fillRect(0,0,o.width,o.height)),a.drawImage(e,0,0,o.width,o.height),o}function isIOS(){return void 0!==isIOS.cachedResult||(isIOS.cachedResult=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"undefined"!=typeof document&&"ontouchend"in document),isIOS.cachedResult}function drawFileInCanvas(e,t={}){return new Promise((function(r,o){let a,s;var $Try_2_Post=function(){try{return s=drawImageInCanvas(a,t.fileType||e.type),r([a,s])}catch(e){return o(e)}},$Try_2_Catch=function(t){try{var $Try_3_Catch=function(e){try{throw e}catch(e){return o(e)}};try{let t;return getDataUrlFromFile(e).then((function(e){try{return t=e,loadImage(t).then((function(e){try{return a=e,function(){try{return $Try_2_Post()}catch(e){return o(e)}}()}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){$Try_3_Catch(e);}}catch(e){return o(e)}};try{if(isIOS()||[i.DESKTOP_SAFARI,i.MOBILE_SAFARI].includes(getBrowserName()))throw new Error("Skip createImageBitmap on IOS and Safari");return createImageBitmap(e).then((function(e){try{return a=e,$Try_2_Post()}catch(e){return $Try_2_Catch()}}),$Try_2_Catch)}catch(e){$Try_2_Catch();}}))}function canvasToFile(e,t,i,o,a=1){return new Promise((function(s,f){let l;if("image/png"===t){let c,u,h;return c=e.getContext("2d"),({data:u}=c.getImageData(0,0,e.width,e.height)),h=UPNG.encode([u.buffer],e.width,e.height,4096*a),l=new Blob([h],{type:t}),l.name=i,l.lastModified=o,$If_4.call(this)}{if("image/bmp"===t)return new Promise((t=>r.toBlob(e,t))).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_5.call(this)}catch(e){return f(e)}}.bind(this),f);{if("function"==typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return e.convertToBlob({type:t,quality:a}).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f);{let d;return d=e.toDataURL(t,a),getFilefromDataUrl(d,i,o).then(function(e){try{return l=e,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f)}function $If_6(){return $If_5.call(this)}}function $If_5(){return $If_4.call(this)}}function $If_4(){return s(l)}}))}function cleanupCanvasMemory(e){e.width=0,e.height=0;}function isAutoOrientationInBrowser(){return new Promise((function(e,t){let i,o,a,s;return void 0!==isAutoOrientationInBrowser.cachedResult?e(isAutoOrientationInBrowser.cachedResult):(getFilefromDataUrl("data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==","test.jpg",Date.now()).then((function(r){try{return i=r,drawFileInCanvas(i).then((function(r){try{return o=r[1],canvasToFile(o,i.type,i.name,i.lastModified).then((function(r){try{return a=r,cleanupCanvasMemory(o),drawFileInCanvas(a).then((function(r){try{return s=r[0],isAutoOrientationInBrowser.cachedResult=1===s.width&&2===s.height,e(isAutoOrientationInBrowser.cachedResult)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t))}))}function getExifOrientation(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=e=>{const r=new DataView(e.target.result);if(65496!=r.getUint16(0,false))return t(-2);const i=r.byteLength;let o=2;for(;o<i;){if(r.getUint16(o+2,false)<=8)return t(-1);const e=r.getUint16(o,false);if(o+=2,65505==e){if(1165519206!=r.getUint32(o+=2,false))return t(-1);const e=18761==r.getUint16(o+=6,false);o+=r.getUint32(o+4,e);const i=r.getUint16(o,e);o+=2;for(let a=0;a<i;a++)if(274==r.getUint16(o+12*a,e))return t(r.getUint16(o+12*a+8,e))}else {if(65280!=(65280&e))break;o+=r.getUint16(o,false);}}return t(-1)},i.onerror=e=>r(e),i.readAsArrayBuffer(e);}))}function handleMaxWidthOrHeight(e,t){const{width:r}=e,{height:i}=e,{maxWidthOrHeight:o}=t;let a,s=e;return isFinite(o)&&(r>o||i>o)&&([s,a]=getNewCanvasAndCtx(r,i),r>i?(s.width=o,s.height=i/r*o):(s.width=r/i*o,s.height=o),a.drawImage(e,0,0,s.width,s.height),cleanupCanvasMemory(e)),s}function followExifOrientation(e,t){const{width:r}=e,{height:i}=e,[o,a]=getNewCanvasAndCtx(r,i);switch(t>4&&t<9?(o.width=i,o.height=r):(o.width=r,o.height=i),t){case 2:a.transform(-1,0,0,1,r,0);break;case 3:a.transform(-1,0,0,-1,r,i);break;case 4:a.transform(1,0,0,-1,0,i);break;case 5:a.transform(0,1,1,0,0,0);break;case 6:a.transform(0,1,-1,0,i,0);break;case 7:a.transform(0,-1,-1,0,i,r);break;case 8:a.transform(0,-1,1,0,0,r);}return a.drawImage(e,0,0,r,i),cleanupCanvasMemory(e),o}function compress(e,t,r=0){return new Promise((function(i,o){let a,s,f,l,c,u,h,d,A,g,p,m,w,v,b,y,E,F,_,B;function incProgress(e=5){if(t.signal&&t.signal.aborted)throw t.signal.reason;a+=e,t.onProgress(Math.min(a,100));}function setProgress(e){if(t.signal&&t.signal.aborted)throw t.signal.reason;a=Math.min(Math.max(e,a),100),t.onProgress(a);}return a=r,s=t.maxIteration||10,f=1024*t.maxSizeMB*1024,incProgress(),drawFileInCanvas(e,t).then(function(r){try{return [,l]=r,incProgress(),c=handleMaxWidthOrHeight(l,t),incProgress(),new Promise((function(r,i){var o;if(!(o=t.exifOrientation))return getExifOrientation(e).then(function(e){try{return o=e,$If_2.call(this)}catch(e){return i(e)}}.bind(this),i);function $If_2(){return r(o)}return $If_2.call(this)})).then(function(r){try{return u=r,incProgress(),isAutoOrientationInBrowser().then(function(r){try{return h=r?c:followExifOrientation(c,u),incProgress(),d=t.initialQuality||1,A=t.fileType||e.type,canvasToFile(h,A,e.name,e.lastModified,d).then(function(r){try{{if(g=r,incProgress(),p=g.size>f,m=g.size>e.size,!p&&!m)return setProgress(100),i(g);var a;function $Loop_3(){if(s--&&(b>f||b>w)){let t,r;return t=B?.95*_.width:_.width,r=B?.95*_.height:_.height,[E,F]=getNewCanvasAndCtx(t,r),F.drawImage(_,0,0,t,r),d*="image/png"===A?.85:.95,canvasToFile(E,A,e.name,e.lastModified,d).then((function(e){try{return y=e,cleanupCanvasMemory(_),_=E,b=y.size,setProgress(Math.min(99,Math.floor((v-b)/(v-f)*100))),$Loop_3}catch(e){return o(e)}}),o)}return [1]}return w=e.size,v=g.size,b=v,_=h,B=!t.alwaysKeepResolution&&p,(a=function(e){for(;e;){if(e.then)return void e.then(a,o);try{if(e.pop){if(e.length)return e.pop()?$Loop_3_exit.call(this):e;e=$Loop_3;}else e=e.call(this);}catch(e){return o(e)}}}.bind(this))($Loop_3);function $Loop_3_exit(){return cleanupCanvasMemory(_),cleanupCanvasMemory(E),cleanupCanvasMemory(c),cleanupCanvasMemory(h),cleanupCanvasMemory(l),setProgress(100),i(y)}}}catch(u){return o(u)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}))}const l="\nlet scriptImported = false\nself.addEventListener('message', async (e) => {\n const { file, id, imageCompressionLibUrl, options } = e.data\n options.onProgress = (progress) => self.postMessage({ progress, id })\n try {\n if (!scriptImported) {\n // console.log('[worker] importScripts', imageCompressionLibUrl)\n self.importScripts(imageCompressionLibUrl)\n scriptImported = true\n }\n // console.log('[worker] self', self)\n const compressedFile = await imageCompression(file, options)\n self.postMessage({ file: compressedFile, id })\n } catch (e) {\n // console.error('[worker] error', e)\n self.postMessage({ error: e.message + '\\n' + e.stack, id })\n }\n})\n";let c;function compressOnWebWorker(e,t){return new Promise(((r,i)=>{c||(c=function createWorkerScriptURL(e){const t=[];return t.push(e),URL.createObjectURL(new Blob(t))}(l));const o=new Worker(c);o.addEventListener("message",(function handler(e){if(t.signal&&t.signal.aborted)o.terminate();else if(void 0===e.data.progress){if(e.data.error)return i(new Error(e.data.error)),void o.terminate();r(e.data.file),o.terminate();}else t.onProgress(e.data.progress);})),o.addEventListener("error",i),t.signal&&t.signal.addEventListener("abort",(()=>{i(t.signal.reason),o.terminate();})),o.postMessage({file:e,imageCompressionLibUrl:t.libURL,options:{...t,onProgress:void 0,signal:void 0}});}))}function imageCompression(e,t){return new Promise((function(r,i){let o,a,s,f,l,c;if(o={...t},s=0,({onProgress:f}=o),o.maxSizeMB=o.maxSizeMB||Number.POSITIVE_INFINITY,l="boolean"!=typeof o.useWebWorker||o.useWebWorker,delete o.useWebWorker,o.onProgress=e=>{s=e,"function"==typeof f&&f(s);},!(e instanceof Blob||e instanceof CustomFile))return i(new Error("The file given is not an instance of Blob or File"));if(!/^image/.test(e.type))return i(new Error("The file given is not an image"));if(c="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,!l||"function"!=typeof Worker||c)return compress(e,o).then(function(e){try{return a=e,$If_4.call(this)}catch(e){return i(e)}}.bind(this),i);var u=function(){try{return $If_4.call(this)}catch(e){return i(e)}}.bind(this),$Try_1_Catch=function(t){try{return compress(e,o).then((function(e){try{return a=e,u()}catch(e){return i(e)}}),i)}catch(e){return i(e)}};try{return o.libURL=o.libURL||"https://cdn.jsdelivr.net/npm/browser-image-compression@2.0.2/dist/browser-image-compression.js",compressOnWebWorker(e,o).then((function(e){try{return a=e,u()}catch(e){return $Try_1_Catch()}}),$Try_1_Catch)}catch(e){$Try_1_Catch();}function $If_4(){try{a.name=e.name,a.lastModified=e.lastModified;}catch(e){}try{o.preserveExif&&"image/jpeg"===e.type&&(!o.fileType||o.fileType&&o.fileType===e.type)&&(a=copyExifWithoutOrientation(e,a));}catch(e){}return r(a)}}))}imageCompression.getDataUrlFromFile=getDataUrlFromFile,imageCompression.getFilefromDataUrl=getFilefromDataUrl,imageCompression.loadImage=loadImage,imageCompression.drawImageInCanvas=drawImageInCanvas,imageCompression.drawFileInCanvas=drawFileInCanvas,imageCompression.canvasToFile=canvasToFile,imageCompression.getExifOrientation=getExifOrientation,imageCompression.handleMaxWidthOrHeight=handleMaxWidthOrHeight,imageCompression.followExifOrientation=followExifOrientation,imageCompression.cleanupCanvasMemory=cleanupCanvasMemory,imageCompression.isAutoOrientationInBrowser=isAutoOrientationInBrowser,imageCompression.approximateBelowMaximumCanvasSizeOfBrowser=approximateBelowMaximumCanvasSizeOfBrowser,imageCompression.copyExifWithoutOrientation=copyExifWithoutOrientation,imageCompression.getBrowserName=getBrowserName,imageCompression.version="2.0.2";
3653
-
3654
- class KritzelImageTool extends KritzelBaseTool {
3445
+ class RemoveSelectionGroupCommand extends KritzelBaseCommand {
3446
+ constructor(store, initiator) {
3447
+ super(store, initiator);
3448
+ this.previousSelectionGroup = this._store.state.selectionGroup;
3449
+ }
3450
+ execute() {
3451
+ this._store.state.objectsOctree.remove(object => object.id === this.previousSelectionGroup.id);
3452
+ this._store.state.selectionGroup = null;
3453
+ }
3454
+ undo() {
3455
+ if (this.previousSelectionGroup) {
3456
+ this._store.state.objectsOctree.insert(this.previousSelectionGroup);
3457
+ this._store.state.selectionGroup = this.previousSelectionGroup;
3458
+ }
3459
+ }
3460
+ }
3461
+
3462
+ class MoveSelectionGroupCommand extends KritzelBaseCommand {
3463
+ constructor(store, initiator, startX, startY, endX, endY, skipFirstExecution = false) {
3464
+ super(store, initiator);
3465
+ this.startX = startX;
3466
+ this.startY = startY;
3467
+ this.endX = endX;
3468
+ this.endY = endY;
3469
+ this.skipExecution = skipFirstExecution;
3470
+ this.selectionGroup = this._store.state.selectionGroup;
3471
+ }
3472
+ execute() {
3473
+ if (this.skipExecution) {
3474
+ this.skipExecution = false;
3475
+ return;
3476
+ }
3477
+ this._store.state.selectionGroup = this.selectionGroup;
3478
+ this._store.state.selectionGroup.move(this.startX, this.startY, this.endX, this.endY);
3479
+ }
3480
+ undo() {
3481
+ this._store.state.selectionGroup = this.selectionGroup;
3482
+ this._store.state.selectionGroup.move(this.endX, this.endY, this.startX, this.startY);
3483
+ }
3484
+ }
3485
+
3486
+ class KritzelBaseHandler {
3487
+ constructor(store) {
3488
+ this._store = store;
3489
+ }
3490
+ }
3491
+
3492
+ class KritzelMoveHandler extends KritzelBaseHandler {
3655
3493
  constructor(store) {
3656
3494
  super(store);
3657
- this.fileInput = null;
3658
- this.maxWidth = 300;
3659
- this.maxHeight = 300;
3660
- this.maxCompressionSize = 300;
3661
- this.setupFileInput();
3662
3495
  }
3663
- onActivate() {
3664
- this.openFilePicker();
3665
- }
3666
- openFilePicker() {
3667
- this.fileInput.click();
3668
- }
3669
- setupFileInput() {
3670
- this.fileInput = document.createElement('input');
3671
- this.fileInput.type = 'file';
3672
- this.fileInput.accept = 'image/*';
3673
- this.fileInput.style.display = 'none';
3674
- this.fileInput.addEventListener('change', this.handleFileSelect.bind(this));
3675
- this.fileInput.addEventListener('cancel', this.handleCancel.bind(this));
3676
- document.body.appendChild(this.fileInput);
3677
- }
3678
- handleFileSelect(event) {
3679
- const input = event.target;
3680
- if (input.files && input.files[0]) {
3681
- const file = input.files[0];
3682
- imageCompression(file, {
3683
- maxWidthOrHeight: this.maxCompressionSize,
3684
- })
3685
- .then(compressedFile => {
3686
- this.readFile(compressedFile);
3687
- })
3688
- .catch(error => {
3689
- console.error('Error during image compression or processing:', error);
3690
- this.handleCancel();
3691
- });
3496
+ handleMouseDown(event) {
3497
+ var _a;
3498
+ if (KritzelEventHelper.isLeftClick(event)) {
3499
+ if (((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
3500
+ const clientX = event.clientX - this._store.offsetX;
3501
+ const clientY = event.clientY - this._store.offsetY;
3502
+ this._store.state.isDragging = true;
3503
+ this.dragStartX = clientX;
3504
+ this.dragStartY = clientY;
3505
+ this.startX = this.dragStartX;
3506
+ this.startY = this.dragStartY;
3507
+ }
3692
3508
  }
3693
- else {
3694
- console.info('File selection cancelled by user.');
3695
- this.handleCancel();
3509
+ }
3510
+ handleMouseMove(event) {
3511
+ if (this._store.state.isDragging && this._store.state.selectionGroup) {
3512
+ const clientX = event.clientX - this._store.offsetX;
3513
+ const clientY = event.clientY - this._store.offsetY;
3514
+ this.endX = clientX;
3515
+ this.endY = clientY;
3516
+ this._store.state.selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
3517
+ this.dragStartX = clientX;
3518
+ this.dragStartY = clientY;
3696
3519
  }
3697
- if (input) {
3698
- input.value = '';
3520
+ }
3521
+ handleMouseUp(_event) {
3522
+ if (this._store.state.isDragging) {
3523
+ this._store.state.isDragging = false;
3524
+ this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
3699
3525
  }
3700
3526
  }
3701
- readFile(file) {
3702
- const reader = new FileReader();
3703
- reader.onload = e => {
3704
- var _a;
3705
- const img = new Image();
3706
- img.src = (_a = e.target) === null || _a === void 0 ? void 0 : _a.result;
3707
- img.onload = () => this.processImage(img);
3708
- };
3709
- reader.readAsDataURL(file);
3527
+ handleTouchStart(event) {
3528
+ var _a;
3529
+ if (this._store.state.touchCount === 1) {
3530
+ if (((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
3531
+ const x = Math.round(event.touches[0].clientX - this._store.offsetX);
3532
+ const y = Math.round(event.touches[0].clientY - this._store.offsetY);
3533
+ this.dragStartX = x;
3534
+ this.dragStartY = y;
3535
+ this.startX = x;
3536
+ this.startY = y;
3537
+ }
3538
+ }
3710
3539
  }
3711
- processImage(img) {
3712
- const { scaledWidth, scaledHeight } = this.calculateScaledDimensions(img);
3713
- const image = this.createKritzelImage(img, scaledWidth, scaledHeight);
3714
- this.addImageToStore(image);
3540
+ handleTouchMove(event) {
3541
+ if (this._store.state.touchCount === 1 && this._store.state.selectionGroup && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
3542
+ const x = Math.round(event.touches[0].clientX - this._store.offsetX);
3543
+ const y = Math.round(event.touches[0].clientY - this._store.offsetY);
3544
+ this._store.state.isDragging = true;
3545
+ this.endX = x;
3546
+ this.endY = y;
3547
+ const moveDeltaX = Math.abs(x - this.startX);
3548
+ const moveDeltaY = Math.abs(y - this.startY);
3549
+ const moveThreshold = 5;
3550
+ if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
3551
+ clearTimeout(this._store.state.longTouchTimeout);
3552
+ this._store.state.selectionGroup.move(x, y, this.dragStartX, this.dragStartY);
3553
+ this.dragStartX = x;
3554
+ this.dragStartY = y;
3555
+ }
3556
+ }
3715
3557
  }
3716
- calculateScaledDimensions(img) {
3717
- let scaledWidth = img.width;
3718
- let scaledHeight = img.height;
3719
- if (img.width > this.maxWidth || img.height > this.maxHeight) {
3720
- const widthRatio = this.maxWidth / img.width;
3721
- const heightRatio = this.maxHeight / img.height;
3722
- const scaleRatio = Math.min(widthRatio, heightRatio);
3723
- scaledWidth = img.width * scaleRatio;
3724
- scaledHeight = img.height * scaleRatio;
3558
+ handleTouchEnd(_event) {
3559
+ if (this._store.state.isDragging) {
3560
+ this._store.state.isDragging = false;
3561
+ this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
3725
3562
  }
3726
- return { scaledWidth, scaledHeight };
3727
3563
  }
3728
- createKritzelImage(img, width, height) {
3729
- const image = new KritzelImage(this._store, img);
3730
- image.width = width;
3731
- image.height = height;
3732
- image.zIndex = this._store.currentZIndex;
3733
- image.centerInViewport();
3734
- return image;
3564
+ }
3565
+
3566
+ var KritzelHandleType;
3567
+ (function (KritzelHandleType) {
3568
+ KritzelHandleType["TopLeft"] = "top-left";
3569
+ KritzelHandleType["TopRight"] = "top-right";
3570
+ KritzelHandleType["BottomLeft"] = "bottom-left";
3571
+ KritzelHandleType["BottomRight"] = "bottom-right";
3572
+ })(KritzelHandleType || (KritzelHandleType = {}));
3573
+
3574
+ class ResizeSelectionGroupCommand extends KritzelBaseCommand {
3575
+ constructor(store, initiator, previousSize, newSize) {
3576
+ super(store, initiator);
3577
+ this.previousSize = previousSize;
3578
+ this.newSize = newSize;
3579
+ this.selectionGroup = this._store.state.selectionGroup;
3735
3580
  }
3736
- addImageToStore(image) {
3737
- const selectionGroup = new KritzelSelectionGroup(this._store);
3738
- selectionGroup.addOrRemove(image);
3739
- selectionGroup.selected = true;
3740
- const addImageCommand = new AddObjectCommand(this._store, this, image);
3741
- const addSelectionGroupCommand = new AddSelectionGroupCommand(this._store, this, selectionGroup);
3742
- this._store.history.executeCommand(new BatchCommand(this._store, this, [addImageCommand, addSelectionGroupCommand]));
3743
- this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
3581
+ execute() {
3582
+ this._store.state.selectionGroup = this.selectionGroup;
3583
+ this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
3744
3584
  }
3745
- handleCancel() {
3746
- this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
3585
+ undo() {
3586
+ this._store.state.selectionGroup = this.selectionGroup;
3587
+ this._store.state.selectionGroup.resize(this.previousSize.x, this.previousSize.y, this.previousSize.width, this.previousSize.height);
3747
3588
  }
3748
3589
  }
3749
3590
 
3750
- class KritzelReviver {
3591
+ class KritzelResizeHandler extends KritzelBaseHandler {
3751
3592
  constructor(store) {
3752
- this._store = store;
3593
+ super(store);
3594
+ this.initialMouseX = 0;
3595
+ this.initialMouseY = 0;
3596
+ this.initialSize = { x: 0, y: 0, width: 0, height: 0 };
3597
+ this.newSize = { x: 0, y: 0, width: 0, height: 0 };
3753
3598
  }
3754
- revive(obj) {
3755
- if (obj && typeof obj === 'object') {
3756
- if (obj.__class__) {
3757
- let revivedObj;
3758
- switch (obj.__class__) {
3759
- case 'KritzelPath':
3760
- revivedObj = new KritzelPath(this._store).revive(obj);
3761
- break;
3762
- case 'KritzelText':
3763
- revivedObj = new KritzelText(this._store, obj.fontSize, obj.fontFamily).revive(obj);
3764
- break;
3765
- case 'KritzelImage':
3766
- revivedObj = new KritzelImage(this._store, obj.img).revive(obj);
3767
- break;
3768
- case 'KritzelSelectionGroup':
3769
- revivedObj = new KritzelSelectionGroup(this._store).revive(obj);
3770
- break;
3771
- case 'KritzelBrushTool':
3772
- revivedObj = new KritzelBrushTool(this._store);
3773
- break;
3774
- case 'KritzelEraserTool':
3775
- revivedObj = new KritzelEraserTool(this._store);
3776
- break;
3777
- case 'KritzelImageTool':
3778
- revivedObj = new KritzelImageTool(this._store);
3779
- break;
3780
- case 'KritzelSelectionTool':
3781
- revivedObj = new KritzelSelectionTool(this._store);
3782
- break;
3783
- case 'KritzelTextTool':
3784
- revivedObj = new KritzelTextTool(this._store);
3785
- break;
3786
- default:
3787
- revivedObj = obj;
3788
- }
3789
- return revivedObj;
3599
+ handleMouseDown(event) {
3600
+ if (KritzelEventHelper.isLeftClick(event)) {
3601
+ if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
3602
+ const clientX = event.clientX - this._store.offsetX;
3603
+ const clientY = event.clientY - this._store.offsetY;
3604
+ this._store.state.isResizing = true;
3605
+ this.initialMouseX = clientX;
3606
+ this.initialMouseY = clientY;
3607
+ this.initialSize.width = this._store.state.selectionGroup.width;
3608
+ this.initialSize.height = this._store.state.selectionGroup.height;
3609
+ this.initialSize.x = this._store.state.selectionGroup.translateX;
3610
+ this.initialSize.y = this._store.state.selectionGroup.translateY;
3790
3611
  }
3791
- const newObj = Array.isArray(obj) ? [] : {};
3792
- for (const key in obj) {
3793
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
3794
- newObj[key] = this.revive(obj[key]);
3795
- }
3612
+ }
3613
+ }
3614
+ handleMouseMove(event) {
3615
+ if (this._store.state.isResizing && this._store.state.selectionGroup) {
3616
+ const clientX = event.clientX - this._store.offsetX;
3617
+ const clientY = event.clientY - this._store.offsetY;
3618
+ const dx = clientX - this.initialMouseX;
3619
+ const dy = clientY - this.initialMouseY;
3620
+ switch (this._store.state.resizeHandleType) {
3621
+ case KritzelHandleType.TopLeft:
3622
+ this.newSize.width = this.initialSize.width - dx;
3623
+ this.newSize.height = this.initialSize.height - dy;
3624
+ this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
3625
+ this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
3626
+ break;
3627
+ case KritzelHandleType.TopRight:
3628
+ this.newSize.width = this.initialSize.width + dx;
3629
+ this.newSize.height = this.initialSize.height - dy;
3630
+ this.newSize.x = this.initialSize.x;
3631
+ this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
3632
+ break;
3633
+ case KritzelHandleType.BottomLeft:
3634
+ this.newSize.width = this.initialSize.width - dx;
3635
+ this.newSize.height = this.initialSize.height + dy;
3636
+ this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
3637
+ this.newSize.y = this.initialSize.y;
3638
+ break;
3639
+ case KritzelHandleType.BottomRight:
3640
+ this.newSize.width = this.initialSize.width + dx;
3641
+ this.newSize.height = this.initialSize.height + dy;
3642
+ this.newSize.x = this.initialSize.x;
3643
+ this.newSize.y = this.initialSize.y;
3644
+ break;
3796
3645
  }
3797
- return newObj;
3646
+ this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
3647
+ this._store.rerender();
3798
3648
  }
3799
- return obj;
3800
- }
3801
- }
3802
-
3803
- class KritzelSelectionGroup extends KritzelBaseObject {
3804
- constructor(store) {
3805
- super(store);
3806
- this.__class__ = 'KritzelSelectionGroup';
3807
- this.objects = [];
3808
- this.unchangedObjects = [];
3809
- this.scale = this._store.state.scale;
3810
- this.zIndex = 99999;
3811
3649
  }
3812
- get length() {
3813
- return this.objects.length;
3650
+ handleMouseUp(_event) {
3651
+ if (this._store.state.isResizing) {
3652
+ const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
3653
+ this._store.history.executeCommand(resizeSelectionGroupCommand);
3654
+ this._store.state.isResizing = false;
3655
+ this._store.rerender();
3656
+ }
3814
3657
  }
3815
- addOrRemove(object) {
3816
- const index = this.objects.findIndex(obj => obj.id === object.id);
3817
- if (index === -1) {
3818
- this.objects.push(object);
3658
+ handleTouchStart(event) {
3659
+ const firstTouch = event.touches[0];
3660
+ if (!firstTouch) {
3661
+ return;
3819
3662
  }
3820
- else {
3821
- this.objects.splice(index, 1);
3663
+ if (this._store.state.touchCount === 1) {
3664
+ if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
3665
+ const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
3666
+ const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
3667
+ this._store.state.isResizing = true;
3668
+ this.initialMouseX = clientX;
3669
+ this.initialMouseY = clientY;
3670
+ this.initialSize.width = this._store.state.selectionGroup.width;
3671
+ this.initialSize.height = this._store.state.selectionGroup.height;
3672
+ this.initialSize.x = this._store.state.selectionGroup.translateX;
3673
+ this.initialSize.y = this._store.state.selectionGroup.translateY;
3674
+ clearTimeout(this._store.state.longTouchTimeout);
3675
+ }
3822
3676
  }
3823
- this.unchangedObjects = ObjectHelper.clone(this.objects);
3824
- this.refreshObjectDimensions();
3825
- }
3826
- deselectAllChildren() {
3827
- this.objects.forEach(obj => (obj.selected = false));
3828
- }
3829
- updatePosition(x, y) {
3830
- this.objects.forEach(obj => {
3831
- const deltaX = obj.translateX - this.translateX;
3832
- const deltaY = obj.translateY - this.translateY;
3833
- obj.translateX = x + deltaX;
3834
- obj.translateY = y + deltaY;
3835
- this._store.state.objectsOctree.update(obj);
3836
- });
3837
- this.unchangedObjects.forEach(obj => {
3838
- const deltaX = obj.translateX - this.translateX;
3839
- const deltaY = obj.translateY - this.translateY;
3840
- obj.translateX = x + deltaX;
3841
- obj.translateY = y + deltaY;
3842
- });
3843
- this.translateX = x;
3844
- this.translateY = y;
3845
- this._store.state.objectsOctree.update(this);
3846
- }
3847
- move(startX, startY, endX, endY) {
3848
- const deltaX = (startX - endX) / this._store.state.scale;
3849
- const deltaY = (startY - endY) / this._store.state.scale;
3850
- this.translateX += deltaX;
3851
- this.translateY += deltaY;
3852
- this._store.state.objectsOctree.update(this);
3853
- this.objects.forEach(obj => {
3854
- obj.translateX += deltaX;
3855
- obj.translateY += deltaY;
3856
- this._store.state.objectsOctree.update(obj);
3857
- });
3858
- this.unchangedObjects.forEach(obj => {
3859
- obj.translateX += deltaX;
3860
- obj.translateY += deltaY;
3861
- });
3862
- }
3863
- resize(x, y, width, height) {
3864
- const widthScaleFactor = width / this.width;
3865
- const heightScaleFactor = height / this.height;
3866
- const deltaX = x - this.translateX;
3867
- const deltaY = y - this.translateY;
3868
- this.objects.forEach(obj => {
3869
- const updatedWidth = obj.width * widthScaleFactor;
3870
- const updatedHeight = obj.height * heightScaleFactor;
3871
- const updatedX = obj.translateX + deltaX + (obj.translateX - this.translateX) * (widthScaleFactor - 1);
3872
- const updatedY = obj.translateY + deltaY + (obj.translateY - this.translateY) * (heightScaleFactor - 1);
3873
- obj.resize(updatedX, updatedY, updatedWidth, updatedHeight);
3874
- this._store.state.objectsOctree.update(obj);
3875
- });
3876
- this.refreshObjectDimensions();
3877
- this.unchangedObjects = ObjectHelper.clone(this.objects);
3878
- }
3879
- rotate(value) {
3880
- this.rotation = value;
3881
- const centerX = this.translateX + this.totalWidth / 2 / this.scale;
3882
- const centerY = this.translateY + this.totalHeight / 2 / this.scale;
3883
- const angle = value;
3884
- const cos = Math.cos(angle);
3885
- const sin = Math.sin(angle);
3886
- this.objects.forEach(child => {
3887
- const unchangedChild = this.getUnchangedObject(child.id);
3888
- const offsetX = this.getOffsetXToCenter(unchangedChild);
3889
- const offsetY = this.getOffsetYToCenter(unchangedChild);
3890
- const rotatedX = cos * offsetX - sin * offsetY;
3891
- const rotatedY = sin * offsetX + cos * offsetY;
3892
- child.translateX = centerX + rotatedX - child.totalWidth / 2 / child.scale;
3893
- child.translateY = centerY + rotatedY - child.totalHeight / 2 / child.scale;
3894
- child.rotation = this.objects.length === 1 ? value : value + unchangedChild.rotation;
3895
- });
3896
3677
  }
3897
- copy() {
3898
- const selectionGroup = new KritzelSelectionGroup(this._store);
3899
- let currentZIndex = this._store.currentZIndex;
3900
- this.objects.forEach(obj => {
3901
- const copiedObject = obj.copy();
3902
- copiedObject.zIndex = currentZIndex;
3903
- selectionGroup.addOrRemove(copiedObject);
3904
- currentZIndex++;
3905
- });
3906
- selectionGroup.unchangedObjects = ObjectHelper.clone(selectionGroup.objects);
3907
- if (this.objects.length === 1) {
3908
- selectionGroup.rotation = this.objects[0].rotation;
3678
+ handleTouchMove(event) {
3679
+ const oneFingerTouch = event.touches[0];
3680
+ if (!oneFingerTouch) {
3681
+ return;
3909
3682
  }
3910
- return selectionGroup;
3911
- }
3912
- refreshObjectDimensions() {
3913
- if (this.objects.length === 1) {
3914
- const obj = this.objects[0];
3915
- this.minX = obj.boundingBox.x / this.scale;
3916
- this.maxX = obj.boundingBox.x / this.scale + obj.boundingBox.width;
3917
- this.minY = obj.boundingBox.y / this.scale;
3918
- this.maxY = obj.boundingBox.y / this.scale + obj.boundingBox.height;
3919
- this.translateX = (this.minX - this.padding) * this.scale;
3920
- this.translateY = (this.minY - this.padding) * this.scale;
3921
- this.width = (this.maxX - this.minX - this.padding) * this.scale;
3922
- this.height = (this.maxY - this.minY - this.padding) * this.scale;
3683
+ if (this._store.state.isResizing && this._store.state.selectionGroup) {
3684
+ const clientX = Math.round(oneFingerTouch.clientX - this._store.offsetX);
3685
+ const clientY = Math.round(oneFingerTouch.clientY - this._store.offsetY);
3686
+ const dx = clientX - this.initialMouseX;
3687
+ const dy = clientY - this.initialMouseY;
3688
+ switch (this._store.state.resizeHandleType) {
3689
+ case KritzelHandleType.TopLeft:
3690
+ this.newSize.width = this.initialSize.width - dx;
3691
+ this.newSize.height = this.initialSize.height - dy;
3692
+ this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
3693
+ this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
3694
+ break;
3695
+ case KritzelHandleType.TopRight:
3696
+ this.newSize.width = this.initialSize.width + dx;
3697
+ this.newSize.height = this.initialSize.height - dy;
3698
+ this.newSize.x = this.initialSize.x;
3699
+ this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
3700
+ break;
3701
+ case KritzelHandleType.BottomLeft:
3702
+ this.newSize.width = this.initialSize.width - dx;
3703
+ this.newSize.height = this.initialSize.height + dy;
3704
+ this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
3705
+ this.newSize.y = this.initialSize.y;
3706
+ break;
3707
+ case KritzelHandleType.BottomRight:
3708
+ this.newSize.width = this.initialSize.width + dx;
3709
+ this.newSize.height = this.initialSize.height + dy;
3710
+ this.newSize.x = this.initialSize.x;
3711
+ this.newSize.y = this.initialSize.y;
3712
+ break;
3713
+ }
3714
+ this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
3715
+ clearTimeout(this._store.state.longTouchTimeout);
3923
3716
  }
3924
- else {
3925
- this.minX = Math.min(...this.objects.map(obj => obj.minXRotated));
3926
- this.maxX = Math.max(...this.objects.map(obj => obj.maxXRotated));
3927
- this.minY = Math.min(...this.objects.map(obj => obj.minYRotated));
3928
- this.maxY = Math.max(...this.objects.map(obj => obj.maxYRotated));
3929
- this.translateX = this.minX - this.padding;
3930
- this.translateY = this.minY - this.padding;
3931
- this.width = (this.maxX - this.minX - this.padding) * this.scale;
3932
- this.height = (this.maxY - this.minY - this.padding) * this.scale;
3717
+ }
3718
+ handleTouchEnd(_event) {
3719
+ if (this._store.state.isResizing) {
3720
+ const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
3721
+ this._store.history.executeCommand(resizeSelectionGroupCommand);
3722
+ this._store.state.isResizing = false;
3723
+ clearTimeout(this._store.state.longTouchTimeout);
3933
3724
  }
3934
- this._store.state.objectsOctree.update(this);
3935
3725
  }
3936
- getOffsetXToCenter(obj) {
3937
- const objCenterX = obj.translateX + obj.totalWidth / obj.scale / 2;
3938
- const groupCenterX = this.translateX + this.totalWidth / this.scale / 2;
3939
- return objCenterX - groupCenterX;
3726
+ }
3727
+
3728
+ class RotateSelectionGroupCommand extends KritzelBaseCommand {
3729
+ constructor(store, initiator, rotation) {
3730
+ super(store, initiator);
3731
+ this.rotation = rotation;
3732
+ this.initialRotation = this._store.state.selectionGroup.rotation;
3733
+ this.selectionGroup = this._store.state.selectionGroup;
3940
3734
  }
3941
- getOffsetYToCenter(obj) {
3942
- const objCenterY = obj.translateY + obj.totalHeight / obj.scale / 2;
3943
- const groupCenterY = this.translateY + this.totalHeight / this.scale / 2;
3944
- return objCenterY - groupCenterY;
3735
+ execute() {
3736
+ this._store.state.selectionGroup = this.selectionGroup;
3737
+ this._store.state.selectionGroup.rotate(this.rotation);
3738
+ this._store.state.selectionGroup.objects.forEach(object => {
3739
+ this._store.state.objectsOctree.update(object);
3740
+ });
3945
3741
  }
3946
- getUnchangedObject(objectId) {
3947
- const obj = this.unchangedObjects.find(obj => obj.id === objectId);
3948
- const reviver = new KritzelReviver(this._store);
3949
- return reviver.revive(obj);
3742
+ undo() {
3743
+ this._store.state.selectionGroup = this.selectionGroup;
3744
+ this._store.state.selectionGroup.rotate(this.rotation - this.initialRotation);
3745
+ this._store.state.selectionGroup.objects.forEach(object => {
3746
+ this._store.state.objectsOctree.update(object);
3747
+ });
3950
3748
  }
3951
3749
  }
3952
3750
 
3953
- class KritzelSelectionHandler extends KritzelBaseHandler {
3954
- get isSelectionClick() {
3955
- return this._store.state.selectionBox && this._store.state.selectionBox.width === 0 && this._store.state.selectionBox.height === 0;
3956
- }
3957
- get isSelectionDrag() {
3958
- return this._store.state.selectionBox && (this._store.state.selectionBox.width > 0 || this._store.state.selectionBox.height > 0);
3959
- }
3751
+ class KritzelRotationHandler extends KritzelBaseHandler {
3960
3752
  constructor(store) {
3961
3753
  super(store);
3962
- this.touchStartX = 0;
3963
- this.touchStartY = 0;
3964
- this.touchStartTimeout = null;
3754
+ this.initialRotation = 0;
3755
+ this.rotation = 0;
3965
3756
  }
3966
3757
  handleMouseDown(event) {
3967
- if (KritzelEventHelper.isLeftClick(event) && !this._store.state.selectionGroup) {
3968
- this.startMouseSelection(event);
3758
+ if (KritzelEventHelper.isLeftClick(event)) {
3759
+ if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
3760
+ const clientX = event.clientX - this._store.offsetX;
3761
+ const clientY = event.clientY - this._store.offsetY;
3762
+ this._store.state.isRotating = true;
3763
+ const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
3764
+ const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
3765
+ const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
3766
+ const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
3767
+ this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
3768
+ }
3969
3769
  }
3970
3770
  }
3971
3771
  handleMouseMove(event) {
3972
- if (this._store.state.isSelecting) {
3973
- this.updateMouseSelection(event);
3772
+ if (this._store.state.isRotating && this._store.state.selectionGroup) {
3773
+ const clientX = event.clientX - this._store.offsetX;
3774
+ const clientY = event.clientY - this._store.offsetY;
3775
+ const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
3776
+ const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
3777
+ const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
3778
+ const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
3779
+ const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
3780
+ this.rotation = currentRotation - this.initialRotation;
3781
+ this._store.state.selectionGroup.rotate(this.rotation);
3782
+ this._store.rerender();
3974
3783
  }
3975
3784
  }
3976
- handleMouseUp(event) {
3977
- if (KritzelEventHelper.isLeftClick(event) && this._store.state.isSelecting) {
3978
- if (this.isSelectionClick) {
3979
- this.updateMouseSelection(event);
3980
- this.addSelectedObjectAtIndexToSelectionGroup(0);
3981
- this.removeSelectionBox();
3982
- }
3983
- if (this.isSelectionDrag) {
3984
- this.updateMouseSelection(event);
3985
- this.addSelectedObjectsToSelectionGroup();
3986
- this.removeSelectionBox();
3987
- }
3785
+ handleMouseUp(_event) {
3786
+ if (this._store.state.isRotating) {
3787
+ this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
3788
+ this._store.state.isRotating = false;
3789
+ this.initialRotation = 0;
3790
+ this.rotation = 0;
3988
3791
  }
3989
3792
  }
3990
3793
  handleTouchStart(event) {
3991
- this.touchStartTimeout = setTimeout(() => {
3992
- if (this._store.state.touchCount === 1 && !this._store.state.isScaling && !this._store.state.selectionGroup) {
3993
- this.startTouchSelection(event);
3994
- this.updateTouchSelection(event);
3794
+ const firstTouch = event.touches[0];
3795
+ if (!firstTouch) {
3796
+ return;
3797
+ }
3798
+ if (this._store.state.touchCount === 1) {
3799
+ if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
3800
+ const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
3801
+ const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
3802
+ this._store.state.isRotating = true;
3803
+ const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
3804
+ const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
3805
+ const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
3806
+ const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
3807
+ this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
3808
+ clearTimeout(this._store.state.longTouchTimeout);
3995
3809
  }
3996
- }, 80);
3810
+ }
3997
3811
  }
3998
3812
  handleTouchMove(event) {
3999
- const x = Math.round(event.touches[0].clientX - this._store.offsetX);
4000
- const y = Math.round(event.touches[0].clientY - this._store.offsetY);
4001
- const moveDeltaX = Math.abs(x - this.touchStartX);
4002
- const moveDeltaY = Math.abs(y - this.touchStartY);
4003
- const moveThreshold = 5;
4004
- if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._store.state.isSelecting) {
4005
- this.updateTouchSelection(event);
3813
+ const firstTouch = event.touches[0];
3814
+ if (!firstTouch) {
3815
+ return;
3816
+ }
3817
+ if (this._store.state.isRotating && this._store.state.selectionGroup) {
3818
+ const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
3819
+ const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
3820
+ const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
3821
+ const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
3822
+ const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
3823
+ const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
3824
+ const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
3825
+ this.rotation = currentRotation - this.initialRotation;
3826
+ this._store.state.selectionGroup.rotate(this.rotation);
4006
3827
  clearTimeout(this._store.state.longTouchTimeout);
4007
3828
  }
4008
3829
  }
4009
- handleTouchEnd(event) {
4010
- clearTimeout(this.touchStartTimeout);
4011
- if (this._store.state.isSelecting) {
4012
- if (this.isSelectionClick) {
4013
- this.updateTouchSelection(event);
4014
- this.addSelectedObjectAtIndexToSelectionGroup(0);
4015
- this.removeSelectionBox();
3830
+ handleTouchEnd(_event) {
3831
+ if (this._store.state.isRotating) {
3832
+ this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
3833
+ this._store.state.isRotating = false;
3834
+ this.initialRotation = 0;
3835
+ this.rotation = 0;
3836
+ clearTimeout(this._store.state.longTouchTimeout);
3837
+ }
3838
+ }
3839
+ }
3840
+
3841
+ class KritzelGeometryHelper {
3842
+ static doPolygonsIntersect(polygon1, polygon2) {
3843
+ // 1. Convert polygons to array of points for easier processing
3844
+ const points1 = [polygon1.bottomLeft, polygon1.bottomRight, polygon1.topRight, polygon1.topLeft];
3845
+ const points2 = [polygon2.bottomLeft, polygon2.bottomRight, polygon2.topRight, polygon2.topLeft];
3846
+ // 2. Check if any point of polygon1 is inside polygon2
3847
+ for (const point of points1) {
3848
+ if (this.isPointInPolygon(point, points2)) {
3849
+ return true;
4016
3850
  }
4017
- if (this.isSelectionDrag) {
4018
- this.updateTouchSelection(event);
4019
- this.addSelectedObjectsToSelectionGroup();
4020
- this.removeSelectionBox();
3851
+ }
3852
+ // 3. Check if any point of polygon2 is inside polygon1
3853
+ for (const point of points2) {
3854
+ if (this.isPointInPolygon(point, points1)) {
3855
+ return true;
4021
3856
  }
4022
- this._store.state.skipContextMenu = false;
4023
3857
  }
4024
- }
4025
- removeSelectionBox() {
4026
- this._store.state.selectionBox = null;
4027
- this._store.state.isSelecting = false;
4028
- this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox);
4029
- this._store.rerender();
4030
- }
4031
- startMouseSelection(event) {
4032
- let clientX, clientY;
4033
- clientX = event.clientX - this._store.offsetX;
4034
- clientY = event.clientY - this._store.offsetY;
4035
- const selectionBox = new KrtizelSelectionBox(this._store);
4036
- this.startX = (clientX - this._store.state.translateX) / this._store.state.scale;
4037
- this.startY = (clientY - this._store.state.translateY) / this._store.state.scale;
4038
- selectionBox.translateX = this.startX;
4039
- selectionBox.translateY = this.startY;
4040
- this._store.state.selectionGroup = null;
4041
- this._store.state.selectionBox = selectionBox;
4042
- this._store.state.isSelecting = true;
4043
- this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox || o instanceof KritzelSelectionGroup);
4044
- this._store.state.objectsOctree.insert(selectionBox);
4045
- }
4046
- startTouchSelection(event) {
4047
- const firstTouch = event.touches[0];
4048
- if (!firstTouch) {
4049
- return;
3858
+ // 4. Check for edge intersections (more complex)
3859
+ for (let i = 0; i < points1.length; i++) {
3860
+ const p1a = points1[i];
3861
+ const p1b = points1[(i + 1) % points1.length]; // Wrap around to the first point
3862
+ for (let j = 0; j < points2.length; j++) {
3863
+ const p2a = points2[j];
3864
+ const p2b = points2[(j + 1) % points2.length];
3865
+ if (this.intersectLines(p1a, p1b, p2a, p2b)) {
3866
+ return true;
3867
+ }
3868
+ }
4050
3869
  }
4051
- let clientX, clientY;
4052
- clientX = Math.round(firstTouch.clientX - this._store.offsetX);
4053
- clientY = Math.round(firstTouch.clientY - this._store.offsetY);
4054
- this.touchStartX = clientX;
4055
- this.touchStartY = clientY;
4056
- const selectionBox = new KrtizelSelectionBox(this._store);
4057
- this.startX = (clientX - this._store.state.translateX) / this._store.state.scale;
4058
- this.startY = (clientY - this._store.state.translateY) / this._store.state.scale;
4059
- selectionBox.translateX = this.startX;
4060
- selectionBox.translateY = this.startY;
4061
- this._store.state.selectionGroup = null;
4062
- this._store.state.selectionBox = selectionBox;
4063
- this._store.state.isSelecting = true;
4064
- this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox || o instanceof KritzelSelectionGroup);
4065
- this._store.state.objectsOctree.insert(selectionBox);
3870
+ return false; // No intersection found
4066
3871
  }
4067
- updateMouseSelection(event) {
4068
- let clientX, clientY;
4069
- clientX = event.clientX - this._store.offsetX;
4070
- clientY = event.clientY - this._store.offsetY;
4071
- const selectionBox = this._store.state.selectionBox;
4072
- if (selectionBox) {
4073
- const currentX = (clientX - this._store.state.translateX) / selectionBox.scale;
4074
- const currentY = (clientY - this._store.state.translateY) / selectionBox.scale;
4075
- selectionBox.width = Math.abs(currentX - this.startX) * selectionBox.scale;
4076
- selectionBox.height = Math.abs(currentY - this.startY) * selectionBox.scale;
4077
- selectionBox.translateX = Math.min(currentX, this.startX);
4078
- selectionBox.translateY = Math.min(currentY, this.startY);
4079
- this.updateSelectedObjects();
4080
- this._store.rerender();
3872
+ static isPointInPolygon(point, polygon) {
3873
+ let inside = false;
3874
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
3875
+ const xi = polygon[i].x, yi = polygon[i].y;
3876
+ const xj = polygon[j].x, yj = polygon[j].y;
3877
+ const intersect = yi > point.y !== yj > point.y && point.x < ((xj - xi) * (point.y - yi)) / (yj - yi) + xi;
3878
+ if (intersect)
3879
+ inside = !inside;
4081
3880
  }
3881
+ return inside;
4082
3882
  }
4083
- updateTouchSelection(event) {
4084
- const firstTouch = event.touches[0];
4085
- if (!firstTouch) {
4086
- return;
4087
- }
4088
- let clientX, clientY;
4089
- clientX = Math.round(firstTouch.clientX - this._store.offsetX);
4090
- clientY = Math.round(firstTouch.clientY - this._store.offsetY);
4091
- const selectionBox = this._store.state.selectionBox;
4092
- if (selectionBox) {
4093
- const currentX = (clientX - this._store.state.translateX) / selectionBox.scale;
4094
- const currentY = (clientY - this._store.state.translateY) / selectionBox.scale;
4095
- selectionBox.width = Math.abs(currentX - this.startX) * selectionBox.scale;
4096
- selectionBox.height = Math.abs(currentY - this.startY) * selectionBox.scale;
4097
- selectionBox.translateX = Math.min(currentX, this.startX);
4098
- selectionBox.translateY = Math.min(currentY, this.startY);
4099
- this.updateSelectedObjects();
3883
+ static intersectLines(p1a, p1b, p2a, p2b) {
3884
+ const det = (p1b.x - p1a.x) * (p2b.y - p2a.y) - (p1b.y - p1a.y) * (p2b.x - p2a.x);
3885
+ if (det === 0) {
3886
+ return false; // Lines are parallel
4100
3887
  }
3888
+ const t = ((p2a.x - p1a.x) * (p2b.y - p2a.y) - (p2a.y - p1a.y) * (p2b.x - p2a.x)) / det;
3889
+ const u = -((p1a.x - p2a.x) * (p1b.y - p1a.y) - (p1a.y - p2a.y) * (p1b.x - p1a.x)) / det;
3890
+ return t >= 0 && t <= 1 && u >= 0 && u <= 1;
4101
3891
  }
4102
- updateSelectedObjects() {
4103
- this._store.allObjects
4104
- .filter(o => !(o instanceof KrtizelSelectionBox))
4105
- .forEach(object => {
4106
- const objectPolygon = object.rotatedPolygon;
4107
- const selectionBoxPolygon = this._store.state.selectionBox.rotatedPolygon;
4108
- object.selected = KritzelGeometryHelper.doPolygonsIntersect(objectPolygon, selectionBoxPolygon);
4109
- });
3892
+ }
3893
+
3894
+ class KrtizelSelectionBox extends KritzelBaseObject {
3895
+ constructor(store) {
3896
+ super(store);
3897
+ this.__class__ = 'KrtizelSelectionBox';
3898
+ this.objects = [];
3899
+ this.backgroundColor = 'var(--kritzel-selection-box-background-color)';
3900
+ this.borderColor = 'var(--kritzel-selection-box-border-color)';
3901
+ this.borderWidth = 2;
3902
+ this.scale = this._store.state.scale;
3903
+ this.height = 0;
3904
+ this.width = 0;
3905
+ this.zIndex = 9999;
3906
+ }
3907
+ }
3908
+
3909
+ class AddSelectionGroupCommand extends KritzelBaseCommand {
3910
+ constructor(store, initiator, selectionGroup) {
3911
+ super(store, initiator);
3912
+ this.selectionGroup = selectionGroup;
3913
+ }
3914
+ execute() {
3915
+ this._store.state.objectsOctree.remove(object => object instanceof KrtizelSelectionBox);
3916
+ this._store.state.objectsOctree.insert(this.selectionGroup);
3917
+ this._store.state.selectionGroup = this.selectionGroup;
3918
+ }
3919
+ undo() {
3920
+ this._store.state.objectsOctree.remove(object => object.id === this.selectionGroup.id);
3921
+ this._store.state.selectionGroup = null;
4110
3922
  }
4111
- addSelectedObjectAtIndexToSelectionGroup(index) {
4112
- const selectedObjects = this._store.selectedObjects.sort((a, b) => b.zIndex - a.zIndex);
4113
- const selectedObject = selectedObjects[index];
4114
- if (!selectedObject) {
4115
- return;
4116
- }
4117
- selectedObjects.forEach(o => (o.selected = false));
4118
- this._store.state.selectionGroup = new KritzelSelectionGroup(this._store);
4119
- this._store.state.selectionGroup.addOrRemove(selectedObject);
4120
- this._store.state.selectionGroup.selected = true;
4121
- this._store.state.selectionGroup.rotation = this._store.state.selectionGroup.objects[0].rotation;
4122
- this._store.history.executeCommand(new AddSelectionGroupCommand(this._store, this, this._store.state.selectionGroup));
3923
+ }
3924
+
3925
+ class KritzelImage extends KritzelBaseObject {
3926
+ constructor(store, img) {
3927
+ super(store);
3928
+ this.__class__ = 'KritzelImage';
3929
+ this.debugInfoVisible = true;
3930
+ this.img = img;
3931
+ this.x = 0;
3932
+ this.y = 0;
3933
+ this.translateX = 0;
3934
+ this.translateY = 0;
3935
+ this.width = img.width;
3936
+ this.height = img.height;
3937
+ this.scale = this._store.state.scale;
4123
3938
  }
4124
- addSelectedObjectsToSelectionGroup() {
4125
- const selectedObjects = this._store.selectedObjects;
4126
- if (selectedObjects.length === 0) {
3939
+ resize(x, y, width, height) {
3940
+ if (width <= 1 || height <= 1) {
4127
3941
  return;
4128
3942
  }
4129
- this._store.state.selectionGroup = new KritzelSelectionGroup(this._store);
4130
- selectedObjects.forEach(o => {
4131
- o.selected = false;
4132
- this._store.state.selectionGroup.addOrRemove(o);
4133
- });
4134
- this._store.state.selectionGroup.selected = true;
4135
- if (this._store.state.selectionGroup.length === 1) {
4136
- this._store.state.selectionGroup.rotation = this._store.state.selectionGroup.objects[0].rotation;
4137
- }
4138
- this._store.history.executeCommand(new AddSelectionGroupCommand(this._store, this, this._store.state.selectionGroup));
3943
+ const scaleFactor = height / this.height;
3944
+ this.width = this.width * scaleFactor;
3945
+ this.height = this.height * scaleFactor;
3946
+ this.translateX = x;
3947
+ this.translateY = y;
4139
3948
  }
4140
3949
  }
4141
3950
 
4142
- class KritzelSelectionTool extends KritzelBaseTool {
3951
+ /**
3952
+ * Browser Image Compression
3953
+ * v2.0.2
3954
+ * by Donald <donaldcwl@gmail.com>
3955
+ * https://github.com/Donaldcwl/browser-image-compression
3956
+ */
3957
+
3958
+ function _mergeNamespaces$1(e,t){return t.forEach((function(t){t&&"string"!=typeof t&&!Array.isArray(t)&&Object.keys(t).forEach((function(r){if("default"!==r&&!(r in e)){var i=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,i.get?i:{enumerable:true,get:function(){return t[r]}});}}));})),Object.freeze(e)}function copyExifWithoutOrientation(e,t){return new Promise((function(r,i){let o;return getApp1Segment(e).then((function(e){try{return o=e,r(new Blob([t.slice(0,2),o,t.slice(2)],{type:"image/jpeg"}))}catch(e){return i(e)}}),i)}))}const getApp1Segment=e=>new Promise(((t,r)=>{const i=new FileReader;i.addEventListener("load",(({target:{result:e}})=>{const i=new DataView(e);let o=0;if(65496!==i.getUint16(o))return r("not a valid JPEG");for(o+=2;;){const a=i.getUint16(o);if(65498===a)break;const s=i.getUint16(o+2);if(65505===a&&1165519206===i.getUint32(o+4)){const a=o+10;let f;switch(i.getUint16(a)){case 18761:f=true;break;case 19789:f=false;break;default:return r("TIFF header contains invalid endian")}if(42!==i.getUint16(a+2,f))return r("TIFF header contains invalid version");const l=i.getUint32(a+4,f),c=a+l+2+12*i.getUint16(a+l,f);for(let e=a+l+2;e<c;e+=12){if(274==i.getUint16(e,f)){if(3!==i.getUint16(e+2,f))return r("Orientation data type is invalid");if(1!==i.getUint32(e+4,f))return r("Orientation data count is invalid");i.setUint16(e+8,1,f);break}}return t(e.slice(o,o+2+s))}o+=2+s;}return t(new Blob)})),i.readAsArrayBuffer(e);}));var e={},t={get exports(){return e},set exports(t){e=t;}};!function(e){var r,i,UZIP={};t.exports=UZIP,UZIP.parse=function(e,t){for(var r=UZIP.bin.readUshort,i=UZIP.bin.readUint,o=0,a={},s=new Uint8Array(e),f=s.length-4;101010256!=i(s,f);)f--;o=f;o+=4;var l=r(s,o+=4);r(s,o+=2);var c=i(s,o+=2),u=i(s,o+=4);o+=4,o=u;for(var h=0;h<l;h++){i(s,o),o+=4,o+=4,o+=4,i(s,o+=4);c=i(s,o+=4);var d=i(s,o+=4),A=r(s,o+=4),g=r(s,o+2),p=r(s,o+4);o+=6;var m=i(s,o+=8);o+=4,o+=A+g+p,UZIP._readLocal(s,m,a,c,d,t);}return a},UZIP._readLocal=function(e,t,r,i,o,a){var s=UZIP.bin.readUshort,f=UZIP.bin.readUint;f(e,t),s(e,t+=4),s(e,t+=2);var l=s(e,t+=2);f(e,t+=2),f(e,t+=4),t+=4;var c=s(e,t+=8),u=s(e,t+=2);t+=2;var h=UZIP.bin.readUTF8(e,t,c);if(t+=c,t+=u,a)r[h]={size:o,csize:i};else {var d=new Uint8Array(e.buffer,t);if(0==l)r[h]=new Uint8Array(d.buffer.slice(t,t+i));else {if(8!=l)throw "unknown compression method: "+l;var A=new Uint8Array(o);UZIP.inflateRaw(d,A),r[h]=A;}}},UZIP.inflateRaw=function(e,t){return UZIP.F.inflate(e,t)},UZIP.inflate=function(e,t){return UZIP.inflateRaw(new Uint8Array(e.buffer,e.byteOffset+2,e.length-6),t)},UZIP.deflate=function(e,t){null==t&&(t={level:6});var r=0,i=new Uint8Array(50+Math.floor(1.1*e.length));i[r]=120,i[r+1]=156,r+=2,r=UZIP.F.deflateRaw(e,i,r,t.level);var o=UZIP.adler(e,0,e.length);return i[r+0]=o>>>24&255,i[r+1]=o>>>16&255,i[r+2]=o>>>8&255,i[r+3]=o>>>0&255,new Uint8Array(i.buffer,0,r+4)},UZIP.deflateRaw=function(e,t){null==t&&(t={level:6});var r=new Uint8Array(50+Math.floor(1.1*e.length)),i=UZIP.F.deflateRaw(e,r,i,t.level);return new Uint8Array(r.buffer,0,i)},UZIP.encode=function(e,t){null==t&&(t=false);var r=0,i=UZIP.bin.writeUint,o=UZIP.bin.writeUshort,a={};for(var s in e){var f=!UZIP._noNeed(s)&&!t,l=e[s],c=UZIP.crc.crc(l,0,l.length);a[s]={cpr:f,usize:l.length,crc:c,file:f?UZIP.deflateRaw(l):l};}for(var s in a)r+=a[s].file.length+30+46+2*UZIP.bin.sizeUTF8(s);r+=22;var u=new Uint8Array(r),h=0,d=[];for(var s in a){var A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,0);}var g=0,p=h;for(var s in a){A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,1,d[g++]);}var m=h-p;return i(u,h,101010256),h+=4,o(u,h+=4,g),o(u,h+=2,g),i(u,h+=2,m),i(u,h+=4,p),h+=4,h+=2,u.buffer},UZIP._noNeed=function(e){var t=e.split(".").pop().toLowerCase();return -1!="png,jpg,jpeg,zip".indexOf(t)},UZIP._writeHeader=function(e,t,r,i,o,a){var s=UZIP.bin.writeUint,f=UZIP.bin.writeUshort,l=i.file;return s(e,t,0==o?67324752:33639248),t+=4,1==o&&(t+=2),f(e,t,20),f(e,t+=2,0),f(e,t+=2,i.cpr?8:0),s(e,t+=2,0),s(e,t+=4,i.crc),s(e,t+=4,l.length),s(e,t+=4,i.usize),f(e,t+=4,UZIP.bin.sizeUTF8(r)),f(e,t+=2,0),t+=2,1==o&&(t+=2,t+=2,s(e,t+=6,a),t+=4),t+=UZIP.bin.writeUTF8(e,t,r),0==o&&(e.set(l,t),t+=l.length),t},UZIP.crc={table:function(){for(var e=new Uint32Array(256),t=0;t<256;t++){for(var r=t,i=0;i<8;i++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r;}return e}(),update:function(e,t,r,i){for(var o=0;o<i;o++)e=UZIP.crc.table[255&(e^t[r+o])]^e>>>8;return e},crc:function(e,t,r){return 4294967295^UZIP.crc.update(4294967295,e,t,r)}},UZIP.adler=function(e,t,r){for(var i=1,o=0,a=t,s=t+r;a<s;){for(var f=Math.min(a+5552,s);a<f;)o+=i+=e[a++];i%=65521,o%=65521;}return o<<16|i},UZIP.bin={readUshort:function(e,t){return e[t]|e[t+1]<<8},writeUshort:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255;},readUint:function(e,t){return 16777216*e[t+3]+(e[t+2]<<16|e[t+1]<<8|e[t])},writeUint:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255,e[t+2]=r>>16&255,e[t+3]=r>>24&255;},readASCII:function(e,t,r){for(var i="",o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII:function(e,t,r){for(var i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i);},pad:function(e){return e.length<2?"0"+e:e},readUTF8:function(e,t,r){for(var i,o="",a=0;a<r;a++)o+="%"+UZIP.bin.pad(e[t+a].toString(16));try{i=decodeURIComponent(o);}catch(i){return UZIP.bin.readASCII(e,t,r)}return i},writeUTF8:function(e,t,r){for(var i=r.length,o=0,a=0;a<i;a++){var s=r.charCodeAt(a);if(0==(4294967168&s))e[t+o]=s,o++;else if(0==(4294965248&s))e[t+o]=192|s>>6,e[t+o+1]=128|s>>0&63,o+=2;else if(0==(4294901760&s))e[t+o]=224|s>>12,e[t+o+1]=128|s>>6&63,e[t+o+2]=128|s>>0&63,o+=3;else {if(0!=(4292870144&s))throw "e";e[t+o]=240|s>>18,e[t+o+1]=128|s>>12&63,e[t+o+2]=128|s>>6&63,e[t+o+3]=128|s>>0&63,o+=4;}}return o},sizeUTF8:function(e){for(var t=e.length,r=0,i=0;i<t;i++){var o=e.charCodeAt(i);if(0==(4294967168&o))r++;else if(0==(4294965248&o))r+=2;else if(0==(4294901760&o))r+=3;else {if(0!=(4292870144&o))throw "e";r+=4;}}return r}},UZIP.F={},UZIP.F.deflateRaw=function(e,t,r,i){var o=[[0,0,0,0,0],[4,4,8,4,0],[4,5,16,8,0],[4,6,16,16,0],[4,10,16,32,0],[8,16,32,32,0],[8,16,128,128,0],[8,32,128,256,0],[32,128,258,1024,1],[32,258,258,4096,1]][i],a=UZIP.F.U,s=UZIP.F._goodIndex;var f=UZIP.F._putsE,l=0,c=r<<3,u=0,h=e.length;if(0==i){for(;l<h;){f(t,c,l+(_=Math.min(65535,h-l))==h?1:0),c=UZIP.F._copyExact(e,l,_,t,c+8),l+=_;}return c>>>3}var d=a.lits,A=a.strt,g=a.prev,p=0,m=0,w=0,v=0,b=0,y=0;for(h>2&&(A[y=UZIP.F._hash(e,0)]=0),l=0;l<h;l++){if(b=y,l+1<h-2){y=UZIP.F._hash(e,l+1);var E=l+1&32767;g[E]=A[y],A[y]=E;}if(u<=l){(p>14e3||m>26697)&&h-l>100&&(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(l==h-1||u==h?1:0,d,p,v,e,w,l-w,t,c),p=m=v=0,w=l);var F=0;l<h-2&&(F=UZIP.F._bestMatch(e,l,g,b,Math.min(o[2],h-l),o[3]));var _=F>>>16,B=65535&F;if(0!=F){B=65535&F;var U=s(_=F>>>16,a.of0);a.lhst[257+U]++;var C=s(B,a.df0);a.dhst[C]++,v+=a.exb[U]+a.dxb[C],d[p]=_<<23|l-u,d[p+1]=B<<16|U<<8|C,p+=2,u=l+_;}else a.lhst[e[l]]++;m++;}}for(w==l&&0!=e.length||(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(1,d,p,v,e,w,l-w,t,c),p=0,m=0,p=m=v=0,w=l);0!=(7&c);)c++;return c>>>3},UZIP.F._bestMatch=function(e,t,r,i,o,a){var s=32767&t,f=r[s],l=s-f+32768&32767;if(f==s||i!=UZIP.F._hash(e,t-l))return 0;for(var c=0,u=0,h=Math.min(32767,t);l<=h&&0!=--a&&f!=s;){if(0==c||e[t+c]==e[t+c-l]){var d=UZIP.F._howLong(e,t,l);if(d>c){if(u=l,(c=d)>=o)break;l+2<d&&(d=l+2);for(var A=0,g=0;g<d-2;g++){var p=t-l+g+32768&32767,m=p-r[p]+32768&32767;m>A&&(A=m,f=p);}}}l+=(s=f)-(f=r[s])+32768&32767;}return c<<16|u},UZIP.F._howLong=function(e,t,r){if(e[t]!=e[t-r]||e[t+1]!=e[t+1-r]||e[t+2]!=e[t+2-r])return 0;var i=t,o=Math.min(e.length,t+258);for(t+=3;t<o&&e[t]==e[t-r];)t++;return t-i},UZIP.F._hash=function(e,t){return (e[t]<<8|e[t+1])+(e[t+2]<<4)&65535},UZIP.saved=0,UZIP.F._writeBlock=function(e,t,r,i,o,a,s,f,l){var c,u,h,d,A,g,p,m,w,v=UZIP.F.U,b=UZIP.F._putsF,y=UZIP.F._putsE;v.lhst[256]++,u=(c=UZIP.F.getTrees())[0],h=c[1],d=c[2],A=c[3],g=c[4],p=c[5],m=c[6],w=c[7];var E=32+(0==(l+3&7)?0:8-(l+3&7))+(s<<3),F=i+UZIP.F.contSize(v.fltree,v.lhst)+UZIP.F.contSize(v.fdtree,v.dhst),_=i+UZIP.F.contSize(v.ltree,v.lhst)+UZIP.F.contSize(v.dtree,v.dhst);_+=14+3*p+UZIP.F.contSize(v.itree,v.ihst)+(2*v.ihst[16]+3*v.ihst[17]+7*v.ihst[18]);for(var B=0;B<286;B++)v.lhst[B]=0;for(B=0;B<30;B++)v.dhst[B]=0;for(B=0;B<19;B++)v.ihst[B]=0;var U=E<F&&E<_?0:F<_?1:2;if(b(f,l,e),b(f,l+1,U),l+=3,0==U){for(;0!=(7&l);)l++;l=UZIP.F._copyExact(o,a,s,f,l);}else {var C,I;if(1==U&&(C=v.fltree,I=v.fdtree),2==U){UZIP.F.makeCodes(v.ltree,u),UZIP.F.revCodes(v.ltree,u),UZIP.F.makeCodes(v.dtree,h),UZIP.F.revCodes(v.dtree,h),UZIP.F.makeCodes(v.itree,d),UZIP.F.revCodes(v.itree,d),C=v.ltree,I=v.dtree,y(f,l,A-257),y(f,l+=5,g-1),y(f,l+=5,p-4),l+=4;for(var Q=0;Q<p;Q++)y(f,l+3*Q,v.itree[1+(v.ordr[Q]<<1)]);l+=3*p,l=UZIP.F._codeTiny(m,v.itree,f,l),l=UZIP.F._codeTiny(w,v.itree,f,l);}for(var M=a,x=0;x<r;x+=2){for(var S=t[x],R=S>>>23,T=M+(8388607&S);M<T;)l=UZIP.F._writeLit(o[M++],C,f,l);if(0!=R){var O=t[x+1],P=O>>16,H=O>>8&255,L=255&O;y(f,l=UZIP.F._writeLit(257+H,C,f,l),R-v.of0[H]),l+=v.exb[H],b(f,l=UZIP.F._writeLit(L,I,f,l),P-v.df0[L]),l+=v.dxb[L],M+=R;}}l=UZIP.F._writeLit(256,C,f,l);}return l},UZIP.F._copyExact=function(e,t,r,i,o){var a=o>>>3;return i[a]=r,i[a+1]=r>>>8,i[a+2]=255-i[a],i[a+3]=255-i[a+1],a+=4,i.set(new Uint8Array(e.buffer,t,r),a),o+(r+4<<3)},UZIP.F.getTrees=function(){for(var e=UZIP.F.U,t=UZIP.F._hufTree(e.lhst,e.ltree,15),r=UZIP.F._hufTree(e.dhst,e.dtree,15),i=[],o=UZIP.F._lenCodes(e.ltree,i),a=[],s=UZIP.F._lenCodes(e.dtree,a),f=0;f<i.length;f+=2)e.ihst[i[f]]++;for(f=0;f<a.length;f+=2)e.ihst[a[f]]++;for(var l=UZIP.F._hufTree(e.ihst,e.itree,7),c=19;c>4&&0==e.itree[1+(e.ordr[c-1]<<1)];)c--;return [t,r,l,o,s,c,i,a]},UZIP.F.getSecond=function(e){for(var t=[],r=0;r<e.length;r+=2)t.push(e[r+1]);return t},UZIP.F.nonZero=function(e){for(var t="",r=0;r<e.length;r+=2)0!=e[r+1]&&(t+=(r>>1)+",");return t},UZIP.F.contSize=function(e,t){for(var r=0,i=0;i<t.length;i++)r+=t[i]*e[1+(i<<1)];return r},UZIP.F._codeTiny=function(e,t,r,i){for(var o=0;o<e.length;o+=2){var a=e[o],s=e[o+1];i=UZIP.F._writeLit(a,t,r,i);var f=16==a?2:17==a?3:7;a>15&&(UZIP.F._putsE(r,i,s,f),i+=f);}return i},UZIP.F._lenCodes=function(e,t){for(var r=e.length;2!=r&&0==e[r-1];)r-=2;for(var i=0;i<r;i+=2){var o=e[i+1],a=i+3<r?e[i+3]:-1,s=i+5<r?e[i+5]:-1,f=0==i?-1:e[i-1];if(0==o&&a==o&&s==o){for(var l=i+5;l+2<r&&e[l+2]==o;)l+=2;(c=Math.min(l+1-i>>>1,138))<11?t.push(17,c-3):t.push(18,c-11),i+=2*c-2;}else if(o==f&&a==o&&s==o){for(l=i+5;l+2<r&&e[l+2]==o;)l+=2;var c=Math.min(l+1-i>>>1,6);t.push(16,c-3),i+=2*c-2;}else t.push(o,0);}return r>>>1},UZIP.F._hufTree=function(e,t,r){var i=[],o=e.length,a=t.length,s=0;for(s=0;s<a;s+=2)t[s]=0,t[s+1]=0;for(s=0;s<o;s++)0!=e[s]&&i.push({lit:s,f:e[s]});var f=i.length,l=i.slice(0);if(0==f)return 0;if(1==f){var c=i[0].lit;l=0==c?1:0;return t[1+(c<<1)]=1,t[1+(l<<1)]=1,1}i.sort((function(e,t){return e.f-t.f}));var u=i[0],h=i[1],d=0,A=1,g=2;for(i[0]={lit:-1,f:u.f+h.f,l:u,r:h,d:0};A!=f-1;)u=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],h=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],i[A++]={lit:-1,f:u.f+h.f,l:u,r:h};var p=UZIP.F.setDepth(i[A-1],0);for(p>r&&(UZIP.F.restrictDepth(l,r,p),p=r),s=0;s<f;s++)t[1+(l[s].lit<<1)]=l[s].d;return p},UZIP.F.setDepth=function(e,t){return -1!=e.lit?(e.d=t,t):Math.max(UZIP.F.setDepth(e.l,t+1),UZIP.F.setDepth(e.r,t+1))},UZIP.F.restrictDepth=function(e,t,r){var i=0,o=1<<r-t,a=0;for(e.sort((function(e,t){return t.d==e.d?e.f-t.f:t.d-e.d})),i=0;i<e.length&&e[i].d>t;i++){var s=e[i].d;e[i].d=t,a+=o-(1<<r-s);}for(a>>>=r-t;a>0;){(s=e[i].d)<t?(e[i].d++,a-=1<<t-s-1):i++;}for(;i>=0;i--)e[i].d==t&&a<0&&(e[i].d--,a++);0!=a&&console.log("debt left");},UZIP.F._goodIndex=function(e,t){var r=0;return t[16|r]<=e&&(r|=16),t[8|r]<=e&&(r|=8),t[4|r]<=e&&(r|=4),t[2|r]<=e&&(r|=2),t[1|r]<=e&&(r|=1),r},UZIP.F._writeLit=function(e,t,r,i){return UZIP.F._putsF(r,i,t[e<<1]),i+t[1+(e<<1)]},UZIP.F.inflate=function(e,t){var r=Uint8Array;if(3==e[0]&&0==e[1])return t||new r(0);var i=UZIP.F,o=i._bitsF,a=i._bitsE,s=i._decodeTiny,f=i.makeCodes,l=i.codes2map,c=i._get17,u=i.U,h=null==t;h&&(t=new r(e.length>>>2<<3));for(var d,A,g=0,p=0,m=0,w=0,v=0,b=0,y=0,E=0,F=0;0==g;)if(g=o(e,F,1),p=o(e,F+1,2),F+=3,0!=p){if(h&&(t=UZIP.F._check(t,E+(1<<17))),1==p&&(d=u.flmap,A=u.fdmap,b=511,y=31),2==p){m=a(e,F,5)+257,w=a(e,F+5,5)+1,v=a(e,F+10,4)+4,F+=14;for(var _=0;_<38;_+=2)u.itree[_]=0,u.itree[_+1]=0;var B=1;for(_=0;_<v;_++){var U=a(e,F+3*_,3);u.itree[1+(u.ordr[_]<<1)]=U,U>B&&(B=U);}F+=3*v,f(u.itree,B),l(u.itree,B,u.imap),d=u.lmap,A=u.dmap,F=s(u.imap,(1<<B)-1,m+w,e,F,u.ttree);var C=i._copyOut(u.ttree,0,m,u.ltree);b=(1<<C)-1;var I=i._copyOut(u.ttree,m,w,u.dtree);y=(1<<I)-1,f(u.ltree,C),l(u.ltree,C,d),f(u.dtree,I),l(u.dtree,I,A);}for(;;){var Q=d[c(e,F)&b];F+=15&Q;var M=Q>>>4;if(M>>>8==0)t[E++]=M;else {if(256==M)break;var x=E+M-254;if(M>264){var S=u.ldef[M-257];x=E+(S>>>3)+a(e,F,7&S),F+=7&S;}var R=A[c(e,F)&y];F+=15&R;var T=R>>>4,O=u.ddef[T],P=(O>>>4)+o(e,F,15&O);for(F+=15&O,h&&(t=UZIP.F._check(t,E+(1<<17)));E<x;)t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P];E=x;}}}else {0!=(7&F)&&(F+=8-(7&F));var H=4+(F>>>3),L=e[H-4]|e[H-3]<<8;h&&(t=UZIP.F._check(t,E+L)),t.set(new r(e.buffer,e.byteOffset+H,L),E),F=H+L<<3,E+=L;}return t.length==E?t:t.slice(0,E)},UZIP.F._check=function(e,t){var r=e.length;if(t<=r)return e;var i=new Uint8Array(Math.max(r<<1,t));return i.set(e,0),i},UZIP.F._decodeTiny=function(e,t,r,i,o,a){for(var s=UZIP.F._bitsE,f=UZIP.F._get17,l=0;l<r;){var c=e[f(i,o)&t];o+=15&c;var u=c>>>4;if(u<=15)a[l]=u,l++;else {var h=0,d=0;16==u?(d=3+s(i,o,2),o+=2,h=a[l-1]):17==u?(d=3+s(i,o,3),o+=3):18==u&&(d=11+s(i,o,7),o+=7);for(var A=l+d;l<A;)a[l]=h,l++;}}return o},UZIP.F._copyOut=function(e,t,r,i){for(var o=0,a=0,s=i.length>>>1;a<r;){var f=e[a+t];i[a<<1]=0,i[1+(a<<1)]=f,f>o&&(o=f),a++;}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},UZIP.F.makeCodes=function(e,t){for(var r,i,o,a,s=UZIP.F.U,f=e.length,l=s.bl_count,c=0;c<=t;c++)l[c]=0;for(c=1;c<f;c+=2)l[e[c]]++;var u=s.next_code;for(r=0,l[0]=0,i=1;i<=t;i++)r=r+l[i-1]<<1,u[i]=r;for(o=0;o<f;o+=2)0!=(a=e[o+1])&&(e[o]=u[a],u[a]++);},UZIP.F.codes2map=function(e,t,r){for(var i=e.length,o=UZIP.F.U.rev15,a=0;a<i;a+=2)if(0!=e[a+1])for(var s=a>>1,f=e[a+1],l=s<<4|f,c=t-f,u=e[a]<<c,h=u+(1<<c);u!=h;){r[o[u]>>>15-t]=l,u++;}},UZIP.F.revCodes=function(e,t){for(var r=UZIP.F.U.rev15,i=15-t,o=0;o<e.length;o+=2){var a=e[o]<<t-e[o+1];e[o]=r[a]>>>i;}},UZIP.F._putsE=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8;},UZIP.F._putsF=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16;},UZIP.F._bitsE=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},UZIP.F._bitsF=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},UZIP.F._get17=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},UZIP.F._get25=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},UZIP.F.U=(r=Uint16Array,i=Uint32Array,{next_code:new r(16),bl_count:new r(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new r(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new i(32),flmap:new r(512),fltree:[],fdmap:new r(32),fdtree:[],lmap:new r(32768),ltree:[],ttree:[],dmap:new r(32768),dtree:[],imap:new r(512),itree:[],rev15:new r(32768),lhst:new i(286),dhst:new i(30),ihst:new i(19),lits:new i(15e3),strt:new r(65536),prev:new r(32768)}),function(){for(var e=UZIP.F.U,t=0;t<32768;t++){var r=t;r=(4278255360&(r=(4042322160&(r=(3435973836&(r=(2863311530&r)>>>1|(1431655765&r)<<1))>>>2|(858993459&r)<<2))>>>4|(252645135&r)<<4))>>>8|(16711935&r)<<8,e.rev15[t]=(r>>>16|r<<16)>>>17;}function pushV(e,t,r){for(;0!=t--;)e.push(0,r);}for(t=0;t<32;t++)e.ldef[t]=e.of0[t]<<3|e.exb[t],e.ddef[t]=e.df0[t]<<4|e.dxb[t];pushV(e.fltree,144,8),pushV(e.fltree,112,9),pushV(e.fltree,24,7),pushV(e.fltree,8,8),UZIP.F.makeCodes(e.fltree,9),UZIP.F.codes2map(e.fltree,9,e.flmap),UZIP.F.revCodes(e.fltree,9),pushV(e.fdtree,32,5),UZIP.F.makeCodes(e.fdtree,5),UZIP.F.codes2map(e.fdtree,5,e.fdmap),UZIP.F.revCodes(e.fdtree,5),pushV(e.itree,19,0),pushV(e.ltree,286,0),pushV(e.dtree,30,0),pushV(e.ttree,320,0);}();}();var UZIP=_mergeNamespaces$1({__proto__:null,default:e},[e]);const UPNG=function(){var e={nextZero(e,t){for(;0!=e[t];)t++;return t},readUshort:(e,t)=>e[t]<<8|e[t+1],writeUshort(e,t,r){e[t]=r>>8&255,e[t+1]=255&r;},readUint:(e,t)=>16777216*e[t]+(e[t+1]<<16|e[t+2]<<8|e[t+3]),writeUint(e,t,r){e[t]=r>>24&255,e[t+1]=r>>16&255,e[t+2]=r>>8&255,e[t+3]=255&r;},readASCII(e,t,r){let i="";for(let o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII(e,t,r){for(let i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i);},readBytes(e,t,r){const i=[];for(let o=0;o<r;o++)i.push(e[t+o]);return i},pad:e=>e.length<2?`0${e}`:e,readUTF8(t,r,i){let o,a="";for(let o=0;o<i;o++)a+=`%${e.pad(t[r+o].toString(16))}`;try{o=decodeURIComponent(a);}catch(o){return e.readASCII(t,r,i)}return o}};function decodeImage(t,r,i,o){const a=r*i,s=_getBPP(o),f=Math.ceil(r*s/8),l=new Uint8Array(4*a),c=new Uint32Array(l.buffer),{ctype:u}=o,{depth:h}=o,d=e.readUshort;if(6==u){const e=a<<2;if(8==h)for(var A=0;A<e;A+=4)l[A]=t[A],l[A+1]=t[A+1],l[A+2]=t[A+2],l[A+3]=t[A+3];if(16==h)for(A=0;A<e;A++)l[A]=t[A<<1];}else if(2==u){const e=o.tabs.tRNS;if(null==e){if(8==h)for(A=0;A<a;A++){var g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g];}if(16==h)for(A=0;A<a;A++){g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g];}}else {var p=e[0];const r=e[1],i=e[2];if(8==h)for(A=0;A<a;A++){var m=A<<2;g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g],t[g]==p&&t[g+1]==r&&t[g+2]==i&&(l[m+3]=0);}if(16==h)for(A=0;A<a;A++){m=A<<2,g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g],d(t,g)==p&&d(t,g+2)==r&&d(t,g+4)==i&&(l[m+3]=0);}}}else if(3==u){const e=o.tabs.PLTE,s=o.tabs.tRNS,c=s?s.length:0;if(1==h)for(var w=0;w<i;w++){var v=w*f,b=w*r;for(A=0;A<r;A++){m=b+A<<2;var y=3*(E=t[v+(A>>3)]>>7-((7&A)<<0)&1);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}}if(2==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>2)]>>6-((3&A)<<1)&3);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}if(4==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>1)]>>4-((1&A)<<2)&15);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}if(8==h)for(A=0;A<a;A++){var E;m=A<<2,y=3*(E=t[A]);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}}else if(4==u){if(8==h)for(A=0;A<a;A++){m=A<<2;var F=t[_=A<<1];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+1];}if(16==h)for(A=0;A<a;A++){var _;m=A<<2,F=t[_=A<<2];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+2];}}else if(0==u)for(p=o.tabs.tRNS?o.tabs.tRNS:-1,w=0;w<i;w++){const e=w*f,i=w*r;if(1==h)for(var B=0;B<r;B++){var U=(F=255*(t[e+(B>>>3)]>>>7-(7&B)&1))==255*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(2==h)for(B=0;B<r;B++){U=(F=85*(t[e+(B>>>2)]>>>6-((3&B)<<1)&3))==85*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(4==h)for(B=0;B<r;B++){U=(F=17*(t[e+(B>>>1)]>>>4-((1&B)<<2)&15))==17*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(8==h)for(B=0;B<r;B++){U=(F=t[e+B])==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(16==h)for(B=0;B<r;B++){F=t[e+(B<<1)],U=d(t,e+(B<<1))==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}}return l}function _decompress(e,r,i,o){const a=_getBPP(e),s=Math.ceil(i*a/8),f=new Uint8Array((s+1+e.interlace)*o);return r=e.tabs.CgBI?t(r,f):_inflate(r,f),0==e.interlace?r=_filterZero(r,e,0,i,o):1==e.interlace&&(r=function _readInterlace(e,t){const r=t.width,i=t.height,o=_getBPP(t),a=o>>3,s=Math.ceil(r*o/8),f=new Uint8Array(i*s);let l=0;const c=[0,0,4,0,2,0,1],u=[0,4,0,2,0,1,0],h=[8,8,8,4,4,2,2],d=[8,8,4,4,2,2,1];let A=0;for(;A<7;){const p=h[A],m=d[A];let w=0,v=0,b=c[A];for(;b<i;)b+=p,v++;let y=u[A];for(;y<r;)y+=m,w++;const E=Math.ceil(w*o/8);_filterZero(e,t,l,w,v);let F=0,_=c[A];for(;_<i;){let t=u[A],i=l+F*E<<3;for(;t<r;){var g;if(1==o)g=(g=e[i>>3])>>7-(7&i)&1,f[_*s+(t>>3)]|=g<<7-((7&t)<<0);if(2==o)g=(g=e[i>>3])>>6-(7&i)&3,f[_*s+(t>>2)]|=g<<6-((3&t)<<1);if(4==o)g=(g=e[i>>3])>>4-(7&i)&15,f[_*s+(t>>1)]|=g<<4-((1&t)<<2);if(o>=8){const r=_*s+t*a;for(let t=0;t<a;t++)f[r+t]=e[(i>>3)+t];}i+=o,t+=m;}F++,_+=p;}w*v!=0&&(l+=v*(1+E)),A+=1;}return f}(r,e)),r}function _inflate(e,r){return t(new Uint8Array(e.buffer,2,e.length-6),r)}var t=function(){const e={H:{}};return e.H.N=function(t,r){const i=Uint8Array;let o,a,s=0,f=0,l=0,c=0,u=0,h=0,d=0,A=0,g=0;if(3==t[0]&&0==t[1])return r||new i(0);const p=e.H,m=p.b,w=p.e,v=p.R,b=p.n,y=p.A,E=p.Z,F=p.m,_=null==r;for(_&&(r=new i(t.length>>>2<<5));0==s;)if(s=m(t,g,1),f=m(t,g+1,2),g+=3,0!=f){if(_&&(r=e.H.W(r,A+(1<<17))),1==f&&(o=F.J,a=F.h,h=511,d=31),2==f){l=w(t,g,5)+257,c=w(t,g+5,5)+1,u=w(t,g+10,4)+4,g+=14;let e=1;for(var B=0;B<38;B+=2)F.Q[B]=0,F.Q[B+1]=0;for(B=0;B<u;B++){const r=w(t,g+3*B,3);F.Q[1+(F.X[B]<<1)]=r,r>e&&(e=r);}g+=3*u,b(F.Q,e),y(F.Q,e,F.u),o=F.w,a=F.d,g=v(F.u,(1<<e)-1,l+c,t,g,F.v);const r=p.V(F.v,0,l,F.C);h=(1<<r)-1;const i=p.V(F.v,l,c,F.D);d=(1<<i)-1,b(F.C,r),y(F.C,r,o),b(F.D,i),y(F.D,i,a);}for(;;){const e=o[E(t,g)&h];g+=15&e;const i=e>>>4;if(i>>>8==0)r[A++]=i;else {if(256==i)break;{let e=A+i-254;if(i>264){const r=F.q[i-257];e=A+(r>>>3)+w(t,g,7&r),g+=7&r;}const o=a[E(t,g)&d];g+=15&o;const s=o>>>4,f=F.c[s],l=(f>>>4)+m(t,g,15&f);for(g+=15&f;A<e;)r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l];A=e;}}}}else {0!=(7&g)&&(g+=8-(7&g));const o=4+(g>>>3),a=t[o-4]|t[o-3]<<8;_&&(r=e.H.W(r,A+a)),r.set(new i(t.buffer,t.byteOffset+o,a),A),g=o+a<<3,A+=a;}return r.length==A?r:r.slice(0,A)},e.H.W=function(e,t){const r=e.length;if(t<=r)return e;const i=new Uint8Array(r<<1);return i.set(e,0),i},e.H.R=function(t,r,i,o,a,s){const f=e.H.e,l=e.H.Z;let c=0;for(;c<i;){const e=t[l(o,a)&r];a+=15&e;const i=e>>>4;if(i<=15)s[c]=i,c++;else {let e=0,t=0;16==i?(t=3+f(o,a,2),a+=2,e=s[c-1]):17==i?(t=3+f(o,a,3),a+=3):18==i&&(t=11+f(o,a,7),a+=7);const r=c+t;for(;c<r;)s[c]=e,c++;}}return a},e.H.V=function(e,t,r,i){let o=0,a=0;const s=i.length>>>1;for(;a<r;){const r=e[a+t];i[a<<1]=0,i[1+(a<<1)]=r,r>o&&(o=r),a++;}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},e.H.n=function(t,r){const i=e.H.m,o=t.length;let a,s,f;let l;const c=i.j;for(var u=0;u<=r;u++)c[u]=0;for(u=1;u<o;u+=2)c[t[u]]++;const h=i.K;for(a=0,c[0]=0,s=1;s<=r;s++)a=a+c[s-1]<<1,h[s]=a;for(f=0;f<o;f+=2)l=t[f+1],0!=l&&(t[f]=h[l],h[l]++);},e.H.A=function(t,r,i){const o=t.length,a=e.H.m.r;for(let e=0;e<o;e+=2)if(0!=t[e+1]){const o=e>>1,s=t[e+1],f=o<<4|s,l=r-s;let c=t[e]<<l;const u=c+(1<<l);for(;c!=u;){i[a[c]>>>15-r]=f,c++;}}},e.H.l=function(t,r){const i=e.H.m.r,o=15-r;for(let e=0;e<t.length;e+=2){const a=t[e]<<r-t[e+1];t[e]=i[a]>>>o;}},e.H.M=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8;},e.H.I=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16;},e.H.e=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},e.H.b=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},e.H.Z=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},e.H.i=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},e.H.m=function(){const e=Uint16Array,t=Uint32Array;return {K:new e(16),j:new e(16),X:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],S:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],T:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],q:new e(32),p:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],z:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],c:new t(32),J:new e(512),_:[],h:new e(32),$:[],w:new e(32768),C:[],v:[],d:new e(32768),D:[],u:new e(512),Q:[],r:new e(32768),s:new t(286),Y:new t(30),a:new t(19),t:new t(15e3),k:new e(65536),g:new e(32768)}}(),function(){const t=e.H.m;for(var r=0;r<32768;r++){let e=r;e=(2863311530&e)>>>1|(1431655765&e)<<1,e=(3435973836&e)>>>2|(858993459&e)<<2,e=(4042322160&e)>>>4|(252645135&e)<<4,e=(4278255360&e)>>>8|(16711935&e)<<8,t.r[r]=(e>>>16|e<<16)>>>17;}function n(e,t,r){for(;0!=t--;)e.push(0,r);}for(r=0;r<32;r++)t.q[r]=t.S[r]<<3|t.T[r],t.c[r]=t.p[r]<<4|t.z[r];n(t._,144,8),n(t._,112,9),n(t._,24,7),n(t._,8,8),e.H.n(t._,9),e.H.A(t._,9,t.J),e.H.l(t._,9),n(t.$,32,5),e.H.n(t.$,5),e.H.A(t.$,5,t.h),e.H.l(t.$,5),n(t.Q,19,0),n(t.C,286,0),n(t.D,30,0),n(t.v,320,0);}(),e.H.N}();function _getBPP(e){return [1,null,3,1,2,null,4][e.ctype]*e.depth}function _filterZero(e,t,r,i,o){let a=_getBPP(t);const s=Math.ceil(i*a/8);let f,l;a=Math.ceil(a/8);let c=e[r],u=0;if(c>1&&(e[r]=[0,0,1][c-2]),3==c)for(u=a;u<s;u++)e[u+1]=e[u+1]+(e[u+1-a]>>>1)&255;for(let t=0;t<o;t++)if(f=r+t*s,l=f+t+1,c=e[l-1],u=0,0==c)for(;u<s;u++)e[f+u]=e[l+u];else if(1==c){for(;u<a;u++)e[f+u]=e[l+u];for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-a];}else if(2==c)for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-s];else if(3==c){for(;u<a;u++)e[f+u]=e[l+u]+(e[f+u-s]>>>1);for(;u<s;u++)e[f+u]=e[l+u]+(e[f+u-s]+e[f+u-a]>>>1);}else {for(;u<a;u++)e[f+u]=e[l+u]+_paeth(0,e[f+u-s],0);for(;u<s;u++)e[f+u]=e[l+u]+_paeth(e[f+u-a],e[f+u-s],e[f+u-a-s]);}return e}function _paeth(e,t,r){const i=e+t-r,o=i-e,a=i-t,s=i-r;return o*o<=a*a&&o*o<=s*s?e:a*a<=s*s?t:r}function _IHDR(t,r,i){i.width=e.readUint(t,r),r+=4,i.height=e.readUint(t,r),r+=4,i.depth=t[r],r++,i.ctype=t[r],r++,i.compress=t[r],r++,i.filter=t[r],r++,i.interlace=t[r],r++;}function _copyTile(e,t,r,i,o,a,s,f,l){const c=Math.min(t,o),u=Math.min(r,a);let h=0,d=0;for(let r=0;r<u;r++)for(let a=0;a<c;a++)if(s>=0&&f>=0?(h=r*t+a<<2,d=(f+r)*o+s+a<<2):(h=(-f+r)*t-s+a<<2,d=r*o+a<<2),0==l)i[d]=e[h],i[d+1]=e[h+1],i[d+2]=e[h+2],i[d+3]=e[h+3];else if(1==l){var A=e[h+3]*(1/255),g=e[h]*A,p=e[h+1]*A,m=e[h+2]*A,w=i[d+3]*(1/255),v=i[d]*w,b=i[d+1]*w,y=i[d+2]*w;const t=1-A,r=A+w*t,o=0==r?0:1/r;i[d+3]=255*r,i[d+0]=(g+v*t)*o,i[d+1]=(p+b*t)*o,i[d+2]=(m+y*t)*o;}else if(2==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];A==w&&g==v&&p==b&&m==y?(i[d]=0,i[d+1]=0,i[d+2]=0,i[d+3]=0):(i[d]=g,i[d+1]=p,i[d+2]=m,i[d+3]=A);}else if(3==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];if(A==w&&g==v&&p==b&&m==y)continue;if(A<220&&w>20)return false}return true}return {decode:function decode(r){const i=new Uint8Array(r);let o=8;const a=e,s=a.readUshort,f=a.readUint,l={tabs:{},frames:[]},c=new Uint8Array(i.length);let u,h=0,d=0;const A=[137,80,78,71,13,10,26,10];for(var g=0;g<8;g++)if(i[g]!=A[g])throw "The input is not a PNG file!";for(;o<i.length;){const e=a.readUint(i,o);o+=4;const r=a.readASCII(i,o,4);if(o+=4,"IHDR"==r)_IHDR(i,o,l);else if("iCCP"==r){for(var p=o;0!=i[p];)p++;a.readASCII(i,o,p-o);const s=i.slice(p+2,o+e);let f=null;try{f=_inflate(s);}catch(e){f=t(s);}l.tabs[r]=f;}else if("CgBI"==r)l.tabs[r]=i.slice(o,o+4);else if("IDAT"==r){for(g=0;g<e;g++)c[h+g]=i[o+g];h+=e;}else if("acTL"==r)l.tabs[r]={num_frames:f(i,o),num_plays:f(i,o+4)},u=new Uint8Array(i.length);else if("fcTL"==r){if(0!=d)(E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height),d=0;const e={x:f(i,o+12),y:f(i,o+16),width:f(i,o+4),height:f(i,o+8)};let t=s(i,o+22);t=s(i,o+20)/(0==t?100:t);const r={rect:e,delay:Math.round(1e3*t),dispose:i[o+24],blend:i[o+25]};l.frames.push(r);}else if("fdAT"==r){for(g=0;g<e-4;g++)u[d+g]=i[o+g+4];d+=e-4;}else if("pHYs"==r)l.tabs[r]=[a.readUint(i,o),a.readUint(i,o+4),i[o+8]];else if("cHRM"==r){l.tabs[r]=[];for(g=0;g<8;g++)l.tabs[r].push(a.readUint(i,o+4*g));}else if("tEXt"==r||"zTXt"==r){null==l.tabs[r]&&(l.tabs[r]={});var m=a.nextZero(i,o),w=a.readASCII(i,o,m-o),v=o+e-m-1;if("tEXt"==r)y=a.readASCII(i,m+1,v);else {var b=_inflate(i.slice(m+2,m+2+v));y=a.readUTF8(b,0,b.length);}l.tabs[r][w]=y;}else if("iTXt"==r){null==l.tabs[r]&&(l.tabs[r]={});m=0,p=o;m=a.nextZero(i,p);w=a.readASCII(i,p,m-p);const t=i[p=m+1];var y;p+=2,m=a.nextZero(i,p),a.readASCII(i,p,m-p),p=m+1,m=a.nextZero(i,p),a.readUTF8(i,p,m-p);v=e-((p=m+1)-o);if(0==t)y=a.readUTF8(i,p,v);else {b=_inflate(i.slice(p,p+v));y=a.readUTF8(b,0,b.length);}l.tabs[r][w]=y;}else if("PLTE"==r)l.tabs[r]=a.readBytes(i,o,e);else if("hIST"==r){const e=l.tabs.PLTE.length/3;l.tabs[r]=[];for(g=0;g<e;g++)l.tabs[r].push(s(i,o+2*g));}else if("tRNS"==r)3==l.ctype?l.tabs[r]=a.readBytes(i,o,e):0==l.ctype?l.tabs[r]=s(i,o):2==l.ctype&&(l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]);else if("gAMA"==r)l.tabs[r]=a.readUint(i,o)/1e5;else if("sRGB"==r)l.tabs[r]=i[o];else if("bKGD"==r)0==l.ctype||4==l.ctype?l.tabs[r]=[s(i,o)]:2==l.ctype||6==l.ctype?l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]:3==l.ctype&&(l.tabs[r]=i[o]);else if("IEND"==r)break;o+=e,a.readUint(i,o),o+=4;}var E;return 0!=d&&((E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height)),l.data=_decompress(l,c,l.width,l.height),delete l.compress,delete l.interlace,delete l.filter,l},toRGBA8:function toRGBA8(e){const t=e.width,r=e.height;if(null==e.tabs.acTL)return [decodeImage(e.data,t,r,e).buffer];const i=[];null==e.frames[0].data&&(e.frames[0].data=e.data);const o=t*r*4,a=new Uint8Array(o),s=new Uint8Array(o),f=new Uint8Array(o);for(let c=0;c<e.frames.length;c++){const u=e.frames[c],h=u.rect.x,d=u.rect.y,A=u.rect.width,g=u.rect.height,p=decodeImage(u.data,A,g,e);if(0!=c)for(var l=0;l<o;l++)f[l]=a[l];if(0==u.blend?_copyTile(p,A,g,a,t,r,h,d,0):1==u.blend&&_copyTile(p,A,g,a,t,r,h,d,1),i.push(a.buffer.slice(0)),0==u.dispose);else if(1==u.dispose)_copyTile(s,A,g,a,t,r,h,d,0);else if(2==u.dispose)for(l=0;l<o;l++)a[l]=f[l];}return i},_paeth:_paeth,_copyTile:_copyTile,_bin:e}}();!function(){const{_copyTile:e}=UPNG,{_bin:t}=UPNG,r=UPNG._paeth;var i={table:function(){const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r;}return e}(),update(e,t,r,o){for(let a=0;a<o;a++)e=i.table[255&(e^t[r+a])]^e>>>8;return e},crc:(e,t,r)=>4294967295^i.update(4294967295,e,t,r)};function addErr(e,t,r,i){t[r]+=e[0]*i>>4,t[r+1]+=e[1]*i>>4,t[r+2]+=e[2]*i>>4,t[r+3]+=e[3]*i>>4;}function N(e){return Math.max(0,Math.min(255,e))}function D(e,t){const r=e[0]-t[0],i=e[1]-t[1],o=e[2]-t[2],a=e[3]-t[3];return r*r+i*i+o*o+a*a}function dither(e,t,r,i,o,a,s){null==s&&(s=1);const f=i.length,l=[];for(var c=0;c<f;c++){const e=i[c];l.push([e>>>0&255,e>>>8&255,e>>>16&255,e>>>24&255]);}for(c=0;c<f;c++){let e=4294967295;for(var u=0,h=0;h<f;h++){var d=D(l[c],l[h]);h!=c&&d<e&&(e=d,u=h);}}const A=new Uint32Array(o.buffer),g=new Int16Array(t*r*4),p=[0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5];for(c=0;c<p.length;c++)p[c]=255*((p[c]+.5)/16-.5);for(let o=0;o<r;o++)for(let w=0;w<t;w++){var m;c=4*(o*t+w);if(2!=s)m=[N(e[c]+g[c]),N(e[c+1]+g[c+1]),N(e[c+2]+g[c+2]),N(e[c+3]+g[c+3])];else {d=p[4*(3&o)+(3&w)];m=[N(e[c]+d),N(e[c+1]+d),N(e[c+2]+d),N(e[c+3]+d)];}u=0;let v=16777215;for(h=0;h<f;h++){const e=D(m,l[h]);e<v&&(v=e,u=h);}const b=l[u],y=[m[0]-b[0],m[1]-b[1],m[2]-b[2],m[3]-b[3]];1==s&&(w!=t-1&&addErr(y,g,c+4,7),o!=r-1&&(0!=w&&addErr(y,g,c+4*t-4,3),addErr(y,g,c+4*t,5),w!=t-1&&addErr(y,g,c+4*t+4,1))),a[c>>2]=u,A[c>>2]=i[u];}}function _main(e,r,o,a,s){null==s&&(s={});const{crc:f}=i,l=t.writeUint,c=t.writeUshort,u=t.writeASCII;let h=8;const d=e.frames.length>1;let A,g=false,p=33+(d?20:0);if(null!=s.sRGB&&(p+=13),null!=s.pHYs&&(p+=21),null!=s.iCCP&&(A=pako.deflate(s.iCCP),p+=21+A.length+4),3==e.ctype){for(var m=e.plte.length,w=0;w<m;w++)e.plte[w]>>>24!=255&&(g=true);p+=8+3*m+4+(g?8+1*m+4:0);}for(var v=0;v<e.frames.length;v++){d&&(p+=38),p+=(F=e.frames[v]).cimg.length+12,0!=v&&(p+=4);}p+=12;const b=new Uint8Array(p),y=[137,80,78,71,13,10,26,10];for(w=0;w<8;w++)b[w]=y[w];if(l(b,h,13),h+=4,u(b,h,"IHDR"),h+=4,l(b,h,r),h+=4,l(b,h,o),h+=4,b[h]=e.depth,h++,b[h]=e.ctype,h++,b[h]=0,h++,b[h]=0,h++,b[h]=0,h++,l(b,h,f(b,h-17,17)),h+=4,null!=s.sRGB&&(l(b,h,1),h+=4,u(b,h,"sRGB"),h+=4,b[h]=s.sRGB,h++,l(b,h,f(b,h-5,5)),h+=4),null!=s.iCCP){const e=13+A.length;l(b,h,e),h+=4,u(b,h,"iCCP"),h+=4,u(b,h,"ICC profile"),h+=11,h+=2,b.set(A,h),h+=A.length,l(b,h,f(b,h-(e+4),e+4)),h+=4;}if(null!=s.pHYs&&(l(b,h,9),h+=4,u(b,h,"pHYs"),h+=4,l(b,h,s.pHYs[0]),h+=4,l(b,h,s.pHYs[1]),h+=4,b[h]=s.pHYs[2],h++,l(b,h,f(b,h-13,13)),h+=4),d&&(l(b,h,8),h+=4,u(b,h,"acTL"),h+=4,l(b,h,e.frames.length),h+=4,l(b,h,null!=s.loop?s.loop:0),h+=4,l(b,h,f(b,h-12,12)),h+=4),3==e.ctype){l(b,h,3*(m=e.plte.length)),h+=4,u(b,h,"PLTE"),h+=4;for(w=0;w<m;w++){const t=3*w,r=e.plte[w],i=255&r,o=r>>>8&255,a=r>>>16&255;b[h+t+0]=i,b[h+t+1]=o,b[h+t+2]=a;}if(h+=3*m,l(b,h,f(b,h-3*m-4,3*m+4)),h+=4,g){l(b,h,m),h+=4,u(b,h,"tRNS"),h+=4;for(w=0;w<m;w++)b[h+w]=e.plte[w]>>>24&255;h+=m,l(b,h,f(b,h-m-4,m+4)),h+=4;}}let E=0;for(v=0;v<e.frames.length;v++){var F=e.frames[v];d&&(l(b,h,26),h+=4,u(b,h,"fcTL"),h+=4,l(b,h,E++),h+=4,l(b,h,F.rect.width),h+=4,l(b,h,F.rect.height),h+=4,l(b,h,F.rect.x),h+=4,l(b,h,F.rect.y),h+=4,c(b,h,a[v]),h+=2,c(b,h,1e3),h+=2,b[h]=F.dispose,h++,b[h]=F.blend,h++,l(b,h,f(b,h-30,30)),h+=4);const t=F.cimg;l(b,h,(m=t.length)+(0==v?0:4)),h+=4;const r=h;u(b,h,0==v?"IDAT":"fdAT"),h+=4,0!=v&&(l(b,h,E++),h+=4),b.set(t,h),h+=m,l(b,h,f(b,r,h-r)),h+=4;}return l(b,h,0),h+=4,u(b,h,"IEND"),h+=4,l(b,h,f(b,h-4,4)),h+=4,b.buffer}function compressPNG(e,t,r){for(let i=0;i<e.frames.length;i++){const o=e.frames[i];const a=o.rect.height,s=new Uint8Array(a*o.bpl+a);o.cimg=_filterZero(o.img,a,o.bpp,o.bpl,s,t,r);}}function compress(t,r,i,o,a){const s=a[0],f=a[1],l=a[2],c=a[3],u=a[4],h=a[5];let d=6,A=8,g=255;for(var p=0;p<t.length;p++){const e=new Uint8Array(t[p]);for(var m=e.length,w=0;w<m;w+=4)g&=e[w+3];}const v=255!=g,b=function framize(t,r,i,o,a,s){const f=[];for(var l=0;l<t.length;l++){const h=new Uint8Array(t[l]),A=new Uint32Array(h.buffer);var c;let g=0,p=0,m=r,w=i,v=o?1:0;if(0!=l){const b=s||o||1==l||0!=f[l-2].dispose?1:2;let y=0,E=1e9;for(let e=0;e<b;e++){var u=new Uint8Array(t[l-1-e]);const o=new Uint32Array(t[l-1-e]);let s=r,f=i,c=-1,h=-1;for(let e=0;e<i;e++)for(let t=0;t<r;t++){A[d=e*r+t]!=o[d]&&(t<s&&(s=t),t>c&&(c=t),e<f&&(f=e),e>h&&(h=e));} -1==c&&(s=f=c=h=0),a&&(1==(1&s)&&s--,1==(1&f)&&f--);const v=(c-s+1)*(h-f+1);v<E&&(E=v,y=e,g=s,p=f,m=c-s+1,w=h-f+1);}u=new Uint8Array(t[l-1-y]);1==y&&(f[l-1].dispose=2),c=new Uint8Array(m*w*4),e(u,r,i,c,m,w,-g,-p,0),v=e(h,r,i,c,m,w,-g,-p,3)?1:0,1==v?_prepareDiff(h,r,i,c,{x:g,y:p,width:m,height:w}):e(h,r,i,c,m,w,-g,-p,0);}else c=h.slice(0);f.push({rect:{x:g,y:p,width:m,height:w},img:c,blend:v,dispose:0});}if(o)for(l=0;l<f.length;l++){if(1==(A=f[l]).blend)continue;const e=A.rect,o=f[l-1].rect,s=Math.min(e.x,o.x),c=Math.min(e.y,o.y),u={x:s,y:c,width:Math.max(e.x+e.width,o.x+o.width)-s,height:Math.max(e.y+e.height,o.y+o.height)-c};f[l-1].dispose=1,l-1!=0&&_updateFrame(t,r,i,f,l-1,u,a),_updateFrame(t,r,i,f,l,u,a);}let h=0;if(1!=t.length)for(var d=0;d<f.length;d++){var A;h+=(A=f[d]).rect.width*A.rect.height;}return f}(t,r,i,s,f,l),y={},E=[],F=[];if(0!=o){const e=[];for(w=0;w<b.length;w++)e.push(b[w].img.buffer);const t=function concatRGBA(e){let t=0;for(var r=0;r<e.length;r++)t+=e[r].byteLength;const i=new Uint8Array(t);let o=0;for(r=0;r<e.length;r++){const t=new Uint8Array(e[r]),a=t.length;for(let e=0;e<a;e+=4){let r=t[e],a=t[e+1],s=t[e+2];const f=t[e+3];0==f&&(r=a=s=0),i[o+e]=r,i[o+e+1]=a,i[o+e+2]=s,i[o+e+3]=f;}o+=a;}return i.buffer}(e),r=quantize(t,o);for(w=0;w<r.plte.length;w++)E.push(r.plte[w].est.rgba);let i=0;for(w=0;w<b.length;w++){const e=(B=b[w]).img.length;var _=new Uint8Array(r.inds.buffer,i>>2,e>>2);F.push(_);const t=new Uint8Array(r.abuf,i,e);h&&dither(B.img,B.rect.width,B.rect.height,E,t,_),B.img.set(t),i+=e;}}else for(p=0;p<b.length;p++){var B=b[p];const e=new Uint32Array(B.img.buffer);var U=B.rect.width;m=e.length,_=new Uint8Array(m);F.push(_);for(w=0;w<m;w++){const t=e[w];if(0!=w&&t==e[w-1])_[w]=_[w-1];else if(w>U&&t==e[w-U])_[w]=_[w-U];else {let e=y[t];if(null==e&&(y[t]=e=E.length,E.push(t),E.length>=300))break;_[w]=e;}}}const C=E.length;C<=256&&0==u&&(A=C<=2?1:C<=4?2:C<=16?4:8,A=Math.max(A,c));for(p=0;p<b.length;p++){(B=b[p]).rect.x;U=B.rect.width;const e=B.rect.height;let t=B.img;let r=4*U,i=4;if(C<=256&&0==u){r=Math.ceil(A*U/8);var I=new Uint8Array(r*e);const o=F[p];for(let t=0;t<e;t++){w=t*r;const e=t*U;if(8==A)for(var Q=0;Q<U;Q++)I[w+Q]=o[e+Q];else if(4==A)for(Q=0;Q<U;Q++)I[w+(Q>>1)]|=o[e+Q]<<4-4*(1&Q);else if(2==A)for(Q=0;Q<U;Q++)I[w+(Q>>2)]|=o[e+Q]<<6-2*(3&Q);else if(1==A)for(Q=0;Q<U;Q++)I[w+(Q>>3)]|=o[e+Q]<<7-1*(7&Q);}t=I,d=3,i=1;}else if(0==v&&1==b.length){I=new Uint8Array(U*e*3);const o=U*e;for(w=0;w<o;w++){const e=3*w,r=4*w;I[e]=t[r],I[e+1]=t[r+1],I[e+2]=t[r+2];}t=I,d=2,i=3,r=3*U;}B.img=t,B.bpl=r,B.bpp=i;}return {ctype:d,depth:A,plte:E,frames:b}}function _updateFrame(t,r,i,o,a,s,f){const l=Uint8Array,c=Uint32Array,u=new l(t[a-1]),h=new c(t[a-1]),d=a+1<t.length?new l(t[a+1]):null,A=new l(t[a]),g=new c(A.buffer);let p=r,m=i,w=-1,v=-1;for(let e=0;e<s.height;e++)for(let t=0;t<s.width;t++){const i=s.x+t,f=s.y+e,l=f*r+i,c=g[l];0==c||0==o[a-1].dispose&&h[l]==c&&(null==d||0!=d[4*l+3])||(i<p&&(p=i),i>w&&(w=i),f<m&&(m=f),f>v&&(v=f));} -1==w&&(p=m=w=v=0),f&&(1==(1&p)&&p--,1==(1&m)&&m--),s={x:p,y:m,width:w-p+1,height:v-m+1};const b=o[a];b.rect=s,b.blend=1,b.img=new Uint8Array(s.width*s.height*4),0==o[a-1].dispose?(e(u,r,i,b.img,s.width,s.height,-s.x,-s.y,0),_prepareDiff(A,r,i,b.img,s)):e(A,r,i,b.img,s.width,s.height,-s.x,-s.y,0);}function _prepareDiff(t,r,i,o,a){e(t,r,i,o,a.width,a.height,-a.x,-a.y,2);}function _filterZero(e,t,r,i,o,a,s){const f=[];let l,c=[0,1,2,3,4];-1!=a?c=[a]:(t*i>5e5||1==r)&&(c=[0]),s&&(l={level:0});const u=UZIP;for(var h=0;h<c.length;h++){for(let a=0;a<t;a++)_filterLine(o,e,a,i,r,c[h]);f.push(u.deflate(o,l));}let d,A=1e9;for(h=0;h<f.length;h++)f[h].length<A&&(d=h,A=f[h].length);return f[d]}function _filterLine(e,t,i,o,a,s){const f=i*o;let l=f+i;if(e[l]=s,l++,0==s)if(o<500)for(var c=0;c<o;c++)e[l+c]=t[f+c];else e.set(new Uint8Array(t.buffer,f,o),l);else if(1==s){for(c=0;c<a;c++)e[l+c]=t[f+c];for(c=a;c<o;c++)e[l+c]=t[f+c]-t[f+c-a]+256&255;}else if(0==i){for(c=0;c<a;c++)e[l+c]=t[f+c];if(2==s)for(c=a;c<o;c++)e[l+c]=t[f+c];if(3==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-(t[f+c-a]>>1)+256&255;if(4==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-r(t[f+c-a],0,0)+256&255;}else {if(2==s)for(c=0;c<o;c++)e[l+c]=t[f+c]+256-t[f+c-o]&255;if(3==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-(t[f+c-o]>>1)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-(t[f+c-o]+t[f+c-a]>>1)&255;}if(4==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-r(0,t[f+c-o],0)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-r(t[f+c-a],t[f+c-o],t[f+c-a-o])&255;}}}function quantize(e,t){const r=new Uint8Array(e),i=r.slice(0),o=new Uint32Array(i.buffer),a=getKDtree(i,t),s=a[0],f=a[1],l=r.length,c=new Uint8Array(l>>2);let u;if(r.length<2e7)for(var h=0;h<l;h+=4){u=getNearest(s,d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255)),c[h>>2]=u.ind,o[h>>2]=u.est.rgba;}else for(h=0;h<l;h+=4){var d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255);for(u=s;u.left;)u=planeDst(u.est,d,A,g,p)<=0?u.left:u.right;c[h>>2]=u.ind,o[h>>2]=u.est.rgba;}return {abuf:i.buffer,inds:c,plte:f}}function getKDtree(e,t,r){null==r&&(r=1e-4);const i=new Uint32Array(e.buffer),o={i0:0,i1:e.length,bst:null,est:null,tdst:0,left:null,right:null};o.bst=stats(e,o.i0,o.i1),o.est=estats(o.bst);const a=[o];for(;a.length<t;){let t=0,o=0;for(var s=0;s<a.length;s++)a[s].est.L>t&&(t=a[s].est.L,o=s);if(t<r)break;const f=a[o],l=splitPixels(e,i,f.i0,f.i1,f.est.e,f.est.eMq255);if(f.i0>=l||f.i1<=l){f.est.L=0;continue}const c={i0:f.i0,i1:l,bst:null,est:null,tdst:0,left:null,right:null};c.bst=stats(e,c.i0,c.i1),c.est=estats(c.bst);const u={i0:l,i1:f.i1,bst:null,est:null,tdst:0,left:null,right:null};u.bst={R:[],m:[],N:f.bst.N-c.bst.N};for(s=0;s<16;s++)u.bst.R[s]=f.bst.R[s]-c.bst.R[s];for(s=0;s<4;s++)u.bst.m[s]=f.bst.m[s]-c.bst.m[s];u.est=estats(u.bst),f.left=c,f.right=u,a[o]=c,a.push(u);}a.sort(((e,t)=>t.bst.N-e.bst.N));for(s=0;s<a.length;s++)a[s].ind=s;return [o,a]}function getNearest(e,t,r,i,o){if(null==e.left)return e.tdst=function dist(e,t,r,i,o){const a=t-e[0],s=r-e[1],f=i-e[2],l=o-e[3];return a*a+s*s+f*f+l*l}(e.est.q,t,r,i,o),e;const a=planeDst(e.est,t,r,i,o);let s=e.left,f=e.right;a>0&&(s=e.right,f=e.left);const l=getNearest(s,t,r,i,o);if(l.tdst<=a*a)return l;const c=getNearest(f,t,r,i,o);return c.tdst<l.tdst?c:l}function planeDst(e,t,r,i,o){const{e:a}=e;return a[0]*t+a[1]*r+a[2]*i+a[3]*o-e.eMq}function splitPixels(e,t,r,i,o,a){for(i-=4;r<i;){for(;vecDot(e,r,o)<=a;)r+=4;for(;vecDot(e,i,o)>a;)i-=4;if(r>=i)break;const s=t[r>>2];t[r>>2]=t[i>>2],t[i>>2]=s,r+=4,i-=4;}for(;vecDot(e,r,o)>a;)r-=4;return r+4}function vecDot(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]+e[t+3]*r[3]}function stats(e,t,r){const i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],o=[0,0,0,0],a=r-t>>2;for(let a=t;a<r;a+=4){const t=e[a]*(1/255),r=e[a+1]*(1/255),s=e[a+2]*(1/255),f=e[a+3]*(1/255);o[0]+=t,o[1]+=r,o[2]+=s,o[3]+=f,i[0]+=t*t,i[1]+=t*r,i[2]+=t*s,i[3]+=t*f,i[5]+=r*r,i[6]+=r*s,i[7]+=r*f,i[10]+=s*s,i[11]+=s*f,i[15]+=f*f;}return i[4]=i[1],i[8]=i[2],i[9]=i[6],i[12]=i[3],i[13]=i[7],i[14]=i[11],{R:i,m:o,N:a}}function estats(e){const{R:t}=e,{m:r}=e,{N:i}=e,a=r[0],s=r[1],f=r[2],l=r[3],c=0==i?0:1/i,u=[t[0]-a*a*c,t[1]-a*s*c,t[2]-a*f*c,t[3]-a*l*c,t[4]-s*a*c,t[5]-s*s*c,t[6]-s*f*c,t[7]-s*l*c,t[8]-f*a*c,t[9]-f*s*c,t[10]-f*f*c,t[11]-f*l*c,t[12]-l*a*c,t[13]-l*s*c,t[14]-l*f*c,t[15]-l*l*c],h=u,d=o;let A=[Math.random(),Math.random(),Math.random(),Math.random()],g=0,p=0;if(0!=i)for(let e=0;e<16&&(A=d.multVec(h,A),p=Math.sqrt(d.dot(A,A)),A=d.sml(1/p,A),!(0!=e&&Math.abs(p-g)<1e-9));e++)g=p;const m=[a*c,s*c,f*c,l*c];return {Cov:u,q:m,e:A,L:g,eMq255:d.dot(d.sml(255,m),A),eMq:d.dot(A,m),rgba:(Math.round(255*m[3])<<24|Math.round(255*m[2])<<16|Math.round(255*m[1])<<8|Math.round(255*m[0])<<0)>>>0}}var o={multVec:(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7]*t[3],e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11]*t[3],e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]*t[3]],dot:(e,t)=>e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],sml:(e,t)=>[e*t[0],e*t[1],e*t[2],e*t[3]]};UPNG.encode=function encode(e,t,r,i,o,a,s){null==i&&(i=0),null==s&&(s=false);const f=compress(e,t,r,i,[false,false,false,0,s,false]);return compressPNG(f,-1),_main(f,t,r,o,a)},UPNG.encodeLL=function encodeLL(e,t,r,i,o,a,s,f){const l={ctype:0+(1==i?0:2)+(0==o?0:4),depth:a,frames:[]},c=(i+o)*a,u=c*t;for(let i=0;i<e.length;i++)l.frames.push({rect:{x:0,y:0,width:t,height:r},img:new Uint8Array(e[i]),blend:0,dispose:1,bpp:Math.ceil(c/8),bpl:Math.ceil(u/8)});return compressPNG(l,0,true),_main(l,t,r,s,f)},UPNG.encode.compress=compress,UPNG.encode.dither=dither,UPNG.quantize=quantize,UPNG.quantize.getKDtree=getKDtree,UPNG.quantize.getNearest=getNearest;}();const r={toArrayBuffer(e,t){const i=e.width,o=e.height,a=i<<2,s=e.getContext("2d").getImageData(0,0,i,o),f=new Uint32Array(s.data.buffer),l=(32*i+31)/32<<2,c=l*o,u=122+c,h=new ArrayBuffer(u),d=new DataView(h),A=1<<20;let g,p,m,w,v=A,b=0,y=0,E=0;function set16(e){d.setUint16(y,e,true),y+=2;}function set32(e){d.setUint32(y,e,true),y+=4;}function seek(e){y+=e;}set16(19778),set32(u),seek(4),set32(122),set32(108),set32(i),set32(-o>>>0),set16(1),set16(32),set32(3),set32(c),set32(2835),set32(2835),seek(8),set32(16711680),set32(65280),set32(255),set32(4278190080),set32(1466527264),function convert(){for(;b<o&&v>0;){for(w=122+b*l,g=0;g<a;)v--,p=f[E++],m=p>>>24,d.setUint32(w+g,p<<8|m),g+=4;b++;}E<f.length?(v=A,setTimeout(convert,r._dly)):t(h);}();},toBlob(e,t){this.toArrayBuffer(e,(e=>{t(new Blob([e],{type:"image/bmp"}));}));},_dly:9};var i={CHROME:"CHROME",FIREFOX:"FIREFOX",DESKTOP_SAFARI:"DESKTOP_SAFARI",IE:"IE",IOS:"IOS",ETC:"ETC"},o={[i.CHROME]:16384,[i.FIREFOX]:11180,[i.DESKTOP_SAFARI]:16384,[i.IE]:8192,[i.IOS]:4096,[i.ETC]:8192};const a="undefined"!=typeof window,s="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,f=a&&window.cordova&&window.cordova.require&&window.cordova.require("cordova/modulemapper"),CustomFile=(a||s)&&(f&&f.getOriginalSymbol(window,"File")||"undefined"!=typeof File&&File),CustomFileReader=(a||s)&&(f&&f.getOriginalSymbol(window,"FileReader")||"undefined"!=typeof FileReader&&FileReader);function getFilefromDataUrl(e,t,r=Date.now()){return new Promise((i=>{const o=e.split(","),a=o[0].match(/:(.*?);/)[1],s=globalThis.atob(o[1]);let f=s.length;const l=new Uint8Array(f);for(;f--;)l[f]=s.charCodeAt(f);const c=new Blob([l],{type:a});c.name=t,c.lastModified=r,i(c);}))}function getDataUrlFromFile(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=()=>t(i.result),i.onerror=e=>r(e),i.readAsDataURL(e);}))}function loadImage(e){return new Promise(((t,r)=>{const i=new Image;i.onload=()=>t(i),i.onerror=e=>r(e),i.src=e;}))}function getBrowserName(){if(void 0!==getBrowserName.cachedResult)return getBrowserName.cachedResult;let e=i.ETC;const{userAgent:t}=navigator;return /Chrom(e|ium)/i.test(t)?e=i.CHROME:/iP(ad|od|hone)/i.test(t)&&/WebKit/i.test(t)?e=i.IOS:/Safari/i.test(t)?e=i.DESKTOP_SAFARI:/Firefox/i.test(t)?e=i.FIREFOX:(/MSIE/i.test(t)||true==!!document.documentMode)&&(e=i.IE),getBrowserName.cachedResult=e,getBrowserName.cachedResult}function approximateBelowMaximumCanvasSizeOfBrowser(e,t){const r=getBrowserName(),i=o[r];let a=e,s=t,f=a*s;const l=a>s?s/a:a/s;for(;f>i*i;){const e=(i+a)/2,t=(i+s)/2;e<t?(s=t,a=t*l):(s=e*l,a=e),f=a*s;}return {width:a,height:s}}function getNewCanvasAndCtx(e,t){let r,i;try{if(r=new OffscreenCanvas(e,t),i=r.getContext("2d"),null===i)throw new Error("getContext of OffscreenCanvas returns null")}catch(e){r=document.createElement("canvas"),i=r.getContext("2d");}return r.width=e,r.height=t,[r,i]}function drawImageInCanvas(e,t){const{width:r,height:i}=approximateBelowMaximumCanvasSizeOfBrowser(e.width,e.height),[o,a]=getNewCanvasAndCtx(r,i);return t&&/jpe?g/.test(t)&&(a.fillStyle="white",a.fillRect(0,0,o.width,o.height)),a.drawImage(e,0,0,o.width,o.height),o}function isIOS(){return void 0!==isIOS.cachedResult||(isIOS.cachedResult=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"undefined"!=typeof document&&"ontouchend"in document),isIOS.cachedResult}function drawFileInCanvas(e,t={}){return new Promise((function(r,o){let a,s;var $Try_2_Post=function(){try{return s=drawImageInCanvas(a,t.fileType||e.type),r([a,s])}catch(e){return o(e)}},$Try_2_Catch=function(t){try{var $Try_3_Catch=function(e){try{throw e}catch(e){return o(e)}};try{let t;return getDataUrlFromFile(e).then((function(e){try{return t=e,loadImage(t).then((function(e){try{return a=e,function(){try{return $Try_2_Post()}catch(e){return o(e)}}()}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){$Try_3_Catch(e);}}catch(e){return o(e)}};try{if(isIOS()||[i.DESKTOP_SAFARI,i.MOBILE_SAFARI].includes(getBrowserName()))throw new Error("Skip createImageBitmap on IOS and Safari");return createImageBitmap(e).then((function(e){try{return a=e,$Try_2_Post()}catch(e){return $Try_2_Catch()}}),$Try_2_Catch)}catch(e){$Try_2_Catch();}}))}function canvasToFile(e,t,i,o,a=1){return new Promise((function(s,f){let l;if("image/png"===t){let c,u,h;return c=e.getContext("2d"),({data:u}=c.getImageData(0,0,e.width,e.height)),h=UPNG.encode([u.buffer],e.width,e.height,4096*a),l=new Blob([h],{type:t}),l.name=i,l.lastModified=o,$If_4.call(this)}{if("image/bmp"===t)return new Promise((t=>r.toBlob(e,t))).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_5.call(this)}catch(e){return f(e)}}.bind(this),f);{if("function"==typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return e.convertToBlob({type:t,quality:a}).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f);{let d;return d=e.toDataURL(t,a),getFilefromDataUrl(d,i,o).then(function(e){try{return l=e,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f)}function $If_6(){return $If_5.call(this)}}function $If_5(){return $If_4.call(this)}}function $If_4(){return s(l)}}))}function cleanupCanvasMemory(e){e.width=0,e.height=0;}function isAutoOrientationInBrowser(){return new Promise((function(e,t){let i,o,a,s;return void 0!==isAutoOrientationInBrowser.cachedResult?e(isAutoOrientationInBrowser.cachedResult):(getFilefromDataUrl("data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==","test.jpg",Date.now()).then((function(r){try{return i=r,drawFileInCanvas(i).then((function(r){try{return o=r[1],canvasToFile(o,i.type,i.name,i.lastModified).then((function(r){try{return a=r,cleanupCanvasMemory(o),drawFileInCanvas(a).then((function(r){try{return s=r[0],isAutoOrientationInBrowser.cachedResult=1===s.width&&2===s.height,e(isAutoOrientationInBrowser.cachedResult)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t))}))}function getExifOrientation(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=e=>{const r=new DataView(e.target.result);if(65496!=r.getUint16(0,false))return t(-2);const i=r.byteLength;let o=2;for(;o<i;){if(r.getUint16(o+2,false)<=8)return t(-1);const e=r.getUint16(o,false);if(o+=2,65505==e){if(1165519206!=r.getUint32(o+=2,false))return t(-1);const e=18761==r.getUint16(o+=6,false);o+=r.getUint32(o+4,e);const i=r.getUint16(o,e);o+=2;for(let a=0;a<i;a++)if(274==r.getUint16(o+12*a,e))return t(r.getUint16(o+12*a+8,e))}else {if(65280!=(65280&e))break;o+=r.getUint16(o,false);}}return t(-1)},i.onerror=e=>r(e),i.readAsArrayBuffer(e);}))}function handleMaxWidthOrHeight(e,t){const{width:r}=e,{height:i}=e,{maxWidthOrHeight:o}=t;let a,s=e;return isFinite(o)&&(r>o||i>o)&&([s,a]=getNewCanvasAndCtx(r,i),r>i?(s.width=o,s.height=i/r*o):(s.width=r/i*o,s.height=o),a.drawImage(e,0,0,s.width,s.height),cleanupCanvasMemory(e)),s}function followExifOrientation(e,t){const{width:r}=e,{height:i}=e,[o,a]=getNewCanvasAndCtx(r,i);switch(t>4&&t<9?(o.width=i,o.height=r):(o.width=r,o.height=i),t){case 2:a.transform(-1,0,0,1,r,0);break;case 3:a.transform(-1,0,0,-1,r,i);break;case 4:a.transform(1,0,0,-1,0,i);break;case 5:a.transform(0,1,1,0,0,0);break;case 6:a.transform(0,1,-1,0,i,0);break;case 7:a.transform(0,-1,-1,0,i,r);break;case 8:a.transform(0,-1,1,0,0,r);}return a.drawImage(e,0,0,r,i),cleanupCanvasMemory(e),o}function compress(e,t,r=0){return new Promise((function(i,o){let a,s,f,l,c,u,h,d,A,g,p,m,w,v,b,y,E,F,_,B;function incProgress(e=5){if(t.signal&&t.signal.aborted)throw t.signal.reason;a+=e,t.onProgress(Math.min(a,100));}function setProgress(e){if(t.signal&&t.signal.aborted)throw t.signal.reason;a=Math.min(Math.max(e,a),100),t.onProgress(a);}return a=r,s=t.maxIteration||10,f=1024*t.maxSizeMB*1024,incProgress(),drawFileInCanvas(e,t).then(function(r){try{return [,l]=r,incProgress(),c=handleMaxWidthOrHeight(l,t),incProgress(),new Promise((function(r,i){var o;if(!(o=t.exifOrientation))return getExifOrientation(e).then(function(e){try{return o=e,$If_2.call(this)}catch(e){return i(e)}}.bind(this),i);function $If_2(){return r(o)}return $If_2.call(this)})).then(function(r){try{return u=r,incProgress(),isAutoOrientationInBrowser().then(function(r){try{return h=r?c:followExifOrientation(c,u),incProgress(),d=t.initialQuality||1,A=t.fileType||e.type,canvasToFile(h,A,e.name,e.lastModified,d).then(function(r){try{{if(g=r,incProgress(),p=g.size>f,m=g.size>e.size,!p&&!m)return setProgress(100),i(g);var a;function $Loop_3(){if(s--&&(b>f||b>w)){let t,r;return t=B?.95*_.width:_.width,r=B?.95*_.height:_.height,[E,F]=getNewCanvasAndCtx(t,r),F.drawImage(_,0,0,t,r),d*="image/png"===A?.85:.95,canvasToFile(E,A,e.name,e.lastModified,d).then((function(e){try{return y=e,cleanupCanvasMemory(_),_=E,b=y.size,setProgress(Math.min(99,Math.floor((v-b)/(v-f)*100))),$Loop_3}catch(e){return o(e)}}),o)}return [1]}return w=e.size,v=g.size,b=v,_=h,B=!t.alwaysKeepResolution&&p,(a=function(e){for(;e;){if(e.then)return void e.then(a,o);try{if(e.pop){if(e.length)return e.pop()?$Loop_3_exit.call(this):e;e=$Loop_3;}else e=e.call(this);}catch(e){return o(e)}}}.bind(this))($Loop_3);function $Loop_3_exit(){return cleanupCanvasMemory(_),cleanupCanvasMemory(E),cleanupCanvasMemory(c),cleanupCanvasMemory(h),cleanupCanvasMemory(l),setProgress(100),i(y)}}}catch(u){return o(u)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}))}const l="\nlet scriptImported = false\nself.addEventListener('message', async (e) => {\n const { file, id, imageCompressionLibUrl, options } = e.data\n options.onProgress = (progress) => self.postMessage({ progress, id })\n try {\n if (!scriptImported) {\n // console.log('[worker] importScripts', imageCompressionLibUrl)\n self.importScripts(imageCompressionLibUrl)\n scriptImported = true\n }\n // console.log('[worker] self', self)\n const compressedFile = await imageCompression(file, options)\n self.postMessage({ file: compressedFile, id })\n } catch (e) {\n // console.error('[worker] error', e)\n self.postMessage({ error: e.message + '\\n' + e.stack, id })\n }\n})\n";let c;function compressOnWebWorker(e,t){return new Promise(((r,i)=>{c||(c=function createWorkerScriptURL(e){const t=[];return t.push(e),URL.createObjectURL(new Blob(t))}(l));const o=new Worker(c);o.addEventListener("message",(function handler(e){if(t.signal&&t.signal.aborted)o.terminate();else if(void 0===e.data.progress){if(e.data.error)return i(new Error(e.data.error)),void o.terminate();r(e.data.file),o.terminate();}else t.onProgress(e.data.progress);})),o.addEventListener("error",i),t.signal&&t.signal.addEventListener("abort",(()=>{i(t.signal.reason),o.terminate();})),o.postMessage({file:e,imageCompressionLibUrl:t.libURL,options:{...t,onProgress:void 0,signal:void 0}});}))}function imageCompression(e,t){return new Promise((function(r,i){let o,a,s,f,l,c;if(o={...t},s=0,({onProgress:f}=o),o.maxSizeMB=o.maxSizeMB||Number.POSITIVE_INFINITY,l="boolean"!=typeof o.useWebWorker||o.useWebWorker,delete o.useWebWorker,o.onProgress=e=>{s=e,"function"==typeof f&&f(s);},!(e instanceof Blob||e instanceof CustomFile))return i(new Error("The file given is not an instance of Blob or File"));if(!/^image/.test(e.type))return i(new Error("The file given is not an image"));if(c="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,!l||"function"!=typeof Worker||c)return compress(e,o).then(function(e){try{return a=e,$If_4.call(this)}catch(e){return i(e)}}.bind(this),i);var u=function(){try{return $If_4.call(this)}catch(e){return i(e)}}.bind(this),$Try_1_Catch=function(t){try{return compress(e,o).then((function(e){try{return a=e,u()}catch(e){return i(e)}}),i)}catch(e){return i(e)}};try{return o.libURL=o.libURL||"https://cdn.jsdelivr.net/npm/browser-image-compression@2.0.2/dist/browser-image-compression.js",compressOnWebWorker(e,o).then((function(e){try{return a=e,u()}catch(e){return $Try_1_Catch()}}),$Try_1_Catch)}catch(e){$Try_1_Catch();}function $If_4(){try{a.name=e.name,a.lastModified=e.lastModified;}catch(e){}try{o.preserveExif&&"image/jpeg"===e.type&&(!o.fileType||o.fileType&&o.fileType===e.type)&&(a=copyExifWithoutOrientation(e,a));}catch(e){}return r(a)}}))}imageCompression.getDataUrlFromFile=getDataUrlFromFile,imageCompression.getFilefromDataUrl=getFilefromDataUrl,imageCompression.loadImage=loadImage,imageCompression.drawImageInCanvas=drawImageInCanvas,imageCompression.drawFileInCanvas=drawFileInCanvas,imageCompression.canvasToFile=canvasToFile,imageCompression.getExifOrientation=getExifOrientation,imageCompression.handleMaxWidthOrHeight=handleMaxWidthOrHeight,imageCompression.followExifOrientation=followExifOrientation,imageCompression.cleanupCanvasMemory=cleanupCanvasMemory,imageCompression.isAutoOrientationInBrowser=isAutoOrientationInBrowser,imageCompression.approximateBelowMaximumCanvasSizeOfBrowser=approximateBelowMaximumCanvasSizeOfBrowser,imageCompression.copyExifWithoutOrientation=copyExifWithoutOrientation,imageCompression.getBrowserName=getBrowserName,imageCompression.version="2.0.2";
3959
+
3960
+ class KritzelImageTool extends KritzelBaseTool {
4143
3961
  constructor(store) {
4144
3962
  super(store);
4145
- this.selectionHandler = new KritzelSelectionHandler(this._store);
4146
- this.moveHandler = new KritzelMoveHandler(this._store);
4147
- this.resizeHandler = new KritzelResizeHandler(this._store);
4148
- this.rotationHandler = new KritzelRotationHandler(this._store);
3963
+ this.fileInput = null;
3964
+ this.maxWidth = 300;
3965
+ this.maxHeight = 300;
3966
+ this.maxCompressionSize = 300;
3967
+ this.setupFileInput();
4149
3968
  }
4150
- handleMouseDown(event) {
4151
- if (KritzelEventHelper.isLeftClick(event)) {
4152
- this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
4153
- this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
4154
- this._store.state.resizeHandleType = this.getHandleType(event);
4155
- const selectedObject = this.getSelectedObject(event);
4156
- const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
4157
- if ((selectedObject === null || isDifferentObject) &&
4158
- this._store.state.selectionGroup &&
4159
- !this._store.state.isResizeHandleSelected &&
4160
- !this._store.state.isRotationHandleSelected) {
4161
- this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
4162
- }
4163
- }
4164
- this.moveHandler.handleMouseDown(event);
4165
- this.selectionHandler.handleMouseDown(event);
4166
- this.resizeHandler.handleMouseDown(event);
4167
- this.rotationHandler.handleMouseDown(event);
4168
- this._store.rerender();
3969
+ onActivate() {
3970
+ this.openFilePicker();
4169
3971
  }
4170
- handleMouseMove(event) {
4171
- this.moveHandler.handleMouseMove(event);
4172
- this.selectionHandler.handleMouseMove(event);
4173
- this.resizeHandler.handleMouseMove(event);
4174
- this.rotationHandler.handleMouseMove(event);
4175
- this._store.rerender();
3972
+ openFilePicker() {
3973
+ this.fileInput.click();
4176
3974
  }
4177
- handleMouseUp(event) {
4178
- this.moveHandler.handleMouseUp(event);
4179
- this.selectionHandler.handleMouseUp(event);
4180
- this.resizeHandler.handleMouseUp(event);
4181
- this.rotationHandler.handleMouseUp(event);
4182
- this._store.rerender();
3975
+ setupFileInput() {
3976
+ this.fileInput = document.createElement('input');
3977
+ this.fileInput.type = 'file';
3978
+ this.fileInput.accept = 'image/*';
3979
+ this.fileInput.style.display = 'none';
3980
+ this.fileInput.addEventListener('change', this.handleFileSelect.bind(this));
3981
+ this.fileInput.addEventListener('cancel', this.handleCancel.bind(this));
3982
+ document.body.appendChild(this.fileInput);
4183
3983
  }
4184
- handleDoubleClick(event) {
4185
- var _a;
4186
- if (KritzelEventHelper.isLeftClick(event)) {
4187
- if (this._store.state.selectionGroup && ((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.objects.length) === 1) {
4188
- const selectedObject = this._store.state.selectionGroup.objects[0];
4189
- if (selectedObject instanceof KritzelText) {
4190
- this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
4191
- this._store.setState('activeTool', KritzelToolRegistry.getTool('text'));
4192
- this._store.state.activeText = selectedObject;
4193
- setTimeout(() => {
4194
- selectedObject.focus();
4195
- }, 300);
4196
- }
4197
- }
3984
+ handleFileSelect(event) {
3985
+ const input = event.target;
3986
+ if (input.files && input.files[0]) {
3987
+ const file = input.files[0];
3988
+ imageCompression(file, {
3989
+ maxWidthOrHeight: this.maxCompressionSize,
3990
+ })
3991
+ .then(compressedFile => {
3992
+ this.readFile(compressedFile);
3993
+ })
3994
+ .catch(error => {
3995
+ console.error('Error during image compression or processing:', error);
3996
+ this.handleCancel();
3997
+ });
4198
3998
  }
4199
- }
4200
- handleDoubleTap(event) {
4201
- const selectionGroup = this.getSelectedObject(event);
4202
- if (!selectionGroup || selectionGroup.objects.length !== 1) {
4203
- return;
3999
+ else {
4000
+ console.info('File selection cancelled by user.');
4001
+ this.handleCancel();
4204
4002
  }
4205
- const selectedObject = selectionGroup.objects[0];
4206
- if (selectedObject instanceof KritzelText) {
4207
- this._store.setState('activeTool', KritzelToolRegistry.getTool('text'));
4208
- this._store.state.activeText = selectedObject;
4209
- setTimeout(() => {
4210
- selectedObject.focus();
4211
- }, 300);
4003
+ if (input) {
4004
+ input.value = '';
4212
4005
  }
4213
4006
  }
4214
- handleTouchStart(event) {
4215
- if (this._store.state.isScaling === true) {
4216
- return;
4007
+ readFile(file) {
4008
+ const reader = new FileReader();
4009
+ reader.onload = e => {
4010
+ var _a;
4011
+ const img = new Image();
4012
+ img.src = (_a = e.target) === null || _a === void 0 ? void 0 : _a.result;
4013
+ img.onload = () => this.processImage(img);
4014
+ };
4015
+ reader.readAsDataURL(file);
4016
+ }
4017
+ processImage(img) {
4018
+ const { scaledWidth, scaledHeight } = this.calculateScaledDimensions(img);
4019
+ const image = this.createKritzelImage(img, scaledWidth, scaledHeight);
4020
+ this.addImageToStore(image);
4021
+ }
4022
+ calculateScaledDimensions(img) {
4023
+ let scaledWidth = img.width;
4024
+ let scaledHeight = img.height;
4025
+ if (img.width > this.maxWidth || img.height > this.maxHeight) {
4026
+ const widthRatio = this.maxWidth / img.width;
4027
+ const heightRatio = this.maxHeight / img.height;
4028
+ const scaleRatio = Math.min(widthRatio, heightRatio);
4029
+ scaledWidth = img.width * scaleRatio;
4030
+ scaledHeight = img.height * scaleRatio;
4217
4031
  }
4218
- if (this._store.state.touchCount === 1) {
4219
- this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
4220
- this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
4221
- this._store.state.resizeHandleType = this.getHandleType(event);
4222
- const selectedObject = this.getSelectedObject(event);
4223
- const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
4224
- if (!this._store.state.selectionGroup && selectedObject) {
4225
- this._store.state.skipContextMenu = true;
4032
+ return { scaledWidth, scaledHeight };
4033
+ }
4034
+ createKritzelImage(img, width, height) {
4035
+ const image = new KritzelImage(this._store, img);
4036
+ image.width = width;
4037
+ image.height = height;
4038
+ image.zIndex = this._store.currentZIndex;
4039
+ image.centerInViewport();
4040
+ return image;
4041
+ }
4042
+ addImageToStore(image) {
4043
+ const selectionGroup = new KritzelSelectionGroup(this._store);
4044
+ selectionGroup.addOrRemove(image);
4045
+ selectionGroup.selected = true;
4046
+ const addImageCommand = new AddObjectCommand(this._store, this, image);
4047
+ const addSelectionGroupCommand = new AddSelectionGroupCommand(this._store, this, selectionGroup);
4048
+ this._store.history.executeCommand(new BatchCommand(this._store, this, [addImageCommand, addSelectionGroupCommand]));
4049
+ this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
4050
+ }
4051
+ handleCancel() {
4052
+ this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
4053
+ }
4054
+ }
4055
+
4056
+ class KritzelReviver {
4057
+ constructor(store) {
4058
+ this._store = store;
4059
+ }
4060
+ revive(obj) {
4061
+ if (obj && typeof obj === 'object') {
4062
+ if (obj.__class__) {
4063
+ let revivedObj;
4064
+ switch (obj.__class__) {
4065
+ case 'KritzelPath':
4066
+ revivedObj = new KritzelPath(this._store).revive(obj);
4067
+ break;
4068
+ case 'KritzelText':
4069
+ revivedObj = new KritzelText(this._store, obj.fontSize, obj.fontFamily).revive(obj);
4070
+ break;
4071
+ case 'KritzelImage':
4072
+ revivedObj = new KritzelImage(this._store, obj.img).revive(obj);
4073
+ break;
4074
+ case 'KritzelSelectionGroup':
4075
+ revivedObj = new KritzelSelectionGroup(this._store).revive(obj);
4076
+ break;
4077
+ case 'KritzelBrushTool':
4078
+ revivedObj = new KritzelBrushTool(this._store);
4079
+ break;
4080
+ case 'KritzelEraserTool':
4081
+ revivedObj = new KritzelEraserTool(this._store);
4082
+ break;
4083
+ case 'KritzelImageTool':
4084
+ revivedObj = new KritzelImageTool(this._store);
4085
+ break;
4086
+ case 'KritzelSelectionTool':
4087
+ revivedObj = new KritzelSelectionTool(this._store);
4088
+ break;
4089
+ case 'KritzelTextTool':
4090
+ revivedObj = new KritzelTextTool(this._store);
4091
+ break;
4092
+ default:
4093
+ revivedObj = obj;
4094
+ }
4095
+ return revivedObj;
4226
4096
  }
4227
- if ((selectedObject === null || isDifferentObject) &&
4228
- this._store.state.selectionGroup &&
4229
- !this._store.state.isResizeHandleSelected &&
4230
- !this._store.state.isRotationHandleSelected) {
4231
- this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
4097
+ const newObj = Array.isArray(obj) ? [] : {};
4098
+ for (const key in obj) {
4099
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
4100
+ newObj[key] = this.revive(obj[key]);
4101
+ }
4232
4102
  }
4103
+ return newObj;
4233
4104
  }
4234
- this.rotationHandler.handleTouchStart(event);
4235
- this.resizeHandler.handleTouchStart(event);
4236
- this.moveHandler.handleTouchStart(event);
4237
- this.selectionHandler.handleTouchStart(event);
4105
+ return obj;
4238
4106
  }
4239
- handleTouchMove(event) {
4240
- if (this._store.state.isScaling === true) {
4241
- return;
4242
- }
4243
- this.rotationHandler.handleTouchMove(event);
4244
- this.resizeHandler.handleTouchMove(event);
4245
- this.moveHandler.handleTouchMove(event);
4246
- this.selectionHandler.handleTouchMove(event);
4247
- this._store.rerender();
4107
+ }
4108
+
4109
+ class KritzelSelectionGroup extends KritzelBaseObject {
4110
+ constructor(store) {
4111
+ super(store);
4112
+ this.__class__ = 'KritzelSelectionGroup';
4113
+ this.objects = [];
4114
+ this.unchangedObjects = [];
4115
+ this.scale = this._store.state.scale;
4116
+ this.zIndex = 99999;
4248
4117
  }
4249
- handleTouchEnd(event) {
4250
- if (this._store.state.isScaling === true) {
4251
- return;
4252
- }
4253
- this.rotationHandler.handleTouchEnd(event);
4254
- this.resizeHandler.handleTouchEnd(event);
4255
- this.moveHandler.handleTouchEnd(event);
4256
- this.selectionHandler.handleTouchEnd(event);
4118
+ get length() {
4119
+ return this.objects.length;
4257
4120
  }
4258
- getSelectedObject(event) {
4259
- const path = event.composedPath().slice(1);
4260
- const objectElement = path.find(element => element.classList && element.classList.contains('object'));
4261
- const object = this._store.findObjectById(objectElement === null || objectElement === void 0 ? void 0 : objectElement.id);
4262
- if (!object) {
4263
- return null;
4264
- }
4265
- if (object instanceof KritzelSelectionGroup) {
4266
- return object;
4121
+ addOrRemove(object) {
4122
+ const index = this.objects.findIndex(obj => obj.id === object.id);
4123
+ if (index === -1) {
4124
+ this.objects.push(object);
4267
4125
  }
4268
4126
  else {
4269
- const group = new KritzelSelectionGroup(this._store);
4270
- group.translateX = 0;
4271
- group.translateY = 0;
4272
- group.addOrRemove(object);
4273
- return group;
4127
+ this.objects.splice(index, 1);
4274
4128
  }
4129
+ this.unchangedObjects = ObjectHelper.clone(this.objects);
4130
+ this.refreshObjectDimensions();
4275
4131
  }
4276
- getHandleType(event) {
4277
- var _a;
4278
- const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
4279
- if (!shadowRoot)
4280
- return;
4281
- const point = event instanceof TouchEvent ? event.touches[0] : event;
4282
- const elementAtPoint = shadowRoot.elementFromPoint(point.clientX, point.clientY);
4283
- const handle = elementAtPoint.closest('.resize-handle-overlay');
4284
- return handle === null || handle === void 0 ? void 0 : handle.classList[1];
4285
- }
4286
- isHandleSelected(event) {
4287
- var _a;
4288
- const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
4289
- if (!shadowRoot)
4290
- return false;
4291
- const point = event instanceof TouchEvent ? event.touches[0] : event;
4292
- const elementAtPoint = shadowRoot.elementFromPoint(point.clientX, point.clientY);
4293
- return elementAtPoint === null || elementAtPoint === void 0 ? void 0 : elementAtPoint.classList.contains('resize-handle-overlay');
4294
- }
4295
- isRotationHandleSelected(event) {
4296
- const path = event.composedPath();
4297
- return !!path.find(element => element.classList && element.classList.contains('rotation-handle-overlay'));
4132
+ deselectAllChildren() {
4133
+ this.objects.forEach(obj => (obj.selected = false));
4298
4134
  }
4299
- }
4300
-
4301
- const kritzelControlsCss = ":host{display:flex;flex-direction:column;user-select:none}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap);height:100%;padding:var(--kritzel-controls-padding);background-color:var(--kritzel-controls-background-color);border-radius:var(--kritzel-controls-border-radius);box-shadow:var(--kritzel-controls-box-shadow);border:var(--kritzel-controls-border);border-radius:var(--kritzel-controls-border-radius);z-index:10000;position:relative}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color);border-radius:var(--kritzel-controls-control-border-radius);padding:var(--kritzel-controls-control-padding);border:none;outline:none;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color)}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color)}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color);color:var(--kritzel-controls-control-selected-color)}.kritzel-divider{width:var(--kritzel-controls-divider-width);height:var(--kritzel-controls-divider-height);background-color:var(--kritzel-controls-divider-background-color)}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;width:40px;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:pointer}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color)}.font-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{position:fixed;bottom:66px;left:50%;transform:translateX(-50%);z-index:10001;}";
4302
-
4303
- const KritzelControls = class {
4304
- constructor(hostRef) {
4305
- index.registerInstance(this, hostRef);
4306
- this.controls = [
4307
- {
4308
- name: 'selection',
4309
- type: 'tool',
4310
- tool: KritzelSelectionTool,
4311
- icon: 'cursor',
4312
- },
4313
- {
4314
- name: 'brush',
4315
- type: 'tool',
4316
- tool: KritzelBrushTool,
4317
- isDefault: true,
4318
- icon: 'pen',
4319
- config: {
4320
- type: 'pen',
4321
- color: '#000000',
4322
- size: 16,
4323
- palettes: {
4324
- pen: [
4325
- '#000000',
4326
- '#ff5252',
4327
- '#ffbc00',
4328
- '#00c853',
4329
- '#0000FF',
4330
- '#d500f9',
4331
- '#fafafa',
4332
- '#a52714',
4333
- '#ee8100',
4334
- '#558b2f',
4335
- '#01579b',
4336
- '#8e24aa',
4337
- '#90a4ae',
4338
- '#ff4081',
4339
- '#ff6e40',
4340
- '#aeea00',
4341
- '#304ffe',
4342
- '#7c4dff',
4343
- '#cfd8dc',
4344
- '#f8bbd0',
4345
- '#ffccbc',
4346
- '#f0f4c3',
4347
- '#9fa8da',
4348
- '#d1c4e9',
4349
- ],
4350
- highlighter: [
4351
- '#0000006e',
4352
- '#ff52526e',
4353
- '#ffbb006e',
4354
- '#00c8536e',
4355
- '#0000FF6e',
4356
- '#d500f96e',
4357
- '#fafafa6e',
4358
- '#a527146e',
4359
- '#ee81006e',
4360
- '#558b2f6e',
4361
- '#01579b6e',
4362
- '#8e24aa6e',
4363
- '#90a4ae6e',
4364
- '#ff40816e',
4365
- '#ff6e406e',
4366
- '#aeea006e',
4367
- '#304ffe6e',
4368
- '#7c4dff6e',
4369
- '#cfd8dc6e',
4370
- '#f8bbd06e',
4371
- '#ffccbc6e',
4372
- '#f0f4c36e',
4373
- '#9fa8da6e',
4374
- '#d1c4e96e',
4375
- ],
4376
- },
4377
- },
4378
- },
4379
- {
4380
- name: 'eraser',
4381
- type: 'tool',
4382
- tool: KritzelEraserTool,
4383
- icon: 'eraser',
4384
- },
4385
- {
4386
- name: 'text',
4387
- type: 'tool',
4388
- tool: KritzelTextTool,
4389
- icon: 'type',
4390
- config: {
4391
- color: '#000000',
4392
- size: 8,
4393
- fontFamily: 'Arial',
4394
- palette: [
4395
- '#000000',
4396
- '#ff5252',
4397
- '#ffbc00',
4398
- '#00c853',
4399
- '#0000FF',
4400
- '#d500f9',
4401
- '#fafafa',
4402
- '#a52714',
4403
- '#ee8100',
4404
- '#558b2f',
4405
- '#01579b',
4406
- '#8e24aa',
4407
- '#90a4ae',
4408
- '#ff4081',
4409
- '#ff6e40',
4410
- '#aeea00',
4411
- '#304ffe',
4412
- '#7c4dff',
4413
- '#cfd8dc',
4414
- '#f8bbd0',
4415
- '#ffccbc',
4416
- '#f0f4c3',
4417
- '#9fa8da',
4418
- '#d1c4e9',
4419
- ],
4420
- },
4421
- },
4422
- {
4423
- name: 'image',
4424
- type: 'tool',
4425
- tool: KritzelImageTool,
4426
- icon: 'image',
4427
- },
4428
- {
4429
- name: 'divider',
4430
- type: 'divider',
4431
- },
4432
- {
4433
- name: 'config',
4434
- type: 'config',
4435
- }
4436
- ];
4437
- this.activeControl = null;
4438
- this.firstConfig = null;
4439
- this.tooltipVisible = false;
4440
- this.kritzelEngine = null;
4135
+ updatePosition(x, y) {
4136
+ this.objects.forEach(obj => {
4137
+ const deltaX = obj.translateX - this.translateX;
4138
+ const deltaY = obj.translateY - this.translateY;
4139
+ obj.translateX = x + deltaX;
4140
+ obj.translateY = y + deltaY;
4141
+ this._store.state.objectsOctree.update(obj);
4142
+ });
4143
+ this.unchangedObjects.forEach(obj => {
4144
+ const deltaX = obj.translateX - this.translateX;
4145
+ const deltaY = obj.translateY - this.translateY;
4146
+ obj.translateX = x + deltaX;
4147
+ obj.translateY = y + deltaY;
4148
+ });
4149
+ this.translateX = x;
4150
+ this.translateY = y;
4151
+ this._store.state.objectsOctree.update(this);
4441
4152
  }
4442
- get activeToolAsTextTool() {
4443
- var _a;
4444
- return (_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.tool;
4153
+ move(startX, startY, endX, endY) {
4154
+ const deltaX = (startX - endX) / this._store.state.scale;
4155
+ const deltaY = (startY - endY) / this._store.state.scale;
4156
+ this.translateX += deltaX;
4157
+ this.translateY += deltaY;
4158
+ this._store.state.objectsOctree.update(this);
4159
+ this.objects.forEach(obj => {
4160
+ obj.translateX += deltaX;
4161
+ obj.translateY += deltaY;
4162
+ this._store.state.objectsOctree.update(obj);
4163
+ });
4164
+ this.unchangedObjects.forEach(obj => {
4165
+ obj.translateX += deltaX;
4166
+ obj.translateY += deltaY;
4167
+ });
4445
4168
  }
4446
- get activeToolAsBrushTool() {
4447
- var _a;
4448
- return (_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.tool;
4169
+ resize(x, y, width, height) {
4170
+ const widthScaleFactor = width / this.width;
4171
+ const heightScaleFactor = height / this.height;
4172
+ const deltaX = x - this.translateX;
4173
+ const deltaY = y - this.translateY;
4174
+ this.objects.forEach(obj => {
4175
+ const updatedWidth = obj.width * widthScaleFactor;
4176
+ const updatedHeight = obj.height * heightScaleFactor;
4177
+ const updatedX = obj.translateX + deltaX + (obj.translateX - this.translateX) * (widthScaleFactor - 1);
4178
+ const updatedY = obj.translateY + deltaY + (obj.translateY - this.translateY) * (heightScaleFactor - 1);
4179
+ obj.resize(updatedX, updatedY, updatedWidth, updatedHeight);
4180
+ this._store.state.objectsOctree.update(obj);
4181
+ });
4182
+ this.refreshObjectDimensions();
4183
+ this.unchangedObjects = ObjectHelper.clone(this.objects);
4449
4184
  }
4450
- async componentWillLoad() {
4451
- await this.initializeEngine();
4452
- await this.initializeTools();
4185
+ rotate(value) {
4186
+ this.rotation = value;
4187
+ const centerX = this.translateX + this.totalWidth / 2 / this.scale;
4188
+ const centerY = this.translateY + this.totalHeight / 2 / this.scale;
4189
+ const angle = value;
4190
+ const cos = Math.cos(angle);
4191
+ const sin = Math.sin(angle);
4192
+ this.objects.forEach(child => {
4193
+ const unchangedChild = this.getUnchangedObject(child.id);
4194
+ const offsetX = this.getOffsetXToCenter(unchangedChild);
4195
+ const offsetY = this.getOffsetYToCenter(unchangedChild);
4196
+ const rotatedX = cos * offsetX - sin * offsetY;
4197
+ const rotatedY = sin * offsetX + cos * offsetY;
4198
+ child.translateX = centerX + rotatedX - child.totalWidth / 2 / child.scale;
4199
+ child.translateY = centerY + rotatedY - child.totalHeight / 2 / child.scale;
4200
+ child.rotation = this.objects.length === 1 ? value : value + unchangedChild.rotation;
4201
+ });
4453
4202
  }
4454
- async initializeEngine() {
4455
- await customElements.whenDefined('kritzel-engine');
4456
- this.kritzelEngine = this.host.parentElement.querySelector('kritzel-engine');
4457
- if (!this.kritzelEngine) {
4458
- throw new Error('kritzel-engine not found in parent element.');
4203
+ copy() {
4204
+ const selectionGroup = new KritzelSelectionGroup(this._store);
4205
+ let currentZIndex = this._store.currentZIndex;
4206
+ this.objects.forEach(obj => {
4207
+ const copiedObject = obj.copy();
4208
+ copiedObject.zIndex = currentZIndex;
4209
+ selectionGroup.addOrRemove(copiedObject);
4210
+ currentZIndex++;
4211
+ });
4212
+ selectionGroup.unchangedObjects = ObjectHelper.clone(selectionGroup.objects);
4213
+ if (this.objects.length === 1) {
4214
+ selectionGroup.rotation = this.objects[0].rotation;
4459
4215
  }
4216
+ return selectionGroup;
4460
4217
  }
4461
- async initializeTools() {
4462
- for (const c of this.controls) {
4463
- if (c.type === 'tool' && c.tool) {
4464
- c.tool = await this.kritzelEngine.registerTool(c.name, c.tool, c.config);
4465
- }
4466
- if (c.type === 'tool' && c.isDefault && c.tool) {
4467
- await this.kritzelEngine.changeActiveTool(c.tool);
4468
- this.activeControl = c;
4469
- }
4470
- if (c.type === 'config') {
4471
- if (this.firstConfig === null) {
4472
- this.firstConfig = c;
4473
- }
4474
- else {
4475
- console.warn('Only one config control is allowed. The first one will be used.');
4476
- }
4477
- }
4218
+ refreshObjectDimensions() {
4219
+ if (this.objects.length === 1) {
4220
+ const obj = this.objects[0];
4221
+ this.minX = obj.boundingBox.x / this.scale;
4222
+ this.maxX = obj.boundingBox.x / this.scale + obj.boundingBox.width;
4223
+ this.minY = obj.boundingBox.y / this.scale;
4224
+ this.maxY = obj.boundingBox.y / this.scale + obj.boundingBox.height;
4225
+ this.translateX = (this.minX - this.padding) * this.scale;
4226
+ this.translateY = (this.minY - this.padding) * this.scale;
4227
+ this.width = (this.maxX - this.minX - this.padding) * this.scale;
4228
+ this.height = (this.maxY - this.minY - this.padding) * this.scale;
4478
4229
  }
4230
+ else {
4231
+ this.minX = Math.min(...this.objects.map(obj => obj.minXRotated));
4232
+ this.maxX = Math.max(...this.objects.map(obj => obj.maxXRotated));
4233
+ this.minY = Math.min(...this.objects.map(obj => obj.minYRotated));
4234
+ this.maxY = Math.max(...this.objects.map(obj => obj.maxYRotated));
4235
+ this.translateX = this.minX - this.padding;
4236
+ this.translateY = this.minY - this.padding;
4237
+ this.width = (this.maxX - this.minX - this.padding) * this.scale;
4238
+ this.height = (this.maxY - this.minY - this.padding) * this.scale;
4239
+ }
4240
+ this._store.state.objectsOctree.update(this);
4479
4241
  }
4480
- async handleActiveToolChange(event) {
4481
- var _a;
4482
- this.activeControl = this.controls.find(control => control.tool === event.detail) || null;
4483
- await ((_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.setFocus());
4242
+ getOffsetXToCenter(obj) {
4243
+ const objCenterX = obj.translateX + obj.totalWidth / obj.scale / 2;
4244
+ const groupCenterX = this.translateX + this.totalWidth / this.scale / 2;
4245
+ return objCenterX - groupCenterX;
4484
4246
  }
4485
- handleClick(event) {
4486
- const element = event.target;
4487
- if (!this.kritzelEngine || element.closest('.kritzel-tooltip')) {
4488
- return;
4489
- }
4490
- this.tooltipVisible = false;
4491
- this.kritzelEngine.enable();
4247
+ getOffsetYToCenter(obj) {
4248
+ const objCenterY = obj.translateY + obj.totalHeight / obj.scale / 2;
4249
+ const groupCenterY = this.translateY + this.totalHeight / this.scale / 2;
4250
+ return objCenterY - groupCenterY;
4492
4251
  }
4493
- preventDefault(event) {
4494
- if (event.cancelable) {
4495
- event.preventDefault();
4496
- event.stopPropagation();
4497
- }
4252
+ getUnchangedObject(objectId) {
4253
+ const obj = this.unchangedObjects.find(obj => obj.id === objectId);
4254
+ const reviver = new KritzelReviver(this._store);
4255
+ return reviver.revive(obj);
4498
4256
  }
4499
- async handleControlClick(control) {
4500
- this.activeControl = control;
4501
- if (this.activeControl.type === 'tool') {
4502
- await this.kritzelEngine.changeActiveTool(this.activeControl.tool);
4503
- }
4257
+ }
4258
+
4259
+ class KritzelSelectionHandler extends KritzelBaseHandler {
4260
+ get isSelectionClick() {
4261
+ return this._store.state.selectionBox && this._store.state.selectionBox.width === 0 && this._store.state.selectionBox.height === 0;
4504
4262
  }
4505
- handleConfigClick(event) {
4506
- event.stopPropagation();
4507
- this.tooltipVisible = !this.tooltipVisible;
4508
- this.kritzelEngine.disable();
4263
+ get isSelectionDrag() {
4264
+ return this._store.state.selectionBox && (this._store.state.selectionBox.width > 0 || this._store.state.selectionBox.height > 0);
4509
4265
  }
4510
- async handleToolChange(event) {
4511
- this.activeControl = Object.assign(Object.assign({}, this.activeControl), { tool: event.detail });
4512
- await this.kritzelEngine.changeActiveTool(this.activeControl.tool);
4266
+ constructor(store) {
4267
+ super(store);
4268
+ this.touchStartX = 0;
4269
+ this.touchStartY = 0;
4270
+ this.touchStartTimeout = null;
4513
4271
  }
4514
- render() {
4515
- var _a, _b;
4516
- const hasNoConfig = ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.config) === undefined || ((_b = this.activeControl) === null || _b === void 0 ? void 0 : _b.config) === null;
4517
- return (index.h(index.Host, { key: '5cc4a48e0881cab17d1e535f4b3cb2dca98d1ce4' }, index.h("kritzel-utility-panel", { key: '916b15a4b2b72d8e4804cdd8d0f9a110db5a2d9b', style: {
4518
- position: 'absolute',
4519
- bottom: '56px',
4520
- left: '12px',
4521
- }, onUndo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.undo(); }, onRedo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.redo(); }, onDelete: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.delete(); } }), index.h("div", { key: '30460311d4cae0dd570c3150aa7f943cb192a51e', class: "kritzel-controls" }, this.controls.map(control => {
4522
- var _a, _b, _c, _d, _e, _f, _g, _h;
4523
- if (control.type === 'tool') {
4524
- return (index.h("button", { class: {
4525
- 'kritzel-control': true,
4526
- 'selected': ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.name) === (control === null || control === void 0 ? void 0 : control.name),
4527
- }, key: control.name, onClick: _event => { var _a; return (_a = this.handleControlClick) === null || _a === void 0 ? void 0 : _a.call(this, control); } }, index.h("kritzel-icon", { name: control.icon })));
4272
+ handleMouseDown(event) {
4273
+ if (KritzelEventHelper.isLeftClick(event) && !this._store.state.selectionGroup) {
4274
+ this.startMouseSelection(event);
4275
+ }
4276
+ }
4277
+ handleMouseMove(event) {
4278
+ if (this._store.state.isSelecting) {
4279
+ this.updateMouseSelection(event);
4280
+ }
4281
+ }
4282
+ handleMouseUp(event) {
4283
+ if (KritzelEventHelper.isLeftClick(event) && this._store.state.isSelecting) {
4284
+ if (this.isSelectionClick) {
4285
+ this.updateMouseSelection(event);
4286
+ this.addSelectedObjectAtIndexToSelectionGroup(0);
4287
+ this.removeSelectionBox();
4528
4288
  }
4529
- if (control.type === 'divider') {
4530
- return index.h("div", { class: "kritzel-divider", key: control.name });
4289
+ if (this.isSelectionDrag) {
4290
+ this.updateMouseSelection(event);
4291
+ this.addSelectedObjectsToSelectionGroup();
4292
+ this.removeSelectionBox();
4531
4293
  }
4532
- if (control.type === 'config' && control.name === ((_b = this.firstConfig) === null || _b === void 0 ? void 0 : _b.name) && this.activeControl) {
4533
- return (index.h("div", { class: "kritzel-config-container", key: control.name }, index.h("kritzel-tooltip", { isVisible: this.tooltipVisible, anchorElement: (_c = this.host.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.kritzel-config-container') }, index.h("div", { style: { width: '294px', height: '100%' } }, this.activeControl.name === 'brush' && (index.h("kritzel-control-brush-config", { tool: this.activeToolAsBrushTool, onToolChange: event => { var _a; return (_a = this.handleToolChange) === null || _a === void 0 ? void 0 : _a.call(this, event); } })), this.activeControl.name === 'text' && (index.h("kritzel-control-text-config", { tool: this.activeToolAsTextTool, onToolChange: event => { var _a; return (_a = this.handleToolChange) === null || _a === void 0 ? void 0 : _a.call(this, event); } })))), index.h("div", { class: "kritzel-config", onClick: event => { var _a; return (_a = this.handleConfigClick) === null || _a === void 0 ? void 0 : _a.call(this, event); }, style: {
4534
- cursor: this.activeControl.config ? 'pointer' : 'default',
4535
- pointerEvents: hasNoConfig ? 'none' : 'auto',
4536
- } }, this.activeControl.tool instanceof KritzelBrushTool && (index.h("div", { class: "color-container" }, index.h("kritzel-color", { value: (_d = this.activeToolAsBrushTool) === null || _d === void 0 ? void 0 : _d.color, size: (_e = this.activeToolAsBrushTool) === null || _e === void 0 ? void 0 : _e.size, style: {
4537
- borderRadius: '50%',
4538
- border: 'none',
4539
- } }))), this.activeControl.tool instanceof KritzelTextTool && (index.h("div", { class: "font-container" }, index.h("kritzel-font", { fontFamily: (_f = this.activeToolAsTextTool) === null || _f === void 0 ? void 0 : _f.fontFamily, size: (_g = this.activeToolAsTextTool) === null || _g === void 0 ? void 0 : _g.fontSize, color: (_h = this.activeToolAsTextTool) === null || _h === void 0 ? void 0 : _h.fontColor }))), hasNoConfig && index.h("div", { class: "no-config" }))));
4294
+ }
4295
+ }
4296
+ handleTouchStart(event) {
4297
+ this.touchStartTimeout = setTimeout(() => {
4298
+ if (this._store.state.touchCount === 1 && !this._store.state.isScaling && !this._store.state.selectionGroup) {
4299
+ this.startTouchSelection(event);
4300
+ this.updateTouchSelection(event);
4540
4301
  }
4541
- }))));
4302
+ }, 80);
4542
4303
  }
4543
- static get assetsDirs() { return ["../assets"]; }
4544
- get host() { return index.getElement(this); }
4545
- };
4546
- KritzelControls.style = kritzelControlsCss;
4547
-
4548
- const kritzelCursorTrailCss = ":host{display:block;position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:9000}";
4549
-
4550
- const KritzelCursorTrail = class {
4551
- constructor(hostRef) {
4552
- index.registerInstance(this, hostRef);
4553
- this.cursorTrailPoints = [];
4554
- this.isLeftButtonDown = false;
4555
- this.TRAIL_DURATION_MS = 100;
4556
- this.MAX_TRAIL_POINTS = 50;
4304
+ handleTouchMove(event) {
4305
+ const x = Math.round(event.touches[0].clientX - this._store.offsetX);
4306
+ const y = Math.round(event.touches[0].clientY - this._store.offsetY);
4307
+ const moveDeltaX = Math.abs(x - this.touchStartX);
4308
+ const moveDeltaY = Math.abs(y - this.touchStartY);
4309
+ const moveThreshold = 5;
4310
+ if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._store.state.isSelecting) {
4311
+ this.updateTouchSelection(event);
4312
+ clearTimeout(this._store.state.longTouchTimeout);
4313
+ }
4557
4314
  }
4558
- componentDidLoad() {
4559
- this.trailCleanupIntervalId = window.setInterval(() => {
4560
- const now = Date.now();
4561
- const newTrailPoints = this.cursorTrailPoints.filter(p => now - p.timestamp < this.TRAIL_DURATION_MS);
4562
- if (newTrailPoints.length !== this.cursorTrailPoints.length) {
4563
- this.cursorTrailPoints = newTrailPoints;
4315
+ handleTouchEnd(event) {
4316
+ clearTimeout(this.touchStartTimeout);
4317
+ if (this._store.state.isSelecting) {
4318
+ if (this.isSelectionClick) {
4319
+ this.updateTouchSelection(event);
4320
+ this.addSelectedObjectAtIndexToSelectionGroup(0);
4321
+ this.removeSelectionBox();
4564
4322
  }
4565
- }, 50);
4323
+ if (this.isSelectionDrag) {
4324
+ this.updateTouchSelection(event);
4325
+ this.addSelectedObjectsToSelectionGroup();
4326
+ this.removeSelectionBox();
4327
+ }
4328
+ this._store.state.skipContextMenu = false;
4329
+ }
4330
+ }
4331
+ removeSelectionBox() {
4332
+ this._store.state.selectionBox = null;
4333
+ this._store.state.isSelecting = false;
4334
+ this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox);
4335
+ this._store.rerender();
4566
4336
  }
4567
- disconnectedCallback() {
4568
- if (this.trailCleanupIntervalId) {
4569
- window.clearInterval(this.trailCleanupIntervalId);
4337
+ startMouseSelection(event) {
4338
+ let clientX, clientY;
4339
+ clientX = event.clientX - this._store.offsetX;
4340
+ clientY = event.clientY - this._store.offsetY;
4341
+ const selectionBox = new KrtizelSelectionBox(this._store);
4342
+ this.startX = (clientX - this._store.state.translateX) / this._store.state.scale;
4343
+ this.startY = (clientY - this._store.state.translateY) / this._store.state.scale;
4344
+ selectionBox.translateX = this.startX;
4345
+ selectionBox.translateY = this.startY;
4346
+ this._store.state.selectionGroup = null;
4347
+ this._store.state.selectionBox = selectionBox;
4348
+ this._store.state.isSelecting = true;
4349
+ this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox || o instanceof KritzelSelectionGroup);
4350
+ this._store.state.objectsOctree.insert(selectionBox);
4351
+ }
4352
+ startTouchSelection(event) {
4353
+ const firstTouch = event.touches[0];
4354
+ if (!firstTouch) {
4355
+ return;
4570
4356
  }
4357
+ let clientX, clientY;
4358
+ clientX = Math.round(firstTouch.clientX - this._store.offsetX);
4359
+ clientY = Math.round(firstTouch.clientY - this._store.offsetY);
4360
+ this.touchStartX = clientX;
4361
+ this.touchStartY = clientY;
4362
+ const selectionBox = new KrtizelSelectionBox(this._store);
4363
+ this.startX = (clientX - this._store.state.translateX) / this._store.state.scale;
4364
+ this.startY = (clientY - this._store.state.translateY) / this._store.state.scale;
4365
+ selectionBox.translateX = this.startX;
4366
+ selectionBox.translateY = this.startY;
4367
+ this._store.state.selectionGroup = null;
4368
+ this._store.state.selectionBox = selectionBox;
4369
+ this._store.state.isSelecting = true;
4370
+ this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox || o instanceof KritzelSelectionGroup);
4371
+ this._store.state.objectsOctree.insert(selectionBox);
4571
4372
  }
4572
- handleMouseDown(ev) {
4573
- if (ev.button === 0) {
4574
- this.isLeftButtonDown = true;
4575
- this.cursorTrailPoints = [];
4373
+ updateMouseSelection(event) {
4374
+ let clientX, clientY;
4375
+ clientX = event.clientX - this._store.offsetX;
4376
+ clientY = event.clientY - this._store.offsetY;
4377
+ const selectionBox = this._store.state.selectionBox;
4378
+ if (selectionBox) {
4379
+ const currentX = (clientX - this._store.state.translateX) / selectionBox.scale;
4380
+ const currentY = (clientY - this._store.state.translateY) / selectionBox.scale;
4381
+ selectionBox.width = Math.abs(currentX - this.startX) * selectionBox.scale;
4382
+ selectionBox.height = Math.abs(currentY - this.startY) * selectionBox.scale;
4383
+ selectionBox.translateX = Math.min(currentX, this.startX);
4384
+ selectionBox.translateY = Math.min(currentY, this.startY);
4385
+ this.updateSelectedObjects();
4386
+ this._store.rerender();
4576
4387
  }
4577
4388
  }
4578
- handleMouseMove(ev) {
4579
- if (!this.isLeftButtonDown) {
4389
+ updateTouchSelection(event) {
4390
+ const firstTouch = event.touches[0];
4391
+ if (!firstTouch) {
4580
4392
  return;
4581
4393
  }
4582
- const newPoint = { x: ev.clientX, y: ev.clientY, timestamp: Date.now() };
4583
- const updatedTrail = [newPoint, ...this.cursorTrailPoints];
4584
- if (updatedTrail.length > this.MAX_TRAIL_POINTS) {
4585
- this.cursorTrailPoints = updatedTrail.slice(0, this.MAX_TRAIL_POINTS);
4586
- }
4587
- else {
4588
- this.cursorTrailPoints = updatedTrail;
4394
+ let clientX, clientY;
4395
+ clientX = Math.round(firstTouch.clientX - this._store.offsetX);
4396
+ clientY = Math.round(firstTouch.clientY - this._store.offsetY);
4397
+ const selectionBox = this._store.state.selectionBox;
4398
+ if (selectionBox) {
4399
+ const currentX = (clientX - this._store.state.translateX) / selectionBox.scale;
4400
+ const currentY = (clientY - this._store.state.translateY) / selectionBox.scale;
4401
+ selectionBox.width = Math.abs(currentX - this.startX) * selectionBox.scale;
4402
+ selectionBox.height = Math.abs(currentY - this.startY) * selectionBox.scale;
4403
+ selectionBox.translateX = Math.min(currentX, this.startX);
4404
+ selectionBox.translateY = Math.min(currentY, this.startY);
4405
+ this.updateSelectedObjects();
4589
4406
  }
4590
4407
  }
4591
- handleMouseUp(ev) {
4592
- if (ev.button === 0) {
4593
- this.isLeftButtonDown = false;
4594
- this.cursorTrailPoints = [];
4595
- }
4408
+ updateSelectedObjects() {
4409
+ this._store.allObjects
4410
+ .filter(o => !(o instanceof KrtizelSelectionBox))
4411
+ .forEach(object => {
4412
+ const objectPolygon = object.rotatedPolygon;
4413
+ const selectionBoxPolygon = this._store.state.selectionBox.rotatedPolygon;
4414
+ object.selected = KritzelGeometryHelper.doPolygonsIntersect(objectPolygon, selectionBoxPolygon);
4415
+ });
4596
4416
  }
4597
- handleTouchStart(ev) {
4598
- if (ev.touches.length === 1) {
4599
- this.isLeftButtonDown = true;
4600
- this.cursorTrailPoints = [];
4417
+ addSelectedObjectAtIndexToSelectionGroup(index) {
4418
+ const selectedObjects = this._store.selectedObjects.sort((a, b) => b.zIndex - a.zIndex);
4419
+ const selectedObject = selectedObjects[index];
4420
+ if (!selectedObject) {
4421
+ return;
4601
4422
  }
4423
+ selectedObjects.forEach(o => (o.selected = false));
4424
+ this._store.state.selectionGroup = new KritzelSelectionGroup(this._store);
4425
+ this._store.state.selectionGroup.addOrRemove(selectedObject);
4426
+ this._store.state.selectionGroup.selected = true;
4427
+ this._store.state.selectionGroup.rotation = this._store.state.selectionGroup.objects[0].rotation;
4428
+ this._store.history.executeCommand(new AddSelectionGroupCommand(this._store, this, this._store.state.selectionGroup));
4602
4429
  }
4603
- handleTouchMove(ev) {
4604
- if (!this.isLeftButtonDown) {
4430
+ addSelectedObjectsToSelectionGroup() {
4431
+ const selectedObjects = this._store.selectedObjects;
4432
+ if (selectedObjects.length === 0) {
4605
4433
  return;
4606
4434
  }
4607
- const touch = ev.touches[0];
4608
- const newPoint = { x: touch.clientX, y: touch.clientY, timestamp: Date.now() };
4609
- const updatedTrail = [newPoint, ...this.cursorTrailPoints];
4610
- if (updatedTrail.length > this.MAX_TRAIL_POINTS) {
4611
- this.cursorTrailPoints = updatedTrail.slice(0, this.MAX_TRAIL_POINTS);
4612
- }
4613
- else {
4614
- this.cursorTrailPoints = updatedTrail;
4435
+ this._store.state.selectionGroup = new KritzelSelectionGroup(this._store);
4436
+ selectedObjects.forEach(o => {
4437
+ o.selected = false;
4438
+ this._store.state.selectionGroup.addOrRemove(o);
4439
+ });
4440
+ this._store.state.selectionGroup.selected = true;
4441
+ if (this._store.state.selectionGroup.length === 1) {
4442
+ this._store.state.selectionGroup.rotation = this._store.state.selectionGroup.objects[0].rotation;
4615
4443
  }
4444
+ this._store.history.executeCommand(new AddSelectionGroupCommand(this._store, this, this._store.state.selectionGroup));
4616
4445
  }
4617
- handleTouchEnd(ev) {
4618
- if (ev.touches.length === 0) {
4619
- this.isLeftButtonDown = false;
4620
- this.cursorTrailPoints = [];
4446
+ }
4447
+
4448
+ class KritzelSelectionTool extends KritzelBaseTool {
4449
+ constructor(store) {
4450
+ super(store);
4451
+ this.selectionHandler = new KritzelSelectionHandler(this._store);
4452
+ this.moveHandler = new KritzelMoveHandler(this._store);
4453
+ this.resizeHandler = new KritzelResizeHandler(this._store);
4454
+ this.rotationHandler = new KritzelRotationHandler(this._store);
4455
+ }
4456
+ handleMouseDown(event) {
4457
+ if (KritzelEventHelper.isLeftClick(event)) {
4458
+ this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
4459
+ this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
4460
+ this._store.state.resizeHandleType = this.getHandleType(event);
4461
+ const selectedObject = this.getSelectedObject(event);
4462
+ const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
4463
+ if ((selectedObject === null || isDifferentObject) &&
4464
+ this._store.state.selectionGroup &&
4465
+ !this._store.state.isResizeHandleSelected &&
4466
+ !this._store.state.isRotationHandleSelected) {
4467
+ this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
4468
+ }
4621
4469
  }
4470
+ this.moveHandler.handleMouseDown(event);
4471
+ this.selectionHandler.handleMouseDown(event);
4472
+ this.resizeHandler.handleMouseDown(event);
4473
+ this.rotationHandler.handleMouseDown(event);
4474
+ this._store.rerender();
4622
4475
  }
4623
- render() {
4624
- return (index.h(index.Host, { key: '604f5c39a01f3aea870861de0a93cd162302d7b2' }, this.cursorTrailPoints.length > 1 && (index.h("svg", { key: '731229b4bceebff36a3292a4346d0f44495e3610', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
4625
- position: 'absolute',
4626
- left: '0',
4627
- top: '0',
4628
- width: '100%',
4629
- height: '100%',
4630
- pointerEvents: 'none',
4631
- opacity: 'var(--kritzel-cursor-trail-opacity)',
4632
- zIndex: '9000',
4633
- } }, this.cursorTrailPoints.slice(1).map((point, index$1) => {
4634
- const prevPoint = this.cursorTrailPoints[index$1];
4635
- const now = Date.now();
4636
- const age = now - point.timestamp;
4637
- const progress = Math.max(0, Math.min(1, age / this.TRAIL_DURATION_MS));
4638
- if (progress >= 1)
4639
- return null;
4640
- const baseStrokeWidth = Math.max(2, 15 * (1 - progress));
4641
- return (index.h("line", { key: `trail-segment-${point.timestamp}`, x1: prevPoint.x.toString(), y1: prevPoint.y.toString(), x2: point.x.toString(), y2: point.y.toString(), stroke: "var(--kritzel-cursor-trail-color)", "stroke-width": baseStrokeWidth.toString(), "stroke-linecap": "round" }));
4642
- })))));
4476
+ handleMouseMove(event) {
4477
+ this.moveHandler.handleMouseMove(event);
4478
+ this.selectionHandler.handleMouseMove(event);
4479
+ this.resizeHandler.handleMouseMove(event);
4480
+ this.rotationHandler.handleMouseMove(event);
4481
+ this._store.rerender();
4643
4482
  }
4644
- };
4645
- KritzelCursorTrail.style = kritzelCursorTrailCss;
4646
-
4647
- const kritzelDropdownCss = ":host{display:inline-flex;vertical-align:middle;width:100%;}.dropdown-wrapper{display:flex;align-items:center;border:1px solid #333333;border-radius:var(--kritzel-controls-control-border-radius, 4px);overflow:hidden;height:32px;width:100%}.custom-select{padding:0 8px;padding-right:30px;height:100%;width:100%;box-sizing:border-box;border-radius:0;border:none;background-color:#fff;cursor:pointer;outline:none;font-size:inherit;color:var(--kritzel-controls-text-color, #333333);-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"%23333333\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"/></svg>');background-size:16px 16px;background-repeat:no-repeat;background-position:right 8px center}.custom-select.has-suffix-border{border-right:1px solid #333333}.custom-select.has-prefix-border{border-left:1px solid #333333}::slotted(*){height:100%;box-sizing:border-box}";
4648
-
4649
- const KritzelDropdown = class {
4650
- constructor(hostRef) {
4651
- index.registerInstance(this, hostRef);
4652
- this.valueChanged = index.createEvent(this, "valueChanged");
4653
- this.options = [];
4654
- this.selectStyles = {};
4655
- this.hasSuffixContent = false;
4656
- this.hasPrefixContent = false;
4657
- this.handleSelectChange = (event) => {
4658
- const newValue = event.target.value;
4659
- if (this.internalValue !== newValue) {
4660
- this.internalValue = newValue;
4661
- this.valueChanged.emit(this.internalValue);
4662
- }
4663
- };
4664
- this.evaluateSuffixContent = () => {
4665
- if (this.suffixSlotElement) {
4666
- const newHasContent = this.suffixSlotElement.assignedNodes({ flatten: true }).length > 0;
4667
- if (this.hasSuffixContent !== newHasContent) {
4668
- this.hasSuffixContent = newHasContent;
4669
- }
4670
- }
4671
- else {
4672
- if (this.hasSuffixContent !== false) {
4673
- this.hasSuffixContent = false;
4483
+ handleMouseUp(event) {
4484
+ this.moveHandler.handleMouseUp(event);
4485
+ this.selectionHandler.handleMouseUp(event);
4486
+ this.resizeHandler.handleMouseUp(event);
4487
+ this.rotationHandler.handleMouseUp(event);
4488
+ this._store.rerender();
4489
+ }
4490
+ handleDoubleClick(event) {
4491
+ var _a;
4492
+ if (KritzelEventHelper.isLeftClick(event)) {
4493
+ if (this._store.state.selectionGroup && ((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.objects.length) === 1) {
4494
+ const selectedObject = this._store.state.selectionGroup.objects[0];
4495
+ if (selectedObject instanceof KritzelText) {
4496
+ this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
4497
+ this._store.setState('activeTool', KritzelToolRegistry.getTool('text'));
4498
+ this._store.state.activeText = selectedObject;
4499
+ setTimeout(() => {
4500
+ selectedObject.focus();
4501
+ }, 300);
4674
4502
  }
4675
4503
  }
4676
- };
4677
- this.evaluatePrefixContent = () => {
4678
- if (this.prefixSlotElement) {
4679
- const newHasContent = this.prefixSlotElement.assignedNodes({ flatten: true }).length > 0;
4680
- if (this.hasPrefixContent !== newHasContent) {
4681
- this.hasPrefixContent = newHasContent;
4682
- }
4504
+ }
4505
+ }
4506
+ handleDoubleTap(event) {
4507
+ const selectionGroup = this.getSelectedObject(event);
4508
+ if (!selectionGroup || selectionGroup.objects.length !== 1) {
4509
+ return;
4510
+ }
4511
+ const selectedObject = selectionGroup.objects[0];
4512
+ if (selectedObject instanceof KritzelText) {
4513
+ this._store.setState('activeTool', KritzelToolRegistry.getTool('text'));
4514
+ this._store.state.activeText = selectedObject;
4515
+ setTimeout(() => {
4516
+ selectedObject.focus();
4517
+ }, 300);
4518
+ }
4519
+ }
4520
+ handleTouchStart(event) {
4521
+ if (this._store.state.isScaling === true) {
4522
+ return;
4523
+ }
4524
+ if (this._store.state.touchCount === 1) {
4525
+ this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
4526
+ this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
4527
+ this._store.state.resizeHandleType = this.getHandleType(event);
4528
+ const selectedObject = this.getSelectedObject(event);
4529
+ const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
4530
+ if (!this._store.state.selectionGroup && selectedObject) {
4531
+ this._store.state.skipContextMenu = true;
4683
4532
  }
4684
- else {
4685
- if (this.hasPrefixContent !== false) {
4686
- this.hasPrefixContent = false;
4687
- }
4533
+ if ((selectedObject === null || isDifferentObject) &&
4534
+ this._store.state.selectionGroup &&
4535
+ !this._store.state.isResizeHandleSelected &&
4536
+ !this._store.state.isRotationHandleSelected) {
4537
+ this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
4688
4538
  }
4689
- };
4690
- }
4691
- componentWillLoad() {
4692
- this.updateInternalValue(this.value, false);
4693
- this.evaluateSuffixContent();
4694
- this.evaluatePrefixContent();
4539
+ }
4540
+ this.rotationHandler.handleTouchStart(event);
4541
+ this.resizeHandler.handleTouchStart(event);
4542
+ this.moveHandler.handleTouchStart(event);
4543
+ this.selectionHandler.handleTouchStart(event);
4695
4544
  }
4696
- externalValueChanged(newValue) {
4697
- if (newValue !== this.internalValue) {
4698
- this.updateInternalValue(newValue, false);
4545
+ handleTouchMove(event) {
4546
+ if (this._store.state.isScaling === true) {
4547
+ return;
4699
4548
  }
4549
+ this.rotationHandler.handleTouchMove(event);
4550
+ this.resizeHandler.handleTouchMove(event);
4551
+ this.moveHandler.handleTouchMove(event);
4552
+ this.selectionHandler.handleTouchMove(event);
4553
+ this._store.rerender();
4700
4554
  }
4701
- optionsChanged() {
4702
- this.updateInternalValue(this.internalValue, true);
4555
+ handleTouchEnd(event) {
4556
+ if (this._store.state.isScaling === true) {
4557
+ return;
4558
+ }
4559
+ this.rotationHandler.handleTouchEnd(event);
4560
+ this.resizeHandler.handleTouchEnd(event);
4561
+ this.moveHandler.handleTouchEnd(event);
4562
+ this.selectionHandler.handleTouchEnd(event);
4703
4563
  }
4704
- updateInternalValue(proposedValue, emitChange) {
4705
- let finalValue = proposedValue;
4706
- if (this.options && this.options.length > 0) {
4707
- const isValidValue = this.options.some(opt => opt.value === finalValue);
4708
- if (!finalValue || !isValidValue) {
4709
- finalValue = this.options[0].value;
4710
- }
4564
+ getSelectedObject(event) {
4565
+ const path = event.composedPath().slice(1);
4566
+ const objectElement = path.find(element => element.classList && element.classList.contains('object'));
4567
+ const object = this._store.findObjectById(objectElement === null || objectElement === void 0 ? void 0 : objectElement.id);
4568
+ if (!object) {
4569
+ return null;
4711
4570
  }
4712
- else {
4713
- finalValue = undefined;
4571
+ if (object instanceof KritzelSelectionGroup) {
4572
+ return object;
4714
4573
  }
4715
- if (this.internalValue !== finalValue) {
4716
- this.internalValue = finalValue;
4717
- if (emitChange || (proposedValue !== finalValue && proposedValue !== undefined)) {
4718
- this.valueChanged.emit(this.internalValue);
4719
- }
4574
+ else {
4575
+ const group = new KritzelSelectionGroup(this._store);
4576
+ group.translateX = 0;
4577
+ group.translateY = 0;
4578
+ group.addOrRemove(object);
4579
+ return group;
4720
4580
  }
4721
4581
  }
4722
- render() {
4723
- const selectClasses = {
4724
- 'custom-select': true,
4725
- 'has-suffix-border': this.hasSuffixContent,
4726
- 'has-prefix-border': this.hasPrefixContent,
4727
- };
4728
- return (index.h(index.Host, { key: '1e4df5425e205d3709d93d71f2e7a47844a5b0f2' }, index.h("div", { key: '6e0d6fa7b35d1d9d61cf2174828d0d0f0d242683', class: "dropdown-wrapper" }, index.h("slot", { key: '07565dc0982498a9b026bc36f285eb728b5c771b', name: "prefix", ref: el => this.prefixSlotElement = el, onSlotchange: this.evaluatePrefixContent }), index.h("select", { key: 'ba618a1166681f36aae554242192e375286ba7e8', class: selectClasses, style: Object.assign(Object.assign({}, this.selectStyles), { width: this.width }), onInput: this.handleSelectChange }, this.options.map(option => (index.h("option", { value: option.value, style: option.style, selected: option.value === this.internalValue }, option.label)))), index.h("slot", { key: '2731003fa214cb3aa968b48db36ab1816d563425', name: "suffix", ref: el => this.suffixSlotElement = el, onSlotchange: this.evaluateSuffixContent }))));
4582
+ getHandleType(event) {
4583
+ var _a;
4584
+ const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
4585
+ if (!shadowRoot)
4586
+ return;
4587
+ const point = event instanceof TouchEvent ? event.touches[0] : event;
4588
+ const elementAtPoint = shadowRoot.elementFromPoint(point.clientX, point.clientY);
4589
+ const handle = elementAtPoint.closest('.resize-handle-overlay');
4590
+ return handle === null || handle === void 0 ? void 0 : handle.classList[1];
4729
4591
  }
4730
- static get watchers() { return {
4731
- "value": ["externalValueChanged"],
4732
- "options": ["optionsChanged"]
4733
- }; }
4734
- };
4735
- KritzelDropdown.style = kritzelDropdownCss;
4592
+ isHandleSelected(event) {
4593
+ var _a;
4594
+ const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
4595
+ if (!shadowRoot)
4596
+ return false;
4597
+ const point = event instanceof TouchEvent ? event.touches[0] : event;
4598
+ const elementAtPoint = shadowRoot.elementFromPoint(point.clientX, point.clientY);
4599
+ return elementAtPoint === null || elementAtPoint === void 0 ? void 0 : elementAtPoint.classList.contains('resize-handle-overlay');
4600
+ }
4601
+ isRotationHandleSelected(event) {
4602
+ const path = event.composedPath();
4603
+ return !!path.find(element => element.classList && element.classList.contains('rotation-handle-overlay'));
4604
+ }
4605
+ }
4736
4606
 
4737
4607
  class KritzelIconRegistry {
4738
4608
  static register(name, svgContent) {
@@ -4782,6 +4652,137 @@ const kritzelEditorCss = "kritzel-editor{display:flex;margin:0;position:relative
4782
4652
  const KritzelEditor = class {
4783
4653
  constructor(hostRef) {
4784
4654
  index.registerInstance(this, hostRef);
4655
+ this.controls = [
4656
+ {
4657
+ name: 'selection',
4658
+ type: 'tool',
4659
+ tool: KritzelSelectionTool,
4660
+ icon: 'cursor',
4661
+ },
4662
+ {
4663
+ name: 'brush',
4664
+ type: 'tool',
4665
+ tool: KritzelBrushTool,
4666
+ isDefault: true,
4667
+ icon: 'pen',
4668
+ config: {
4669
+ type: 'pen',
4670
+ color: '#000000',
4671
+ size: 16,
4672
+ palettes: {
4673
+ pen: [
4674
+ '#000000',
4675
+ '#ff5252',
4676
+ '#ffbc00',
4677
+ '#00c853',
4678
+ '#0000FF',
4679
+ '#d500f9',
4680
+ '#fafafa',
4681
+ '#a52714',
4682
+ '#ee8100',
4683
+ '#558b2f',
4684
+ '#01579b',
4685
+ '#8e24aa',
4686
+ '#90a4ae',
4687
+ '#ff4081',
4688
+ '#ff6e40',
4689
+ '#aeea00',
4690
+ '#304ffe',
4691
+ '#7c4dff',
4692
+ '#cfd8dc',
4693
+ '#f8bbd0',
4694
+ '#ffccbc',
4695
+ '#f0f4c3',
4696
+ '#9fa8da',
4697
+ '#d1c4e9',
4698
+ ],
4699
+ highlighter: [
4700
+ '#0000006e',
4701
+ '#ff52526e',
4702
+ '#ffbb006e',
4703
+ '#00c8536e',
4704
+ '#0000FF6e',
4705
+ '#d500f96e',
4706
+ '#fafafa6e',
4707
+ '#a527146e',
4708
+ '#ee81006e',
4709
+ '#558b2f6e',
4710
+ '#01579b6e',
4711
+ '#8e24aa6e',
4712
+ '#90a4ae6e',
4713
+ '#ff40816e',
4714
+ '#ff6e406e',
4715
+ '#aeea006e',
4716
+ '#304ffe6e',
4717
+ '#7c4dff6e',
4718
+ '#cfd8dc6e',
4719
+ '#f8bbd06e',
4720
+ '#ffccbc6e',
4721
+ '#f0f4c36e',
4722
+ '#9fa8da6e',
4723
+ '#d1c4e96e',
4724
+ ],
4725
+ },
4726
+ },
4727
+ },
4728
+ {
4729
+ name: 'eraser',
4730
+ type: 'tool',
4731
+ tool: KritzelEraserTool,
4732
+ icon: 'eraser',
4733
+ },
4734
+ {
4735
+ name: 'text',
4736
+ type: 'tool',
4737
+ tool: KritzelTextTool,
4738
+ icon: 'type',
4739
+ config: {
4740
+ color: '#000000',
4741
+ size: 8,
4742
+ fontFamily: 'Arial',
4743
+ palette: [
4744
+ '#000000',
4745
+ '#ff5252',
4746
+ '#ffbc00',
4747
+ '#00c853',
4748
+ '#0000FF',
4749
+ '#d500f9',
4750
+ '#fafafa',
4751
+ '#a52714',
4752
+ '#ee8100',
4753
+ '#558b2f',
4754
+ '#01579b',
4755
+ '#8e24aa',
4756
+ '#90a4ae',
4757
+ '#ff4081',
4758
+ '#ff6e40',
4759
+ '#aeea00',
4760
+ '#304ffe',
4761
+ '#7c4dff',
4762
+ '#cfd8dc',
4763
+ '#f8bbd0',
4764
+ '#ffccbc',
4765
+ '#f0f4c3',
4766
+ '#9fa8da',
4767
+ '#d1c4e9',
4768
+ ],
4769
+ },
4770
+ },
4771
+ {
4772
+ name: 'image',
4773
+ type: 'tool',
4774
+ tool: KritzelImageTool,
4775
+ icon: 'image',
4776
+ },
4777
+ {
4778
+ name: 'divider',
4779
+ type: 'divider',
4780
+ },
4781
+ {
4782
+ name: 'config',
4783
+ type: 'config',
4784
+ },
4785
+ ];
4785
4786
  this.customSvgIcons = {};
4786
4787
  }
4787
4788
  handleTouchStart(event) {
@@ -4795,7 +4796,7 @@ const KritzelEditor = class {
4795
4796
  }
4796
4797
  }
4797
4798
  render() {
4798
- return (index.h(index.Host, { key: 'abd8f2477e1596034ec953781f7d7145117fc0ef' }, index.h("kritzel-engine", { key: 'ea4bc0f6c876ceeea558c2dbc315f6a6448ab34e' }), index.h("kritzel-controls", { key: '566473bb09a72d34e37bc52d6037f6776b345d96', controls: this.controls })));
4799
+ return (index.h(index.Host, { key: '233e9903879a2ce4cd725541a45ebb3a35d29509' }, index.h("kritzel-engine", { key: '5608642e19c459349157dc41047a3f44aa88e1ef' }), index.h("kritzel-controls", { key: '765c8cad9b60de5a88e7d5c920bd407fc0f50e36', controls: this.controls })));
4799
4800
  }
4800
4801
  };
4801
4802
  KritzelEditor.style = kritzelEditorCss;