kritzel-stencil 0.1.78 → 0.1.80

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 (163) hide show
  1. package/dist/cjs/{index-BRZ6e6oa.js → index-CFnj_FXt.js} +36 -9
  2. package/dist/cjs/index.cjs.js +1 -1
  3. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +333 -177
  4. package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
  5. package/dist/cjs/loader.cjs.js +2 -2
  6. package/dist/cjs/stencil.cjs.js +3 -3
  7. package/dist/cjs/{workspace.migrations-sUPrO23c.js → workspace.migrations-DUXtSb7C.js} +244 -197
  8. package/dist/collection/classes/core/core.class.js +39 -31
  9. package/dist/collection/classes/core/store.class.js +57 -16
  10. package/dist/collection/classes/core/viewport.class.js +12 -12
  11. package/dist/collection/classes/handlers/context-menu.handler.js +1 -1
  12. package/dist/collection/classes/handlers/line-handle.handler.js +7 -4
  13. package/dist/collection/classes/handlers/move.handler.js +11 -8
  14. package/dist/collection/classes/handlers/resize.handler.js +12 -3
  15. package/dist/collection/classes/handlers/rotation.handler.js +12 -3
  16. package/dist/collection/classes/handlers/selection.handler.js +20 -15
  17. package/dist/collection/classes/managers/anchor.manager.js +4 -4
  18. package/dist/collection/classes/objects/base-object.class.js +6 -6
  19. package/dist/collection/classes/objects/custom-element.class.js +2 -2
  20. package/dist/collection/classes/objects/group.class.js +10 -10
  21. package/dist/collection/classes/objects/image.class.js +2 -2
  22. package/dist/collection/classes/objects/line.class.js +7 -7
  23. package/dist/collection/classes/objects/path.class.js +5 -5
  24. package/dist/collection/classes/objects/selection-box.class.js +1 -1
  25. package/dist/collection/classes/objects/selection-group.class.js +16 -16
  26. package/dist/collection/classes/objects/shape.class.js +37 -31
  27. package/dist/collection/classes/objects/text.class.js +40 -32
  28. package/dist/collection/classes/structures/app-state-map.structure.js +18 -16
  29. package/dist/collection/classes/structures/object-map.structure.js +30 -27
  30. package/dist/collection/classes/tools/brush-tool.class.js +14 -14
  31. package/dist/collection/classes/tools/image-tool.class.js +1 -1
  32. package/dist/collection/classes/tools/line-tool.class.js +14 -14
  33. package/dist/collection/classes/tools/selection-tool.class.js +2 -2
  34. package/dist/collection/classes/tools/shape-tool.class.js +6 -6
  35. package/dist/collection/classes/tools/text-tool.class.js +2 -2
  36. package/dist/collection/collection-manifest.json +1 -1
  37. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +6 -6
  38. package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +2 -2
  39. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +70 -11
  40. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +21 -1
  41. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +159 -60
  42. package/dist/collection/configs/default-engine-config.js +2 -2
  43. package/dist/collection/constants/version.js +1 -1
  44. package/dist/collection/helpers/keyboard.helper.js +15 -11
  45. package/dist/components/index.js +1 -1
  46. package/dist/components/kritzel-active-users.js +1 -1
  47. package/dist/components/kritzel-avatar.js +1 -1
  48. package/dist/components/kritzel-awareness-cursors.js +1 -1
  49. package/dist/components/kritzel-back-to-content.js +1 -1
  50. package/dist/components/kritzel-brush-style.js +1 -1
  51. package/dist/components/kritzel-button.js +1 -1
  52. package/dist/components/kritzel-color-palette.js +1 -1
  53. package/dist/components/kritzel-color.js +1 -1
  54. package/dist/components/kritzel-context-menu.js +1 -1
  55. package/dist/components/kritzel-controls.js +1 -1
  56. package/dist/components/kritzel-current-user-dialog.js +1 -1
  57. package/dist/components/kritzel-current-user.js +1 -1
  58. package/dist/components/kritzel-cursor-trail.js +1 -1
  59. package/dist/components/kritzel-dialog.js +1 -1
  60. package/dist/components/kritzel-dropdown.js +1 -1
  61. package/dist/components/kritzel-editor.js +1 -1
  62. package/dist/components/kritzel-engine.js +1 -1
  63. package/dist/components/kritzel-export.js +1 -1
  64. package/dist/components/kritzel-font-family.js +1 -1
  65. package/dist/components/kritzel-font-size.js +1 -1
  66. package/dist/components/kritzel-font.js +1 -1
  67. package/dist/components/kritzel-icon.js +1 -1
  68. package/dist/components/kritzel-input.js +1 -1
  69. package/dist/components/kritzel-line-endings.js +1 -1
  70. package/dist/components/kritzel-login-dialog.js +1 -1
  71. package/dist/components/kritzel-master-detail.js +1 -1
  72. package/dist/components/kritzel-menu-item.js +1 -1
  73. package/dist/components/kritzel-menu.js +1 -1
  74. package/dist/components/kritzel-more-menu.js +1 -1
  75. package/dist/components/kritzel-numeric-input.js +1 -1
  76. package/dist/components/kritzel-opacity-slider.js +1 -1
  77. package/dist/components/kritzel-pill-tabs.js +1 -1
  78. package/dist/components/kritzel-portal.js +1 -1
  79. package/dist/components/kritzel-settings.js +1 -1
  80. package/dist/components/kritzel-shape-fill.js +1 -1
  81. package/dist/components/kritzel-share-dialog.js +1 -1
  82. package/dist/components/kritzel-slide-toggle.js +1 -1
  83. package/dist/components/kritzel-split-button.js +1 -1
  84. package/dist/components/kritzel-stroke-size.js +1 -1
  85. package/dist/components/kritzel-tool-config.js +1 -1
  86. package/dist/components/kritzel-tooltip.js +1 -1
  87. package/dist/components/kritzel-utility-panel.js +1 -1
  88. package/dist/components/kritzel-workspace-manager.js +1 -1
  89. package/dist/components/{p-Md9Y-b3d.js → p-1ppb4M65.js} +1 -1
  90. package/dist/components/{p-KJ4dHzrS.js → p-7yR-sKH8.js} +1 -1
  91. package/dist/components/{p-CN8IxBlU.js → p-B-Gej_Ak.js} +1 -1
  92. package/dist/components/{p-76W5pG2O.js → p-B4F19Aqj.js} +1 -1
  93. package/dist/components/{p-BuI6Gkzg.js → p-B5WII1Lk.js} +1 -1
  94. package/dist/components/p-BWj1eE2b.js +1 -0
  95. package/dist/components/{p-ZC5YELQJ.js → p-BZ8bK8qT.js} +1 -1
  96. package/dist/components/{p-DkWWzVg8.js → p-BaaFG0p-.js} +1 -1
  97. package/dist/components/{p-6NFl6EB2.js → p-Bat829Bg.js} +1 -1
  98. package/dist/components/p-BcwZ36sO.js +1 -0
  99. package/dist/components/{p-53di1Zko.js → p-BjPmEs5A.js} +1 -1
  100. package/dist/components/{p-D5IhryUR.js → p-Brwz_Dpb.js} +1 -1
  101. package/dist/components/p-BzQmBVwr.js +9 -0
  102. package/dist/components/{p-C2l9mZ1P.js → p-C-MtTi6x.js} +1 -1
  103. package/dist/components/p-C8WnYSHi.js +1 -0
  104. package/dist/components/{p-BLsH_Oi0.js → p-C9zsWWH2.js} +1 -1
  105. package/dist/components/{p-ZQ2bKafG.js → p-CJKsuQun.js} +1 -1
  106. package/dist/components/{p-m1nVDC3G.js → p-CJzg_ejc.js} +1 -1
  107. package/dist/components/{p-Dte67BWd.js → p-CM7rYf9A.js} +1 -1
  108. package/dist/components/{p-Dr3-pKVg.js → p-CMGHx71q.js} +1 -1
  109. package/dist/components/{p-CI9Nbh-x.js → p-CNMpVlot.js} +1 -1
  110. package/dist/components/{p-DDKjsXCe.js → p-CS7r-zhx.js} +1 -1
  111. package/dist/components/{p-DaGZEV0R.js → p-C_fSm7T4.js} +1 -1
  112. package/dist/components/{p-Ck1dhpUQ.js → p-CfEGaTaV.js} +1 -1
  113. package/dist/components/{p-CWMFGEe0.js → p-CvyE2Wg-.js} +1 -1
  114. package/dist/components/{p-D3pNw-SV.js → p-D5BXoK9m.js} +1 -1
  115. package/dist/components/{p-DV7Z_qfa.js → p-D7pwbRUy.js} +1 -1
  116. package/dist/components/{p-CBslLN3-.js → p-DCH4Rlqx.js} +1 -1
  117. package/dist/components/{p-CYh7yV-K.js → p-DEOUiiyI.js} +1 -1
  118. package/dist/components/{p-pCC6t6BH.js → p-DKeBfe_l.js} +1 -1
  119. package/dist/components/{p-DWsCbu01.js → p-DUQmBcTy.js} +1 -1
  120. package/dist/components/{p-D14QNK3X.js → p-DUnKjQN7.js} +1 -1
  121. package/dist/components/{p-BrZ_gL8Q.js → p-DYcsC2zO.js} +1 -1
  122. package/dist/components/{p-D7yzmu1l.js → p-DkT0KZCm.js} +1 -1
  123. package/dist/components/{p-Cns7qSKS.js → p-DrsORMoT.js} +1 -1
  124. package/dist/components/{p-BueaqfA2.js → p-Dw0Obsn5.js} +1 -1
  125. package/dist/components/{p-DxzDda_J.js → p-Gm5hSQ-e.js} +1 -1
  126. package/dist/components/{p-C4fKLlrd.js → p-HK-6khHo.js} +1 -1
  127. package/dist/components/{p-_QEHfsIk.js → p-V3VW2JKl.js} +1 -1
  128. package/dist/components/{p-Lhyh6KeB.js → p-VxgCvVox.js} +1 -1
  129. package/dist/components/{p-l_YGO7RB.js → p-cjeDomsc.js} +1 -1
  130. package/dist/components/{p-gtQlsorg.js → p-rNu5JVNH.js} +1 -1
  131. package/dist/components/p-xYCbKFih.js +1 -0
  132. package/dist/esm/{index-BbOHefEf.js → index-D9HaikfQ.js} +36 -9
  133. package/dist/esm/index.js +1 -1
  134. package/dist/esm/kritzel-active-users_42.entry.js +333 -177
  135. package/dist/esm/kritzel-brush-style.entry.js +1 -1
  136. package/dist/esm/loader.js +3 -3
  137. package/dist/esm/stencil.js +4 -4
  138. package/dist/esm/{workspace.migrations-NhRgr2_H.js → workspace.migrations-OzSSw5kt.js} +244 -197
  139. package/dist/stencil/index.esm.js +1 -1
  140. package/dist/stencil/p-D9HaikfQ.js +2 -0
  141. package/dist/stencil/p-OzSSw5kt.js +1 -0
  142. package/dist/stencil/{p-98238bf9.entry.js → p-b0be4da1.entry.js} +1 -1
  143. package/dist/stencil/p-f7be06a8.entry.js +9 -0
  144. package/dist/stencil/stencil.esm.js +1 -1
  145. package/dist/types/classes/core/store.class.d.ts +23 -0
  146. package/dist/types/classes/objects/shape.class.d.ts +1 -0
  147. package/dist/types/classes/objects/text.class.d.ts +1 -0
  148. package/dist/types/classes/providers/hocuspocus-sync-provider.class.d.ts +1 -1
  149. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +7 -5
  150. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +10 -4
  151. package/dist/types/components.d.ts +35 -13
  152. package/dist/types/constants/version.d.ts +1 -1
  153. package/dist/types/helpers/tool-config.helper.d.ts +1 -1
  154. package/dist/types/interfaces/engine-state.interface.d.ts +10 -10
  155. package/package.json +1 -1
  156. package/dist/components/p-Ban3OlgZ.js +0 -9
  157. package/dist/components/p-CGGiwvWZ.js +0 -1
  158. package/dist/components/p-CHY71o5B.js +0 -1
  159. package/dist/components/p-DXpYcAnT.js +0 -1
  160. package/dist/components/p-pGzF7PUB.js +0 -1
  161. package/dist/stencil/p-4a4b38e4.entry.js +0 -9
  162. package/dist/stencil/p-BbOHefEf.js +0 -2
  163. package/dist/stencil/p-NhRgr2_H.js +0 -1
