kritzel-stencil 0.0.118 → 0.0.120

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 (167) hide show
  1. package/dist/cjs/{index-CXT94beA.js → index-BcrLbdO1.js} +50 -10
  2. package/dist/cjs/index-BcrLbdO1.js.map +1 -0
  3. package/dist/cjs/index-BjLSiQIM.js +2342 -0
  4. package/dist/cjs/index-BjLSiQIM.js.map +1 -0
  5. package/dist/cjs/index.cjs.js +8 -1
  6. package/dist/cjs/index.cjs.js.map +1 -1
  7. package/dist/cjs/kritzel-brush-style_18.cjs.entry.js +362 -1743
  8. package/dist/cjs/kritzel-brush-style_18.cjs.entry.js.map +1 -1
  9. package/dist/cjs/loader.cjs.js +2 -2
  10. package/dist/cjs/stencil.cjs.js +3 -3
  11. package/dist/cjs/stencil.cjs.js.map +1 -1
  12. package/dist/collection/classes/commands/add-selection-group.command.js +2 -0
  13. package/dist/collection/classes/commands/add-selection-group.command.js.map +1 -1
  14. package/dist/collection/classes/objects/base-object.class.js +4 -0
  15. package/dist/collection/classes/objects/base-object.class.js.map +1 -1
  16. package/dist/collection/classes/objects/image.class.js +23 -2
  17. package/dist/collection/classes/objects/image.class.js.map +1 -1
  18. package/dist/collection/classes/objects/path.class.js +15 -5
  19. package/dist/collection/classes/objects/path.class.js.map +1 -1
  20. package/dist/collection/classes/objects/text.class.js +2 -1
  21. package/dist/collection/classes/objects/text.class.js.map +1 -1
  22. package/dist/collection/classes/store.class.js +2 -13
  23. package/dist/collection/classes/store.class.js.map +1 -1
  24. package/dist/collection/classes/tools/image-tool.class.js +6 -23
  25. package/dist/collection/classes/tools/image-tool.class.js.map +1 -1
  26. package/dist/collection/classes/tools/selection-tool.class.js +4 -13
  27. package/dist/collection/classes/tools/selection-tool.class.js.map +1 -1
  28. package/dist/collection/classes/viewport.class.js.map +1 -1
  29. package/dist/collection/collection-manifest.json +1 -1
  30. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +217 -13
  31. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
  32. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +158 -68
  33. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
  34. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +104 -4
  35. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js.map +1 -1
  36. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +30 -9
  37. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js.map +1 -1
  38. package/dist/collection/configs/default-brush-tool.config.js +60 -0
  39. package/dist/collection/configs/default-brush-tool.config.js.map +1 -0
  40. package/dist/collection/configs/default-engine-state.js +6 -2
  41. package/dist/collection/configs/default-engine-state.js.map +1 -1
  42. package/dist/collection/configs/default-text-tool.config.js +32 -0
  43. package/dist/collection/configs/default-text-tool.config.js.map +1 -0
  44. package/dist/collection/constants/engine.constants.js +3 -0
  45. package/dist/collection/constants/engine.constants.js.map +1 -0
  46. package/dist/collection/index.js +8 -0
  47. package/dist/collection/index.js.map +1 -1
  48. package/dist/collection/interfaces/context-menu-item.interface.js.map +1 -1
  49. package/dist/collection/interfaces/engine-state.interface.js.map +1 -1
  50. package/dist/collection/interfaces/object.interface.js.map +1 -1
  51. package/dist/components/index.js +4 -4
  52. package/dist/components/kritzel-brush-style.js +1 -1
  53. package/dist/components/kritzel-color-palette.js +1 -1
  54. package/dist/components/kritzel-color.js +1 -1
  55. package/dist/components/kritzel-context-menu.js +1 -1
  56. package/dist/components/kritzel-control-brush-config.js +1 -1
  57. package/dist/components/kritzel-control-text-config.js +1 -1
  58. package/dist/components/kritzel-controls.js +1 -1
  59. package/dist/components/kritzel-cursor-trail.js +1 -1
  60. package/dist/components/kritzel-dropdown.js +1 -1
  61. package/dist/components/kritzel-editor.js +110 -68
  62. package/dist/components/kritzel-editor.js.map +1 -1
  63. package/dist/components/kritzel-engine.js +1 -1
  64. package/dist/components/kritzel-font-family.js +1 -1
  65. package/dist/components/kritzel-font-size.js +1 -1
  66. package/dist/components/kritzel-font.js +1 -1
  67. package/dist/components/kritzel-icon.js +1 -1
  68. package/dist/components/kritzel-stroke-size.js +1 -1
  69. package/dist/components/kritzel-tooltip.js +1 -1
  70. package/dist/components/kritzel-utility-panel.js +1 -1
  71. package/dist/components/{p-CtNzxQ7T.js → p--2FkikYE.js} +4 -4
  72. package/dist/components/{p-CtNzxQ7T.js.map → p--2FkikYE.js.map} +1 -1
  73. package/dist/components/{p-LIijWPsT.js → p--tElassI.js} +4 -4
  74. package/dist/components/{p-LIijWPsT.js.map → p--tElassI.js.map} +1 -1
  75. package/dist/components/{p-C6kzcN4b.js → p-B2wWYPH8.js} +4 -4
  76. package/dist/components/{p-C6kzcN4b.js.map → p-B2wWYPH8.js.map} +1 -1
  77. package/dist/components/{p-93b-eQ0s.js → p-BAMl2Ww6.js} +29 -27
  78. package/dist/components/p-BAMl2Ww6.js.map +1 -0
  79. package/dist/components/{p-B8nuvSxt.js → p-BSS4UREq.js} +10 -10
  80. package/dist/components/{p-B8nuvSxt.js.map → p-BSS4UREq.js.map} +1 -1
  81. package/dist/components/{p-JQA2FRVr.js → p-C3E9PtD3.js} +11 -11
  82. package/dist/components/{p-JQA2FRVr.js.map → p-C3E9PtD3.js.map} +1 -1
  83. package/dist/components/{p-B57pFHwJ.js → p-CDpq9L_H.js} +4 -4
  84. package/dist/components/{p-B57pFHwJ.js.map → p-CDpq9L_H.js.map} +1 -1
  85. package/dist/components/p-CEYRFk55.js +119 -0
  86. package/dist/components/p-CEYRFk55.js.map +1 -0
  87. package/dist/components/{p-BV9-NuyD.js → p-CIb4IA9u.js} +6 -6
  88. package/dist/components/{p-BV9-NuyD.js.map → p-CIb4IA9u.js.map} +1 -1
  89. package/dist/components/{p-eBBOf568.js → p-CqPrOhzi.js} +5 -5
  90. package/dist/components/{p-eBBOf568.js.map → p-CqPrOhzi.js.map} +1 -1
  91. package/dist/components/{p-CaQ7Iei7.js → p-CxmkJbeV.js} +4 -4
  92. package/dist/components/{p-CaQ7Iei7.js.map → p-CxmkJbeV.js.map} +1 -1
  93. package/dist/components/{p-yBnfPxIa.js → p-D-Rf05Ov.js} +5 -5
  94. package/dist/components/{p-yBnfPxIa.js.map → p-D-Rf05Ov.js.map} +1 -1
  95. package/dist/components/{p-CSSrNLad.js → p-D0L3GqSK.js} +4 -4
  96. package/dist/components/{p-CSSrNLad.js.map → p-D0L3GqSK.js.map} +1 -1
  97. package/dist/components/{p-fmNiA3Yr.js → p-D1oFXBAp.js} +5 -5
  98. package/dist/components/{p-fmNiA3Yr.js.map → p-D1oFXBAp.js.map} +1 -1
  99. package/dist/components/{p-DRuQsvUx.js → p-DC3j4P1n.js} +23 -8
  100. package/dist/components/p-DC3j4P1n.js.map +1 -0
  101. package/dist/components/{p-D04aTZsR.js → p-DbPbyRLO.js} +5 -5
  102. package/dist/components/{p-D04aTZsR.js.map → p-DbPbyRLO.js.map} +1 -1
  103. package/dist/components/{p-DoQOtXjT.js → p-dCaxwGmu.js} +44 -9
  104. package/dist/components/p-dCaxwGmu.js.map +1 -0
  105. package/dist/components/{p-DuWb7MaD.js → p-eS30Bqrc.js} +136 -125
  106. package/dist/components/p-eS30Bqrc.js.map +1 -0
  107. package/dist/components/{p-BBIuV3j1.js → p-gDLg_PJJ.js} +5 -5
  108. package/dist/components/{p-BBIuV3j1.js.map → p-gDLg_PJJ.js.map} +1 -1
  109. package/dist/esm/{index-CGHvfMWF.js → index-BPFXWTBp.js} +50 -10
  110. package/dist/esm/index-BPFXWTBp.js.map +1 -0
  111. package/dist/esm/index-DsUDklEm.js +2318 -0
  112. package/dist/esm/index-DsUDklEm.js.map +1 -0
  113. package/dist/esm/index.js +1 -1
  114. package/dist/esm/kritzel-brush-style_18.entry.js +332 -1713
  115. package/dist/esm/kritzel-brush-style_18.entry.js.map +1 -1
  116. package/dist/esm/loader.js +3 -3
  117. package/dist/esm/stencil.js +4 -4
  118. package/dist/esm/stencil.js.map +1 -1
  119. package/dist/stencil/index.esm.js +1 -1
  120. package/dist/stencil/p-0ae72b0d.entry.js +2 -0
  121. package/dist/stencil/p-0ae72b0d.entry.js.map +1 -0
  122. package/dist/stencil/p-BPFXWTBp.js +3 -0
  123. package/dist/stencil/p-BPFXWTBp.js.map +1 -0
  124. package/dist/stencil/p-DsUDklEm.js +2 -0
  125. package/dist/stencil/p-DsUDklEm.js.map +1 -0
  126. package/dist/stencil/stencil.esm.js +1 -1
  127. package/dist/stencil/stencil.esm.js.map +1 -1
  128. package/dist/types/classes/objects/base-object.class.d.ts +3 -1
  129. package/dist/types/classes/objects/image.class.d.ts +8 -0
  130. package/dist/types/classes/objects/path.class.d.ts +9 -0
  131. package/dist/types/classes/objects/text.class.d.ts +2 -1
  132. package/dist/types/classes/store.class.d.ts +1 -1
  133. package/dist/types/classes/tools/image-tool.class.d.ts +0 -4
  134. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +9 -3
  135. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +12 -4
  136. package/dist/types/components/ui/kritzel-context-menu/kritzel-context-menu.d.ts +8 -0
  137. package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +2 -1
  138. package/dist/types/components.d.ts +77 -22
  139. package/dist/types/configs/default-brush-tool.config.d.ts +2 -0
  140. package/dist/types/configs/default-text-tool.config.d.ts +2 -0
  141. package/dist/types/constants/engine.constants.d.ts +2 -0
  142. package/dist/types/index.d.ts +8 -0
  143. package/dist/types/interfaces/context-menu-item.interface.d.ts +13 -2
  144. package/dist/types/interfaces/engine-state.interface.d.ts +5 -1
  145. package/dist/types/interfaces/object.interface.d.ts +2 -0
  146. package/package.json +1 -1
  147. package/dist/cjs/index-CXT94beA.js.map +0 -1
  148. package/dist/cjs/index-aaWestcD.js +0 -827
  149. package/dist/cjs/index-aaWestcD.js.map +0 -1
  150. package/dist/collection/configs/default-toolbar-controls.js +0 -139
  151. package/dist/collection/configs/default-toolbar-controls.js.map +0 -1
  152. package/dist/components/p-93b-eQ0s.js.map +0 -1
  153. package/dist/components/p-CYnE3twZ.js +0 -49
  154. package/dist/components/p-CYnE3twZ.js.map +0 -1
  155. package/dist/components/p-DRuQsvUx.js.map +0 -1
  156. package/dist/components/p-DoQOtXjT.js.map +0 -1
  157. package/dist/components/p-DuWb7MaD.js.map +0 -1
  158. package/dist/esm/index-CGHvfMWF.js.map +0 -1
  159. package/dist/esm/index-Dn7aP72S.js +0 -814
  160. package/dist/esm/index-Dn7aP72S.js.map +0 -1
  161. package/dist/stencil/p-6c35ba88.entry.js +0 -2
  162. package/dist/stencil/p-6c35ba88.entry.js.map +0 -1
  163. package/dist/stencil/p-CGHvfMWF.js +0 -3
  164. package/dist/stencil/p-CGHvfMWF.js.map +0 -1
  165. package/dist/stencil/p-Dn7aP72S.js +0 -2
  166. package/dist/stencil/p-Dn7aP72S.js.map +0 -1
  167. package/dist/types/configs/default-toolbar-controls.d.ts +0 -4
@@ -1,5 +1,5 @@
1
- import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-CGHvfMWF.js';
2
- import { K as KritzelBaseTool, a as KritzelEventHelper, b as KritzelPath, A as AddObjectCommand, c as KritzelTextTool, d as KritzelMouseButton, e as KritzelBaseCommand, f as KritzelBaseObject, g as KritzelImage, h as KritzelText, O as ObjectHelper, i as KritzelToolRegistry, j as KritzelKeyboardHelper } from './index-Dn7aP72S.js';
1
+ import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-BPFXWTBp.js';
2
+ import { K as KritzelBrushTool, a as KritzelTextTool, b as KritzelMouseButton, c as KritzelSelectionTool, D as DEFAULT_BRUSH_CONFIG, d as KritzelEraserTool, e as DEFAULT_TEXT_CONFIG, f as KritzelImageTool, g as KritzelEventHelper, h as KritzelBaseCommand, i as KritzelSelectionGroup, j as KrtizelSelectionBox, R as RemoveSelectionGroupCommand, k as RemoveObjectCommand, B as BatchCommand, A as AddObjectCommand, l as AddSelectionGroupCommand, m as KritzelToolRegistry, n as KritzelBaseHandler, o as KritzelBaseTool, p as KritzelKeyboardHelper } from './index-DsUDklEm.js';
3
3
 
