kritzel-stencil 0.1.76 → 0.1.78

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 (128) hide show
  1. package/dist/cjs/{index-Dc7LOVhs.js → index-BRZ6e6oa.js} +1 -1
  2. package/dist/cjs/index.cjs.js +2 -330
  3. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +88 -50
  4. package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/stencil.cjs.js +2 -2
  7. package/dist/cjs/{workspace.migrations-DkmVO6dE.js → workspace.migrations-sUPrO23c.js} +378 -13
  8. package/dist/collection/classes/objects/selection-group.class.js +2 -0
  9. package/dist/collection/collection-manifest.json +1 -1
  10. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.css +6 -1
  11. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +5 -2
  12. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +2 -0
  13. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +16 -6
  14. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +21 -0
  15. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +24 -10
  16. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.css +3 -0
  17. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.css +1 -0
  18. package/dist/collection/configs/default-engine-config.js +1 -0
  19. package/dist/collection/constants/version.js +1 -1
  20. package/dist/components/index.js +1 -1
  21. package/dist/components/kritzel-active-users.js +1 -1
  22. package/dist/components/kritzel-avatar.js +1 -1
  23. package/dist/components/kritzel-awareness-cursors.js +1 -1
  24. package/dist/components/kritzel-back-to-content.js +1 -1
  25. package/dist/components/kritzel-brush-style.js +1 -1
  26. package/dist/components/kritzel-button.js +1 -1
  27. package/dist/components/kritzel-color-palette.js +1 -1
  28. package/dist/components/kritzel-color.js +1 -1
  29. package/dist/components/kritzel-context-menu.js +1 -1
  30. package/dist/components/kritzel-controls.js +1 -1
  31. package/dist/components/kritzel-current-user-dialog.js +1 -1
  32. package/dist/components/kritzel-current-user.js +1 -1
  33. package/dist/components/kritzel-cursor-trail.js +1 -1
  34. package/dist/components/kritzel-dialog.js +1 -1
  35. package/dist/components/kritzel-dropdown.js +1 -1
  36. package/dist/components/kritzel-editor.js +1 -1
  37. package/dist/components/kritzel-engine.js +1 -1
  38. package/dist/components/kritzel-export.js +1 -1
  39. package/dist/components/kritzel-font-family.js +1 -1
  40. package/dist/components/kritzel-font-size.js +1 -1
  41. package/dist/components/kritzel-font.js +1 -1
  42. package/dist/components/kritzel-icon.js +1 -1
  43. package/dist/components/kritzel-input.js +1 -1
  44. package/dist/components/kritzel-line-endings.js +1 -1
  45. package/dist/components/kritzel-login-dialog.js +1 -1
  46. package/dist/components/kritzel-master-detail.js +1 -1
  47. package/dist/components/kritzel-menu-item.js +1 -1
  48. package/dist/components/kritzel-menu.js +1 -1
  49. package/dist/components/kritzel-more-menu.js +1 -1
  50. package/dist/components/kritzel-numeric-input.js +1 -1
  51. package/dist/components/kritzel-opacity-slider.js +1 -1
  52. package/dist/components/kritzel-pill-tabs.js +1 -1
  53. package/dist/components/kritzel-portal.js +1 -1
  54. package/dist/components/kritzel-settings.js +1 -1
  55. package/dist/components/kritzel-shape-fill.js +1 -1
  56. package/dist/components/kritzel-share-dialog.js +1 -1
  57. package/dist/components/kritzel-slide-toggle.js +1 -1
  58. package/dist/components/kritzel-split-button.js +1 -1
  59. package/dist/components/kritzel-stroke-size.js +1 -1
  60. package/dist/components/kritzel-tool-config.js +1 -1
  61. package/dist/components/kritzel-tooltip.js +1 -1
  62. package/dist/components/kritzel-utility-panel.js +1 -1
  63. package/dist/components/kritzel-workspace-manager.js +1 -1
  64. package/dist/components/{p-Dt-J69xt.js → p-53di1Zko.js} +1 -1
  65. package/dist/components/{p-DS0xx1eT.js → p-6NFl6EB2.js} +1 -1
  66. package/dist/components/{p-DSzQ6H2j.js → p-76W5pG2O.js} +1 -1
  67. package/dist/components/{p-DRbG92F9.js → p-BLsH_Oi0.js} +1 -1
  68. package/dist/components/p-Ban3OlgZ.js +9 -0
  69. package/dist/components/{p-CUkKKbnu.js → p-BrZ_gL8Q.js} +1 -1
  70. package/dist/components/{p-kj9wbLY8.js → p-BuI6Gkzg.js} +1 -1
  71. package/dist/components/{p-BeFUNGEI.js → p-BueaqfA2.js} +1 -1
  72. package/dist/components/{p-BiByyU2C.js → p-C2l9mZ1P.js} +1 -1
  73. package/dist/components/{p-CsR4owzk.js → p-C4fKLlrd.js} +1 -1
  74. package/dist/components/{p-BA0ayKqO.js → p-CBslLN3-.js} +1 -1
  75. package/dist/components/p-CHY71o5B.js +1 -0
  76. package/dist/components/{p-KQzWumjB.js → p-CI9Nbh-x.js} +1 -1
  77. package/dist/components/{p-CsoDfhD5.js → p-CN8IxBlU.js} +1 -1
  78. package/dist/components/{p-2OYw6GJ7.js → p-CWMFGEe0.js} +1 -1
  79. package/dist/components/{p-Dj_Qjga5.js → p-CYh7yV-K.js} +1 -1
  80. package/dist/components/{p-xM-_OeRO.js → p-Ck1dhpUQ.js} +1 -1
  81. package/dist/components/{p-b4gyXoju.js → p-Cns7qSKS.js} +1 -1
  82. package/dist/components/{p-C69Stayh.js → p-D14QNK3X.js} +1 -1
  83. package/dist/components/{p-iRL0wQHQ.js → p-D3pNw-SV.js} +1 -1
  84. package/dist/components/{p-BEJQ2kP7.js → p-D5IhryUR.js} +1 -1
  85. package/dist/components/{p-CZhyKp-f.js → p-D7yzmu1l.js} +1 -1
  86. package/dist/components/{p-HLbqRJGs.js → p-DDKjsXCe.js} +1 -1
  87. package/dist/components/{p-TyR-YTXm.js → p-DV7Z_qfa.js} +1 -1
  88. package/dist/components/{p-ByR0VXeU.js → p-DWsCbu01.js} +1 -1
  89. package/dist/components/{p-31FVoNWR.js → p-DaGZEV0R.js} +1 -1
  90. package/dist/components/{p-Da46jw3N.js → p-DkWWzVg8.js} +1 -1
  91. package/dist/components/{p-D1O7DxL4.js → p-Dr3-pKVg.js} +1 -1
  92. package/dist/components/{p-JdNoaqqb.js → p-Dte67BWd.js} +1 -1
  93. package/dist/components/{p-CHmi1QWx.js → p-DxzDda_J.js} +1 -1
  94. package/dist/components/{p-CAIGuV2J.js → p-KJ4dHzrS.js} +1 -1
  95. package/dist/components/{p-BiouZo1q.js → p-Lhyh6KeB.js} +1 -1
  96. package/dist/components/{p-CFhp1W9F.js → p-Md9Y-b3d.js} +1 -1
  97. package/dist/components/{p-C1uR_ZNW.js → p-ZC5YELQJ.js} +1 -1
  98. package/dist/components/{p-C7SBI_0T.js → p-ZQ2bKafG.js} +1 -1
  99. package/dist/components/{p-0kShCfeb.js → p-_QEHfsIk.js} +1 -1
  100. package/dist/components/{p-DXjuuVq9.js → p-gtQlsorg.js} +1 -1
  101. package/dist/components/{p-GYI7sDxr.js → p-l_YGO7RB.js} +1 -1
  102. package/dist/components/{p-DvIEvoZu.js → p-m1nVDC3G.js} +1 -1
  103. package/dist/components/{p-7o2FWtFx.js → p-pCC6t6BH.js} +1 -1
  104. package/dist/components/p-pGzF7PUB.js +1 -0
  105. package/dist/esm/{index-MV-81ybv.js → index-BbOHefEf.js} +1 -1
  106. package/dist/esm/index.js +2 -331
  107. package/dist/esm/kritzel-active-users_42.entry.js +88 -50
  108. package/dist/esm/kritzel-brush-style.entry.js +1 -1
  109. package/dist/esm/loader.js +2 -2
  110. package/dist/esm/stencil.js +3 -3
  111. package/dist/esm/{workspace.migrations-D48_Bqvh.js → workspace.migrations-NhRgr2_H.js} +378 -12
  112. package/dist/stencil/index.esm.js +1 -1
  113. package/dist/stencil/p-4a4b38e4.entry.js +9 -0
  114. package/dist/stencil/{p-fc21e29c.entry.js → p-98238bf9.entry.js} +1 -1
  115. package/dist/stencil/p-NhRgr2_H.js +1 -0
  116. package/dist/stencil/stencil.esm.js +1 -1
  117. package/dist/types/classes/objects/selection-group.class.d.ts +1 -0
  118. package/dist/types/components.d.ts +4 -2
  119. package/dist/types/constants/version.d.ts +1 -1
  120. package/dist/types/interfaces/engine-state.interface.d.ts +1 -0
  121. package/package.json +2 -2
  122. package/dist/components/p-CJ2eHeoV.js +0 -1
  123. package/dist/components/p-jdYmu4SA.js +0 -9
  124. package/dist/components/p-xNwOWoiT.js +0 -1
  125. package/dist/stencil/p-775a7246.entry.js +0 -9
  126. package/dist/stencil/p-D48_Bqvh.js +0 -1
  127. /package/dist/components/{p-pebXO4LU.js → p-CGGiwvWZ.js} +0 -0
  128. /package/dist/stencil/{p-MV-81ybv.js → p-BbOHefEf.js} +0 -0
