kritzel-stencil 0.4.7 → 0.4.8

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 (47) hide show
  1. package/dist/cjs/index.cjs.js +1 -1
  2. package/dist/cjs/kritzel-active-users_47.cjs.entry.js +31 -14
  3. package/dist/cjs/{schema.constants-C8hqt--r.js → schema.constants-gDeS7USU.js} +75 -7
  4. package/dist/collection/classes/handlers/line-handle.handler.js +1 -1
  5. package/dist/collection/classes/managers/license.manager.js +56 -0
  6. package/dist/collection/classes/objects/line.class.js +1 -1
  7. package/dist/collection/classes/objects/shape.class.js +3 -3
  8. package/dist/collection/classes/objects/text.class.js +1 -1
  9. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +10 -3
  10. package/dist/collection/constants/license.constants.js +1 -1
  11. package/dist/collection/constants/version.js +1 -1
  12. package/dist/collection/helpers/svg-export.helper.js +19 -9
  13. package/dist/collection/helpers/theme.helper.js +8 -0
  14. package/dist/collection/themes/dark-theme.js +2 -0
  15. package/dist/collection/themes/light-theme.js +2 -0
  16. package/dist/components/index.js +3 -3
  17. package/dist/components/kritzel-awareness-cursors.js +1 -1
  18. package/dist/components/kritzel-color-palette.js +1 -1
  19. package/dist/components/kritzel-color.js +1 -1
  20. package/dist/components/kritzel-controls.js +1 -1
  21. package/dist/components/kritzel-editor.js +9 -9
  22. package/dist/components/kritzel-engine.js +1 -1
  23. package/dist/components/kritzel-settings.js +1 -1
  24. package/dist/components/kritzel-stroke-size.js +1 -1
  25. package/dist/components/kritzel-tool-config.js +1 -1
  26. package/dist/components/{p-Ka7OWbnk.js → p-0H4HOJjy.js} +2 -2
  27. package/dist/components/{p-1nG2hxfJ.js → p-9m1cAVwG.js} +2 -2
  28. package/dist/components/{p-DkH3hoLz.js → p-BknTMcbz.js} +5 -5
  29. package/dist/components/{p-zd7zXld8.js → p-CMZ09rB1.js} +1 -1
  30. package/dist/components/{p-BmyTdQGy.js → p-CURiiQfq.js} +12 -0
  31. package/dist/components/{p-Bm_BWQa4.js → p-Ckm1Aq0V.js} +1 -1
  32. package/dist/components/{p-BZxOukfY.js → p-Cr2z2UBL.js} +4 -4
  33. package/dist/components/{p-C2yi85nc.js → p-D8bHNNEm.js} +93 -20
  34. package/dist/components/{p-D0oplzU-.js → p-DgA865Tp.js} +1 -1
  35. package/dist/esm/index.js +2 -2
  36. package/dist/esm/kritzel-active-users_47.entry.js +31 -14
  37. package/dist/esm/{schema.constants-uC7_X6yr.js → schema.constants-Rpm1NA9u.js} +75 -7
  38. package/dist/stencil/index.esm.js +2 -2
  39. package/dist/stencil/{p-472f2e90.entry.js → p-8c1b7b08.entry.js} +31 -14
  40. package/dist/stencil/{p-uC7_X6yr.js → p-Rpm1NA9u.js} +75 -7
  41. package/dist/stencil/stencil.esm.js +1 -1
  42. package/dist/types/classes/managers/license.manager.d.ts +6 -0
  43. package/dist/types/constants/license.constants.d.ts +1 -1
  44. package/dist/types/constants/version.d.ts +1 -1
  45. package/dist/types/helpers/theme.helper.d.ts +1 -0
  46. package/dist/types/interfaces/theme.interface.d.ts +2 -0
  47. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { K as KritzelControls$1, d as defineCustomElement$1 } from './p-DkH3hoLz.js';
1
+ import { K as KritzelControls$1, d as defineCustomElement$1 } from './p-BknTMcbz.js';
2
2
 
3
3
  const KritzelControls = KritzelControls$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,12 +1,12 @@
1
1
  import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
2
  import { K as KritzelIconRegistry, d as defineCustomElement$s } from './p-CdR76C4L.js';
3
- import { v as DEFAULT_STROKE_SIZES, w as DEFAULT_FONT_SIZES, S as ShapeType, m as KritzelSelectionTool, f as KritzelBrushTool, h as KritzelEraserTool, g as KritzelLineTool, k as KritzelShapeTool, j as KritzelTextTool, i as KritzelImageTool, s as KritzelAlignment, x as DEFAULT_SYNC_CONFIG, y as KritzelSelectionGroup, z as KritzelSelectionBox, B as KritzelKeyboardHelper, C as defineCustomElement$x } from './p-C2yi85nc.js';
4
- import { D as DEFAULT_COLOR_PALETTE, T as ThemeHelper, d as darkTheme, l as lightTheme } from './p-BmyTdQGy.js';
3
+ import { v as DEFAULT_STROKE_SIZES, w as DEFAULT_FONT_SIZES, S as ShapeType, m as KritzelSelectionTool, f as KritzelBrushTool, h as KritzelEraserTool, g as KritzelLineTool, k as KritzelShapeTool, j as KritzelTextTool, i as KritzelImageTool, s as KritzelAlignment, x as DEFAULT_SYNC_CONFIG, y as KritzelSelectionGroup, z as KritzelSelectionBox, B as KritzelKeyboardHelper, C as defineCustomElement$x } from './p-D8bHNNEm.js';
4
+ import { D as DEFAULT_COLOR_PALETTE, T as ThemeHelper, d as darkTheme, l as lightTheme } from './p-CURiiQfq.js';
5
5
  import { D as DEFAULT_TEXT_TOOL_AVAILABLE_FONTS, r as resolveTextToolAvailableFonts, K as KritzelFontRegistry } from './p-DJkKlUyZ.js';
6
6
  import { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, d as defineCustomElement$4 } from './p-CwuGA058.js';
7
7
  import { K as KritzelDevicesHelper } from './p-jGOpkGDl.js';
8
8
  import { O as ObjectHelper } from './p-Dd-pMvlr.js';
9
- import { d as defineCustomElement$J } from './p-Ka7OWbnk.js';
9
+ import { d as defineCustomElement$J } from './p-0H4HOJjy.js';
10
10
  import * as Y from 'yjs';
11
11
  import 'y-indexeddb';