@@ -446,7 +446,7 @@ class KritzelBaseObject {
446
446
  const object = new KritzelBaseObject();
447
447
  object._core = core;
448
448
  object.zIndex = core.store.currentZIndex;
449
- object.workspaceId = core.store.state.activeWorkspace.id;
449
+ object.workspaceId = core.store.activeWorkspace.id;
450
450
  object.userId = core.user?.id;
451
451
  return object;
452
452
  }
@@ -513,7 +513,7 @@ class KritzelBaseObject {
513
513
  * Triggers a re-render of the object in the canvas.
514
514
  */
515
515
  update() {
516
- this._core.store.state.objects.update(this);
516
+ this._core.store.objects.update(this);
517
517
  }
518
518
  /**
519
519
  * Moves the object based on the delta between start and end coordinates.
@@ -528,7 +528,7 @@ class KritzelBaseObject {
528
528
  const deltaY = (startY - endY) / this._core.store.state.scale;
529
529
  this.translateX += deltaX;
530
530
  this.translateY += deltaY;
531
- this._core.store.state.objects.update(this);
531
+ this._core.store.objects.update(this);
532
532
  }
533
533
  /**
534
534
  * Resizes the object to new dimensions and position.
@@ -547,7 +547,7 @@ class KritzelBaseObject {
547
547
  this.height = height;
548
548
  this.translateX = x;
549
549
  this.translateY = y;
550
- this._core.store.state.objects.update(this);
550
+ this._core.store.objects.update(this);
551
551
  // Update any lines that are anchored to this object (after position is updated)
552
552
  this._core.anchorManager.updateAnchorsForObject(this.id);
553
553
  }
@@ -557,7 +557,7 @@ class KritzelBaseObject {
557
557
  */
558
558
  rotate(value) {
559
559
  this.rotation = value;
560
- this._core.store.state.objects.update(this);
560
+ this._core.store.objects.update(this);
561
561
  }
562
562
  /**
563
563
  * Creates a shallow clone of this object with the same ID.
@@ -662,7 +662,7 @@ class KritzelBaseObject {
662
662
  updatePosition(x, y) {
663
663
  this.translateX = x;
664
664
  this.translateY = y;
665
- this._core.store.state.objects.update(this);
665
+ this._core.store.objects.update(this);
666
666
  }
667
667
  }
668
668
 
@@ -705,23 +705,27 @@ class KritzelKeyboardHelper {
705
705
  const meta = document.querySelector('meta[name="viewport"][content*="interactive-widget=resizes-content"]');
706
706
  if (meta) {
707
707
  let currentContent = meta.getAttribute('content');
708
- if (!currentContent.includes('interactive-widget=resizes-content')) {
708
+ if (!currentContent?.includes('interactive-widget=resizes-content')) {
709
709
  currentContent += ', interactive-widget=resizes-content';
710
710
  }
711
- meta.setAttribute('content', currentContent);
711
+ if (currentContent) {
712
+ meta.setAttribute('content', currentContent);
713
+ }
712
714
  }
713
715
  }
714
716
  static disableInteractiveWidget() {
715
717
  const meta = document.querySelector('meta[name="viewport"][content*="interactive-widget=resizes-content"]');
716
718
  if (meta) {
717
719
  let currentContent = meta.getAttribute('content');
718
- let newContent = currentContent.replace(/\s*interactive-widget=resizes-content\s*[,;]?/g, '');
719
- newContent = newContent
720
- .replace(/,(\s*,)+/g, ',')
721
- .replace(/^,/, '')
722
- .replace(/,$/, '')
723
- .trim();
724
- meta.setAttribute('content', newContent);
720
+ let newContent = currentContent?.replace(/\s*interactive-widget=resizes-content\s*[,;]?/g, '');
721
+ if (newContent !== undefined) {
722
+ newContent = newContent
723
+ .replace(/,(\s*,)+/g, ',')
724
+ .replace(/^,/, '')
725
+ .replace(/,$/, '')
726
+ .trim();
727
+ meta.setAttribute('content', newContent);
728
+ }
725
729
  }
726
730
  }
727
731
  static onKeyboardVisibleChanged(callback) {
@@ -734,8 +738,8 @@ class KritzelKeyboardHelper {
734
738
  const isOpen = isMobileDevice && isViewportReduced;
735
739
  callback(isOpen);
736
740
  };
737
- window.visualViewport.addEventListener('resize', onResize);
738
- return () => window.visualViewport.removeEventListener('resize', onResize);
741
+ window.visualViewport?.addEventListener('resize', onResize);
742
+ return () => window.visualViewport?.removeEventListener('resize', onResize);
739
743
  }
740
744
  else {
741
745
  // Fallback for older browsers does not provide a reliable event-based mechanism.
@@ -15246,6 +15250,12 @@ class KritzelText extends KritzelBaseObject {
15246
15250
  isEditing = false;
15247
15251
  editor = null;
15248
15252
  content = null;
15253
+ get _editor() {
15254
+ if (!this._editor) {
15255
+ throw new Error('KritzelShape: editor is not initialized');
15256
+ }
15257
+ return this._editor;
15258
+ }
15249
15259
  _schema = new Schema({
15250
15260
  nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),
15251
15261
  marks: schema.spec.marks,
@@ -15257,10 +15267,10 @@ class KritzelText extends KritzelBaseObject {
15257
15267
  * @returns `true` if the editor is empty or contains only whitespace, `false` otherwise.
15258
15268
  */
15259
15269
  get isEmpty() {
15260
- if (!this.editor) {
15270
+ if (!this._editor) {
15261
15271
  return true;
15262
15272
  }
15263
- const doc = this.editor.state.doc;
15273
+ const doc = this._editor.state.doc;
15264
15274
  if (doc.content.size === 0) {
15265
15275
  return true;
15266
15276
  }
@@ -15333,10 +15343,10 @@ class KritzelText extends KritzelBaseObject {
15333
15343
  const object = new KritzelText();
15334
15344
  object._core = core;
15335
15345
  object.id = object.generateId();
15336
- object.workspaceId = core.store.state.activeWorkspace.id;
15346
+ object.workspaceId = core.store.activeWorkspace.id;
15337
15347
  object.userId = core.user?.id;
15338
- object.fontSize = fontSize;
15339
- object.fontFamily = fontFamily;
15348
+ object.fontSize = fontSize || 8;
15349
+ object.fontFamily = fontFamily || 'Arial';
15340
15350
  object.translateX = 0;
15341
15351
  object.translateY = 0;
15342
15352
  const coreScale = core.store.state.scale;
@@ -15364,7 +15374,7 @@ class KritzelText extends KritzelBaseObject {
15364
15374
  element.style.fontFamily = this.fontFamily;
15365
15375
  element.style.fontSize = `${this.fontSize}pt`;
15366
15376
  element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor);
15367
- if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
15377
+ if (this.isMounted && this.elementRef === element && this._editor.dom.parentElement === element) {
15368
15378
  if (!this._core.store.state.isScaling && !this._core.store.state.isPanning) {
15369
15379
  requestAnimationFrame(() => this.adjustSizeOnInput());
15370
15380
  }
@@ -15374,7 +15384,7 @@ class KritzelText extends KritzelBaseObject {
15374
15384
  this.elementRef.style.whiteSpace = 'pre-wrap';
15375
15385
  this.elementRef.style.wordWrap = 'break-word';
15376
15386
  this.elementRef.innerHTML = '';
15377
- this.elementRef.appendChild(this.editor.dom);
15387
+ this.elementRef.appendChild(this._editor.dom);
15378
15388
  this.isMounted = true;
15379
15389
  requestAnimationFrame(() => this.adjustSizeOnInput());
15380
15390
  }
@@ -15392,13 +15402,13 @@ class KritzelText extends KritzelBaseObject {
15392
15402
  }),
15393
15403
  editable: () => false,
15394
15404
  dispatchTransaction: transaction => {
15395
- const newState = this.editor.state.apply(transaction);
15396
- this.editor.updateState(newState);
15405
+ const newState = this._editor.state.apply(transaction);
15406
+ this._editor.updateState(newState);
15397
15407
  if (transaction.docChanged) {
15398
15408
  this.content = newState.doc.toJSON();
15399
15409
  this.adjustSizeOnInput();
15400
15410
  if (!transaction.getMeta('fromRemote')) {
15401
- this._core.store.state.objects.update(this, { temporary: true });
15411
+ this._core.store.objects.update(this, { temporary: true });
15402
15412
  }
15403
15413
  }
15404
15414
  },
@@ -15411,11 +15421,11 @@ class KritzelText extends KritzelBaseObject {
15411
15421
  */
15412
15422
  setContent(content) {
15413
15423
  this.content = content;
15414
- if (this.editor && content) {
15415
- const newDoc = this.editor.state.schema.nodeFromJSON(content);
15416
- const tr = this.editor.state.tr.replaceWith(0, this.editor.state.doc.content.size, newDoc.content);
15424
+ if (this._editor && content) {
15425
+ const newDoc = this._editor.state.schema.nodeFromJSON(content);
15426
+ const tr = this._editor.state.tr.replaceWith(0, this._editor.state.doc.content.size, newDoc.content);
15417
15427
  tr.setMeta('fromRemote', true);
15418
- this.editor.dispatch(tr);
15428
+ this._editor.dispatch(tr);
15419
15429
  }
15420
15430
  }
15421
15431
  /**
@@ -15469,7 +15479,7 @@ class KritzelText extends KritzelBaseObject {
15469
15479
  this.height = originalHeight * this.scaleFactor;
15470
15480
  this.translateX = x;
15471
15481
  this.translateY = y;
15472
- this._core.store.state.objects.update(this);
15482
+ this._core.store.objects.update(this);
15473
15483
  }
15474
15484
  /**
15475
15485
  * Focuses the text editor and optionally positions the cursor at specific coordinates.
@@ -15480,13 +15490,13 @@ class KritzelText extends KritzelBaseObject {
15480
15490
  * @param coords.y - Y coordinate for cursor placement.
15481
15491
  */
15482
15492
  focus(coords) {
15483
- if (this.editor) {
15484
- const doc = this.editor.state.doc;
15493
+ if (this._editor) {
15494
+ const doc = this._editor.state.doc;
15485
15495
  if (coords.x && coords.y && !this.isEmpty) {
15486
- const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
15496
+ const pos = this._editor.posAtCoords({ left: coords.x, top: coords.y });
15487
15497
  if (pos) {
15488
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
15489
- this.editor.focus();
15498
+ this._editor.dispatch(this._editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
15499
+ this._editor.focus();
15490
15500
  if (KritzelDevicesHelper.isIOS()) {
15491
15501
  this.scrollIntoViewOnIOS();
15492
15502
  }
@@ -15494,8 +15504,8 @@ class KritzelText extends KritzelBaseObject {
15494
15504
  }
15495
15505
  }
15496
15506
  const end = Math.max(1, doc.content.size - 1);
15497
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, end)));
15498
- this.editor.focus();
15507
+ this._editor.dispatch(this._editor.state.tr.setSelection(TextSelection.create(doc, end)));
15508
+ this._editor.focus();
15499
15509
  if (KritzelDevicesHelper.isIOS()) {
15500
15510
  this.scrollIntoViewOnIOS();
15501
15511
  }
@@ -15507,11 +15517,11 @@ class KritzelText extends KritzelBaseObject {
15507
15517
  */
15508
15518
  scrollIntoViewOnIOS() {
15509
15519
  setTimeout(() => {
15510
- if (this.editor && this.editor.dom) {
15511
- this.editor.dom.scrollIntoView({
15520
+ if (this._editor && this._editor.dom) {
15521
+ this._editor.dom.scrollIntoView({
15512
15522
  behavior: 'smooth',
15513
15523
  block: 'center',
15514
- inline: 'nearest'
15524
+ inline: 'nearest',
15515
15525
  });
15516
15526
  }
15517
15527
  }, 300);
@@ -15526,11 +15536,13 @@ class KritzelText extends KritzelBaseObject {
15526
15536
  KritzelKeyboardHelper.disableInteractiveWidget();
15527
15537
  this.uneditedObject = this.clone();
15528
15538
  this._core.store.setState('activeTool', KritzelToolRegistry.getTool('text'));
15529
- this.editor.setProps({ editable: () => true });
15539
+ this._editor.setProps({ editable: () => true });
15530
15540
  this.isEditing = true;
15531
15541
  this._core.rerender();
15532
15542
  this.adjustSizeOnInput();
15533
- this.focus({ x: event?.clientX, y: event?.clientY });
15543
+ if (event?.clientX && event?.clientY) {
15544
+ this.focus({ x: event?.clientX, y: event?.clientY });
15545
+ }
15534
15546
  KritzelKeyboardHelper.enableInteractiveWidget();
15535
15547
  }
15536
15548
  /**
@@ -15540,12 +15552,12 @@ class KritzelText extends KritzelBaseObject {
15540
15552
  */
15541
15553
  save() {
15542
15554
  requestAnimationFrame(() => this.adjustSizeOnInput());
15543
- this.content = this.editor.state.doc.toJSON();
15544
- this.editor.setProps({ editable: () => false });
15545
- this.editor.dom.blur();
15555
+ this.content = this._editor.state.doc.toJSON();
15556
+ this._editor.setProps({ editable: () => false });
15557
+ this._editor.dom.blur();
15546
15558
  this.isEditing = false;
15547
- this._core.store.state.objects.consolidateTemporaryItems();
15548
- this._core.store.state.objects.update(this);
15559
+ this._core.store.objects.consolidateTemporaryItems();
15560
+ this._core.store.objects.update(this);
15549
15561
  this._core.engine.emitObjectsChange();
15550
15562
  }
15551
15563
  /**
@@ -15723,7 +15735,7 @@ class KritzelPath extends KritzelBaseObject {
15723
15735
  const object = new KritzelPath();
15724
15736
  object._core = core;
15725
15737
  object.id = object.generateId();
15726
- object.workspaceId = core.store.state.activeWorkspace.id;
15738
+ object.workspaceId = core.store.activeWorkspace.id;
15727
15739
  object.userId = core.user?.id;
15728
15740
  object.options = options;
15729
15741
  object.points = options?.points ?? [];
@@ -15781,7 +15793,7 @@ class KritzelPath extends KritzelBaseObject {
15781
15793
  this.translateX = x;
15782
15794
  this.translateY = y;
15783
15795
  this._adjustedPoints = null;
15784
- this._core.store.state.objects.update(this);
15796
+ this._core.store.objects.update(this);
15785
15797
  }
15786
15798
  /**
15787
15799
  * Rotates the path by the specified angle.
@@ -15791,7 +15803,7 @@ class KritzelPath extends KritzelBaseObject {
15791
15803
  rotate(value) {
15792
15804
  this.rotation = value;
15793
15805
  this._adjustedPoints = null;
15794
- this._core.store.state.objects.update(this);
15806
+ this._core.store.objects.update(this);
15795
15807
  }
15796
15808
  /**
15797
15809
  * Moves the path by calculating the delta between start and end positions.
@@ -15807,7 +15819,7 @@ class KritzelPath extends KritzelBaseObject {
15807
15819
  this.translateX += deltaX;
15808
15820
  this.translateY += deltaY;
15809
15821
  this._adjustedPoints = null;
15810
- this._core.store.state.objects.update(this);
15822
+ this._core.store.objects.update(this);
15811
15823
  }
15812
15824
  /**
15813
15825
  * Tests whether a point intersects with the path's stroke.
@@ -15902,7 +15914,7 @@ class KritzelPath extends KritzelBaseObject {
15902
15914
  this.translateX = x;
15903
15915
  this.translateY = y;
15904
15916
  this._adjustedPoints = null;
15905
- this._core.store.state.objects.update(this);
15917
+ this._core.store.objects.update(this);
15906
15918
  }
15907
15919
  /**
15908
15920
  * Lifecycle hook called after properties have been updated.
@@ -16225,7 +16237,7 @@ class KritzelImage extends KritzelBaseObject {
16225
16237
  const object = new KritzelImage();
16226
16238
  object._core = core;
16227
16239
  object.id = object.generateId();
16228
- object.workspaceId = core.store.state.activeWorkspace.id;
16240
+ object.workspaceId = core.store.activeWorkspace.id;
16229
16241
  object.userId = core.user?.id;
16230
16242
  object.x = 0;
16231
16243
  object.y = 0;
@@ -16254,7 +16266,7 @@ class KritzelImage extends KritzelBaseObject {
16254
16266
  this.translateX = x;
16255
16267
  this.translateY = y;
16256
16268
  // Update to sync changes to y.js and propagate to other tabs
16257
- this._core.store.state.objects.update(this);
16269
+ this._core.store.objects.update(this);
16258
16270
  }
16259
16271
  /**
16260
16272
  * Creates a KritzelImage from a URL, handling image loading and dimension calculation.
@@ -16376,7 +16388,7 @@ class KritzelLine extends KritzelBaseObject {
16376
16388
  const object = new KritzelLine();
16377
16389
  object._core = core;
16378
16390
  object.id = object.generateId();
16379
- object.workspaceId = core.store.state.activeWorkspace.id;
16391
+ object.workspaceId = core.store.activeWorkspace.id;
16380
16392
  object.userId = core.user?.id;
16381
16393
  object.options = options;
16382
16394
  object.startX = options?.startX ?? 0;
@@ -16432,7 +16444,7 @@ class KritzelLine extends KritzelBaseObject {
16432
16444
  this.translateY = y;
16433
16445
  this._adjustedPoints = null;
16434
16446
  this._clipInfo = null;
16435
- this._core.store.state.objects.update(this);
16447
+ this._core.store.objects.update(this);
16436
16448
  // Update anchors after the line is updated
16437
16449
  this._core.anchorManager.updateAnchorsForObject(this.id);
16438
16450
  if (this.startAnchor) {
@@ -16451,7 +16463,7 @@ class KritzelLine extends KritzelBaseObject {
16451
16463
  this.rotation = value;
16452
16464
  this._adjustedPoints = null;
16453
16465
  this._clipInfo = null;
16454
- this._core.store.state.objects.update(this);
16466
+ this._core.store.objects.update(this);
16455
16467
  }
16456
16468
  /**
16457
16469
  * Moves the line by calculating the delta between start and end positions.
@@ -16475,7 +16487,7 @@ class KritzelLine extends KritzelBaseObject {
16475
16487
  }
16476
16488
  this._adjustedPoints = null;
16477
16489
  this._clipInfo = null;
16478
- this._core.store.state.objects.update(this);
16490
+ this._core.store.objects.update(this);
16479
16491
  }
16480
16492
  /**
16481
16493
  * Tests if a point intersects with the line within the stroke tolerance.
@@ -16602,7 +16614,7 @@ class KritzelLine extends KritzelBaseObject {
16602
16614
  this.translateY = y;
16603
16615
  this._adjustedPoints = null;
16604
16616
  this._clipInfo = null;
16605
- this._core.store.state.objects.update(this);
16617
+ this._core.store.objects.update(this);
16606
16618
  }
16607
16619
  /**
16608
16620
  * Updates a specific endpoint of the line (start or end).
@@ -16660,7 +16672,7 @@ class KritzelLine extends KritzelBaseObject {
16660
16672
  // Clear cached adjusted points
16661
16673
  this._adjustedPoints = null;
16662
16674
  this._clipInfo = null;
16663
- this._core.store.state.objects.update(this);
16675
+ this._core.store.objects.update(this);
16664
16676
  }
16665
16677
  /**
16666
16678
  * Updates the control point for a quadratic Bezier curve.
@@ -16710,7 +16722,7 @@ class KritzelLine extends KritzelBaseObject {
16710
16722
  // Clear cached adjusted points
16711
16723
  this._adjustedPoints = null;
16712
16724
  this._clipInfo = null;
16713
- this._core.store.state.objects.update(this);
16725
+ this._core.store.objects.update(this);
16714
16726
  }
16715
16727
  /**
16716
16728
  * Computes the line endpoints in world coordinates, accounting for rotation,
@@ -17114,7 +17126,7 @@ class KritzelGroup extends KritzelBaseObject {
17114
17126
  }
17115
17127
  return this.childIds
17116
17128
  .map(id => {
17117
- const found = this._core.store.state.objects.filter(obj => obj.id === id);
17129
+ const found = this._core.store.objects.filter(obj => obj.id === id);
17118
17130
  return found.length > 0 ? found[0] : null;
17119
17131
  })
17120
17132
  .filter((obj) => obj !== null);
@@ -17136,7 +17148,7 @@ class KritzelGroup extends KritzelBaseObject {
17136
17148
  const group = new KritzelGroup();
17137
17149
  group._core = core;
17138
17150
  group.id = group.generateId();
17139
- group.workspaceId = core.store.state.activeWorkspace.id;
17151
+ group.workspaceId = core.store.activeWorkspace.id;
17140
17152
  group.userId = core.user?.id;
17141
17153
  group.scale = core.store.state.scale;
17142
17154
  group.zIndex = core.store.currentZIndex;
@@ -17169,7 +17181,7 @@ class KritzelGroup extends KritzelBaseObject {
17169
17181
  * @returns The parent KritzelGroup if found, or null if the object is not a child of any group.
17170
17182
  */
17171
17183
  static findParentGroup(core, objectId) {
17172
- const allGroups = core.store.state.objects
17184
+ const allGroups = core.store.objects
17173
17185
  .filter(obj => obj.__class__ === 'KritzelGroup');
17174
17186
  for (const group of allGroups) {
17175
17187
  if (group.childIds.includes(objectId)) {
@@ -17355,8 +17367,8 @@ class KritzelGroup extends KritzelBaseObject {
17355
17367
  const deltaY = (startY - endY) / this._core.store.state.scale;
17356
17368
  this.translateX += deltaX;
17357
17369
  this.translateY += deltaY;
17358
- this._core.store.state.objects.transaction(() => {
17359
- this._core.store.state.objects.update(this);
17370
+ this._core.store.objects.transaction(() => {
17371
+ this._core.store.objects.update(this);
17360
17372
  this.children.forEach(child => {
17361
17373
  child.move(startX, startY, endX, endY);
17362
17374
  // Update any lines anchored to this child
@@ -17394,7 +17406,7 @@ class KritzelGroup extends KritzelBaseObject {
17394
17406
  const sin = Math.sin(-rotation);
17395
17407
  const cosR = Math.cos(rotation);
17396
17408
  const sinR = Math.sin(rotation);
17397
- this._core.store.state.objects.transaction(() => {
17409
+ this._core.store.objects.transaction(() => {
17398
17410
  this.children.forEach(child => {
17399
17411
  // Calculate child center
17400
17412
  const childCenterX = child.translateX + child.totalWidth / 2 / child.scale;
@@ -17432,7 +17444,7 @@ class KritzelGroup extends KritzelBaseObject {
17432
17444
  });
17433
17445
  this.refreshBoundingBox();
17434
17446
  this.captureChildSnapshots();
17435
- this._core.store.state.objects.update(this);
17447
+ this._core.store.objects.update(this);
17436
17448
  });
17437
17449
  }
17438
17450
  /**
@@ -17448,8 +17460,8 @@ class KritzelGroup extends KritzelBaseObject {
17448
17460
  const angle = value - this.snapshotRotation;
17449
17461
  const cos = Math.cos(angle);
17450
17462
  const sin = Math.sin(angle);
17451
- this._core.store.state.objects.transaction(() => {
17452
- this._core.store.state.objects.update(this);
17463
+ this._core.store.objects.transaction(() => {
17464
+ this._core.store.objects.update(this);
17453
17465
  this.children.forEach(child => {
17454
17466
  const unchangedSnapshot = this.unchangedChildSnapshots.get(child.id);
17455
17467
  if (!unchangedSnapshot)
@@ -17575,7 +17587,7 @@ class KritzelGroup extends KritzelBaseObject {
17575
17587
  * Triggers synchronization with y.js for collaborative editing.
17576
17588
  */
17577
17589
  update() {
17578
- this._core.store.state.objects.update(this);
17590
+ this._core.store.objects.update(this);
17579
17591
  }
17580
17592
  /**
17581
17593
  * Updates the workspace ID for this group and all its children recursively.
@@ -17633,6 +17645,12 @@ class KritzelShape extends KritzelBaseObject {
17633
17645
  get viewBox() {
17634
17646
  return `${this.x} ${this.y} ${this.width} ${this.height}`;
17635
17647
  }
17648
+ get _editor() {
17649
+ if (!this.editor) {
17650
+ throw new Error('KritzelShape: editor is not initialized');
17651
+ }
17652
+ return this.editor;
17653
+ }
17636
17654
  /**
17637
17655
  * Creates a new KritzelShape instance with optional configuration.
17638
17656
  * This constructor initializes the shape with default values that can be
@@ -17688,7 +17706,7 @@ class KritzelShape extends KritzelBaseObject {
17688
17706
  const object = new KritzelShape();
17689
17707
  object._core = core;
17690
17708
  object.id = object.generateId();
17691
- object.workspaceId = core.store.state.activeWorkspace.id;
17709
+ object.workspaceId = core.store.activeWorkspace.id;
17692
17710
  object.userId = core.user?.id;
17693
17711
  object.x = config?.x ?? 0;
17694
17712
  object.y = config?.y ?? 0;
@@ -17740,7 +17758,7 @@ class KritzelShape extends KritzelBaseObject {
17740
17758
  if (element === null || this.isInViewport() === false) {
17741
17759
  return;
17742
17760
  }
17743
- if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
17761
+ if (this.isMounted && this.elementRef === element && this._editor.dom.parentElement === element) {
17744
17762
  return;
17745
17763
  }
17746
17764
  this.elementRef = element;
@@ -17756,7 +17774,7 @@ class KritzelShape extends KritzelBaseObject {
17756
17774
  * @returns void
17757
17775
  */
17758
17776
  mountTextEditor(element) {
17759
- if (element === null) {
17777
+ if (element === null || !this.editor) {
17760
17778
  return;
17761
17779
  }
17762
17780
  element.style.fontFamily = this.fontFamily;
@@ -17787,12 +17805,12 @@ class KritzelShape extends KritzelBaseObject {
17787
17805
  }),
17788
17806
  editable: () => false,
17789
17807
  dispatchTransaction: transaction => {
17790
- const newState = this.editor.state.apply(transaction);
17791
- this.editor.updateState(newState);
17808
+ const newState = this._editor.state.apply(transaction);
17809
+ this._editor.updateState(newState);
17792
17810
  if (transaction.docChanged) {
17793
17811
  this.content = newState.doc.toJSON();
17794
17812
  if (!transaction.getMeta('fromRemote')) {
17795
- this._core.store.state.objects.update(this, { temporary: true });
17813
+ this._core.store.objects.update(this, { temporary: true });
17796
17814
  }
17797
17815
  }
17798
17816
  },
@@ -17836,7 +17854,7 @@ class KritzelShape extends KritzelBaseObject {
17836
17854
  this.height = height;
17837
17855
  this.translateX = x;
17838
17856
  this.translateY = y;
17839
- this._core.store.state.objects.update(this);
17857
+ this._core.store.objects.update(this);
17840
17858
  }
17841
17859
  /**
17842
17860
  * Focuses the text editor and optionally positions the cursor at specific coordinates.
@@ -17850,25 +17868,23 @@ class KritzelShape extends KritzelBaseObject {
17850
17868
  * @returns void
17851
17869
  */
17852
17870
  focus(coords) {
17853
- if (this.editor) {
17854
- const doc = this.editor.state.doc;
17855
- if (coords?.x && coords?.y) {
17856
- const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
17857
- if (pos) {
17858
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
17859
- this.editor.focus();
17860
- if (KritzelDevicesHelper.isIOS()) {
17861
- this.scrollIntoViewOnIOS();
17862
- }
17863
- return;
17871
+ const doc = this._editor.state.doc;
17872
+ if (coords?.x && coords?.y) {
17873
+ const pos = this._editor.posAtCoords({ left: coords.x, top: coords.y });
17874
+ if (pos) {
17875
+ this._editor.dispatch(this._editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
17876
+ this._editor.focus();
17877
+ if (KritzelDevicesHelper.isIOS()) {
17878
+ this.scrollIntoViewOnIOS();
17864
17879
  }
17880
+ return;
17865
17881
  }
17866
- const end = Math.max(1, doc.content.size - 1);
17867
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, end)));
17868
- this.editor.focus();
17869
- if (KritzelDevicesHelper.isIOS()) {
17870
- this.scrollIntoViewOnIOS();
17871
- }
17882
+ }
17883
+ const end = Math.max(1, doc.content.size - 1);
17884
+ this._editor.dispatch(this._editor.state.tr.setSelection(TextSelection.create(doc, end)));
17885
+ this._editor.focus();
17886
+ if (KritzelDevicesHelper.isIOS()) {
17887
+ this.scrollIntoViewOnIOS();
17872
17888
  }
17873
17889
  }
17874
17890
  /**
@@ -17904,10 +17920,12 @@ class KritzelShape extends KritzelBaseObject {
17904
17920
  KritzelKeyboardHelper.disableInteractiveWidget();
17905
17921
  this.uneditedObject = this.clone();
17906
17922
  this._core.store.setState('activeTool', KritzelToolRegistry.getTool('shape'));
17907
- this.editor.setProps({ editable: () => true });
17923
+ this._editor.setProps({ editable: () => true });
17908
17924
  this.isEditing = true;
17909
17925
  this._core.rerender();
17910
- this.focus({ x: event?.clientX, y: event?.clientY });
17926
+ if (event?.clientX && event?.clientY) {
17927
+ this.focus({ x: event.clientX, y: event.clientY });
17928
+ }
17911
17929
  KritzelKeyboardHelper.enableInteractiveWidget();
17912
17930
  }
17913
17931
  /**
@@ -17919,12 +17937,12 @@ class KritzelShape extends KritzelBaseObject {
17919
17937
  * @returns void
17920
17938
  */
17921
17939
  save() {
17922
- this.content = this.editor.state.doc.toJSON();
17923
- this.editor.setProps({ editable: () => false });
17924
- this.editor.dom.blur();
17940
+ this.content = this._editor.state.doc.toJSON();
17941
+ this._editor.setProps({ editable: () => false });
17942
+ this._editor.dom.blur();
17925
17943
  this.isEditing = false;
17926
- this._core.store.state.objects.consolidateTemporaryItems();
17927
- this._core.store.state.objects.update(this);
17944
+ this._core.store.objects.consolidateTemporaryItems();
17945
+ this._core.store.objects.update(this);
17928
17946
  this._core.engine.emitObjectsChange();
17929
17947
  }
17930
17948
  /**
@@ -18369,8 +18387,8 @@ class KritzelBrushTool extends KritzelBaseTool {
18369
18387
  });
18370
18388
  path.isCompleted = false;
18371
18389
  this._currentPathId = path.id;
18372
- this._core.store.state.objects.insert(path);
18373
- this._core.store.state.objects?.setActiveDrawingObject(path.id);
18390
+ this._core.store.objects.insert(path);
18391
+ this._core.store.objects?.setActiveDrawingObject(path.id);
18374
18392
  }
18375
18393
  }
18376
18394
  if (event.pointerType === 'touch' || event.pointerType === 'pen') {
@@ -18393,8 +18411,8 @@ class KritzelBrushTool extends KritzelBaseTool {
18393
18411
  });
18394
18412
  path.isCompleted = false;
18395
18413
  this._currentPathId = path.id;
18396
- this._core.store.state.objects.insert(path);
18397
- this._core.store.state.objects?.setActiveDrawingObject(path.id);
18414
+ this._core.store.objects.insert(path);
18415
+ this._core.store.objects?.setActiveDrawingObject(path.id);
18398
18416
  }
18399
18417
  }
18400
18418
  }
@@ -18410,7 +18428,7 @@ class KritzelBrushTool extends KritzelBaseTool {
18410
18428
  }
18411
18429
  if (event.pointerType === 'mouse') {
18412
18430
  if (this._core.store.state.isDrawing && this._currentPathId) {
18413
- const currentPath = this._core.store.state.objects.findById(this._currentPathId);
18431
+ const currentPath = this._core.store.objects.findById(this._currentPathId);
18414
18432
  if (currentPath) {
18415
18433
  const viewportScale = this._core.store.state.scale;
18416
18434
  const lockScale = this._core.store.state.lockDrawingScale;
@@ -18430,7 +18448,7 @@ class KritzelBrushTool extends KritzelBaseTool {
18430
18448
  updatedPath.workspaceId = currentPath.workspaceId;
18431
18449
  updatedPath.zIndex = currentPath.zIndex;
18432
18450
  updatedPath.isCompleted = false;
18433
- this._core.store.state.objects.update(updatedPath);
18451
+ this._core.store.objects.update(updatedPath);
18434
18452
  }
18435
18453
  }
18436
18454
  }
@@ -18438,7 +18456,7 @@ class KritzelBrushTool extends KritzelBaseTool {
18438
18456
  const activePointers = Array.from(this._core.store.state.pointers.values());
18439
18457
  if (activePointers.length === 1) {
18440
18458
  if (this._currentPathId) {
18441
- const currentPath = this._core.store.state.objects.findById(this._currentPathId);
18459
+ const currentPath = this._core.store.objects.findById(this._currentPathId);
18442
18460
  if (currentPath) {
18443
18461
  const viewportScale = this._core.store.state.scale;
18444
18462
  const lockScale = this._core.store.state.lockDrawingScale;
@@ -18458,7 +18476,7 @@ class KritzelBrushTool extends KritzelBaseTool {
18458
18476
  updatedPath.workspaceId = currentPath.workspaceId;
18459
18477
  updatedPath.zIndex = currentPath.zIndex;
18460
18478
  updatedPath.isCompleted = false;
18461
- this._core.store.state.objects.update(updatedPath);
18479
+ this._core.store.objects.update(updatedPath);
18462
18480
  }
18463
18481
  }
18464
18482
  }
@@ -18478,14 +18496,14 @@ class KritzelBrushTool extends KritzelBaseTool {
18478
18496
  if (this._core.store.state.isDrawing) {
18479
18497
  this._core.store.state.isDrawing = false;
18480
18498
  if (this._currentPathId) {
18481
- const currentPath = this._core.store.state.objects.findById(this._currentPathId);
18499
+ const currentPath = this._core.store.objects.findById(this._currentPathId);
18482
18500
  if (currentPath) {
18483
18501
  currentPath.isCompleted = true;
18484
- this._core.store.state.objects.update(currentPath);
18502
+ this._core.store.objects.update(currentPath);
18485
18503
  this._core.engine.emitObjectsChange();
18486
18504
  this._core.engine.emitObjectsAdded([currentPath]);
18487
18505
  }
18488
- this._core.store.state.objects?.setActiveDrawingObject(null);
18506
+ this._core.store.objects?.setActiveDrawingObject(null);
18489
18507
  this._currentPathId = null;
18490
18508
  }
18491
18509
  }
@@ -18494,14 +18512,14 @@ class KritzelBrushTool extends KritzelBaseTool {
18494
18512
  if (this._core.store.state.isDrawing) {
18495
18513
  this._core.store.state.isDrawing = false;
18496
18514
  if (this._currentPathId) {
18497
- const currentPath = this._core.store.state.objects.findById(this._currentPathId);
18515
+ const currentPath = this._core.store.objects.findById(this._currentPathId);
18498
18516
  if (currentPath) {
18499
18517
  currentPath.isCompleted = true;
18500
- this._core.store.state.objects.update(currentPath);
18518
+ this._core.store.objects.update(currentPath);
18501
18519
  this._core.engine.emitObjectsChange();
18502
18520
  this._core.engine.emitObjectsAdded([currentPath]);
18503
18521
  }
18504
- this._core.store.state.objects?.setActiveDrawingObject(null);
18522
+ this._core.store.objects?.setActiveDrawingObject(null);
18505
18523
  this._currentPathId = null;
18506
18524
  }
18507
18525
  }
@@ -18529,10 +18547,10 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18529
18547
  snapshotTranslateX = 0;
18530
18548
  snapshotTranslateY = 0;
18531
18549
  clientId;
18532
- minX;
18533
- maxX;
18534
- minY;
18535
- maxY;
18550
+ minX = 0;
18551
+ maxX = 0;
18552
+ minY = 0;
18553
+ maxY = 0;
18536
18554
  // Selection styling properties
18537
18555
  handleColor;
18538
18556
  handleStrokeColor;
@@ -18572,7 +18590,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18572
18590
  return this._cachedObjects;
18573
18591
  }
18574
18592
  const idSet = new Set(this._objectIds);
18575
- const foundObjects = this._core.store.state.objects.filter(obj => idSet.has(obj.id));
18593
+ const foundObjects = this._core.store.objects.filter(obj => idSet.has(obj.id));
18576
18594
  // Preserve the original order from objectIds
18577
18595
  const objectMap = new Map(foundObjects.map(obj => [obj.id, obj]));
18578
18596
  this._cachedObjects = this._objectIds
@@ -18599,9 +18617,9 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18599
18617
  const object = new KritzelSelectionGroup();
18600
18618
  object._core = core;
18601
18619
  object.id = object.generateId();
18602
- object.workspaceId = core.store.state.activeWorkspace.id;
18620
+ object.workspaceId = core.store.activeWorkspace.id;
18603
18621
  object.userId = core.user?.id;
18604
- object.clientId = core.store.state.objects?.localClientId ?? undefined;
18622
+ object.clientId = core.store.objects?.localClientId ?? undefined;
18605
18623
  object.scale = core.store.state.scale;
18606
18624
  object.zIndex = 99999;
18607
18625
  // Initialize styling with theme-aware defaults
@@ -18740,7 +18758,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18740
18758
  });
18741
18759
  this.translateX = x;
18742
18760
  this.translateY = y;
18743
- this._core.store.state.objects.update(this);
18761
+ this._core.store.objects.update(this);
18744
18762
  }
18745
18763
  /**
18746
18764
  * Capture snapshots of current object states for undo/redo operations
@@ -18817,7 +18835,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18817
18835
  // Only update the selection group itself
18818
18836
  // Child objects are already updated during move/resize/rotate operations
18819
18837
  // Updating them again here would create redundant y.js updates
18820
- this._core.store.state.objects.update(this);
18838
+ this._core.store.objects.update(this);
18821
18839
  }
18822
18840
  /**
18823
18841
  * Moves the selection group and all its contained objects by calculating the delta from drag coordinates.
@@ -18833,8 +18851,8 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18833
18851
  const deltaY = (startY - endY) / this._core.store.state.scale;
18834
18852
  this.translateX += deltaX;
18835
18853
  this.translateY += deltaY;
18836
- this._core.store.state.objects.transaction(() => {
18837
- this._core.store.state.objects.update(this);
18854
+ this._core.store.objects.transaction(() => {
18855
+ this._core.store.objects.update(this);
18838
18856
  const children = this.objects;
18839
18857
  for (const obj of children) {
18840
18858
  obj.move(startX, startY, endX, endY);
@@ -18877,7 +18895,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18877
18895
  const sin = Math.sin(-rotation);
18878
18896
  const cosR = Math.cos(rotation);
18879
18897
  const sinR = Math.sin(rotation);
18880
- this._core.store.state.objects.transaction(() => {
18898
+ this._core.store.objects.transaction(() => {
18881
18899
  // Cache objects once to avoid repeated getter calls during resize
18882
18900
  const children = this.objects;
18883
18901
  children.forEach(child => {
@@ -18929,7 +18947,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18929
18947
  // Note: Don't capture new snapshots here - we need to preserve the original snapshots
18930
18948
  // until the transform operation is complete to avoid compounding errors during drag
18931
18949
  this.refreshObjectDimensions(children);
18932
- this._core.store.state.objects.update(this);
18950
+ this._core.store.objects.update(this);
18933
18951
  });
18934
18952
  }
18935
18953
  /**
@@ -18947,9 +18965,9 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18947
18965
  const sin = Math.sin(angle);
18948
18966
  // Cache objects once to avoid repeated getter calls during rotation
18949
18967
  const children = this.objects;
18950
- this._core.store.state.objects.transaction(() => {
18968
+ this._core.store.objects.transaction(() => {
18951
18969
  // Update the SelectionGroup itself to propagate rotation to other tabs
18952
- this._core.store.state.objects.update(this);
18970
+ this._core.store.objects.update(this);
18953
18971
  const childCount = children.length;
18954
18972
  for (const child of children) {
18955
18973
  const unchangedSnapshot = this.unchangedObjectSnapshots.get(child.id);
@@ -19046,7 +19064,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
19046
19064
  this.translateY = cy - (this.height / this.scale + 2 * this.padding) / 2;
19047
19065
  }
19048
19066
  if (!skipPersist) {
19049
- this._core.store.state.objects.update(this);
19067
+ this._core.store.objects.update(this);
19050
19068
  }
19051
19069
  }
19052
19070
  /**
@@ -19164,8 +19182,8 @@ class KritzelLineTool extends KritzelBaseTool {
19164
19182
  });
19165
19183
  line.isCompleted = false;
19166
19184
  this._currentLineId = line.id;
19167
- this._core.store.state.objects.insert(line);
19168
- this._core.store.state.objects?.setActiveDrawingObject(line.id);
19185
+ this._core.store.objects.insert(line);
19186
+ this._core.store.objects?.setActiveDrawingObject(line.id);
19169
19187
  }
19170
19188
  }
19171
19189
  if (event.pointerType === 'touch' || event.pointerType === 'pen') {
@@ -19194,8 +19212,8 @@ class KritzelLineTool extends KritzelBaseTool {
19194
19212
  });
19195
19213
  line.isCompleted = false;
19196
19214
  this._currentLineId = line.id;
19197
- this._core.store.state.objects.insert(line);
19198
- this._core.store.state.objects?.setActiveDrawingObject(line.id);
19215
+ this._core.store.objects.insert(line);
19216
+ this._core.store.objects?.setActiveDrawingObject(line.id);
19199
19217
  }
19200
19218
  }
19201
19219
  }
@@ -19211,7 +19229,7 @@ class KritzelLineTool extends KritzelBaseTool {
19211
19229
  }
19212
19230
  if (event.pointerType === 'mouse') {
19213
19231
  if (this._core.store.state.isDrawing && this._currentLineId) {
19214
- const currentLine = this._core.store.state.objects.findById(this._currentLineId);
19232
+ const currentLine = this._core.store.objects.findById(this._currentLineId);
19215
19233
  if (currentLine) {
19216
19234
  const viewportScale = this._core.store.state.scale;
19217
19235
  const lockScale = this._core.store.state.lockDrawingScale;
@@ -19235,14 +19253,14 @@ class KritzelLineTool extends KritzelBaseTool {
19235
19253
  updatedLine.workspaceId = currentLine.workspaceId;
19236
19254
  updatedLine.zIndex = currentLine.zIndex;
19237
19255
  updatedLine.isCompleted = false;
19238
- this._core.store.state.objects.update(updatedLine);
19256
+ this._core.store.objects.update(updatedLine);
19239
19257
  }
19240
19258
  }
19241
19259
  }
19242
19260
  if (event.pointerType === 'touch' || event.pointerType === 'pen') {
19243
19261
  const activePointers = Array.from(this._core.store.state.pointers.values());
19244
19262
  if (activePointers.length === 1 && this._currentLineId) {
19245
- const currentLine = this._core.store.state.objects.findById(this._currentLineId);
19263
+ const currentLine = this._core.store.objects.findById(this._currentLineId);
19246
19264
  if (currentLine) {
19247
19265
  const viewportScale = this._core.store.state.scale;
19248
19266
  const lockScale = this._core.store.state.lockDrawingScale;
@@ -19266,7 +19284,7 @@ class KritzelLineTool extends KritzelBaseTool {
19266
19284
  updatedLine.workspaceId = currentLine.workspaceId;
19267
19285
  updatedLine.zIndex = currentLine.zIndex;
19268
19286
  updatedLine.isCompleted = false;
19269
- this._core.store.state.objects.update(updatedLine);
19287
+ this._core.store.objects.update(updatedLine);
19270
19288
  }
19271
19289
  }
19272
19290
  }
@@ -19285,16 +19303,16 @@ class KritzelLineTool extends KritzelBaseTool {
19285
19303
  if (this._core.store.state.isDrawing) {
19286
19304
  this._core.store.state.isDrawing = false;
19287
19305
  if (this._currentLineId) {
19288
- const currentLine = this._core.store.state.objects.findById(this._currentLineId);
19306
+ const currentLine = this._core.store.objects.findById(this._currentLineId);
19289
19307
  if (currentLine) {
19290
19308
  currentLine.isCompleted = true;
19291
- this._core.store.state.objects.update(currentLine);
19309
+ this._core.store.objects.update(currentLine);
19292
19310
  this._core.engine.emitObjectsChange();
19293
19311
  this._core.engine.emitObjectsAdded([currentLine]);
19294
19312
  // Switch to selection tool and select the drawn line
19295
19313
  this.selectLineAndSwitchTool(currentLine);
19296
19314
  }
19297
- this._core.store.state.objects?.setActiveDrawingObject(null);
19315
+ this._core.store.objects?.setActiveDrawingObject(null);
19298
19316
  this._currentLineId = null;
19299
19317
  }
19300
19318
  }
@@ -19303,16 +19321,16 @@ class KritzelLineTool extends KritzelBaseTool {
19303
19321
  if (this._core.store.state.isDrawing) {
19304
19322
  this._core.store.state.isDrawing = false;
19305
19323
  if (this._currentLineId) {
19306
- const currentLine = this._core.store.state.objects.findById(this._currentLineId);
19324
+ const currentLine = this._core.store.objects.findById(this._currentLineId);
19307
19325
  if (currentLine) {
19308
19326
  currentLine.isCompleted = true;
19309
- this._core.store.state.objects.update(currentLine);
19327
+ this._core.store.objects.update(currentLine);
19310
19328
  this._core.engine.emitObjectsChange();
19311
19329
  this._core.engine.emitObjectsAdded([currentLine]);
19312
19330
  // Switch to selection tool and select the drawn line
19313
19331
  this.selectLineAndSwitchTool(currentLine);
19314
19332
  }
19315
- this._core.store.state.objects?.setActiveDrawingObject(null);
19333
+ this._core.store.objects?.setActiveDrawingObject(null);
19316
19334
  this._currentLineId = null;
19317
19335
  }
19318
19336
  }
@@ -19499,7 +19517,7 @@ class KritzelImageTool extends KritzelBaseTool {
19499
19517
  if (this._core.store.isDisabled) {
19500
19518
  return;
19501
19519
  }
19502
- this.fileInput.click();
19520
+ this.fileInput?.click();
19503
19521
  }
19504
19522
  /**
19505
19523
  * Creates and configures the hidden file input element.
@@ -19663,7 +19681,7 @@ class KritzelTextTool extends KritzelBaseTool {
19663
19681
  text.translateX = (clientX - this._core.store.state.translateX) / viewportScale;
19664
19682
  text.translateY = (clientY - this._core.store.state.translateY) / viewportScale;
19665
19683
  text.zIndex = this._core.store.currentZIndex;
19666
- this._core.store.state.objects.insert(text);
19684
+ this._core.store.objects.insert(text);
19667
19685
  this._core.rerender();
19668
19686
  text.edit(event);
19669
19687
  }
@@ -19700,7 +19718,7 @@ class KritzelTextTool extends KritzelBaseTool {
19700
19718
  text.translateX = (clientX - this._core.store.state.translateX) / viewportScale;
19701
19719
  text.translateY = (clientY - this._core.store.state.translateY) / viewportScale;
19702
19720
  text.zIndex = this._core.store.currentZIndex;
19703
- this._core.store.state.objects.insert(text);
19721
+ this._core.store.objects.insert(text);
19704
19722
  this._core.rerender();
19705
19723
  text.edit(event);
19706
19724
  }
@@ -19893,8 +19911,8 @@ class KritzelShapeTool extends KritzelBaseTool {
19893
19911
  fontFamily: this.fontFamily,
19894
19912
  scale: lockScale ? 1 : viewportScale,
19895
19913
  });
19896
- this._core.store.state.objects.insert(this.currentShape);
19897
- this._core.store.state.objects?.setActiveDrawingObject(this.currentShape.id);
19914
+ this._core.store.objects.insert(this.currentShape);
19915
+ this._core.store.objects?.setActiveDrawingObject(this.currentShape.id);
19898
19916
  this._core.rerender();
19899
19917
  }
19900
19918
  /**
@@ -19928,7 +19946,7 @@ class KritzelShapeTool extends KritzelBaseTool {
19928
19946
  this.currentShape.translateX = -this._core.store.state.translateX / divider;
19929
19947
  this.currentShape.translateY = -this._core.store.state.translateY / divider;
19930
19948
  this.currentShape.updateDimensions();
19931
- this._core.store.state.objects.update(this.currentShape);
19949
+ this._core.store.objects.update(this.currentShape);
19932
19950
  }
19933
19951
  /**
19934
19952
  * Completes the shape drawing process.
@@ -19944,18 +19962,18 @@ class KritzelShapeTool extends KritzelBaseTool {
19944
19962
  // Compare in screen space
19945
19963
  if (this.currentShape.width < 10 && this.currentShape.height < 10) {
19946
19964
  const shapeId = this.currentShape.id;
19947
- this._core.store.state.objects.remove(o => o.id === shapeId);
19965
+ this._core.store.objects.remove(o => o.id === shapeId);
19948
19966
  }
19949
19967
  else {
19950
19968
  this.currentShape.zIndex = this._core.store.currentZIndex;
19951
- this._core.store.state.objects.update(this.currentShape);
19969
+ this._core.store.objects.update(this.currentShape);
19952
19970
  this._core.engine.emitObjectsChange();
19953
19971
  this._core.engine.emitObjectsAdded([this.currentShape]);
19954
19972
  this._core.selectObjects([this.currentShape]);
19955
19973
  this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
19956
19974
  }
19957
19975
  this.isDrawing = false;
19958
- this._core.store.state.objects?.setActiveDrawingObject(null);
19976
+ this._core.store.objects?.setActiveDrawingObject(null);
19959
19977
  this.currentShape = null;
19960
19978
  this._core.rerender();
19961
19979
  }
@@ -20162,17 +20180,17 @@ const ANCHOR_DISCONNECT_THRESHOLD = 30;
20162
20180
  */
20163
20181
  class KritzelMoveHandler extends KritzelBaseHandler {
20164
20182
  /** X coordinate where the drag started (updates during drag for incremental movement) */
20165
- dragStartX;
20183
+ dragStartX = 0;
20166
20184
  /** Y coordinate where the drag started (updates during drag for incremental movement) */
20167
- dragStartY;
20185
+ dragStartY = 0;
20168
20186
  /** Initial X coordinate when starting interaction (remains constant during drag) */
20169
- startX;
20187
+ startX = 0;
20170
20188
  /** Initial Y coordinate when starting interaction (remains constant during drag) */
20171
- startY;
20189
+ startY = 0;
20172
20190
  /** Current X coordinate during move operation */
20173
- endX;
20191
+ endX = 0;
20174
20192
  /** Current Y coordinate during move operation */
20175
- endY;
20193
+ endY = 0;
20176
20194
  /** Initial position when drag started (for calculating total accumulated distance) */
20177
20195
  initialDragX = 0;
20178
20196
  initialDragY = 0;
@@ -20330,7 +20348,10 @@ class KritzelMoveHandler extends KritzelBaseHandler {
20330
20348
  const moveDeltaY = Math.abs(y - this.startY);
20331
20349
  const moveThreshold = 5;
20332
20350
  if (this.hasMoved || moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
20333
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20351
+ const timeout = this._core.store.state.longTouchTimeout;
20352
+ if (timeout) {
20353
+ globalThis.clearTimeout?.(timeout);
20354
+ }
20334
20355
  // Check for anchor disconnect threshold on lines
20335
20356
  this.checkAndDisconnectAnchors(x, y);
20336
20357
  selectionGroup.move(x, y, this.dragStartX, this.dragStartY);
@@ -20429,7 +20450,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
20429
20450
  // Mark as disconnected so we don't try again
20430
20451
  this.disconnectedLineIds.add(line.id);
20431
20452
  // Update the line to persist the change
20432
- this._core.store.state.objects.update(line);
20453
+ this._core.store.objects.update(line);
20433
20454
  }
20434
20455
  }
20435
20456
  }
@@ -20526,7 +20547,10 @@ class KritzelResizeHandler extends KritzelBaseHandler {
20526
20547
  this.initialSize.height = selectionGroup.height;
20527
20548
  this.initialSize.x = selectionGroup.translateX;
20528
20549
  this.initialSize.y = selectionGroup.translateY;
20529
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20550
+ const timeout = this._core.store.state.longTouchTimeout;
20551
+ if (timeout) {
20552
+ globalThis.clearTimeout?.(timeout);
20553
+ }
20530
20554
  }
20531
20555
  }
20532
20556
  }
@@ -20621,7 +20645,10 @@ class KritzelResizeHandler extends KritzelBaseHandler {
20621
20645
  const resizeDeltaY = Math.abs(dy);
20622
20646
  const resizeThreshold = 5;
20623
20647
  if (resizeDeltaX > resizeThreshold || resizeDeltaY > resizeThreshold) {
20624
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20648
+ const timeout = this._core.store.state.longTouchTimeout;
20649
+ if (timeout) {
20650
+ globalThis.clearTimeout?.(timeout);
20651
+ }
20625
20652
  this.hasResized = true;
20626
20653
  }
20627
20654
  if (!this.hasResized) {
@@ -20730,7 +20757,10 @@ class KritzelResizeHandler extends KritzelBaseHandler {
20730
20757
  this._core.store.state.hasObjectsChanged = true;
20731
20758
  }
20732
20759
  this.reset();
20733
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20760
+ const timeout = this._core.store.state.longTouchTimeout;
20761
+ if (timeout) {
20762
+ globalThis.clearTimeout?.(timeout);
20763
+ }
20734
20764
  }
20735
20765
  }
20736
20766
  }
@@ -20808,7 +20838,10 @@ class KritzelRotationHandler extends KritzelBaseHandler {
20808
20838
  const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;
20809
20839
  this.initialSelectionGroupRotation = selectionGroup.rotation;
20810
20840
  this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - selectionGroup.rotation;
20811
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20841
+ const timeout = this._core.store.state.longTouchTimeout;
20842
+ if (timeout) {
20843
+ globalThis.clearTimeout?.(timeout);
20844
+ }
20812
20845
  }
20813
20846
  }
20814
20847
  }
@@ -20853,7 +20886,10 @@ class KritzelRotationHandler extends KritzelBaseHandler {
20853
20886
  const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
20854
20887
  this.rotation = currentRotation - this.initialRotation;
20855
20888
  selectionGroup.rotate(this.rotation);
20856
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20889
+ const timeout = this._core.store.state.longTouchTimeout;
20890
+ if (timeout) {
20891
+ globalThis.clearTimeout?.(timeout);
20892
+ }
20857
20893
  }
20858
20894
  }
20859
20895
  }
@@ -20880,7 +20916,10 @@ class KritzelRotationHandler extends KritzelBaseHandler {
20880
20916
  this._core.store.state.isRotating = false;
20881
20917
  this._core.store.state.hasObjectsChanged = true;
20882
20918
  this.reset();
20883
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20919
+ const timeout = this._core.store.state.longTouchTimeout;
20920
+ if (timeout) {
20921
+ globalThis.clearTimeout?.(timeout);
20922
+ }
20884
20923
  }
20885
20924
  }
20886
20925
  }
@@ -20905,7 +20944,7 @@ class KritzelSelectionBox extends KritzelBaseObject {
20905
20944
  const object = new KritzelSelectionBox();
20906
20945
  object._core = core;
20907
20946
  object.id = object.generateId();
20908
- object.workspaceId = core.store.state.activeWorkspace.id;
20947
+ object.workspaceId = core.store.activeWorkspace.id;
20909
20948
  object.userId = core.user?.id;
20910
20949
  object.scale = core.store.state.scale;
20911
20950
  object.zIndex = 99999;
@@ -20925,8 +20964,8 @@ class KritzelSelectionBox extends KritzelBaseObject {
20925
20964
  * via shift/ctrl modifiers.
20926
20965
  */
20927
20966
  class KritzelSelectionHandler extends KritzelBaseHandler {
20928
- startX;
20929
- startY;
20967
+ startX = 0;
20968
+ startY = 0;
20930
20969
  touchStartX = 0;
20931
20970
  touchStartY = 0;
20932
20971
  touchStartTimeout = null;
@@ -21004,7 +21043,10 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21004
21043
  const moveThreshold = 5;
21005
21044
  if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._core.store.state.isSelecting) {
21006
21045
  this.updateTouchSelection();
21007
- clearTimeout(this._core.store.state.longTouchTimeout);
21046
+ const timeout = this._core.store.state.longTouchTimeout;
21047
+ if (timeout) {
21048
+ globalThis.clearTimeout?.(timeout);
21049
+ }
21008
21050
  }
21009
21051
  }
21010
21052
  }
@@ -21069,9 +21111,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21069
21111
  */
21070
21112
  removeSelectionBox() {
21071
21113
  this._core.store.state.isSelecting = false;
21072
- this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox);
21114
+ this._core.store.objects.remove(o => o instanceof KritzelSelectionBox);
21073
21115
  this._core.store.setSelectionBox(null);
21074
- this._core.store.state.objects.clearLocalSelectionBox();
21116
+ this._core.store.objects.clearLocalSelectionBox();
21075
21117
  }
21076
21118
  /**
21077
21119
  * Initiates a mouse-based selection by creating a selection box at the click position.
@@ -21090,12 +21132,12 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21090
21132
  selectionBox.translateX = this.startX;
21091
21133
  selectionBox.translateY = this.startY;
21092
21134
  this._core.store.state.isSelecting = true;
21093
- this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup && (o.userId == null || o.userId === this._core.user?.id)));
21135
+ this._core.store.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup && (o.userId == null || o.userId === this._core.user?.id)));
21094
21136
  this._core.store.setSelectionBox(null);
21095
21137
  if (!isAdditive) {
21096
21138
  this._core.store.setSelectionGroup(null);
21097
21139
  }
21098
- this._core.store.state.objects.insert(selectionBox);
21140
+ this._core.store.objects.insert(selectionBox);
21099
21141
  this._core.store.setSelectionBox(selectionBox);
21100
21142
  }
21101
21143
  /**
@@ -21122,12 +21164,12 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21122
21164
  selectionBox.translateX = this.startX;
21123
21165
  selectionBox.translateY = this.startY;
21124
21166
  this._core.store.state.isSelecting = true;
21125
- this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup && (o.userId == null || o.userId === this._core.user?.id)));
21167
+ this._core.store.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup && (o.userId == null || o.userId === this._core.user?.id)));
21126
21168
  this._core.store.setSelectionBox(null);
21127
21169
  if (!isAdditive) {
21128
21170
  this._core.store.setSelectionGroup(null);
21129
21171
  }
21130
- this._core.store.state.objects.insert(selectionBox);
21172
+ this._core.store.objects.insert(selectionBox);
21131
21173
  this._core.store.setSelectionBox(selectionBox);
21132
21174
  }
21133
21175
  /**
@@ -21150,7 +21192,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21150
21192
  selectionBox.height = height;
21151
21193
  selectionBox.translateX = Math.min(currentX, this.startX);
21152
21194
  selectionBox.translateY = Math.min(currentY, this.startY);
21153
- this._core.store.state.objects.setLocalSelectionBox({
21195
+ this._core.store.objects.setLocalSelectionBox({
21154
21196
  x: selectionBox.translateX,
21155
21197
  y: selectionBox.translateY,
21156
21198
  width: width / selectionBox.scale,
@@ -21189,7 +21231,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21189
21231
  selectionBox.height = height;
21190
21232
  selectionBox.translateX = Math.min(currentX, this.startX);
21191
21233
  selectionBox.translateY = Math.min(currentY, this.startY);
21192
- this._core.store.state.objects.setLocalSelectionBox({
21234
+ this._core.store.objects.setLocalSelectionBox({
21193
21235
  x: selectionBox.translateX,
21194
21236
  y: selectionBox.translateY,
21195
21237
  width: width / selectionBox.scale,
@@ -21229,9 +21271,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21229
21271
  y: minY,
21230
21272
  z: selectionBox.scale,
21231
21273
  width: maxX - minX,
21232
- height: maxY - minY
21274
+ height: maxY - minY,
21233
21275
  };
21234
- const candidates = this._core.store.state.objects.query(selectionBounds);
21276
+ const candidates = this._core.store.objects.query(selectionBounds);
21235
21277
  // Track newly selected objects for efficient comparison
21236
21278
  const newlySelectedObjects = new Set();
21237
21279
  // Only test candidates that overlap the bounding box
@@ -21263,7 +21305,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21263
21305
  const selectedObject = this.getTopmostHitObject(event);
21264
21306
  const isAdditive = event.shiftKey || event.ctrlKey;
21265
21307
  this.clearSelectionPreview();
21266
- this.addObjectToSelectionGroup(selectedObject, isAdditive);
21308
+ if (selectedObject) {
21309
+ this.addObjectToSelectionGroup(selectedObject, isAdditive);
21310
+ }
21267
21311
  this.removeSelectionBox();
21268
21312
  }
21269
21313
  /**
@@ -21346,7 +21390,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21346
21390
  return;
21347
21391
  }
21348
21392
  // Build parent group lookup map ONCE - O(g * c) instead of O(n * g * c)
21349
- const allGroups = this._core.store.state.objects.filter(obj => obj.__class__ === 'KritzelGroup');
21393
+ const allGroups = this._core.store.objects.filter(obj => obj.__class__ === 'KritzelGroup');
21350
21394
  const childToParentMap = new Map();
21351
21395
  for (const group of allGroups) {
21352
21396
  for (const childId of group.childIds) {
@@ -21513,7 +21557,10 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
21513
21557
  if (handleType === 'start' || handleType === 'end') {
21514
21558
  this._core.anchorManager.removeAnchor(line.id, handleType);
21515
21559
  }
21516
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
21560
+ const timeout = this._core.store.state.longTouchTimeout;
21561
+ if (timeout) {
21562
+ globalThis.clearTimeout?.(timeout);
21563
+ }
21517
21564
  }
21518
21565
  /**
21519
21566
  * Handles pointer move events during a line handle drag operation.
@@ -21808,8 +21855,8 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
21808
21855
  const rotatedDeltaCx = deltaCx * cos - deltaCy * sin;
21809
21856
  const rotatedDeltaCy = deltaCx * sin + deltaCy * cos;
21810
21857
  // Calculate new translate
21811
- const newTranslateX = this.initialTranslateX + scale * (oldWidth - newWidth) / 2 + scale * rotatedDeltaCx;
21812
- const newTranslateY = this.initialTranslateY + scale * (oldHeight - newHeight) / 2 + scale * rotatedDeltaCy;
21858
+ const newTranslateX = this.initialTranslateX + (scale * (oldWidth - newWidth)) / 2 + scale * rotatedDeltaCx;
21859
+ const newTranslateY = this.initialTranslateY + (scale * (oldHeight - newHeight)) / 2 + scale * rotatedDeltaCy;
21813
21860
  // Update the line properties
21814
21861
  line.startX = startX;
21815
21862
  line.startY = startY;
@@ -21824,7 +21871,7 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
21824
21871
  line.translateY = newTranslateY;
21825
21872
  // Clear cached adjusted points
21826
21873
  line._adjustedPoints = null;
21827
- this._core.store.state.objects.update(line);
21874
+ this._core.store.objects.update(line);
21828
21875
  }
21829
21876
  /**
21830
21877
  * Handles pointer up events to complete a line handle drag operation.
@@ -22095,7 +22142,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
22095
22142
  const objects = this.flattenObjects(this.getSelectedObjects());
22096
22143
  for (const obj of objects) {
22097
22144
  if (obj instanceof KritzelLine)
22098
- return obj.arrows;
22145
+ return obj.arrows ?? { start: { enabled: false }, end: { enabled: false } };
22099
22146
  }
22100
22147
  return { start: { enabled: false }, end: { enabled: false } };
22101
22148
  }
@@ -22337,7 +22384,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
22337
22384
  getSelectedObject(event) {
22338
22385
  const path = event.composedPath().slice(1);
22339
22386
  const objectElement = path.find(element => element.classList && element.classList.contains('object'));
22340
- const object = this._core.findObjectById(objectElement?.id);
22387
+ const object = objectElement?.id ? this._core.findObjectById(objectElement.id) : null;
22341
22388
  if (!object) {
22342
22389
  return null;
22343
22390
  }
@@ -25748,7 +25795,7 @@ class KritzelAnchorManager {
25748
25795
  // Snap the endpoint to the target's center
25749
25796
  this.snapEndpointToObject(line, endpoint, targetObjectId);
25750
25797
  // Persist the change
25751
- this._core.store.state.objects.update(line);
25798
+ this._core.store.objects.update(line);
25752
25799
  }
25753
25800
  /**
25754
25801
  * Removes an anchor from a line endpoint.
@@ -26127,7 +26174,7 @@ class KritzelAnchorManager {
26127
26174
  // Update the line to persist the change
26128
26175
  const line = this.getLineById(entry.lineId);
26129
26176
  if (line) {
26130
- this._core.store.state.objects.update(line);
26177
+ this._core.store.objects.update(line);
26131
26178
  }
26132
26179
  }
26133
26180
  // Remove the object from the index
@@ -26229,7 +26276,7 @@ class KritzelAnchorManager {
26229
26276
  * @returns The KritzelLine object if found and is a line, null otherwise.
26230
26277
  */
26231
26278
  getLineById(lineId) {
26232
- const objects = this._core.store.state.objects.filter(o => o.id === lineId);
26279
+ const objects = this._core.store.objects.filter(o => o.id === lineId);
26233
26280
  if (objects.length === 0) {
26234
26281
  return null;
26235
26282
  }
@@ -26243,7 +26290,7 @@ class KritzelAnchorManager {
26243
26290
  * @returns The KritzelBaseObject if found, null otherwise.
26244
26291
  */
26245
26292
  getObjectById(objectId) {
26246
- const objects = this._core.store.state.objects.filter(o => o.id === objectId);
26293
+ const objects = this._core.store.objects.filter(o => o.id === objectId);
26247
26294
  return objects.length > 0 ? objects[0] : null;
26248
26295
  }
26249
26296
  /**