@@ -1,5 +1,5 @@
1
- import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-MV-81ybv.js';
2
- import { b as KritzelPath, d as KritzelLine, z as KritzelColorHelper, n as KritzelSelectionTool, g as KritzelBrushTool, h as KritzelLineTool, l as KritzelShapeTool, k as KritzelTextTool, B as KritzelDevicesHelper, E as KritzelMouseButton, F as DEFAULT_COLOR_PALETTE, S as ShapeType, D as DEFAULT_BRUSH_CONFIG, i as KritzelEraserTool, s as DEFAULT_LINE_TOOL_CONFIG, r as DEFAULT_TEXT_CONFIG, j as KritzelImageTool, v as KritzelAlignment, I as IndexedDBSyncProvider, G as KritzelSelectionGroup, J as KritzelSelectionBox, L as KritzelIconRegistry, M as KritzelKeyboardHelper, N as KritzelBaseHandler, O as KritzelToolRegistry, P as KritzelBaseObject, o as KritzelWorkspace, e as KritzelGroup, c as KritzelImage, f as KritzelShape, K as KritzelText, x as runMigrations, w as CURRENT_WORKSPACE_SCHEMA_VERSION, y as WORKSPACE_MIGRATIONS, C as CURRENT_APP_STATE_SCHEMA_VERSION, A as APP_STATE_MIGRATIONS, Q as ObjectHelper, m as KritzelCursorHelper, p as KritzelAnchorManager, q as KritzelThemeManager, R as KritzelClassHelper, T as KritzelEventHelper, U as KritzelBaseTool, W as WORKSPACE_EXPORT_VERSION } from './workspace.migrations-D48_Bqvh.js';
1
+ import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-BbOHefEf.js';
2
+ import { a as KritzelPath, c as KritzelLine, y as KritzelColorHelper, m as KritzelSelectionTool, f as KritzelBrushTool, g as KritzelLineTool, k as KritzelShapeTool, j as KritzelTextTool, z as KritzelDevicesHelper, B as KritzelMouseButton, E as DEFAULT_COLOR_PALETTE, S as ShapeType, D as DEFAULT_BRUSH_CONFIG, h as KritzelEraserTool, r as DEFAULT_LINE_TOOL_CONFIG, q as DEFAULT_TEXT_CONFIG, i as KritzelImageTool, u as KritzelAlignment, H as HocuspocusSyncProvider, I as IndexedDBSyncProvider, F as KritzelSelectionGroup, G as KritzelSelectionBox, J as KritzelIconRegistry, L as KritzelKeyboardHelper, M as KritzelBaseHandler, N as KritzelToolRegistry, O as KritzelBaseObject, n as KritzelWorkspace, d as KritzelGroup, b as KritzelImage, e as KritzelShape, K as KritzelText, w as runMigrations, v as CURRENT_WORKSPACE_SCHEMA_VERSION, x as WORKSPACE_MIGRATIONS, C as CURRENT_APP_STATE_SCHEMA_VERSION, A as APP_STATE_MIGRATIONS, P as ObjectHelper, l as KritzelCursorHelper, o as KritzelAnchorManager, p as KritzelThemeManager, Q as KritzelClassHelper, R as KritzelEventHelper, T as KritzelBaseTool, W as WORKSPACE_EXPORT_VERSION } from './workspace.migrations-NhRgr2_H.js';
3
3
  import * as Y from 'yjs';