12
12
  import 'y-websocket';
@@ -14,10 +14,10 @@ import { d as defineCustomElement$L } from './p-yD_3Z3K1.js';
14
14
  import { d as defineCustomElement$K } from './p-DXcjIb_a.js';
15
15
  import { d as defineCustomElement$I } from './p-BYO6pz8T.js';
16
16
  import { d as defineCustomElement$H } from './p-oGAPPwAL.js';
17
- import { d as defineCustomElement$G } from './p-zd7zXld8.js';
18
- import { d as defineCustomElement$F } from './p-1nG2hxfJ.js';
17
+ import { d as defineCustomElement$G } from './p-CMZ09rB1.js';
18
+ import { d as defineCustomElement$F } from './p-9m1cAVwG.js';
19
19
  import { d as defineCustomElement$E } from './p-BxpKq94F.js';
20
- import { d as defineCustomElement$D } from './p-DkH3hoLz.js';
20
+ import { d as defineCustomElement$D } from './p-BknTMcbz.js';
21
21
  import { d as defineCustomElement$C } from './p-BO9BvTtK.js';
22
22
  import { d as defineCustomElement$B } from './p-BU-FZuj0.js';
23
23
  import { d as defineCustomElement$A } from './p-Cm33td2O.js';
@@ -39,14 +39,14 @@ import { d as defineCustomElement$i } from './p-DIMNEOTW.js';
39
39
  import { d as defineCustomElement$h } from './p-BzrxIesp.js';
40
40
  import { d as defineCustomElement$g } from './p-D09kgc5Q.js';
41
41
  import { d as defineCustomElement$f } from './p-BLOPBDUF.js';
42
- import { d as defineCustomElement$e } from './p-D0oplzU-.js';
42
+ import { d as defineCustomElement$e } from './p-DgA865Tp.js';
43
43
  import { d as defineCustomElement$d } from './p-BFYtCsZu.js';
44
44
  import { d as defineCustomElement$c } from './p-BMRln59F.js';
45
45
  import { d as defineCustomElement$b } from './p-BzJEwFtn.js';
46
46
  import { d as defineCustomElement$a } from './p-D8TOEhPY.js';
47
- import { d as defineCustomElement$9 } from './p-Bm_BWQa4.js';
47
+ import { d as defineCustomElement$9 } from './p-Ckm1Aq0V.js';
48
48
  import { d as defineCustomElement$8 } from './p-CM1duewg.js';
49
- import { d as defineCustomElement$7 } from './p-BZxOukfY.js';
49
+ import { d as defineCustomElement$7 } from './p-Cr2z2UBL.js';
50
50
  import { d as defineCustomElement$6 } from './p-DrQRChp3.js';
51
51
  import { d as defineCustomElement$5 } from './p-DwY5pghH.js';
52
52
  import { d as defineCustomElement$3 } from './p-DDbO5q-e.js';
@@ -1,4 +1,4 @@
1
- import { G as KritzelEngine$1, C as defineCustomElement$1 } from './p-C2yi85nc.js';
1
+ import { G as KritzelEngine$1, C as defineCustomElement$1 } from './p-D8bHNNEm.js';
2
2
 
3
3
  const KritzelEngine = KritzelEngine$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,4 +1,4 @@
1
- import { K as KritzelSettings$1, d as defineCustomElement$1 } from './p-D0oplzU-.js';
1
+ import { K as KritzelSettings$1, d as defineCustomElement$1 } from './p-DgA865Tp.js';
2
2
 
3
3
  const KritzelSettings = KritzelSettings$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,4 +1,4 @@
1
- import { K as KritzelStrokeSize$1, d as defineCustomElement$1 } from './p-Bm_BWQa4.js';
1
+ import { K as KritzelStrokeSize$1, d as defineCustomElement$1 } from './p-Ckm1Aq0V.js';
2
2
 
3
3
  const KritzelStrokeSize = KritzelStrokeSize$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,4 +1,4 @@
1
- import { a as KritzelToolConfig$1, d as defineCustomElement$1 } from './p-BZxOukfY.js';
1
+ import { a as KritzelToolConfig$1, d as defineCustomElement$1 } from './p-Cr2z2UBL.js';
2
2
 
3
3
  const KritzelToolConfig = KritzelToolConfig$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,6 +1,6 @@
