@kritzel/engine 0.4.31

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 (373) hide show
  1. package/LICENSE.md +50 -0
  2. package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
  3. package/dist/cjs/engine.constants-CakmdKMW.js +28206 -0
  4. package/dist/cjs/index-BbbWU2aN.js +1742 -0
  5. package/dist/cjs/index.cjs.js +4232 -0
  6. package/dist/cjs/kritzel-awareness-cursors_5.cjs.entry.js +28004 -0
  7. package/dist/cjs/loader.cjs.js +13 -0
  8. package/dist/cjs/stencil.cjs.js +25 -0
  9. package/dist/collection/classes/core/core.class.js +1389 -0
  10. package/dist/collection/classes/core/reviver.class.js +124 -0
  11. package/dist/collection/classes/core/store.class.js +337 -0
  12. package/dist/collection/classes/core/viewport.class.js +794 -0
  13. package/dist/collection/classes/core/workspace.class.js +112 -0
  14. package/dist/collection/classes/handlers/base.handler.js +20 -0
  15. package/dist/collection/classes/handlers/context-menu.handler.js +170 -0
  16. package/dist/collection/classes/handlers/hover.handler.js +35 -0
  17. package/dist/collection/classes/handlers/key.handler.js +162 -0
  18. package/dist/collection/classes/handlers/line-handle.handler.js +475 -0
  19. package/dist/collection/classes/handlers/move.handler.js +295 -0
  20. package/dist/collection/classes/handlers/resize.handler.js +327 -0
  21. package/dist/collection/classes/handlers/rotation.handler.js +174 -0
  22. package/dist/collection/classes/handlers/selection.handler.js +526 -0
  23. package/dist/collection/classes/managers/anchor.manager.js +1476 -0
  24. package/dist/collection/classes/managers/browser-permission.manager.js +64 -0
  25. package/dist/collection/classes/managers/clipboard.manager.js +346 -0
  26. package/dist/collection/classes/managers/clipboard.types.js +1 -0
  27. package/dist/collection/classes/managers/cursor.manager.js +139 -0
  28. package/dist/collection/classes/managers/license.manager.js +341 -0
  29. package/dist/collection/classes/managers/localization.manager.js +227 -0
  30. package/dist/collection/classes/managers/theme.manager.js +206 -0
  31. package/dist/collection/classes/objects/base-object.class.js +462 -0
  32. package/dist/collection/classes/objects/dynamic-object.class.js +437 -0
  33. package/dist/collection/classes/objects/group.class.js +590 -0
  34. package/dist/collection/classes/objects/image.class.js +500 -0
  35. package/dist/collection/classes/objects/line.class.js +789 -0
  36. package/dist/collection/classes/objects/path.class.js +578 -0
  37. package/dist/collection/classes/objects/selection-box.class.js +32 -0
  38. package/dist/collection/classes/objects/selection-group.class.js +752 -0
  39. package/dist/collection/classes/objects/shape.class.js +628 -0
  40. package/dist/collection/classes/objects/text.class.js +461 -0
  41. package/dist/collection/classes/providers/assets/asset-resolver.class.js +536 -0
  42. package/dist/collection/classes/providers/assets/http-asset-provider.class.js +111 -0
  43. package/dist/collection/classes/providers/assets/indexeddb-asset-provider.class.js +241 -0
  44. package/dist/collection/classes/providers/assets/presigned-asset-provider.class.js +86 -0
  45. package/dist/collection/classes/providers/paste-intent/event-paste-intent.provider.js +48 -0
  46. package/dist/collection/classes/providers/paste-intent/ios-paste-intent.provider.js +16 -0
  47. package/dist/collection/classes/providers/paste-intent/navigator-paste-intent.provider.js +86 -0
  48. package/dist/collection/classes/providers/sync/broadcast-sync-provider.class.js +100 -0
  49. package/dist/collection/classes/providers/sync/hocuspocus-sync-provider.class.js +333 -0
  50. package/dist/collection/classes/providers/sync/in-memory-sync-provider.class.js +69 -0
  51. package/dist/collection/classes/providers/sync/indexeddb-sync-provider.class.js +39 -0
  52. package/dist/collection/classes/providers/sync/websocket-sync-provider.class.js +110 -0
  53. package/dist/collection/classes/registries/dynamic-object-renderer.registry.js +52 -0
  54. package/dist/collection/classes/registries/font-registry.class.js +161 -0
  55. package/dist/collection/classes/registries/icon-registry.class.js +118 -0
  56. package/dist/collection/classes/registries/paste-intent-provider.registry.js +26 -0
  57. package/dist/collection/classes/registries/tool.registry.js +69 -0
  58. package/dist/collection/classes/structures/app-state-map.structure.js +461 -0
  59. package/dist/collection/classes/structures/object-map.structure.js +1103 -0
  60. package/dist/collection/classes/structures/quadtree.structure.js +251 -0
  61. package/dist/collection/classes/tools/base-tool.class.js +88 -0
  62. package/dist/collection/classes/tools/brush-tool.class.js +236 -0
  63. package/dist/collection/classes/tools/eraser-tool.class.js +133 -0
  64. package/dist/collection/classes/tools/image-tool.class.js +152 -0
  65. package/dist/collection/classes/tools/line-tool.class.js +249 -0
  66. package/dist/collection/classes/tools/selection-tool.class.js +611 -0
  67. package/dist/collection/classes/tools/shape-tool.class.js +251 -0
  68. package/dist/collection/classes/tools/text-tool.class.js +179 -0
  69. package/dist/collection/collection-manifest.json +17 -0
  70. package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.css +115 -0
  71. package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.js +380 -0
  72. package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.css +10 -0
  73. package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.js +153 -0
  74. package/dist/collection/components/kritzel-engine/kritzel-engine.css +81 -0
  75. package/dist/collection/components/kritzel-engine/kritzel-engine.js +6345 -0
  76. package/dist/collection/components/kritzel-icon/kritzel-icon.css +18 -0
  77. package/dist/collection/components/kritzel-icon/kritzel-icon.js +93 -0
  78. package/dist/collection/components/kritzel-watermark/kritzel-watermark.css +29 -0
  79. package/dist/collection/components/kritzel-watermark/kritzel-watermark.js +83 -0
  80. package/dist/collection/configs/default-asset-storage.config.js +9 -0
  81. package/dist/collection/configs/default-brush-tool.config.js +9 -0
  82. package/dist/collection/configs/default-engine-config.js +73 -0
  83. package/dist/collection/configs/default-line-tool.config.js +12 -0
  84. package/dist/collection/configs/default-shape-tool.config.js +15 -0
  85. package/dist/collection/configs/default-sync.config.js +6 -0
  86. package/dist/collection/configs/default-text-tool.config.js +12 -0
  87. package/dist/collection/constants/color-palette.constants.js +40 -0
  88. package/dist/collection/constants/core.constants.js +1 -0
  89. package/dist/collection/constants/engine.constants.js +4 -0
  90. package/dist/collection/constants/license.constants.js +25 -0
  91. package/dist/collection/constants/schema.constants.js +4 -0
  92. package/dist/collection/constants/storage.constants.js +1 -0
  93. package/dist/collection/constants/stroke-size.constants.js +2 -0
  94. package/dist/collection/constants/text-tool-fonts.constants.js +18 -0
  95. package/dist/collection/constants/version.js +6 -0
  96. package/dist/collection/enums/alignment.enum.js +9 -0
  97. package/dist/collection/enums/event-button.enum.js +6 -0
  98. package/dist/collection/enums/handle-type.enum.js +7 -0
  99. package/dist/collection/enums/shape-type.enum.js +6 -0
  100. package/dist/collection/events/active-workspace-change.event.js +1 -0
  101. package/dist/collection/events/editor-is-ready.event.js +1 -0
  102. package/dist/collection/events/login.event.js +1 -0
  103. package/dist/collection/helpers/alignment.helper.js +73 -0
  104. package/dist/collection/helpers/class.helper.js +5 -0
  105. package/dist/collection/helpers/color.helper.js +106 -0
  106. package/dist/collection/helpers/cursor.helper.js +57 -0
  107. package/dist/collection/helpers/devices.helper.js +28 -0
  108. package/dist/collection/helpers/event.helper.js +58 -0
  109. package/dist/collection/helpers/geometry.helper.js +149 -0
  110. package/dist/collection/helpers/html.helper.js +116 -0
  111. package/dist/collection/helpers/image-file.helper.js +6 -0
  112. package/dist/collection/helpers/keyboard.helper.js +55 -0
  113. package/dist/collection/helpers/localization.helper.js +25 -0
  114. package/dist/collection/helpers/math.helper.js +8 -0
  115. package/dist/collection/helpers/migration.helper.js +45 -0
  116. package/dist/collection/helpers/object.helper.js +29 -0
  117. package/dist/collection/helpers/svg-export.helper.js +655 -0
  118. package/dist/collection/helpers/theme.helper.js +77 -0
  119. package/dist/collection/helpers/tool-config.helper.js +63 -0
  120. package/dist/collection/helpers/wheel.helper.js +113 -0
  121. package/dist/collection/index.js +107 -0
  122. package/dist/collection/interfaces/anchor.interface.js +1 -0
  123. package/dist/collection/interfaces/arrow-head.interface.js +1 -0
  124. package/dist/collection/interfaces/asset-provider.interface.js +1 -0
  125. package/dist/collection/interfaces/asset-storage-config.interface.js +1 -0
  126. package/dist/collection/interfaces/asset.interface.js +1 -0
  127. package/dist/collection/interfaces/bounding-box.interface.js +1 -0
  128. package/dist/collection/interfaces/clonable.interface.js +1 -0
  129. package/dist/collection/interfaces/context-menu-item.interface.js +1 -0
  130. package/dist/collection/interfaces/context-menu-state.interface.js +1 -0
  131. package/dist/collection/interfaces/debug-info.interface.js +1 -0
  132. package/dist/collection/interfaces/dialog.interface.js +1 -0
  133. package/dist/collection/interfaces/document-metadata.interface.js +1 -0
  134. package/dist/collection/interfaces/dynamic-object-renderer.interface.js +1 -0
  135. package/dist/collection/interfaces/engine-state.interface.js +1 -0
  136. package/dist/collection/interfaces/font.interface.js +1 -0
  137. package/dist/collection/interfaces/localization.interface.js +1 -0
  138. package/dist/collection/interfaces/login-config.interface.js +1 -0
  139. package/dist/collection/interfaces/master-detail.interface.js +1 -0
  140. package/dist/collection/interfaces/menu-item.interface.js +1 -0
  141. package/dist/collection/interfaces/migration.interface.js +1 -0
  142. package/dist/collection/interfaces/notification.interface.js +1 -0
  143. package/dist/collection/interfaces/object-change-event.interface.js +1 -0
  144. package/dist/collection/interfaces/object-export.interface.js +1 -0
  145. package/dist/collection/interfaces/object.interface.js +1 -0
  146. package/dist/collection/interfaces/paste-intent-provider.interface.js +1 -0
  147. package/dist/collection/interfaces/point.interface.js +1 -0
  148. package/dist/collection/interfaces/polygon.interface.js +1 -0
  149. package/dist/collection/interfaces/remote-cursor.interface.js +1 -0
  150. package/dist/collection/interfaces/selection-state.interface.js +1 -0
  151. package/dist/collection/interfaces/serializable.interface.js +1 -0
  152. package/dist/collection/interfaces/settings.interface.js +1 -0
  153. package/dist/collection/interfaces/share.interface.js +1 -0
  154. package/dist/collection/interfaces/shortcut.interface.js +1 -0
  155. package/dist/collection/interfaces/sync-config.interface.js +21 -0
  156. package/dist/collection/interfaces/sync-provider.interface.js +1 -0
  157. package/dist/collection/interfaces/theme.interface.js +1 -0
  158. package/dist/collection/interfaces/tool-config.interface.js +1 -0
  159. package/dist/collection/interfaces/tool-type.interface.js +1 -0
  160. package/dist/collection/interfaces/tool.interface.js +1 -0
  161. package/dist/collection/interfaces/toolbar-item.interface.js +1 -0
  162. package/dist/collection/interfaces/undo-state.interface.js +1 -0
  163. package/dist/collection/interfaces/user.interface.js +1 -0
  164. package/dist/collection/interfaces/viewport-state.interface.js +1 -0
  165. package/dist/collection/locales/de-locale.js +119 -0
  166. package/dist/collection/locales/en-locale.js +120 -0
  167. package/dist/collection/locales/fr-locale.js +119 -0
  168. package/dist/collection/migrations/app-state.migrations.js +47 -0
  169. package/dist/collection/migrations/workspace.migrations.js +67 -0
  170. package/dist/collection/themes/dark-theme.js +340 -0
  171. package/dist/collection/themes/light-theme.js +346 -0
  172. package/dist/collection/types/deep-readonly.type.js +1 -0
  173. package/dist/collection/types/state.types.js +1 -0
  174. package/dist/components/index.d.ts +47 -0
  175. package/dist/components/index.js +4143 -0
  176. package/dist/components/kritzel-awareness-cursors.d.ts +11 -0
  177. package/dist/components/kritzel-awareness-cursors.js +6 -0
  178. package/dist/components/kritzel-cursor-trail.d.ts +11 -0
  179. package/dist/components/kritzel-cursor-trail.js +6 -0
  180. package/dist/components/kritzel-engine.d.ts +11 -0
  181. package/dist/components/kritzel-engine.js +52641 -0
  182. package/dist/components/kritzel-icon.d.ts +11 -0
  183. package/dist/components/kritzel-icon.js +6 -0
  184. package/dist/components/kritzel-watermark.d.ts +11 -0
  185. package/dist/components/kritzel-watermark.js +6 -0
  186. package/dist/components/p-B2Htv9ou.js +49 -0
  187. package/dist/components/p-BvRGQvVI.js +3456 -0
  188. package/dist/components/p-CfSx6HU_.js +1469 -0
  189. package/dist/components/p-YP8wAcF4.js +122 -0
  190. package/dist/components/p-fx6msYHJ.js +167 -0
  191. package/dist/esm/app-globals-DQuL1Twl.js +3 -0
  192. package/dist/esm/engine.constants-Bl5-pbq-.js +28143 -0
  193. package/dist/esm/index-BU9Mv7y0.js +1715 -0
  194. package/dist/esm/index.js +4134 -0
  195. package/dist/esm/kritzel-awareness-cursors_5.entry.js +27978 -0
  196. package/dist/esm/loader.js +11 -0
  197. package/dist/esm/stencil.js +21 -0
  198. package/dist/index.cjs.js +1 -0
  199. package/dist/index.js +1 -0
  200. package/dist/stencil/index.esm.js +4134 -0
  201. package/dist/stencil/p-BU9Mv7y0.js +1702 -0
  202. package/dist/stencil/p-Bl5-pbq-.js +28143 -0
  203. package/dist/stencil/p-DQuL1Twl.js +3 -0
  204. package/dist/stencil/p-f0a8b7af.entry.js +27978 -0
  205. package/dist/stencil/stencil.esm.js +21 -0
  206. package/dist/types/classes/core/core.class.d.ts +532 -0
  207. package/dist/types/classes/core/reviver.class.d.ts +32 -0
  208. package/dist/types/classes/core/store.class.d.ts +198 -0
  209. package/dist/types/classes/core/viewport.class.d.ts +256 -0
  210. package/dist/types/classes/core/workspace.class.d.ts +95 -0
  211. package/dist/types/classes/handlers/base.handler.d.ts +18 -0
  212. package/dist/types/classes/handlers/context-menu.handler.d.ts +67 -0
  213. package/dist/types/classes/handlers/hover.handler.d.ts +23 -0
  214. package/dist/types/classes/handlers/key.handler.d.ts +44 -0
  215. package/dist/types/classes/handlers/line-handle.handler.d.ts +115 -0
  216. package/dist/types/classes/handlers/move.handler.d.ts +94 -0
  217. package/dist/types/classes/handlers/resize.handler.d.ts +95 -0
  218. package/dist/types/classes/handlers/rotation.handler.d.ts +50 -0
  219. package/dist/types/classes/handlers/selection.handler.d.ts +153 -0
  220. package/dist/types/classes/managers/anchor.manager.d.ts +513 -0
  221. package/dist/types/classes/managers/browser-permission.manager.d.ts +41 -0
  222. package/dist/types/classes/managers/clipboard.manager.d.ts +71 -0
  223. package/dist/types/classes/managers/clipboard.types.d.ts +23 -0
  224. package/dist/types/classes/managers/cursor.manager.d.ts +66 -0
  225. package/dist/types/classes/managers/license.manager.d.ts +147 -0
  226. package/dist/types/classes/managers/localization.manager.d.ts +145 -0
  227. package/dist/types/classes/managers/theme.manager.d.ts +112 -0
  228. package/dist/types/classes/objects/base-object.class.d.ts +266 -0
  229. package/dist/types/classes/objects/dynamic-object.class.d.ts +148 -0
  230. package/dist/types/classes/objects/group.class.d.ts +231 -0
  231. package/dist/types/classes/objects/image.class.d.ts +246 -0
  232. package/dist/types/classes/objects/line.class.d.ts +285 -0
  233. package/dist/types/classes/objects/path.class.d.ts +220 -0
  234. package/dist/types/classes/objects/selection-box.class.d.ts +19 -0
  235. package/dist/types/classes/objects/selection-group.class.d.ts +267 -0
  236. package/dist/types/classes/objects/shape.class.d.ts +322 -0
  237. package/dist/types/classes/objects/text.class.d.ts +197 -0
  238. package/dist/types/classes/providers/assets/asset-resolver.class.d.ts +141 -0
  239. package/dist/types/classes/providers/assets/http-asset-provider.class.d.ts +79 -0
  240. package/dist/types/classes/providers/assets/indexeddb-asset-provider.class.d.ts +69 -0
  241. package/dist/types/classes/providers/assets/presigned-asset-provider.class.d.ts +69 -0
  242. package/dist/types/classes/providers/paste-intent/event-paste-intent.provider.d.ts +8 -0
  243. package/dist/types/classes/providers/paste-intent/ios-paste-intent.provider.d.ts +6 -0
  244. package/dist/types/classes/providers/paste-intent/navigator-paste-intent.provider.d.ts +9 -0
  245. package/dist/types/classes/providers/sync/broadcast-sync-provider.class.d.ts +23 -0
  246. package/dist/types/classes/providers/sync/hocuspocus-sync-provider.class.d.ts +163 -0
  247. package/dist/types/classes/providers/sync/in-memory-sync-provider.class.d.ts +39 -0
  248. package/dist/types/classes/providers/sync/indexeddb-sync-provider.class.d.ts +25 -0
  249. package/dist/types/classes/providers/sync/websocket-sync-provider.class.d.ts +63 -0
  250. package/dist/types/classes/registries/dynamic-object-renderer.registry.d.ts +32 -0
  251. package/dist/types/classes/registries/font-registry.class.d.ts +19 -0
  252. package/dist/types/classes/registries/icon-registry.class.d.ts +39 -0
  253. package/dist/types/classes/registries/paste-intent-provider.registry.d.ts +10 -0
  254. package/dist/types/classes/registries/tool.registry.d.ts +53 -0
  255. package/dist/types/classes/structures/app-state-map.structure.d.ts +171 -0
  256. package/dist/types/classes/structures/object-map.structure.d.ts +403 -0
  257. package/dist/types/classes/structures/quadtree.structure.d.ts +128 -0
  258. package/dist/types/classes/tools/base-tool.class.d.ts +72 -0
  259. package/dist/types/classes/tools/brush-tool.class.d.ts +68 -0
  260. package/dist/types/classes/tools/eraser-tool.class.d.ts +38 -0
  261. package/dist/types/classes/tools/image-tool.class.d.ts +74 -0
  262. package/dist/types/classes/tools/line-tool.class.d.ts +63 -0
  263. package/dist/types/classes/tools/selection-tool.class.d.ts +188 -0
  264. package/dist/types/classes/tools/shape-tool.class.d.ts +90 -0
  265. package/dist/types/classes/tools/text-tool.class.d.ts +66 -0
  266. package/dist/types/components/kritzel-awareness-cursors/kritzel-awareness-cursors.d.ts +29 -0
  267. package/dist/types/components/kritzel-cursor-trail/kritzel-cursor-trail.d.ts +19 -0
  268. package/dist/types/components/kritzel-engine/kritzel-engine.d.ts +695 -0
  269. package/dist/types/components/kritzel-icon/kritzel-icon.d.ts +6 -0
  270. package/dist/types/components/kritzel-watermark/kritzel-watermark.d.ts +20 -0
  271. package/dist/types/components.d.ts +981 -0
  272. package/dist/types/configs/default-asset-storage.config.d.ts +8 -0
  273. package/dist/types/configs/default-brush-tool.config.d.ts +2 -0
  274. package/dist/types/configs/default-engine-config.d.ts +2 -0
  275. package/dist/types/configs/default-line-tool.config.d.ts +2 -0
  276. package/dist/types/configs/default-shape-tool.config.d.ts +2 -0
  277. package/dist/types/configs/default-sync.config.d.ts +5 -0
  278. package/dist/types/configs/default-text-tool.config.d.ts +2 -0
  279. package/dist/types/constants/color-palette.constants.d.ts +31 -0
  280. package/dist/types/constants/core.constants.d.ts +0 -0
  281. package/dist/types/constants/engine.constants.d.ts +4 -0
  282. package/dist/types/constants/license.constants.d.ts +25 -0
  283. package/dist/types/constants/schema.constants.d.ts +4 -0
  284. package/dist/types/constants/storage.constants.d.ts +1 -0
  285. package/dist/types/constants/stroke-size.constants.d.ts +2 -0
  286. package/dist/types/constants/text-tool-fonts.constants.d.ts +3 -0
  287. package/dist/types/constants/version.d.ts +6 -0
  288. package/dist/types/enums/alignment.enum.d.ts +8 -0
  289. package/dist/types/enums/event-button.enum.d.ts +5 -0
  290. package/dist/types/enums/handle-type.enum.d.ts +6 -0
  291. package/dist/types/enums/shape-type.enum.d.ts +5 -0
  292. package/dist/types/events/active-workspace-change.event.d.ts +7 -0
  293. package/dist/types/events/editor-is-ready.event.d.ts +18 -0
  294. package/dist/types/events/login.event.d.ts +3 -0
  295. package/dist/types/helpers/alignment.helper.d.ts +21 -0
  296. package/dist/types/helpers/class.helper.d.ts +3 -0
  297. package/dist/types/helpers/color.helper.d.ts +34 -0
  298. package/dist/types/helpers/cursor.helper.d.ts +22 -0
  299. package/dist/types/helpers/devices.helper.d.ts +8 -0
  300. package/dist/types/helpers/event.helper.d.ts +6 -0
  301. package/dist/types/helpers/geometry.helper.d.ts +38 -0
  302. package/dist/types/helpers/html.helper.d.ts +8 -0
  303. package/dist/types/helpers/image-file.helper.d.ts +3 -0
  304. package/dist/types/helpers/keyboard.helper.d.ts +6 -0
  305. package/dist/types/helpers/localization.helper.d.ts +18 -0
  306. package/dist/types/helpers/math.helper.d.ts +4 -0
  307. package/dist/types/helpers/migration.helper.d.ts +30 -0
  308. package/dist/types/helpers/object.helper.d.ts +9 -0
  309. package/dist/types/helpers/svg-export.helper.d.ts +231 -0
  310. package/dist/types/helpers/theme.helper.d.ts +42 -0
  311. package/dist/types/helpers/tool-config.helper.d.ts +4 -0
  312. package/dist/types/helpers/wheel.helper.d.ts +9 -0
  313. package/dist/types/index.d.ts +109 -0
  314. package/dist/types/interfaces/anchor.interface.d.ts +147 -0
  315. package/dist/types/interfaces/arrow-head.interface.d.ts +27 -0
  316. package/dist/types/interfaces/asset-provider.interface.d.ts +88 -0
  317. package/dist/types/interfaces/asset-storage-config.interface.d.ts +40 -0
  318. package/dist/types/interfaces/asset.interface.d.ts +43 -0
  319. package/dist/types/interfaces/bounding-box.interface.d.ts +8 -0
  320. package/dist/types/interfaces/clonable.interface.d.ts +3 -0
  321. package/dist/types/interfaces/context-menu-item.interface.d.ts +25 -0
  322. package/dist/types/interfaces/context-menu-state.interface.d.ts +16 -0
  323. package/dist/types/interfaces/debug-info.interface.d.ts +7 -0
  324. package/dist/types/interfaces/dialog.interface.d.ts +4 -0
  325. package/dist/types/interfaces/document-metadata.interface.d.ts +6 -0
  326. package/dist/types/interfaces/dynamic-object-renderer.interface.d.ts +40 -0
  327. package/dist/types/interfaces/engine-state.interface.d.ts +82 -0
  328. package/dist/types/interfaces/font.interface.d.ts +15 -0
  329. package/dist/types/interfaces/localization.interface.d.ts +143 -0
  330. package/dist/types/interfaces/login-config.interface.d.ts +24 -0
  331. package/dist/types/interfaces/master-detail.interface.d.ts +14 -0
  332. package/dist/types/interfaces/menu-item.interface.d.ts +27 -0
  333. package/dist/types/interfaces/migration.interface.d.ts +16 -0
  334. package/dist/types/interfaces/notification.interface.d.ts +10 -0
  335. package/dist/types/interfaces/object-change-event.interface.d.ts +31 -0
  336. package/dist/types/interfaces/object-export.interface.d.ts +20 -0
  337. package/dist/types/interfaces/object.interface.d.ts +53 -0
  338. package/dist/types/interfaces/paste-intent-provider.interface.d.ts +10 -0
  339. package/dist/types/interfaces/point.interface.d.ts +4 -0
  340. package/dist/types/interfaces/polygon.interface.d.ts +7 -0
  341. package/dist/types/interfaces/remote-cursor.interface.d.ts +18 -0
  342. package/dist/types/interfaces/selection-state.interface.d.ts +7 -0
  343. package/dist/types/interfaces/serializable.interface.d.ts +5 -0
  344. package/dist/types/interfaces/settings.interface.d.ts +25 -0
  345. package/dist/types/interfaces/share.interface.d.ts +9 -0
  346. package/dist/types/interfaces/shortcut.interface.d.ts +10 -0
  347. package/dist/types/interfaces/sync-config.interface.d.ts +41 -0
  348. package/dist/types/interfaces/sync-provider.interface.d.ts +66 -0
  349. package/dist/types/interfaces/theme.interface.d.ts +553 -0
  350. package/dist/types/interfaces/tool-config.interface.d.ts +24 -0
  351. package/dist/types/interfaces/tool-type.interface.d.ts +1 -0
  352. package/dist/types/interfaces/tool.interface.d.ts +8 -0
  353. package/dist/types/interfaces/toolbar-item.interface.d.ts +66 -0
  354. package/dist/types/interfaces/undo-state.interface.d.ts +6 -0
  355. package/dist/types/interfaces/user.interface.d.ts +22 -0
  356. package/dist/types/interfaces/viewport-state.interface.d.ts +7 -0
  357. package/dist/types/locales/de-locale.d.ts +5 -0
  358. package/dist/types/locales/en-locale.d.ts +6 -0
  359. package/dist/types/locales/fr-locale.d.ts +5 -0
  360. package/dist/types/migrations/app-state.migrations.d.ts +11 -0
  361. package/dist/types/migrations/workspace.migrations.d.ts +11 -0
  362. package/dist/types/stencil-public-runtime.d.ts +1873 -0
  363. package/dist/types/themes/dark-theme.d.ts +5 -0
  364. package/dist/types/themes/light-theme.d.ts +5 -0
  365. package/dist/types/types/deep-readonly.type.d.ts +7 -0
  366. package/dist/types/types/state.types.d.ts +3 -0
  367. package/loader/cdn.js +1 -0
  368. package/loader/index.cjs.js +1 -0
  369. package/loader/index.d.ts +24 -0
  370. package/loader/index.es2017.js +1 -0
  371. package/loader/index.js +2 -0
  372. package/package.json +101 -0
  373. package/readme.md +11 -0