4
4
  import 'y-websocket';
5
5
  import 'y-indexeddb';
@@ -154,7 +154,7 @@ const KritzelAvatar = class {
154
154
  };
155
155
  KritzelAvatar.style = kritzelAvatarCss();
156
156
 
157
- const kritzelAwarenessCursorsCss = () => `:host{display:block;position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:9500}.awareness-cursor{position:absolute;top:0;left:0;transition:transform var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out, opacity 300ms ease;will-change:transform}.awareness-cursor.stale{opacity:0}.awareness-cursor.tracking-object{transition-duration:0ms}.cursor-arrow{filter:drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3))}.cursor-label{position:absolute;left:16px;top:16px;white-space:nowrap;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;font-size:var(--kritzel-awareness-cursor-label-font-size, 12px);color:var(--kritzel-awareness-cursor-label-text-color, #ffffff);padding:2px 8px;border-radius:4px;line-height:1.4;font-weight:500;pointer-events:none;user-select:none}.edge-indicator{position:absolute;top:-12px;left:-12px;width:24px;height:24px;display:flex;align-items:center;justify-content:center;transition:transform var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out, opacity 300ms ease;will-change:transform;pointer-events:auto;user-select:none;cursor:pointer}.edge-indicator.stale{opacity:0}.edge-indicator.tracking-object{transition-duration:0ms}.edge-arrow{position:absolute;filter:drop-shadow(0 1px 3px rgba(0, 0, 0, 0.3))}.edge-label{position:absolute;white-space:nowrap;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;font-size:var(--kritzel-awareness-cursor-label-font-size, 12px);color:var(--kritzel-awareness-cursor-label-text-color, #ffffff);padding:2px 8px;border-radius:4px;line-height:1.4;font-weight:500;pointer-events:none;opacity:0;transform-origin:center;transition:opacity 150ms ease}.edge-indicator:hover .edge-label{opacity:1}.remote-selection-box{position:absolute;top:0;left:0;border-width:2px;border-style:solid;pointer-events:none;will-change:transform, width, height;transition:transform var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out, width var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out, height var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out}`;
157
+ const kritzelAwarenessCursorsCss = () => `:host{display:block;position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:1}.awareness-cursor{position:absolute;top:0;left:0;transition:transform var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out, opacity 300ms ease;will-change:transform}.awareness-cursor.stale{opacity:0}.awareness-cursor.tracking-object{transition-duration:0ms}.cursor-arrow{filter:drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3))}.cursor-label{position:absolute;left:16px;top:16px;white-space:nowrap;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;font-size:var(--kritzel-awareness-cursor-label-font-size, 12px);color:var(--kritzel-awareness-cursor-label-text-color, #ffffff);padding:2px 8px;border-radius:4px;line-height:1.4;font-weight:500;pointer-events:none;user-select:none}.edge-indicator{position:absolute;top:-12px;left:-12px;width:24px;height:24px;display:flex;align-items:center;justify-content:center;transition:transform var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out, opacity 300ms ease;will-change:transform;pointer-events:auto;user-select:none;cursor:pointer}.edge-indicator.stale{opacity:0}.edge-indicator.tracking-object{transition-duration:0ms}.edge-arrow{position:absolute;filter:drop-shadow(0 1px 3px rgba(0, 0, 0, 0.3));transition:opacity 300ms ease}.edge-arrow.stale{opacity:0}.edge-label{position:absolute;white-space:nowrap;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;font-size:var(--kritzel-awareness-cursor-label-font-size, 12px);color:var(--kritzel-awareness-cursor-label-text-color, #ffffff);padding:2px 8px;border-radius:4px;line-height:1.4;font-weight:500;pointer-events:none;opacity:0;transform-origin:center;transition:opacity 150ms ease}.edge-indicator:hover .edge-label{opacity:1}.remote-selection-box{position:absolute;top:0;left:0;border-width:2px;border-style:solid;pointer-events:none;will-change:transform, width, height;transition:transform var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out, width var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out, height var(--kritzel-awareness-cursor-transition-duration, 100ms) ease-out}`;
158
158
 
159
159
  const STALE_THRESHOLD_MS = 10_000;
160
160
  const REMOVE_THRESHOLD_MS = 30_000;
@@ -236,6 +236,9 @@ const KritzelAwarenessCursors = class {
236
236
  updated.delete(clientId);
237
237
  changed = true;
238
238
  }
239
+ else if (!changed && now - cursor.lastCursorMove > STALE_THRESHOLD_MS) {
240
+ changed = true;
241
+ }
239
242
  }