1
1
  import { p as proxyCustomElement, H, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
2
  import { O as ObjectHelper } from './p-Dd-pMvlr.js';
3
- import { a as KritzelColorHelper } from './p-BmyTdQGy.js';
3
+ import { a as KritzelColorHelper } from './p-CURiiQfq.js';
4
4
 
5
5
  class KritzelGeometryHelper {
6
6
  static doPolygonsIntersect(polygon1, polygon2) {
@@ -1950,7 +1950,7 @@ class KritzelLine extends KritzelBaseObject {
1950
1950
  getArrowFill(end) {
1951
1951
  const config = end === 'start' ? this.arrows?.start : this.arrows?.end;
1952
1952
  const color = config?.fill ?? this.stroke;
1953
- return KritzelColorHelper.resolveThemeColor(color);
1953
+ return KritzelColorHelper.resolveThemeColor(color, this._core?.themeManager?.currentTheme);
1954
1954
  }
1955
1955
  /**
1956
1956
  * Generates SVG path data for an arrow head based on the given style.
@@ -1,6 +1,6 @@
1
1
  import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
- import { a as KritzelColorHelper } from './p-BmyTdQGy.js';
3
- import { d as defineCustomElement$1 } from './p-zd7zXld8.js';
2
+ import { a as KritzelColorHelper } from './p-CURiiQfq.js';
3
+ import { d as defineCustomElement$1 } from './p-CMZ09rB1.js';
4
4
 
5
5
  const kritzelColorPaletteCss = () => `:host{display:flex;align-items:flex-start;gap:8px;padding:0;width:100%;box-sizing:border-box}.color-grid{width:100%;display:grid;grid-template-columns:repeat(6, 32px);gap:8px;justify-items:center;overflow:hidden;height:40px;transition:height 0.1s ease-in-out}.color-grid.expanded{height:500px}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box}.color-container:hover{background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.color-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-color-palette-selected-background-color)}`;
6
6
 
@@ -1,9 +1,9 @@
1
1
  import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
2
  import { K as KritzelDevicesHelper } from './p-jGOpkGDl.js';
3
- import { K as KritzelToolConfigHelper, d as defineCustomElement$3 } from './p-BZxOukfY.js';
4
- import { a as KritzelColorHelper } from './p-BmyTdQGy.js';
5
- import { d as defineCustomElement$e } from './p-zd7zXld8.js';
6
- import { d as defineCustomElement$d } from './p-1nG2hxfJ.js';
3
+ import { K as KritzelToolConfigHelper, d as defineCustomElement$3 } from './p-Cr2z2UBL.js';
4
+ import { a as KritzelColorHelper } from './p-CURiiQfq.js';
5
+ import { d as defineCustomElement$e } from './p-CMZ09rB1.js';
6
+ import { d as defineCustomElement$d } from './p-9m1cAVwG.js';
7
7
  import { d as defineCustomElement$c } from './p-Df3BwVGy.js';
8
8
  import { d as defineCustomElement$b } from './p-DgnK50xO.js';
9
9
  import { d as defineCustomElement$a } from './p-djJSnjAX.js';
@@ -12,7 +12,7 @@ import { d as defineCustomElement$8 } from './p-CdR76C4L.js';
12
12
  import { d as defineCustomElement$7 } from './p-CXpv9Rxe.js';
13
13
  import { d as defineCustomElement$6 } from './p-BzrxIesp.js';
14
14
  import { d as defineCustomElement$5 } from './p-BFYtCsZu.js';
15
- import { d as defineCustomElement$4 } from './p-Bm_BWQa4.js';
15
+ import { d as defineCustomElement$4 } from './p-Ckm1Aq0V.js';
16
16
  import { d as defineCustomElement$2 } from './p-DrQRChp3.js';
17
17
  import { d as defineCustomElement$1 } from './p-DwY5pghH.js';
18
18
 
@@ -1,5 +1,5 @@
1
1
  import { p as proxyCustomElement, H, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
- import { a as KritzelColorHelper } from './p-BmyTdQGy.js';
2
+ import { a as KritzelColorHelper } from './p-CURiiQfq.js';
3
3
 
4
4
  const kritzelColorCss = () => `:host{display:flex}.checkerboard-bg{background:repeating-conic-gradient( var(--kritzel-checkerboard-color-dark, #ccc) 0% 25%, var(--kritzel-checkerboard-color-light, #fff) 0% 50% ) 50% / 8px 8px;position:relative;overflow:hidden}.color-circle{width:24px;height:24px;border-radius:50%;box-sizing:border-box;display:block}.color-circle.white{border:1px solid var(--kritzel-color-palette-circle-border-color, #dddcdc)}`;
5
5
 
@@ -173,7 +173,9 @@ const lightTheme = {
173
173
  },
174
174
  snap: {
175
175
  indicatorFill: 'rgba(59, 130, 246, 0.3)',
176
+ indicatorFillInactive: 'rgba(59, 130, 246, 0.18)',
176
177
  indicatorStroke: '#007bff',
178
+ indicatorStrokeInactive: 'rgba(59, 130, 246, 0.5)',
177
179
  lineStroke: 'rgba(0, 0, 0, 0.2)',
178
180
  },
179
181
  fontSize: {
@@ -510,7 +512,9 @@ const darkTheme = {
510
512
  },
511
513
  snap: {
512
514
  indicatorFill: 'rgba(10, 132, 255, 0.35)',
515
+ indicatorFillInactive: 'rgba(10, 132, 255, 0.2)',
513
516
  indicatorStroke: '#0A84FF',
517
+ indicatorStrokeInactive: 'rgba(255, 255, 255, 0.45)',
514
518
  lineStroke: 'rgba(255, 255, 255, 0.35)',
515
519
  },
516
520
  fontSize: {
@@ -710,6 +714,7 @@ const darkTheme = {
710
714
  };
711
715
 
712
716
  class ThemeHelper {
717
+ static appliedVariableNames = new WeakMap();
713
718
  /**
714
719
  * Converts a camelCase string to kebab-case.
715
720
  * @example ThemeHelper.camelToKebab('controlHoverBackgroundColor') → 'control-hover-background-color'
@@ -775,7 +780,14 @@ class ThemeHelper {
775
780
  */
776
781
  static applyThemeToElement(element, theme) {
777
782
  const variables = ThemeHelper.flattenThemeToVariables(theme);
783
+ const previousVariableNames = ThemeHelper.appliedVariableNames.get(element);
784
+ for (const name of previousVariableNames ?? []) {
785
+ if (!variables.has(name)) {
786
+ element.style.removeProperty(name);
787
+ }
788
+ }
778
789
  ThemeHelper.applyVariablesToElement(element, variables);
790
+ ThemeHelper.appliedVariableNames.set(element, new Set(variables.keys()));
779
791
  }
780
792
  }
781
793
 
@@ -1,5 +1,5 @@
1
1
  import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
- import { d as defineCustomElement$1 } from './p-zd7zXld8.js';
2
+ import { d as defineCustomElement$1 } from './p-CMZ09rB1.js';
3
3
 
4
4
  const kritzelStrokeSizeCss = () => `:host{display:flex;align-items:flex-start;gap:0;padding:0;width:100%;box-sizing:border-box}.size-grid{width:100%;display:grid;grid-template-columns:repeat(auto-fill, 32px);gap:8px;justify-items:center}.size-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box}.size-container:hover{background-color:var(--kritzel-stroke-size-hover-background-color, #ebebeb)}.size-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-stroke-size-selected-background-color, #ebebeb)}`;
5
5
 
@@ -1,8 +1,8 @@
1
1
  import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
- import { a as KritzelColorHelper } from './p-BmyTdQGy.js';
2
+ import { a as KritzelColorHelper } from './p-CURiiQfq.js';
3
3
  import { r as resolveTextToolAvailableFonts, K as KritzelFontRegistry } from './p-DJkKlUyZ.js';
4
- import { d as defineCustomElement$b } from './p-zd7zXld8.js';
5
- import { d as defineCustomElement$a } from './p-1nG2hxfJ.js';
4
+ import { d as defineCustomElement$b } from './p-CMZ09rB1.js';
5
+ import { d as defineCustomElement$a } from './p-9m1cAVwG.js';
6
6
  import { d as defineCustomElement$9 } from './p-Df3BwVGy.js';
7
7
  import { d as defineCustomElement$8 } from './p-DgnK50xO.js';
8
8
  import { d as defineCustomElement$7 } from './p-djJSnjAX.js';
@@ -11,7 +11,7 @@ import { d as defineCustomElement$5 } from './p-CdR76C4L.js';
11
11
  import { d as defineCustomElement$4 } from './p-CXpv9Rxe.js';
12
12
  import { d as defineCustomElement$3 } from './p-BzrxIesp.js';
13
13
  import { d as defineCustomElement$2 } from './p-BFYtCsZu.js';
14
- import { d as defineCustomElement$1 } from './p-Bm_BWQa4.js';
14
+ import { d as defineCustomElement$1 } from './p-Ckm1Aq0V.js';
15
15
 
16
16
  class KritzelToolConfigHelper {
17
17
  static getToolConfig(tool) {
@@ -1,8 +1,8 @@
1
1
  import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
2
  import { a as KritzelMouseButton, d as defineCustomElement$5 } from './p-Cm33td2O.js';
3
- import { K as KritzelBaseObject, e as KritzelMathHelper, f as KritzelGeometryHelper, a as KritzelPath, b as KritzelLine, d as defineCustomElement$6 } from './p-Ka7OWbnk.js';
3
+ import { K as KritzelBaseObject, e as KritzelMathHelper, f as KritzelGeometryHelper, a as KritzelPath, b as KritzelLine, d as defineCustomElement$6 } from './p-0H4HOJjy.js';
4
4
  import { c as commonjsGlobal } from './p-BFTU3MAI.js';
5
- import { a as KritzelColorHelper, D as DEFAULT_COLOR_PALETTE, K as KritzelThemeManager } from './p-BmyTdQGy.js';
5
+ import { a as KritzelColorHelper, D as DEFAULT_COLOR_PALETTE, K as KritzelThemeManager } from './p-CURiiQfq.js';
6
6
  import { K as KritzelDevicesHelper } from './p-jGOpkGDl.js';
7
7
  import { K as KritzelFontRegistry, r as resolveTextToolAvailableFonts } from './p-DJkKlUyZ.js';
8
8
  import { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, d as defineCustomElement$1 } from './p-CwuGA058.js';
@@ -13877,7 +13877,7 @@ class KritzelText extends KritzelBaseObject {
13877
13877
  }
13878
13878
  element.style.fontFamily = KritzelFontRegistry.resolveCssFontFamily(this.fontFamily);
13879
13879
  element.style.fontSize = `${this.fontSize}pt`;
13880
- element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor);
13880
+ element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor, this._core?.themeManager?.currentTheme);
13881
13881
  if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
13882
13882
  if (!this._core.store.state.isScaling && !this._core.store.state.isPanning) {
13883
13883
  requestAnimationFrame(() => this.adjustSizeOnInput());
@@ -16219,7 +16219,7 @@ class KritzelShape extends KritzelBaseObject {
16219
16219
  }
16220
16220
  element.style.fontFamily = this.fontFamily;
16221
16221
  element.style.fontSize = `${this.fontSize}pt`;
16222
- element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor);
16222
+ element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor, this._core?.themeManager?.currentTheme);
16223
16223
  element.style.whiteSpace = 'pre-wrap';
16224
16224
  element.style.wordWrap = 'break-word';
16225
16225
  if (this.editor.dom.parentElement === element) {
@@ -16535,13 +16535,13 @@ class KritzelShape extends KritzelBaseObject {
16535
16535
  this.fontColor = KritzelColorHelper.determineTextColor(this.fillColor);
16536
16536
  // Update the editor's text color immediately
16537
16537
  if (this.editor?.dom?.parentElement) {
16538
- this.editor.dom.parentElement.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor);
16538
+ this.editor.dom.parentElement.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor, this._core?.themeManager?.currentTheme);
16539
16539
  }
16540
16540
  }
16541
16541
  else if (changedProperties.includes('fontColor')) {
16542
16542
  // Also update editor when fontColor changes directly
16543
16543
  if (this.editor?.dom?.parentElement) {
16544
- this.editor.dom.parentElement.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor);
16544
+ this.editor.dom.parentElement.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor, this._core?.themeManager?.currentTheme);
16545
16545
  }
