@inditextech/weave-sdk 3.1.0 → 3.2.0-SNAPSHOT.100.1

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.
package/dist/sdk.node.js CHANGED
@@ -4,6 +4,7 @@ import pino from "pino";
4
4
  import { WEAVE_ASYNC_STATUS, WEAVE_AWARENESS_LAYER_ID, WEAVE_EXPORT_BACKGROUND_COLOR, WEAVE_EXPORT_FORMATS, WEAVE_INSTANCE_STATUS, WEAVE_KONVA_BACKEND, WEAVE_LOG_LEVEL, WEAVE_NODE_CHANGE_TYPE, WEAVE_NODE_CUSTOM_EVENTS, WEAVE_NODE_LAYER_ID, WEAVE_NODE_POSITION, WEAVE_STORE_CONNECTION_STATUS, WEAVE_UTILITY_LAYER_ID } from "@inditextech/weave-types";
5
5
  import { getYjsDoc, getYjsValue, observeDeep, syncedStore } from "@syncedstore/core";
6
6
  import * as Y from "yjs";
7
+ import "konva/lib/types";
7
8
 
8
9
  //#region rolldown:runtime
9
10
  var __create = Object.create;
@@ -15150,6 +15151,7 @@ var WeaveStore = class {
15150
15151
  });
15151
15152
  }