240
243
  if (changed) {
241
244
  this.remoteCursors = updated;
@@ -331,7 +334,7 @@ const KritzelAwarenessCursors = class {
331
334
  }
332
335
  render() {
333
336
  const cursors = Array.from(this.remoteCursors.values());
334
- return (h(Host, { key: '4dd962322c7e955b9038c55cb10f8ffda1e0b246' }, cursors.map(remoteCursor => {
337
+ return (h(Host, { key: '5a28def6e024249c4309c087502cde9f219f5421' }, cursors.map(remoteCursor => {
335
338
  if (!remoteCursor.cursor)
336
339
  return null;
337
340
  // When a remote user is actively drawing, derive cursor position from
@@ -407,7 +410,7 @@ const KritzelAwarenessCursors = class {
407
410
  const displayName = this.getUserDisplayName(cursor.user);
408
411
  return (h("div", { key: `edge-${cursor.clientId}`, class: { 'edge-indicator': true, stale, 'tracking-object': trackingObject }, style: {
409
412
  transform: `translate(${clamped.x}px, ${clamped.y}px)`,
410
- } }, h("svg", { class: "edge-arrow", width: "16", height: "16", viewBox: "0 0 16 16", style: { transform: `rotate(${arrowDeg}deg)` } }, h("path", { d: "M8 1L14 13H2L8 1Z", fill: color, stroke: "#ffffff", "stroke-width": "1.5", "stroke-linejoin": "round" })), h("span", { class: "edge-label", style: {
413
+ } }, h("svg", { class: { 'edge-arrow': true, stale }, width: "16", height: "16", viewBox: "0 0 16 16", style: { transform: `rotate(${arrowDeg}deg)` } }, h("path", { d: "M8 1L14 13H2L8 1Z", fill: color, stroke: "#ffffff", "stroke-width": "1.5", "stroke-linejoin": "round" })), h("span", { class: "edge-label", style: {
411
414
  backgroundColor: color,
412
415
  transform: `translate(${labelX}px, ${labelY}px)`,
413
416
  } }, displayName)));
@@ -1832,7 +1835,7 @@ const DEFAULT_SHAPE_CONFIG = {
1832
1835
  const ABSOLUTE_SCALE_MAX = 1000;
1833
1836
  const ABSOLUTE_SCALE_MIN = 0.0001;
1834
1837
 
1835
- const kritzelEditorCss = () => `kritzel-editor{display:flex;margin:0;position:relative;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}kritzel-controls{position:absolute;bottom:var(--kritzel-editor-controls-bottom, 14px);transition:transform var(--kritzel-editor-controls-transition-duration, 0.1s) var(--kritzel-editor-controls-transition, ease-in-out)}kritzel-controls.keyboard-open{transform:var(--kritzel-editor-controls-transform, translateY(300%))}.top-left-buttons{position:absolute;top:var(--kritzel-editor-top-left-buttons-top, 14px);left:var(--kritzel-editor-top-left-buttons-left, 14px);display:flex;align-items:flex-start;gap:8px}.top-right-buttons{position:absolute;top:var(--kritzel-editor-top-right-buttons-top, 14px);right:var(--kritzel-editor-top-right-buttons-right, 14px);display:flex;align-items:center;gap:8px}.top-right-button{display:flex;align-items:center;justify-content:center;width:50px;height:50px;padding:0;border:var(--kritzel-split-button-border, 1px solid #ebebeb);border-radius:var(--kritzel-split-button-border-radius, 12px);background-color:var(--kritzel-split-button-background-color, #ffffff);cursor:var(--kritzel-global-pointer-cursor, pointer);box-shadow:var(--kritzel-split-button-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));transition:background-color 150ms ease;-webkit-tap-highlight-color:transparent}.top-right-button:hover{background-color:#f5f5f5}.top-right-button:active{background-color:#ebebeb}`;
1838
+ const kritzelEditorCss = () => `kritzel-editor{display:flex;margin:0;position:relative;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}kritzel-controls{position:absolute;bottom:var(--kritzel-editor-controls-bottom, 14px);transition:transform var(--kritzel-editor-controls-transition-duration, 0.1s) var(--kritzel-editor-controls-transition, ease-in-out)}kritzel-controls.keyboard-open{transform:var(--kritzel-editor-controls-transform, translateY(300%))}.top-left-buttons{position:absolute;top:var(--kritzel-editor-top-left-buttons-top, 14px);left:var(--kritzel-editor-top-left-buttons-left, 14px);display:flex;align-items:flex-start;gap:8px;z-index:10000}.top-right-buttons{position:absolute;top:var(--kritzel-editor-top-right-buttons-top, 14px);right:var(--kritzel-editor-top-right-buttons-right, 14px);display:flex;align-items:center;gap:8px;z-index:10000}.top-right-button{display:flex;align-items:center;justify-content:center;width:50px;height:50px;padding:0;border:var(--kritzel-split-button-border, 1px solid #ebebeb);border-radius:var(--kritzel-split-button-border-radius, 12px);background-color:var(--kritzel-split-button-background-color, #ffffff);cursor:var(--kritzel-global-pointer-cursor, pointer);box-shadow:var(--kritzel-split-button-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));transition:background-color 150ms ease;-webkit-tap-highlight-color:transparent}.top-right-button:hover{background-color:#f5f5f5}.top-right-button:active{background-color:#ebebeb}`;
1836
1839
 
1837
1840
  const KritzelEditor = class {
1838
1841
  constructor(hostRef) {
@@ -2011,10 +2014,19 @@ const KritzelEditor = class {
2011
2014
  isControlsVisible = true;
2012
2015
  isUtilityPanelVisible = true;
2013
2016
  syncConfig = {
2014
- providers: [IndexedDBSyncProvider]
2017
+ appStateId: 'kritzel-app-test',
2018
+ providers: [HocuspocusSyncProvider, IndexedDBSyncProvider]
2015
2019
  };
2016
2020
  /** Optional login configuration. When provided, a "Sign in" button is shown that opens a login dialog with the configured providers. */
2017
- loginConfig;
2021
+ loginConfig = {
2022
+ providers: [
2023
+ {
2024
+ label: 'Sign in with Google',
2025
+ icon: 'google',
2026
+ name: 'Google',
2027
+ }
2028
+ ]
2029
+ };
2018
2030
  /** Optional unique identifier for namespacing storage keys across multiple editor instances. */
2019
2031
  editorId;
2020
2032
  /** Optional workspace ID to set as active. If provided, the editor will automatically activate the workspace with this ID. */
@@ -2528,7 +2540,7 @@ const KritzelEditor = class {
2528
2540
  const isLoggedIn = this.isLoggedIn;
2529
2541
  const shouldShowCurrentUser = isLoggedIn;
2530
2542
  const shouldShowLoginButton = !!this.loginConfig && !isLoggedIn;
2531
- return (h(Host, { key: 'd1944655652eb2939e3696ed70050baaca0871e2' }, h("div", { key: 'ce5dfd9b8f8d9927e9a6ace4056f9053163c7e0a', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'e127a667c6e4e853bb4f0c9ffd0edaa6d80d9dfa', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'a9abb378f3c79f356d2164cbddf6badba10188a8', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: 'c5f764580f3623eeb9381e54769a891a48c04620', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event) }), h("kritzel-controls", { key: '2479b6979d5b2b6c55a873bd1d8468b5fd967f72', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'ec6ac72ba154abe0738259464f20cae9e7dbdd9e', class: "top-right-buttons" }, h("kritzel-settings", { key: 'f68f791d673b30331e55f358b9c71b3e2a9a8388', ref: el => (this.settingsRef = el), shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: 'dfe5a051caccee504df4f347705303fa1f812556', ref: el => (this.exportRef = el), workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '48983a14d3902cd238cf0d9ed302ed561a655a9a', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '589bdc895741a2d17f60c4b549d14fe8fff74c17', user: this.user }), shouldShowLoginButton && h("kritzel-button", { key: '50414a9d7ade623678c767ce63c49f5e99336bed', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in"), h("kritzel-more-menu", { key: 'db3069ee0b093acd238750df81c6f426139c9b87', items: this.moreMenuItems }), h("kritzel-share-dialog", { key: 'e16057838f00b2c3f239e794b4310bd2690d16e2', ref: el => (this.shareDialogRef = el), isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: 'a6d1fc06c983542c6af95e7bb4b2b2d522a03605', ref: el => (this.loginDialogRef = el), providers: this.loginConfig.providers, dialogTitle: this.loginConfig.title, subtitle: this.loginConfig.subtitle, onProviderLogin: this.handleProviderLogin })))));
2543
+ return (h(Host, { key: '6dbc3a8c64dd097ba82e46341b3fb97cbd0194db' }, h("div", { key: '26ceb62f59ad830fd651a1712f57e5d711e7c6f4', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'afb4f5b87c5dc0a673444fb27930e43994df4e02', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'f3c0f31841cb819917c3277852bc9b5ce291c09a', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: '8a9e57132e6b74ec812ee516dc7f0d5fc6c8a2e1', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event) }), h("kritzel-controls", { key: '6caadf512a0208fecdb18b6d68b17daa522161a3', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'e27e5f3965be2fd15c83b91470ef87c4031dd7a2', class: "top-right-buttons" }, h("kritzel-settings", { key: '57f8e75287402aecbb7740d46dfa15839de2169f', ref: el => (this.settingsRef = el), shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '5ccf176d4fe1221c5d7597bd1c8537cf3324d3ee', ref: el => (this.exportRef = el), workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '44a334b808706e11163e89b91074ca4ea8ab4b18', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: 'bcb3c966e630b1a8fc4ccd438fc8fbb11cd2b167', user: this.user }), shouldShowLoginButton && h("kritzel-button", { key: 'f1957e56257b7c565311e41b770579f7e2bb910d', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in"), h("kritzel-more-menu", { key: 'd8c1d1b51cf87725d68aaf4457b88828986a40dc', items: this.moreMenuItems }), h("kritzel-share-dialog", { key: 'f5840e7f56cf6897ec28b0f28d9b204037bf3348', ref: el => (this.shareDialogRef = el), isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: 'cfdcc3d5e7a5e29b0a352f0d4423ae79195dbf69', ref: el => (this.loginDialogRef = el), providers: this.loginConfig.providers, dialogTitle: this.loginConfig.title, subtitle: this.loginConfig.subtitle, onProviderLogin: this.handleProviderLogin })))));
2532
2544
  }
2533
2545
  static get watchers() { return {
2534
2546
  "isEngineReady": [{
@@ -2577,7 +2589,7 @@ function requireLodash () {
2577
2589
  var undefined$1;
2578
2590
 
2579
2591
  /** Used as the semantic version number. */
2580
- var VERSION = '4.17.23';
2592
+ var VERSION = '4.18.1';
2581
2593
 
2582
2594
  /** Used as the size to enable large array optimizations. */
2583
2595
  var LARGE_ARRAY_SIZE = 200;
@@ -2585,7 +2597,8 @@ function requireLodash () {
2585
2597
  /** Error message constants. */
2586
2598
  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
2587
2599
  FUNC_ERROR_TEXT = 'Expected a function',
2588
- INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';
2600
+ INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`',
2601
+ INVALID_TEMPL_IMPORTS_ERROR_TEXT = 'Invalid `imports` option passed into `_.template`';
2589
2602
 
2590
2603
  /** Used to stand-in for `undefined` hash values. */
2591
2604
  var HASH_UNDEFINED = '__lodash_hash_undefined__';
@@ -4317,6 +4330,10 @@ function requireLodash () {
4317
4330
  * embedded Ruby (ERB) as well as ES2015 template strings. Change the
4318
4331
  * following template settings to use alternative delimiters.
4319
4332
  *
4333
+ * **Security:** See
4334
+ * [threat model](https://github.com/lodash/lodash/blob/main/threat-model.md)
4335
+ * — `_.template` is insecure and will be removed in v5.
4336
+ *
4320
4337
  * @static
4321
4338
  * @memberOf _
4322
4339
  * @type {Object}
@@ -4865,7 +4882,7 @@ function requireLodash () {
4865
4882
  * @name has
4866
4883
  * @memberOf SetCache
4867
4884
  * @param {*} value The value to search for.
4868
- * @returns {number} Returns `true` if `value` is found, else `false`.
4885
+ * @returns {boolean} Returns `true` if `value` is found, else `false`.
4869
4886
  */
4870
4887
  function setCacheHas(value) {
4871
4888
  return this.__data__.has(value);
@@ -6936,7 +6953,9 @@ function requireLodash () {
6936
6953
  function baseUnset(object, path) {
6937
6954
  path = castPath(path, object);
6938
6955
 
6939
- // Prevent prototype pollution, see: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
6956
+ // Prevent prototype pollution:
6957
+ // https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
6958
+ // https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh
6940
6959
  var index = -1,
6941
6960
  length = path.length;
6942
6961
 
@@ -6944,32 +6963,17 @@ function requireLodash () {
6944
6963
  return true;
6945
6964
  }
6946
6965
 
6947
- var isRootPrimitive = object == null || (typeof object !== 'object' && typeof object !== 'function');
6948
-
6949
6966
  while (++index < length) {
6950
- var key = path[index];
6951
-
6952
- // skip non-string keys (e.g., Symbols, numbers)
6953
- if (typeof key !== 'string') {
6954
- continue;
6955
- }
6967
+ var key = toKey(path[index]);
6956
6968
 
6957
6969
  // Always block "__proto__" anywhere in the path if it's not expected
6958
6970
  if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
6959
6971
  return false;
6960
6972
  }
6961
6973
 
6962
- // Block "constructor.prototype" chains
6963
- if (key === 'constructor' &&
6964
- (index + 1) < length &&
6965
- typeof path[index + 1] === 'string' &&
6966
- path[index + 1] === 'prototype') {
6967
-
6968
- // Allow ONLY when the path starts at a primitive root, e.g., _.unset(0, 'constructor.prototype.a')
6969
- if (isRootPrimitive && index === 0) {
6970
- continue;
6971
- }
6972
-
6974
+ // Block constructor/prototype as non-terminal traversal keys to prevent
6975
+ // escaping the object graph into built-in constructors and prototypes.
6976
+ if ((key === 'constructor' || key === 'prototype') && index < length - 1) {
6973
6977
  return false;
6974
6978
  }
6975
6979
  }
@@ -9526,7 +9530,7 @@ function requireLodash () {
9526
9530
 
9527
9531
  /**
9528
9532
  * Creates an array with all falsey values removed. The values `false`, `null`,
9529
- * `0`, `""`, `undefined`, and `NaN` are falsey.
9533
+ * `0`, `-0`, `0n`, `""`, `undefined`, and `NaN` are falsy.
9530
9534
  *
9531
9535
  * @static
9532
9536
  * @memberOf _
@@ -10065,7 +10069,7 @@ function requireLodash () {
10065
10069
 
10066
10070
  while (++index < length) {
10067
10071
  var pair = pairs[index];
10068
- result[pair[0]] = pair[1];
10072
+ baseAssignValue(result, pair[0], pair[1]);
10069
10073
  }
10070
10074
  return result;
10071
10075
  }
@@ -16725,6 +16729,8 @@ function requireLodash () {
16725
16729
  * **Note:** JavaScript follows the IEEE-754 standard for resolving
16726
16730
  * floating-point values which can produce unexpected results.
16727
16731
  *
16732
+ * **Note:** If `lower` is greater than `upper`, the values are swapped.
16733
+ *
16728
16734
  * @static
16729
16735
  * @memberOf _
16730
16736
  * @since 0.7.0
@@ -16738,9 +16744,16 @@ function requireLodash () {
16738
16744
  * _.random(0, 5);
16739
16745
  * // => an integer between 0 and 5
16740
16746
  *
16747
+ * // when lower is greater than upper the values are swapped
16748
+ * _.random(5, 0);
16749
+ * // => an integer between 0 and 5
16750
+ *
16741
16751
  * _.random(5);
16742
16752
  * // => also an integer between 0 and 5
16743
16753
  *
16754
+ * _.random(-5);
16755
+ * // => an integer between -5 and 0
16756
+ *
16744
16757
  * _.random(5, true);
16745
16758
  * // => a floating-point number between 0 and 5
16746
16759
  *
@@ -17342,6 +17355,10 @@ function requireLodash () {
17342
17355
  * properties may be accessed as free variables in the template. If a setting
17343
17356
  * object is given, it takes precedence over `_.templateSettings` values.
17344
17357
  *
17358
+ * **Security:** `_.template` is insecure and should not be used. It will be
17359
+ * removed in Lodash v5. Avoid untrusted input. See
17360
+ * [threat model](https://github.com/lodash/lodash/blob/main/threat-model.md).
17361
+ *
17345
17362
  * **Note:** In the development build `_.template` utilizes
17346
17363
  * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
17347
17364
  * for easier debugging.
@@ -17449,12 +17466,18 @@ function requireLodash () {
17449
17466
  options = undefined$1;
17450
17467
  }
17451
17468
  string = toString(string);
17452
- options = assignInWith({}, options, settings, customDefaultsAssignIn);
17469
+ options = assignWith({}, options, settings, customDefaultsAssignIn);
17453
17470
 
17454
- var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
17471
+ var imports = assignWith({}, options.imports, settings.imports, customDefaultsAssignIn),
17455
17472
  importsKeys = keys(imports),
17456
17473
  importsValues = baseValues(imports, importsKeys);
17457
17474
 
17475
+ arrayEach(importsKeys, function(key) {
17476
+ if (reForbiddenIdentifierChars.test(key)) {
17477
+ throw new Error(INVALID_TEMPL_IMPORTS_ERROR_TEXT);
17478
+ }
17479
+ });
17480
+
17458
17481
  var isEscaping,
17459
17482
  isEvaluating,
17460
17483
  index = 0,
@@ -20881,6 +20904,7 @@ const DEFAULT_ENGINE_CONFIG = {
20881
20904
  isDrawing: false,
20882
20905
  isErasing: false,
20883
20906
  isWriting: false,
20907
+ isWorkspaceLoading: false,
20884
20908
  isCtrlKeyPressed: false,
20885
20909
  isContextMenuVisible: false,
20886
20910
  contextMenuItems: [],
@@ -25460,7 +25484,7 @@ async function toPng(node, options = {}) {
25460
25484
  return canvas.toDataURL();
25461
25485
  }
25462
25486
 
25463
- const kritzelEngineCss = () => `:host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.ProseMirror{outline:none}p,h1,h2,h3,h4,h5,h6,blockquote,pre{margin:0;padding:0}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}.PlaygroundEditorTheme__quote{margin:0;margin-left:20px;margin-bottom:10px;font-size:15px;color:rgb(101, 103, 107);border-left-color:rgb(206, 208, 212);border-left-width:4px;border-left-style:solid;padding-left:16px}`;
25487
+ const kritzelEngineCss = () => `:host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.ProseMirror{outline:none}p,h1,h2,h3,h4,h5,h6,blockquote,pre{margin:0;padding:0}.workspace-loading-overlay{position:absolute;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;background-color:var(--kritzel-loading-overlay-background, rgba(255, 255, 255, 0.6));color:var(--kritzel-loading-overlay-color, #333);font-size:1.25rem;pointer-events:all;animation:workspace-loading-fade-in var(--kritzel-loading-overlay-delay, 300ms) ease-out forwards;opacity:0}@keyframes workspace-loading-fade-in{to{opacity:1}}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}.PlaygroundEditorTheme__quote{margin:0;margin-left:20px;margin-bottom:10px;font-size:15px;color:rgb(101, 103, 107);border-left-color:rgb(206, 208, 212);border-left-width:4px;border-left-style:solid;padding-left:16px}`;
25464
25488
 
25465
25489
  const KritzelEngine = class {
25466
25490
  get host() { return getElement(this); }
@@ -26772,6 +26796,7 @@ const KritzelEngine = class {
26772
26796
  await this._workspaceInitializationPromise;
26773
26797
  return;
26774
26798
  }
26799
+ this.core.store.state.isWorkspaceLoading = true;
26775
26800
  const initializationPromise = this.core.initializeWorkspace(workspace, options);
26776
26801
  this._workspaceInitializationPromise = initializationPromise;
26777
26802
  this._workspaceInitializationTargetKey = targetKey;
@@ -26783,6 +26808,7 @@ const KritzelEngine = class {
26783
26808
  this._workspaceInitializationPromise = null;
26784
26809
  this._workspaceInitializationTargetKey = null;
26785
26810
  }
26811
+ this.core.store.state.isWorkspaceLoading = false;
26786
26812
  }
26787
26813
  }
26788
26814
  emitObjectsChange() {
@@ -26850,7 +26876,7 @@ const KritzelEngine = class {
26850
26876
  this.emitObjectsInViewportChange();
26851
26877
  }
26852
26878
  }
26853
- return (h(Host, null, this.core.store.state.debugInfo.showViewportInfo && (h("div", { class: "debug-panel" }, h("div", null, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", null, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", null, "TranslateX: ", this.core.store.state?.translateX), h("div", null, "TranslateY: ", this.core.store.state?.translateY), h("div", null, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", null, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", null, "PointerCount: ", this.core.store.state.pointers.size), h("div", null, "Scale: ", this.core.store.state?.scale), h("div", null, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", null, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", null, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", null, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", null, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", null, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", null, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", null, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", null, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", null, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", null, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", null, "PointerX: ", this.core.store.state?.pointerX), h("div", null, "PointerY: ", this.core.store.state?.pointerY), h("div", null, "TotalObjects: ", this.core.store.totalObjectCount), h("div", null, "ObjectsInViewport: ", this.core.store.objectsInViewport.length), h("div", null, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", null, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { id: "origin", class: "origin", style: {
26879
+ return (h(Host, null, this.core.store.state.isWorkspaceLoading && (h("div", { class: "workspace-loading-overlay" }, "Loading...")), this.core.store.state.debugInfo.showViewportInfo && (h("div", { class: "debug-panel" }, h("div", null, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", null, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", null, "TranslateX: ", this.core.store.state?.translateX), h("div", null, "TranslateY: ", this.core.store.state?.translateY), h("div", null, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", null, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", null, "PointerCount: ", this.core.store.state.pointers.size), h("div", null, "Scale: ", this.core.store.state?.scale), h("div", null, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", null, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", null, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", null, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", null, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", null, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", null, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", null, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", null, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", null, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", null, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", null, "PointerX: ", this.core.store.state?.pointerX), h("div", null, "PointerY: ", this.core.store.state?.pointerY), h("div", null, "TotalObjects: ", this.core.store.totalObjectCount), h("div", null, "ObjectsInViewport: ", this.core.store.objectsInViewport.length), h("div", null, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", null, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { id: "origin", class: "origin", style: {
26854
26880
  transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
26855
26881
  } }, visibleObjects?.map(object => {
26856
26882
  return (h("div", { key: object.id, id: object.id, class: "object", style: {
@@ -26999,18 +27025,30 @@ const KritzelEngine = class {
26999
27025
  zIndex: (object.zIndex + 2).toString(),
27000
27026
  } }, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "Id: ", object.id), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "userId: ", object.userId), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "translateY: ", object.translateY), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "rotationDegrees: ", object.rotationDegrees), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "zIndex: ", object.zIndex))), (this.core.displaySelectionGroupUI(object) || this.core.displaySelectionLineUI(object)) &&
27001
27027
  (() => {
27002
- const isRemoteSelection = KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') &&
27003
- object.userId != null &&
27004
- this.core.user?.id != null &&
27005
- object.userId !== this.core.user.id;
27028
+ const isSelectionGroup = KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup');
27029
+ const localClientId = this.core.store.state.objects?.localClientId;
27030
+ const awarenessStates = this.core.store.state.objects?.awareness?.getStates();
27031
+ const isRemoteSelection = isSelectionGroup && (
27032
+ // Different user
27033
+ (object.userId != null && this.core.user?.id != null && object.userId !== this.core.user.id) ||
27034
+ // Same user but different client that is still actively connected (e.g. same account on another device)
27035
+ (object.userId != null && this.core.user?.id != null && object.userId === this.core.user.id &&
27036
+ object.clientId != null && localClientId != null && object.clientId !== localClientId &&
27037
+ awarenessStates?.has(object.clientId) === true));
27006
27038
  let remoteUserColor;
27007
27039
  if (isRemoteSelection) {
27008
- const awarenessStates = this.core.store.state.objects?.awareness?.getStates();
27009
27040
  if (awarenessStates) {
27010
- for (const state of awarenessStates.values()) {
27011
- if (state.user?.id === object.userId) {
27012
- remoteUserColor = state.user.color;
27013
- break;
27041
+ // Try direct lookup by clientId first (most precise)
27042
+ if (isSelectionGroup && object.clientId != null) {
27043
+ remoteUserColor = awarenessStates.get(object.clientId)?.user?.color;
27044
+ }
27045
+ // Fall back to userId match (for selection groups without clientId)
27046
+ if (!remoteUserColor) {
27047
+ for (const state of awarenessStates.values()) {
27048
+ if (state.user?.id === object.userId) {
27049
+ remoteUserColor = state.user.color;
27050
+ break;
27051
+ }
27014
27052
  }
27015
27053
  }
27016
27054
  }
@@ -27601,7 +27639,7 @@ const KritzelLineEndings = class {
27601
27639
  };
27602
27640
  KritzelLineEndings.style = kritzelLineEndingsCss();
27603
27641
 
27604
- const kritzelLoginDialogCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-width-small:380px}.login-content{display:flex;flex-direction:column;gap:20px}.login-subtitle{font-size:13px;color:var(--kritzel-login-dialog-subtitle-color, #666666);margin:0;line-height:1.5;text-align:center}.login-providers{display:flex;flex-direction:column;gap:10px}.provider-button{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:12px 16px;border:1px solid var(--kritzel-login-dialog-button-border-color, #e0e0e0);border-radius:8px;background:var(--kritzel-login-dialog-button-background, #ffffff);color:var(--kritzel-login-dialog-button-text-color, #333333);font-size:14px;font-weight:500;font-family:inherit;cursor:var(--kritzel-global-pointer-cursor, pointer);transition:background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;-webkit-tap-highlight-color:transparent}.provider-button:hover:not(:disabled){background:var(--kritzel-login-dialog-button-hover-background, #f5f5f5);border-color:var(--kritzel-login-dialog-button-hover-border-color, #cccccc)}.provider-button:active:not(:disabled){background:var(--kritzel-login-dialog-button-active-background, #ebebeb)}.provider-button:focus-visible{outline:revert;outline-offset:revert}.provider-button.is-disabled{opacity:0.5;cursor:default;pointer-events:none}.provider-button.is-loading{cursor:default}.provider-label{flex-shrink:0}.provider-button.is-loading .provider-label{opacity:0.7}@keyframes kritzel-login-spin{to{transform:rotate(360deg)}}.spinner{width:20px;height:20px;border:2px solid var(--kritzel-login-dialog-spinner-color, #cccccc);border-top-color:var(--kritzel-login-dialog-spinner-active-color, #333333);border-radius:50%;animation:kritzel-login-spin 0.6s linear infinite}`;
27642
+ const kritzelLoginDialogCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-width-small:380px}.login-content{display:flex;flex-direction:column;gap:20px}.login-subtitle{font-size:13px;color:var(--kritzel-login-dialog-subtitle-color, #666666);margin:0;line-height:1.5;text-align:center}.login-providers{display:flex;flex-direction:column;gap:10px}.provider-button{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:12px 16px;border:1px solid var(--kritzel-login-dialog-button-border-color, #e0e0e0);border-radius:8px;background:var(--kritzel-login-dialog-button-background, #ffffff);color:var(--kritzel-login-dialog-button-text-color, #333333);font-size:14px;font-weight:500;font-family:inherit;cursor:var(--kritzel-global-pointer-cursor, pointer);transition:background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;-webkit-tap-highlight-color:transparent}.provider-button:hover:not(:disabled){background:var(--kritzel-login-dialog-button-hover-background, #f5f5f5);border-color:var(--kritzel-login-dialog-button-hover-border-color, #cccccc)}.provider-button:active:not(:disabled){background:var(--kritzel-login-dialog-button-active-background, #ebebeb)}.provider-button:focus-visible{outline:revert;outline-offset:revert}.provider-button.is-disabled{opacity:0.5;cursor:default;pointer-events:none}.provider-button.is-loading{cursor:default}.provider-label{flex-shrink:0}.provider-button.is-loading .provider-label{opacity:0.7}@keyframes kritzel-login-spin{to{transform:rotate(360deg)}}.spinner{width:20px;height:20px;box-sizing:border-box;display:block;flex-shrink:0;border:2px solid var(--kritzel-login-dialog-spinner-color, #cccccc);border-top-color:var(--kritzel-login-dialog-spinner-active-color, #333333);border-radius:50%;animation:kritzel-login-spin 0.6s linear infinite}`;
27605
27643
 
27606
27644
  const KritzelLoginDialog = class {
27607
27645
  constructor(hostRef) {
@@ -28499,7 +28537,7 @@ const KritzelPortal = class {
28499
28537
  * This file is auto-generated by the version bump scripts.
28500
28538
  * Do not modify manually.
28501
28539
  */
28502
- const KRITZEL_VERSION = '0.1.76';
28540
+ const KRITZEL_VERSION = '0.1.78';
28503
28541
 
28504
28542
  const kritzelSettingsCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}.shortcuts-list{display:flex;flex-direction:column;gap:24px}.shortcuts-category{display:flex;flex-direction:column;gap:8px}.shortcuts-category-title{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.shortcuts-group{display:flex;flex-direction:column;gap:4px}.shortcut-item{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-item-bg, rgba(0, 0, 0, 0.02))}.shortcut-label{font-size:14px;color:var(--kritzel-settings-content-text-color, #666666)}.shortcut-key{font-family:monospace;font-size:12px;padding:2px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-key-bg, #f0f0f0);color:var(--kritzel-settings-shortcut-key-color, #333333);border:1px solid var(--kritzel-settings-shortcut-key-border, #ddd)}`;
28505
28543
 
@@ -29344,7 +29382,7 @@ const KritzelTooltip = class {
29344
29382
  };
29345
29383
  KritzelTooltip.style = kritzelTooltipCss();
29346
29384
 
29347
- const kritzelUtilityPanelCss = () => `:host{display:flex;flex-direction:row;align-items:center;padding:4px;gap:8px;border-top-left-radius:12px;border-top-right-radius:12px;background-color:var(--kritzel-utility-panel-background-color, #e2e2e2);width:fit-content;user-select:none}.utility-button{display:flex;justify-content:center;align-items:center;width:28px;height:28px;padding:8px 4px;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);color:var(--kritzel-utility-panel-button-color, #333333);--kritzel-icon-color:var(--kritzel-utility-panel-button-color, #333333);-webkit-tap-highlight-color:transparent;border-radius:var(--kritzel-utility-panel-button-border-radius, 8px)}.utility-button:hover,.utility-button:focus-visible{background-color:var(--kritzel-utility-panel-button-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.utility-button:disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}.utility-separator{width:1px;height:16px;background-color:var(--kritzel-utility-panel-separator-color, hsl(0, 0%, 0%, 8%))}`;
29385
+ const kritzelUtilityPanelCss = () => `:host{display:flex;flex-direction:row;align-items:center;padding:4px;gap:8px;border-top-left-radius:12px;border-top-right-radius:12px;background-color:var(--kritzel-utility-panel-background-color, #e2e2e2);width:fit-content;user-select:none;z-index:10000}.utility-button{display:flex;justify-content:center;align-items:center;width:28px;height:28px;padding:8px 4px;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);color:var(--kritzel-utility-panel-button-color, #333333);--kritzel-icon-color:var(--kritzel-utility-panel-button-color, #333333);-webkit-tap-highlight-color:transparent;border-radius:var(--kritzel-utility-panel-button-border-radius, 8px)}.utility-button:hover,.utility-button:focus-visible{background-color:var(--kritzel-utility-panel-button-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.utility-button:disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}.utility-separator{width:1px;height:16px;background-color:var(--kritzel-utility-panel-separator-color, hsl(0, 0%, 0%, 8%))}`;
29348
29386
 
29349
29387
  const KritzelUtilityPanel = class {
29350
29388
  constructor(hostRef) {
@@ -1,4 +1,4 @@
1
- import { r as registerInstance, c as createEvent, h, H as Host } from './index-MV-81ybv.js';
1
+ import { r as registerInstance, c as createEvent, h, H as Host } from './index-BbOHefEf.js';
2
2
 
3
3
  const kritzelBrushStyleCss = () => `:host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box;width:100%}.brush-style-button{display:flex;justify-content:center;align-items:center;width:42px;height:32px;padding:0;border:none;outline:none;background:none;border-radius:0;color:var(--control-text-color);font-weight:bold;-webkit-tap-highlight-color:transparent}.font-style-button:not(:last-child){border-right:1px solid #333333}.font-style-button:hover{background-color:var(--control-hover-bg)}.font-style-button:active{background-color:var(--control-active-bg)}.font-style-button.selected,.font-style-button.selected:hover,.font-style-button.selected:active{background-color:var(--control-selected-bg);color:var(--control-selected-color)}`;
4
4
 
@@ -1,5 +1,5 @@
1
- import { b as bootstrapLazy } from './index-MV-81ybv.js';
2
- export { s as setNonce } from './index-MV-81ybv.js';
1
+ import { b as bootstrapLazy } from './index-BbOHefEf.js';
2
+ export { s as setNonce } from './index-BbOHefEf.js';
3
3
  import { g as globalScripts } from './app-globals-DQuL1Twl.js';
4
4
 
5
5
  const defineCustomElements = async (win, options) => {
@@ -1,9 +1,9 @@
1
- import { p as promiseResolve, b as bootstrapLazy } from './index-MV-81ybv.js';
2
- export { s as setNonce } from './index-MV-81ybv.js';
1
+ import { p as promiseResolve, b as bootstrapLazy } from './index-BbOHefEf.js';
2
+ export { s as setNonce } from './index-BbOHefEf.js';
3
3
  import { g as globalScripts } from './app-globals-DQuL1Twl.js';
4
4
 
5
5
  /*
6
- Stencil Client Patch Browser v4.43.2 | MIT Licensed | https://stenciljs.com
6
+ Stencil Client Patch Browser v4.43.3 | MIT Licensed | https://stenciljs.com
7
7
  */
8
8
 
9
9
  var patchBrowser = () => {