16546
16546
  }
16547
16547
  }
@@ -21164,7 +21164,7 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
21164
21164
  t: clipInfo?.t,
21165
21165
  edgeX: clipInfo?.edgeX,
21166
21166
  edgeY: clipInfo?.edgeY,
21167
- lineStroke: KritzelColorHelper.resolveThemeColor(line.stroke),
21167
+ lineStroke: KritzelColorHelper.resolveThemeColor(line.stroke, this._core.themeManager.currentTheme),
21168
21168
  lineStrokeWidth: line.strokeWidth / line.scale,
21169
21169
  arrowOffset: endpoint === 'start'
21170
21170
  ? (line.hasStartArrow ? line.getArrowSize('start') / line.scale : undefined)
@@ -23839,7 +23839,7 @@ const KRITZEL_LICENSE_TOKEN_PREFIX = 'KRTZL1.';
23839
23839
  * printed public key here. Replacing this value invalidates every license
23840
23840
  * signed with the previous key.
23841
23841
  */
23842
- const KRITZEL_LICENSE_PUBLIC_KEY = 'I-pYJlxDEjT94rwSaqhXW5Sv__fMKS-JKKnV3pg0PaM';
23842
+ const KRITZEL_LICENSE_PUBLIC_KEY = '2IwZDin-qV3kOt8SEQCqdaJsGT9S7tAGapUYJVnVGQo';
23843
23843
 
23844
23844
  /** Minimum delay (ms) between periodic license re-validations. */
23845
23845
  const MIN_REVALIDATION_DELAY_MS = 30_000;
@@ -24072,8 +24072,64 @@ class KritzelLicenseManager {
24072
24072
  if (typeof claims.exp === 'number' && claims.exp * 1000 <= Date.now()) {
24073
24073
  return { status: 'rejected' }; // Cleanly expired.
24074
24074
  }
24075
+ const allowedDomains = this.normalizeAllowedDomains(claims.allowedDomains);
24076
+ if (allowedDomains === null || allowedDomains.length === 0) {
24077
+ return { status: 'rejected' };
24078
+ }
24079
+ const currentHostname = this.getCurrentHostname();
24080
+ if (!currentHostname || !allowedDomains.includes(currentHostname)) {
24081
+ return { status: 'rejected' };
24082
+ }
24075
24083
  return { status: 'pass', payloadSegment, signatureSegment, claims };
24076
24084
  }