4
4
  const kritzelBrushStyleCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box;width:100%}.brush-style-button{display:flex;justify-content:center;align-items:center;width:42px;height:32px;padding:0;border:none;outline:none;background:none;cursor:default;border-radius:0;color:var(--control-text-color);font-weight:bold;-webkit-tap-highlight-color:transparent}.font-style-button:not(:last-child){border-right:1px solid #333333}.font-style-button:hover{background-color:var(--control-hover-bg)}.font-style-button:active{background-color:var(--control-active-bg)}.font-style-button.selected,.font-style-button.selected:hover,.font-style-button.selected:active{background-color:var(--control-selected-bg);color:var(--control-selected-color)}";
5
5
 
@@ -126,17 +126,82 @@ const KritzelContextMenu = class {
126
126
  constructor(hostRef) {
127
127
  registerInstance(this, hostRef);
128
128
  this.actionSelected = createEvent(this, "actionSelected");
129
+ this.disabledStates = new Map();
130
+ this.visibleItems = [];
129
131
  }
130
- handleItemClick(item) {
131
- const isDisabled = typeof item.disabled === 'function' ? item.disabled() : item.disabled;
132
- if (!isDisabled) {
132
+ componentWillLoad() {
133
+ this.resolveVisibleItems();
134
+ this.resolveDisabledStates();
135
+ }
136
+ onItemsChanged() {
137
+ this.resolveVisibleItems();
138
+ this.resolveDisabledStates();
139
+ }
140
+ handleItemClick(item, index) {
141
+ if (!this.disabledStates.get(index)) {
133
142
  this.actionSelected.emit(item);
134
143
  }
135
144
  }
145
+ async resolveVisibleItems() {
146
+ const visibleItems = [];
147
+ const visibilityPromises = this.items.map(async (item, index) => {
148
+ let isVisible = true;
149
+ if (item.visible !== undefined) {
150
+ if (typeof item.visible === 'boolean') {
151
+ isVisible = item.visible;
152
+ }
153
+ else if (typeof item.visible === 'function') {
154
+ const result = item.visible(null, this.objects);
155
+ if (result instanceof Promise) {
156
+ isVisible = await result;
157
+ }
158
+ else {
159
+ isVisible = result;
160
+ }
161
+ }
162
+ }
163
+ return { item, index, isVisible };
164
+ });
165
+ const visibilityResults = await Promise.all(visibilityPromises);
166
+ visibilityResults.forEach(({ item, isVisible }) => {
167
+ if (isVisible) {
168
+ visibleItems.push(item);
169
+ }
170
+ });
171
+ this.visibleItems = visibleItems;
172
+ }
173
+ async resolveDisabledStates() {
174
+ const newStates = new Map();
175
+ const disabledPromises = this.visibleItems.map(async (item, index) => {
176
+ let isDisabled = false;
177
+ if (typeof item.disabled === 'boolean') {
178
+ isDisabled = item.disabled;
179
+ }
180
+ else if (typeof item.disabled === 'function') {
181
+ const result = item.disabled(null, this.objects);
182
+ if (result instanceof Promise) {
183
+ isDisabled = await result;
184
+ }
185
+ else {
186
+ isDisabled = result;
187
+ }
188
+ }
189
+ newStates.set(index, isDisabled);
190
+ });
191
+ await Promise.all(disabledPromises);
192
+ this.disabledStates = new Map(newStates);
193
+ }
136
194
  render() {
137
- return (h(Host, { key: '92cf80d71faae3e33bc29d9e9b3a81b4b6ee6c87' }, h("div", { key: '838734ed3f1e3af86a5db7312c2206e90835a8f0', class: "menu-container" }, this.items.map(item => (h("button", { key: `${item.label}-${this.items.indexOf(item)}`, class: { 'menu-item': true, 'disabled': typeof item.disabled === 'function' ? item.disabled() : item.disabled }, onClick: () => this.handleItemClick(item), onTouchStart: () => this.handleItemClick(item), disabled: typeof item.disabled === 'function' ? item.disabled() : item.disabled }, item.icon && h("kritzel-icon", { name: item.icon, size: 16 }), h("span", { class: "label" }, item.label)))))));
195
+ return (h(Host, { key: '3265d2e63ff1e1f91faf1c6c5da3490687f3adb1' }, h("div", { key: '80b2100e2ffcaba25ca08cfec650b1f7558c5d25', class: "menu-container" }, this.visibleItems.map((item, index) => {
196
+ var _a;
197
+ const isDisabled = (_a = this.disabledStates.get(index)) !== null && _a !== void 0 ? _a : false;
198
+ return (h("button", { key: `${item.label}-${index}`, class: { 'menu-item': true, 'disabled': isDisabled }, onClick: () => this.handleItemClick(item, index), onTouchStart: () => this.handleItemClick(item, index), disabled: isDisabled }, item.icon && h("kritzel-icon", { name: item.icon, size: 16 }), h("span", { class: "label" }, item.label)));
199
+ }))));
138
200
  }
139
201
  get hostElement() { return getElement(this); }
202
+ static get watchers() { return {
203
+ "items": ["onItemsChanged"]
204
+ }; }
140
205
  };
141
206
  KritzelContextMenu.style = kritzelContextMenuCss;
142
207
 
@@ -224,118 +289,6 @@ const KritzelControlTextConfig = class {
224
289
  };
225
290
  KritzelControlTextConfig.style = kritzelControlTextConfigCss;
226
291
 
227
- class KritzelBrushTool extends KritzelBaseTool {
228
- constructor(store) {
229
- super(store);
230
- this.type = 'pen';
231
- this.color = '#000000';
232
- this.size = 6;
233
- this.palettes = {
234
- pen: ['#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF', '#808080', '#C0C0C0', '#800000', '#008000', '#000080', '#808000', '#800080'],
235
- highlighter: ['#ffff00', '#ffb347', '#b4ffb4'],
236
- };
237
- }
238
- handlePointerDown(event) {
239
- if (event.cancelable) {
240
- event.preventDefault();
241
- }
242
- if (event.pointerType === 'mouse') {
243
- if (KritzelEventHelper.isLeftClick(event)) {
244
- this._store.state.isDrawing = true;
245
- const x = event.clientX - this._store.offsetX;
246
- const y = event.clientY - this._store.offsetY;
247
- this._store.state.currentPath = KritzelPath.create(this._store, {
248
- points: [[x, y]],
249
- translateX: -this._store.state.translateX,
250
- translateY: -this._store.state.translateY,
251
- scale: this._store.state.scale,
252
- fill: this.color,
253
- strokeWidth: this.size,
254
- });
255
- }
256
- }
257
- if (event.pointerType === 'touch') {
258
- const activePointers = Array.from(this._store.state.pointers.values());
259
- if (activePointers.length === 1) {
260
- const x = Math.round(activePointers[0].clientX - this._store.offsetX);
261
- const y = Math.round(activePointers[0].clientY - this._store.offsetY);
262
- this._store.state.isDrawing = true;
263
- this._store.state.currentPath = KritzelPath.create(this._store, {
264
- points: [[x, y]],
265
- translateX: -this._store.state.translateX,
266
- translateY: -this._store.state.translateY,
267
- scale: this._store.state.scale,
268
- fill: this.color,
269
- strokeWidth: this.size,
270
- });
271
- this._store.rerender();
272
- }
273
- }
274
- }
275
- handlePointerMove(event) {
276
- if (event.cancelable) {
277
- event.preventDefault();
278
- }
279
- if (event.pointerType === 'mouse') {
280
- if (this._store.state.isDrawing) {
281
- const x = event.clientX - this._store.offsetX;
282
- const y = event.clientY - this._store.offsetY;
283
- this._store.state.currentPath = KritzelPath.create(this._store, {
284
- points: [...this._store.state.currentPath.points, [x, y]],
285
- translateX: -this._store.state.translateX,
286
- translateY: -this._store.state.translateY,
287
- scale: this._store.state.scale,
288
- fill: this.color,
289
- strokeWidth: this.size,
290
- });
291
- this._store.rerender();
292
- }
293
- }
294
- if (event.pointerType === 'touch') {
295
- const activePointers = Array.from(this._store.state.pointers.values());
296
- if (activePointers.length === 1) {
297
- const x = Math.round(activePointers[0].clientX - this._store.offsetX);
298
- const y = Math.round(activePointers[0].clientY - this._store.offsetY);
299
- this._store.state.currentPath = KritzelPath.create(this._store, {
300
- points: [...this._store.state.currentPath.points, [x, y]],
301
- translateX: -this._store.state.translateX,
302
- translateY: -this._store.state.translateY,
303
- scale: this._store.state.scale,
304
- fill: this.color,
305
- strokeWidth: this.size,
306
- });
307
- this._store.rerender();
308
- }
309
- }
310
- }
311
- handlePointerUp(event) {
312
- if (event.cancelable) {
313
- event.preventDefault();
314
- }
315
- if (event.pointerType === 'mouse') {
316
- if (this._store.state.isDrawing) {
317
- this._store.state.isDrawing = false;
318
- if (this._store.state.currentPath) {
319
- this._store.state.currentPath.zIndex = this._store.currentZIndex;
320
- this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
321
- }
322
- this._store.state.currentPath = undefined;
323
- }
324
- }
325
- if (event.pointerType === 'touch') {
326
- if (this._store.state.isDrawing) {
327
- this._store.state.isDrawing = false;
328
- if (this._store.state.currentPath) {
329
- this._store.state.currentPath.zIndex = this._store.currentZIndex;
330
- this._store.history.executeCommand(new AddObjectCommand(this._store, this, this._store.state.currentPath));
331
- }
332
- this._store.state.currentPath = undefined;
333
- this._store.rerender();
334
- }
335
- }
336
- }
337
- }
338
-
339
292
  class KritzelDevicesHelper {
340
293
  static isTouchDevice() {
341
294
  return window.matchMedia('(any-pointer: coarse)').matches;
@@ -350,8 +303,9 @@ const KritzelControls = class {
350
303
  this.isControlsReady = createEvent(this, "isControlsReady");
351
304
  this.controls = [];
352
305
  this.activeControl = null;
306
+ this.isUtilityPanelVisible = true;
353
307
  this.firstConfig = null;
354
- this.tooltipVisible = false;
308
+ this.isTooltipVisible = false;
355
309
  this.isTouchDevice = KritzelDevicesHelper.isTouchDevice();
356
310
  this.kritzelEngine = null;
357
311
  }
@@ -365,12 +319,12 @@ const KritzelControls = class {
365
319
  if (!this.kritzelEngine || element.closest('.kritzel-tooltip')) {
366
320
  return;
367
321
  }
368
- this.tooltipVisible = false;
322
+ this.isTooltipVisible = false;
369
323
  this.kritzelEngine.enable();
370
324
  }
371
325
  async closeTooltip() {
372
326
  var _a;
373
- this.tooltipVisible = false;
327
+ this.isTooltipVisible = false;
374
328
  (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.enable();
375
329
  }
376
330
  get activeToolAsTextTool() {
@@ -420,7 +374,7 @@ const KritzelControls = class {
420
374
  }
421
375
  handleConfigClick(event) {
422
376
  event.stopPropagation();
423
- this.tooltipVisible = !this.tooltipVisible;
377
+ this.isTooltipVisible = !this.isTooltipVisible;
424
378
  this.kritzelEngine.disable();
425
379
  }
426
380
  async handleToolChange(event) {
@@ -430,13 +384,13 @@ const KritzelControls = class {
430
384
  render() {
431
385
  var _a, _b;
432
386
  const hasNoConfig = ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.config) === undefined || ((_b = this.activeControl) === null || _b === void 0 ? void 0 : _b.config) === null;
433
- return (h(Host, { key: 'fecdf68cef50c38670d8117cd4da92b572c940a5', class: {
387
+ return (h(Host, { key: '5531510d4b95c082148ce3e8f5d3048f808162b2', class: {
434
388
  mobile: this.isTouchDevice,
435
- } }, h("kritzel-utility-panel", { key: '82c6af0d540137a2c24aac659f41e24b783b6555', style: {
389
+ } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: 'e7e58ee4ae6a8a77918d5c8a954c2dcae287b265', style: {
436
390
  position: 'absolute',
437
391
  bottom: '56px',
438
392
  left: '12px',
439
- }, onUndo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.undo(); }, onRedo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.redo(); }, onDelete: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.delete(); } }), h("div", { key: 'a59d0611b6cd88779b7b72970a0fda50c7808686', class: "kritzel-controls" }, this.controls.map(control => {
393
+ }, onUndo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.undo(); }, onRedo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.redo(); }, onDelete: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.delete(); } })), h("div", { key: '65ad87089a38f3e89f8332fc6f261555c2e7eb40', class: "kritzel-controls" }, this.controls.map(control => {
440
394
  var _a, _b, _c, _d, _e, _f, _g, _h;
441
395
  if (control.type === 'tool') {
442
396
  return (h("button", { class: {
@@ -448,7 +402,7 @@ const KritzelControls = class {
448
402
  return h("div", { class: "kritzel-divider", key: control.name });
449
403
  }
450
404
  if (control.type === 'config' && control.name === ((_b = this.firstConfig) === null || _b === void 0 ? void 0 : _b.name) && this.activeControl) {
451
- return (h("div", { class: "kritzel-config-container", key: control.name }, h("kritzel-tooltip", { isVisible: this.tooltipVisible, anchorElement: (_c = this.host.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.kritzel-config-container') }, h("div", { style: { width: '294px', height: '100%' } }, this.activeControl.name === 'brush' && (h("kritzel-control-brush-config", { tool: this.activeToolAsBrushTool, onToolChange: event => { var _a; return (_a = this.handleToolChange) === null || _a === void 0 ? void 0 : _a.call(this, event); } })), this.activeControl.name === 'text' && (h("kritzel-control-text-config", { tool: this.activeToolAsTextTool, onToolChange: event => { var _a; return (_a = this.handleToolChange) === null || _a === void 0 ? void 0 : _a.call(this, event); } })))), h("div", { class: "kritzel-config", onClick: event => { var _a; return (_a = this.handleConfigClick) === null || _a === void 0 ? void 0 : _a.call(this, event); }, style: {
405
+ return (h("div", { class: "kritzel-config-container", key: control.name }, h("kritzel-tooltip", { isVisible: this.isTooltipVisible, anchorElement: (_c = this.host.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.kritzel-config-container') }, h("div", { style: { width: '294px', height: '100%' } }, this.activeControl.name === 'brush' && (h("kritzel-control-brush-config", { tool: this.activeToolAsBrushTool, onToolChange: event => { var _a; return (_a = this.handleToolChange) === null || _a === void 0 ? void 0 : _a.call(this, event); } })), this.activeControl.name === 'text' && (h("kritzel-control-text-config", { tool: this.activeToolAsTextTool, onToolChange: event => { var _a; return (_a = this.handleToolChange) === null || _a === void 0 ? void 0 : _a.call(this, event); } })))), h("div", { class: "kritzel-config", onClick: event => { var _a; return (_a = this.handleConfigClick) === null || _a === void 0 ? void 0 : _a.call(this, event); }, style: {
452
406
  cursor: this.activeControl.config ? 'pointer' : 'default',
453
407
  pointerEvents: hasNoConfig ? 'none' : 'auto',
454
408
  } }, this.activeControl.tool instanceof KritzelBrushTool && (h("div", { class: "color-container" }, h("kritzel-color", { value: (_d = this.activeToolAsBrushTool) === null || _d === void 0 ? void 0 : _d.color, size: (_e = this.activeToolAsBrushTool) === null || _e === void 0 ? void 0 : _e.size, style: {
@@ -574,1538 +528,119 @@ const KritzelDropdown = class {
574
528
  const newHasContent = this.suffixSlotElement.assignedNodes({ flatten: true }).length > 0;
575
529
  if (this.hasSuffixContent !== newHasContent) {
576
530
  this.hasSuffixContent = newHasContent;
577
- }
578
- }
579
- else {
580
- if (this.hasSuffixContent !== false) {
581
- this.hasSuffixContent = false;
582
- }
583
- }
584
- };
585
- this.evaluatePrefixContent = () => {
586
- if (this.prefixSlotElement) {
587
- const newHasContent = this.prefixSlotElement.assignedNodes({ flatten: true }).length > 0;
588
- if (this.hasPrefixContent !== newHasContent) {
589
- this.hasPrefixContent = newHasContent;
590
- }
591
- }
592
- else {
593
- if (this.hasPrefixContent !== false) {
594
- this.hasPrefixContent = false;
595
- }
596
- }
597
- };
598
- }
599
- componentWillLoad() {
600
- this.updateInternalValue(this.value, false);
601
- this.evaluateSuffixContent();
602
- this.evaluatePrefixContent();
603
- }
604
- externalValueChanged(newValue) {
605
- if (newValue !== this.internalValue) {
606
- this.updateInternalValue(newValue, false);
607
- }
608
- }
609
- optionsChanged() {
610
- this.updateInternalValue(this.internalValue, true);
611
- }
612
- updateInternalValue(proposedValue, emitChange) {
613
- let finalValue = proposedValue;
614
- if (this.options && this.options.length > 0) {
615
- const isValidValue = this.options.some(opt => opt.value === finalValue);
616
- if (!finalValue || !isValidValue) {
617
- finalValue = this.options[0].value;
618
- }
619
- }
620
- else {
621
- finalValue = undefined;
622
- }
623
- if (this.internalValue !== finalValue) {
624
- this.internalValue = finalValue;
625
- if (emitChange || (proposedValue !== finalValue && proposedValue !== undefined)) {
626
- this.valueChanged.emit(this.internalValue);
627
- }
628
- }
629
- }
630
- render() {
631
- const selectClasses = {
632
- 'custom-select': true,
633
- 'has-suffix-border': this.hasSuffixContent,
634
- 'has-prefix-border': this.hasPrefixContent,
635
- };
636
- return (h(Host, { key: '32c5f5a4f807c1e316c91b795c005b8d30ce6189' }, h("div", { key: 'b1cbeff18e688da4a2f7472be290b9527a619f07', class: "dropdown-wrapper" }, h("slot", { key: 'b3bbb7e21c6f5620cab41aa4b1c7206b6c75fd86', name: "prefix", ref: el => this.prefixSlotElement = el, onSlotchange: this.evaluatePrefixContent }), h("select", { key: '8b2dcdc125bee59cf29fce7c980b755e78d5816e', class: selectClasses, style: Object.assign(Object.assign({}, this.selectStyles), { width: this.width }), onInput: this.handleSelectChange }, this.options.map(option => (h("option", { value: option.value, style: option.style, selected: option.value === this.internalValue }, option.label)))), h("slot", { key: '8d83f0dea41ac959bf2392948efef33bb70d0154', name: "suffix", ref: el => this.suffixSlotElement = el, onSlotchange: this.evaluateSuffixContent }))));
637
- }
638
- static get watchers() { return {
639
- "value": ["externalValueChanged"],
640
- "options": ["optionsChanged"]
641
- }; }
642
- };
643
- KritzelDropdown.style = kritzelDropdownCss;
644
-
645
- class KritzelIconRegistry {
646
- static register(name, svgContent) {
647
- if (this.registry.has(name)) {
648
- console.warn(`[IconRegistry] Icon "${name}" is already registered. It will be overwritten.`);
649
- }
650
- this.registry.set(name, svgContent);
651
- }
652
- static get(name) {
653
- return this.registry.get(name);
654
- }
655
- static registerIcons(icons) {
656
- for (const name in icons) {
657
- if (Object.prototype.hasOwnProperty.call(icons, name)) {
658
- this.register(name, icons[name]);
659
- }
660
- }
661
- }
662
- static has(name) {
663
- return this.registry.has(name);
664
- }
665
- }
666
- KritzelIconRegistry.registry = new Map();
667
- KritzelIconRegistry.registerIcons({
668
- 'cursor': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z"/></svg>',
669
- 'pen': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/></svg>',
670
- 'highlighter': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-highlighter-icon lucide-highlighter"><path d="m9 11-6 6v3h9l3-3"/><path d="m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4"/></svg>',
671
- 'eraser': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21"/><path d="M22 21H7"/><path d="m5 11 9 9"/></svg>',
672
- 'type': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9" x2="15" y1="20" y2="20"/><line x1="12" x2="12" y1="4" y2="20"/></svg>',
673
- 'image': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>',
674
- 'chevron-down': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',
675
- 'chevron-up': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m18 15-6-6-6 6"/></svg>',
676
- 'copy': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy-icon lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>',
677
- 'paste': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clipboard-paste-icon lucide-clipboard-paste"><path d="M11 14h10"/><path d="M16 4h2a2 2 0 0 1 2 2v1.344"/><path d="m17 18 4-4-4-4"/><path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113"/><rect x="8" y="2" width="8" height="4" rx="1"/></svg>',
678
- 'cut': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scissors-icon lucide-scissors"><circle cx="6" cy="6" r="3"/><path d="M8.12 8.12 12 12"/><path d="M20 4 8.12 15.88"/><circle cx="6" cy="18" r="3"/><path d="M14.8 14.8 20 20"/></svg>',
679
- 'delete': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash2-icon lucide-trash-2"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>',
680
- 'bring-to-front': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-up-to-line-icon lucide-arrow-up-to-line"><path d="M5 3h14"/><path d="m18 13-6-6-6 6"/><path d="M12 7v14"/></svg>',
681
- 'send-to-back': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-down-to-line-icon lucide-arrow-down-to-line"><path d="M12 17V3"/><path d="m6 11 6 6 6-6"/><path d="M19 21H5"/></svg>',
682
- 'select-all': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-mouse-pointer-icon lucide-square-mouse-pointer"><path d="M12.034 12.681a.498.498 0 0 1 .647-.647l9 3.5a.5.5 0 0 1-.033.943l-3.444 1.068a1 1 0 0 0-.66.66l-1.067 3.443a.5.5 0 0 1-.943.033z"/><path d="M21 11V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h6"/></svg>',
683
- 'download': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download-icon lucide-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>',
684
- 'undo': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-undo-icon lucide-undo"><path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/></svg>',
685
- 'redo': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-redo-icon lucide-redo"><path d="M21 7v6h-6"/><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7"/></svg>'
686
- });
687
-
688
- class BatchCommand extends KritzelBaseCommand {
689
- constructor(store, initiator, commands) {
690
- super(store, initiator);
691
- this.commands = commands;
692
- }
693
- execute() {
694
- this.commands.forEach(command => command.execute());
695
- }
696
- undo() {
697
- this.commands.forEach(command => command.undo());
698
- }
699
- }
700
-
701
- class RemoveObjectCommand extends KritzelBaseCommand {
702
- constructor(store, initiator, object) {
703
- super(store, initiator);
704
- this.object = object;
705
- }
706
- execute() {
707
- this._store.state.objectsOctree.remove(object => object.id === this.object.id);
708
- }
709
- undo() {
710
- this._store.state.objectsOctree.insert(this.object);
711
- }
712
- }
713
-
714
- class KritzelEraserTool extends KritzelBaseTool {
715
- constructor(store) {
716
- super(store);
717
- this.touchStartTimeout = null;
718
- }
719
- handlePointerDown(event) {
720
- if (event.pointerType === 'mouse') {
721
- if (KritzelEventHelper.isLeftClick(event)) {
722
- this._store.state.isErasing = true;
723
- }
724
- }
725
- if (event.pointerType === 'touch') {
726
- this.touchStartTimeout = setTimeout(() => {
727
- if (this._store.state.pointers.size === 1 && !this._store.state.isScaling) {
728
- this._store.state.isErasing = true;
729
- }
730
- }, 80);
731
- }
732
- }
733
- handlePointerMove(event) {
734
- var _a, _b;
735
- if (event.pointerType === 'mouse') {
736
- if (this._store.state.isErasing) {
737
- const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
738
- if (!shadowRoot)
739
- return;
740
- const selectedObject = this._store.getObjectFromPointerEvent(event, '.object');
741
- if (!selectedObject)
742
- return;
743
- selectedObject.markedForRemoval = true;
744
- this._store.rerender();
745
- }
746
- }
747
- if (event.pointerType === 'touch') {
748
- if (this._store.state.pointers.size === 1 && this._store.state.isErasing) {
749
- const shadowRoot = (_b = this._store.state.host) === null || _b === void 0 ? void 0 : _b.shadowRoot;
750
- if (!shadowRoot)
751
- return;
752
- const selectedObject = this._store.getObjectFromPointerEvent(event, '.object');
753
- if (!selectedObject)
754
- return;
755
- selectedObject.markedForRemoval = true;
756
- this._store.rerender();
757
- }
758
- }
759
- }
760
- handlePointerUp(event) {
761
- if (event.pointerType === 'mouse') {
762
- if (this._store.state.isErasing) {
763
- const removeCommands = this._store.allObjects
764
- .filter(object => object.markedForRemoval)
765
- .map(object => {
766
- object.markedForRemoval = false;
767
- return new RemoveObjectCommand(this._store, this, object);
768
- });
769
- if (removeCommands.length > 0) {
770
- this._store.history.executeCommand(new BatchCommand(this._store, this, removeCommands));
771
- }
772
- this._store.state.isErasing = false;
773
- }
774
- }
775
- if (event.pointerType === 'touch') {
776
- clearTimeout(this.touchStartTimeout);
777
- if (this._store.state.isErasing) {
778
- const removeCommands = this._store.allObjects
779
- .filter(object => object.markedForRemoval)
780
- .map(object => {
781
- object.markedForRemoval = false;
782
- return new RemoveObjectCommand(this._store, this, object);
783
- });
784
- if (removeCommands.length > 0) {
785
- this._store.history.executeCommand(new BatchCommand(this._store, this, removeCommands));
786
- }
787
- this._store.state.isErasing = false;
788
- }
789
- }
790
- }
791
- }
792
-
793
- class RemoveSelectionGroupCommand extends KritzelBaseCommand {
794
- constructor(store, initiator) {
795
- super(store, initiator);
796
- this.previousSelectionGroup = this._store.state.selectionGroup;
797
- }
798
- execute() {
799
- this._store.state.objectsOctree.remove(object => { var _a; return object.id === ((_a = this.previousSelectionGroup) === null || _a === void 0 ? void 0 : _a.id); });
800
- this._store.state.selectionGroup = null;
801
- }
802
- undo() {
803
- if (this.previousSelectionGroup) {
804
- this._store.state.objectsOctree.insert(this.previousSelectionGroup);
805
- this._store.state.selectionGroup = this.previousSelectionGroup;
806
- }
807
- }
808
- }
809
-
810
- class MoveSelectionGroupCommand extends KritzelBaseCommand {
811
- constructor(store, initiator, startX, startY, endX, endY, skipFirstExecution = false) {
812
- super(store, initiator);
813
- this.startX = startX;
814
- this.startY = startY;
815
- this.endX = endX;
816
- this.endY = endY;
817
- this.skipExecution = skipFirstExecution;
818
- this.selectionGroup = this._store.state.selectionGroup;
819
- }
820
- execute() {
821
- if (this.skipExecution) {
822
- this.skipExecution = false;
823
- return;
824
- }
825
- this._store.state.selectionGroup = this.selectionGroup;
826
- this._store.state.selectionGroup.move(this.startX, this.startY, this.endX, this.endY);
827
- }
828
- undo() {
829
- this._store.state.selectionGroup = this.selectionGroup;
830
- this._store.state.selectionGroup.move(this.endX, this.endY, this.startX, this.startY);
831
- }
832
- }
833
-
834
- class KritzelBaseHandler {
835
- constructor(store) {
836
- this._store = store;
837
- }
838
- }
839
-
840
- class KritzelMoveHandler extends KritzelBaseHandler {
841
- constructor(store) {
842
- super(store);
843
- }
844
- handlePointerDown(event) {
845
- var _a, _b;
846
- if (event.pointerType === 'mouse') {
847
- if (KritzelEventHelper.isLeftClick(event)) {
848
- if (((_a = this._store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
849
- const clientX = event.clientX - this._store.offsetX;
850
- const clientY = event.clientY - this._store.offsetY;
851
- this._store.state.isDragging = true;
852
- this.dragStartX = clientX;
853
- this.dragStartY = clientY;
854
- this.startX = this.dragStartX;
855
- this.startY = this.dragStartY;
856
- }
857
- }
858
- }
859
- if (event.pointerType === 'touch') {
860
- const activePointers = Array.from(this._store.state.pointers.values());
861
- if (this._store.state.pointers.size === 1) {
862
- if (((_b = this._store.state.selectionGroup) === null || _b === void 0 ? void 0 : _b.selected) && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
863
- const x = Math.round(activePointers[0].clientX - this._store.offsetX);
864
- const y = Math.round(activePointers[0].clientY - this._store.offsetY);
865
- this.dragStartX = x;
866
- this.dragStartY = y;
867
- this.startX = x;
868
- this.startY = y;
869
- }
870
- }
871
- }
872
- }
873
- handlePointerMove(event) {
874
- if (event.pointerType === 'mouse') {
875
- if (this._store.state.isDragging && this._store.state.selectionGroup) {
876
- const clientX = event.clientX - this._store.offsetX;
877
- const clientY = event.clientY - this._store.offsetY;
878
- this.endX = clientX;
879
- this.endY = clientY;
880
- this._store.state.selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
881
- this.dragStartX = clientX;
882
- this.dragStartY = clientY;
883
- }
884
- }
885
- if (event.pointerType === 'touch') {
886
- const activePointers = Array.from(this._store.state.pointers.values());
887
- if (this._store.state.pointers.size === 1 && this._store.state.selectionGroup && !this._store.state.isResizeHandleSelected && !this._store.state.isRotationHandleSelected) {
888
- const x = Math.round(activePointers[0].clientX - this._store.offsetX);
889
- const y = Math.round(activePointers[0].clientY - this._store.offsetY);
890
- this._store.state.isDragging = true;
891
- this.endX = x;
892
- this.endY = y;
893
- const moveDeltaX = Math.abs(x - this.startX);
894
- const moveDeltaY = Math.abs(y - this.startY);
895
- const moveThreshold = 5;
896
- if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
897
- clearTimeout(this._store.state.longTouchTimeout);
898
- this._store.state.selectionGroup.move(x, y, this.dragStartX, this.dragStartY);
899
- this.dragStartX = x;
900
- this.dragStartY = y;
901
- }
902
- }
903
- }
904
- }
905
- handlePointerUp(event) {
906
- if (event.pointerType === 'mouse') {
907
- if (this._store.state.isDragging) {
908
- this._store.state.isDragging = false;
909
- this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
910
- }
911
- }
912
- if (event.pointerType === 'touch') {
913
- if (this._store.state.isDragging) {
914
- this._store.state.isDragging = false;
915
- this._store.history.executeCommand(new MoveSelectionGroupCommand(this._store, this, this.endX, this.endY, this.startX, this.startY, true));
916
- }
917
- }
918
- }
919
- }
920
-
921
- var KritzelHandleType;
922
- (function (KritzelHandleType) {
923
- KritzelHandleType["TopLeft"] = "top-left";
924
- KritzelHandleType["TopRight"] = "top-right";
925
- KritzelHandleType["BottomLeft"] = "bottom-left";
926
- KritzelHandleType["BottomRight"] = "bottom-right";
927
- })(KritzelHandleType || (KritzelHandleType = {}));
928
-
929
- class ResizeSelectionGroupCommand extends KritzelBaseCommand {
930
- constructor(store, initiator, previousSize, newSize) {
931
- super(store, initiator);
932
- this.previousSize = previousSize;
933
- this.newSize = newSize;
934
- this.selectionGroup = this._store.state.selectionGroup;
935
- }
936
- execute() {
937
- this._store.state.selectionGroup = this.selectionGroup;
938
- this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
939
- }
940
- undo() {
941
- this._store.state.selectionGroup = this.selectionGroup;
942
- this._store.state.selectionGroup.resize(this.previousSize.x, this.previousSize.y, this.previousSize.width, this.previousSize.height);
943
- }
944
- }
945
-
946
- class KritzelResizeHandler extends KritzelBaseHandler {
947
- constructor(store) {
948
- super(store);
949
- this.initialMouseX = 0;
950
- this.initialMouseY = 0;
951
- this.initialSize = { x: 0, y: 0, width: 0, height: 0 };
952
- this.newSize = { x: 0, y: 0, width: 0, height: 0 };
953
- }
954
- handlePointerDown(event) {
955
- if (event.pointerType === 'mouse') {
956
- if (KritzelEventHelper.isLeftClick(event)) {
957
- if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
958
- const clientX = event.clientX - this._store.offsetX;
959
- const clientY = event.clientY - this._store.offsetY;
960
- this._store.state.isResizing = true;
961
- this.initialMouseX = clientX;
962
- this.initialMouseY = clientY;
963
- this.initialSize.width = this._store.state.selectionGroup.width;
964
- this.initialSize.height = this._store.state.selectionGroup.height;
965
- this.initialSize.x = this._store.state.selectionGroup.translateX;
966
- this.initialSize.y = this._store.state.selectionGroup.translateY;
967
- }
968
- }
969
- }
970
- if (event.pointerType === 'touch') {
971
- const activePointers = Array.from(this._store.state.pointers.values());
972
- const firstTouch = activePointers[0];
973
- if (!firstTouch) {
974
- return;
975
- }
976
- if (activePointers.length === 1) {
977
- if (this._store.state.selectionGroup && this._store.state.isResizeHandleSelected) {
978
- const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
979
- const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
980
- this._store.state.isResizing = true;
981
- this.initialMouseX = clientX;
982
- this.initialMouseY = clientY;
983
- this.initialSize.width = this._store.state.selectionGroup.width;
984
- this.initialSize.height = this._store.state.selectionGroup.height;
985
- this.initialSize.x = this._store.state.selectionGroup.translateX;
986
- this.initialSize.y = this._store.state.selectionGroup.translateY;
987
- clearTimeout(this._store.state.longTouchTimeout);
988
- }
989
- }
990
- }
991
- }
992
- handlePointerMove(event) {
993
- if (event.pointerType === 'mouse') {
994
- if (this._store.state.isResizing && this._store.state.selectionGroup) {
995
- const clientX = event.clientX - this._store.offsetX;
996
- const clientY = event.clientY - this._store.offsetY;
997
- const dx = clientX - this.initialMouseX;
998
- const dy = clientY - this.initialMouseY;
999
- switch (this._store.state.resizeHandleType) {
1000
- case KritzelHandleType.TopLeft:
1001
- this.newSize.width = this.initialSize.width - dx;
1002
- this.newSize.height = this.initialSize.height - dy;
1003
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1004
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1005
- break;
1006
- case KritzelHandleType.TopRight:
1007
- this.newSize.width = this.initialSize.width + dx;
1008
- this.newSize.height = this.initialSize.height - dy;
1009
- this.newSize.x = this.initialSize.x;
1010
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1011
- break;
1012
- case KritzelHandleType.BottomLeft:
1013
- this.newSize.width = this.initialSize.width - dx;
1014
- this.newSize.height = this.initialSize.height + dy;
1015
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1016
- this.newSize.y = this.initialSize.y;
1017
- break;
1018
- case KritzelHandleType.BottomRight:
1019
- this.newSize.width = this.initialSize.width + dx;
1020
- this.newSize.height = this.initialSize.height + dy;
1021
- this.newSize.x = this.initialSize.x;
1022
- this.newSize.y = this.initialSize.y;
1023
- break;
1024
- }
1025
- this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
1026
- this._store.rerender();
1027
- }
1028
- }
1029
- if (event.pointerType === 'touch') {
1030
- const activePointers = Array.from(this._store.state.pointers.values());
1031
- const oneFingerTouch = activePointers[0];
1032
- if (!oneFingerTouch) {
1033
- return;
1034
- }
1035
- if (this._store.state.isResizing && this._store.state.selectionGroup) {
1036
- const clientX = Math.round(oneFingerTouch.clientX - this._store.offsetX);
1037
- const clientY = Math.round(oneFingerTouch.clientY - this._store.offsetY);
1038
- const dx = clientX - this.initialMouseX;
1039
- const dy = clientY - this.initialMouseY;
1040
- switch (this._store.state.resizeHandleType) {
1041
- case KritzelHandleType.TopLeft:
1042
- this.newSize.width = this.initialSize.width - dx;
1043
- this.newSize.height = this.initialSize.height - dy;
1044
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1045
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1046
- break;
1047
- case KritzelHandleType.TopRight:
1048
- this.newSize.width = this.initialSize.width + dx;
1049
- this.newSize.height = this.initialSize.height - dy;
1050
- this.newSize.x = this.initialSize.x;
1051
- this.newSize.y = dy / this._store.state.scale + this.initialSize.y;
1052
- break;
1053
- case KritzelHandleType.BottomLeft:
1054
- this.newSize.width = this.initialSize.width - dx;
1055
- this.newSize.height = this.initialSize.height + dy;
1056
- this.newSize.x = dx / this._store.state.scale + this.initialSize.x;
1057
- this.newSize.y = this.initialSize.y;
1058
- break;
1059
- case KritzelHandleType.BottomRight:
1060
- this.newSize.width = this.initialSize.width + dx;
1061
- this.newSize.height = this.initialSize.height + dy;
1062
- this.newSize.x = this.initialSize.x;
1063
- this.newSize.y = this.initialSize.y;
1064
- break;
1065
- }
1066
- this._store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
1067
- clearTimeout(this._store.state.longTouchTimeout);
1068
- }
1069
- }
1070
- }
1071
- handlePointerUp(event) {
1072
- if (event.pointerType === 'mouse') {
1073
- if (this._store.state.isResizing) {
1074
- const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
1075
- this._store.history.executeCommand(resizeSelectionGroupCommand);
1076
- this._store.state.isResizing = false;
1077
- this._store.rerender();
1078
- }
1079
- }
1080
- if (event.pointerType === 'touch') {
1081
- if (this._store.state.isResizing) {
1082
- const resizeSelectionGroupCommand = new ResizeSelectionGroupCommand(this._store, this, structuredClone(this.initialSize), structuredClone(this.newSize));
1083
- this._store.history.executeCommand(resizeSelectionGroupCommand);
1084
- this._store.state.isResizing = false;
1085
- this._store.rerender();
1086
- clearTimeout(this._store.state.longTouchTimeout);
1087
- }
1088
- }
1089
- }
1090
- }
1091
-
1092
- class RotateSelectionGroupCommand extends KritzelBaseCommand {
1093
- constructor(store, initiator, rotation) {
1094
- super(store, initiator);
1095
- this.rotation = rotation;
1096
- this.initialRotation = this._store.state.selectionGroup.rotation;
1097
- this.selectionGroup = this._store.state.selectionGroup;
1098
- }
1099
- execute() {
1100
- this._store.state.selectionGroup = this.selectionGroup;
1101
- this._store.state.selectionGroup.rotate(this.rotation);
1102
- this._store.state.selectionGroup.objects.forEach(object => {
1103
- this._store.state.objectsOctree.update(object);
1104
- });
1105
- }
1106
- undo() {
1107
- this._store.state.selectionGroup = this.selectionGroup;
1108
- this._store.state.selectionGroup.rotate(this.rotation - this.initialRotation);
1109
- this._store.state.selectionGroup.objects.forEach(object => {
1110
- this._store.state.objectsOctree.update(object);
1111
- });
1112
- }
1113
- }
1114
-
1115
- class KritzelRotationHandler extends KritzelBaseHandler {
1116
- constructor(store) {
1117
- super(store);
1118
- this.initialRotation = 0;
1119
- this.rotation = 0;
1120
- }
1121
- handlePointerDown(event) {
1122
- if (event.pointerType === 'mouse') {
1123
- if (KritzelEventHelper.isLeftClick(event)) {
1124
- if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
1125
- const clientX = event.clientX - this._store.offsetX;
1126
- const clientY = event.clientY - this._store.offsetY;
1127
- this._store.state.isRotating = true;
1128
- const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1129
- const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1130
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1131
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1132
- this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
1133
- }
1134
- }
1135
- }
1136
- if (event.pointerType === 'touch') {
1137
- const activePointers = Array.from(this._store.state.pointers.values());
1138
- const firstTouch = activePointers[0];
1139
- if (!firstTouch) {
1140
- return;
1141
- }
1142
- if (activePointers.length === 1) {
1143
- if (this._store.state.selectionGroup && this._store.state.isRotationHandleSelected) {
1144
- const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1145
- const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1146
- this._store.state.isRotating = true;
1147
- const centerX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1148
- const centerY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1149
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1150
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1151
- this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - this._store.state.selectionGroup.rotation;
1152
- clearTimeout(this._store.state.longTouchTimeout);
1153
- }
1154
- }
1155
- }
1156
- }
1157
- handlePointerMove(event) {
1158
- if (event.pointerType === 'mouse') {
1159
- if (this._store.state.isRotating && this._store.state.selectionGroup) {
1160
- const clientX = event.clientX - this._store.offsetX;
1161
- const clientY = event.clientY - this._store.offsetY;
1162
- const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1163
- const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1164
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1165
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1166
- const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
1167
- this.rotation = currentRotation - this.initialRotation;
1168
- this._store.state.selectionGroup.rotate(this.rotation);
1169
- this._store.rerender();
1170
- }
1171
- }
1172
- if (event.pointerType === 'touch') {
1173
- const activePointers = Array.from(this._store.state.pointers.values());
1174
- const firstTouch = activePointers[0];
1175
- if (!firstTouch) {
1176
- return;
1177
- }
1178
- if (this._store.state.isRotating && this._store.state.selectionGroup) {
1179
- const clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1180
- const clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1181
- const groupCenterX = this._store.state.selectionGroup.translateX + this._store.state.selectionGroup.width / 2 / this._store.state.scale;
1182
- const groupCenterY = this._store.state.selectionGroup.translateY + this._store.state.selectionGroup.height / 2 / this._store.state.scale;
1183
- const cursorX = (clientX - this._store.state.translateX) / this._store.state.scale;
1184
- const cursorY = (clientY - this._store.state.translateY) / this._store.state.scale;
1185
- const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
1186
- this.rotation = currentRotation - this.initialRotation;
1187
- this._store.state.selectionGroup.rotate(this.rotation);
1188
- this._store.rerender();
1189
- clearTimeout(this._store.state.longTouchTimeout);
1190
- }
1191
- }
1192
- }
1193
- handlePointerUp(event) {
1194
- if (event.pointerType === 'mouse') {
1195
- if (this._store.state.isRotating) {
1196
- this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
1197
- this._store.state.isRotating = false;
1198
- this.initialRotation = 0;
1199
- this.rotation = 0;
1200
- }
1201
- }
1202
- if (event.pointerType === 'touch') {
1203
- if (this._store.state.isRotating) {
1204
- this._store.history.executeCommand(new RotateSelectionGroupCommand(this._store, this, this.rotation));
1205
- this._store.state.isRotating = false;
1206
- this.initialRotation = 0;
1207
- this.rotation = 0;
1208
- clearTimeout(this._store.state.longTouchTimeout);
1209
- }
1210
- }
1211
- }
1212
- }
1213
-
1214
- class KritzelGeometryHelper {
1215
- static doPolygonsIntersect(polygon1, polygon2) {
1216
- // 1. Convert polygons to array of points for easier processing
1217
- const points1 = [polygon1.bottomLeft, polygon1.bottomRight, polygon1.topRight, polygon1.topLeft];
1218
- const points2 = [polygon2.bottomLeft, polygon2.bottomRight, polygon2.topRight, polygon2.topLeft];
1219
- // 2. Check if any point of polygon1 is inside polygon2
1220
- for (const point of points1) {
1221
- if (this.isPointInPolygon(point, points2)) {
1222
- return true;
1223
- }
1224
- }
1225
- // 3. Check if any point of polygon2 is inside polygon1
1226
- for (const point of points2) {
1227
- if (this.isPointInPolygon(point, points1)) {
1228
- return true;
1229
- }
1230
- }
1231
- // 4. Check for edge intersections (more complex)
1232
- for (let i = 0; i < points1.length; i++) {
1233
- const p1a = points1[i];
1234
- const p1b = points1[(i + 1) % points1.length]; // Wrap around to the first point
1235
- for (let j = 0; j < points2.length; j++) {
1236
- const p2a = points2[j];
1237
- const p2b = points2[(j + 1) % points2.length];
1238
- if (this.intersectLines(p1a, p1b, p2a, p2b)) {
1239
- return true;
1240
- }
1241
- }
1242
- }
1243
- return false; // No intersection found
1244
- }
1245
- static isPointInPolygon(point, polygon) {
1246
- let inside = false;
1247
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
1248
- const xi = polygon[i].x, yi = polygon[i].y;
1249
- const xj = polygon[j].x, yj = polygon[j].y;
1250
- const intersect = yi > point.y !== yj > point.y && point.x < ((xj - xi) * (point.y - yi)) / (yj - yi) + xi;
1251
- if (intersect)
1252
- inside = !inside;
1253
- }
1254
- return inside;
1255
- }
1256
- static intersectLines(p1a, p1b, p2a, p2b) {
1257
- const det = (p1b.x - p1a.x) * (p2b.y - p2a.y) - (p1b.y - p1a.y) * (p2b.x - p2a.x);
1258
- if (det === 0) {
1259
- return false; // Lines are parallel
1260
- }
1261
- const t = ((p2a.x - p1a.x) * (p2b.y - p2a.y) - (p2a.y - p1a.y) * (p2b.x - p2a.x)) / det;
1262
- const u = -((p1a.x - p2a.x) * (p1b.y - p1a.y) - (p1a.y - p2a.y) * (p1b.x - p1a.x)) / det;
1263
- return t >= 0 && t <= 1 && u >= 0 && u <= 1;
1264
- }
1265
- }
1266
-
1267
- class KrtizelSelectionBox extends KritzelBaseObject {
1268
- constructor() {
1269
- super(...arguments);
1270
- this.__class__ = 'KrtizelSelectionBox';
1271
- this.objects = [];
1272
- }
1273
- static create(store) {
1274
- const object = new KrtizelSelectionBox();
1275
- object._store = store;
1276
- object.id = object.generateId();
1277
- object.scale = store.state.scale;
1278
- object.zIndex = 99999;
1279
- object.backgroundColor = 'var(--kritzel-selection-box-background-color, rgba(14, 17, 17, 0.2))';
1280
- object.borderColor = 'var(--kritzel-selection-box-border-color, rgba(14, 17, 17, 0.5))';
1281
- object.borderWidth = 2;
1282
- object.height = 0;
1283
- object.width = 0;
1284
- return object;
1285
- }
1286
- }
1287
-
1288
- class AddSelectionGroupCommand extends KritzelBaseCommand {
1289
- constructor(store, initiator, selectionGroup) {
1290
- super(store, initiator);
1291
- this.selectionGroup = selectionGroup;
1292
- }
1293
- execute() {
1294
- this._store.state.objectsOctree.remove(object => object instanceof KrtizelSelectionBox);
1295
- this._store.state.objectsOctree.insert(this.selectionGroup);
1296
- this._store.state.selectionGroup = this.selectionGroup;
1297
- }
1298
- undo() {
1299
- this._store.state.objectsOctree.remove(object => object.id === this.selectionGroup.id);
1300
- this._store.state.selectionGroup = null;
1301
- }
1302
- }
1303
-
1304
- class KritzelSelectionHandler extends KritzelBaseHandler {
1305
- get isSelectionClick() {
1306
- return this._store.state.selectionBox && this._store.state.selectionBox.width === 0 && this._store.state.selectionBox.height === 0;
1307
- }
1308
- get isSelectionDrag() {
1309
- return this._store.state.selectionBox && (this._store.state.selectionBox.width > 0 || this._store.state.selectionBox.height > 0);
1310
- }
1311
- constructor(store) {
1312
- super(store);
1313
- this.touchStartX = 0;
1314
- this.touchStartY = 0;
1315
- this.touchStartTimeout = null;
1316
- }
1317
- handlePointerDown(event) {
1318
- if (event.pointerType === 'mouse') {
1319
- if (KritzelEventHelper.isLeftClick(event) && !this._store.state.selectionGroup) {
1320
- this.startMouseSelection(event);
1321
- }
1322
- }
1323
- if (event.pointerType === 'touch') {
1324
- this.touchStartTimeout = setTimeout(() => {
1325
- if (this._store.state.pointers.size === 1 && !this._store.state.isScaling && !this._store.state.selectionGroup) {
1326
- this.startTouchSelection();
1327
- this.updateTouchSelection();
1328
- }
1329
- }, 80);
1330
- }
1331
- }
1332
- handlePointerMove(event) {
1333
- if (event.pointerType === 'mouse') {
1334
- if (this._store.state.isSelecting) {
1335
- this.updateMouseSelection(event);
1336
- }
1337
- }
1338
- if (event.pointerType === 'touch') {
1339
- const activePointers = Array.from(this._store.state.pointers.values());
1340
- const x = Math.round(activePointers[0].clientX - this._store.offsetX);
1341
- const y = Math.round(activePointers[0].clientY - this._store.offsetY);
1342
- const moveDeltaX = Math.abs(x - this.touchStartX);
1343
- const moveDeltaY = Math.abs(y - this.touchStartY);
1344
- const moveThreshold = 5;
1345
- if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._store.state.isSelecting) {
1346
- this.updateTouchSelection();
1347
- clearTimeout(this._store.state.longTouchTimeout);
1348
- }
1349
- }
1350
- }
1351
- handlePointerUp(event) {
1352
- if (event.pointerType === 'mouse') {
1353
- if (KritzelEventHelper.isLeftClick(event) && this._store.state.isSelecting) {
1354
- if (this.isSelectionClick) {
1355
- this.updateMouseSelection(event);
1356
- this.addSelectedObjectAtIndexToSelectionGroup(0);
1357
- this.removeSelectionBox();
1358
- }
1359
- if (this.isSelectionDrag) {
1360
- this.updateMouseSelection(event);
1361
- this.addSelectedObjectsToSelectionGroup();
1362
- this.removeSelectionBox();
1363
- }
1364
- }
1365
- }
1366
- if (event.pointerType === 'touch') {
1367
- clearTimeout(this.touchStartTimeout);
1368
- if (this._store.state.isSelecting) {
1369
- if (this.isSelectionClick) {
1370
- this.updateTouchSelection();
1371
- this.addSelectedObjectAtIndexToSelectionGroup(0);
1372
- this.removeSelectionBox();
1373
- }
1374
- if (this.isSelectionDrag) {
1375
- this.updateTouchSelection();
1376
- this.addSelectedObjectsToSelectionGroup();
1377
- this.removeSelectionBox();
1378
- }
1379
- this._store.state.skipContextMenu = false;
1380
- }
1381
- }
1382
- }
1383
- removeSelectionBox() {
1384
- this._store.state.selectionBox = null;
1385
- this._store.state.isSelecting = false;
1386
- this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox);
1387
- this._store.rerender();
1388
- }
1389
- startMouseSelection(event) {
1390
- let clientX, clientY;
1391
- clientX = event.clientX - this._store.offsetX;
1392
- clientY = event.clientY - this._store.offsetY;
1393
- const selectionBox = KrtizelSelectionBox.create(this._store);
1394
- this.startX = (clientX - this._store.state.translateX) / this._store.state.scale;
1395
- this.startY = (clientY - this._store.state.translateY) / this._store.state.scale;
1396
- selectionBox.translateX = this.startX;
1397
- selectionBox.translateY = this.startY;
1398
- this._store.state.selectionGroup = null;
1399
- this._store.state.selectionBox = selectionBox;
1400
- this._store.state.isSelecting = true;
1401
- this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox || o instanceof KritzelSelectionGroup);
1402
- this._store.state.objectsOctree.insert(selectionBox);
1403
- }
1404
- startTouchSelection() {
1405
- const activePointers = Array.from(this._store.state.pointers.values());
1406
- const firstTouch = activePointers[0];
1407
- if (!firstTouch) {
1408
- return;
1409
- }
1410
- let clientX, clientY;
1411
- clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1412
- clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1413
- this.touchStartX = clientX;
1414
- this.touchStartY = clientY;
1415
- const selectionBox = KrtizelSelectionBox.create(this._store);
1416
- this.startX = (clientX - this._store.state.translateX) / this._store.state.scale;
1417
- this.startY = (clientY - this._store.state.translateY) / this._store.state.scale;
1418
- selectionBox.translateX = this.startX;
1419
- selectionBox.translateY = this.startY;
1420
- this._store.state.selectionGroup = null;
1421
- this._store.state.selectionBox = selectionBox;
1422
- this._store.state.isSelecting = true;
1423
- this._store.state.objectsOctree.remove(o => o instanceof KrtizelSelectionBox || o instanceof KritzelSelectionGroup);
1424
- this._store.state.objectsOctree.insert(selectionBox);
1425
- }
1426
- updateMouseSelection(event) {
1427
- let clientX, clientY;
1428
- clientX = event.clientX - this._store.offsetX;
1429
- clientY = event.clientY - this._store.offsetY;
1430
- const selectionBox = this._store.state.selectionBox;
1431
- if (selectionBox) {
1432
- const currentX = (clientX - this._store.state.translateX) / selectionBox.scale;
1433
- const currentY = (clientY - this._store.state.translateY) / selectionBox.scale;
1434
- selectionBox.width = Math.abs(currentX - this.startX) * selectionBox.scale;
1435
- selectionBox.height = Math.abs(currentY - this.startY) * selectionBox.scale;
1436
- selectionBox.translateX = Math.min(currentX, this.startX);
1437
- selectionBox.translateY = Math.min(currentY, this.startY);
1438
- this.updateSelectedObjects();
1439
- this._store.rerender();
1440
- }
1441
- }
1442
- updateTouchSelection() {
1443
- const activePointers = Array.from(this._store.state.pointers.values());
1444
- const firstTouch = activePointers[0];
1445
- if (!firstTouch) {
1446
- return;
1447
- }
1448
- let clientX, clientY;
1449
- clientX = Math.round(firstTouch.clientX - this._store.offsetX);
1450
- clientY = Math.round(firstTouch.clientY - this._store.offsetY);
1451
- const selectionBox = this._store.state.selectionBox;
1452
- if (selectionBox) {
1453
- const currentX = (clientX - this._store.state.translateX) / selectionBox.scale;
1454
- const currentY = (clientY - this._store.state.translateY) / selectionBox.scale;
1455
- selectionBox.width = Math.abs(currentX - this.startX) * selectionBox.scale;
1456
- selectionBox.height = Math.abs(currentY - this.startY) * selectionBox.scale;
1457
- selectionBox.translateX = Math.min(currentX, this.startX);
1458
- selectionBox.translateY = Math.min(currentY, this.startY);
1459
- this.updateSelectedObjects();
1460
- }
1461
- }
1462
- updateSelectedObjects() {
1463
- this._store.allObjects
1464
- .filter(o => !(o instanceof KrtizelSelectionBox))
1465
- .forEach(object => {
1466
- const objectPolygon = object.rotatedPolygon;
1467
- const selectionBoxPolygon = this._store.state.selectionBox.rotatedPolygon;
1468
- object.selected = KritzelGeometryHelper.doPolygonsIntersect(objectPolygon, selectionBoxPolygon);
1469
- });
1470
- }
1471
- addSelectedObjectAtIndexToSelectionGroup(index) {
1472
- const selectedObjects = this._store.selectedObjects.sort((a, b) => b.zIndex - a.zIndex);
1473
- const selectedObject = selectedObjects[index];
1474
- if (!selectedObject) {
1475
- return;
1476
- }
1477
- selectedObjects.forEach(o => (o.selected = false));
1478
- this._store.state.selectionGroup = KritzelSelectionGroup.create(this._store);
1479
- this._store.state.selectionGroup.addOrRemove(selectedObject);
1480
- this._store.state.selectionGroup.selected = true;
1481
- this._store.state.selectionGroup.rotation = this._store.state.selectionGroup.objects[0].rotation;
1482
- this._store.history.executeCommand(new AddSelectionGroupCommand(this._store, this, this._store.state.selectionGroup));
1483
- }
1484
- addSelectedObjectsToSelectionGroup() {
1485
- const selectedObjects = this._store.selectedObjects;
1486
- if (selectedObjects.length === 0) {
1487
- return;
1488
- }
1489
- this._store.state.selectionGroup = KritzelSelectionGroup.create(this._store);
1490
- selectedObjects.forEach(o => {
1491
- o.selected = false;
1492
- this._store.state.selectionGroup.addOrRemove(o);
1493
- });
1494
- this._store.state.selectionGroup.selected = true;
1495
- if (this._store.state.selectionGroup.length === 1) {
1496
- this._store.state.selectionGroup.rotation = this._store.state.selectionGroup.objects[0].rotation;
1497
- }
1498
- this._store.history.executeCommand(new AddSelectionGroupCommand(this._store, this, this._store.state.selectionGroup));
1499
- }
1500
- }
1501
-
1502
- class KritzelSelectionTool extends KritzelBaseTool {
1503
- constructor(store) {
1504
- super(store);
1505
- this.selectionHandler = new KritzelSelectionHandler(this._store);
1506
- this.moveHandler = new KritzelMoveHandler(this._store);
1507
- this.resizeHandler = new KritzelResizeHandler(this._store);
1508
- this.rotationHandler = new KritzelRotationHandler(this._store);
1509
- }
1510
- handlePointerDown(event) {
1511
- if (event.cancelable) {
1512
- event.preventDefault();
1513
- }
1514
- if (event.pointerType === 'mouse') {
1515
- if (KritzelEventHelper.isLeftClick(event)) {
1516
- this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
1517
- this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
1518
- this._store.state.resizeHandleType = this.getHandleType(event);
1519
- const selectedObject = this.getSelectedObject(event);
1520
- const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
1521
- if ((selectedObject === null || isDifferentObject) &&
1522
- this._store.state.selectionGroup &&
1523
- !this._store.state.isResizeHandleSelected &&
1524
- !this._store.state.isRotationHandleSelected) {
1525
- this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
1526
- }
1527
- if (selectedObject && selectedObject.selected && selectedObject.objects.length === 1) {
1528
- setTimeout(() => {
1529
- if (this._store.state.isDragging === false && this._store.state.isResizing === false && this._store.state.isRotating === false) {
1530
- selectedObject.objects[0].onSelectedClick();
1531
- }
1532
- }, 100);
1533
- }
1534
- }
1535
- this.moveHandler.handlePointerDown(event);
1536
- this.selectionHandler.handlePointerDown(event);
1537
- this.resizeHandler.handlePointerDown(event);
1538
- this.rotationHandler.handlePointerDown(event);
1539
- this._store.rerender();
1540
- }
1541
- if (event.pointerType === 'touch') {
1542
- if (this._store.state.isScaling === true) {
1543
- return;
531
+ }
1544
532
  }
1545
- if (this._store.state.pointers.size === 1) {
1546
- this._store.state.isResizeHandleSelected = this.isHandleSelected(event);
1547
- this._store.state.isRotationHandleSelected = this.isRotationHandleSelected(event);
1548
- this._store.state.resizeHandleType = this.getHandleType(event);
1549
- const selectedObject = this.getSelectedObject(event);
1550
- const isDifferentObject = selectedObject && this._store.state.selectionGroup && selectedObject.id !== this._store.state.selectionGroup.id;
1551
- if (!this._store.state.selectionGroup && selectedObject) {
1552
- this._store.state.skipContextMenu = true;
533
+ else {
534
+ if (this.hasSuffixContent !== false) {
535
+ this.hasSuffixContent = false;
1553
536
  }
1554
- if ((selectedObject === null || isDifferentObject) &&
1555
- this._store.state.selectionGroup &&
1556
- !this._store.state.isResizeHandleSelected &&
1557
- !this._store.state.isRotationHandleSelected) {
1558
- this._store.history.executeCommand(new RemoveSelectionGroupCommand(this._store, this._store.state.selectionGroup));
537
+ }
538
+ };
539
+ this.evaluatePrefixContent = () => {
540
+ if (this.prefixSlotElement) {
541
+ const newHasContent = this.prefixSlotElement.assignedNodes({ flatten: true }).length > 0;
542
+ if (this.hasPrefixContent !== newHasContent) {
543
+ this.hasPrefixContent = newHasContent;
1559
544
  }
1560
- if (selectedObject && selectedObject.selected && selectedObject.objects.length === 1) {
1561
- setTimeout(() => {
1562
- if (this._store.state.isDragging === false && this._store.state.isResizing === false && this._store.state.isRotating === false) {
1563
- selectedObject.objects[0].onSelectedClick();
1564
- }
1565
- }, 100);
545
+ }
546
+ else {
547
+ if (this.hasPrefixContent !== false) {
548
+ this.hasPrefixContent = false;
1566
549
  }
1567
550
  }
1568
- this.rotationHandler.handlePointerDown(event);
1569
- this.resizeHandler.handlePointerDown(event);
1570
- this.moveHandler.handlePointerDown(event);
1571
- this.selectionHandler.handlePointerDown(event);
1572
- }
551
+ };
1573
552
  }
1574
- handlePointerMove(event) {
1575
- if (event.cancelable) {
1576
- event.preventDefault();
1577
- }
1578
- if (event.pointerType === 'mouse') {
1579
- this.moveHandler.handlePointerMove(event);
1580
- this.selectionHandler.handlePointerMove(event);
1581
- this.resizeHandler.handlePointerMove(event);
1582
- this.rotationHandler.handlePointerMove(event);
1583
- this._store.rerender();
1584
- }
1585
- if (event.pointerType === 'touch') {
1586
- if (this._store.state.isScaling === true) {
1587
- return;
1588
- }
1589
- this.rotationHandler.handlePointerMove(event);
1590
- this.resizeHandler.handlePointerMove(event);
1591
- this.moveHandler.handlePointerMove(event);
1592
- this.selectionHandler.handlePointerMove(event);
1593
- this._store.rerender();
1594
- }
553
+ componentWillLoad() {
554
+ this.updateInternalValue(this.value, false);
555
+ this.evaluateSuffixContent();
556
+ this.evaluatePrefixContent();
1595
557
  }
1596
- handlePointerUp(event) {
1597
- if (event.cancelable) {
1598
- event.preventDefault();
1599
- }
1600
- if (event.pointerType === 'mouse') {
1601
- this.moveHandler.handlePointerUp(event);
1602
- this.selectionHandler.handlePointerUp(event);
1603
- this.resizeHandler.handlePointerUp(event);
1604
- this.rotationHandler.handlePointerUp(event);
1605
- this._store.rerender();
1606
- }
1607
- if (event.pointerType === 'touch') {
1608
- if (this._store.state.isScaling === true) {
1609
- return;
1610
- }
1611
- this.rotationHandler.handlePointerUp(event);
1612
- this.resizeHandler.handlePointerUp(event);
1613
- this.moveHandler.handlePointerUp(event);
1614
- this.selectionHandler.handlePointerUp(event);
558
+ externalValueChanged(newValue) {
559
+ if (newValue !== this.internalValue) {
560
+ this.updateInternalValue(newValue, false);
1615
561
  }
1616
562
  }
1617
- getSelectedObject(event) {
1618
- const path = event.composedPath().slice(1);
1619
- const objectElement = path.find(element => element.classList && element.classList.contains('object'));
1620
- const object = this._store.findObjectById(objectElement === null || objectElement === void 0 ? void 0 : objectElement.id);
1621
- if (!object) {
1622
- return null;
1623
- }
1624
- if (object instanceof KritzelSelectionGroup) {
1625
- return object;
563
+ optionsChanged() {
564
+ this.updateInternalValue(this.internalValue, true);
565
+ }
566
+ updateInternalValue(proposedValue, emitChange) {
567
+ let finalValue = proposedValue;
568
+ if (this.options && this.options.length > 0) {
569
+ const isValidValue = this.options.some(opt => opt.value === finalValue);
570
+ if (!finalValue || !isValidValue) {
571
+ finalValue = this.options[0].value;
572
+ }
1626
573
  }
1627
574
  else {
1628
- const group = KritzelSelectionGroup.create(this._store);
1629
- group.translateX = 0;
1630
- group.translateY = 0;
1631
- group.addOrRemove(object);
1632
- return group;
575
+ finalValue = undefined;
1633
576
  }
1634
- }
1635
- getHandleType(event) {
1636
- var _a;
1637
- const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
1638
- if (!shadowRoot)
1639
- return;
1640
- const point = event instanceof TouchEvent ? event.touches[0] : event;
1641
- const elementAtPoint = shadowRoot.elementFromPoint(point.clientX, point.clientY);
1642
- const handle = elementAtPoint.closest('.resize-handle-overlay');
1643
- return handle === null || handle === void 0 ? void 0 : handle.classList[1];
1644
- }
1645
- isHandleSelected(event) {
1646
- var _a;
1647
- const shadowRoot = (_a = this._store.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
1648
- if (!shadowRoot)
1649
- return false;
1650
- const point = event instanceof TouchEvent ? event.touches[0] : event;
1651
- const elementAtPoint = shadowRoot.elementFromPoint(point.clientX, point.clientY);
1652
- return elementAtPoint === null || elementAtPoint === void 0 ? void 0 : elementAtPoint.classList.contains('resize-handle-overlay');
1653
- }
1654
- isRotationHandleSelected(event) {
1655
- const path = event.composedPath();
1656
- return !!path.find(element => element.classList && element.classList.contains('rotation-handle-overlay'));
1657
- }
1658
- }
1659
-
1660
- class KritzelReviver {
1661
- constructor(store) {
1662
- this._store = store;
1663
- }
1664
- revive(obj) {
1665
- if (obj && typeof obj === 'object') {
1666
- if (obj.__class__) {
1667
- let revivedObj;
1668
- switch (obj.__class__) {
1669
- case 'KritzelPath':
1670
- revivedObj = KritzelPath.create(this._store).revive(obj);
1671
- break;
1672
- case 'KritzelText':
1673
- revivedObj = KritzelText.create(this._store, obj.fontSize, obj.fontFamily).revive(obj);
1674
- break;
1675
- case 'KritzelImage':
1676
- revivedObj = KritzelImage.create(this._store).revive(obj);
1677
- break;
1678
- case 'KritzelSelectionGroup':
1679
- revivedObj = KritzelSelectionGroup.create(this._store).revive(obj);
1680
- break;
1681
- case 'KritzelBrushTool':
1682
- revivedObj = new KritzelBrushTool(this._store);
1683
- break;
1684
- case 'KritzelEraserTool':
1685
- revivedObj = new KritzelEraserTool(this._store);
1686
- break;
1687
- case 'KritzelImageTool':
1688
- revivedObj = new KritzelImageTool(this._store);
1689
- break;
1690
- case 'KritzelSelectionTool':
1691
- revivedObj = new KritzelSelectionTool(this._store);
1692
- break;
1693
- case 'KritzelTextTool':
1694
- revivedObj = new KritzelTextTool(this._store);
1695
- break;
1696
- default:
1697
- revivedObj = obj;
1698
- }
1699
- return revivedObj;
1700
- }
1701
- const newObj = Array.isArray(obj) ? [] : {};
1702
- for (const key in obj) {
1703
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
1704
- newObj[key] = this.revive(obj[key]);
1705
- }
577
+ if (this.internalValue !== finalValue) {
578
+ this.internalValue = finalValue;
579
+ if (emitChange || (proposedValue !== finalValue && proposedValue !== undefined)) {
580
+ this.valueChanged.emit(this.internalValue);
1706
581
  }
1707
- return newObj;
1708
582
  }
1709
- return obj;
1710
- }
1711
- }
1712
-
1713
- class KritzelSelectionGroup extends KritzelBaseObject {
1714
- constructor() {
1715
- super(...arguments);
1716
- this.__class__ = 'KritzelSelectionGroup';
1717
- this.objects = [];
1718
- this.unchangedObjects = [];
1719
583
  }
1720
- get length() {
1721
- return this.objects.length;
1722
- }
1723
- static create(store) {
1724
- const object = new KritzelSelectionGroup();
1725
- object._store = store;
1726
- object.id = object.generateId();
1727
- object.scale = store.state.scale;
1728
- object.zIndex = 99999;
1729
- return object;
584
+ render() {
585
+ const selectClasses = {
586
+ 'custom-select': true,
587
+ 'has-suffix-border': this.hasSuffixContent,
588
+ 'has-prefix-border': this.hasPrefixContent,
589
+ };
590
+ return (h(Host, { key: '32c5f5a4f807c1e316c91b795c005b8d30ce6189' }, h("div", { key: 'b1cbeff18e688da4a2f7472be290b9527a619f07', class: "dropdown-wrapper" }, h("slot", { key: 'b3bbb7e21c6f5620cab41aa4b1c7206b6c75fd86', name: "prefix", ref: el => this.prefixSlotElement = el, onSlotchange: this.evaluatePrefixContent }), h("select", { key: '8b2dcdc125bee59cf29fce7c980b755e78d5816e', class: selectClasses, style: Object.assign(Object.assign({}, this.selectStyles), { width: this.width }), onInput: this.handleSelectChange }, this.options.map(option => (h("option", { value: option.value, style: option.style, selected: option.value === this.internalValue }, option.label)))), h("slot", { key: '8d83f0dea41ac959bf2392948efef33bb70d0154', name: "suffix", ref: el => this.suffixSlotElement = el, onSlotchange: this.evaluateSuffixContent }))));
1730
591
  }
1731
- addOrRemove(object) {
1732
- const index = this.objects.findIndex(obj => obj.id === object.id);
1733
- if (index === -1) {
1734
- this.objects.push(object);
1735
- }
1736
- else {
1737
- this.objects.splice(index, 1);
592
+ static get watchers() { return {
593
+ "value": ["externalValueChanged"],
594
+ "options": ["optionsChanged"]
595
+ }; }
596
+ };
597
+ KritzelDropdown.style = kritzelDropdownCss;
598
+
599
+ class KritzelIconRegistry {
600
+ static register(name, svgContent) {
601
+ if (this.registry.has(name)) {
602
+ console.warn(`[IconRegistry] Icon "${name}" is already registered. It will be overwritten.`);
1738
603
  }
1739
- this.unchangedObjects = ObjectHelper.clone(this.objects);
1740
- this.refreshObjectDimensions();
1741
- }
1742
- deselectAllChildren() {
1743
- this.objects.forEach(obj => (obj.selected = false));
1744
- }
1745
- updatePosition(x, y) {
1746
- this.objects.forEach(obj => {
1747
- const deltaX = obj.translateX - this.translateX;
1748
- const deltaY = obj.translateY - this.translateY;
1749
- obj.translateX = x + deltaX;
1750
- obj.translateY = y + deltaY;
1751
- this._store.state.objectsOctree.update(obj);
1752
- });
1753
- this.unchangedObjects.forEach(obj => {
1754
- const deltaX = obj.translateX - this.translateX;
1755
- const deltaY = obj.translateY - this.translateY;
1756
- obj.translateX = x + deltaX;
1757
- obj.translateY = y + deltaY;
1758
- });
1759
- this.translateX = x;
1760
- this.translateY = y;
1761
- this._store.state.objectsOctree.update(this);
1762
- }
1763
- move(startX, startY, endX, endY) {
1764
- const deltaX = (startX - endX) / this._store.state.scale;
1765
- const deltaY = (startY - endY) / this._store.state.scale;
1766
- this.translateX += deltaX;
1767
- this.translateY += deltaY;
1768
- this._store.state.objectsOctree.update(this);
1769
- this.objects.forEach(obj => {
1770
- obj.translateX += deltaX;
1771
- obj.translateY += deltaY;
1772
- this._store.state.objectsOctree.update(obj);
1773
- });
1774
- this.unchangedObjects.forEach(obj => {
1775
- obj.translateX += deltaX;
1776
- obj.translateY += deltaY;
1777
- });
1778
- }
1779
- resize(x, y, width, height) {
1780
- const widthScaleFactor = width / this.width;
1781
- const heightScaleFactor = height / this.height;
1782
- const deltaX = x - this.translateX;
1783
- const deltaY = y - this.translateY;
1784
- this.objects.forEach(child => {
1785
- const updatedWidth = child.width * widthScaleFactor;
1786
- const updatedHeight = child.height * heightScaleFactor;
1787
- const updatedX = child.translateX + deltaX + (child.translateX - this.translateX) * (widthScaleFactor - 1);
1788
- const updatedY = child.translateY + deltaY + (child.translateY - this.translateY) * (heightScaleFactor - 1);
1789
- child.resize(updatedX, updatedY, updatedWidth, updatedHeight);
1790
- this._store.state.objectsOctree.update(child);
1791
- });
1792
- this.refreshObjectDimensions();
1793
- this.unchangedObjects = ObjectHelper.clone(this.objects);
1794
- }
1795
- rotate(value) {
1796
- this.rotation = value;
1797
- const centerX = this.translateX + this.totalWidth / 2 / this.scale;
1798
- const centerY = this.translateY + this.totalHeight / 2 / this.scale;
1799
- const angle = value;
1800
- const cos = Math.cos(angle);
1801
- const sin = Math.sin(angle);
1802
- this.objects.forEach(child => {
1803
- const unchangedChild = this.getUnchangedObject(child.id);
1804
- const offsetX = this.getOffsetXToCenter(unchangedChild);
1805
- const offsetY = this.getOffsetYToCenter(unchangedChild);
1806
- const rotatedX = cos * offsetX - sin * offsetY;
1807
- const rotatedY = sin * offsetX + cos * offsetY;
1808
- child.translateX = centerX + rotatedX - child.totalWidth / 2 / child.scale;
1809
- child.translateY = centerY + rotatedY - child.totalHeight / 2 / child.scale;
1810
- child.rotation = this.objects.length === 1 ? value : value + unchangedChild.rotation;
1811
- this._store.state.objectsOctree.update(child);
1812
- });
604
+ this.registry.set(name, svgContent);
1813
605
  }
1814
- copy() {
1815
- const selectionGroup = KritzelSelectionGroup.create(this._store);
1816
- let currentZIndex = this._store.currentZIndex;
1817
- this.objects.forEach(obj => {
1818
- const copiedObject = obj.copy();
1819
- copiedObject.zIndex = currentZIndex;
1820
- selectionGroup.addOrRemove(copiedObject);
1821
- currentZIndex++;
1822
- });
1823
- selectionGroup.unchangedObjects = ObjectHelper.clone(selectionGroup.objects);
1824
- if (this.objects.length === 1) {
1825
- selectionGroup.rotation = this.objects[0].rotation;
1826
- }
1827
- return selectionGroup;
1828
- }
1829
- refreshObjectDimensions() {
1830
- if (this.objects.length === 1) {
1831
- const obj = this.objects[0];
1832
- this.minX = obj.boundingBox.x / this.scale;
1833
- this.maxX = obj.boundingBox.x / this.scale + obj.boundingBox.width;
1834
- this.minY = obj.boundingBox.y / this.scale;
1835
- this.maxY = obj.boundingBox.y / this.scale + obj.boundingBox.height;
1836
- this.translateX = (this.minX - this.padding) * this.scale;
1837
- this.translateY = (this.minY - this.padding) * this.scale;
1838
- this.width = (this.maxX - this.minX - this.padding) * this.scale;
1839
- this.height = (this.maxY - this.minY - this.padding) * this.scale;
1840
- }
1841
- else {
1842
- this.minX = Math.min(...this.objects.map(obj => obj.minXRotated));
1843
- this.maxX = Math.max(...this.objects.map(obj => obj.maxXRotated));
1844
- this.minY = Math.min(...this.objects.map(obj => obj.minYRotated));
1845
- this.maxY = Math.max(...this.objects.map(obj => obj.maxYRotated));
1846
- this.translateX = this.minX - this.padding;
1847
- this.translateY = this.minY - this.padding;
1848
- this.width = (this.maxX - this.minX - this.padding) * this.scale;
1849
- this.height = (this.maxY - this.minY - this.padding) * this.scale;
1850
- }
1851
- this._store.state.objectsOctree.update(this);
1852
- }
1853
- getOffsetXToCenter(obj) {
1854
- const objCenterX = obj.translateX + obj.totalWidth / obj.scale / 2;
1855
- const groupCenterX = this.translateX + this.totalWidth / this.scale / 2;
1856
- return objCenterX - groupCenterX;
1857
- }
1858
- getOffsetYToCenter(obj) {
1859
- const objCenterY = obj.translateY + obj.totalHeight / obj.scale / 2;
1860
- const groupCenterY = this.translateY + this.totalHeight / this.scale / 2;
1861
- return objCenterY - groupCenterY;
1862
- }
1863
- getUnchangedObject(objectId) {
1864
- const obj = this.unchangedObjects.find(obj => obj.id === objectId);
1865
- const reviver = new KritzelReviver(this._store);
1866
- return reviver.revive(obj);
606
+ static get(name) {
607
+ return this.registry.get(name);
1867
608
  }
1868
- }
1869
-
1870
- /**
1871
- * Browser Image Compression
1872
- * v2.0.2
1873
- * by Donald <donaldcwl@gmail.com>
1874
- * https://github.com/Donaldcwl/browser-image-compression
1875
- */
1876
-
1877
- function _mergeNamespaces(e,t){return t.forEach((function(t){t&&"string"!=typeof t&&!Array.isArray(t)&&Object.keys(t).forEach((function(r){if("default"!==r&&!(r in e)){var i=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,i.get?i:{enumerable:true,get:function(){return t[r]}});}}));})),Object.freeze(e)}function copyExifWithoutOrientation(e,t){return new Promise((function(r,i){let o;return getApp1Segment(e).then((function(e){try{return o=e,r(new Blob([t.slice(0,2),o,t.slice(2)],{type:"image/jpeg"}))}catch(e){return i(e)}}),i)}))}const getApp1Segment=e=>new Promise(((t,r)=>{const i=new FileReader;i.addEventListener("load",(({target:{result:e}})=>{const i=new DataView(e);let o=0;if(65496!==i.getUint16(o))return r("not a valid JPEG");for(o+=2;;){const a=i.getUint16(o);if(65498===a)break;const s=i.getUint16(o+2);if(65505===a&&1165519206===i.getUint32(o+4)){const a=o+10;let f;switch(i.getUint16(a)){case 18761:f=true;break;case 19789:f=false;break;default:return r("TIFF header contains invalid endian")}if(42!==i.getUint16(a+2,f))return r("TIFF header contains invalid version");const l=i.getUint32(a+4,f),c=a+l+2+12*i.getUint16(a+l,f);for(let e=a+l+2;e<c;e+=12){if(274==i.getUint16(e,f)){if(3!==i.getUint16(e+2,f))return r("Orientation data type is invalid");if(1!==i.getUint32(e+4,f))return r("Orientation data count is invalid");i.setUint16(e+8,1,f);break}}return t(e.slice(o,o+2+s))}o+=2+s;}return t(new Blob)})),i.readAsArrayBuffer(e);}));var e={},t={get exports(){return e},set exports(t){e=t;}};!function(e){var r,i,UZIP={};t.exports=UZIP,UZIP.parse=function(e,t){for(var r=UZIP.bin.readUshort,i=UZIP.bin.readUint,o=0,a={},s=new Uint8Array(e),f=s.length-4;101010256!=i(s,f);)f--;o=f;o+=4;var l=r(s,o+=4);r(s,o+=2);var c=i(s,o+=2),u=i(s,o+=4);o+=4,o=u;for(var h=0;h<l;h++){i(s,o),o+=4,o+=4,o+=4,i(s,o+=4);c=i(s,o+=4);var d=i(s,o+=4),A=r(s,o+=4),g=r(s,o+2),p=r(s,o+4);o+=6;var m=i(s,o+=8);o+=4,o+=A+g+p,UZIP._readLocal(s,m,a,c,d,t);}return a},UZIP._readLocal=function(e,t,r,i,o,a){var s=UZIP.bin.readUshort,f=UZIP.bin.readUint;f(e,t),s(e,t+=4),s(e,t+=2);var l=s(e,t+=2);f(e,t+=2),f(e,t+=4),t+=4;var c=s(e,t+=8),u=s(e,t+=2);t+=2;var h=UZIP.bin.readUTF8(e,t,c);if(t+=c,t+=u,a)r[h]={size:o,csize:i};else {var d=new Uint8Array(e.buffer,t);if(0==l)r[h]=new Uint8Array(d.buffer.slice(t,t+i));else {if(8!=l)throw "unknown compression method: "+l;var A=new Uint8Array(o);UZIP.inflateRaw(d,A),r[h]=A;}}},UZIP.inflateRaw=function(e,t){return UZIP.F.inflate(e,t)},UZIP.inflate=function(e,t){return UZIP.inflateRaw(new Uint8Array(e.buffer,e.byteOffset+2,e.length-6),t)},UZIP.deflate=function(e,t){null==t&&(t={level:6});var r=0,i=new Uint8Array(50+Math.floor(1.1*e.length));i[r]=120,i[r+1]=156,r+=2,r=UZIP.F.deflateRaw(e,i,r,t.level);var o=UZIP.adler(e,0,e.length);return i[r+0]=o>>>24&255,i[r+1]=o>>>16&255,i[r+2]=o>>>8&255,i[r+3]=o>>>0&255,new Uint8Array(i.buffer,0,r+4)},UZIP.deflateRaw=function(e,t){null==t&&(t={level:6});var r=new Uint8Array(50+Math.floor(1.1*e.length)),i=UZIP.F.deflateRaw(e,r,i,t.level);return new Uint8Array(r.buffer,0,i)},UZIP.encode=function(e,t){null==t&&(t=false);var r=0,i=UZIP.bin.writeUint,o=UZIP.bin.writeUshort,a={};for(var s in e){var f=!UZIP._noNeed(s)&&!t,l=e[s],c=UZIP.crc.crc(l,0,l.length);a[s]={cpr:f,usize:l.length,crc:c,file:f?UZIP.deflateRaw(l):l};}for(var s in a)r+=a[s].file.length+30+46+2*UZIP.bin.sizeUTF8(s);r+=22;var u=new Uint8Array(r),h=0,d=[];for(var s in a){var A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,0);}var g=0,p=h;for(var s in a){A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,1,d[g++]);}var m=h-p;return i(u,h,101010256),h+=4,o(u,h+=4,g),o(u,h+=2,g),i(u,h+=2,m),i(u,h+=4,p),h+=4,h+=2,u.buffer},UZIP._noNeed=function(e){var t=e.split(".").pop().toLowerCase();return -1!="png,jpg,jpeg,zip".indexOf(t)},UZIP._writeHeader=function(e,t,r,i,o,a){var s=UZIP.bin.writeUint,f=UZIP.bin.writeUshort,l=i.file;return s(e,t,0==o?67324752:33639248),t+=4,1==o&&(t+=2),f(e,t,20),f(e,t+=2,0),f(e,t+=2,i.cpr?8:0),s(e,t+=2,0),s(e,t+=4,i.crc),s(e,t+=4,l.length),s(e,t+=4,i.usize),f(e,t+=4,UZIP.bin.sizeUTF8(r)),f(e,t+=2,0),t+=2,1==o&&(t+=2,t+=2,s(e,t+=6,a),t+=4),t+=UZIP.bin.writeUTF8(e,t,r),0==o&&(e.set(l,t),t+=l.length),t},UZIP.crc={table:function(){for(var e=new Uint32Array(256),t=0;t<256;t++){for(var r=t,i=0;i<8;i++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r;}return e}(),update:function(e,t,r,i){for(var o=0;o<i;o++)e=UZIP.crc.table[255&(e^t[r+o])]^e>>>8;return e},crc:function(e,t,r){return 4294967295^UZIP.crc.update(4294967295,e,t,r)}},UZIP.adler=function(e,t,r){for(var i=1,o=0,a=t,s=t+r;a<s;){for(var f=Math.min(a+5552,s);a<f;)o+=i+=e[a++];i%=65521,o%=65521;}return o<<16|i},UZIP.bin={readUshort:function(e,t){return e[t]|e[t+1]<<8},writeUshort:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255;},readUint:function(e,t){return 16777216*e[t+3]+(e[t+2]<<16|e[t+1]<<8|e[t])},writeUint:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255,e[t+2]=r>>16&255,e[t+3]=r>>24&255;},readASCII:function(e,t,r){for(var i="",o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII:function(e,t,r){for(var i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i);},pad:function(e){return e.length<2?"0"+e:e},readUTF8:function(e,t,r){for(var i,o="",a=0;a<r;a++)o+="%"+UZIP.bin.pad(e[t+a].toString(16));try{i=decodeURIComponent(o);}catch(i){return UZIP.bin.readASCII(e,t,r)}return i},writeUTF8:function(e,t,r){for(var i=r.length,o=0,a=0;a<i;a++){var s=r.charCodeAt(a);if(0==(4294967168&s))e[t+o]=s,o++;else if(0==(4294965248&s))e[t+o]=192|s>>6,e[t+o+1]=128|s>>0&63,o+=2;else if(0==(4294901760&s))e[t+o]=224|s>>12,e[t+o+1]=128|s>>6&63,e[t+o+2]=128|s>>0&63,o+=3;else {if(0!=(4292870144&s))throw "e";e[t+o]=240|s>>18,e[t+o+1]=128|s>>12&63,e[t+o+2]=128|s>>6&63,e[t+o+3]=128|s>>0&63,o+=4;}}return o},sizeUTF8:function(e){for(var t=e.length,r=0,i=0;i<t;i++){var o=e.charCodeAt(i);if(0==(4294967168&o))r++;else if(0==(4294965248&o))r+=2;else if(0==(4294901760&o))r+=3;else {if(0!=(4292870144&o))throw "e";r+=4;}}return r}},UZIP.F={},UZIP.F.deflateRaw=function(e,t,r,i){var o=[[0,0,0,0,0],[4,4,8,4,0],[4,5,16,8,0],[4,6,16,16,0],[4,10,16,32,0],[8,16,32,32,0],[8,16,128,128,0],[8,32,128,256,0],[32,128,258,1024,1],[32,258,258,4096,1]][i],a=UZIP.F.U,s=UZIP.F._goodIndex;var f=UZIP.F._putsE,l=0,c=r<<3,u=0,h=e.length;if(0==i){for(;l<h;){f(t,c,l+(_=Math.min(65535,h-l))==h?1:0),c=UZIP.F._copyExact(e,l,_,t,c+8),l+=_;}return c>>>3}var d=a.lits,A=a.strt,g=a.prev,p=0,m=0,w=0,v=0,b=0,y=0;for(h>2&&(A[y=UZIP.F._hash(e,0)]=0),l=0;l<h;l++){if(b=y,l+1<h-2){y=UZIP.F._hash(e,l+1);var E=l+1&32767;g[E]=A[y],A[y]=E;}if(u<=l){(p>14e3||m>26697)&&h-l>100&&(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(l==h-1||u==h?1:0,d,p,v,e,w,l-w,t,c),p=m=v=0,w=l);var F=0;l<h-2&&(F=UZIP.F._bestMatch(e,l,g,b,Math.min(o[2],h-l),o[3]));var _=F>>>16,B=65535&F;if(0!=F){B=65535&F;var U=s(_=F>>>16,a.of0);a.lhst[257+U]++;var C=s(B,a.df0);a.dhst[C]++,v+=a.exb[U]+a.dxb[C],d[p]=_<<23|l-u,d[p+1]=B<<16|U<<8|C,p+=2,u=l+_;}else a.lhst[e[l]]++;m++;}}for(w==l&&0!=e.length||(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(1,d,p,v,e,w,l-w,t,c),p=0,m=0,p=m=v=0,w=l);0!=(7&c);)c++;return c>>>3},UZIP.F._bestMatch=function(e,t,r,i,o,a){var s=32767&t,f=r[s],l=s-f+32768&32767;if(f==s||i!=UZIP.F._hash(e,t-l))return 0;for(var c=0,u=0,h=Math.min(32767,t);l<=h&&0!=--a&&f!=s;){if(0==c||e[t+c]==e[t+c-l]){var d=UZIP.F._howLong(e,t,l);if(d>c){if(u=l,(c=d)>=o)break;l+2<d&&(d=l+2);for(var A=0,g=0;g<d-2;g++){var p=t-l+g+32768&32767,m=p-r[p]+32768&32767;m>A&&(A=m,f=p);}}}l+=(s=f)-(f=r[s])+32768&32767;}return c<<16|u},UZIP.F._howLong=function(e,t,r){if(e[t]!=e[t-r]||e[t+1]!=e[t+1-r]||e[t+2]!=e[t+2-r])return 0;var i=t,o=Math.min(e.length,t+258);for(t+=3;t<o&&e[t]==e[t-r];)t++;return t-i},UZIP.F._hash=function(e,t){return (e[t]<<8|e[t+1])+(e[t+2]<<4)&65535},UZIP.saved=0,UZIP.F._writeBlock=function(e,t,r,i,o,a,s,f,l){var c,u,h,d,A,g,p,m,w,v=UZIP.F.U,b=UZIP.F._putsF,y=UZIP.F._putsE;v.lhst[256]++,u=(c=UZIP.F.getTrees())[0],h=c[1],d=c[2],A=c[3],g=c[4],p=c[5],m=c[6],w=c[7];var E=32+(0==(l+3&7)?0:8-(l+3&7))+(s<<3),F=i+UZIP.F.contSize(v.fltree,v.lhst)+UZIP.F.contSize(v.fdtree,v.dhst),_=i+UZIP.F.contSize(v.ltree,v.lhst)+UZIP.F.contSize(v.dtree,v.dhst);_+=14+3*p+UZIP.F.contSize(v.itree,v.ihst)+(2*v.ihst[16]+3*v.ihst[17]+7*v.ihst[18]);for(var B=0;B<286;B++)v.lhst[B]=0;for(B=0;B<30;B++)v.dhst[B]=0;for(B=0;B<19;B++)v.ihst[B]=0;var U=E<F&&E<_?0:F<_?1:2;if(b(f,l,e),b(f,l+1,U),l+=3,0==U){for(;0!=(7&l);)l++;l=UZIP.F._copyExact(o,a,s,f,l);}else {var C,I;if(1==U&&(C=v.fltree,I=v.fdtree),2==U){UZIP.F.makeCodes(v.ltree,u),UZIP.F.revCodes(v.ltree,u),UZIP.F.makeCodes(v.dtree,h),UZIP.F.revCodes(v.dtree,h),UZIP.F.makeCodes(v.itree,d),UZIP.F.revCodes(v.itree,d),C=v.ltree,I=v.dtree,y(f,l,A-257),y(f,l+=5,g-1),y(f,l+=5,p-4),l+=4;for(var Q=0;Q<p;Q++)y(f,l+3*Q,v.itree[1+(v.ordr[Q]<<1)]);l+=3*p,l=UZIP.F._codeTiny(m,v.itree,f,l),l=UZIP.F._codeTiny(w,v.itree,f,l);}for(var M=a,x=0;x<r;x+=2){for(var S=t[x],R=S>>>23,T=M+(8388607&S);M<T;)l=UZIP.F._writeLit(o[M++],C,f,l);if(0!=R){var O=t[x+1],P=O>>16,H=O>>8&255,L=255&O;y(f,l=UZIP.F._writeLit(257+H,C,f,l),R-v.of0[H]),l+=v.exb[H],b(f,l=UZIP.F._writeLit(L,I,f,l),P-v.df0[L]),l+=v.dxb[L],M+=R;}}l=UZIP.F._writeLit(256,C,f,l);}return l},UZIP.F._copyExact=function(e,t,r,i,o){var a=o>>>3;return i[a]=r,i[a+1]=r>>>8,i[a+2]=255-i[a],i[a+3]=255-i[a+1],a+=4,i.set(new Uint8Array(e.buffer,t,r),a),o+(r+4<<3)},UZIP.F.getTrees=function(){for(var e=UZIP.F.U,t=UZIP.F._hufTree(e.lhst,e.ltree,15),r=UZIP.F._hufTree(e.dhst,e.dtree,15),i=[],o=UZIP.F._lenCodes(e.ltree,i),a=[],s=UZIP.F._lenCodes(e.dtree,a),f=0;f<i.length;f+=2)e.ihst[i[f]]++;for(f=0;f<a.length;f+=2)e.ihst[a[f]]++;for(var l=UZIP.F._hufTree(e.ihst,e.itree,7),c=19;c>4&&0==e.itree[1+(e.ordr[c-1]<<1)];)c--;return [t,r,l,o,s,c,i,a]},UZIP.F.getSecond=function(e){for(var t=[],r=0;r<e.length;r+=2)t.push(e[r+1]);return t},UZIP.F.nonZero=function(e){for(var t="",r=0;r<e.length;r+=2)0!=e[r+1]&&(t+=(r>>1)+",");return t},UZIP.F.contSize=function(e,t){for(var r=0,i=0;i<t.length;i++)r+=t[i]*e[1+(i<<1)];return r},UZIP.F._codeTiny=function(e,t,r,i){for(var o=0;o<e.length;o+=2){var a=e[o],s=e[o+1];i=UZIP.F._writeLit(a,t,r,i);var f=16==a?2:17==a?3:7;a>15&&(UZIP.F._putsE(r,i,s,f),i+=f);}return i},UZIP.F._lenCodes=function(e,t){for(var r=e.length;2!=r&&0==e[r-1];)r-=2;for(var i=0;i<r;i+=2){var o=e[i+1],a=i+3<r?e[i+3]:-1,s=i+5<r?e[i+5]:-1,f=0==i?-1:e[i-1];if(0==o&&a==o&&s==o){for(var l=i+5;l+2<r&&e[l+2]==o;)l+=2;(c=Math.min(l+1-i>>>1,138))<11?t.push(17,c-3):t.push(18,c-11),i+=2*c-2;}else if(o==f&&a==o&&s==o){for(l=i+5;l+2<r&&e[l+2]==o;)l+=2;var c=Math.min(l+1-i>>>1,6);t.push(16,c-3),i+=2*c-2;}else t.push(o,0);}return r>>>1},UZIP.F._hufTree=function(e,t,r){var i=[],o=e.length,a=t.length,s=0;for(s=0;s<a;s+=2)t[s]=0,t[s+1]=0;for(s=0;s<o;s++)0!=e[s]&&i.push({lit:s,f:e[s]});var f=i.length,l=i.slice(0);if(0==f)return 0;if(1==f){var c=i[0].lit;l=0==c?1:0;return t[1+(c<<1)]=1,t[1+(l<<1)]=1,1}i.sort((function(e,t){return e.f-t.f}));var u=i[0],h=i[1],d=0,A=1,g=2;for(i[0]={lit:-1,f:u.f+h.f,l:u,r:h,d:0};A!=f-1;)u=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],h=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],i[A++]={lit:-1,f:u.f+h.f,l:u,r:h};var p=UZIP.F.setDepth(i[A-1],0);for(p>r&&(UZIP.F.restrictDepth(l,r,p),p=r),s=0;s<f;s++)t[1+(l[s].lit<<1)]=l[s].d;return p},UZIP.F.setDepth=function(e,t){return -1!=e.lit?(e.d=t,t):Math.max(UZIP.F.setDepth(e.l,t+1),UZIP.F.setDepth(e.r,t+1))},UZIP.F.restrictDepth=function(e,t,r){var i=0,o=1<<r-t,a=0;for(e.sort((function(e,t){return t.d==e.d?e.f-t.f:t.d-e.d})),i=0;i<e.length&&e[i].d>t;i++){var s=e[i].d;e[i].d=t,a+=o-(1<<r-s);}for(a>>>=r-t;a>0;){(s=e[i].d)<t?(e[i].d++,a-=1<<t-s-1):i++;}for(;i>=0;i--)e[i].d==t&&a<0&&(e[i].d--,a++);0!=a&&console.log("debt left");},UZIP.F._goodIndex=function(e,t){var r=0;return t[16|r]<=e&&(r|=16),t[8|r]<=e&&(r|=8),t[4|r]<=e&&(r|=4),t[2|r]<=e&&(r|=2),t[1|r]<=e&&(r|=1),r},UZIP.F._writeLit=function(e,t,r,i){return UZIP.F._putsF(r,i,t[e<<1]),i+t[1+(e<<1)]},UZIP.F.inflate=function(e,t){var r=Uint8Array;if(3==e[0]&&0==e[1])return t||new r(0);var i=UZIP.F,o=i._bitsF,a=i._bitsE,s=i._decodeTiny,f=i.makeCodes,l=i.codes2map,c=i._get17,u=i.U,h=null==t;h&&(t=new r(e.length>>>2<<3));for(var d,A,g=0,p=0,m=0,w=0,v=0,b=0,y=0,E=0,F=0;0==g;)if(g=o(e,F,1),p=o(e,F+1,2),F+=3,0!=p){if(h&&(t=UZIP.F._check(t,E+(1<<17))),1==p&&(d=u.flmap,A=u.fdmap,b=511,y=31),2==p){m=a(e,F,5)+257,w=a(e,F+5,5)+1,v=a(e,F+10,4)+4,F+=14;for(var _=0;_<38;_+=2)u.itree[_]=0,u.itree[_+1]=0;var B=1;for(_=0;_<v;_++){var U=a(e,F+3*_,3);u.itree[1+(u.ordr[_]<<1)]=U,U>B&&(B=U);}F+=3*v,f(u.itree,B),l(u.itree,B,u.imap),d=u.lmap,A=u.dmap,F=s(u.imap,(1<<B)-1,m+w,e,F,u.ttree);var C=i._copyOut(u.ttree,0,m,u.ltree);b=(1<<C)-1;var I=i._copyOut(u.ttree,m,w,u.dtree);y=(1<<I)-1,f(u.ltree,C),l(u.ltree,C,d),f(u.dtree,I),l(u.dtree,I,A);}for(;;){var Q=d[c(e,F)&b];F+=15&Q;var M=Q>>>4;if(M>>>8==0)t[E++]=M;else {if(256==M)break;var x=E+M-254;if(M>264){var S=u.ldef[M-257];x=E+(S>>>3)+a(e,F,7&S),F+=7&S;}var R=A[c(e,F)&y];F+=15&R;var T=R>>>4,O=u.ddef[T],P=(O>>>4)+o(e,F,15&O);for(F+=15&O,h&&(t=UZIP.F._check(t,E+(1<<17)));E<x;)t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P];E=x;}}}else {0!=(7&F)&&(F+=8-(7&F));var H=4+(F>>>3),L=e[H-4]|e[H-3]<<8;h&&(t=UZIP.F._check(t,E+L)),t.set(new r(e.buffer,e.byteOffset+H,L),E),F=H+L<<3,E+=L;}return t.length==E?t:t.slice(0,E)},UZIP.F._check=function(e,t){var r=e.length;if(t<=r)return e;var i=new Uint8Array(Math.max(r<<1,t));return i.set(e,0),i},UZIP.F._decodeTiny=function(e,t,r,i,o,a){for(var s=UZIP.F._bitsE,f=UZIP.F._get17,l=0;l<r;){var c=e[f(i,o)&t];o+=15&c;var u=c>>>4;if(u<=15)a[l]=u,l++;else {var h=0,d=0;16==u?(d=3+s(i,o,2),o+=2,h=a[l-1]):17==u?(d=3+s(i,o,3),o+=3):18==u&&(d=11+s(i,o,7),o+=7);for(var A=l+d;l<A;)a[l]=h,l++;}}return o},UZIP.F._copyOut=function(e,t,r,i){for(var o=0,a=0,s=i.length>>>1;a<r;){var f=e[a+t];i[a<<1]=0,i[1+(a<<1)]=f,f>o&&(o=f),a++;}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},UZIP.F.makeCodes=function(e,t){for(var r,i,o,a,s=UZIP.F.U,f=e.length,l=s.bl_count,c=0;c<=t;c++)l[c]=0;for(c=1;c<f;c+=2)l[e[c]]++;var u=s.next_code;for(r=0,l[0]=0,i=1;i<=t;i++)r=r+l[i-1]<<1,u[i]=r;for(o=0;o<f;o+=2)0!=(a=e[o+1])&&(e[o]=u[a],u[a]++);},UZIP.F.codes2map=function(e,t,r){for(var i=e.length,o=UZIP.F.U.rev15,a=0;a<i;a+=2)if(0!=e[a+1])for(var s=a>>1,f=e[a+1],l=s<<4|f,c=t-f,u=e[a]<<c,h=u+(1<<c);u!=h;){r[o[u]>>>15-t]=l,u++;}},UZIP.F.revCodes=function(e,t){for(var r=UZIP.F.U.rev15,i=15-t,o=0;o<e.length;o+=2){var a=e[o]<<t-e[o+1];e[o]=r[a]>>>i;}},UZIP.F._putsE=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8;},UZIP.F._putsF=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16;},UZIP.F._bitsE=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},UZIP.F._bitsF=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},UZIP.F._get17=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},UZIP.F._get25=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},UZIP.F.U=(r=Uint16Array,i=Uint32Array,{next_code:new r(16),bl_count:new r(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new r(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new i(32),flmap:new r(512),fltree:[],fdmap:new r(32),fdtree:[],lmap:new r(32768),ltree:[],ttree:[],dmap:new r(32768),dtree:[],imap:new r(512),itree:[],rev15:new r(32768),lhst:new i(286),dhst:new i(30),ihst:new i(19),lits:new i(15e3),strt:new r(65536),prev:new r(32768)}),function(){for(var e=UZIP.F.U,t=0;t<32768;t++){var r=t;r=(4278255360&(r=(4042322160&(r=(3435973836&(r=(2863311530&r)>>>1|(1431655765&r)<<1))>>>2|(858993459&r)<<2))>>>4|(252645135&r)<<4))>>>8|(16711935&r)<<8,e.rev15[t]=(r>>>16|r<<16)>>>17;}function pushV(e,t,r){for(;0!=t--;)e.push(0,r);}for(t=0;t<32;t++)e.ldef[t]=e.of0[t]<<3|e.exb[t],e.ddef[t]=e.df0[t]<<4|e.dxb[t];pushV(e.fltree,144,8),pushV(e.fltree,112,9),pushV(e.fltree,24,7),pushV(e.fltree,8,8),UZIP.F.makeCodes(e.fltree,9),UZIP.F.codes2map(e.fltree,9,e.flmap),UZIP.F.revCodes(e.fltree,9),pushV(e.fdtree,32,5),UZIP.F.makeCodes(e.fdtree,5),UZIP.F.codes2map(e.fdtree,5,e.fdmap),UZIP.F.revCodes(e.fdtree,5),pushV(e.itree,19,0),pushV(e.ltree,286,0),pushV(e.dtree,30,0),pushV(e.ttree,320,0);}();}();var UZIP=_mergeNamespaces({__proto__:null,default:e},[e]);const UPNG=function(){var e={nextZero(e,t){for(;0!=e[t];)t++;return t},readUshort:(e,t)=>e[t]<<8|e[t+1],writeUshort(e,t,r){e[t]=r>>8&255,e[t+1]=255&r;},readUint:(e,t)=>16777216*e[t]+(e[t+1]<<16|e[t+2]<<8|e[t+3]),writeUint(e,t,r){e[t]=r>>24&255,e[t+1]=r>>16&255,e[t+2]=r>>8&255,e[t+3]=255&r;},readASCII(e,t,r){let i="";for(let o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII(e,t,r){for(let i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i);},readBytes(e,t,r){const i=[];for(let o=0;o<r;o++)i.push(e[t+o]);return i},pad:e=>e.length<2?`0${e}`:e,readUTF8(t,r,i){let o,a="";for(let o=0;o<i;o++)a+=`%${e.pad(t[r+o].toString(16))}`;try{o=decodeURIComponent(a);}catch(o){return e.readASCII(t,r,i)}return o}};function decodeImage(t,r,i,o){const a=r*i,s=_getBPP(o),f=Math.ceil(r*s/8),l=new Uint8Array(4*a),c=new Uint32Array(l.buffer),{ctype:u}=o,{depth:h}=o,d=e.readUshort;if(6==u){const e=a<<2;if(8==h)for(var A=0;A<e;A+=4)l[A]=t[A],l[A+1]=t[A+1],l[A+2]=t[A+2],l[A+3]=t[A+3];if(16==h)for(A=0;A<e;A++)l[A]=t[A<<1];}else if(2==u){const e=o.tabs.tRNS;if(null==e){if(8==h)for(A=0;A<a;A++){var g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g];}if(16==h)for(A=0;A<a;A++){g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g];}}else {var p=e[0];const r=e[1],i=e[2];if(8==h)for(A=0;A<a;A++){var m=A<<2;g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g],t[g]==p&&t[g+1]==r&&t[g+2]==i&&(l[m+3]=0);}if(16==h)for(A=0;A<a;A++){m=A<<2,g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g],d(t,g)==p&&d(t,g+2)==r&&d(t,g+4)==i&&(l[m+3]=0);}}}else if(3==u){const e=o.tabs.PLTE,s=o.tabs.tRNS,c=s?s.length:0;if(1==h)for(var w=0;w<i;w++){var v=w*f,b=w*r;for(A=0;A<r;A++){m=b+A<<2;var y=3*(E=t[v+(A>>3)]>>7-((7&A)<<0)&1);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}}if(2==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>2)]>>6-((3&A)<<1)&3);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}if(4==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>1)]>>4-((1&A)<<2)&15);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}if(8==h)for(A=0;A<a;A++){var E;m=A<<2,y=3*(E=t[A]);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255;}}else if(4==u){if(8==h)for(A=0;A<a;A++){m=A<<2;var F=t[_=A<<1];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+1];}if(16==h)for(A=0;A<a;A++){var _;m=A<<2,F=t[_=A<<2];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+2];}}else if(0==u)for(p=o.tabs.tRNS?o.tabs.tRNS:-1,w=0;w<i;w++){const e=w*f,i=w*r;if(1==h)for(var B=0;B<r;B++){var U=(F=255*(t[e+(B>>>3)]>>>7-(7&B)&1))==255*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(2==h)for(B=0;B<r;B++){U=(F=85*(t[e+(B>>>2)]>>>6-((3&B)<<1)&3))==85*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(4==h)for(B=0;B<r;B++){U=(F=17*(t[e+(B>>>1)]>>>4-((1&B)<<2)&15))==17*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(8==h)for(B=0;B<r;B++){U=(F=t[e+B])==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}else if(16==h)for(B=0;B<r;B++){F=t[e+(B<<1)],U=d(t,e+(B<<1))==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F;}}return l}function _decompress(e,r,i,o){const a=_getBPP(e),s=Math.ceil(i*a/8),f=new Uint8Array((s+1+e.interlace)*o);return r=e.tabs.CgBI?t(r,f):_inflate(r,f),0==e.interlace?r=_filterZero(r,e,0,i,o):1==e.interlace&&(r=function _readInterlace(e,t){const r=t.width,i=t.height,o=_getBPP(t),a=o>>3,s=Math.ceil(r*o/8),f=new Uint8Array(i*s);let l=0;const c=[0,0,4,0,2,0,1],u=[0,4,0,2,0,1,0],h=[8,8,8,4,4,2,2],d=[8,8,4,4,2,2,1];let A=0;for(;A<7;){const p=h[A],m=d[A];let w=0,v=0,b=c[A];for(;b<i;)b+=p,v++;let y=u[A];for(;y<r;)y+=m,w++;const E=Math.ceil(w*o/8);_filterZero(e,t,l,w,v);let F=0,_=c[A];for(;_<i;){let t=u[A],i=l+F*E<<3;for(;t<r;){var g;if(1==o)g=(g=e[i>>3])>>7-(7&i)&1,f[_*s+(t>>3)]|=g<<7-((7&t)<<0);if(2==o)g=(g=e[i>>3])>>6-(7&i)&3,f[_*s+(t>>2)]|=g<<6-((3&t)<<1);if(4==o)g=(g=e[i>>3])>>4-(7&i)&15,f[_*s+(t>>1)]|=g<<4-((1&t)<<2);if(o>=8){const r=_*s+t*a;for(let t=0;t<a;t++)f[r+t]=e[(i>>3)+t];}i+=o,t+=m;}F++,_+=p;}w*v!=0&&(l+=v*(1+E)),A+=1;}return f}(r,e)),r}function _inflate(e,r){return t(new Uint8Array(e.buffer,2,e.length-6),r)}var t=function(){const e={H:{}};return e.H.N=function(t,r){const i=Uint8Array;let o,a,s=0,f=0,l=0,c=0,u=0,h=0,d=0,A=0,g=0;if(3==t[0]&&0==t[1])return r||new i(0);const p=e.H,m=p.b,w=p.e,v=p.R,b=p.n,y=p.A,E=p.Z,F=p.m,_=null==r;for(_&&(r=new i(t.length>>>2<<5));0==s;)if(s=m(t,g,1),f=m(t,g+1,2),g+=3,0!=f){if(_&&(r=e.H.W(r,A+(1<<17))),1==f&&(o=F.J,a=F.h,h=511,d=31),2==f){l=w(t,g,5)+257,c=w(t,g+5,5)+1,u=w(t,g+10,4)+4,g+=14;let e=1;for(var B=0;B<38;B+=2)F.Q[B]=0,F.Q[B+1]=0;for(B=0;B<u;B++){const r=w(t,g+3*B,3);F.Q[1+(F.X[B]<<1)]=r,r>e&&(e=r);}g+=3*u,b(F.Q,e),y(F.Q,e,F.u),o=F.w,a=F.d,g=v(F.u,(1<<e)-1,l+c,t,g,F.v);const r=p.V(F.v,0,l,F.C);h=(1<<r)-1;const i=p.V(F.v,l,c,F.D);d=(1<<i)-1,b(F.C,r),y(F.C,r,o),b(F.D,i),y(F.D,i,a);}for(;;){const e=o[E(t,g)&h];g+=15&e;const i=e>>>4;if(i>>>8==0)r[A++]=i;else {if(256==i)break;{let e=A+i-254;if(i>264){const r=F.q[i-257];e=A+(r>>>3)+w(t,g,7&r),g+=7&r;}const o=a[E(t,g)&d];g+=15&o;const s=o>>>4,f=F.c[s],l=(f>>>4)+m(t,g,15&f);for(g+=15&f;A<e;)r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l];A=e;}}}}else {0!=(7&g)&&(g+=8-(7&g));const o=4+(g>>>3),a=t[o-4]|t[o-3]<<8;_&&(r=e.H.W(r,A+a)),r.set(new i(t.buffer,t.byteOffset+o,a),A),g=o+a<<3,A+=a;}return r.length==A?r:r.slice(0,A)},e.H.W=function(e,t){const r=e.length;if(t<=r)return e;const i=new Uint8Array(r<<1);return i.set(e,0),i},e.H.R=function(t,r,i,o,a,s){const f=e.H.e,l=e.H.Z;let c=0;for(;c<i;){const e=t[l(o,a)&r];a+=15&e;const i=e>>>4;if(i<=15)s[c]=i,c++;else {let e=0,t=0;16==i?(t=3+f(o,a,2),a+=2,e=s[c-1]):17==i?(t=3+f(o,a,3),a+=3):18==i&&(t=11+f(o,a,7),a+=7);const r=c+t;for(;c<r;)s[c]=e,c++;}}return a},e.H.V=function(e,t,r,i){let o=0,a=0;const s=i.length>>>1;for(;a<r;){const r=e[a+t];i[a<<1]=0,i[1+(a<<1)]=r,r>o&&(o=r),a++;}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},e.H.n=function(t,r){const i=e.H.m,o=t.length;let a,s,f;let l;const c=i.j;for(var u=0;u<=r;u++)c[u]=0;for(u=1;u<o;u+=2)c[t[u]]++;const h=i.K;for(a=0,c[0]=0,s=1;s<=r;s++)a=a+c[s-1]<<1,h[s]=a;for(f=0;f<o;f+=2)l=t[f+1],0!=l&&(t[f]=h[l],h[l]++);},e.H.A=function(t,r,i){const o=t.length,a=e.H.m.r;for(let e=0;e<o;e+=2)if(0!=t[e+1]){const o=e>>1,s=t[e+1],f=o<<4|s,l=r-s;let c=t[e]<<l;const u=c+(1<<l);for(;c!=u;){i[a[c]>>>15-r]=f,c++;}}},e.H.l=function(t,r){const i=e.H.m.r,o=15-r;for(let e=0;e<t.length;e+=2){const a=t[e]<<r-t[e+1];t[e]=i[a]>>>o;}},e.H.M=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8;},e.H.I=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16;},e.H.e=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},e.H.b=function(e,t,r){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},e.H.Z=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},e.H.i=function(e,t){return (e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},e.H.m=function(){const e=Uint16Array,t=Uint32Array;return {K:new e(16),j:new e(16),X:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],S:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],T:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],q:new e(32),p:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],z:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],c:new t(32),J:new e(512),_:[],h:new e(32),$:[],w:new e(32768),C:[],v:[],d:new e(32768),D:[],u:new e(512),Q:[],r:new e(32768),s:new t(286),Y:new t(30),a:new t(19),t:new t(15e3),k:new e(65536),g:new e(32768)}}(),function(){const t=e.H.m;for(var r=0;r<32768;r++){let e=r;e=(2863311530&e)>>>1|(1431655765&e)<<1,e=(3435973836&e)>>>2|(858993459&e)<<2,e=(4042322160&e)>>>4|(252645135&e)<<4,e=(4278255360&e)>>>8|(16711935&e)<<8,t.r[r]=(e>>>16|e<<16)>>>17;}function n(e,t,r){for(;0!=t--;)e.push(0,r);}for(r=0;r<32;r++)t.q[r]=t.S[r]<<3|t.T[r],t.c[r]=t.p[r]<<4|t.z[r];n(t._,144,8),n(t._,112,9),n(t._,24,7),n(t._,8,8),e.H.n(t._,9),e.H.A(t._,9,t.J),e.H.l(t._,9),n(t.$,32,5),e.H.n(t.$,5),e.H.A(t.$,5,t.h),e.H.l(t.$,5),n(t.Q,19,0),n(t.C,286,0),n(t.D,30,0),n(t.v,320,0);}(),e.H.N}();function _getBPP(e){return [1,null,3,1,2,null,4][e.ctype]*e.depth}function _filterZero(e,t,r,i,o){let a=_getBPP(t);const s=Math.ceil(i*a/8);let f,l;a=Math.ceil(a/8);let c=e[r],u=0;if(c>1&&(e[r]=[0,0,1][c-2]),3==c)for(u=a;u<s;u++)e[u+1]=e[u+1]+(e[u+1-a]>>>1)&255;for(let t=0;t<o;t++)if(f=r+t*s,l=f+t+1,c=e[l-1],u=0,0==c)for(;u<s;u++)e[f+u]=e[l+u];else if(1==c){for(;u<a;u++)e[f+u]=e[l+u];for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-a];}else if(2==c)for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-s];else if(3==c){for(;u<a;u++)e[f+u]=e[l+u]+(e[f+u-s]>>>1);for(;u<s;u++)e[f+u]=e[l+u]+(e[f+u-s]+e[f+u-a]>>>1);}else {for(;u<a;u++)e[f+u]=e[l+u]+_paeth(0,e[f+u-s],0);for(;u<s;u++)e[f+u]=e[l+u]+_paeth(e[f+u-a],e[f+u-s],e[f+u-a-s]);}return e}function _paeth(e,t,r){const i=e+t-r,o=i-e,a=i-t,s=i-r;return o*o<=a*a&&o*o<=s*s?e:a*a<=s*s?t:r}function _IHDR(t,r,i){i.width=e.readUint(t,r),r+=4,i.height=e.readUint(t,r),r+=4,i.depth=t[r],r++,i.ctype=t[r],r++,i.compress=t[r],r++,i.filter=t[r],r++,i.interlace=t[r],r++;}function _copyTile(e,t,r,i,o,a,s,f,l){const c=Math.min(t,o),u=Math.min(r,a);let h=0,d=0;for(let r=0;r<u;r++)for(let a=0;a<c;a++)if(s>=0&&f>=0?(h=r*t+a<<2,d=(f+r)*o+s+a<<2):(h=(-f+r)*t-s+a<<2,d=r*o+a<<2),0==l)i[d]=e[h],i[d+1]=e[h+1],i[d+2]=e[h+2],i[d+3]=e[h+3];else if(1==l){var A=e[h+3]*(1/255),g=e[h]*A,p=e[h+1]*A,m=e[h+2]*A,w=i[d+3]*(1/255),v=i[d]*w,b=i[d+1]*w,y=i[d+2]*w;const t=1-A,r=A+w*t,o=0==r?0:1/r;i[d+3]=255*r,i[d+0]=(g+v*t)*o,i[d+1]=(p+b*t)*o,i[d+2]=(m+y*t)*o;}else if(2==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];A==w&&g==v&&p==b&&m==y?(i[d]=0,i[d+1]=0,i[d+2]=0,i[d+3]=0):(i[d]=g,i[d+1]=p,i[d+2]=m,i[d+3]=A);}else if(3==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];if(A==w&&g==v&&p==b&&m==y)continue;if(A<220&&w>20)return false}return true}return {decode:function decode(r){const i=new Uint8Array(r);let o=8;const a=e,s=a.readUshort,f=a.readUint,l={tabs:{},frames:[]},c=new Uint8Array(i.length);let u,h=0,d=0;const A=[137,80,78,71,13,10,26,10];for(var g=0;g<8;g++)if(i[g]!=A[g])throw "The input is not a PNG file!";for(;o<i.length;){const e=a.readUint(i,o);o+=4;const r=a.readASCII(i,o,4);if(o+=4,"IHDR"==r)_IHDR(i,o,l);else if("iCCP"==r){for(var p=o;0!=i[p];)p++;a.readASCII(i,o,p-o);const s=i.slice(p+2,o+e);let f=null;try{f=_inflate(s);}catch(e){f=t(s);}l.tabs[r]=f;}else if("CgBI"==r)l.tabs[r]=i.slice(o,o+4);else if("IDAT"==r){for(g=0;g<e;g++)c[h+g]=i[o+g];h+=e;}else if("acTL"==r)l.tabs[r]={num_frames:f(i,o),num_plays:f(i,o+4)},u=new Uint8Array(i.length);else if("fcTL"==r){if(0!=d)(E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height),d=0;const e={x:f(i,o+12),y:f(i,o+16),width:f(i,o+4),height:f(i,o+8)};let t=s(i,o+22);t=s(i,o+20)/(0==t?100:t);const r={rect:e,delay:Math.round(1e3*t),dispose:i[o+24],blend:i[o+25]};l.frames.push(r);}else if("fdAT"==r){for(g=0;g<e-4;g++)u[d+g]=i[o+g+4];d+=e-4;}else if("pHYs"==r)l.tabs[r]=[a.readUint(i,o),a.readUint(i,o+4),i[o+8]];else if("cHRM"==r){l.tabs[r]=[];for(g=0;g<8;g++)l.tabs[r].push(a.readUint(i,o+4*g));}else if("tEXt"==r||"zTXt"==r){null==l.tabs[r]&&(l.tabs[r]={});var m=a.nextZero(i,o),w=a.readASCII(i,o,m-o),v=o+e-m-1;if("tEXt"==r)y=a.readASCII(i,m+1,v);else {var b=_inflate(i.slice(m+2,m+2+v));y=a.readUTF8(b,0,b.length);}l.tabs[r][w]=y;}else if("iTXt"==r){null==l.tabs[r]&&(l.tabs[r]={});m=0,p=o;m=a.nextZero(i,p);w=a.readASCII(i,p,m-p);const t=i[p=m+1];var y;p+=2,m=a.nextZero(i,p),a.readASCII(i,p,m-p),p=m+1,m=a.nextZero(i,p),a.readUTF8(i,p,m-p);v=e-((p=m+1)-o);if(0==t)y=a.readUTF8(i,p,v);else {b=_inflate(i.slice(p,p+v));y=a.readUTF8(b,0,b.length);}l.tabs[r][w]=y;}else if("PLTE"==r)l.tabs[r]=a.readBytes(i,o,e);else if("hIST"==r){const e=l.tabs.PLTE.length/3;l.tabs[r]=[];for(g=0;g<e;g++)l.tabs[r].push(s(i,o+2*g));}else if("tRNS"==r)3==l.ctype?l.tabs[r]=a.readBytes(i,o,e):0==l.ctype?l.tabs[r]=s(i,o):2==l.ctype&&(l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]);else if("gAMA"==r)l.tabs[r]=a.readUint(i,o)/1e5;else if("sRGB"==r)l.tabs[r]=i[o];else if("bKGD"==r)0==l.ctype||4==l.ctype?l.tabs[r]=[s(i,o)]:2==l.ctype||6==l.ctype?l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]:3==l.ctype&&(l.tabs[r]=i[o]);else if("IEND"==r)break;o+=e,a.readUint(i,o),o+=4;}var E;return 0!=d&&((E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height)),l.data=_decompress(l,c,l.width,l.height),delete l.compress,delete l.interlace,delete l.filter,l},toRGBA8:function toRGBA8(e){const t=e.width,r=e.height;if(null==e.tabs.acTL)return [decodeImage(e.data,t,r,e).buffer];const i=[];null==e.frames[0].data&&(e.frames[0].data=e.data);const o=t*r*4,a=new Uint8Array(o),s=new Uint8Array(o),f=new Uint8Array(o);for(let c=0;c<e.frames.length;c++){const u=e.frames[c],h=u.rect.x,d=u.rect.y,A=u.rect.width,g=u.rect.height,p=decodeImage(u.data,A,g,e);if(0!=c)for(var l=0;l<o;l++)f[l]=a[l];if(0==u.blend?_copyTile(p,A,g,a,t,r,h,d,0):1==u.blend&&_copyTile(p,A,g,a,t,r,h,d,1),i.push(a.buffer.slice(0)),0==u.dispose);else if(1==u.dispose)_copyTile(s,A,g,a,t,r,h,d,0);else if(2==u.dispose)for(l=0;l<o;l++)a[l]=f[l];}return i},_paeth:_paeth,_copyTile:_copyTile,_bin:e}}();!function(){const{_copyTile:e}=UPNG,{_bin:t}=UPNG,r=UPNG._paeth;var i={table:function(){const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r;}return e}(),update(e,t,r,o){for(let a=0;a<o;a++)e=i.table[255&(e^t[r+a])]^e>>>8;return e},crc:(e,t,r)=>4294967295^i.update(4294967295,e,t,r)};function addErr(e,t,r,i){t[r]+=e[0]*i>>4,t[r+1]+=e[1]*i>>4,t[r+2]+=e[2]*i>>4,t[r+3]+=e[3]*i>>4;}function N(e){return Math.max(0,Math.min(255,e))}function D(e,t){const r=e[0]-t[0],i=e[1]-t[1],o=e[2]-t[2],a=e[3]-t[3];return r*r+i*i+o*o+a*a}function dither(e,t,r,i,o,a,s){null==s&&(s=1);const f=i.length,l=[];for(var c=0;c<f;c++){const e=i[c];l.push([e>>>0&255,e>>>8&255,e>>>16&255,e>>>24&255]);}for(c=0;c<f;c++){let e=4294967295;for(var u=0,h=0;h<f;h++){var d=D(l[c],l[h]);h!=c&&d<e&&(e=d,u=h);}}const A=new Uint32Array(o.buffer),g=new Int16Array(t*r*4),p=[0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5];for(c=0;c<p.length;c++)p[c]=255*((p[c]+.5)/16-.5);for(let o=0;o<r;o++)for(let w=0;w<t;w++){var m;c=4*(o*t+w);if(2!=s)m=[N(e[c]+g[c]),N(e[c+1]+g[c+1]),N(e[c+2]+g[c+2]),N(e[c+3]+g[c+3])];else {d=p[4*(3&o)+(3&w)];m=[N(e[c]+d),N(e[c+1]+d),N(e[c+2]+d),N(e[c+3]+d)];}u=0;let v=16777215;for(h=0;h<f;h++){const e=D(m,l[h]);e<v&&(v=e,u=h);}const b=l[u],y=[m[0]-b[0],m[1]-b[1],m[2]-b[2],m[3]-b[3]];1==s&&(w!=t-1&&addErr(y,g,c+4,7),o!=r-1&&(0!=w&&addErr(y,g,c+4*t-4,3),addErr(y,g,c+4*t,5),w!=t-1&&addErr(y,g,c+4*t+4,1))),a[c>>2]=u,A[c>>2]=i[u];}}function _main(e,r,o,a,s){null==s&&(s={});const{crc:f}=i,l=t.writeUint,c=t.writeUshort,u=t.writeASCII;let h=8;const d=e.frames.length>1;let A,g=false,p=33+(d?20:0);if(null!=s.sRGB&&(p+=13),null!=s.pHYs&&(p+=21),null!=s.iCCP&&(A=pako.deflate(s.iCCP),p+=21+A.length+4),3==e.ctype){for(var m=e.plte.length,w=0;w<m;w++)e.plte[w]>>>24!=255&&(g=true);p+=8+3*m+4+(g?8+1*m+4:0);}for(var v=0;v<e.frames.length;v++){d&&(p+=38),p+=(F=e.frames[v]).cimg.length+12,0!=v&&(p+=4);}p+=12;const b=new Uint8Array(p),y=[137,80,78,71,13,10,26,10];for(w=0;w<8;w++)b[w]=y[w];if(l(b,h,13),h+=4,u(b,h,"IHDR"),h+=4,l(b,h,r),h+=4,l(b,h,o),h+=4,b[h]=e.depth,h++,b[h]=e.ctype,h++,b[h]=0,h++,b[h]=0,h++,b[h]=0,h++,l(b,h,f(b,h-17,17)),h+=4,null!=s.sRGB&&(l(b,h,1),h+=4,u(b,h,"sRGB"),h+=4,b[h]=s.sRGB,h++,l(b,h,f(b,h-5,5)),h+=4),null!=s.iCCP){const e=13+A.length;l(b,h,e),h+=4,u(b,h,"iCCP"),h+=4,u(b,h,"ICC profile"),h+=11,h+=2,b.set(A,h),h+=A.length,l(b,h,f(b,h-(e+4),e+4)),h+=4;}if(null!=s.pHYs&&(l(b,h,9),h+=4,u(b,h,"pHYs"),h+=4,l(b,h,s.pHYs[0]),h+=4,l(b,h,s.pHYs[1]),h+=4,b[h]=s.pHYs[2],h++,l(b,h,f(b,h-13,13)),h+=4),d&&(l(b,h,8),h+=4,u(b,h,"acTL"),h+=4,l(b,h,e.frames.length),h+=4,l(b,h,null!=s.loop?s.loop:0),h+=4,l(b,h,f(b,h-12,12)),h+=4),3==e.ctype){l(b,h,3*(m=e.plte.length)),h+=4,u(b,h,"PLTE"),h+=4;for(w=0;w<m;w++){const t=3*w,r=e.plte[w],i=255&r,o=r>>>8&255,a=r>>>16&255;b[h+t+0]=i,b[h+t+1]=o,b[h+t+2]=a;}if(h+=3*m,l(b,h,f(b,h-3*m-4,3*m+4)),h+=4,g){l(b,h,m),h+=4,u(b,h,"tRNS"),h+=4;for(w=0;w<m;w++)b[h+w]=e.plte[w]>>>24&255;h+=m,l(b,h,f(b,h-m-4,m+4)),h+=4;}}let E=0;for(v=0;v<e.frames.length;v++){var F=e.frames[v];d&&(l(b,h,26),h+=4,u(b,h,"fcTL"),h+=4,l(b,h,E++),h+=4,l(b,h,F.rect.width),h+=4,l(b,h,F.rect.height),h+=4,l(b,h,F.rect.x),h+=4,l(b,h,F.rect.y),h+=4,c(b,h,a[v]),h+=2,c(b,h,1e3),h+=2,b[h]=F.dispose,h++,b[h]=F.blend,h++,l(b,h,f(b,h-30,30)),h+=4);const t=F.cimg;l(b,h,(m=t.length)+(0==v?0:4)),h+=4;const r=h;u(b,h,0==v?"IDAT":"fdAT"),h+=4,0!=v&&(l(b,h,E++),h+=4),b.set(t,h),h+=m,l(b,h,f(b,r,h-r)),h+=4;}return l(b,h,0),h+=4,u(b,h,"IEND"),h+=4,l(b,h,f(b,h-4,4)),h+=4,b.buffer}function compressPNG(e,t,r){for(let i=0;i<e.frames.length;i++){const o=e.frames[i];const a=o.rect.height,s=new Uint8Array(a*o.bpl+a);o.cimg=_filterZero(o.img,a,o.bpp,o.bpl,s,t,r);}}function compress(t,r,i,o,a){const s=a[0],f=a[1],l=a[2],c=a[3],u=a[4],h=a[5];let d=6,A=8,g=255;for(var p=0;p<t.length;p++){const e=new Uint8Array(t[p]);for(var m=e.length,w=0;w<m;w+=4)g&=e[w+3];}const v=255!=g,b=function framize(t,r,i,o,a,s){const f=[];for(var l=0;l<t.length;l++){const h=new Uint8Array(t[l]),A=new Uint32Array(h.buffer);var c;let g=0,p=0,m=r,w=i,v=o?1:0;if(0!=l){const b=s||o||1==l||0!=f[l-2].dispose?1:2;let y=0,E=1e9;for(let e=0;e<b;e++){var u=new Uint8Array(t[l-1-e]);const o=new Uint32Array(t[l-1-e]);let s=r,f=i,c=-1,h=-1;for(let e=0;e<i;e++)for(let t=0;t<r;t++){A[d=e*r+t]!=o[d]&&(t<s&&(s=t),t>c&&(c=t),e<f&&(f=e),e>h&&(h=e));} -1==c&&(s=f=c=h=0),a&&(1==(1&s)&&s--,1==(1&f)&&f--);const v=(c-s+1)*(h-f+1);v<E&&(E=v,y=e,g=s,p=f,m=c-s+1,w=h-f+1);}u=new Uint8Array(t[l-1-y]);1==y&&(f[l-1].dispose=2),c=new Uint8Array(m*w*4),e(u,r,i,c,m,w,-g,-p,0),v=e(h,r,i,c,m,w,-g,-p,3)?1:0,1==v?_prepareDiff(h,r,i,c,{x:g,y:p,width:m,height:w}):e(h,r,i,c,m,w,-g,-p,0);}else c=h.slice(0);f.push({rect:{x:g,y:p,width:m,height:w},img:c,blend:v,dispose:0});}if(o)for(l=0;l<f.length;l++){if(1==(A=f[l]).blend)continue;const e=A.rect,o=f[l-1].rect,s=Math.min(e.x,o.x),c=Math.min(e.y,o.y),u={x:s,y:c,width:Math.max(e.x+e.width,o.x+o.width)-s,height:Math.max(e.y+e.height,o.y+o.height)-c};f[l-1].dispose=1,l-1!=0&&_updateFrame(t,r,i,f,l-1,u,a),_updateFrame(t,r,i,f,l,u,a);}let h=0;if(1!=t.length)for(var d=0;d<f.length;d++){var A;h+=(A=f[d]).rect.width*A.rect.height;}return f}(t,r,i,s,f,l),y={},E=[],F=[];if(0!=o){const e=[];for(w=0;w<b.length;w++)e.push(b[w].img.buffer);const t=function concatRGBA(e){let t=0;for(var r=0;r<e.length;r++)t+=e[r].byteLength;const i=new Uint8Array(t);let o=0;for(r=0;r<e.length;r++){const t=new Uint8Array(e[r]),a=t.length;for(let e=0;e<a;e+=4){let r=t[e],a=t[e+1],s=t[e+2];const f=t[e+3];0==f&&(r=a=s=0),i[o+e]=r,i[o+e+1]=a,i[o+e+2]=s,i[o+e+3]=f;}o+=a;}return i.buffer}(e),r=quantize(t,o);for(w=0;w<r.plte.length;w++)E.push(r.plte[w].est.rgba);let i=0;for(w=0;w<b.length;w++){const e=(B=b[w]).img.length;var _=new Uint8Array(r.inds.buffer,i>>2,e>>2);F.push(_);const t=new Uint8Array(r.abuf,i,e);h&&dither(B.img,B.rect.width,B.rect.height,E,t,_),B.img.set(t),i+=e;}}else for(p=0;p<b.length;p++){var B=b[p];const e=new Uint32Array(B.img.buffer);var U=B.rect.width;m=e.length,_=new Uint8Array(m);F.push(_);for(w=0;w<m;w++){const t=e[w];if(0!=w&&t==e[w-1])_[w]=_[w-1];else if(w>U&&t==e[w-U])_[w]=_[w-U];else {let e=y[t];if(null==e&&(y[t]=e=E.length,E.push(t),E.length>=300))break;_[w]=e;}}}const C=E.length;C<=256&&0==u&&(A=C<=2?1:C<=4?2:C<=16?4:8,A=Math.max(A,c));for(p=0;p<b.length;p++){(B=b[p]).rect.x;U=B.rect.width;const e=B.rect.height;let t=B.img;let r=4*U,i=4;if(C<=256&&0==u){r=Math.ceil(A*U/8);var I=new Uint8Array(r*e);const o=F[p];for(let t=0;t<e;t++){w=t*r;const e=t*U;if(8==A)for(var Q=0;Q<U;Q++)I[w+Q]=o[e+Q];else if(4==A)for(Q=0;Q<U;Q++)I[w+(Q>>1)]|=o[e+Q]<<4-4*(1&Q);else if(2==A)for(Q=0;Q<U;Q++)I[w+(Q>>2)]|=o[e+Q]<<6-2*(3&Q);else if(1==A)for(Q=0;Q<U;Q++)I[w+(Q>>3)]|=o[e+Q]<<7-1*(7&Q);}t=I,d=3,i=1;}else if(0==v&&1==b.length){I=new Uint8Array(U*e*3);const o=U*e;for(w=0;w<o;w++){const e=3*w,r=4*w;I[e]=t[r],I[e+1]=t[r+1],I[e+2]=t[r+2];}t=I,d=2,i=3,r=3*U;}B.img=t,B.bpl=r,B.bpp=i;}return {ctype:d,depth:A,plte:E,frames:b}}function _updateFrame(t,r,i,o,a,s,f){const l=Uint8Array,c=Uint32Array,u=new l(t[a-1]),h=new c(t[a-1]),d=a+1<t.length?new l(t[a+1]):null,A=new l(t[a]),g=new c(A.buffer);let p=r,m=i,w=-1,v=-1;for(let e=0;e<s.height;e++)for(let t=0;t<s.width;t++){const i=s.x+t,f=s.y+e,l=f*r+i,c=g[l];0==c||0==o[a-1].dispose&&h[l]==c&&(null==d||0!=d[4*l+3])||(i<p&&(p=i),i>w&&(w=i),f<m&&(m=f),f>v&&(v=f));} -1==w&&(p=m=w=v=0),f&&(1==(1&p)&&p--,1==(1&m)&&m--),s={x:p,y:m,width:w-p+1,height:v-m+1};const b=o[a];b.rect=s,b.blend=1,b.img=new Uint8Array(s.width*s.height*4),0==o[a-1].dispose?(e(u,r,i,b.img,s.width,s.height,-s.x,-s.y,0),_prepareDiff(A,r,i,b.img,s)):e(A,r,i,b.img,s.width,s.height,-s.x,-s.y,0);}function _prepareDiff(t,r,i,o,a){e(t,r,i,o,a.width,a.height,-a.x,-a.y,2);}function _filterZero(e,t,r,i,o,a,s){const f=[];let l,c=[0,1,2,3,4];-1!=a?c=[a]:(t*i>5e5||1==r)&&(c=[0]),s&&(l={level:0});const u=UZIP;for(var h=0;h<c.length;h++){for(let a=0;a<t;a++)_filterLine(o,e,a,i,r,c[h]);f.push(u.deflate(o,l));}let d,A=1e9;for(h=0;h<f.length;h++)f[h].length<A&&(d=h,A=f[h].length);return f[d]}function _filterLine(e,t,i,o,a,s){const f=i*o;let l=f+i;if(e[l]=s,l++,0==s)if(o<500)for(var c=0;c<o;c++)e[l+c]=t[f+c];else e.set(new Uint8Array(t.buffer,f,o),l);else if(1==s){for(c=0;c<a;c++)e[l+c]=t[f+c];for(c=a;c<o;c++)e[l+c]=t[f+c]-t[f+c-a]+256&255;}else if(0==i){for(c=0;c<a;c++)e[l+c]=t[f+c];if(2==s)for(c=a;c<o;c++)e[l+c]=t[f+c];if(3==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-(t[f+c-a]>>1)+256&255;if(4==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-r(t[f+c-a],0,0)+256&255;}else {if(2==s)for(c=0;c<o;c++)e[l+c]=t[f+c]+256-t[f+c-o]&255;if(3==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-(t[f+c-o]>>1)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-(t[f+c-o]+t[f+c-a]>>1)&255;}if(4==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-r(0,t[f+c-o],0)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-r(t[f+c-a],t[f+c-o],t[f+c-a-o])&255;}}}function quantize(e,t){const r=new Uint8Array(e),i=r.slice(0),o=new Uint32Array(i.buffer),a=getKDtree(i,t),s=a[0],f=a[1],l=r.length,c=new Uint8Array(l>>2);let u;if(r.length<2e7)for(var h=0;h<l;h+=4){u=getNearest(s,d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255)),c[h>>2]=u.ind,o[h>>2]=u.est.rgba;}else for(h=0;h<l;h+=4){var d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255);for(u=s;u.left;)u=planeDst(u.est,d,A,g,p)<=0?u.left:u.right;c[h>>2]=u.ind,o[h>>2]=u.est.rgba;}return {abuf:i.buffer,inds:c,plte:f}}function getKDtree(e,t,r){null==r&&(r=1e-4);const i=new Uint32Array(e.buffer),o={i0:0,i1:e.length,bst:null,est:null,tdst:0,left:null,right:null};o.bst=stats(e,o.i0,o.i1),o.est=estats(o.bst);const a=[o];for(;a.length<t;){let t=0,o=0;for(var s=0;s<a.length;s++)a[s].est.L>t&&(t=a[s].est.L,o=s);if(t<r)break;const f=a[o],l=splitPixels(e,i,f.i0,f.i1,f.est.e,f.est.eMq255);if(f.i0>=l||f.i1<=l){f.est.L=0;continue}const c={i0:f.i0,i1:l,bst:null,est:null,tdst:0,left:null,right:null};c.bst=stats(e,c.i0,c.i1),c.est=estats(c.bst);const u={i0:l,i1:f.i1,bst:null,est:null,tdst:0,left:null,right:null};u.bst={R:[],m:[],N:f.bst.N-c.bst.N};for(s=0;s<16;s++)u.bst.R[s]=f.bst.R[s]-c.bst.R[s];for(s=0;s<4;s++)u.bst.m[s]=f.bst.m[s]-c.bst.m[s];u.est=estats(u.bst),f.left=c,f.right=u,a[o]=c,a.push(u);}a.sort(((e,t)=>t.bst.N-e.bst.N));for(s=0;s<a.length;s++)a[s].ind=s;return [o,a]}function getNearest(e,t,r,i,o){if(null==e.left)return e.tdst=function dist(e,t,r,i,o){const a=t-e[0],s=r-e[1],f=i-e[2],l=o-e[3];return a*a+s*s+f*f+l*l}(e.est.q,t,r,i,o),e;const a=planeDst(e.est,t,r,i,o);let s=e.left,f=e.right;a>0&&(s=e.right,f=e.left);const l=getNearest(s,t,r,i,o);if(l.tdst<=a*a)return l;const c=getNearest(f,t,r,i,o);return c.tdst<l.tdst?c:l}function planeDst(e,t,r,i,o){const{e:a}=e;return a[0]*t+a[1]*r+a[2]*i+a[3]*o-e.eMq}function splitPixels(e,t,r,i,o,a){for(i-=4;r<i;){for(;vecDot(e,r,o)<=a;)r+=4;for(;vecDot(e,i,o)>a;)i-=4;if(r>=i)break;const s=t[r>>2];t[r>>2]=t[i>>2],t[i>>2]=s,r+=4,i-=4;}for(;vecDot(e,r,o)>a;)r-=4;return r+4}function vecDot(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]+e[t+3]*r[3]}function stats(e,t,r){const i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],o=[0,0,0,0],a=r-t>>2;for(let a=t;a<r;a+=4){const t=e[a]*(1/255),r=e[a+1]*(1/255),s=e[a+2]*(1/255),f=e[a+3]*(1/255);o[0]+=t,o[1]+=r,o[2]+=s,o[3]+=f,i[0]+=t*t,i[1]+=t*r,i[2]+=t*s,i[3]+=t*f,i[5]+=r*r,i[6]+=r*s,i[7]+=r*f,i[10]+=s*s,i[11]+=s*f,i[15]+=f*f;}return i[4]=i[1],i[8]=i[2],i[9]=i[6],i[12]=i[3],i[13]=i[7],i[14]=i[11],{R:i,m:o,N:a}}function estats(e){const{R:t}=e,{m:r}=e,{N:i}=e,a=r[0],s=r[1],f=r[2],l=r[3],c=0==i?0:1/i,u=[t[0]-a*a*c,t[1]-a*s*c,t[2]-a*f*c,t[3]-a*l*c,t[4]-s*a*c,t[5]-s*s*c,t[6]-s*f*c,t[7]-s*l*c,t[8]-f*a*c,t[9]-f*s*c,t[10]-f*f*c,t[11]-f*l*c,t[12]-l*a*c,t[13]-l*s*c,t[14]-l*f*c,t[15]-l*l*c],h=u,d=o;let A=[Math.random(),Math.random(),Math.random(),Math.random()],g=0,p=0;if(0!=i)for(let e=0;e<16&&(A=d.multVec(h,A),p=Math.sqrt(d.dot(A,A)),A=d.sml(1/p,A),!(0!=e&&Math.abs(p-g)<1e-9));e++)g=p;const m=[a*c,s*c,f*c,l*c];return {Cov:u,q:m,e:A,L:g,eMq255:d.dot(d.sml(255,m),A),eMq:d.dot(A,m),rgba:(Math.round(255*m[3])<<24|Math.round(255*m[2])<<16|Math.round(255*m[1])<<8|Math.round(255*m[0])<<0)>>>0}}var o={multVec:(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7]*t[3],e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11]*t[3],e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]*t[3]],dot:(e,t)=>e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],sml:(e,t)=>[e*t[0],e*t[1],e*t[2],e*t[3]]};UPNG.encode=function encode(e,t,r,i,o,a,s){null==i&&(i=0),null==s&&(s=false);const f=compress(e,t,r,i,[false,false,false,0,s,false]);return compressPNG(f,-1),_main(f,t,r,o,a)},UPNG.encodeLL=function encodeLL(e,t,r,i,o,a,s,f){const l={ctype:0+(1==i?0:2)+(0==o?0:4),depth:a,frames:[]},c=(i+o)*a,u=c*t;for(let i=0;i<e.length;i++)l.frames.push({rect:{x:0,y:0,width:t,height:r},img:new Uint8Array(e[i]),blend:0,dispose:1,bpp:Math.ceil(c/8),bpl:Math.ceil(u/8)});return compressPNG(l,0,true),_main(l,t,r,s,f)},UPNG.encode.compress=compress,UPNG.encode.dither=dither,UPNG.quantize=quantize,UPNG.quantize.getKDtree=getKDtree,UPNG.quantize.getNearest=getNearest;}();const r={toArrayBuffer(e,t){const i=e.width,o=e.height,a=i<<2,s=e.getContext("2d").getImageData(0,0,i,o),f=new Uint32Array(s.data.buffer),l=(32*i+31)/32<<2,c=l*o,u=122+c,h=new ArrayBuffer(u),d=new DataView(h),A=1<<20;let g,p,m,w,v=A,b=0,y=0,E=0;function set16(e){d.setUint16(y,e,true),y+=2;}function set32(e){d.setUint32(y,e,true),y+=4;}function seek(e){y+=e;}set16(19778),set32(u),seek(4),set32(122),set32(108),set32(i),set32(-o>>>0),set16(1),set16(32),set32(3),set32(c),set32(2835),set32(2835),seek(8),set32(16711680),set32(65280),set32(255),set32(4278190080),set32(1466527264),function convert(){for(;b<o&&v>0;){for(w=122+b*l,g=0;g<a;)v--,p=f[E++],m=p>>>24,d.setUint32(w+g,p<<8|m),g+=4;b++;}E<f.length?(v=A,setTimeout(convert,r._dly)):t(h);}();},toBlob(e,t){this.toArrayBuffer(e,(e=>{t(new Blob([e],{type:"image/bmp"}));}));},_dly:9};var i={CHROME:"CHROME",FIREFOX:"FIREFOX",DESKTOP_SAFARI:"DESKTOP_SAFARI",IE:"IE",IOS:"IOS",ETC:"ETC"},o={[i.CHROME]:16384,[i.FIREFOX]:11180,[i.DESKTOP_SAFARI]:16384,[i.IE]:8192,[i.IOS]:4096,[i.ETC]:8192};const a="undefined"!=typeof window,s="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,f=a&&window.cordova&&window.cordova.require&&window.cordova.require("cordova/modulemapper"),CustomFile=(a||s)&&(f&&f.getOriginalSymbol(window,"File")||"undefined"!=typeof File&&File),CustomFileReader=(a||s)&&(f&&f.getOriginalSymbol(window,"FileReader")||"undefined"!=typeof FileReader&&FileReader);function getFilefromDataUrl(e,t,r=Date.now()){return new Promise((i=>{const o=e.split(","),a=o[0].match(/:(.*?);/)[1],s=globalThis.atob(o[1]);let f=s.length;const l=new Uint8Array(f);for(;f--;)l[f]=s.charCodeAt(f);const c=new Blob([l],{type:a});c.name=t,c.lastModified=r,i(c);}))}function getDataUrlFromFile(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=()=>t(i.result),i.onerror=e=>r(e),i.readAsDataURL(e);}))}function loadImage(e){return new Promise(((t,r)=>{const i=new Image;i.onload=()=>t(i),i.onerror=e=>r(e),i.src=e;}))}function getBrowserName(){if(void 0!==getBrowserName.cachedResult)return getBrowserName.cachedResult;let e=i.ETC;const{userAgent:t}=navigator;return /Chrom(e|ium)/i.test(t)?e=i.CHROME:/iP(ad|od|hone)/i.test(t)&&/WebKit/i.test(t)?e=i.IOS:/Safari/i.test(t)?e=i.DESKTOP_SAFARI:/Firefox/i.test(t)?e=i.FIREFOX:(/MSIE/i.test(t)||true==!!document.documentMode)&&(e=i.IE),getBrowserName.cachedResult=e,getBrowserName.cachedResult}function approximateBelowMaximumCanvasSizeOfBrowser(e,t){const r=getBrowserName(),i=o[r];let a=e,s=t,f=a*s;const l=a>s?s/a:a/s;for(;f>i*i;){const e=(i+a)/2,t=(i+s)/2;e<t?(s=t,a=t*l):(s=e*l,a=e),f=a*s;}return {width:a,height:s}}function getNewCanvasAndCtx(e,t){let r,i;try{if(r=new OffscreenCanvas(e,t),i=r.getContext("2d"),null===i)throw new Error("getContext of OffscreenCanvas returns null")}catch(e){r=document.createElement("canvas"),i=r.getContext("2d");}return r.width=e,r.height=t,[r,i]}function drawImageInCanvas(e,t){const{width:r,height:i}=approximateBelowMaximumCanvasSizeOfBrowser(e.width,e.height),[o,a]=getNewCanvasAndCtx(r,i);return t&&/jpe?g/.test(t)&&(a.fillStyle="white",a.fillRect(0,0,o.width,o.height)),a.drawImage(e,0,0,o.width,o.height),o}function isIOS(){return void 0!==isIOS.cachedResult||(isIOS.cachedResult=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"undefined"!=typeof document&&"ontouchend"in document),isIOS.cachedResult}function drawFileInCanvas(e,t={}){return new Promise((function(r,o){let a,s;var $Try_2_Post=function(){try{return s=drawImageInCanvas(a,t.fileType||e.type),r([a,s])}catch(e){return o(e)}},$Try_2_Catch=function(t){try{var $Try_3_Catch=function(e){try{throw e}catch(e){return o(e)}};try{let t;return getDataUrlFromFile(e).then((function(e){try{return t=e,loadImage(t).then((function(e){try{return a=e,function(){try{return $Try_2_Post()}catch(e){return o(e)}}()}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){$Try_3_Catch(e);}}catch(e){return o(e)}};try{if(isIOS()||[i.DESKTOP_SAFARI,i.MOBILE_SAFARI].includes(getBrowserName()))throw new Error("Skip createImageBitmap on IOS and Safari");return createImageBitmap(e).then((function(e){try{return a=e,$Try_2_Post()}catch(e){return $Try_2_Catch()}}),$Try_2_Catch)}catch(e){$Try_2_Catch();}}))}function canvasToFile(e,t,i,o,a=1){return new Promise((function(s,f){let l;if("image/png"===t){let c,u,h;return c=e.getContext("2d"),({data:u}=c.getImageData(0,0,e.width,e.height)),h=UPNG.encode([u.buffer],e.width,e.height,4096*a),l=new Blob([h],{type:t}),l.name=i,l.lastModified=o,$If_4.call(this)}{if("image/bmp"===t)return new Promise((t=>r.toBlob(e,t))).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_5.call(this)}catch(e){return f(e)}}.bind(this),f);{if("function"==typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return e.convertToBlob({type:t,quality:a}).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f);{let d;return d=e.toDataURL(t,a),getFilefromDataUrl(d,i,o).then(function(e){try{return l=e,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f)}function $If_6(){return $If_5.call(this)}}function $If_5(){return $If_4.call(this)}}function $If_4(){return s(l)}}))}function cleanupCanvasMemory(e){e.width=0,e.height=0;}function isAutoOrientationInBrowser(){return new Promise((function(e,t){let i,o,a,s;return void 0!==isAutoOrientationInBrowser.cachedResult?e(isAutoOrientationInBrowser.cachedResult):(getFilefromDataUrl("data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==","test.jpg",Date.now()).then((function(r){try{return i=r,drawFileInCanvas(i).then((function(r){try{return o=r[1],canvasToFile(o,i.type,i.name,i.lastModified).then((function(r){try{return a=r,cleanupCanvasMemory(o),drawFileInCanvas(a).then((function(r){try{return s=r[0],isAutoOrientationInBrowser.cachedResult=1===s.width&&2===s.height,e(isAutoOrientationInBrowser.cachedResult)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t))}))}function getExifOrientation(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=e=>{const r=new DataView(e.target.result);if(65496!=r.getUint16(0,false))return t(-2);const i=r.byteLength;let o=2;for(;o<i;){if(r.getUint16(o+2,false)<=8)return t(-1);const e=r.getUint16(o,false);if(o+=2,65505==e){if(1165519206!=r.getUint32(o+=2,false))return t(-1);const e=18761==r.getUint16(o+=6,false);o+=r.getUint32(o+4,e);const i=r.getUint16(o,e);o+=2;for(let a=0;a<i;a++)if(274==r.getUint16(o+12*a,e))return t(r.getUint16(o+12*a+8,e))}else {if(65280!=(65280&e))break;o+=r.getUint16(o,false);}}return t(-1)},i.onerror=e=>r(e),i.readAsArrayBuffer(e);}))}function handleMaxWidthOrHeight(e,t){const{width:r}=e,{height:i}=e,{maxWidthOrHeight:o}=t;let a,s=e;return isFinite(o)&&(r>o||i>o)&&([s,a]=getNewCanvasAndCtx(r,i),r>i?(s.width=o,s.height=i/r*o):(s.width=r/i*o,s.height=o),a.drawImage(e,0,0,s.width,s.height),cleanupCanvasMemory(e)),s}function followExifOrientation(e,t){const{width:r}=e,{height:i}=e,[o,a]=getNewCanvasAndCtx(r,i);switch(t>4&&t<9?(o.width=i,o.height=r):(o.width=r,o.height=i),t){case 2:a.transform(-1,0,0,1,r,0);break;case 3:a.transform(-1,0,0,-1,r,i);break;case 4:a.transform(1,0,0,-1,0,i);break;case 5:a.transform(0,1,1,0,0,0);break;case 6:a.transform(0,1,-1,0,i,0);break;case 7:a.transform(0,-1,-1,0,i,r);break;case 8:a.transform(0,-1,1,0,0,r);}return a.drawImage(e,0,0,r,i),cleanupCanvasMemory(e),o}function compress(e,t,r=0){return new Promise((function(i,o){let a,s,f,l,c,u,h,d,A,g,p,m,w,v,b,y,E,F,_,B;function incProgress(e=5){if(t.signal&&t.signal.aborted)throw t.signal.reason;a+=e,t.onProgress(Math.min(a,100));}function setProgress(e){if(t.signal&&t.signal.aborted)throw t.signal.reason;a=Math.min(Math.max(e,a),100),t.onProgress(a);}return a=r,s=t.maxIteration||10,f=1024*t.maxSizeMB*1024,incProgress(),drawFileInCanvas(e,t).then(function(r){try{return [,l]=r,incProgress(),c=handleMaxWidthOrHeight(l,t),incProgress(),new Promise((function(r,i){var o;if(!(o=t.exifOrientation))return getExifOrientation(e).then(function(e){try{return o=e,$If_2.call(this)}catch(e){return i(e)}}.bind(this),i);function $If_2(){return r(o)}return $If_2.call(this)})).then(function(r){try{return u=r,incProgress(),isAutoOrientationInBrowser().then(function(r){try{return h=r?c:followExifOrientation(c,u),incProgress(),d=t.initialQuality||1,A=t.fileType||e.type,canvasToFile(h,A,e.name,e.lastModified,d).then(function(r){try{{if(g=r,incProgress(),p=g.size>f,m=g.size>e.size,!p&&!m)return setProgress(100),i(g);var a;function $Loop_3(){if(s--&&(b>f||b>w)){let t,r;return t=B?.95*_.width:_.width,r=B?.95*_.height:_.height,[E,F]=getNewCanvasAndCtx(t,r),F.drawImage(_,0,0,t,r),d*="image/png"===A?.85:.95,canvasToFile(E,A,e.name,e.lastModified,d).then((function(e){try{return y=e,cleanupCanvasMemory(_),_=E,b=y.size,setProgress(Math.min(99,Math.floor((v-b)/(v-f)*100))),$Loop_3}catch(e){return o(e)}}),o)}return [1]}return w=e.size,v=g.size,b=v,_=h,B=!t.alwaysKeepResolution&&p,(a=function(e){for(;e;){if(e.then)return void e.then(a,o);try{if(e.pop){if(e.length)return e.pop()?$Loop_3_exit.call(this):e;e=$Loop_3;}else e=e.call(this);}catch(e){return o(e)}}}.bind(this))($Loop_3);function $Loop_3_exit(){return cleanupCanvasMemory(_),cleanupCanvasMemory(E),cleanupCanvasMemory(c),cleanupCanvasMemory(h),cleanupCanvasMemory(l),setProgress(100),i(y)}}}catch(u){return o(u)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}))}const l="\nlet scriptImported = false\nself.addEventListener('message', async (e) => {\n const { file, id, imageCompressionLibUrl, options } = e.data\n options.onProgress = (progress) => self.postMessage({ progress, id })\n try {\n if (!scriptImported) {\n // console.log('[worker] importScripts', imageCompressionLibUrl)\n self.importScripts(imageCompressionLibUrl)\n scriptImported = true\n }\n // console.log('[worker] self', self)\n const compressedFile = await imageCompression(file, options)\n self.postMessage({ file: compressedFile, id })\n } catch (e) {\n // console.error('[worker] error', e)\n self.postMessage({ error: e.message + '\\n' + e.stack, id })\n }\n})\n";let c;function compressOnWebWorker(e,t){return new Promise(((r,i)=>{c||(c=function createWorkerScriptURL(e){const t=[];return t.push(e),URL.createObjectURL(new Blob(t))}(l));const o=new Worker(c);o.addEventListener("message",(function handler(e){if(t.signal&&t.signal.aborted)o.terminate();else if(void 0===e.data.progress){if(e.data.error)return i(new Error(e.data.error)),void o.terminate();r(e.data.file),o.terminate();}else t.onProgress(e.data.progress);})),o.addEventListener("error",i),t.signal&&t.signal.addEventListener("abort",(()=>{i(t.signal.reason),o.terminate();})),o.postMessage({file:e,imageCompressionLibUrl:t.libURL,options:{...t,onProgress:void 0,signal:void 0}});}))}function imageCompression(e,t){return new Promise((function(r,i){let o,a,s,f,l,c;if(o={...t},s=0,({onProgress:f}=o),o.maxSizeMB=o.maxSizeMB||Number.POSITIVE_INFINITY,l="boolean"!=typeof o.useWebWorker||o.useWebWorker,delete o.useWebWorker,o.onProgress=e=>{s=e,"function"==typeof f&&f(s);},!(e instanceof Blob||e instanceof CustomFile))return i(new Error("The file given is not an instance of Blob or File"));if(!/^image/.test(e.type))return i(new Error("The file given is not an image"));if(c="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,!l||"function"!=typeof Worker||c)return compress(e,o).then(function(e){try{return a=e,$If_4.call(this)}catch(e){return i(e)}}.bind(this),i);var u=function(){try{return $If_4.call(this)}catch(e){return i(e)}}.bind(this),$Try_1_Catch=function(t){try{return compress(e,o).then((function(e){try{return a=e,u()}catch(e){return i(e)}}),i)}catch(e){return i(e)}};try{return o.libURL=o.libURL||"https://cdn.jsdelivr.net/npm/browser-image-compression@2.0.2/dist/browser-image-compression.js",compressOnWebWorker(e,o).then((function(e){try{return a=e,u()}catch(e){return $Try_1_Catch()}}),$Try_1_Catch)}catch(e){$Try_1_Catch();}function $If_4(){try{a.name=e.name,a.lastModified=e.lastModified;}catch(e){}try{o.preserveExif&&"image/jpeg"===e.type&&(!o.fileType||o.fileType&&o.fileType===e.type)&&(a=copyExifWithoutOrientation(e,a));}catch(e){}return r(a)}}))}imageCompression.getDataUrlFromFile=getDataUrlFromFile,imageCompression.getFilefromDataUrl=getFilefromDataUrl,imageCompression.loadImage=loadImage,imageCompression.drawImageInCanvas=drawImageInCanvas,imageCompression.drawFileInCanvas=drawFileInCanvas,imageCompression.canvasToFile=canvasToFile,imageCompression.getExifOrientation=getExifOrientation,imageCompression.handleMaxWidthOrHeight=handleMaxWidthOrHeight,imageCompression.followExifOrientation=followExifOrientation,imageCompression.cleanupCanvasMemory=cleanupCanvasMemory,imageCompression.isAutoOrientationInBrowser=isAutoOrientationInBrowser,imageCompression.approximateBelowMaximumCanvasSizeOfBrowser=approximateBelowMaximumCanvasSizeOfBrowser,imageCompression.copyExifWithoutOrientation=copyExifWithoutOrientation,imageCompression.getBrowserName=getBrowserName,imageCompression.version="2.0.2";
1878
-
1879
- class KritzelImageTool extends KritzelBaseTool {
1880
- constructor(store) {
1881
- super(store);
1882
- this.fileInput = null;
1883
- this.maxWidth = 300;
1884
- this.maxHeight = 300;
1885
- this.maxCompressionSize = 300;
1886
- this.setupFileInput();
1887
- }
1888
- onActivate() {
1889
- this.openFilePicker();
1890
- }
1891
- openFilePicker() {
1892
- this.fileInput.click();
1893
- }
1894
- setupFileInput() {
1895
- this.fileInput = document.createElement('input');
1896
- this.fileInput.type = 'file';
1897
- this.fileInput.accept = 'image/*';
1898
- this.fileInput.style.display = 'none';
1899
- this.fileInput.addEventListener('change', this.handleFileSelect.bind(this));
1900
- this.fileInput.addEventListener('cancel', this.handleCancel.bind(this));
1901
- document.body.appendChild(this.fileInput);
1902
- }
1903
- handleFileSelect(event) {
1904
- const input = event.target;
1905
- if (input.files && input.files[0]) {
1906
- const file = input.files[0];
1907
- imageCompression(file, {
1908
- maxWidthOrHeight: this.maxCompressionSize,
1909
- })
1910
- .then(compressedFile => {
1911
- this.readFile(compressedFile);
1912
- })
1913
- .catch(error => {
1914
- console.error('Error during image compression or processing:', error);
1915
- this.handleCancel();
1916
- });
1917
- }
1918
- else {
1919
- console.info('File selection cancelled by user.');
1920
- this.handleCancel();
1921
- }
1922
- if (input) {
1923
- input.value = '';
609
+ static registerIcons(icons) {
610
+ for (const name in icons) {
611
+ if (Object.prototype.hasOwnProperty.call(icons, name)) {
612
+ this.register(name, icons[name]);
613
+ }
1924
614
  }
1925
615
  }
1926
- readFile(file) {
1927
- const reader = new FileReader();
1928
- reader.onload = e => {
1929
- var _a;
1930
- const img = new Image();
1931
- img.src = (_a = e.target) === null || _a === void 0 ? void 0 : _a.result;
1932
- img.onload = () => this.processImage(img);
1933
- };
1934
- reader.readAsDataURL(file);
1935
- }
1936
- processImage(img) {
1937
- const { scaledWidth, scaledHeight } = this.calculateScaledDimensions(img);
1938
- const image = this.createKritzelImage(img, scaledWidth, scaledHeight);
1939
- this.addImageToStore(image);
1940
- }
1941
- calculateScaledDimensions(img) {
1942
- let scaledWidth = img.width;
1943
- let scaledHeight = img.height;
1944
- if (img.width > this.maxWidth || img.height > this.maxHeight) {
1945
- const widthRatio = this.maxWidth / img.width;
1946
- const heightRatio = this.maxHeight / img.height;
1947
- const scaleRatio = Math.min(widthRatio, heightRatio);
1948
- scaledWidth = img.width * scaleRatio;
1949
- scaledHeight = img.height * scaleRatio;
1950
- }
1951
- return { scaledWidth, scaledHeight };
1952
- }
1953
- createKritzelImage(img, width, height) {
1954
- const image = KritzelImage.create(this._store);
1955
- image.src = img.src;
1956
- image.width = width;
1957
- image.height = height;
1958
- image.zIndex = this._store.currentZIndex;
1959
- image.centerInViewport();
1960
- return image;
1961
- }
1962
- addImageToStore(image) {
1963
- const selectionGroup = KritzelSelectionGroup.create(this._store);
1964
- selectionGroup.addOrRemove(image);
1965
- selectionGroup.selected = true;
1966
- const addImageCommand = new AddObjectCommand(this._store, this, image);
1967
- const addSelectionGroupCommand = new AddSelectionGroupCommand(this._store, this, selectionGroup);
1968
- this._store.history.executeCommand(new BatchCommand(this._store, this, [addImageCommand, addSelectionGroupCommand]));
1969
- this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
1970
- }
1971
- handleCancel() {
1972
- this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
616
+ static has(name) {
617
+ return this.registry.has(name);
1973
618
  }
1974
619
  }
620
+ KritzelIconRegistry.registry = new Map();
621
+ KritzelIconRegistry.registerIcons({
622
+ 'cursor': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z"/></svg>',
623
+ 'pen': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/></svg>',
624
+ 'highlighter': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-highlighter-icon lucide-highlighter"><path d="m9 11-6 6v3h9l3-3"/><path d="m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4"/></svg>',
625
+ 'eraser': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21"/><path d="M22 21H7"/><path d="m5 11 9 9"/></svg>',
626
+ 'type': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9" x2="15" y1="20" y2="20"/><line x1="12" x2="12" y1="4" y2="20"/></svg>',
627
+ 'image': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>',
628
+ 'chevron-down': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',
629
+ 'chevron-up': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m18 15-6-6-6 6"/></svg>',
630
+ 'copy': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy-icon lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>',
631
+ 'paste': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clipboard-paste-icon lucide-clipboard-paste"><path d="M11 14h10"/><path d="M16 4h2a2 2 0 0 1 2 2v1.344"/><path d="m17 18 4-4-4-4"/><path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113"/><rect x="8" y="2" width="8" height="4" rx="1"/></svg>',
632
+ 'cut': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scissors-icon lucide-scissors"><circle cx="6" cy="6" r="3"/><path d="M8.12 8.12 12 12"/><path d="M20 4 8.12 15.88"/><circle cx="6" cy="18" r="3"/><path d="M14.8 14.8 20 20"/></svg>',
633
+ 'delete': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash2-icon lucide-trash-2"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>',
634
+ 'bring-to-front': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-up-to-line-icon lucide-arrow-up-to-line"><path d="M5 3h14"/><path d="m18 13-6-6-6 6"/><path d="M12 7v14"/></svg>',
635
+ 'send-to-back': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-down-to-line-icon lucide-arrow-down-to-line"><path d="M12 17V3"/><path d="m6 11 6 6 6-6"/><path d="M19 21H5"/></svg>',
636
+ 'select-all': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-mouse-pointer-icon lucide-square-mouse-pointer"><path d="M12.034 12.681a.498.498 0 0 1 .647-.647l9 3.5a.5.5 0 0 1-.033.943l-3.444 1.068a1 1 0 0 0-.66.66l-1.067 3.443a.5.5 0 0 1-.943.033z"/><path d="M21 11V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h6"/></svg>',
637
+ 'download': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download-icon lucide-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>',
638
+ 'undo': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-undo-icon lucide-undo"><path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/></svg>',
639
+ 'redo': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-redo-icon lucide-redo"><path d="M21 7v6h-6"/><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7"/></svg>'
640
+ });
1975
641
 
1976
- const DEFAULT_BRUSH_CONFIG = {
1977
- type: 'pen',
1978
- color: '#000000',
1979
- size: 16,
1980
- palettes: {
1981
- pen: [
1982
- '#000000',
1983
- '#ff5252',
1984
- '#ffbc00',
1985
- '#00c853',
1986
- '#0000FF',
1987
- '#d500f9',
1988
- '#fafafa',
1989
- '#a52714',
1990
- '#ee8100',
1991
- '#558b2f',
1992
- '#01579b',
1993
- '#8e24aa',
1994
- '#90a4ae',
1995
- '#ff4081',
1996
- '#ff6e40',
1997
- '#aeea00',
1998
- '#304ffe',
1999
- '#7c4dff',
2000
- '#cfd8dc',
2001
- '#f8bbd0',
2002
- '#ffccbc',
2003
- '#f0f4c3',
2004
- '#9fa8da',
2005
- '#d1c4e9',
2006
- ],
2007
- highlighter: [
2008
- '#0000006e',
2009
- '#ff52526e',
2010
- '#ffbb006e',
2011
- '#00c8536e',
2012
- '#0000FF6e',
2013
- '#d500f96e',
2014
- '#fafafa6e',
2015
- '#a527146e',
2016
- '#ee81006e',
2017
- '#558b2f6e',
2018
- '#01579b6e',
2019
- '#8e24aa6e',
2020
- '#90a4ae6e',
2021
- '#ff40816e',
2022
- '#ff6e406e',
2023
- '#aeea006e',
2024
- '#304ffe6e',
2025
- '#7c4dff6e',
2026
- '#cfd8dc6e',
2027
- '#f8bbd06e',
2028
- '#ffccbc6e',
2029
- '#f0f4c36e',
2030
- '#9fa8da6e',
2031
- '#d1c4e96e',
2032
- ],
2033
- },
2034
- };
2035
- const DEFAULT_TEXT_CONFIG = {
2036
- color: '#000000',
2037
- size: 8,
2038
- fontFamily: 'Arial',
2039
- palette: [
2040
- '#000000',
2041
- '#ff5252',
2042
- '#ffbc00',
2043
- '#00c853',
2044
- '#0000FF',
2045
- '#d500f9',
2046
- '#fafafa',
2047
- '#a52714',
2048
- '#ee8100',
2049
- '#558b2f',
2050
- '#01579b',
2051
- '#8e24aa',
2052
- '#90a4ae',
2053
- '#ff4081',
2054
- '#ff6e40',
2055
- '#aeea00',
2056
- '#304ffe',
2057
- '#7c4dff',
2058
- '#cfd8dc',
2059
- '#f8bbd0',
2060
- '#ffccbc',
2061
- '#f0f4c3',
2062
- '#9fa8da',
2063
- '#d1c4e9',
2064
- ],
2065
- };
2066
- const DEFAULT_KRITZEL_CONTROLS = [
2067
- {
2068
- name: 'selection',
2069
- type: 'tool',
2070
- tool: KritzelSelectionTool,
2071
- icon: 'cursor',
2072
- },
2073
- {
2074
- name: 'brush',
2075
- type: 'tool',
2076
- tool: KritzelBrushTool,
2077
- isDefault: true,
2078
- icon: 'pen',
2079
- config: DEFAULT_BRUSH_CONFIG,
2080
- },
2081
- {
2082
- name: 'eraser',
2083
- type: 'tool',
2084
- tool: KritzelEraserTool,
2085
- icon: 'eraser',
2086
- },
2087
- {
2088
- name: 'text',
2089
- type: 'tool',
2090
- tool: KritzelTextTool,
2091
- icon: 'type',
2092
- config: DEFAULT_TEXT_CONFIG,
2093
- },
2094
- {
2095
- name: 'image',
2096
- type: 'tool',
2097
- tool: KritzelImageTool,
2098
- icon: 'image',
2099
- },
2100
- {
2101
- name: 'divider',
2102
- type: 'divider',
2103
- },
2104
- {
2105
- name: 'config',
2106
- type: 'config',
2107
- },
2108
- ];
642
+ const ABSOLUTE_SCALE_MAX = 1000;
643
+ const ABSOLUTE_SCALE_MIN = 0.0001;
2109
644
 
2110
645
  const kritzelEditorCss = "kritzel-editor{display:flex;margin:0;position:relative;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}kritzel-controls{position:absolute;bottom:28px}";
2111
646
 
@@ -2113,9 +648,88 @@ const KritzelEditor = class {
2113
648
  constructor(hostRef) {
2114
649
  registerInstance(this, hostRef);
2115
650
  this.isReady = createEvent(this, "isReady");
2116
- this.controls = DEFAULT_KRITZEL_CONTROLS;
651
+ this.scaleMax = ABSOLUTE_SCALE_MAX;
652
+ this.scaleMin = ABSOLUTE_SCALE_MIN;
653
+ this.controls = [
654
+ {
655
+ name: 'selection',
656
+ type: 'tool',
657
+ tool: KritzelSelectionTool,
658
+ icon: 'cursor',
659
+ },
660
+ {
661
+ name: 'brush',
662
+ type: 'tool',
663
+ tool: KritzelBrushTool,
664
+ isDefault: true,
665
+ icon: 'pen',
666
+ config: DEFAULT_BRUSH_CONFIG,
667
+ },
668
+ {
669
+ name: 'eraser',
670
+ type: 'tool',
671
+ tool: KritzelEraserTool,
672
+ icon: 'eraser',
673
+ },
674
+ {
675
+ name: 'text',
676
+ type: 'tool',
677
+ tool: KritzelTextTool,
678
+ icon: 'type',
679
+ config: DEFAULT_TEXT_CONFIG,
680
+ },
681
+ {
682
+ name: 'image',
683
+ type: 'tool',
684
+ tool: KritzelImageTool,
685
+ icon: 'image',
686
+ },
687
+ {
688
+ name: 'divider',
689
+ type: 'divider',
690
+ },
691
+ {
692
+ name: 'config',
693
+ type: 'config',
694
+ },
695
+ ];
696
+ this.globalContextMenuItems = [
697
+ {
698
+ label: 'Paste',
699
+ icon: 'paste',
700
+ disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,
701
+ action: menu => this.engineRef.paste(menu.x, menu.y),
702
+ },
703
+ { label: 'Select All', icon: 'select-all', action: () => this.selectAllObjectsInViewport() },
704
+ ];
705
+ this.objectContextMenuItems = [
706
+ {
707
+ label: 'Edit',
708
+ icon: 'pen',
709
+ visible: (_, objects) => objects.length === 1 && objects[0].isEditable,
710
+ action: (_, objects) => {
711
+ if (objects.length === 1) {
712
+ const object = objects[0];
713
+ if (object.isEditable) {
714
+ object.edit();
715
+ }
716
+ }
717
+ }
718
+ },
719
+ { label: 'Copy', icon: 'copy', action: () => this.engineRef.copy() },
720
+ {
721
+ label: 'Paste',
722
+ icon: 'paste',
723
+ disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,
724
+ action: menu => this.engineRef.paste(menu.x, menu.y),
725
+ },
726
+ { label: 'Delete', icon: 'delete', action: () => this.engineRef.delete() },
727
+ { label: 'Bring to Front', icon: 'bring-to-front', action: () => this.engineRef.moveToTop() },
728
+ { label: 'Send to Back', icon: 'send-to-back', action: () => this.engineRef.moveToBottom() },
729
+ ];
2117
730
  this.customSvgIcons = {};
2118
- this.hideControls = false;
731
+ this.isControlsVisible = true;
732
+ this.isUtilityPanelVisible = true;
2119
733
  this.isEngineReady = false;
2120
734
  this.isControlsReady = false;
2121
735
  }
@@ -2186,7 +800,7 @@ const KritzelEditor = class {
2186
800
  }
2187
801
  }
2188
802
  render() {
2189
- return (h(Host, { key: '6621a06171194680b6df309dfa328e96ce7723c5' }, h("kritzel-engine", { key: '623628c15564168b8e508dbe45afbf2e5f5b1ed5', ref: el => (this.engineRef = el), onIsEngineReady: () => (this.isEngineReady = true) }), h("kritzel-controls", { key: 'dc56bb4c327d17236443c648fd3ca37eeaadc515', ref: el => (this.controlsRef = el), controls: this.controls, style: this.hideControls ? { display: 'none' } : { display: 'flex' }, onIsControlsReady: () => (this.isControlsReady = true) })));
803
+ return (h(Host, { key: '512d901979a81f1affdda0e920d7216e7605863a' }, h("kritzel-engine", { key: '9828d5a1e78f6ce66fde98e95d82947cd8efba25', ref: el => (this.engineRef = el), onIsEngineReady: () => (this.isEngineReady = true), scaleMax: this.scaleMax, scaleMin: this.scaleMin, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems }), h("kritzel-controls", { key: 'a8d52ab6fce293a97c34aeb2a03823916dcdf947', ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, style: this.isControlsVisible ? { display: 'flex' } : { display: 'none' }, onIsControlsReady: () => (this.isControlsReady = true) })));
2190
804
  }
2191
805
  get host() { return getElement(this); }
2192
806
  static get watchers() { return {
@@ -2646,13 +1260,17 @@ const DEFAULT_ENGINE_STATE = {
2646
1260
  cursorX: 0,
2647
1261
  cursorY: 0,
2648
1262
  scale: 1,
2649
- scaleMax: 1000,
2650
- scaleMin: 0.0001,
1263
+ scaleMax: 1,
1264
+ scaleMin: 1,
2651
1265
  scaleStep: 0.05,
2652
1266
  startX: 0,
2653
1267
  startY: 0,
2654
1268
  translateX: 0,
1269
+ translateXMax: 400,
1270
+ translateXMin: 0,
2655
1271
  translateY: 0,
1272
+ translateYMax: 400,
1273
+ translateYMin: 0,
2656
1274
  viewportWidth: 0,
2657
1275
  viewportHeight: 0,
2658
1276
  historyBufferSize: 1000,
@@ -2883,19 +1501,8 @@ class KritzelStore {
2883
1501
  const shadowRoot = (_a = this.state.host) === null || _a === void 0 ? void 0 : _a.shadowRoot;
2884
1502
  if (!shadowRoot)
2885
1503
  return null;
2886
- let clientX;
2887
- let clientY;
2888
- if ('touches' in event) {
2889
- const touch = event.touches[0];
2890
- if (!touch)
2891
- return null;
2892
- clientX = touch.clientX;
2893
- clientY = touch.clientY;
2894
- }
2895
- else {
2896
- clientX = event.clientX;
2897
- clientY = event.clientY;
2898
- }
1504
+ const clientX = event.clientX;
1505
+ const clientY = event.clientY;
2899
1506
  const elementAtPoint = shadowRoot.elementFromPoint(clientX, clientY);
2900
1507
  if (!elementAtPoint)
2901
1508
  return null;
@@ -3039,6 +1646,26 @@ class KritzelClassHelper {
3039
1646
  const kritzelEngineCss = ":host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}textarea{all:unset;box-sizing:border-box;outline:none !important;border:none !important;overflow:visible}.resize-handle-overlay.top-left,.resize-handle-overlay.bottom-right{cursor:nwse-resize}.resize-handle-overlay.top-right,.resize-handle-overlay.bottom-left{cursor:nesw-resize}.rotation-handle-overlay{cursor:grab}";
3040
1647
 
3041
1648
  const KritzelEngine = class {
1649
+ validateScaleMax(newValue) {
1650
+ if (newValue > ABSOLUTE_SCALE_MAX) {
1651
+ console.warn(`scaleMax cannot be greater than ${ABSOLUTE_SCALE_MAX}.`);
1652
+ this.scaleMax = ABSOLUTE_SCALE_MAX;
1653
+ this.store.state.scaleMax = this.scaleMax;
1654
+ }
1655
+ else {
1656
+ this.store.state.scaleMax = newValue;
1657
+ }
1658
+ }
1659
+ validateScaleMin(newValue) {
1660
+ if (newValue < ABSOLUTE_SCALE_MIN) {
1661
+ console.warn(`scaleMin cannot be less than ${ABSOLUTE_SCALE_MIN}.`);
1662
+ this.scaleMin = ABSOLUTE_SCALE_MIN;
1663
+ this.store.state.scaleMin = this.scaleMin;
1664
+ }
1665
+ else {
1666
+ this.store.state.scaleMin = newValue;
1667
+ }
1668
+ }
3042
1669
  get isSelecting() {
3043
1670
  return this.store.state.activeTool instanceof KritzelSelectionTool && this.store.state.isSelecting;
3044
1671
  }
@@ -3049,56 +1676,21 @@ const KritzelEngine = class {
3049
1676
  registerInstance(this, hostRef);
3050
1677
  this.isEngineReady = createEvent(this, "isEngineReady");
3051
1678
  this.activeToolChange = createEvent(this, "activeToolChange");
3052
- this.globalContextMenuItems = [
3053
- {
3054
- label: 'Paste',
3055
- icon: 'paste',
3056
- disabled: () => this.store.state.copiedObjects === null,
3057
- action: () => {
3058
- const x = (-this.store.state.translateX + this.store.state.contextMenuX) / this.store.state.scale;
3059
- const y = (-this.store.state.translateY + this.store.state.contextMenuY) / this.store.state.scale;
3060
- this.paste(x, y);
3061
- },
3062
- },
3063
- { label: 'Select All', icon: 'select-all', action: () => this.selectAllObjectsInViewport() },
3064
- ];
3065
- this.objectContextMenuItems = [
3066
- { label: 'Copy', icon: 'copy', action: () => this.copy() },
3067
- {
3068
- label: 'Paste',
3069
- icon: 'paste',
3070
- disabled: () => this.store.state.copiedObjects === null,
3071
- action: () => {
3072
- const x = (-this.store.state.translateX + this.store.state.contextMenuX) / this.store.state.scale;
3073
- const y = (-this.store.state.translateY + this.store.state.contextMenuY) / this.store.state.scale;
3074
- this.paste(x, y);
3075
- },
3076
- },
3077
- { label: 'Delete', icon: 'delete', action: () => this.delete() },
3078
- { label: 'Bring to Front', icon: 'bring-to-front', action: () => this.moveToTop() },
3079
- { label: 'Send to Back', icon: 'send-to-back', action: () => this.moveToBottom() },
3080
- ];
1679
+ this.scaleMax = ABSOLUTE_SCALE_MAX;
1680
+ this.scaleMin = ABSOLUTE_SCALE_MIN;
3081
1681
  this.forceUpdate = 0;
3082
1682
  this.contextMenuElement = null;
3083
1683
  this.store = new KritzelStore(this);
3084
- this.contextMenuHandler = new KritzelContextMenuHandler(this.store, this.globalContextMenuItems, this.objectContextMenuItems);
3085
- this.keyHandler = new KritzelKeyHandler(this.store);
3086
- this.store.onStateChange('activeTool', (activeTool) => {
3087
- if (!(activeTool instanceof KritzelSelectionTool)) {
3088
- this.store.clearSelection();
3089
- }
3090
- this.store.state.skipContextMenu = false;
3091
- this.activeToolChange.emit(activeTool);
3092
- KritzelKeyboardHelper.forceHideKeyboard();
3093
- });
3094
- this.store.onStateChange('isFocused', (isFocused) => {
3095
- if (!isFocused) {
3096
- this.store.resetActiveText();
3097
- }
3098
- });
1684
+ }
1685
+ componentWillLoad() {
1686
+ this.validateScaleMax(this.scaleMax);
1687
+ this.validateScaleMin(this.scaleMin);
3099
1688
  }
3100
1689
  componentDidLoad() {
1690
+ this.contextMenuHandler = new KritzelContextMenuHandler(this.store, this.globalContextMenuItems, this.objectContextMenuItems);
1691
+ this.keyHandler = new KritzelKeyHandler(this.store);
3101
1692
  this.viewport = new KritzelViewport(this.store, this.host);
1693
+ this._registerStateChangeListeners();
3102
1694
  if (this.store.state.isReady === false) {
3103
1695
  this.store.state.isReady = true;
3104
1696
  this.isEngineReady.emit();
@@ -3188,10 +1780,6 @@ const KritzelEngine = class {
3188
1780
  const isInKritzelEngine = path.includes(kritzelEngineElement || this.host);
3189
1781
  this.store.setState('isFocused', isInside && isInKritzelEngine);
3190
1782
  }
3191
- handleContextMenuAction(event) {
3192
- event.detail.action();
3193
- this.hideContextMenu();
3194
- }
3195
1783
  async registerTool(toolName, toolClass, toolConfig) {
3196
1784
  if (typeof toolClass !== 'function' || !(toolClass.prototype instanceof KritzelBaseTool)) {
3197
1785
  console.error(`Failed to register tool "${toolName}": Tool class must be a constructor function`);
@@ -3310,21 +1898,42 @@ const KritzelEngine = class {
3310
1898
  this.store.history.executeCommand(command);
3311
1899
  return object;
3312
1900
  }
1901
+ async getCopiedObjects() {
1902
+ var _a;
1903
+ return ((_a = this.store.state.copiedObjects) === null || _a === void 0 ? void 0 : _a.objects) || [];
1904
+ }
1905
+ _registerStateChangeListeners() {
1906
+ this.store.onStateChange('activeTool', this._handleActiveToolChange.bind(this));
1907
+ this.store.onStateChange('isFocused', this._handleIsFocusedChange.bind(this));
1908
+ }
1909
+ _handleActiveToolChange(activeTool) {
1910
+ if (!(activeTool instanceof KritzelSelectionTool)) {
1911
+ this.store.clearSelection();
1912
+ }
1913
+ this.store.state.skipContextMenu = false;
1914
+ this.activeToolChange.emit(activeTool);
1915
+ KritzelKeyboardHelper.forceHideKeyboard();
1916
+ }
1917
+ _handleIsFocusedChange(isFocused) {
1918
+ if (!isFocused) {
1919
+ this.store.resetActiveText();
1920
+ }
1921
+ }
3313
1922
  render() {
3314
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
1923
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
3315
1924
  const computedStyle = window.getComputedStyle(this.host);
3316
1925
  const baseHandleSizePx = computedStyle.getPropertyValue('--kritzel-selection-handle-size').trim() || '6px';
3317
1926
  const baseHandleSize = parseFloat(baseHandleSizePx);
3318
1927
  const baseHandleTouchSize = baseHandleSize * 2 < 14 ? 14 : baseHandleSize;
3319
- return (h(Host, { key: '1a8a4ac086fd25b356d25f1c4f094005771a3d57' }, h("div", { key: '5edf7faeb5d63e8341fa81b48287eaee001ed163', class: "debug-panel", style: { display: this.store.state.debugInfo.showViewportInfo ? 'block' : 'none' } }, h("div", { key: '356a8bb56abb4a9c98ab79f1d224a64e6c202a34' }, "TranslateX: ", (_a = this.store.state) === null || _a === void 0 ? void 0 :
3320
- _a.translateX), h("div", { key: 'e3d853e7e11c32bf5f801c29a0ed9add91ce24c3' }, "TranslateY: ", (_b = this.store.state) === null || _b === void 0 ? void 0 :
3321
- _b.translateY), h("div", { key: '7ada7c0c256bbdc79b2b74b391c87a319c9aaf05' }, "ViewportWidth: ", (_c = this.store.state) === null || _c === void 0 ? void 0 :
3322
- _c.viewportWidth), h("div", { key: '156ed10ab63bbacf30d549f115d82beeb6e714d5' }, "ViewportHeight: ", (_d = this.store.state) === null || _d === void 0 ? void 0 :
3323
- _d.viewportHeight), h("div", { key: '1cf8c42989b1c4117a4895f05686313e169b808e' }, "ObjectsInViewport. ", this.store.objects.length), h("div", { key: '1e558a335a31c050c80cda3cd763267fe95335d2' }, "Scale: ", (_e = this.store.state) === null || _e === void 0 ? void 0 :
3324
- _e.scale), h("div", { key: 'ff43094ed2f27d2157946329cc4473d92c2d3e30' }, "ActiveTool: ", (_g = (_f = this.store.state) === null || _f === void 0 ? void 0 : _f.activeTool) === null || _g === void 0 ? void 0 :
3325
- _g.name), h("div", { key: '844c0e1dd8d77270419e3c0a0362536e6027f4cb' }, "HasViewportChanged: ", ((_h = this.store.state) === null || _h === void 0 ? void 0 : _h.hasViewportChanged) ? 'true' : 'false'), h("div", { key: '64a782868924f27f9ef4d426694ddac338293bc5' }, "IsEnabled: ", ((_j = this.store.state) === null || _j === void 0 ? void 0 : _j.isEnabled) ? 'true' : 'false'), h("div", { key: '4fc48b5006641e0ecb9af0d8cc5b4fe2868faa3d' }, "IsScaling: ", ((_k = this.store.state) === null || _k === void 0 ? void 0 : _k.isScaling) ? 'true' : 'false'), h("div", { key: '1407e97aba7434599060b33ead00da898482cc6a' }, "IsPanning: ", ((_l = this.store.state) === null || _l === void 0 ? void 0 : _l.isPanning) ? 'true' : 'false'), h("div", { key: 'f99a32e77014bf5548a5ae50a99ee4e6f6ae4801' }, "IsFocused: ", this.store.state.isFocused ? 'true' : 'false'), h("div", { key: '0c7708d4a8dc78e171b9493b8b5ab2cfe2984ad6' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: '5bca3b678ee83f2faba320dfbeb63af8d41b2908' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: '2cecae3e2108ca108220ca7bb67777829cd223ef' }, "IsResizeHandleSelected: ", this.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: 'd0cf8270f99ae6e8ce915a856e54ed7b38cd40aa' }, "IsRotationHandleSelected: ", this.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: '4f1a0bad54e9a4ad46fec56d7c692a48e02cb7a2' }, "IsDrawing: ", this.store.state.isDrawing ? 'true' : 'false'), h("div", { key: '9a4b3fdc05e103a2c73a7940bd9a84a68f912b14' }, "IsWriting: ", this.store.state.isWriting ? 'true' : 'false'), h("div", { key: '5a480fdbe4a3fa435697bb94701971dda75f41d3' }, "CursorX: ", (_m = this.store.state) === null || _m === void 0 ? void 0 :
3326
- _m.cursorX), h("div", { key: 'f549e8faa3ddad5b3294bb72f24ad3735539e84b' }, "CursorY: ", (_o = this.store.state) === null || _o === void 0 ? void 0 :
3327
- _o.cursorY)), h("div", { key: 'e81679812ed19a50a09357549df00e590ae613b6', class: "origin", style: {
1928
+ return (h(Host, { key: 'd484b59ebdea9e7b9e8e086c39e7b3a339fb034d' }, h("div", { key: 'ea68c0a3c0020110b5aca6f3a7bdfab223b64744', class: "debug-panel", style: { display: this.store.state.debugInfo.showViewportInfo ? 'block' : 'none' } }, h("div", { key: '4a7c60073190f2123dbb6bda4e206a1b488db7ac' }, "TranslateX: ", (_a = this.store.state) === null || _a === void 0 ? void 0 :
1929
+ _a.translateX), h("div", { key: 'c4fe558accb441fb06ff048f41b07b520ffde505' }, "TranslateY: ", (_b = this.store.state) === null || _b === void 0 ? void 0 :
1930
+ _b.translateY), h("div", { key: '00d5fd0b0ec3c79f9ab1dc9a1032fa2f70c7c246' }, "ViewportWidth: ", (_c = this.store.state) === null || _c === void 0 ? void 0 :
1931
+ _c.viewportWidth), h("div", { key: '87c8f03bfcc6de031e3d9d74576a6028bfc155bc' }, "ViewportHeight: ", (_d = this.store.state) === null || _d === void 0 ? void 0 :
1932
+ _d.viewportHeight), h("div", { key: 'f4e82ddee133818b6ad60b5b6c5e9e721fce4968' }, "ObjectsInViewport. ", this.store.objects.length), h("div", { key: '4f9018ce1184b676248614d4edfdeffd49ac7ce2' }, "Scale: ", (_e = this.store.state) === null || _e === void 0 ? void 0 :
1933
+ _e.scale), h("div", { key: 'cc5d72952bc4b80a42d26ca1b1e56bcab96ab76c' }, "ActiveTool: ", (_g = (_f = this.store.state) === null || _f === void 0 ? void 0 : _f.activeTool) === null || _g === void 0 ? void 0 :
1934
+ _g.name), h("div", { key: '387071b0ea3f2064d1ea0e0495aa92de8072a900' }, "HasViewportChanged: ", ((_h = this.store.state) === null || _h === void 0 ? void 0 : _h.hasViewportChanged) ? 'true' : 'false'), h("div", { key: 'a386b4fb631860b94f710cb601b1809283ab9664' }, "IsEnabled: ", ((_j = this.store.state) === null || _j === void 0 ? void 0 : _j.isEnabled) ? 'true' : 'false'), h("div", { key: 'a67ad19caa6a6cafa8b19dace26c25d60347090a' }, "IsScaling: ", ((_k = this.store.state) === null || _k === void 0 ? void 0 : _k.isScaling) ? 'true' : 'false'), h("div", { key: '9fe3152ba0a3e936b6c6551673de3a67bd5de0d1' }, "IsPanning: ", ((_l = this.store.state) === null || _l === void 0 ? void 0 : _l.isPanning) ? 'true' : 'false'), h("div", { key: '8103da258c7bdede340c6c64188a2f9657af16c3' }, "IsFocused: ", this.store.state.isFocused ? 'true' : 'false'), h("div", { key: '10b315366f6cf8eb2f27a20083094c9e483c2fe3' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: 'b65926aca01fe6b41f70e8d7484674f568e9945a' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: '5e95a4268ab30bf06918e83aa5f7e96b5ee1dbe2' }, "IsResizeHandleSelected: ", this.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: '3922b7fcb2b74ec28f515db8254f05b454ef6b12' }, "IsRotationHandleSelected: ", this.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: '13c162ec56f0990948bac4569c28a6076582c7ea' }, "IsDrawing: ", this.store.state.isDrawing ? 'true' : 'false'), h("div", { key: 'f909cbc959961e47dbff28e5c620175dc04f6873' }, "IsWriting: ", this.store.state.isWriting ? 'true' : 'false'), h("div", { key: '505122e286976b8fa9e9fac5b131bcecb359eaae' }, "CursorX: ", (_m = this.store.state) === null || _m === void 0 ? void 0 :
1935
+ _m.cursorX), h("div", { key: '116217379cf67a0a268e97912ec44d52a98c434b' }, "CursorY: ", (_o = this.store.state) === null || _o === void 0 ? void 0 :
1936
+ _o.cursorY)), h("div", { key: 'b0bcbb90404d0cbc1281b932bd13e67df612d58d', class: "origin", style: {
3328
1937
  transform: `matrix(${(_p = this.store.state) === null || _p === void 0 ? void 0 : _p.scale}, 0, 0, ${(_q = this.store.state) === null || _q === void 0 ? void 0 : _q.scale}, ${(_r = this.store.state) === null || _r === void 0 ? void 0 : _r.translateX}, ${(_s = this.store.state) === null || _s === void 0 ? void 0 : _s.translateY})`,
3329
1938
  } }, (_t = this.store.objects) === null || _t === void 0 ? void 0 :
3330
1939
  _t.map(object => {
@@ -3421,7 +2030,7 @@ const KritzelEngine = class {
3421
2030
  fill: 'transparent',
3422
2031
  cursor: 'grab',
3423
2032
  }, visibility: object.selected && !this.isSelecting ? 'visible' : 'hidden' }), h("g", { style: { display: this.store.state.debugInfo.showObjectInfo ? 'block' : 'none', pointerEvents: 'none' } }, h("foreignObject", { x: object.totalWidth.toString(), y: "0", width: "400px", height: "160px", style: { minHeight: '0', minWidth: '0', display: object.debugInfoVisible ? 'block' : 'none' } }, h("div", { style: { width: '100%', height: '100%' } }, h("div", { style: { whiteSpace: 'nowrap' } }, "zIndex: ", object.zIndex), h("div", { style: { whiteSpace: 'nowrap' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap' } }, "translateY: ", object.translateY), h("div", { style: { whiteSpace: 'nowrap' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap' } }, "scale: ", object.scale), h("div", { style: { whiteSpace: 'nowrap' } }, "rotation: ", object.rotation)))))));
3424
- }), h("svg", { key: 'bf2c561803773e19aed36d418e96b9f797c305be', class: "object", xmlns: "http://www.w3.org/2000/svg", style: {
2033
+ }), h("svg", { key: '4fd9e58c617eaf428edbdc3491d3f4fabe3ce564', class: "object", xmlns: "http://www.w3.org/2000/svg", style: {
3425
2034
  height: (_u = this.store.state.currentPath) === null || _u === void 0 ? void 0 : _u.height.toString(),
3426
2035
  width: (_v = this.store.state.currentPath) === null || _v === void 0 ? void 0 : _v.width.toString(),
3427
2036
  left: '0',
@@ -3431,14 +2040,24 @@ const KritzelEngine = class {
3431
2040
  transform: (_x = this.store.state.currentPath) === null || _x === void 0 ? void 0 : _x.transformationMatrix,
3432
2041
  transformOrigin: 'top left',
3433
2042
  overflow: 'visible',
3434
- }, viewBox: (_y = this.store.state.currentPath) === null || _y === void 0 ? void 0 : _y.viewBox }, h("path", { key: '5177dab02b9a5563129d00b80b99a1a198eb8ff5', d: (_z = this.store.state.currentPath) === null || _z === void 0 ? void 0 : _z.d, fill: (_0 = this.store.state.currentPath) === null || _0 === void 0 ? void 0 : _0.fill, stroke: (_1 = this.store.state.currentPath) === null || _1 === void 0 ? void 0 : _1.stroke }))), this.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: 'ea3ae0531d9b2109e547baca7159ea29ebd34827', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.store.state.contextMenuItems, style: {
2043
+ }, viewBox: (_y = this.store.state.currentPath) === null || _y === void 0 ? void 0 : _y.viewBox }, h("path", { key: 'ac88c3b66d642bbe42a0ac5345b4f4d6cddef5a3', d: (_z = this.store.state.currentPath) === null || _z === void 0 ? void 0 : _z.d, fill: (_0 = this.store.state.currentPath) === null || _0 === void 0 ? void 0 : _0.fill, stroke: (_1 = this.store.state.currentPath) === null || _1 === void 0 ? void 0 : _1.stroke }))), this.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: '75d7dfe1ef3ab64ae960c69a471224095a812cb8', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.store.state.contextMenuItems, objects: ((_2 = this.store.state.selectionGroup) === null || _2 === void 0 ? void 0 : _2.objects) || [], style: {
3435
2044
  position: 'fixed',
3436
2045
  left: `${this.store.state.contextMenuX}px`,
3437
2046
  top: `${this.store.state.contextMenuY}px`,
3438
2047
  zIndex: '10000',
3439
- }, onActionSelected: event => this.handleContextMenuAction(event) })), ((_2 = this.store.state) === null || _2 === void 0 ? void 0 : _2.activeTool) instanceof KritzelEraserTool && !this.store.state.isScaling && h("kritzel-cursor-trail", { key: 'c785558a0f922d7caeacaeeb44a9492ebcc0be7d', store: this.store })));
2048
+ }, onActionSelected: event => {
2049
+ event.detail.action({
2050
+ x: (-this.store.state.translateX + this.store.state.contextMenuX) / this.store.state.scale,
2051
+ y: (-this.store.state.translateY + this.store.state.contextMenuY) / this.store.state.scale,
2052
+ }, this.store.state.selectionGroup.objects);
2053
+ this.hideContextMenu();
2054
+ } })), ((_3 = this.store.state) === null || _3 === void 0 ? void 0 : _3.activeTool) instanceof KritzelEraserTool && !this.store.state.isScaling && h("kritzel-cursor-trail", { key: 'a056ea6d5c4271f6af82d259d6d8126fef07c7bd', store: this.store })));
3440
2055
  }
3441
2056
  get host() { return getElement(this); }
2057
+ static get watchers() { return {
2058
+ "scaleMax": ["validateScaleMax"],
2059
+ "scaleMin": ["validateScaleMin"]
2060
+ }; }
3442
2061
  };
3443
2062
  KritzelEngine.style = kritzelEngineCss;
3444
2063