@@ -0,0 +1,628 @@
1
+ import { KritzelBaseObject } from "./base-object.class";
2
+ import { KritzelKeyboardHelper } from "../../helpers/keyboard.helper";
3
+ import { KritzelDevicesHelper } from "../../helpers/devices.helper";
4
+ import { KritzelGeometryHelper } from "../../helpers/geometry.helper";
5
+ import { ShapeType } from "../../enums/shape-type.enum";
6
+ import { EditorState, TextSelection } from "prosemirror-state";
7
+ import { EditorView } from "prosemirror-view";
8
+ import { Schema } from "prosemirror-model";
9
+ import { schema } from "prosemirror-schema-basic";
10
+ import { addListNodes } from "prosemirror-schema-list";
11
+ import { keymap } from "prosemirror-keymap";
12
+ import { baseKeymap } from "prosemirror-commands";
13
+ import { KritzelColorHelper } from "../../helpers/color.helper";
14
+ import { KritzelMathHelper } from "../../helpers/math.helper";
15
+ export class KritzelShape extends KritzelBaseObject {
16
+ __class__ = 'KritzelShape';
17
+ shapeType = ShapeType.Rectangle;
18
+ fillColor = { light: 'transparent', dark: 'transparent' };
19
+ strokeColor = { light: '#000000', dark: '#ffffff' };
20
+ strokeWidth = 4;
21
+ fontFamily = 'Arial';
22
+ fontSize = 16;
23
+ fontColor = { light: '#000000', dark: '#ffffff' };
24
+ /** Screen-space x coordinate of the shape's top-left corner (like Path.x) */
25
+ x = 0;
26
+ /** Screen-space y coordinate of the shape's top-left corner (like Path.y) */
27
+ y = 0;
28
+ scale = 1;
29
+ scaleFactor = 1;
30
+ isDebugInfoVisible = true;
31
+ isEditable = true;
32
+ isEditing = false;
33
+ editor = null;
34
+ content = null;
35
+ _schema = new Schema({
36
+ nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),
37
+ marks: schema.spec.marks,
38
+ });
39
+ uneditedObject = null;
40
+ /**
41
+ * Returns the viewBox for the shape's SVG, using screen-space coordinates.
42
+ * This follows the same pattern as KritzelPath.viewBox.
43
+ */
44
+ get viewBox() {
45
+ return `${this.x} ${this.y} ${this.width} ${this.height}`;
46
+ }
47
+ /**
48
+ * Creates a new KritzelShape instance with optional configuration.
49
+ * This constructor initializes the shape with default values that can be
50
+ * overridden by the provided configuration object.
51
+ *
52
+ * @param config - Optional configuration object for the shape
53
+ * @param config.x - Screen-space x coordinate of the shape's top-left corner
54
+ * @param config.y - Screen-space y coordinate of the shape's top-left corner
55
+ * @param config.translateX - World-space x translation offset
56
+ * @param config.translateY - World-space y translation offset
57
+ * @param config.width - Width of the shape in screen-space pixels
58
+ * @param config.height - Height of the shape in screen-space pixels
59
+ * @param config.shapeType - Type of shape (Rectangle, Ellipse, Triangle)
60
+ * @param config.fillColor - Theme-aware fill color with light and dark variants
61
+ * @param config.strokeColor - Theme-aware stroke color with light and dark variants
62
+ * @param config.strokeWidth - Width of the shape's stroke in pixels
63
+ * @param config.fontSize - Font size for text content in points
64
+ * @param config.fontFamily - Font family for text content
65
+ * @param config.fontColor - Theme-aware font color (auto-determined from fillColor if not specified)
66
+ * @param config.scale - Viewport scale factor at creation time
67
+ * @param config.scaleX - Horizontal scale factor for transformations
68
+ * @param config.scaleY - Vertical scale factor for transformations
69
+ */
70
+ constructor(config) {
71
+ super();
72
+ // Always create the editor so setContent() works immediately
73
+ this.editor = this.createEditor();
74
+ if (config) {
75
+ this.x = config.x ?? 0;
76
+ this.y = config.y ?? 0;
77
+ this.translateX = config.translateX ?? 0;
78
+ this.translateY = config.translateY ?? 0;
79
+ this.rotation = KritzelMathHelper.degreesToRadians(config.rotation ?? 0);
80
+ this.width = config.width ?? 100;
81
+ this.height = config.height ?? 100;
82
+ this.shapeType = config.shapeType ?? ShapeType.Rectangle;
83
+ this.fillColor = config.fillColor ?? { light: 'transparent', dark: 'transparent' };
84
+ this.strokeColor = config.strokeColor ?? config.fillColor ?? { light: '#000000', dark: '#ffffff' };
85
+ this.strokeWidth = config.strokeWidth ?? 4;
86
+ this.fontSize = config.fontSize ?? 16;
87
+ this.fontFamily = config.fontFamily ?? 'Arial';
88
+ this.fontColor = config.fontColor ?? KritzelColorHelper.determineTextColor(this.fillColor);
89
+ this.scale = config.scale ?? 1;
90
+ this.scaleFactor = config.scaleX ?? 1;
91
+ }
92
+ }
93
+ /**
94
+ * Creates a new KritzelShape with screen-space coordinates.
95
+ * Following the same pattern as KritzelPath.create():
96
+ * - x, y are screen-space coordinates of the shape's top-left corner
97
+ * - translateX, translateY should be set to -viewportTranslateX, -viewportTranslateY
98
+ * - width, height are in screen-space
99
+ * - scale is the viewport scale at creation time
100
+ */
101
+ static create(core, config) {
102
+ const object = new KritzelShape();
103
+ object._core = core;
104
+ object.id = object.generateId();
105
+ object.workspaceId = core.store.state.activeWorkspace.id;
106
+ object.userId = core.user?.id;
107
+ object.x = config?.x ?? 0;
108
+ object.y = config?.y ?? 0;
109
+ object.translateX = config?.translateX ?? 0;
110
+ object.translateY = config?.translateY ?? 0;
111
+ object.rotation = KritzelMathHelper.degreesToRadians(config?.rotation ?? 0);
112
+ object.width = config?.width ?? 100;
113
+ object.height = config?.height ?? 100;
114
+ object.shapeType = config?.shapeType ?? ShapeType.Rectangle;
115
+ object.fillColor = config?.fillColor ?? { light: 'transparent', dark: 'transparent' };
116
+ object.strokeColor = config?.strokeColor ?? config?.fillColor ?? { light: '#000000', dark: '#ffffff' };
117
+ object.strokeWidth = config?.strokeWidth ?? 4;
118
+ object.opacity = config?.opacity ?? 1;
119
+ object.fontSize = config?.fontSize ?? 16;
120
+ object.fontFamily = config?.fontFamily ?? 'Arial';
121
+ object.fontColor = config?.fontColor ?? KritzelColorHelper.determineTextColor(object.fillColor);
122
+ object.backgroundColor = { light: 'transparent', dark: 'transparent' };
123
+ object.scaleFactor = 1;
124
+ object.scale = config?.scale ?? core.store.state.scale;
125
+ object.zIndex = core.store.currentZIndex;
126
+ // Compute world-space translateX/Y from screen-space coordinates
127
+ // This follows the same pattern as KritzelPath.updateDimensions()
128
+ object.updateDimensions();
129
+ return object;
130
+ }
131
+ /**
132
+ * Updates the translateX/Y to world coordinates based on screen-space x, y.
133
+ * This follows the same pattern as KritzelPath.updateDimensions().
134
+ *
135
+ * The formula: translateX = (x + initialTranslateX) / scale
136
+ * where initialTranslateX was -viewportTranslateX
137
+ *
138
+ * This converts screen-space position to world coordinates.
139
+ */
140
+ updateDimensions() {
141
+ this.translateX = (this.x + this.translateX) / this.scale;
142
+ this.translateY = (this.y + this.translateY) / this.scale;
143
+ }
144
+ /**
145
+ * Mounts the shape to a DOM element for rendering.
146
+ * This method attaches the shape to the provided HTML element, enabling
147
+ * it to be displayed in the viewport. It performs visibility checks and
148
+ * prevents redundant mounting operations.
149
+ *
150
+ * @param element - The HTML div element to mount the shape to
151
+ * @returns void
152
+ */
153
+ mount(element) {
154
+ if (element === null || this.isInViewport() === false) {
155
+ return;
156
+ }
157
+ if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
158
+ return;
159
+ }
160
+ this.elementRef = element;
161
+ this.isMounted = true;
162
+ }
163
+ /**
164
+ * Mounts the ProseMirror text editor to a DOM element.
165
+ * This method attaches the rich text editor to the provided container element,
166
+ * applying font styling and ensuring proper text wrapping. It prevents
167
+ * redundant DOM operations if the editor is already mounted to the same element.
168
+ *
169
+ * @param element - The HTML div element to mount the text editor to
170
+ * @returns void
171
+ */
172
+ mountTextEditor(element) {
173
+ if (element === null) {
174
+ return;
175
+ }
176
+ element.style.fontFamily = this.fontFamily;
177
+ element.style.fontSize = `${this.fontSize}pt`;
178
+ element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor, this._core?.themeManager?.currentTheme);
179
+ element.style.whiteSpace = 'pre-wrap';
180
+ element.style.wordWrap = 'break-word';
181
+ if (this.editor.dom.parentElement === element) {
182
+ return;
183
+ }
184
+ element.innerHTML = '';
185
+ element.appendChild(this.editor.dom);
186
+ }
187
+ /**
188
+ * Creates and initializes a ProseMirror editor instance for rich text editing.
189
+ * The editor is configured with a schema that supports basic text formatting
190
+ * and list nodes. It starts in non-editable mode and handles document changes
191
+ * by updating the shape's content and syncing with the store.
192
+ *
193
+ * @returns A new ProseMirror EditorView instance configured for this shape
194
+ */
195
+ createEditor() {
196
+ const doc = this._schema.node('doc', null, [this._schema.node('paragraph')]);
197
+ return new EditorView(null, {
198
+ state: EditorState.create({
199
+ doc: doc,
200
+ plugins: [keymap(baseKeymap)],
201
+ }),
202
+ editable: () => false,
203
+ dispatchTransaction: transaction => {
204
+ const newState = this.editor.state.apply(transaction);
205
+ this.editor.updateState(newState);
206
+ if (transaction.docChanged) {
207
+ this.content = newState.doc.toJSON();
208
+ if (!transaction.getMeta('fromRemote')) {
209
+ this._core.store.objects.update(this, { temporary: true });
210
+ }
211
+ }
212
+ },
213
+ });
214
+ }
215
+ /**
216
+ * Sets the text content of the shape's editor from a serialized document.
217
+ * This method is typically used to restore content from storage or to apply
218
+ * remote changes during collaboration. The 'fromRemote' meta flag prevents
219
+ * the change from being re-broadcast to collaborators.
220
+ *
221
+ * @param content - The serialized ProseMirror document content (JSON format)
222
+ * @returns void
223
+ */
224
+ setContent(content) {
225
+ this.content = content;
226
+ if (this.editor && content) {
227
+ const newDoc = this.editor.state.schema.nodeFromJSON(content);
228
+ const tr = this.editor.state.tr.replaceWith(0, this.editor.state.doc.content.size, newDoc.content);
229
+ tr.setMeta('fromRemote', true);
230
+ this.editor.dispatch(tr);
231
+ }
232
+ }
233
+ /**
234
+ * Resizes the shape to the specified dimensions and position.
235
+ * This method updates the shape's world-space coordinates and dimensions,
236
+ * then triggers a store update to persist the changes. Minimum dimension
237
+ * constraints prevent the shape from becoming invisibly small.
238
+ *
239
+ * @param x - New world-space x coordinate for the shape's position
240
+ * @param y - New world-space y coordinate for the shape's position
241
+ * @param width - New width of the shape in pixels
242
+ * @param height - New height of the shape in pixels
243
+ * @returns void
244
+ */
245
+ resize(x, y, width, height) {
246
+ if (width <= 1 || height <= 1) {
247
+ return;
248
+ }
249
+ this.width = width;
250
+ this.height = height;
251
+ this.translateX = x;
252
+ this.translateY = y;
253
+ this._core.store.objects.update(this);
254
+ }
255
+ /**
256
+ * Focuses the text editor and optionally positions the cursor at specific coordinates.
257
+ * If coordinates are provided, the cursor is placed at the corresponding text position.
258
+ * Otherwise, the cursor is placed at the end of the document. On iOS devices,
259
+ * additional scrolling behavior is triggered to ensure visibility.
260
+ *
261
+ * @param coords - Optional screen coordinates to position the cursor
262
+ * @param coords.x - Screen x coordinate for cursor placement
263
+ * @param coords.y - Screen y coordinate for cursor placement
264
+ * @returns void
265
+ */
266
+ focus(coords) {
267
+ if (!this.editor) {
268
+ return;
269
+ }
270
+ const doc = this.editor.state.doc;
271
+ if (coords && Number.isFinite(coords.x) && Number.isFinite(coords.y)) {
272
+ const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
273
+ if (pos) {
274
+ this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
275
+ this.editor.focus();
276
+ if (KritzelDevicesHelper.isIOS()) {
277
+ this.scrollIntoViewOnIOS();
278
+ }
279
+ return;
280
+ }
281
+ }
282
+ const end = Math.max(1, doc.content.size - 1);
283
+ this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, end)));
284
+ this.editor.focus();
285
+ if (KritzelDevicesHelper.isIOS()) {
286
+ this.scrollIntoViewOnIOS();
287
+ }
288
+ }
289
+ /**
290
+ * Scrolls the editor into view on iOS devices with a slight delay.
291
+ * This workaround addresses iOS-specific behavior where the virtual keyboard
292
+ * can obscure the editor. The delay allows the keyboard to fully appear
293
+ * before scrolling.
294
+ *
295
+ * @returns void
296
+ */
297
+ scrollIntoViewOnIOS() {
298
+ setTimeout(() => {
299
+ if (this.editor && this.editor.dom) {
300
+ this.editor.dom.scrollIntoView({
301
+ behavior: 'smooth',
302
+ block: 'center',
303
+ inline: 'nearest',
304
+ });
305
+ }
306
+ }, 300);
307
+ }
308
+ /**
309
+ * Enters edit mode for the shape, enabling text editing.
310
+ * This method stores a clone of the current state for potential undo operations,
311
+ * switches to the shape tool, enables the editor, and focuses at the pointer
312
+ * location if provided. Keyboard handling is temporarily adjusted to support
313
+ * text input.
314
+ *
315
+ * @param event - Optional pointer event containing the click coordinates for cursor placement
316
+ * @returns void
317
+ */
318
+ edit(event) {
319
+ KritzelKeyboardHelper.disableInteractiveWidget();
320
+ this.uneditedObject = this.clone();
321
+ const hasPointerCoordinates = typeof event?.clientX === 'number' && typeof event?.clientY === 'number';
322
+ const focusCoordinates = hasPointerCoordinates ? { x: event.clientX, y: event.clientY } : undefined;
323
+ this._core.store.setState('activeTool', this._core.toolRegistry.getTool('shape'));
324
+ this.editor.setProps({ editable: () => true });
325
+ this.isEditing = true;
326
+ this._core.rerender();
327
+ if (focusCoordinates) {
328
+ this.focus(focusCoordinates);
329
+ }
330
+ // iOS can drop initial focus when edit mode toggles and the DOM re-renders.
331
+ // Retry focus in the next frame while still in the same interaction sequence.
332
+ if (KritzelDevicesHelper.isIOS() && focusCoordinates) {
333
+ requestAnimationFrame(() => {
334
+ if (this.isEditing) {
335
+ this.focus(focusCoordinates);
336
+ }
337
+ });
338
+ }
339
+ KritzelKeyboardHelper.enableInteractiveWidget();
340
+ }
341
+ /**
342
+ * Exits edit mode and saves the current text content.
343
+ * This method serializes the editor's document state, disables editing,
344
+ * removes focus from the editor, consolidates any temporary changes in the
345
+ * store, and emits an objects change event to notify listeners.
346
+ *
347
+ * @returns void
348
+ */
349
+ save() {
350
+ this.content = this.editor.state.doc.toJSON();
351
+ this.editor.setProps({ editable: () => false });
352
+ this.editor.dom.blur();
353
+ this.isEditing = false;
354
+ this._core.store.objects.consolidateTemporaryItems();
355
+ this._core.store.objects.update(this);
356
+ this._core.engine.emitObjectsChange();
357
+ }
358
+ /**
359
+ * Handles the Escape key while the shape's text editor is in edit mode.
360
+ * Implements a two-stage behavior: if the editor currently has a non-empty
361
+ * text selection, the selection is collapsed to a caret without exiting
362
+ * edit mode. If the selection is already collapsed, edit mode is exited
363
+ * (saving the current content), the canvas selection is cleared and the
364
+ * active tool is switched back to the selection tool so subsequent
365
+ * interactions start fresh.
366
+ */
367
+ handleEscape() {
368
+ if (!this.editor || !this.isEditing) {
369
+ return;
370
+ }
371
+ const { state } = this.editor;
372
+ if (!state.selection.empty) {
373
+ const pos = state.selection.head;
374
+ this.editor.dispatch(state.tr.setSelection(TextSelection.create(state.doc, pos)));
375
+ this.editor.focus();
376
+ return;
377
+ }
378
+ this._core.resetActiveShape();
379
+ this._core.clearSelection();
380
+ this._core.store.setState('activeTool', this._core.toolRegistry.getTool('selection'));
381
+ }
382
+ /**
383
+ * Handles pointer down events when the shape is in edit mode.
384
+ * This method stops event propagation for untracked pointers to prevent
385
+ * the canvas from capturing text selection interactions within the editor.
386
+ *
387
+ * @param event - The pointer down event from user interaction
388
+ * @returns void
389
+ */
390
+ handlePointerDown(event) {
391
+ if (!this.isEditing) {
392
+ return;
393
+ }
394
+ if (!this._core.store.state.pointers.has(event.pointerId)) {
395
+ event.stopPropagation();
396
+ }
397
+ }
398
+ /**
399
+ * Handles pointer move events when the shape is in edit mode.
400
+ * This method stops event propagation for untracked pointers to allow
401
+ * text selection drag operations within the editor without triggering
402
+ * canvas pan or other interactions.
403
+ *
404
+ * @param event - The pointer move event from user interaction
405
+ * @returns void
406
+ */
407
+ handlePointerMove(event) {
408
+ if (!this.isEditing) {
409
+ return;
410
+ }
411
+ if (!this._core.store.state.pointers.has(event.pointerId)) {
412
+ event.stopPropagation();
413
+ }
414
+ }
415
+ /**
416
+ * Handles pointer up events when the shape is in edit mode.
417
+ * This method stops event propagation for untracked pointers to complete
418
+ * text selection operations within the editor without triggering
419
+ * canvas click handlers.
420
+ *
421
+ * @param event - The pointer up event from user interaction
422
+ * @returns void
423
+ */
424
+ handlePointerUp(event) {
425
+ if (!this.isEditing) {
426
+ return;
427
+ }
428
+ if (!this._core.store.state.pointers.has(event.pointerId)) {
429
+ event.stopPropagation();
430
+ }
431
+ }
432
+ /**
433
+ * Creates a copy of this shape with a new editor instance.
434
+ * This method extends the base copy behavior by creating a fresh
435
+ * ProseMirror editor for the copied shape and restoring the text
436
+ * content from the original.
437
+ *
438
+ * @returns A new KritzelShape instance with copied properties and content
439
+ */
440
+ copy() {
441
+ const copiedObject = super.copy();
442
+ copiedObject.editor = copiedObject.createEditor();
443
+ if (this.content) {
444
+ copiedObject.setContent(this.content);
445
+ }
446
+ return copiedObject;
447
+ }
448
+ /**
449
+ * Serializes the shape to a plain JavaScript object for storage or transmission.
450
+ * This method excludes non-serializable properties like the core reference,
451
+ * DOM elements, schema, and editor instance. The remaining properties are
452
+ * deep-cloned to prevent reference issues.
453
+ *
454
+ * @returns A serializable object containing all persistent shape properties
455
+ */
456
+ serialize() {
457
+ const { _core, _elementRef, _schema, element, totalWidth, totalHeight, editor, uneditedObject, ...remainingProps } = this;
458
+ const clonedProps = structuredClone(remainingProps);
459
+ if (element && typeof element === 'object' && 'nodeType' in element && element.nodeType === 1) {
460
+ clonedProps.element = element.cloneNode(true);
461
+ }
462
+ return clonedProps;
463
+ }
464
+ /**
465
+ * Restores a shape from a serialized object representation.
466
+ * This method extends the base deserialization by additionally restoring
467
+ * the text editor content from the serialized data.
468
+ *
469
+ * @template KritzelShape - The type parameter for return type consistency
470
+ * @param object - The serialized shape data to restore from
471
+ * @returns The deserialized shape instance (this)
472
+ */
473
+ deserialize(object) {
474
+ super.deserialize(object);
475
+ if (object.content) {
476
+ this.setContent(object.content);
477
+ }
478
+ return this;
479
+ }
480
+ /**
481
+ * Lifecycle hook called after properties are updated via updateObject.
482
+ * This method automatically adjusts the text color based on fill color
483
+ * brightness to ensure readability. When the fill color changes, the font
484
+ * color is recalculated and the editor's styling is updated immediately.
485
+ *
486
+ * @param changedProperties - Array of property names that were modified
487
+ * @returns void
488
+ */
489
+ onAfterUpdate(changedProperties) {
490
+ if (changedProperties.includes('fillColor')) {
491
+ this.fontColor = KritzelColorHelper.determineTextColor(this.fillColor);
492
+ // Update the editor's text color immediately
493
+ if (this.editor?.dom?.parentElement) {
494
+ this.editor.dom.parentElement.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor, this._core?.themeManager?.currentTheme);
495
+ }
496
+ }
497
+ else if (changedProperties.includes('fontColor')) {
498
+ // Also update editor when fontColor changes directly
499
+ if (this.editor?.dom?.parentElement) {
500
+ this.editor.dom.parentElement.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor, this._core?.themeManager?.currentTheme);
501
+ }
502
+ }
503
+ }
504
+ /**
505
+ * Returns the clipping polygon for arrow intersection calculations.
506
+ * This method generates a polygon representation of the shape's outline
507
+ * for use in determining where arrows or connectors should terminate.
508
+ *
509
+ * The polygon includes padding for half the stroke width to ensure
510
+ * arrow heads don't visually overlap the shape's stroke.
511
+ *
512
+ * Shape-specific behavior:
513
+ * - Ellipse: Returns a 32-segment polygon approximation of the ellipse
514
+ * - Triangle: Returns the 3 corner points, expanded outward by stroke padding
515
+ * - Rectangle: Returns null to use the default rotatedPolygon from base class
516
+ *
517
+ * @returns An array of KritzelPoint objects defining the clipping polygon,
518
+ * or null for rectangles (which use the default implementation)
519
+ */
520
+ getClipPolygon() {
521
+ // Calculate world-space center and dimensions
522
+ const worldWidth = this.totalWidth / this.scale;
523
+ const worldHeight = this.totalHeight / this.scale;
524
+ const centerX = this.translateX + worldWidth / 2;
525
+ const centerY = this.translateY + worldHeight / 2;
526
+ // Add padding for stroke width so arrows don't overlap the stroke
527
+ const strokePadding = (this.strokeWidth / this.scale) / 2;
528
+ switch (this.shapeType) {
529
+ case ShapeType.Ellipse:
530
+ // Return a 32-segment polygon approximation of the ellipse
531
+ // Add stroke padding to radii
532
+ return KritzelGeometryHelper.getEllipsePolygonApproximation(centerX, centerY, worldWidth / 2 + strokePadding, worldHeight / 2 + strokePadding, 32, this.rotation);
533
+ case ShapeType.Triangle:
534
+ // Return the 3 corners of the triangle in world coordinates
535
+ // Triangle: top-center, bottom-right, bottom-left
536
+ // Expand each vertex outward from center by strokePadding
537
+ const expandVertex = (vx, vy) => {
538
+ const dx = vx - centerX;
539
+ const dy = vy - centerY;
540
+ const dist = Math.sqrt(dx * dx + dy * dy);
541
+ if (dist === 0)
542
+ return { x: vx, y: vy };
543
+ const scale = (dist + strokePadding) / dist;
544
+ return {
545
+ x: centerX + dx * scale,
546
+ y: centerY + dy * scale
547
+ };
548
+ };
549
+ const topX = this.translateX + worldWidth / 2;
550
+ const topY = this.translateY;
551
+ const bottomLeftX = this.translateX;
552
+ const bottomLeftY = this.translateY + worldHeight;
553
+ const bottomRightX = this.translateX + worldWidth;
554
+ const bottomRightY = this.translateY + worldHeight;
555
+ const expandedTop = expandVertex(topX, topY);
556
+ const expandedBottomRight = expandVertex(bottomRightX, bottomRightY);
557
+ const expandedBottomLeft = expandVertex(bottomLeftX, bottomLeftY);
558
+ // Apply rotation around center if rotated
559
+ if (this.rotation !== 0) {
560
+ const cos = Math.cos(this.rotation);
561
+ const sin = Math.sin(this.rotation);
562
+ const rotate = (p) => {
563
+ const dx = p.x - centerX;
564
+ const dy = p.y - centerY;
565
+ return {
566
+ x: centerX + dx * cos - dy * sin,
567
+ y: centerY + dx * sin + dy * cos
568
+ };
569
+ };
570
+ return [
571
+ rotate(expandedTop),
572
+ rotate(expandedBottomRight),
573
+ rotate(expandedBottomLeft)
574
+ ];
575
+ }
576
+ return [expandedTop, expandedBottomRight, expandedBottomLeft];
577
+ case ShapeType.Rectangle:
578
+ default:
579
+ // For rectangles, return null to use the default rotatedPolygon
580
+ return null;
581
+ }
582
+ }
583
+ /**
584
+ * Generates the SVG path string for rendering the shape.
585
+ * The path uses screen-space coordinates relative to the shape's (x, y) position.
586
+ * This method supports all shape types and returns the appropriate path commands.
587
+ *
588
+ * Path formats by shape type:
589
+ * - Rectangle: Four-point closed path (M, L, L, L, Z)
590
+ * - Ellipse: Two-arc closed path using the elliptical arc command (M, A, A)
591
+ * - Triangle: Three-point closed path with vertices at top-center, bottom-right, bottom-left
592
+ *
593
+ * @returns An SVG path data string (d attribute) for the shape
594
+ */
595
+ getSvgPath() {
596
+ const w = this.width;
597
+ const h = this.height;
598
+ switch (this.shapeType) {
599
+ case ShapeType.Rectangle:
600
+ return `M ${this.x} ${this.y} L ${this.x + w} ${this.y} L ${this.x + w} ${this.y + h} L ${this.x} ${this.y + h} Z`;
601
+ case ShapeType.Ellipse:
602
+ const cx = this.x + w / 2;
603
+ const cy = this.y + h / 2;
604
+ const rx = w / 2;
605
+ const ry = h / 2;
606
+ return `M ${cx - rx} ${cy} A ${rx} ${ry} 0 1 0 ${cx + rx} ${cy} A ${rx} ${ry} 0 1 0 ${cx - rx} ${cy}`;
607
+ case ShapeType.Triangle:
608
+ const topX = this.x + w / 2;
609
+ const topY = this.y;
610
+ const bottomLeftX = this.x;
611
+ const bottomLeftY = this.y + h;
612
+ const bottomRightX = this.x + w;
613
+ const bottomRightY = this.y + h;
614
+ return `M ${topX} ${topY} L ${bottomRightX} ${bottomRightY} L ${bottomLeftX} ${bottomLeftY} Z`;
615
+ default:
616
+ return `M ${this.x} ${this.y} L ${this.x + w} ${this.y} L ${this.x + w} ${this.y + h} L ${this.x} ${this.y + h} Z`;
617
+ }
618
+ }
619
+ getSupportedExportFormats() {
620
+ return ['svg'];
621
+ }
622
+ async exportAs(format, context) {
623
+ if (format !== 'svg') {
624
+ return null;
625
+ }
626
+ return context.getObjectAsSvgDataUrl(this);
627
+ }
628
+ }