24085
+ /** Returns the normalized current hostname, or null when unavailable/invalid. */
24086
+ getCurrentHostname() {
24087
+ const hostname = globalThis.location?.hostname;
24088
+ if (typeof hostname !== 'string') {
24089
+ return null;
24090
+ }
24091
+ return this.normalizeDomain(hostname);
24092
+ }
24093
+ /** Normalizes and validates the allowed domains claim. */
24094
+ normalizeAllowedDomains(domains) {
24095
+ if (!Array.isArray(domains)) {
24096
+ return null;
24097
+ }
24098
+ const normalized = new Set();
24099
+ for (const entry of domains) {
24100
+ if (typeof entry !== 'string') {
24101
+ return null;
24102
+ }
24103
+ const domain = this.normalizeDomain(entry);
24104
+ if (!domain) {
24105
+ return null;
24106
+ }
24107
+ normalized.add(domain);
24108
+ }
24109
+ return Array.from(normalized);
24110
+ }
24111
+ /** Normalizes a domain and rejects malformed hostnames. */
24112
+ normalizeDomain(value) {
24113
+ const trimmed = value.trim().toLowerCase();
24114
+ if (trimmed.length === 0) {
24115
+ return null;
24116
+ }
24117
+ const withoutTrailingDot = trimmed.endsWith('.') ? trimmed.slice(0, -1) : trimmed;
24118
+ if (withoutTrailingDot.length === 0) {
24119
+ return null;
24120
+ }
24121
+ try {
24122
+ const parsed = new URL(`https://${withoutTrailingDot}`);
24123
+ const normalizedHostname = parsed.hostname.toLowerCase();
24124
+ if (normalizedHostname !== withoutTrailingDot) {
24125
+ return null;
24126
+ }
24127
+ return normalizedHostname;
24128
+ }
24129
+ catch {
24130
+ return null;
24131
+ }
24132
+ }
24077
24133
  /**
24078
24134
  * Verifies the Ed25519 signature of the token against the embedded public
24079
24135
  * key. Resolves true/false for a definitive valid/invalid signature.
@@ -47291,14 +47347,20 @@ class KritzelSvgExportHelper {
47291
47347
  const scale = this.getObjectScale(text);
47292
47348
  // Convert ProseMirror content to HTML
47293
47349
  const htmlContent = this.prosemirrorToHtml(text.content, text, theme);
47294
- // Calculate dimensions accounting for scale
47350
+ // Calculate dimensions in SVG world units (world units = CSS px in a 1:1 SVG).
47295
47351
  const width = text.totalWidth / scale;
47296
47352
  const height = text.totalHeight / scale;
47353
+ // Convert the font size from pt to SVG world units (px equivalent).
47354
+ // text.fontSize is stored in CSS pt; 1 pt = 4/3 px at 96 dpi.
47355
+ // We also bake in scaleFactor (user resize) and divide by the object scale so
47356
+ // that the rendered font aligns with the world-unit dimensions above.
47357
+ // The CSS transform: scale(scaleFactor) is removed from the div because the
47358
+ // adjusted font-size already accounts for it – keeping both would double-scale
47359
+ // the content and overflow the foreignObject.
47360
+ const svgFontSizePx = (text.fontSize * (4 / 3) * (text.scaleFactor || 1) / scale).toFixed(4);
47297
47361
  return `<g transform="${transform}"${opacity}>
47298
- <foreignObject x="0" y="0" width="${width}" height="${height}">
47299
- <div xmlns="http://www.w3.org/1999/xhtml" style="font-family: ${text.fontFamily}; font-size: ${text.fontSize}pt; color: ${fontColor}; background-color: ${bgColor || 'transparent'}; transform: scale(${text.scaleFactor}); transform-origin: top left; white-space: pre-wrap; word-wrap: break-word;">
47300
- ${htmlContent}
47301
- </div>
47362
+ <foreignObject x="0" y="0" width="${width}" height="${height}" overflow="visible">
47363
+ <div xmlns="http://www.w3.org/1999/xhtml" style="font-family: ${text.fontFamily}; font-size: ${svgFontSizePx}px; color: ${fontColor}; background-color: ${bgColor || 'transparent'}; white-space: pre-wrap; word-wrap: break-word; width: 100%; margin: 0; padding: 0; box-sizing: border-box;">${htmlContent.trim()}</div>
47302
47364
  </foreignObject>
47303
47365
  </g>`;
47304
47366
  }
@@ -47317,9 +47379,13 @@ class KritzelSvgExportHelper {
47317
47379
  const height = text.totalHeight / scale;
47318
47380
  const lines = this.prosemirrorToPlainTextLines(text.content);
47319
47381
  const resolvedLines = lines.length > 0 ? lines : [''];
47320
- const resolvedFontSize = Math.max(1, text.fontSize * (text.scaleFactor || 1));
47321
- const lineHeight = resolvedFontSize * 1.2;
47322
- const startY = resolvedFontSize;
47382
+ // Convert the font size from pt to SVG world units (px equivalent).
47383
+ // text.fontSize is stored in CSS pt; 1 pt = 4/3 px at 96 dpi.
47384
+ // We also bake in scaleFactor (user resize) and divide by the object scale so
47385
+ // that the rendered lines align with the world-unit bounding box dimensions above.
47386
+ const resolvedFontSizePx = Math.max(1, text.fontSize * (4 / 3) * (text.scaleFactor || 1) / scale);
47387
+ const lineHeight = resolvedFontSizePx * 1.2;
47388
+ const startY = resolvedFontSizePx;
47323
47389
  const bgRect = bgColor && bgColor !== 'transparent'
47324
47390
  ? `<rect x="0" y="0" width="${width}" height="${height}" fill="${bgColor}"/>`
47325
47391
  : '';
@@ -47331,7 +47397,7 @@ class KritzelSvgExportHelper {
47331
47397
  .join('');
47332
47398
  return `<g transform="${transform}"${opacity}>
47333
47399
  ${bgRect}
47334
- <text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSize}" fill="${fontColor}">${tspans}</text>
47400
+ <text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSizePx}" fill="${fontColor}">${tspans}</text>
47335
47401
  </g>`;
47336
47402
  }
47337
47403
  /**
@@ -50994,7 +51060,9 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
50994
51060
  this.emitObjectsInViewportChange();
50995
51061
  }
50996
51062
  }
50997
- return (h(Host, null, h("kritzel-loading-overlay", { visible: this.core.store.state.isLoading, text: this.core.localizationManager.translate('engine.loading') }), h("kritzel-sync-indicator", { visible: this.isSyncing, text: "Syncing..." }), 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: {
51063
+ return (h(Host, null, h("kritzel-loading-overlay", { visible: this.core.store.state.isLoading, text: this.core.localizationManager.translate('engine.loading') }), h("kritzel-sync-indicator", { visible: this.isSyncing, text: "Syncing..." }), this.core.store.state.debugInfo.showViewportInfo && (h("div", { class: "debug-panel", style: {
51064
+ color: 'var(--kritzel-global-text-primary)',
51065
+ } }, 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: {
50998
51066
  transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
50999
51067
  opacity: this._sceneBootstrapOpacity.toString(),
51000
51068
  transition: this._sceneBootstrapTransitionEnabled ? 'opacity 220ms ease-out' : 'none',
@@ -51177,6 +51245,7 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
51177
51245
  left: `${object.totalWidth}px`,
51178
51246
  top: '0',
51179
51247
  zIndex: (object.zIndex + 2).toString(),
51248
+ color: 'var(--kritzel-global-text-primary)',
51180
51249
  } }, 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' } }, "scale: ", object.scale), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "rotationDegrees: ", object.rotationDegrees), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "zIndex: ", object.zIndex), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "isSelected: ", object.isSelected ? 'true' : 'false'), KritzelClassHelper.isInstanceOf(object, 'KritzelCustomElement') && (h("div", null, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "isInteractive: ", object.isInteractive ? 'true' : 'false'))), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (h("div", null, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "assetId: ", object.assetId), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "mimeType: ", object.mimeType))))), (this.core.displaySelectionGroupUI(object) || this.core.displaySelectionLineUI(object)) &&
51181
51250
  (() => {
51182
51251
  const isSelectionGroup = KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup');
@@ -51377,8 +51446,12 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
51377
51446
  strokeDasharray: data.dashArray,
51378
51447
  strokeLinecap: 'round',
51379
51448
  } }))), h("circle", { cx: data.centerX, cy: data.centerY, r: data.indicatorRadius, style: {
51380
- fill: isActiveSnap ? 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))' : 'rgba(59, 130, 246, 0.18)',
51381
- stroke: isActiveSnap ? 'var(--kritzel-snap-indicator-stroke, #007bff)' : 'rgba(59, 130, 246, 0.5)',
51449
+ fill: isActiveSnap
51450
+ ? 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))'
51451
+ : 'var(--kritzel-snap-indicator-fill-inactive, var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.18)))',
51452
+ stroke: isActiveSnap
51453
+ ? 'var(--kritzel-snap-indicator-stroke, #007bff)'
51454
+ : 'var(--kritzel-snap-indicator-stroke-inactive, var(--kritzel-snap-indicator-stroke, rgba(59, 130, 246, 0.5)))',
51382
51455
  strokeWidth: data.indicatorStrokeWidth,
51383
51456
  } }))));
51384
51457
  })(), (() => {
@@ -12,7 +12,7 @@ import { d as defineCustomElement$1 } from './p-BzJEwFtn.js';
12
12
  * This file is auto-generated by the version bump scripts.
13
13
  * Do not modify manually.
14
14
  */