15152
15153
  if (!this.isRoomLoaded && !(0, import_lodash.isEmpty)(this.state.weave)) {
15154
+ this.instance.checkForAsyncElements();
15153
15155
  this.instance.setupRenderer();
15154
15156
  this.isRoomLoaded = true;
15155
15157
  this.emitOnRoomLoadedEvent();
@@ -17603,7 +17605,7 @@ var require_mergeWith = __commonJS({ "../../node_modules/lodash/mergeWith.js"(ex
17603
17605
  var import_mergeWith = __toESM(require_mergeWith(), 1);
17604
17606
 
17605
17607
  //#endregion
17606
- //#region src/utils.ts
17608
+ //#region src/utils/utils.ts
17607
17609
  function resetScale(node) {
17608
17610
  node.width(Math.round((Math.max(1, node.width() * node.scaleX()) + Number.EPSILON) * 100) / 100);
17609
17611
  node.height(Math.round((Math.max(1, node.height() * node.scaleY()) + Number.EPSILON) * 100) / 100);
@@ -17816,7 +17818,7 @@ function getTargetAndSkipNodes(instance, e, forceTransformer = false) {
17816
17818
  };
17817
17819
  let skipNodes = [];
17818
17820
  let node = void 0;
17819
- if (e.type === "dragmove" && nodesSelectionPlugin && nodesSelectionPlugin.getTransformer().nodes().length === 1) {
17821
+ if (e.type === "dragmove" && nodesSelectionPlugin?.getTransformer().nodes().length === 1) {
17820
17822
  node = nodesSelectionPlugin.getTransformer().nodes()[0];
17821
17823
  skipNodes.push(node.getAttrs().id ?? "");
17822
17824
  if (node.getAttr("eventTarget")) {
@@ -17922,7 +17924,7 @@ const getPositionRelativeToContainerOnPosition = (instance) => {
17922
17924
  };
17923
17925
  const canComposite = (node) => {
17924
17926
  const parent = node.getParent();
17925
- return parent && parent.getClassName() === "Group" && parent.getAttrs().nodeType !== "frame" && parent.getAttrs().nodeId === void 0;
17927
+ return parent?.getClassName() === "Group" && parent?.getAttrs().nodeType !== "frame" && parent?.getAttrs().nodeId === void 0;
17926
17928
  };
17927
17929
  function mergeExceptArrays(object, source) {
17928
17930
  return (0, import_mergeWith.default)({}, object, source, (objValue, srcValue) => {
@@ -18790,7 +18792,11 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18790
18792
  } else nodeHovered?.handleMouseout?.();
18791
18793
  });
18792
18794
  tr.on("mouseover", () => {
18793
- stage.container().style.cursor = "grab";
18795
+ const nodesSelected = tr.nodes();
18796
+ if (nodesSelected.length === 1) {
18797
+ const node = nodesSelected[0];
18798
+ stage.container().style.cursor = node.defineMousePointer() ?? "grab";
18799
+ } else stage.container().style.cursor = "grab";
18794
18800
  });
18795
18801
  tr.on("mouseout", () => {
18796
18802
  this.instance.getStage().handleMouseover?.();
@@ -19513,7 +19519,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19513
19519
  if (areNodesSelected) {
19514
19520
  stage.container().tabIndex = 1;
19515
19521
  stage.container().focus();
19516
- stage.container().style.cursor = "grab";
19522
+ stage.container().style.cursor = nodeTargeted.defineMousePointer() ?? "grab";
19517
19523
  }
19518
19524
  this.triggerSelectedNodesEvent();
19519
19525
  }
@@ -19787,32 +19793,25 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19787
19793
  if (!this.enabled) return;
19788
19794
  }
19789
19795
  });
19790
- if (catcher) {
19791
- document.addEventListener("paste", async (e) => {
19792
- const dataList = e.clipboardData?.items;
19793
- if (!dataList) return;
19794
- if (dataList?.length > 0) this.sendExternalPasteEvent(dataList);
19795
- });
19796
- catcher.addEventListener("paste", async (e) => {
19797
- e.preventDefault();
19798
- let items = void 0;
19799
- let hasWeaveData = false;
19800
- if (!items) {
19801
- if (this.isClipboardAPIAvailable()) items = await navigator.clipboard.read();
19802
- }
19803
- if (!items || items.length === 0) return;
19804
- if (this.isClipboardAPIAvailable()) {
19805
- const readText = await navigator.clipboard.readText();
19806
- const continueToPaste = this.isWeaveData(readText);
19807
- if (continueToPaste) hasWeaveData = true;
19808
- }
19809
- if (hasWeaveData) {
19810
- this.handlePaste();
19811
- return;
19812
- }
19813
- this.sendExternalPasteEvent(void 0, items);
19814
- });
19815
- }
19796
+ if (catcher) catcher.addEventListener("paste", async (e) => {
19797
+ e.preventDefault();
19798
+ let items = void 0;
19799
+ let hasWeaveData = false;
19800
+ if (!items) {
19801
+ if (this.isClipboardAPIAvailable()) items = await navigator.clipboard.read();
19802
+ }
19803
+ if (!items || items.length === 0) return;
19804
+ if (this.isClipboardAPIAvailable()) {
19805
+ const readText = await navigator.clipboard.readText();
19806
+ const continueToPaste = this.isWeaveData(readText);
19807
+ if (continueToPaste) hasWeaveData = true;
19808
+ }
19809
+ if (hasWeaveData) {
19810
+ this.handlePaste();
19811
+ return;
19812
+ }
19813
+ this.sendExternalPasteEvent(void 0, items);
19814
+ });
19816
19815
  }
19817
19816
  sendExternalPasteEvent(dataList, items) {
19818
19817
  const stage = this.instance.getStage();
@@ -20197,6 +20196,11 @@ var WeaveNode = class {
20197
20196
  node.handleMouseout = function() {};
20198
20197
  node.handleSelectNode = function() {};
20199
20198
  node.handleDeselectNode = function() {};
20199
+ node.defineMousePointer = () => {
20200
+ const selectedNodes = this.getSelectionPlugin()?.getSelectedNodes() ?? [];
20201
+ if (this.isSelecting() && selectedNodes.includes(node)) return "grab";
20202
+ return "pointer";
20203
+ };
20200
20204
  node.canBeHovered = function() {
20201
20205
  return true;
20202
20206
  };
@@ -20683,12 +20687,12 @@ var WeaveNode = class {
20683
20687
  }
20684
20688
  if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20685
20689
  showHover = true;
20686
- stage.container().style.cursor = "pointer";
20690
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "pointer";
20687
20691
  cancelBubble = true;
20688
20692
  }
20689
20693
  if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20690
20694
  showHover = true;
20691
- stage.container().style.cursor = "grab";
20695
+ stage.container().style.cursor = realNode?.defineMousePointer() ?? "grab";
20692
20696
  cancelBubble = true;
20693
20697
  }
20694
20698
  if (!isTargetable) cancelBubble = true;
@@ -20874,6 +20878,9 @@ var WeaveAction = class {
20874
20878
  hasAliases() {
20875
20879
  return false;
20876
20880
  }
20881
+ setForceExecution(forceExecution) {
20882
+ this.forceExecution = forceExecution;
20883
+ }
20877
20884
  getAliases() {
20878
20885
  return [];
20879
20886
  }
@@ -21351,8 +21358,10 @@ var WeaveTargetingManager = class {
21351
21358
  };
21352
21359
  let measureContainer = mainLayer;
21353
21360
  let container = mainLayer;
21361
+ const utilityLayer = this.instance.getUtilityLayer();
21362
+ if (utilityLayer) utilityLayer.visible(false);
21354
21363
  const nodesSelection = this.instance.getPlugin("nodesSelection");
21355
- if (nodesSelection) nodesSelection.disable();
21364
+ if (nodesSelection) nodesSelection.getTransformer().visible(false);
21356
21365
  const dummyRect = new Konva.Rect({
21357
21366
  width: 10,
21358
21367
  height: 10,
@@ -21373,7 +21382,8 @@ var WeaveTargetingManager = class {
21373
21382
  x: 0,
21374
21383
  y: 0
21375
21384
  };
21376
- if (nodesSelection) nodesSelection.enable();
21385
+ if (utilityLayer) utilityLayer.visible(true);
21386
+ if (nodesSelection) nodesSelection.getTransformer().visible(true);
21377
21387
  dummyRect.destroy();
21378
21388
  return {
21379
21389
  mousePoint: relativeMousePointer,
@@ -21777,13 +21787,13 @@ var WeaveStateManager = class {
21777
21787
  updateNodes(nodes) {
21778
21788
  for (const node of nodes) this.updateNode(node);
21779
21789
  }
21780
- stateTransactional(callback) {
21790
+ stateTransactional(callback, origin) {
21781
21791
  const state = this.instance.getStore().getState();
21782
21792
  const doc = getYjsDoc(state);
21783
- const userId = this.instance.getStore().getUser().id;
21793
+ const transactionOrigin = origin ?? this.instance.getStore().getUser().id;
21784
21794
  doc.transact(() => {
21785
21795
  callback();
21786
- }, userId);
21796
+ }, transactionOrigin);
21787
21797
  }
21788
21798
  removeNode(node) {
21789
21799
  const state = this.instance.getStore().getState();
@@ -21918,7 +21928,6 @@ var WeaveRegisterManager = class {
21918
21928
  registerActionsHandlers() {
21919
21929
  const config = this.instance.getConfiguration();
21920
21930
  if (config.actions) for (const action of config.actions) this.registerActionHandler(action);
21921
- this.logger.info(`Actions handlers registered`);
21922
21931
  }
21923
21932
  registerActionHandler(action) {
21924
21933
  const actionName = action.getName();
@@ -21945,7 +21954,7 @@ var WeaveRegisterManager = class {
21945
21954
 
21946
21955
  //#endregion
21947
21956
  //#region package.json
21948
- var version = "3.1.0";
21957
+ var version = "3.2.0-SNAPSHOT.100.1";
21949
21958
 
21950
21959
  //#endregion
21951
21960
  //#region src/managers/setup.ts
@@ -22085,14 +22094,15 @@ var WeaveActionsManager = class {
22085
22094
  getActiveAction() {
22086
22095
  return this.activeAction;
22087
22096
  }
22088
- triggerAction(actionName, params) {
22097
+ triggerAction(actionName, params, forceExecution = false) {
22089
22098
  const actionsHandlers = this.instance.getActionsHandlers();
22090
22099
  if (typeof actionName === "undefined") throw new Error("Action name is required");
22091
22100
  if (actionName && !actionsHandlers[actionName]) throw new Error(`Action handler with name [${actionName}] not registered`);
22092
- if (typeof this.activeAction !== "undefined") this.cancelAction(this.activeAction);
22093
- this.activeAction = actionName;
22101
+ if (this.activeAction !== void 0 && !forceExecution) this.cancelAction(this.activeAction);
22102
+ if (!forceExecution) this.activeAction = actionName;
22103
+ actionsHandlers[actionName].setForceExecution(forceExecution);
22094
22104
  const payload = actionsHandlers[actionName].trigger(this.cancelActionCallback(actionName), params);
22095
- this.instance.emitEvent("onActiveActionChange", this.activeAction);
22105
+ if (!forceExecution) this.instance.emitEvent("onActiveActionChange", this.activeAction);
22096
22106
  return payload;
22097
22107
  }
22098
22108
  updatePropsAction(actionName, props) {
@@ -22592,7 +22602,7 @@ var WeaveMutexManager = class {
22592
22602
  };
22593
22603
 
22594
22604
  //#endregion
22595
- //#region src/utils/watch-map.ts
22605
+ //#region src/internal-utils/watch-map.ts
22596
22606
  function watchMap(onChange, map = new Map()) {
22597
22607
  const handler = { get(target, prop, receiver) {
22598
22608
  if (prop === "set") return (key, value$1) => {
@@ -22647,14 +22657,13 @@ var WeaveAsyncManager = class {
22647
22657
  this.asyncElements = watchMap(() => {
22648
22658
  this.instance.emitEvent("onAsyncElementChange");
22649
22659
  }, new Map());
22650
- this.instance.addEventListener("onRoomLoaded", (isRoomLoaded) => {
22651
- if (!isRoomLoaded) return;
22652
- const roomHasResourcesToLoad = this.roomHasResourcesToLoad();
22653
- if (!roomHasResourcesToLoad && !this.asyncElementsLoadedEventEmitted) {
22654
- this.instance.emitEvent("onAsyncElementsLoaded");
22655
- this.asyncElementsLoadedEventEmitted = true;
22656
- }
22657
- });
22660
+ }
22661
+ checkForAsyncElements(elements) {
22662
+ const amountAsyncResourcesExtracted = this.extractAsyncResources(elements);
22663
+ if (amountAsyncResourcesExtracted === 0 && !this.asyncElementsLoadedEventEmitted) {
22664
+ this.instance.emitEvent("onAsyncElementsLoaded");
22665
+ this.asyncElementsLoadedEventEmitted = true;
22666
+ }
22658
22667
  }
22659
22668
  extractAsyncElements(state) {
22660
22669
  const asyncElements = [];
@@ -22670,11 +22679,20 @@ var WeaveAsyncManager = class {
22670
22679
  } else for (const element of Object.values(state.weave)) traverse(element);
22671
22680
  return asyncElements;
22672
22681
  }
22673
- roomHasResourcesToLoad() {
22682
+ extractAsyncResources(elements) {
22674
22683
  const roomData = this.instance.getStore().getState();
22675
- const jsonRoomData = JSON.parse(JSON.stringify(roomData));
22684
+ let jsonRoomData = JSON.parse(JSON.stringify(roomData));
22685
+ if (elements) jsonRoomData = elements;
22676
22686
  const asyncElements = this.extractAsyncElements(jsonRoomData);
22677
- return asyncElements.length > 0;
22687
+ for (const element of asyncElements) {
22688
+ const elementId = element.props?.id;
22689
+ if (!elementId) continue;
22690
+ if (!this.asyncElements.has(elementId)) this.asyncElements.set(elementId, {
22691
+ type: element.type,
22692
+ status: WEAVE_ASYNC_STATUS.NOT_LOADED
22693
+ });
22694
+ }
22695
+ return asyncElements.length;
22678
22696
  }
22679
22697
  asyncElementsLoaded() {
22680
22698
  return [...this.asyncElements.values()].every((el) => el.status === WEAVE_ASYNC_STATUS.LOADED);
@@ -23120,8 +23138,8 @@ var Weave = class {
23120
23138
  getActiveAction() {
23121
23139
  return this.actionsManager.getActiveAction();
23122
23140
  }
23123
- triggerAction(actionName, params) {
23124
- return this.actionsManager.triggerAction(actionName, params);
23141
+ triggerAction(actionName, params, forceExecution = false) {
23142
+ return this.actionsManager.triggerAction(actionName, params, forceExecution);
23125
23143
  }
23126
23144
  getPropsAction(actionName) {
23127
23145
  return this.actionsManager.getPropsAction(actionName);
@@ -23153,9 +23171,10 @@ var Weave = class {
23153
23171
  return this.stateManager.getNode(nodeKey);
23154
23172
  }
23155
23173
  addNode(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23174
+ const { origin,...restOptions } = options;
23156
23175
  this.stateTransactional(() => {
23157
- this.addNodeNT(node, parentId, options);
23158
- });
23176
+ this.addNodeNT(node, parentId, restOptions);
23177
+ }, origin);
23159
23178
  }
23160
23179
  addNodeNT(node, parentId = "mainLayer", options = DEFAULT_ADD_NODE_OPTIONS) {
23161
23180
  const { index, emitUserChangeEvent, overrideUserChangeType } = mergeExceptArrays(DEFAULT_ADD_NODE_OPTIONS, options);
@@ -23176,9 +23195,10 @@ var Weave = class {
23176
23195
  }
23177
23196
  }
23178
23197
  updateNode(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23198
+ const { origin,...restOptions } = options;
23179
23199
  this.stateTransactional(() => {
23180
- this.updateNodeNT(node, options);
23181
- });
23200
+ this.updateNodeNT(node, restOptions);
23201
+ }, origin);
23182
23202
  }
23183
23203
  updateNodeNT(node, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23184
23204
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23196,9 +23216,10 @@ var Weave = class {
23196
23216
  }
23197
23217
  }
23198
23218
  updateNodes(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23219
+ const { origin,...restOptions } = options;
23199
23220
  this.stateTransactional(() => {
23200
- this.updateNodesNT(nodes, options);
23201
- });
23221
+ this.updateNodesNT(nodes, restOptions);
23222
+ }, origin);
23202
23223
  }
23203
23224
  updateNodesNT(nodes, options = DEFAULT_UPDATE_NODE_OPTIONS) {
23204
23225
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_UPDATE_NODE_OPTIONS, options);
@@ -23222,9 +23243,10 @@ var Weave = class {
23222
23243
  }
23223
23244
  }
23224
23245
  removeNode(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23246
+ const { origin,...restOptions } = options;
23225
23247
  this.stateTransactional(() => {
23226
- this.removeNodeNT(node, options);
23227
- });
23248
+ this.removeNodeNT(node, restOptions);
23249
+ }, origin);
23228
23250
  }
23229
23251
  removeNodeNT(node, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23230
23252
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_REMOVE_NODE_OPTIONS, options);
@@ -23256,9 +23278,10 @@ var Weave = class {
23256
23278
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23257
23279
  }
23258
23280
  removeNodes(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23281
+ const { origin,...restOptions } = options;
23259
23282
  this.stateTransactional(() => {
23260
- this.removeNodesNT(nodes, options);
23261
- });
23283
+ this.removeNodesNT(nodes, restOptions);
23284
+ }, origin);
23262
23285
  }
23263
23286
  removeNodesNT(nodes, options = DEFAULT_REMOVE_NODE_OPTIONS) {
23264
23287
  for (const node of nodes) this.removeNodeNT(node, options);
@@ -23266,9 +23289,10 @@ var Weave = class {
23266
23289
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
23267
23290
  }
23268
23291
  zMoveNode(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23292
+ const { origin,...restOptions } = options;
23269
23293
  this.stateTransactional(() => {
23270
- this.zMoveNodeNT(node, position, options);
23271
- });
23294
+ this.zMoveNodeNT(node, position, restOptions);
23295
+ }, origin);
23272
23296
  }
23273
23297
  zMoveNodeNT(node, position, options = DEFAULT_MOVE_NODE_OPTIONS) {
23274
23298
  const { emitUserChangeEvent } = mergeExceptArrays(DEFAULT_MOVE_NODE_OPTIONS, options);
@@ -23322,8 +23346,8 @@ var Weave = class {
23322
23346
  getBoundingBox(nodes, config) {
23323
23347
  return getBoundingBox(nodes, config);
23324
23348
  }
23325
- stateTransactional(callback) {
23326
- this.stateManager.stateTransactional(callback);
23349
+ stateTransactional(callback, origin) {
23350
+ this.stateManager.stateTransactional(callback, origin);
23327
23351
  }
23328
23352
  moveUp(node) {
23329
23353
  this.zIndexManager.moveUp(node);
@@ -23487,6 +23511,9 @@ var Weave = class {
23487
23511
  nodeHandler.show(node);
23488
23512
  }
23489
23513
  }
23514
+ checkForAsyncElements(elements) {
23515
+ this.asyncManager.checkForAsyncElements(elements);
23516
+ }
23490
23517
  asyncElementsLoaded() {
23491
23518
  return this.asyncManager.asyncElementsLoaded();
23492
23519
  }
@@ -23557,7 +23584,93 @@ var Weave = class {
23557
23584
  };
23558
23585
 
23559
23586
  //#endregion
23560
- //#region src/utils/upscale.ts
23587
+ //#region src/utils/image.ts
23588
+ function loadImageSource(image, options) {
23589
+ return new Promise((resolve, reject) => {
23590
+ const { crossOrigin } = mergeExceptArrays({ crossOrigin: "anonymous" }, options);
23591
+ const reader = new FileReader();
23592
+ reader.onloadend = () => {
23593
+ const imageSource = Konva.Util.createImageElement();
23594
+ imageSource.crossOrigin = crossOrigin;
23595
+ imageSource.onerror = () => {
23596
+ reject();
23597
+ };
23598
+ imageSource.onload = async () => {
23599
+ resolve(imageSource);
23600
+ };
23601
+ imageSource.src = reader.result;
23602
+ };
23603
+ reader.onerror = () => {
23604
+ reject(new Error("Failed to read image file"));
23605
+ };
23606
+ reader.readAsDataURL(image);
23607
+ });
23608
+ }
23609
+ async function downscaleImageFile(file, ratio) {
23610
+ const bitmap = await createImageBitmap(file);
23611
+ const width = Math.round(bitmap.width * ratio);
23612
+ const height = Math.round(bitmap.height * ratio);
23613
+ const canvas = document.createElement("canvas");
23614
+ canvas.width = width;
23615
+ canvas.height = height;
23616
+ const ctx = canvas.getContext("2d");
23617
+ ctx.drawImage(bitmap, 0, 0, width, height);
23618
+ return new Promise((resolve) => {
23619
+ canvas.toBlob((blob) => resolve(blob), file.type, .9);
23620
+ });
23621
+ }
23622
+ function getImageSizeFromFile(file) {
23623
+ return new Promise((resolve, reject) => {
23624
+ const img = new Image();
23625
+ const url = URL.createObjectURL(file);
23626
+ img.onload = () => {
23627
+ resolve({
23628
+ width: img.naturalWidth,
23629
+ height: img.naturalHeight
23630
+ });
23631
+ URL.revokeObjectURL(url);
23632
+ };
23633
+ img.onerror = reject;
23634
+ img.src = url;
23635
+ });
23636
+ }
23637
+ function getDownscaleRatio(width, height, options) {
23638
+ const { maxWidth, maxHeight } = mergeExceptArrays({
23639
+ maxWidth: 200,
23640
+ maxHeight: 200
23641
+ }, options);
23642
+ const widthRatio = maxWidth / width;
23643
+ const heightRatio = maxHeight / height;
23644
+ return Math.min(widthRatio, heightRatio, 1);
23645
+ }
23646
+ const downscaleImageFromURL = (url, options) => {
23647
+ return new Promise((resolve, reject) => {
23648
+ const { type, crossOrigin, maxWidth, maxHeight } = mergeExceptArrays({
23649
+ type: "image/png",
23650
+ crossOrigin: "anonymous",
23651
+ maxWidth: 200,
23652
+ maxHeight: 200
23653
+ }, options);
23654
+ const img = new Image();
23655
+ img.crossOrigin = crossOrigin;
23656
+ img.onload = () => {
23657
+ const ratio = Math.min(maxWidth / img.width, maxHeight / img.height, 1);
23658
+ const width = Math.round(img.width * ratio);
23659
+ const height = Math.round(img.height * ratio);
23660
+ const canvas = document.createElement("canvas");
23661
+ canvas.width = width;
23662
+ canvas.height = height;
23663
+ const ctx = canvas.getContext("2d");
23664
+ ctx.drawImage(img, 0, 0, width, height);
23665
+ resolve(canvas.toDataURL(type));
23666
+ };
23667
+ img.onerror = reject;
23668
+ img.src = url;
23669
+ });
23670
+ };
23671
+
23672
+ //#endregion
23673
+ //#region src/internal-utils/upscale.ts
23561
23674
  const setupUpscaleStage = (instance, stage) => {
23562
23675
  const config = instance.getConfiguration();
23563
23676
  const doUpscale = config.performance?.upscale?.enabled ?? false;
@@ -23991,7 +24104,7 @@ const WEAVE_LINE_NODE_DEFAULT_CONFIG = { snapAngles: {
23991
24104
  } };
23992
24105
 
23993
24106
  //#endregion
23994
- //#region src/utils/greedy-snapper.ts
24107
+ //#region src/internal-utils/greedy-snapper.ts
23995
24108
  var GreedySnapper = class {
23996
24109
  snappedAngle = null;
23997
24110
  constructor(config) {
@@ -25008,7 +25121,12 @@ const WEAVE_IMAGE_CROP_ANCHOR_POSITION = {
25008
25121
  const WEAVE_IMAGE_DEFAULT_CONFIG = {
25009
25122
  performance: { cache: { enabled: false } },
25010
25123
  style: { placeholder: { fill: "#aaaaaa" } },
25124
+ imageLoading: {
25125
+ maxRetryAttempts: 15,
25126
+ retryDelayMs: 2e3
25127
+ },
25011
25128
  crossOrigin: "anonymous",
25129
+ useFallbackImage: true,
25012
25130
  cropMode: {
25013
25131
  gridLines: { enabled: true },
25014
25132
  overlay: { fill: "rgba(0,0,0,0.2)" },
@@ -25578,8 +25696,10 @@ var WeaveImageCrop = class WeaveImageCrop {
25578
25696
  var WeaveImageNode = class extends WeaveNode {
25579
25697
  imageBitmapCache = {};
25580
25698
  imageSource = {};
25699
+ imageFallback = {};
25581
25700
  imageState = {};
25582
- imageIconSource = null;
25701
+ imageTryoutAttempts = {};
25702
+ imageTryoutIds = {};
25583
25703
  nodeType = WEAVE_IMAGE_NODE_TYPE;
25584
25704
  constructor(params) {
25585
25705
  super();
@@ -25589,9 +25709,14 @@ var WeaveImageNode = class extends WeaveNode {
25589
25709
  y: 0,
25590
25710
  time: 0
25591
25711
  };
25592
- this.lastTapTime = 0;
25593
25712
  this.config = mergeExceptArrays(WEAVE_IMAGE_DEFAULT_CONFIG, config);
25594
25713
  this.imageCrop = null;
25714
+ this.imageBitmapCache = {};
25715
+ this.imageSource = {};
25716
+ this.imageState = {};
25717
+ this.imageTryoutIds = {};
25718
+ this.imageTryoutAttempts = {};
25719
+ this.imageFallback = {};
25595
25720
  }
25596
25721
  getConfiguration() {
25597
25722
  return this.config;
@@ -25672,6 +25797,12 @@ var WeaveImageNode = class extends WeaveNode {
25672
25797
  cropping: false
25673
25798
  });
25674
25799
  this.setupDefaultNodeAugmentation(image);
25800
+ image.defineMousePointer = () => {
25801
+ if (this.imageState[id]?.status === "loading") return "wait";
25802
+ const selectedNodes = this.getSelectionPlugin()?.getSelectedNodes() ?? [];
25803
+ if (this.isSelecting() && selectedNodes.includes(image)) return "grab";
25804
+ return "pointer";
25805
+ };
25675
25806
  image.movedToContainer = () => {
25676
25807
  const stage = this.instance.getStage();
25677
25808
  const image$1 = stage.findOne(`#${id}`);
@@ -25750,8 +25881,8 @@ var WeaveImageNode = class extends WeaveNode {
25750
25881
  image.dblClick = () => {
25751
25882
  if (this.imageState[id]?.loaded && !this.imageState[id]?.error) this.config.onDblClick?.(this, image);
25752
25883
  };
25753
- if (this.imageSource[id]) {
25754
- imagePlaceholder.destroy();
25884
+ if (this.imageSource[id] && imageProps.imageURL) {
25885
+ imagePlaceholder?.destroy();
25755
25886
  const imageSource = this.imageSource[id];
25756
25887
  internalImage.setAttrs({
25757
25888
  image: imageSource,
@@ -25776,13 +25907,14 @@ var WeaveImageNode = class extends WeaveNode {
25776
25907
  height: sourceImageHeight
25777
25908
  });
25778
25909
  this.imageState[id] = {
25910
+ status: "loaded",
25779
25911
  loaded: true,
25780
25912
  error: false
25781
25913
  };
25782
25914
  this.updateImageCrop(image);
25783
25915
  } else {
25784
25916
  this.updatePlaceholderSize(image, imagePlaceholder);
25785
- this.loadImage(imageProps, image);
25917
+ this.loadImage(imageProps, image, true);
25786
25918
  }
25787
25919
  if (this.config.performance.cache.enabled) image.on("transformend", () => {
25788
25920
  this.cacheNode(image);
@@ -26013,7 +26145,7 @@ var WeaveImageNode = class extends WeaveNode {
26013
26145
  scaleY: 1,
26014
26146
  rotation: 0,
26015
26147
  visible: true,
26016
- fill: "#ccccccff",
26148
+ fill: this.config.style.placeholder.fill,
26017
26149
  strokeWidth: 0,
26018
26150
  draggable: false,
26019
26151
  zIndex: 0
@@ -26047,7 +26179,7 @@ var WeaveImageNode = class extends WeaveNode {
26047
26179
  scaleY: 1,
26048
26180
  rotation: 0,
26049
26181
  visible: true,
26050
- fill: "#ccccccff",
26182
+ fill: this.config.style.placeholder.fill,
26051
26183
  strokeWidth: 0,
26052
26184
  draggable: false,
26053
26185
  zIndex: 0
@@ -26089,59 +26221,111 @@ var WeaveImageNode = class extends WeaveNode {
26089
26221
  }
26090
26222
  this.cacheNode(nodeInstance);
26091
26223
  }
26092
- preloadImage(imageId, imageURL, { onLoad, onError }) {
26224
+ preloadFallbackImage(imageId, imageURL, { onLoad, onError }) {
26225
+ const imageURLToLoad = imageURL ?? "http://localhost/false-image";
26226
+ this.imageFallback[imageId] = Konva.Util.createImageElement();
26227
+ this.imageFallback[imageId].crossOrigin = this.config.crossOrigin;
26228
+ this.imageFallback[imageId].onerror = (error) => {
26229
+ this.imageState[imageId] = {
26230
+ status: "error-fallback",
26231
+ loaded: false,
26232
+ error: true
26233
+ };
26234
+ onError(error);
26235
+ };
26236
+ this.imageFallback[imageId].onload = async () => {
26237
+ this.imageState[imageId] = {
26238
+ status: "loading",
26239
+ loaded: true,
26240
+ error: false
26241
+ };
26242
+ onLoad();
26243
+ };
26244
+ this.imageState[imageId] = {
26245
+ status: "loading",
26246
+ loaded: false,
26247
+ error: false
26248
+ };
26249
+ try {
26250
+ this.imageFallback[imageId].src = imageURLToLoad;
26251
+ } catch (ex) {
26252
+ console.error(ex);
26253
+ }
26254
+ }
26255
+ preloadImage(imageId, imageURL, { onLoad, onError }, loadingTryout = false) {
26256
+ const imageURLToLoad = imageURL ?? "http://localhost/false-image";
26093
26257
  this.imageSource[imageId] = Konva.Util.createImageElement();
26094
26258
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
26095
26259
  this.imageSource[imageId].onerror = (error) => {
26096
- this.imageState[imageId] = {
26260
+ if (!loadingTryout) this.imageState[imageId] = {
26261
+ status: "error",
26097
26262
  loaded: false,
26098
26263
  error: true
26099
26264
  };
26100
26265
  delete this.imageSource[imageId];
26101
- delete this.imageState[imageId];
26102
26266
  onError(error);
26103
26267
  };
26104
26268
  this.imageSource[imageId].onload = async () => {
26105
26269
  this.imageState[imageId] = {
26270
+ status: "loaded",
26106
26271
  loaded: true,
26107
26272
  error: false
26108
26273
  };
26109
26274
  onLoad();
26110
26275
  };
26111
- this.imageState[imageId] = {
26276
+ if (this.imageState[imageId]) this.imageState[imageId].status = "loading";
26277
+ else this.imageState[imageId] = {
26278
+ status: "loading",
26112
26279
  loaded: false,
26113
26280
  error: false
26114
26281
  };
26115
26282
  try {
26116
- if (imageURL) this.imageSource[imageId].src = imageURL;
26283
+ this.imageSource[imageId].src = imageURLToLoad;
26117
26284
  } catch (ex) {
26118
26285
  console.error(ex);
26119
26286
  }
26120
26287
  }
26121
- loadImage(params, image) {
26288
+ loadImage(params, image, useFallback = false, loadTryout = false) {
26122
26289
  const imageProps = params;
26123
26290
  const { id } = imageProps;
26124
26291
  const imagePlaceholder = image.findOne(`#${id}-placeholder`);
26125
26292
  const internalImage = image.findOne(`#${id}-image`);
26126
- const realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
26293
+ let realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
26294
+ let preloadFunction = this.preloadImage.bind(this);
26295
+ const loadFallback = useFallback && imageProps.imageFallback && this.config.useFallbackImage;
26296
+ if (loadFallback) {
26297
+ preloadFunction = this.preloadFallbackImage.bind(this);
26298
+ realImageURL = imageProps.imageFallback;
26299
+ }
26127
26300
  this.loadAsyncElement(id);
26128
- this.preloadImage(id, realImageURL ?? "", {
26301
+ preloadFunction(id, realImageURL ?? "", {
26129
26302
  onLoad: () => {
26130
- if (image && imagePlaceholder && internalImage) {
26303
+ if (useFallback) this.imageTryoutIds[id] = setTimeout(() => {
26304
+ const node = this.instance.getStage().findOne(`#${id}`);
26305
+ if (node) {
26306
+ this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1;
26307
+ this.loadImage(node.getAttrs(), node, false, true);
26308
+ }
26309
+ }, this.config.imageLoading.retryDelayMs);
26310
+ if (useFallback && loadTryout && this.imageTryoutIds[id]) {
26311
+ clearTimeout(this.imageTryoutIds[id]);
26312
+ delete this.imageTryoutIds[id];
26313
+ }
26314
+ if (image && internalImage) {
26131
26315
  image.setAttrs({
26132
26316
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26133
26317
  height: imageProps.height ? imageProps.height : this.imageSource[id].height
26134
26318
  });
26135
- imagePlaceholder.destroy();
26136
- const imageSource = this.imageSource[id];
26319
+ imagePlaceholder?.destroy();
26320
+ const imageSource = loadFallback ? this.imageFallback[id] : this.imageSource[id];
26137
26321
  internalImage.setAttrs({
26138
26322
  width: imageProps.width ? imageProps.width : this.imageSource[id].width,
26139
26323
  height: imageProps.height ? imageProps.height : this.imageSource[id].height,
26140
26324
  image: imageSource,
26141
26325
  visible: true
26142
26326
  });
26143
- let sourceImageWidth = this.imageSource[id].width;
26144
- let sourceImageHeight = this.imageSource[id].height;
26327
+ let sourceImageWidth = imageProps.width ? imageProps.width : this.imageSource[id].width;
26328
+ let sourceImageHeight = imageProps.height ? imageProps.height : this.imageSource[id].height;
26145
26329
  if (image.getAttrs().imageInfo) {
26146
26330
  sourceImageWidth = image.getAttrs().imageInfo.width;
26147
26331
  sourceImageHeight = image.getAttrs().imageInfo.height;
@@ -26160,40 +26344,56 @@ var WeaveImageNode = class extends WeaveNode {
26160
26344
  width: imageRect.width,
26161
26345
  height: imageRect.height
26162
26346
  });
26163
- this.imageState[id] = {
26164
- loaded: true,
26165
- error: false
26166
- };
26347
+ const stage = this.instance.getStage();
26348
+ if (!loadFallback) {
26349
+ if (!this.instance.isServerSide() && stage.container().style.cursor === "wait") stage.container().style.cursor = "pointer";
26350
+ this.imageState[id] = {
26351
+ status: "loaded",
26352
+ loaded: true,
26353
+ error: false
26354
+ };
26355
+ }
26167
26356
  this.updateImageCrop(image);
26168
26357
  this.resolveAsyncElement(id);
26169
26358
  this.cacheNode(image);
26170
26359
  }
26171
26360
  },
26172
26361
  onError: (error) => {
26362
+ if (!this.config.useFallbackImage) this.imageTryoutIds[id] = setTimeout(() => {
26363
+ const node = this.instance.getStage().findOne(`#${id}`);
26364
+ if (node) {
26365
+ this.imageTryoutAttempts[id] = (this.imageTryoutAttempts[id] ?? 0) + 1;
26366
+ this.loadImage(node.getAttrs(), node, false, true);
26367
+ }
26368
+ }, this.config.imageLoading.retryDelayMs);
26369
+ if (loadTryout) {
26370
+ const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0;
26371
+ if (tryoutAttempts < this.config.imageLoading.maxRetryAttempts) this.imageTryoutIds[id] = setTimeout(() => {
26372
+ const node = this.instance.getStage().findOne(`#${id}`);
26373
+ if (node) {
26374
+ this.imageTryoutAttempts[id] = tryoutAttempts + 1;
26375
+ this.loadImage(node.getAttrs(), node, false, true);
26376
+ }
26377
+ }, this.config.imageLoading.retryDelayMs);
26378
+ return;
26379
+ }
26380
+ if (this.config.useFallbackImage && !useFallback && !loadTryout && imageProps.imageFallback) {
26381
+ this.loadImage({ ...params }, image, true);
26382
+ return;
26383
+ }
26173
26384
  this.imageState[id] = {
26385
+ status: "error",
26174
26386
  loaded: false,
26175
26387
  error: true
26176
26388
  };
26177
- image.setAttrs({
26178
- image: void 0,
26179
- width: 100,
26180
- height: 100,
26181
- imageInfo: {
26182
- width: 100,
26183
- height: 100
26184
- },
26185
- uncroppedImage: {
26186
- width: 100,
26187
- height: 100
26188
- }
26189
- });
26389
+ image.setAttrs({ image: void 0 });
26190
26390
  this.resolveAsyncElement(id);
26191
26391
  console.error("Error loading image", realImageURL, error);
26192
26392
  imagePlaceholder?.setAttrs({ visible: true });
26193
26393
  internalImage?.setAttrs({ visible: false });
26194
26394
  this.cacheNode(image);
26195
26395
  }
26196
- });
26396
+ }, loadTryout);
26197
26397
  }
26198
26398
  updatePlaceholderSize(image, imagePlaceholder) {
26199
26399
  const imageAttrs = image.getAttrs();
@@ -26214,8 +26414,16 @@ var WeaveImageNode = class extends WeaveNode {
26214
26414
  const internalImage = image?.findOne(`#${imageAttrs.id}-image`);
26215
26415
  if (!this.imageState[imageAttrs.id ?? ""]?.loaded) return;
26216
26416
  if (image && internalImage && !imageAttrs.adding && imageAttrs.cropInfo && imageAttrs.uncroppedImage) {
26417
+ const imageId = imageAttrs.id ?? "";
26217
26418
  const originalImageInfo = imageAttrs.imageInfo;
26218
- const actualImageInfo = this.imageSource[imageAttrs.id ?? ""];
26419
+ let actualImageInfo = {
26420
+ width: this.imageSource[imageId]?.width ?? 0,
26421
+ height: this.imageSource[imageId]?.height ?? 0
26422
+ };
26423
+ if (actualImageInfo.width === 0 && actualImageInfo.height === 0 && this.imageFallback[imageId]) actualImageInfo = {
26424
+ width: this.imageFallback[imageId].width,
26425
+ height: this.imageFallback[imageId].height
26426
+ };
26219
26427
  const originalActualDiffScale = originalImageInfo ? actualImageInfo.width / originalImageInfo.width : 1;
26220
26428
  const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
26221
26429
  const cropScale = imageAttrs.cropInfo ? imageAttrs.cropInfo.scaleX : actualScale;
@@ -26244,6 +26452,9 @@ var WeaveImageNode = class extends WeaveNode {
26244
26452
  internalImage.height(imageAttrs.uncroppedImage.height);
26245
26453
  }
26246
26454
  }
26455
+ getFallbackImageSource(imageId) {
26456
+ return this.imageFallback[imageId];
26457
+ }
26247
26458
  getImageSource(imageId) {
26248
26459
  return this.imageSource[imageId];
26249
26460
  }
@@ -26295,6 +26506,23 @@ var WeaveImageNode = class extends WeaveNode {
26295
26506
  getIsAsync() {
26296
26507
  return true;
26297
26508
  }
26509
+ forceLoadImage(nodeInstance) {
26510
+ const nodeId = nodeInstance.getAttrs().id ?? "";
26511
+ const node = this.instance.getStage().findOne(`#${nodeId}`);
26512
+ if (this.imageTryoutIds[nodeId]) {
26513
+ clearTimeout(this.imageTryoutIds[nodeId]);
26514
+ delete this.imageTryoutIds[nodeId];
26515
+ }
26516
+ if (node) this.loadImage(node.getAttrs(), node, false, false);
26517
+ }
26518
+ onDestroy(nodeInstance) {
26519
+ const nodeId = nodeInstance.getAttrs().id ?? "";
26520
+ delete this.imageSource[nodeId];
26521
+ delete this.imageState[nodeId];
26522
+ delete this.imageTryoutAttempts[nodeId];
26523
+ delete this.imageFallback[nodeId];
26524
+ nodeInstance.destroy();
26525
+ }
26298
26526
  };
26299
26527
 
26300
26528
  //#endregion
@@ -33018,14 +33246,19 @@ var WeaveBrushToolAction = class extends WeaveAction {
33018
33246
  });
33019
33247
  window.addEventListener("keydown", (e) => {
33020
33248
  if (e.code === "Enter" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) {
33249
+ e.stopPropagation();
33021
33250
  this.cancelAction();
33022
33251
  return;
33023
33252
  }
33024
33253
  if (e.code === "Space" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) {
33254
+ e.stopPropagation();
33025
33255
  this.isSpacePressed = true;
33026
33256
  return;
33027
33257
  }
33028
- if (e.code === "Escape" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) this.cancelAction();
33258
+ if (e.code === "Escape" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) {
33259
+ e.stopPropagation();
33260
+ this.cancelAction();
33261
+ }
33029
33262
  });
33030
33263
  const handlePointerDown = (e) => {
33031
33264
  if (this.state === BRUSH_TOOL_STATE.INACTIVE) return;
@@ -33352,42 +33585,62 @@ var WeaveTextToolAction = class extends WeaveAction {
33352
33585
 
33353
33586
  //#endregion
33354
33587
  //#region src/actions/image-tool/constants.ts
33355
- const IMAGE_TOOL_ACTION_NAME = "imageTool";
33356
- const IMAGE_TOOL_STATE = {
33588
+ const WEAVE_IMAGE_TOOL_ACTION_NAME = "imageTool";
33589
+ const WEAVE_IMAGE_TOOL_UPLOAD_TYPE = {
33590
+ ["FILE"]: "file",
33591
+ ["IMAGE_URL"]: "imageURL"
33592
+ };
33593
+ const WEAVE_IMAGE_TOOL_STATE = {
33357
33594
  ["IDLE"]: "idle",
33358
33595
  ["DEFINING_POSITION"]: "definingPosition",
33359
33596
  ["SELECTED_POSITION"]: "selectedPosition",
33360
33597
  ["ADDING"]: "adding",
33361
33598
  ["FINISHED"]: "finished"
33362
33599
  };
33363
- const IMAGE_TOOL_LOAD_FROM = {
33364
- ["DATAURL"]: "dataURL",
33365
- ["URL"]: "url"
33366
- };
33600
+ const WEAVE_IMAGE_TOOL_CONFIG_DEFAULT = { style: { cursor: {
33601
+ padding: 5,
33602
+ imageThumbnail: {
33603
+ width: 250,
33604
+ height: 250,
33605
+ shadowColor: "#aaaaaa",
33606
+ shadowBlur: 10,
33607
+ shadowOffset: {
33608
+ x: 2,
33609
+ y: 2
33610
+ },
33611
+ shadowOpacity: .5
33612
+ }
33613
+ } } };
33367
33614
 
33368
33615
  //#endregion
33369
33616
  //#region src/actions/image-tool/image-tool.ts
33370
33617
  var WeaveImageToolAction = class extends WeaveAction {
33371
33618
  initialized = false;
33372
33619
  initialCursor = null;
33373
- cursorPadding = 5;
33620
+ imageFile = null;
33621
+ imageURL = null;
33374
33622
  forceMainContainer = false;
33623
+ ignoreKeyboardEvents = false;
33624
+ ignorePointerEvents = false;
33625
+ uploadType = null;
33375
33626
  onPropsChange = void 0;
33376
33627
  update = void 0;
33377
- constructor() {
33628
+ constructor(params) {
33378
33629
  super();
33630
+ this.config = mergeExceptArrays(WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, params?.config ?? {});
33379
33631
  this.pointers = new Map();
33380
33632
  this.initialized = false;
33381
- this.state = IMAGE_TOOL_STATE.IDLE;
33633
+ this.state = WEAVE_IMAGE_TOOL_STATE.IDLE;
33382
33634
  this.imageId = null;
33383
33635
  this.tempImageId = null;
33384
33636
  this.tempImageNode = null;
33385
33637
  this.container = void 0;
33386
33638
  this.imageURL = null;
33639
+ this.uploadType = null;
33387
33640
  this.clickPoint = null;
33388
33641
  }
33389
33642
  getName() {
33390
- return IMAGE_TOOL_ACTION_NAME;
33643
+ return WEAVE_IMAGE_TOOL_ACTION_NAME;
33391
33644
  }
33392
33645
  initProps() {
33393
33646
  return {
@@ -33401,14 +33654,15 @@ var WeaveImageToolAction = class extends WeaveAction {
33401
33654
  this.instance.addEventListener("onStageDrop", (e) => {
33402
33655
  const dragId = this.instance.getDragStartedId();
33403
33656
  const dragProperties = this.instance.getDragProperties();
33404
- if (dragProperties && dragId === IMAGE_TOOL_ACTION_NAME) {
33657
+ if (dragProperties && dragId === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33405
33658
  this.instance.getStage().setPointersPositions(e);
33406
33659
  const position = getPositionRelativeToContainerOnPosition(this.instance);
33407
- this.instance.triggerAction(IMAGE_TOOL_ACTION_NAME, {
33408
- imageURL: dragProperties.imageURL,
33409
- ...dragProperties.imageId && { imageId: dragProperties.imageId },
33410
- ...dragProperties.imageWidth && { imageWidth: dragProperties.imageWidth },
33411
- ...dragProperties.imageHeight && { imageHeight: dragProperties.imageHeight },
33660
+ if (!position) return;
33661
+ this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
33662
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL,
33663
+ image: dragProperties.imageURL,
33664
+ ...dragProperties.imageId ? { imageId: dragProperties.imageId } : {},
33665
+ ...dragProperties.forceMainContainer && { forceMainContainer: dragProperties.forceMainContainer },
33412
33666
  position
33413
33667
  });
33414
33668
  }
@@ -33417,87 +33671,93 @@ var WeaveImageToolAction = class extends WeaveAction {
33417
33671
  setupEvents() {
33418
33672
  const stage = this.instance.getStage();
33419
33673
  window.addEventListener("keydown", (e) => {
33420
- if (e.code === "Escape" && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33674
+ if (e.code === "Escape" && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME && !this.ignoreKeyboardEvents) {
33421
33675
  this.cancelAction();
33422
33676
  return;
33423
33677
  }
33424
33678
  });
33425
33679
  stage.on("pointerdown", (e) => {
33426
33680
  this.setTapStart(e);
33681
+ if (this.ignorePointerEvents) return;
33427
33682
  this.pointers.set(e.evt.pointerId, {
33428
33683
  x: e.evt.clientX,
33429
33684
  y: e.evt.clientY
33430
33685
  });
33431
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33432
- this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
33686
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33687
+ this.state = WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION;
33433
33688
  return;
33434
33689
  }
33435
- if (this.state === IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = IMAGE_TOOL_STATE.SELECTED_POSITION;
33690
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION;
33436
33691
  });
33437
33692
  stage.on("pointermove", (e) => {
33438
- if (this.state === IMAGE_TOOL_STATE.IDLE) return;
33693
+ if (this.ignorePointerEvents) return;
33694
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.IDLE) return;
33439
33695
  this.setCursor();
33440
- if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
33441
- this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
33696
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME) {
33697
+ this.state = WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION;
33442
33698
  return;
33443
33699
  }
33444
- if ([IMAGE_TOOL_STATE.DEFINING_POSITION, IMAGE_TOOL_STATE.SELECTED_POSITION].includes(this.state) && this.tempImageNode && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME && e.evt.pointerType === "mouse") {
33700
+ if ([WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION, WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION].includes(this.state) && this.tempImageNode && this.instance.getActiveAction() === WEAVE_IMAGE_TOOL_ACTION_NAME && e.evt.pointerType === "mouse") {
33445
33701
  const mousePos = stage.getRelativePointerPosition();
33702
+ const cursorPadding = this.config.style.cursor.padding;
33446
33703
  this.tempImageNode.setAttrs({
33447
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33448
- y: (mousePos?.y ?? 0) + this.cursorPadding
33704
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33705
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleX()
33449
33706
  });
33450
33707
  }
33451
33708
  });
33452
33709
  stage.on("pointerup", (e) => {
33710
+ if (this.ignorePointerEvents) return;
33453
33711
  this.pointers.delete(e.evt.pointerId);
33454
- if (this.state === IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33712
+ if (this.state === WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
33455
33713
  });
33456
33714
  this.initialized = true;
33457
33715
  }
33458
33716
  setState(state) {
33459
33717
  this.state = state;
33460
33718
  }
33461
- loadImage(imageData, kind, position) {
33719
+ async loadImage(params) {
33462
33720
  this.setCursor();
33463
33721
  this.setFocusStage();
33464
33722
  if (!this.imageId) {
33465
33723
  this.cancelAction();
33466
33724
  return;
33467
33725
  }
33468
- this.imageURL = kind === IMAGE_TOOL_LOAD_FROM.DATAURL ? "not-defined" : imageData;
33469
33726
  const imageNodeHandler = this.getImageNodeHandler();
33470
- if (!imageNodeHandler) {
33471
- this.cancelAction();
33472
- return;
33473
- }
33474
- if (IMAGE_TOOL_LOAD_FROM.URL === kind) {
33475
- this.props = {
33476
- ...this.props,
33477
- imageURL: this.imageURL,
33478
- width: this.props.loadImageWidth,
33479
- height: this.props.loadImageHeight
33727
+ if (!imageNodeHandler) return;
33728
+ const actualImageId = this.imageId;
33729
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE) {
33730
+ const image = params.image;
33731
+ const realImageSize = await getImageSizeFromFile(image.file);
33732
+ const downscaledImage = await downscaleImageFile(image.file, image.downscaleRatio);
33733
+ const reader = new FileReader();
33734
+ reader.onloadend = () => {
33735
+ imageNodeHandler.preloadFallbackImage(actualImageId, reader.result, {
33736
+ onLoad: () => {
33737
+ this.props = {
33738
+ ...this.props,
33739
+ imageFallback: reader.result,
33740
+ imageURL: void 0,
33741
+ width: realImageSize.width,
33742
+ height: realImageSize.height
33743
+ };
33744
+ this.addImageNode(params?.position);
33745
+ },
33746
+ onError: () => {
33747
+ this.cancelAction();
33748
+ }
33749
+ });
33480
33750
  };
33481
- this.addImageNode(position);
33751
+ reader.onerror = () => {};
33752
+ reader.readAsDataURL(downscaledImage);
33753
+ }
33754
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL) {
33755
+ const image = params.image;
33756
+ setTimeout(() => {
33757
+ this.saveImageUrl(actualImageId, image.url);
33758
+ }, 0);
33759
+ this.addImageNode(params?.position);
33482
33760
  }
33483
- imageNodeHandler.preloadImage(this.imageId, imageData, {
33484
- onLoad: () => {
33485
- this.instance.emitEvent("onImageLoadEnd", void 0);
33486
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33487
- if (imageSource && this.imageId) this.props = {
33488
- ...this.props,
33489
- imageURL: this.imageURL,
33490
- width: imageSource.width,
33491
- height: imageSource.height
33492
- };
33493
- this.addImageNode(position);
33494
- },
33495
- onError: () => {
33496
- this.instance.emitEvent("onImageLoadEnd", new Error("Error loading image"));
33497
- this.cancelAction();
33498
- }
33499
- });
33500
- this.instance.emitEvent("onImageLoadStart");
33501
33761
  }
33502
33762
  isTouchDevice() {
33503
33763
  return window.matchMedia("(pointer: coarse)").matches;
@@ -33507,54 +33767,67 @@ var WeaveImageToolAction = class extends WeaveAction {
33507
33767
  this.setCursor();
33508
33768
  this.setFocusStage();
33509
33769
  if (position) {
33510
- this.setState(IMAGE_TOOL_STATE.SELECTED_POSITION);
33770
+ this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33511
33771
  this.handleAdding(position);
33512
33772
  return;
33513
33773
  }
33774
+ const imageNodeHandler = this.getImageNodeHandler();
33775
+ if (!imageNodeHandler) {
33776
+ this.cancelAction();
33777
+ return;
33778
+ }
33514
33779
  if (this.imageId) {
33515
33780
  const mousePos = stage.getRelativePointerPosition();
33516
33781
  this.tempImageId = v4_default();
33517
- const imageNodeHandler = this.getImageNodeHandler();
33518
- if (!imageNodeHandler) {
33519
- this.cancelAction();
33520
- return;
33521
- }
33522
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33782
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33783
+ if (this.uploadType === "file") imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33523
33784
  if (!imageSource) {
33524
33785
  this.cancelAction();
33525
33786
  return;
33526
33787
  }
33527
33788
  const aspectRatio = imageSource.width / imageSource.height;
33528
33789
  if (!this.tempImageNode && this.tempImageId && !this.isTouchDevice()) {
33790
+ const cursorPadding = this.config.style.cursor.padding;
33791
+ const imageThumbnailWidth = this.config.style.cursor.imageThumbnail.width;
33792
+ const imageThumbnailHeight = this.config.style.cursor.imageThumbnail.height;
33793
+ const shadowColor = this.config.style.cursor.imageThumbnail.shadowColor;
33794
+ const shadowBlur = this.config.style.cursor.imageThumbnail.shadowBlur;
33795
+ const shadowOffset = this.config.style.cursor.imageThumbnail.shadowOffset;
33796
+ const shadowOpacity = this.config.style.cursor.imageThumbnail.shadowOpacity;
33529
33797
  this.tempImageNode = new Konva.Image({
33530
33798
  id: this.tempImageId,
33531
- x: (mousePos?.x ?? 0) + this.cursorPadding,
33532
- y: (mousePos?.y ?? 0) + this.cursorPadding,
33533
- width: 240 * aspectRatio * (1 / stage.scaleX()),
33534
- height: 240 * (1 / stage.scaleY()),
33799
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
33800
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY(),
33801
+ width: imageThumbnailWidth * aspectRatio * (1 / stage.scaleX()),
33802
+ height: imageThumbnailHeight * (1 / stage.scaleY()),
33535
33803
  opacity: 1,
33536
33804
  adding: true,
33537
33805
  image: imageSource,
33538
33806
  stroke: "#000000ff",
33539
33807
  strokeWidth: 0,
33540
33808
  strokeScaleEnabled: true,
33541
- listening: false
33809
+ listening: false,
33810
+ shadowColor,
33811
+ shadowBlur,
33812
+ shadowOffset,
33813
+ shadowOpacity
33542
33814
  });
33543
33815
  this.instance.getMainLayer()?.add(this.tempImageNode);
33544
33816
  }
33545
33817
  this.instance.emitEvent("onAddingImage", { imageURL: this.props.imageURL });
33546
33818
  }
33547
33819
  this.clickPoint = null;
33548
- this.setState(IMAGE_TOOL_STATE.DEFINING_POSITION);
33820
+ this.setState(WEAVE_IMAGE_TOOL_STATE.DEFINING_POSITION);
33549
33821
  }
33550
33822
  handleAdding(position) {
33823
+ const imageNodeHandler = this.getImageNodeHandler();
33824
+ if (!imageNodeHandler) {
33825
+ this.cancelAction();
33826
+ return;
33827
+ }
33551
33828
  if (this.imageId) {
33552
- const imageNodeHandler = this.getImageNodeHandler();
33553
- if (!imageNodeHandler) {
33554
- this.cancelAction();
33555
- return;
33556
- }
33557
- const imageSource = imageNodeHandler.getImageSource(this.imageId);
33829
+ let imageSource = imageNodeHandler.getImageSource(this.imageId);
33830
+ if (this.uploadType === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE) imageSource = imageNodeHandler.getFallbackImageSource(this.imageId);
33558
33831
  if (!imageSource && !position) {
33559
33832
  this.cancelAction();
33560
33833
  return;
@@ -33563,8 +33836,10 @@ var WeaveImageToolAction = class extends WeaveAction {
33563
33836
  this.clickPoint = mousePoint;
33564
33837
  this.container = container;
33565
33838
  const nodeHandler = this.instance.getNodeHandler("image");
33566
- const imageWidth = this.props.loadImageWidth ? this.props.loadImageWidth : imageSource?.width;
33567
- const imageHeight = this.props.loadImageHeight ? this.props.loadImageHeight : imageSource?.height;
33839
+ const imageWidth = this.props.width ? this.props.width : imageSource?.width;
33840
+ const imageHeight = this.props.height ? this.props.height : imageSource?.height;
33841
+ let realImageURL = void 0;
33842
+ if (this.uploadType === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL && this.imageURL) realImageURL = this.imageURL?.url;
33568
33843
  if (nodeHandler) {
33569
33844
  const node = nodeHandler.create(this.imageId, {
33570
33845
  ...this.props,
@@ -33572,7 +33847,7 @@ var WeaveImageToolAction = class extends WeaveAction {
33572
33847
  y: this.clickPoint?.y ?? 0,
33573
33848
  opacity: 1,
33574
33849
  adding: false,
33575
- imageURL: this.imageURL,
33850
+ imageURL: realImageURL,
33576
33851
  stroke: "#000000ff",
33577
33852
  strokeWidth: 0,
33578
33853
  strokeScaleEnabled: true,
@@ -33581,15 +33856,32 @@ var WeaveImageToolAction = class extends WeaveAction {
33581
33856
  imageInfo: {
33582
33857
  width: imageWidth,
33583
33858
  height: imageHeight
33859
+ },
33860
+ uncroppedImage: {
33861
+ width: imageWidth,
33862
+ height: imageHeight
33584
33863
  }
33585
33864
  });
33586
33865
  this.instance.addNode(node, this.forceMainContainer ? this.instance.getMainLayer()?.getAttrs().id : this.container?.getAttrs().id);
33587
- this.instance.emitEvent("onAddedImage", {
33588
- imageURL: this.props.imageURL,
33589
- nodeId: this.imageId
33590
- });
33866
+ this.instance.emitEvent("onAddedImage", { nodeId: this.imageId });
33867
+ if (this.uploadType === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE) {
33868
+ const uploadImageFunctionInternal = async () => {
33869
+ const nodeId = this.imageId ?? "";
33870
+ try {
33871
+ const imageURL = await this.uploadImageFunction(this.imageFile.file);
33872
+ this.saveImageUrl(nodeId, imageURL);
33873
+ this.instance.emitEvent("onImageUploaded", {
33874
+ imageURL,
33875
+ nodeId
33876
+ });
33877
+ } catch (error) {
33878
+ this.instance.emitEvent("onImageUploadedError", { error });
33879
+ }
33880
+ };
33881
+ uploadImageFunctionInternal();
33882
+ }
33591
33883
  }
33592
- this.setState(IMAGE_TOOL_STATE.FINISHED);
33884
+ this.setState(WEAVE_IMAGE_TOOL_STATE.FINISHED);
33593
33885
  }
33594
33886
  this.cancelAction();
33595
33887
  }
@@ -33599,55 +33891,507 @@ var WeaveImageToolAction = class extends WeaveAction {
33599
33891
  this.cancelAction = cancelAction;
33600
33892
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33601
33893
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
33894
+ this.ignorePointerEvents = false;
33895
+ this.ignoreKeyboardEvents = false;
33602
33896
  this.forceMainContainer = params?.forceMainContainer ?? false;
33897
+ this.imageFile = null;
33898
+ this.imageURL = null;
33603
33899
  this.imageId = v4_default();
33604
33900
  this.props = this.initProps();
33605
33901
  if (params?.imageId) this.updateProps({ imageId: params.imageId });
33606
- if (params?.imageId) this.updateProps({ loadImageWidth: params.imageWidth });
33607
- if (params?.imageId) this.updateProps({ loadImageHeight: params.imageHeight });
33608
- if (params.imageData) this.loadImage(params.imageData, IMAGE_TOOL_LOAD_FROM.DATAURL, params?.position ?? void 0);
33609
- if (params.imageURL) this.loadImage(params.imageURL, IMAGE_TOOL_LOAD_FROM.URL, params?.position ?? void 0);
33610
- return {
33611
- nodeId: this.imageId,
33612
- finishUploadCallback: (nodeId, imageURL) => {
33613
- return this.saveImageUrl.bind(this)(nodeId, imageURL);
33902
+ if (this.forceExecution) {
33903
+ this.ignorePointerEvents = true;
33904
+ this.ignoreKeyboardEvents = true;
33905
+ }
33906
+ if (params?.position) this.setState(WEAVE_IMAGE_TOOL_STATE.SELECTED_POSITION);
33907
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE && params.image) {
33908
+ this.uploadType = WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE;
33909
+ this.imageFile = params.image;
33910
+ this.uploadImageFunction = params.uploadImageFunction;
33911
+ this.loadImage({
33912
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE,
33913
+ image: params.image,
33914
+ position: params?.position
33915
+ });
33916
+ }
33917
+ if (params.type === WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL && params.image) {
33918
+ this.uploadType = WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL;
33919
+ this.imageURL = params.image;
33920
+ this.updateProps({
33921
+ imageFallback: params.image.fallback,
33922
+ width: params.image.width,
33923
+ height: params.image.height
33924
+ });
33925
+ this.loadImage({
33926
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL,
33927
+ image: params.image,
33928
+ position: params?.position
33929
+ });
33930
+ }
33931
+ return { nodeId: this.imageId };
33932
+ }
33933
+ saveImageUrl(nodeId, imageURL) {
33934
+ const stage = this.instance.getStage();
33935
+ const nodeHandler = this.instance.getNodeHandler("image");
33936
+ const node = stage.findOne(`#${nodeId}`);
33937
+ if (nodeHandler && node) {
33938
+ node.setAttr("imageURL", imageURL);
33939
+ nodeHandler.forceLoadImage(node);
33940
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33941
+ }
33942
+ }
33943
+ cleanup() {
33944
+ const stage = this.instance.getStage();
33945
+ if (this.tempImageNode) this.tempImageNode.destroy();
33946
+ if (!this.forceExecution) {
33947
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
33948
+ if (selectionPlugin) {
33949
+ const node = stage.findOne(`#${this.imageId}`);
33950
+ if (node) selectionPlugin.setSelectedNodes([node]);
33951
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33952
+ }
33953
+ stage.container().style.cursor = "default";
33954
+ this.instance.endDrag(WEAVE_IMAGE_TOOL_ACTION_NAME);
33955
+ }
33956
+ this.initialCursor = null;
33957
+ this.forceMainContainer = false;
33958
+ this.container = void 0;
33959
+ this.tempImageNode = null;
33960
+ this.imageURL = null;
33961
+ this.clickPoint = null;
33962
+ this.setState(WEAVE_IMAGE_TOOL_STATE.IDLE);
33963
+ }
33964
+ getImageNodeHandler() {
33965
+ return this.instance.getNodeHandler("image");
33966
+ }
33967
+ setCursor() {
33968
+ const stage = this.instance.getStage();
33969
+ stage.container().style.cursor = "crosshair";
33970
+ }
33971
+ setFocusStage() {
33972
+ const stage = this.instance.getStage();
33973
+ stage.container().tabIndex = 1;
33974
+ stage.container().blur();
33975
+ stage.container().focus();
33976
+ }
33977
+ setDragAndDropProperties(properties) {
33978
+ this.instance.startDrag(WEAVE_IMAGE_TOOL_ACTION_NAME);
33979
+ this.instance.setDragProperties(properties);
33980
+ }
33981
+ getActualState() {
33982
+ return this.state;
33983
+ }
33984
+ };
33985
+
33986
+ //#endregion
33987
+ //#region src/actions/images-tool/constants.ts
33988
+ const WEAVE_IMAGES_TOOL_ACTION_NAME = "imagesTool";
33989
+ const WEAVE_IMAGES_TOOL_UPLOAD_TYPE = {
33990
+ ["FILE"]: "file",
33991
+ ["IMAGE_URL"]: "imageURL"
33992
+ };
33993
+ const WEAVE_IMAGES_TOOL_STATE = {
33994
+ ["IDLE"]: "idle",
33995
+ ["UPLOADING"]: "uploading",
33996
+ ["DEFINING_POSITION"]: "definingPosition",
33997
+ ["SELECTED_POSITION"]: "selectedPosition",
33998
+ ["ADDING"]: "adding",
33999
+ ["FINISHED"]: "finished"
34000
+ };
34001
+ const WEAVE_IMAGES_TOOL_DEFAULT_CONFIG = {
34002
+ style: {
34003
+ cursor: {
34004
+ padding: 5,
34005
+ imageThumbnails: {
34006
+ padding: 15,
34007
+ width: 250,
34008
+ height: 250,
34009
+ shadowColor: "#aaaaaa",
34010
+ shadowBlur: 10,
34011
+ shadowOffset: {
34012
+ x: 2,
34013
+ y: 2
34014
+ },
34015
+ shadowOpacity: .5
33614
34016
  }
34017
+ },
34018
+ moreImages: {
34019
+ paddingX: 12,
34020
+ paddingY: 8,
34021
+ fontSize: 16,
34022
+ fontFamily: "Arial",
34023
+ textColor: "#000000",
34024
+ backgroundColor: "#FFFFFF",
34025
+ backgroundOpacity: 1
34026
+ },
34027
+ images: { padding: 20 }
34028
+ },
34029
+ layout: { columns: 4 }
34030
+ };
34031
+
34032
+ //#endregion
34033
+ //#region src/internal-utils/generic.ts
34034
+ function sleep(ms) {
34035
+ return new Promise((resolve) => setTimeout(resolve, ms));
34036
+ }
34037
+
34038
+ //#endregion
34039
+ //#region src/actions/images-tool/images-tool.ts
34040
+ var WeaveImagesToolAction = class extends WeaveAction {
34041
+ initialized = false;
34042
+ initialCursor = null;
34043
+ nodesIds = [];
34044
+ imagesFile = [];
34045
+ imagesURL = [];
34046
+ forceMainContainer = false;
34047
+ uploadType = null;
34048
+ onPropsChange = void 0;
34049
+ update = void 0;
34050
+ constructor(params) {
34051
+ super();
34052
+ this.config = mergeExceptArrays(WEAVE_IMAGES_TOOL_DEFAULT_CONFIG, params ?? {});
34053
+ this.pointers = new Map();
34054
+ this.initialized = false;
34055
+ this.tempPointerFeedbackNode = null;
34056
+ this.state = WEAVE_IMAGES_TOOL_STATE.IDLE;
34057
+ this.imagesFile = [];
34058
+ this.imagesURL = [];
34059
+ this.container = void 0;
34060
+ this.preloadImgs = {};
34061
+ this.uploadType = null;
34062
+ this.clickPoint = null;
34063
+ }
34064
+ getName() {
34065
+ return WEAVE_IMAGES_TOOL_ACTION_NAME;
34066
+ }
34067
+ getPreloadedImage(imageId) {
34068
+ return this.preloadImgs?.[imageId];
34069
+ }
34070
+ initProps() {
34071
+ return {
34072
+ width: 100,
34073
+ height: 100,
34074
+ scaleX: 1,
34075
+ scaleY: 1
33615
34076
  };
33616
34077
  }
34078
+ onInit() {
34079
+ this.instance.addEventListener("onStageDrop", (e) => {
34080
+ const dragId = this.instance.getDragStartedId();
34081
+ const dragProperties = this.instance.getDragProperties();
34082
+ if (dragProperties && dragId === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34083
+ this.instance.getStage().setPointersPositions(e);
34084
+ const position = getPositionRelativeToContainerOnPosition(this.instance);
34085
+ if (!position) return;
34086
+ this.instance.triggerAction(WEAVE_IMAGES_TOOL_ACTION_NAME, {
34087
+ type: WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL,
34088
+ images: dragProperties.imagesURL,
34089
+ position,
34090
+ ...dragProperties.forceMainContainer && { forceMainContainer: dragProperties.forceMainContainer }
34091
+ });
34092
+ }
34093
+ });
34094
+ }
34095
+ setupEvents() {
34096
+ const stage = this.instance.getStage();
34097
+ stage.container().addEventListener("keydown", (e) => {
34098
+ if (e.key === "Escape" && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) this.cancelAction();
34099
+ });
34100
+ stage.on("pointerdown", (e) => {
34101
+ this.setTapStart(e);
34102
+ this.pointers.set(e.evt.pointerId, {
34103
+ x: e.evt.clientX,
34104
+ y: e.evt.clientY
34105
+ });
34106
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34107
+ this.state = WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION;
34108
+ return;
34109
+ }
34110
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION) this.state = WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION;
34111
+ });
34112
+ stage.on("pointermove", (e) => {
34113
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.IDLE) return;
34114
+ this.setCursor();
34115
+ this.setFocusStage();
34116
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME) {
34117
+ this.state = WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION;
34118
+ return;
34119
+ }
34120
+ if ([WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION, WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION].includes(this.state) && this.tempPointerFeedbackNode && this.instance.getActiveAction() === WEAVE_IMAGES_TOOL_ACTION_NAME && e.evt.pointerType === "mouse") {
34121
+ const mousePos = stage.getRelativePointerPosition();
34122
+ const cursorPadding = this.config.style.cursor.padding;
34123
+ this.tempPointerFeedbackNode.setAttrs({
34124
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
34125
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY()
34126
+ });
34127
+ }
34128
+ });
34129
+ stage.on("pointerup", (e) => {
34130
+ this.pointers.delete(e.evt.pointerId);
34131
+ if (this.state === WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
34132
+ });
34133
+ this.initialized = true;
34134
+ }
34135
+ setState(state) {
34136
+ this.state = state;
34137
+ }
34138
+ async addImages(position) {
34139
+ const stage = this.instance.getStage();
34140
+ this.setCursor();
34141
+ this.setFocusStage();
34142
+ if (position) {
34143
+ this.setState(WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION);
34144
+ this.handleAdding(position);
34145
+ return;
34146
+ }
34147
+ if (!this.tempPointerFeedbackNode && !this.isTouchDevice() && this.imagesFile && this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE) {
34148
+ const mousePos = stage.getRelativePointerPosition();
34149
+ const cursorPadding = this.config.style.cursor.padding;
34150
+ const imageThumbnailsPadding = this.config.style.cursor.imageThumbnails.padding;
34151
+ this.tempPointerFeedbackNode = new Konva.Group({
34152
+ x: (mousePos?.x ?? 0) + cursorPadding / stage.scaleX(),
34153
+ y: (mousePos?.y ?? 0) + cursorPadding / stage.scaleY(),
34154
+ listening: false
34155
+ });
34156
+ const imagesTop3 = this.imagesFile.slice(0, 3) ?? [];
34157
+ let maxWidth = 0;
34158
+ let maxHeight = 0;
34159
+ let position$1 = {
34160
+ x: 0,
34161
+ y: 0
34162
+ };
34163
+ for (const image of imagesTop3) {
34164
+ const imageSource = await loadImageSource(image.file);
34165
+ const maxImageWidth = this.config.style.cursor.imageThumbnails.width;
34166
+ const maxImageHeight = this.config.style.cursor.imageThumbnails.height;
34167
+ const shadowColor = this.config.style.cursor.imageThumbnails.shadowColor;
34168
+ const shadowBlur = this.config.style.cursor.imageThumbnails.shadowBlur;
34169
+ const shadowOffset = this.config.style.cursor.imageThumbnails.shadowOffset;
34170
+ const shadowOpacity = this.config.style.cursor.imageThumbnails.shadowOpacity;
34171
+ const aspectRatio = imageSource.width / imageSource.height || 1;
34172
+ const imageWidth = maxImageWidth * aspectRatio * (1 / stage.scaleX());
34173
+ const imageHeight = maxImageHeight * (1 / stage.scaleY());
34174
+ const imageNode = new Konva.Image({
34175
+ x: position$1.x,
34176
+ y: position$1.y,
34177
+ width: imageWidth,
34178
+ height: imageHeight,
34179
+ opacity: 1,
34180
+ adding: true,
34181
+ image: imageSource,
34182
+ stroke: "#000000ff",
34183
+ strokeWidth: 0,
34184
+ strokeScaleEnabled: true,
34185
+ listening: false,
34186
+ shadowColor,
34187
+ shadowBlur,
34188
+ shadowOffset,
34189
+ shadowOpacity
34190
+ });
34191
+ maxWidth = position$1.x + imageWidth;
34192
+ maxHeight = Math.max(maxHeight, position$1.y + imageHeight);
34193
+ position$1 = {
34194
+ x: position$1.x + imageThumbnailsPadding / stage.scaleX(),
34195
+ y: position$1.y + imageThumbnailsPadding / stage.scaleY()
34196
+ };
34197
+ this.tempPointerFeedbackNode.add(imageNode);
34198
+ imageNode.moveToBottom();
34199
+ }
34200
+ if (this.imagesFile.length > 3) {
34201
+ const paddingX = this.config.style.moreImages.paddingX;
34202
+ const paddingY = this.config.style.moreImages.paddingY;
34203
+ const fontSize = this.config.style.moreImages.fontSize;
34204
+ const fontFamily = this.config.style.moreImages.fontFamily;
34205
+ const textColor = this.config.style.moreImages.textColor;
34206
+ const backgroundColor = this.config.style.moreImages.backgroundColor;
34207
+ const backgroundOpacity = this.config.style.moreImages.backgroundOpacity;
34208
+ const text = `and ${this.imagesFile.length - 3} more image(s)`;
34209
+ const textNode = new Konva.Text({
34210
+ x: maxWidth + paddingX / stage.scaleX() + cursorPadding / stage.scaleX(),
34211
+ y: position$1.y,
34212
+ fontFamily,
34213
+ fontSize: fontSize / stage.scaleX(),
34214
+ text,
34215
+ fill: textColor,
34216
+ listening: false
34217
+ });
34218
+ const textSize = textNode.measureSize(text);
34219
+ textNode.y((maxHeight - textSize.height) / 2);
34220
+ this.tempPointerFeedbackNode.add(textNode);
34221
+ const textBg = new Konva.Rect({
34222
+ x: textNode.x() - paddingX / stage.scaleX(),
34223
+ y: textNode.y() - paddingY / stage.scaleY(),
34224
+ width: textNode.width() + 2 * paddingX / stage.scaleX(),
34225
+ height: textNode.height() + 2 * paddingY / stage.scaleY(),
34226
+ fill: backgroundColor,
34227
+ opacity: backgroundOpacity
34228
+ });
34229
+ this.tempPointerFeedbackNode.add(textBg);
34230
+ textBg.moveToBottom();
34231
+ textNode.moveToTop();
34232
+ }
34233
+ this.instance.getUtilityLayer()?.add(this.tempPointerFeedbackNode);
34234
+ this.instance.emitEvent("onAddingImages");
34235
+ }
34236
+ this.clickPoint = null;
34237
+ this.setState(WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION);
34238
+ }
34239
+ async handleAdding(position) {
34240
+ const stage = this.instance.getStage();
34241
+ this.tempPointerFeedbackNode?.destroy();
34242
+ this.tempPointerFeedbackNode = null;
34243
+ this.instance.getUtilityLayer()?.batchDraw();
34244
+ stage.container().style.cursor = "default";
34245
+ const { mousePoint, container } = this.instance.getMousePointer(position);
34246
+ this.clickPoint = mousePoint;
34247
+ this.container = container;
34248
+ const originPoint = {
34249
+ x: this.clickPoint?.x ?? 0,
34250
+ y: this.clickPoint?.y ?? 0
34251
+ };
34252
+ if (!this.imagesFile && !this.imagesURL) return;
34253
+ const imageToolActionHandler = this.instance.getActionHandler(WEAVE_IMAGE_TOOL_ACTION_NAME);
34254
+ if (!imageToolActionHandler) return;
34255
+ const imagesPadding = this.config.style.images.padding;
34256
+ const layoutColumns = this.config.layout.columns;
34257
+ let imagePositionX = originPoint.x;
34258
+ let imagePositionY = originPoint.y;
34259
+ let maxHeight = 0;
34260
+ if (this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE && this.imagesFile) {
34261
+ const imagesToUpload = this.imagesFile.length;
34262
+ let imagesUploaded = 0;
34263
+ await this.onStartUploading();
34264
+ const handleUploadImage = async () => {
34265
+ imagesUploaded++;
34266
+ if (imagesUploaded >= imagesToUpload) {
34267
+ await this.onFinishedUploading();
34268
+ this.instance.removeEventListener("onImageUploaded", handleUploadImage);
34269
+ }
34270
+ };
34271
+ this.instance.addEventListener("onImageUploaded", handleUploadImage);
34272
+ for (let i = 0; i < this.imagesFile.length; i++) {
34273
+ const imageFile = this.imagesFile[i];
34274
+ const { imageId, width, height,...restImageFile } = imageFile;
34275
+ const uploadImageFunctionInternal = async () => {
34276
+ const imageURL = await this.uploadImageFunction(imageFile.file);
34277
+ return imageURL;
34278
+ };
34279
+ const { nodeId } = this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
34280
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.FILE,
34281
+ image: restImageFile,
34282
+ uploadImageFunction: uploadImageFunctionInternal,
34283
+ ...imageId && { imageId },
34284
+ position: {
34285
+ x: imagePositionX,
34286
+ y: imagePositionY
34287
+ },
34288
+ forceMainContainer: this.forceMainContainer
34289
+ }, true);
34290
+ this.nodesIds.push(nodeId);
34291
+ maxHeight = Math.max(maxHeight, height);
34292
+ imagePositionX += imagesPadding + width;
34293
+ if ((i + 1) % layoutColumns === 0) {
34294
+ imagePositionX = originPoint.x;
34295
+ imagePositionY = imagePositionY + maxHeight + imagesPadding;
34296
+ maxHeight = 0;
34297
+ }
34298
+ while (imageToolActionHandler.getActualState() !== WEAVE_IMAGES_TOOL_STATE.IDLE) await sleep(10);
34299
+ }
34300
+ this.instance.emitEvent("onAddedImages", { nodesIds: this.nodesIds });
34301
+ }
34302
+ if (this.uploadType === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL && this.imagesURL) {
34303
+ for (let i = 0; i < this.imagesURL.length; i++) {
34304
+ const imageURL = this.imagesURL[i];
34305
+ const { imageId, options,...restImageURL } = imageURL;
34306
+ const imageURLElement = restImageURL;
34307
+ const { nodeId } = this.instance.triggerAction(WEAVE_IMAGE_TOOL_ACTION_NAME, {
34308
+ type: WEAVE_IMAGE_TOOL_UPLOAD_TYPE.IMAGE_URL,
34309
+ image: imageURLElement,
34310
+ ...imageId && { imageId },
34311
+ ...options && { options },
34312
+ position: {
34313
+ x: imagePositionX,
34314
+ y: imagePositionY
34315
+ },
34316
+ forceMainContainer: this.forceMainContainer
34317
+ }, true);
34318
+ this.nodesIds.push(nodeId);
34319
+ maxHeight = Math.max(maxHeight, imageURL.height);
34320
+ imagePositionX += imagesPadding + imageURL.width;
34321
+ if ((i + 1) % layoutColumns === 0) {
34322
+ imagePositionX = originPoint.x;
34323
+ imagePositionY = imagePositionY + maxHeight + imagesPadding;
34324
+ maxHeight = 0;
34325
+ }
34326
+ while (imageToolActionHandler.getActualState() !== WEAVE_IMAGES_TOOL_STATE.IDLE) await sleep(10);
34327
+ }
34328
+ this.instance.emitEvent("onAddedImages", { nodesIds: this.nodesIds });
34329
+ }
34330
+ this.setState(WEAVE_IMAGES_TOOL_STATE.FINISHED);
34331
+ this.cancelAction();
34332
+ }
34333
+ trigger(cancelAction, params) {
34334
+ if (!this.instance) throw new Error("Instance not defined");
34335
+ if (!this.initialized) this.setupEvents();
34336
+ this.cancelAction = cancelAction;
34337
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34338
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
34339
+ if (params?.position) this.setState(WEAVE_IMAGES_TOOL_STATE.SELECTED_POSITION);
34340
+ this.forceMainContainer = params.forceMainContainer ?? false;
34341
+ if (params.type === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE) {
34342
+ this.uploadType = WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE;
34343
+ this.onStartUploading = params.onStartUploading;
34344
+ this.onFinishedUploading = params.onFinishedUploading;
34345
+ this.uploadImageFunction = params.uploadImageFunction;
34346
+ this.nodesIds = [];
34347
+ this.imagesFile = params.images;
34348
+ }
34349
+ if (params.type === WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL) {
34350
+ this.uploadType = WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL;
34351
+ this.nodesIds = [];
34352
+ this.imagesURL = params.images;
34353
+ }
34354
+ if (![WEAVE_IMAGES_TOOL_UPLOAD_TYPE.FILE, WEAVE_IMAGES_TOOL_UPLOAD_TYPE.IMAGE_URL].includes(params.type)) {
34355
+ this.cancelAction();
34356
+ return;
34357
+ }
34358
+ this.addImages(params?.position);
34359
+ }
33617
34360
  saveImageUrl(nodeId, imageURL) {
33618
- this.imageURL = imageURL;
33619
- if (this.state !== IMAGE_TOOL_STATE.DEFINING_POSITION) {
34361
+ if (this.state !== WEAVE_IMAGES_TOOL_STATE.DEFINING_POSITION) {
33620
34362
  const stage = this.instance.getStage();
33621
34363
  const nodeHandler = this.instance.getNodeHandler("image");
33622
34364
  const node = stage.findOne(`#${nodeId}`);
33623
34365
  if (nodeHandler && node) {
33624
34366
  node.setAttr("imageURL", imageURL);
33625
- this.instance.updateNode(nodeHandler.serialize(node));
34367
+ nodeHandler.forceLoadImage(node);
34368
+ this.instance.updateNode(nodeHandler.serialize(node), { origin: "system" });
33626
34369
  }
33627
34370
  }
33628
34371
  }
33629
34372
  cleanup() {
33630
34373
  const stage = this.instance.getStage();
33631
- if (this.tempImageNode) this.tempImageNode.destroy();
34374
+ this.tempPointerFeedbackNode?.destroy();
34375
+ this.tempPointerFeedbackNode = null;
34376
+ this.instance.getUtilityLayer()?.batchDraw();
33632
34377
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
33633
34378
  if (selectionPlugin) {
33634
- const node = stage.findOne(`#${this.imageId}`);
33635
- if (node) selectionPlugin.setSelectedNodes([node]);
34379
+ const addedNodes = [];
34380
+ for (const nodeId of this.nodesIds) {
34381
+ const node = stage.findOne(`#${nodeId}`);
34382
+ if (node) addedNodes.push(node);
34383
+ }
34384
+ selectionPlugin.setSelectedNodes(addedNodes);
33636
34385
  this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
33637
34386
  }
34387
+ this.instance.endDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33638
34388
  stage.container().style.cursor = "default";
33639
- this.instance.endDrag(IMAGE_TOOL_ACTION_NAME);
33640
- this.initialCursor = null;
33641
- this.imageId = null;
34389
+ this.uploadType = null;
33642
34390
  this.forceMainContainer = false;
34391
+ this.initialCursor = null;
33643
34392
  this.container = void 0;
33644
- this.tempImageNode = null;
33645
- this.imageURL = null;
33646
34393
  this.clickPoint = null;
33647
- this.setState(IMAGE_TOOL_STATE.IDLE);
33648
- }
33649
- getImageNodeHandler() {
33650
- return this.instance.getNodeHandler("image");
34394
+ this.setState(WEAVE_IMAGES_TOOL_STATE.IDLE);
33651
34395
  }
33652
34396
  setCursor() {
33653
34397
  const stage = this.instance.getStage();
@@ -33659,8 +34403,11 @@ var WeaveImageToolAction = class extends WeaveAction {
33659
34403
  stage.container().blur();
33660
34404
  stage.container().focus();
33661
34405
  }
34406
+ isTouchDevice() {
34407
+ return window.matchMedia("(pointer: coarse)").matches;
34408
+ }
33662
34409
  setDragAndDropProperties(properties) {
33663
- this.instance.startDrag(IMAGE_TOOL_ACTION_NAME);
34410
+ this.instance.startDrag(WEAVE_IMAGES_TOOL_ACTION_NAME);
33664
34411
  this.instance.setDragProperties(properties);
33665
34412
  }
33666
34413
  };
@@ -38894,4 +39641,4 @@ const setupCanvasBackend = async () => {
38894
39641
  };
38895
39642
 
38896
39643
  //#endregion
38897
- export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, ARROW_TOOL_ACTION_NAME, ARROW_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_LINE_DEFAULT_CONFIG, GUIDE_ENTER_SNAPPING_TOLERANCE, GUIDE_EXIT_SNAPPING_TOLERANCE, GUIDE_HORIZONTAL_LINE_NAME, GUIDE_LINE_DEFAULT_CONFIG, GUIDE_LINE_DRAG_SNAPPING_THRESHOLD, GUIDE_LINE_NAME, GUIDE_LINE_TRANSFORM_SNAPPING_THRESHOLD, GUIDE_ORIENTATION, GUIDE_VERTICAL_LINE_NAME, IMAGE_TOOL_ACTION_NAME, IMAGE_TOOL_LOAD_FROM, IMAGE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, NODE_SNAP, NODE_SNAP_HORIZONTAL, NODE_SNAP_VERTICAL, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_COLOR, WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS, WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO, WEAVE_GRID_DEFAULT_MAJOR_EVERY, WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO, WEAVE_GRID_DEFAULT_ORIGIN_COLOR, WEAVE_GRID_DEFAULT_RADIUS, WEAVE_GRID_DEFAULT_SIZE, WEAVE_GRID_DEFAULT_STROKE, WEAVE_GRID_DEFAULT_TYPE, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGE_CROP_ANCHOR_POSITION, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_IMAGE_CROPPING_MODE, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAGE_TEXT_EDITION_MODE, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE, WEAVE_STROKE_SINGLE_NODE_TIP_TYPE, WEAVE_STROKE_SINGLE_NODE_TYPE, WEAVE_STROKE_TOOL_ACTION_NAME, WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES, WEAVE_STROKE_TOOL_DEFAULT_CONFIG, WEAVE_STROKE_TOOL_STATE, WEAVE_TEXT_NODE_DEFAULT_CONFIG, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveRenderer, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStore, WeaveStrokeNode, WeaveStrokeSingleNode, WeaveStrokeToolAction, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, setupCanvasBackend, setupSkiaBackend };
39644
+ export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, ARROW_TOOL_ACTION_NAME, ARROW_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_LINE_DEFAULT_CONFIG, GUIDE_ENTER_SNAPPING_TOLERANCE, GUIDE_EXIT_SNAPPING_TOLERANCE, GUIDE_HORIZONTAL_LINE_NAME, GUIDE_LINE_DEFAULT_CONFIG, GUIDE_LINE_DRAG_SNAPPING_THRESHOLD, GUIDE_LINE_NAME, GUIDE_LINE_TRANSFORM_SNAPPING_THRESHOLD, GUIDE_ORIENTATION, GUIDE_VERTICAL_LINE_NAME, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, NODE_SNAP, NODE_SNAP_HORIZONTAL, NODE_SNAP_VERTICAL, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_COLOR, WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS, WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO, WEAVE_GRID_DEFAULT_MAJOR_EVERY, WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO, WEAVE_GRID_DEFAULT_ORIGIN_COLOR, WEAVE_GRID_DEFAULT_RADIUS, WEAVE_GRID_DEFAULT_SIZE, WEAVE_GRID_DEFAULT_STROKE, WEAVE_GRID_DEFAULT_TYPE, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGES_TOOL_ACTION_NAME, WEAVE_IMAGES_TOOL_DEFAULT_CONFIG, WEAVE_IMAGES_TOOL_STATE, WEAVE_IMAGES_TOOL_UPLOAD_TYPE, WEAVE_IMAGE_CROP_ANCHOR_POSITION, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_IMAGE_TOOL_ACTION_NAME, WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, WEAVE_IMAGE_TOOL_STATE, WEAVE_IMAGE_TOOL_UPLOAD_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_DROP_AREA_KEY, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_IMAGE_CROPPING_MODE, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAGE_TEXT_EDITION_MODE, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE, WEAVE_STROKE_SINGLE_NODE_TIP_TYPE, WEAVE_STROKE_SINGLE_NODE_TYPE, WEAVE_STROKE_TOOL_ACTION_NAME, WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES, WEAVE_STROKE_TOOL_DEFAULT_CONFIG, WEAVE_STROKE_TOOL_STATE, WEAVE_TEXT_NODE_DEFAULT_CONFIG, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveImagesToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveRenderer, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStore, WeaveStrokeNode, WeaveStrokeSingleNode, WeaveStrokeToolAction, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, downscaleImageFile, downscaleImageFromURL, getBoundingBox, getDownscaleRatio, getExportBoundingBox, getImageSizeFromFile, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, loadImageSource, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, setupCanvasBackend, setupSkiaBackend };