15
- const KRITZEL_VERSION = '0.4.7';
15
+ const KRITZEL_VERSION = '0.4.8';
16
16
 
17
17
  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-tab-panel{display:none}.settings-tab-panel.is-active{display:block}.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)}`;
18
18
 
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { H as HocuspocusProvider, a as HocuspocusProviderWebsocket } from './schema.constants-uC7_X6yr.js';
2
- export { O as APP_STATE_MIGRATIONS, A as AssetNotFoundError, Q as CURRENT_APP_STATE_SCHEMA_VERSION, R as CURRENT_WORKSPACE_SCHEMA_VERSION, C as DEFAULT_ASSET_STORAGE_CONFIG, D as DEFAULT_BRUSH_CONFIG, B as DEFAULT_LINE_TOOL_CONFIG, z as DEFAULT_TEXT_CONFIG, J as DE_LOCALE, G as EN_LOCALE, L as FR_LOCALE, I as IndexedDBAssetProvider, M as KritzelAlignment, t as KritzelAnchorManager, r as KritzelAssetResolver, K as KritzelBaseObject, i as KritzelBaseTool, j as KritzelBrushTool, p as KritzelCursorHelper, h as KritzelCustomElement, x as KritzelCustomElementRendererRegistry, l as KritzelEraserTool, y as KritzelFontRegistry, f as KritzelGroup, d as KritzelImage, m as KritzelImageTool, w as KritzelLicenseManager, e as KritzelLine, k as KritzelLineTool, v as KritzelLocalizationManager, c as KritzelPath, q as KritzelSelectionTool, g as KritzelShape, o as KritzelShapeTool, b as KritzelText, n as KritzelTextTool, u as KritzelThemeManager, s as KritzelWorkspace, S as ShapeType, W as WORKSPACE_EXPORT_VERSION, P as WORKSPACE_MIGRATIONS, F as darkTheme, E as lightTheme, N as runMigrations } from './schema.constants-uC7_X6yr.js';
1
+ import { H as HocuspocusProvider, a as HocuspocusProviderWebsocket } from './schema.constants-Rpm1NA9u.js';
2
+ export { O as APP_STATE_MIGRATIONS, A as AssetNotFoundError, Q as CURRENT_APP_STATE_SCHEMA_VERSION, R as CURRENT_WORKSPACE_SCHEMA_VERSION, C as DEFAULT_ASSET_STORAGE_CONFIG, D as DEFAULT_BRUSH_CONFIG, B as DEFAULT_LINE_TOOL_CONFIG, z as DEFAULT_TEXT_CONFIG, J as DE_LOCALE, G as EN_LOCALE, L as FR_LOCALE, I as IndexedDBAssetProvider, M as KritzelAlignment, t as KritzelAnchorManager, r as KritzelAssetResolver, K as KritzelBaseObject, i as KritzelBaseTool, j as KritzelBrushTool, p as KritzelCursorHelper, h as KritzelCustomElement, x as KritzelCustomElementRendererRegistry, l as KritzelEraserTool, y as KritzelFontRegistry, f as KritzelGroup, d as KritzelImage, m as KritzelImageTool, w as KritzelLicenseManager, e as KritzelLine, k as KritzelLineTool, v as KritzelLocalizationManager, c as KritzelPath, q as KritzelSelectionTool, g as KritzelShape, o as KritzelShapeTool, b as KritzelText, n as KritzelTextTool, u as KritzelThemeManager, s as KritzelWorkspace, S as ShapeType, W as WORKSPACE_EXPORT_VERSION, P as WORKSPACE_MIGRATIONS, F as darkTheme, E as lightTheme, N as runMigrations } from './schema.constants-Rpm1NA9u.js';
3
3
  import * as Y from 'yjs';
4
4
  import { IndexeddbPersistence } from 'y-indexeddb';
5
5
  import { WebsocketProvider } from 'y-websocket';
@@ -1,5 +1,5 @@
1
1
  import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-Dhio9uis.js';
2
- import { c as KritzelPath, e as KritzelLine, T as KritzelColorHelper, U as KritzelDevicesHelper, V as KritzelMouseButton, X as KritzelHTMLHelper, Y as DEFAULT_STROKE_SIZES, Z as DEFAULT_COLOR_PALETTE, S as ShapeType, q as KritzelSelectionTool, D as DEFAULT_BRUSH_CONFIG, j as KritzelBrushTool, l as KritzelEraserTool, B as DEFAULT_LINE_TOOL_CONFIG, k as KritzelLineTool, o as KritzelShapeTool, z as DEFAULT_TEXT_CONFIG, n as KritzelTextTool, m as KritzelImageTool, M as KritzelAlignment, C as DEFAULT_ASSET_STORAGE_CONFIG, _ as ObjectHelper, $ as resolveTextToolAvailableFonts, a0 as ThemeHelper, F as darkTheme, E as lightTheme, a1 as KritzelSelectionGroup, a2 as KritzelSelectionBox, a3 as KritzelIconRegistry, y as KritzelFontRegistry, a4 as KritzelKeyboardHelper, a5 as KritzelBaseHandler, s as KritzelWorkspace, f as KritzelGroup, h as KritzelCustomElement, d as KritzelImage, g as KritzelShape, b as KritzelText, N as runMigrations, R as CURRENT_WORKSPACE_SCHEMA_VERSION, P as WORKSPACE_MIGRATIONS, a6 as KritzelClassHelper, Q as CURRENT_APP_STATE_SCHEMA_VERSION, O as APP_STATE_MIGRATIONS, p as KritzelCursorHelper, a7 as KritzelImageFileHelper, a8 as imageCompression, t as KritzelAnchorManager, u as KritzelThemeManager, v as KritzelLocalizationManager, w as KritzelLicenseManager, r as KritzelAssetResolver, a9 as KritzelEventHelper, W as WORKSPACE_EXPORT_VERSION, i as KritzelBaseTool } from './schema.constants-uC7_X6yr.js';
2
+ import { c as KritzelPath, e as KritzelLine, T as KritzelColorHelper, U as KritzelDevicesHelper, V as KritzelMouseButton, X as KritzelHTMLHelper, Y as DEFAULT_STROKE_SIZES, Z as DEFAULT_COLOR_PALETTE, S as ShapeType, q as KritzelSelectionTool, D as DEFAULT_BRUSH_CONFIG, j as KritzelBrushTool, l as KritzelEraserTool, B as DEFAULT_LINE_TOOL_CONFIG, k as KritzelLineTool, o as KritzelShapeTool, z as DEFAULT_TEXT_CONFIG, n as KritzelTextTool, m as KritzelImageTool, M as KritzelAlignment, C as DEFAULT_ASSET_STORAGE_CONFIG, _ as ObjectHelper, $ as resolveTextToolAvailableFonts, a0 as ThemeHelper, F as darkTheme, E as lightTheme, a1 as KritzelSelectionGroup, a2 as KritzelSelectionBox, a3 as KritzelIconRegistry, y as KritzelFontRegistry, a4 as KritzelKeyboardHelper, a5 as KritzelBaseHandler, s as KritzelWorkspace, f as KritzelGroup, h as KritzelCustomElement, d as KritzelImage, g as KritzelShape, b as KritzelText, N as runMigrations, R as CURRENT_WORKSPACE_SCHEMA_VERSION, P as WORKSPACE_MIGRATIONS, a6 as KritzelClassHelper, Q as CURRENT_APP_STATE_SCHEMA_VERSION, O as APP_STATE_MIGRATIONS, p as KritzelCursorHelper, a7 as KritzelImageFileHelper, a8 as imageCompression, t as KritzelAnchorManager, u as KritzelThemeManager, v as KritzelLocalizationManager, w as KritzelLicenseManager, r as KritzelAssetResolver, a9 as KritzelEventHelper, W as WORKSPACE_EXPORT_VERSION, i as KritzelBaseTool } from './schema.constants-Rpm1NA9u.js';
3
3
  import * as Y from 'yjs';
4
4
  import 'y-indexeddb';
5
5
  import 'y-websocket';
@@ -26262,14 +26262,20 @@ class KritzelSvgExportHelper {
26262
26262
  const scale = this.getObjectScale(text);
26263
26263
  // Convert ProseMirror content to HTML
26264
26264
  const htmlContent = this.prosemirrorToHtml(text.content, text, theme);
26265
- // Calculate dimensions accounting for scale
26265
+ // Calculate dimensions in SVG world units (world units = CSS px in a 1:1 SVG).
26266
26266
  const width = text.totalWidth / scale;
26267
26267
  const height = text.totalHeight / scale;
26268
+ // Convert the font size from pt to SVG world units (px equivalent).
26269
+ // text.fontSize is stored in CSS pt; 1 pt = 4/3 px at 96 dpi.
26270
+ // We also bake in scaleFactor (user resize) and divide by the object scale so
26271
+ // that the rendered font aligns with the world-unit dimensions above.
26272
+ // The CSS transform: scale(scaleFactor) is removed from the div because the
26273
+ // adjusted font-size already accounts for it – keeping both would double-scale
26274
+ // the content and overflow the foreignObject.
26275
+ const svgFontSizePx = (text.fontSize * (4 / 3) * (text.scaleFactor || 1) / scale).toFixed(4);
26268
26276
  return `<g transform="${transform}"${opacity}>
26269
- <foreignObject x="0" y="0" width="${width}" height="${height}">
26270
- <div xmlns="http://www.w3.org/1999/xhtml" style="font-family: ${text.fontFamily}; font-size: ${text.fontSize}pt; color: ${fontColor}; background-color: ${bgColor || 'transparent'}; transform: scale(${text.scaleFactor}); transform-origin: top left; white-space: pre-wrap; word-wrap: break-word;">
26271
- ${htmlContent}
26272
- </div>
26277
+ <foreignObject x="0" y="0" width="${width}" height="${height}" overflow="visible">
26278
+ <div xmlns="http://www.w3.org/1999/xhtml" style="font-family: ${text.fontFamily}; font-size: ${svgFontSizePx}px; color: ${fontColor}; background-color: ${bgColor || 'transparent'}; white-space: pre-wrap; word-wrap: break-word; width: 100%; margin: 0; padding: 0; box-sizing: border-box;">${htmlContent.trim()}</div>
26273
26279
  </foreignObject>
26274
26280
  </g>`;
26275
26281
  }
@@ -26288,9 +26294,13 @@ class KritzelSvgExportHelper {
26288
26294
  const height = text.totalHeight / scale;
26289
26295
  const lines = this.prosemirrorToPlainTextLines(text.content);
26290
26296
  const resolvedLines = lines.length > 0 ? lines : [''];
26291
- const resolvedFontSize = Math.max(1, text.fontSize * (text.scaleFactor || 1));
26292
- const lineHeight = resolvedFontSize * 1.2;
26293
- const startY = resolvedFontSize;
26297
+ // Convert the font size from pt to SVG world units (px equivalent).
26298
+ // text.fontSize is stored in CSS pt; 1 pt = 4/3 px at 96 dpi.
26299
+ // We also bake in scaleFactor (user resize) and divide by the object scale so
26300
+ // that the rendered lines align with the world-unit bounding box dimensions above.
26301
+ const resolvedFontSizePx = Math.max(1, text.fontSize * (4 / 3) * (text.scaleFactor || 1) / scale);
26302
+ const lineHeight = resolvedFontSizePx * 1.2;
26303
+ const startY = resolvedFontSizePx;
26294
26304
  const bgRect = bgColor && bgColor !== 'transparent'
26295
26305
  ? `<rect x="0" y="0" width="${width}" height="${height}" fill="${bgColor}"/>`
26296
26306
  : '';
@@ -26302,7 +26312,7 @@ class KritzelSvgExportHelper {
26302
26312
  .join('');
26303
26313
  return `<g transform="${transform}"${opacity}>
26304
26314
  ${bgRect}
26305
- <text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSize}" fill="${fontColor}">${tspans}</text>
26315
+ <text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSizePx}" fill="${fontColor}">${tspans}</text>
26306
26316
  </g>`;
26307
26317
  }
26308
26318
  /**
@@ -29961,7 +29971,9 @@ const KritzelEngine = class {
29961
29971
  this.emitObjectsInViewportChange();
29962
29972
  }
29963
29973
  }
29964
- return (h(Host, null, h("kritzel-loading-overlay", { visible: this.core.store.state.isLoading, text: this.core.localizationManager.translate('engine.loading') }), h("kritzel-sync-indicator", { visible: this.isSyncing, text: "Syncing..." }), 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: {
29974
+ return (h(Host, null, h("kritzel-loading-overlay", { visible: this.core.store.state.isLoading, text: this.core.localizationManager.translate('engine.loading') }), h("kritzel-sync-indicator", { visible: this.isSyncing, text: "Syncing..." }), this.core.store.state.debugInfo.showViewportInfo && (h("div", { class: "debug-panel", style: {
29975
+ color: 'var(--kritzel-global-text-primary)',
29976
+ } }, 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: {
29965
29977
  transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
29966
29978
  opacity: this._sceneBootstrapOpacity.toString(),
29967
29979
  transition: this._sceneBootstrapTransitionEnabled ? 'opacity 220ms ease-out' : 'none',
@@ -30144,6 +30156,7 @@ const KritzelEngine = class {
30144
30156
  left: `${object.totalWidth}px`,
30145
30157
  top: '0',
30146
30158
  zIndex: (object.zIndex + 2).toString(),
30159
+ color: 'var(--kritzel-global-text-primary)',
30147
30160
  } }, 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' } }, "scale: ", object.scale), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "rotationDegrees: ", object.rotationDegrees), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "zIndex: ", object.zIndex), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "isSelected: ", object.isSelected ? 'true' : 'false'), KritzelClassHelper.isInstanceOf(object, 'KritzelCustomElement') && (h("div", null, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "isInteractive: ", object.isInteractive ? 'true' : 'false'))), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (h("div", null, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "assetId: ", object.assetId), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "mimeType: ", object.mimeType))))), (this.core.displaySelectionGroupUI(object) || this.core.displaySelectionLineUI(object)) &&
30148
30161
  (() => {
30149
30162
  const isSelectionGroup = KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup');
@@ -30344,8 +30357,12 @@ const KritzelEngine = class {
30344
30357
  strokeDasharray: data.dashArray,
30345
30358
  strokeLinecap: 'round',
30346
30359
  } }))), h("circle", { cx: data.centerX, cy: data.centerY, r: data.indicatorRadius, style: {
30347
- fill: isActiveSnap ? 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))' : 'rgba(59, 130, 246, 0.18)',
30348
- stroke: isActiveSnap ? 'var(--kritzel-snap-indicator-stroke, #007bff)' : 'rgba(59, 130, 246, 0.5)',
30360
+ fill: isActiveSnap
30361
+ ? 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))'
30362
+ : 'var(--kritzel-snap-indicator-fill-inactive, var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.18)))',
30363
+ stroke: isActiveSnap
30364
+ ? 'var(--kritzel-snap-indicator-stroke, #007bff)'
30365
+ : 'var(--kritzel-snap-indicator-stroke-inactive, var(--kritzel-snap-indicator-stroke, rgba(59, 130, 246, 0.5)))',
30349
30366
  strokeWidth: data.indicatorStrokeWidth,
30350
30367
  } }))));
30351
30368
  })(), (() => {
@@ -31818,7 +31835,7 @@ const KritzelPortal = class {
31818
31835
  * This file is auto-generated by the version bump scripts.
31819
31836
  * Do not modify manually.
31820
31837
  */
31821
- const KRITZEL_VERSION = '0.4.7';
31838
+ const KRITZEL_VERSION = '0.4.8';
31822
31839
 
31823
31840
  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-tab-panel{display:none}.settings-tab-panel.is-active{display:block}.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)}`;
31824
31841