@excalidraw/excalidraw 0.18.0-39ce38a0d-200a6bd94 → 0.18.0-3bdaafe
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/dev/{chunk-Y7B3JU7D.js → chunk-CP5DND7P.js} +2 -2
- package/dist/dev/{chunk-Y7B3JU7D.js.map → chunk-CP5DND7P.js.map} +1 -1
- package/dist/dev/{chunk-GZYPVQVV.js → chunk-WQARCR2O.js} +805 -70
- package/dist/dev/chunk-WQARCR2O.js.map +7 -0
- package/dist/dev/data/{image-V3RGFWEQ.js → image-6EX7CJAB.js} +3 -3
- package/dist/dev/index.js +960 -1496
- package/dist/dev/index.js.map +4 -4
- package/dist/dev/subset-shared.chunk.js +1 -1
- package/dist/dev/subset-worker.chunk.js +1 -1
- package/dist/prod/{chunk-ATYYHCCY.js → chunk-A66AFZZU.js} +1 -1
- package/dist/prod/chunk-K6SESUPD.js +7 -0
- package/dist/prod/data/image-I65E4LM3.js +1 -0
- package/dist/prod/index.js +20 -23
- package/dist/prod/subset-shared.chunk.js +1 -1
- package/dist/prod/subset-worker.chunk.js +1 -1
- package/dist/types/common/src/constants.d.ts +2 -0
- package/dist/types/element/src/Scene.d.ts +6 -2
- package/dist/types/element/src/bounds.d.ts +1 -1
- package/dist/types/element/src/delta.d.ts +6 -4
- package/dist/types/element/src/index.d.ts +1 -0
- package/dist/types/element/src/positionElementsOnGrid.d.ts +2 -0
- package/dist/types/element/src/store.d.ts +6 -1
- package/dist/types/element/src/textElement.d.ts +1 -1
- package/dist/types/excalidraw/actions/actionCanvas.d.ts +15 -1
- package/dist/types/excalidraw/clipboard.d.ts +1 -0
- package/dist/types/excalidraw/components/App.d.ts +11 -8
- package/dist/types/excalidraw/components/shapes.d.ts +129 -1
- package/dist/types/excalidraw/data/blob.d.ts +7 -4
- package/dist/types/excalidraw/data/restore.d.ts +6 -1
- package/dist/types/excalidraw/index.d.ts +1 -1
- package/dist/types/excalidraw/types.d.ts +5 -2
- package/history.ts +1 -1
- package/package.json +5 -5
- package/dist/dev/chunk-GZYPVQVV.js.map +0 -7
- package/dist/prod/chunk-QH2XZQ34.js +0 -4
- package/dist/prod/data/image-4FTETSFG.js +0 -1
- /package/dist/dev/data/{image-V3RGFWEQ.js.map → image-6EX7CJAB.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
define_import_meta_env_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CP5DND7P.js";
|
|
4
4
|
import {
|
|
5
5
|
__publicField
|
|
6
6
|
} from "./chunk-XDFCUUT6.js";
|
|
@@ -9,15 +9,15 @@ import {
|
|
|
9
9
|
import tEXt from "png-chunk-text";
|
|
10
10
|
import encodePng from "png-chunks-encode";
|
|
11
11
|
import decodePng from "png-chunks-extract";
|
|
12
|
-
import { EXPORT_DATA_TYPES as
|
|
12
|
+
import { EXPORT_DATA_TYPES as EXPORT_DATA_TYPES4, MIME_TYPES as MIME_TYPES8 } from "@excalidraw/common";
|
|
13
13
|
|
|
14
14
|
// data/blob.ts
|
|
15
15
|
import { nanoid } from "nanoid";
|
|
16
16
|
import {
|
|
17
17
|
IMAGE_MIME_TYPES,
|
|
18
|
-
MIME_TYPES as
|
|
18
|
+
MIME_TYPES as MIME_TYPES7,
|
|
19
19
|
bytesToHexString,
|
|
20
|
-
isPromiseLike
|
|
20
|
+
isPromiseLike as isPromiseLike2
|
|
21
21
|
} from "@excalidraw/common";
|
|
22
22
|
import { clearElementsForExport as clearElementsForExport2 } from "@excalidraw/element";
|
|
23
23
|
|
|
@@ -4677,10 +4677,709 @@ var getExportSize = (elements, exportPadding, scale) => {
|
|
|
4677
4677
|
return [width, height];
|
|
4678
4678
|
};
|
|
4679
4679
|
|
|
4680
|
-
//
|
|
4681
|
-
import {
|
|
4680
|
+
// clipboard.ts
|
|
4681
|
+
import {
|
|
4682
|
+
ALLOWED_PASTE_MIME_TYPES,
|
|
4683
|
+
EXPORT_DATA_TYPES as EXPORT_DATA_TYPES3,
|
|
4684
|
+
MIME_TYPES as MIME_TYPES6,
|
|
4685
|
+
arrayToMap as arrayToMap2,
|
|
4686
|
+
isMemberOf,
|
|
4687
|
+
isPromiseLike,
|
|
4688
|
+
EVENT as EVENT2
|
|
4689
|
+
} from "@excalidraw/common";
|
|
4690
|
+
import { mutateElement } from "@excalidraw/element";
|
|
4691
|
+
import { deepCopyElement } from "@excalidraw/element";
|
|
4692
|
+
import {
|
|
4693
|
+
isFrameLikeElement as isFrameLikeElement2,
|
|
4694
|
+
isInitializedImageElement as isInitializedImageElement2
|
|
4695
|
+
} from "@excalidraw/element";
|
|
4696
|
+
import { getContainingFrame as getContainingFrame2 } from "@excalidraw/element";
|
|
4697
|
+
|
|
4698
|
+
// charts.ts
|
|
4699
|
+
import { pointFrom as pointFrom3 } from "@excalidraw/math";
|
|
4682
4700
|
import {
|
|
4701
|
+
COLOR_PALETTE as COLOR_PALETTE2,
|
|
4702
|
+
DEFAULT_CHART_COLOR_INDEX,
|
|
4703
|
+
getAllColorsSpecificShade,
|
|
4683
4704
|
DEFAULT_FONT_FAMILY as DEFAULT_FONT_FAMILY2,
|
|
4705
|
+
DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE2,
|
|
4706
|
+
VERTICAL_ALIGN,
|
|
4707
|
+
randomId,
|
|
4708
|
+
isDevEnv
|
|
4709
|
+
} from "@excalidraw/common";
|
|
4710
|
+
import {
|
|
4711
|
+
newTextElement as newTextElement2,
|
|
4712
|
+
newLinearElement,
|
|
4713
|
+
newElement
|
|
4714
|
+
} from "@excalidraw/element";
|
|
4715
|
+
var BAR_WIDTH = 32;
|
|
4716
|
+
var BAR_GAP = 12;
|
|
4717
|
+
var BAR_HEIGHT = 256;
|
|
4718
|
+
var GRID_OPACITY = 50;
|
|
4719
|
+
var NOT_SPREADSHEET = "NOT_SPREADSHEET";
|
|
4720
|
+
var VALID_SPREADSHEET = "VALID_SPREADSHEET";
|
|
4721
|
+
var tryParseNumber = (s) => {
|
|
4722
|
+
const match = /^([-+]?)[$€£¥₩]?([-+]?)([\d.,]+)[%]?$/.exec(s);
|
|
4723
|
+
if (!match) {
|
|
4724
|
+
return null;
|
|
4725
|
+
}
|
|
4726
|
+
return parseFloat(`${(match[1] || match[2]) + match[3]}`.replace(/,/g, ""));
|
|
4727
|
+
};
|
|
4728
|
+
var isNumericColumn = (lines, columnIndex) => lines.slice(1).every((line) => tryParseNumber(line[columnIndex]) !== null);
|
|
4729
|
+
var tryParseCells = (cells) => {
|
|
4730
|
+
const numCols = cells[0].length;
|
|
4731
|
+
if (numCols > 2) {
|
|
4732
|
+
return { type: NOT_SPREADSHEET, reason: "More than 2 columns" };
|
|
4733
|
+
}
|
|
4734
|
+
if (numCols === 1) {
|
|
4735
|
+
if (!isNumericColumn(cells, 0)) {
|
|
4736
|
+
return { type: NOT_SPREADSHEET, reason: "Value is not numeric" };
|
|
4737
|
+
}
|
|
4738
|
+
const hasHeader2 = tryParseNumber(cells[0][0]) === null;
|
|
4739
|
+
const values = (hasHeader2 ? cells.slice(1) : cells).map(
|
|
4740
|
+
(line) => tryParseNumber(line[0])
|
|
4741
|
+
);
|
|
4742
|
+
if (values.length < 2) {
|
|
4743
|
+
return { type: NOT_SPREADSHEET, reason: "Less than two rows" };
|
|
4744
|
+
}
|
|
4745
|
+
return {
|
|
4746
|
+
type: VALID_SPREADSHEET,
|
|
4747
|
+
spreadsheet: {
|
|
4748
|
+
title: hasHeader2 ? cells[0][0] : null,
|
|
4749
|
+
labels: null,
|
|
4750
|
+
values
|
|
4751
|
+
}
|
|
4752
|
+
};
|
|
4753
|
+
}
|
|
4754
|
+
const labelColumnNumeric = isNumericColumn(cells, 0);
|
|
4755
|
+
const valueColumnNumeric = isNumericColumn(cells, 1);
|
|
4756
|
+
if (!labelColumnNumeric && !valueColumnNumeric) {
|
|
4757
|
+
return { type: NOT_SPREADSHEET, reason: "Value is not numeric" };
|
|
4758
|
+
}
|
|
4759
|
+
const [labelColumnIndex, valueColumnIndex] = valueColumnNumeric ? [0, 1] : [1, 0];
|
|
4760
|
+
const hasHeader = tryParseNumber(cells[0][valueColumnIndex]) === null;
|
|
4761
|
+
const rows = hasHeader ? cells.slice(1) : cells;
|
|
4762
|
+
if (rows.length < 2) {
|
|
4763
|
+
return { type: NOT_SPREADSHEET, reason: "Less than 2 rows" };
|
|
4764
|
+
}
|
|
4765
|
+
return {
|
|
4766
|
+
type: VALID_SPREADSHEET,
|
|
4767
|
+
spreadsheet: {
|
|
4768
|
+
title: hasHeader ? cells[0][valueColumnIndex] : null,
|
|
4769
|
+
labels: rows.map((row) => row[labelColumnIndex]),
|
|
4770
|
+
values: rows.map((row) => tryParseNumber(row[valueColumnIndex]))
|
|
4771
|
+
}
|
|
4772
|
+
};
|
|
4773
|
+
};
|
|
4774
|
+
var transposeCells = (cells) => {
|
|
4775
|
+
const nextCells = [];
|
|
4776
|
+
for (let col = 0; col < cells[0].length; col++) {
|
|
4777
|
+
const nextCellRow = [];
|
|
4778
|
+
for (let row = 0; row < cells.length; row++) {
|
|
4779
|
+
nextCellRow.push(cells[row][col]);
|
|
4780
|
+
}
|
|
4781
|
+
nextCells.push(nextCellRow);
|
|
4782
|
+
}
|
|
4783
|
+
return nextCells;
|
|
4784
|
+
};
|
|
4785
|
+
var tryParseSpreadsheet = (text) => {
|
|
4786
|
+
let lines = text.trim().split("\n").map((line) => line.trim().split(" "));
|
|
4787
|
+
if (lines.length && lines[0].length !== 2) {
|
|
4788
|
+
lines = text.trim().split("\n").map((line) => line.trim().split(","));
|
|
4789
|
+
}
|
|
4790
|
+
if (lines.length === 0) {
|
|
4791
|
+
return { type: NOT_SPREADSHEET, reason: "No values" };
|
|
4792
|
+
}
|
|
4793
|
+
const numColsFirstLine = lines[0].length;
|
|
4794
|
+
const isSpreadsheet = lines.every((line) => line.length === numColsFirstLine);
|
|
4795
|
+
if (!isSpreadsheet) {
|
|
4796
|
+
return {
|
|
4797
|
+
type: NOT_SPREADSHEET,
|
|
4798
|
+
reason: "All rows don't have same number of columns"
|
|
4799
|
+
};
|
|
4800
|
+
}
|
|
4801
|
+
const result = tryParseCells(lines);
|
|
4802
|
+
if (result.type !== VALID_SPREADSHEET) {
|
|
4803
|
+
const transposedResults = tryParseCells(transposeCells(lines));
|
|
4804
|
+
if (transposedResults.type === VALID_SPREADSHEET) {
|
|
4805
|
+
return transposedResults;
|
|
4806
|
+
}
|
|
4807
|
+
}
|
|
4808
|
+
return result;
|
|
4809
|
+
};
|
|
4810
|
+
var bgColors = getAllColorsSpecificShade(DEFAULT_CHART_COLOR_INDEX);
|
|
4811
|
+
var commonProps = {
|
|
4812
|
+
fillStyle: "hachure",
|
|
4813
|
+
fontFamily: DEFAULT_FONT_FAMILY2,
|
|
4814
|
+
fontSize: DEFAULT_FONT_SIZE2,
|
|
4815
|
+
opacity: 100,
|
|
4816
|
+
roughness: 1,
|
|
4817
|
+
strokeColor: COLOR_PALETTE2.black,
|
|
4818
|
+
roundness: null,
|
|
4819
|
+
strokeStyle: "solid",
|
|
4820
|
+
strokeWidth: 1,
|
|
4821
|
+
verticalAlign: VERTICAL_ALIGN.MIDDLE,
|
|
4822
|
+
locked: false
|
|
4823
|
+
};
|
|
4824
|
+
var getChartDimensions = (spreadsheet) => {
|
|
4825
|
+
const chartWidth = (BAR_WIDTH + BAR_GAP) * spreadsheet.values.length + BAR_GAP;
|
|
4826
|
+
const chartHeight = BAR_HEIGHT + BAR_GAP * 2;
|
|
4827
|
+
return { chartWidth, chartHeight };
|
|
4828
|
+
};
|
|
4829
|
+
var chartXLabels = (spreadsheet, x, y, groupId, backgroundColor) => {
|
|
4830
|
+
return spreadsheet.labels?.map((label, index) => {
|
|
4831
|
+
return newTextElement2({
|
|
4832
|
+
groupIds: [groupId],
|
|
4833
|
+
backgroundColor,
|
|
4834
|
+
...commonProps,
|
|
4835
|
+
text: label.length > 8 ? `${label.slice(0, 5)}...` : label,
|
|
4836
|
+
x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP * 2,
|
|
4837
|
+
y: y + BAR_GAP / 2,
|
|
4838
|
+
width: BAR_WIDTH,
|
|
4839
|
+
angle: 5.87,
|
|
4840
|
+
fontSize: 16,
|
|
4841
|
+
textAlign: "center",
|
|
4842
|
+
verticalAlign: "top"
|
|
4843
|
+
});
|
|
4844
|
+
}) || [];
|
|
4845
|
+
};
|
|
4846
|
+
var chartYLabels = (spreadsheet, x, y, groupId, backgroundColor) => {
|
|
4847
|
+
const minYLabel = newTextElement2({
|
|
4848
|
+
groupIds: [groupId],
|
|
4849
|
+
backgroundColor,
|
|
4850
|
+
...commonProps,
|
|
4851
|
+
x: x - BAR_GAP,
|
|
4852
|
+
y: y - BAR_GAP,
|
|
4853
|
+
text: "0",
|
|
4854
|
+
textAlign: "right"
|
|
4855
|
+
});
|
|
4856
|
+
const maxYLabel = newTextElement2({
|
|
4857
|
+
groupIds: [groupId],
|
|
4858
|
+
backgroundColor,
|
|
4859
|
+
...commonProps,
|
|
4860
|
+
x: x - BAR_GAP,
|
|
4861
|
+
y: y - BAR_HEIGHT - minYLabel.height / 2,
|
|
4862
|
+
text: Math.max(...spreadsheet.values).toLocaleString(),
|
|
4863
|
+
textAlign: "right"
|
|
4864
|
+
});
|
|
4865
|
+
return [minYLabel, maxYLabel];
|
|
4866
|
+
};
|
|
4867
|
+
var chartLines = (spreadsheet, x, y, groupId, backgroundColor) => {
|
|
4868
|
+
const { chartWidth, chartHeight } = getChartDimensions(spreadsheet);
|
|
4869
|
+
const xLine = newLinearElement({
|
|
4870
|
+
backgroundColor,
|
|
4871
|
+
groupIds: [groupId],
|
|
4872
|
+
...commonProps,
|
|
4873
|
+
type: "line",
|
|
4874
|
+
x,
|
|
4875
|
+
y,
|
|
4876
|
+
width: chartWidth,
|
|
4877
|
+
points: [pointFrom3(0, 0), pointFrom3(chartWidth, 0)]
|
|
4878
|
+
});
|
|
4879
|
+
const yLine = newLinearElement({
|
|
4880
|
+
backgroundColor,
|
|
4881
|
+
groupIds: [groupId],
|
|
4882
|
+
...commonProps,
|
|
4883
|
+
type: "line",
|
|
4884
|
+
x,
|
|
4885
|
+
y,
|
|
4886
|
+
height: chartHeight,
|
|
4887
|
+
points: [pointFrom3(0, 0), pointFrom3(0, -chartHeight)]
|
|
4888
|
+
});
|
|
4889
|
+
const maxLine = newLinearElement({
|
|
4890
|
+
backgroundColor,
|
|
4891
|
+
groupIds: [groupId],
|
|
4892
|
+
...commonProps,
|
|
4893
|
+
type: "line",
|
|
4894
|
+
x,
|
|
4895
|
+
y: y - BAR_HEIGHT - BAR_GAP,
|
|
4896
|
+
strokeStyle: "dotted",
|
|
4897
|
+
width: chartWidth,
|
|
4898
|
+
opacity: GRID_OPACITY,
|
|
4899
|
+
points: [pointFrom3(0, 0), pointFrom3(chartWidth, 0)]
|
|
4900
|
+
});
|
|
4901
|
+
return [xLine, yLine, maxLine];
|
|
4902
|
+
};
|
|
4903
|
+
var chartBaseElements = (spreadsheet, x, y, groupId, backgroundColor, debug) => {
|
|
4904
|
+
const { chartWidth, chartHeight } = getChartDimensions(spreadsheet);
|
|
4905
|
+
const title = spreadsheet.title ? newTextElement2({
|
|
4906
|
+
backgroundColor,
|
|
4907
|
+
groupIds: [groupId],
|
|
4908
|
+
...commonProps,
|
|
4909
|
+
text: spreadsheet.title,
|
|
4910
|
+
x: x + chartWidth / 2,
|
|
4911
|
+
y: y - BAR_HEIGHT - BAR_GAP * 2 - DEFAULT_FONT_SIZE2,
|
|
4912
|
+
roundness: null,
|
|
4913
|
+
textAlign: "center"
|
|
4914
|
+
}) : null;
|
|
4915
|
+
const debugRect = debug ? newElement({
|
|
4916
|
+
backgroundColor,
|
|
4917
|
+
groupIds: [groupId],
|
|
4918
|
+
...commonProps,
|
|
4919
|
+
type: "rectangle",
|
|
4920
|
+
x,
|
|
4921
|
+
y: y - chartHeight,
|
|
4922
|
+
width: chartWidth,
|
|
4923
|
+
height: chartHeight,
|
|
4924
|
+
strokeColor: COLOR_PALETTE2.black,
|
|
4925
|
+
fillStyle: "solid",
|
|
4926
|
+
opacity: 6
|
|
4927
|
+
}) : null;
|
|
4928
|
+
return [
|
|
4929
|
+
...debugRect ? [debugRect] : [],
|
|
4930
|
+
...title ? [title] : [],
|
|
4931
|
+
...chartXLabels(spreadsheet, x, y, groupId, backgroundColor),
|
|
4932
|
+
...chartYLabels(spreadsheet, x, y, groupId, backgroundColor),
|
|
4933
|
+
...chartLines(spreadsheet, x, y, groupId, backgroundColor)
|
|
4934
|
+
];
|
|
4935
|
+
};
|
|
4936
|
+
var chartTypeBar = (spreadsheet, x, y) => {
|
|
4937
|
+
const max = Math.max(...spreadsheet.values);
|
|
4938
|
+
const groupId = randomId();
|
|
4939
|
+
const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)];
|
|
4940
|
+
const bars = spreadsheet.values.map((value, index) => {
|
|
4941
|
+
const barHeight = value / max * BAR_HEIGHT;
|
|
4942
|
+
return newElement({
|
|
4943
|
+
backgroundColor,
|
|
4944
|
+
groupIds: [groupId],
|
|
4945
|
+
...commonProps,
|
|
4946
|
+
type: "rectangle",
|
|
4947
|
+
x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP,
|
|
4948
|
+
y: y - barHeight - BAR_GAP,
|
|
4949
|
+
width: BAR_WIDTH,
|
|
4950
|
+
height: barHeight
|
|
4951
|
+
});
|
|
4952
|
+
});
|
|
4953
|
+
return [
|
|
4954
|
+
...bars,
|
|
4955
|
+
...chartBaseElements(
|
|
4956
|
+
spreadsheet,
|
|
4957
|
+
x,
|
|
4958
|
+
y,
|
|
4959
|
+
groupId,
|
|
4960
|
+
backgroundColor,
|
|
4961
|
+
isDevEnv()
|
|
4962
|
+
)
|
|
4963
|
+
];
|
|
4964
|
+
};
|
|
4965
|
+
var chartTypeLine = (spreadsheet, x, y) => {
|
|
4966
|
+
const max = Math.max(...spreadsheet.values);
|
|
4967
|
+
const groupId = randomId();
|
|
4968
|
+
const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)];
|
|
4969
|
+
let index = 0;
|
|
4970
|
+
const points = [];
|
|
4971
|
+
for (const value of spreadsheet.values) {
|
|
4972
|
+
const cx = index * (BAR_WIDTH + BAR_GAP);
|
|
4973
|
+
const cy = -(value / max) * BAR_HEIGHT;
|
|
4974
|
+
points.push([cx, cy]);
|
|
4975
|
+
index++;
|
|
4976
|
+
}
|
|
4977
|
+
const maxX = Math.max(...points.map((element) => element[0]));
|
|
4978
|
+
const maxY = Math.max(...points.map((element) => element[1]));
|
|
4979
|
+
const minX = Math.min(...points.map((element) => element[0]));
|
|
4980
|
+
const minY = Math.min(...points.map((element) => element[1]));
|
|
4981
|
+
const line = newLinearElement({
|
|
4982
|
+
backgroundColor,
|
|
4983
|
+
groupIds: [groupId],
|
|
4984
|
+
...commonProps,
|
|
4985
|
+
type: "line",
|
|
4986
|
+
x: x + BAR_GAP + BAR_WIDTH / 2,
|
|
4987
|
+
y: y - BAR_GAP,
|
|
4988
|
+
height: maxY - minY,
|
|
4989
|
+
width: maxX - minX,
|
|
4990
|
+
strokeWidth: 2,
|
|
4991
|
+
points
|
|
4992
|
+
});
|
|
4993
|
+
const dots = spreadsheet.values.map((value, index2) => {
|
|
4994
|
+
const cx = index2 * (BAR_WIDTH + BAR_GAP) + BAR_GAP / 2;
|
|
4995
|
+
const cy = -(value / max) * BAR_HEIGHT + BAR_GAP / 2;
|
|
4996
|
+
return newElement({
|
|
4997
|
+
backgroundColor,
|
|
4998
|
+
groupIds: [groupId],
|
|
4999
|
+
...commonProps,
|
|
5000
|
+
fillStyle: "solid",
|
|
5001
|
+
strokeWidth: 2,
|
|
5002
|
+
type: "ellipse",
|
|
5003
|
+
x: x + cx + BAR_WIDTH / 2,
|
|
5004
|
+
y: y + cy - BAR_GAP * 2,
|
|
5005
|
+
width: BAR_GAP,
|
|
5006
|
+
height: BAR_GAP
|
|
5007
|
+
});
|
|
5008
|
+
});
|
|
5009
|
+
const lines = spreadsheet.values.map((value, index2) => {
|
|
5010
|
+
const cx = index2 * (BAR_WIDTH + BAR_GAP) + BAR_GAP / 2;
|
|
5011
|
+
const cy = value / max * BAR_HEIGHT + BAR_GAP / 2 + BAR_GAP;
|
|
5012
|
+
return newLinearElement({
|
|
5013
|
+
backgroundColor,
|
|
5014
|
+
groupIds: [groupId],
|
|
5015
|
+
...commonProps,
|
|
5016
|
+
type: "line",
|
|
5017
|
+
x: x + cx + BAR_WIDTH / 2 + BAR_GAP / 2,
|
|
5018
|
+
y: y - cy,
|
|
5019
|
+
height: cy,
|
|
5020
|
+
strokeStyle: "dotted",
|
|
5021
|
+
opacity: GRID_OPACITY,
|
|
5022
|
+
points: [pointFrom3(0, 0), pointFrom3(0, cy)]
|
|
5023
|
+
});
|
|
5024
|
+
});
|
|
5025
|
+
return [
|
|
5026
|
+
...chartBaseElements(
|
|
5027
|
+
spreadsheet,
|
|
5028
|
+
x,
|
|
5029
|
+
y,
|
|
5030
|
+
groupId,
|
|
5031
|
+
backgroundColor,
|
|
5032
|
+
isDevEnv()
|
|
5033
|
+
),
|
|
5034
|
+
line,
|
|
5035
|
+
...lines,
|
|
5036
|
+
...dots
|
|
5037
|
+
];
|
|
5038
|
+
};
|
|
5039
|
+
var renderSpreadsheet = (chartType, spreadsheet, x, y) => {
|
|
5040
|
+
if (chartType === "line") {
|
|
5041
|
+
return chartTypeLine(spreadsheet, x, y);
|
|
5042
|
+
}
|
|
5043
|
+
return chartTypeBar(spreadsheet, x, y);
|
|
5044
|
+
};
|
|
5045
|
+
|
|
5046
|
+
// clipboard.ts
|
|
5047
|
+
var probablySupportsClipboardReadText = "clipboard" in navigator && "readText" in navigator.clipboard;
|
|
5048
|
+
var probablySupportsClipboardWriteText = "clipboard" in navigator && "writeText" in navigator.clipboard;
|
|
5049
|
+
var probablySupportsClipboardBlob = "clipboard" in navigator && "write" in navigator.clipboard && "ClipboardItem" in window && "toBlob" in HTMLCanvasElement.prototype;
|
|
5050
|
+
var clipboardContainsElements = (contents) => {
|
|
5051
|
+
if ([
|
|
5052
|
+
EXPORT_DATA_TYPES3.excalidraw,
|
|
5053
|
+
EXPORT_DATA_TYPES3.excalidrawClipboard,
|
|
5054
|
+
EXPORT_DATA_TYPES3.excalidrawClipboardWithAPI
|
|
5055
|
+
].includes(contents?.type) && Array.isArray(contents.elements)) {
|
|
5056
|
+
return true;
|
|
5057
|
+
}
|
|
5058
|
+
return false;
|
|
5059
|
+
};
|
|
5060
|
+
var createPasteEvent = ({
|
|
5061
|
+
types,
|
|
5062
|
+
files
|
|
5063
|
+
}) => {
|
|
5064
|
+
if (!types && !files) {
|
|
5065
|
+
console.warn("createPasteEvent: no types or files provided");
|
|
5066
|
+
}
|
|
5067
|
+
const event = new ClipboardEvent(EVENT2.PASTE, {
|
|
5068
|
+
clipboardData: new DataTransfer()
|
|
5069
|
+
});
|
|
5070
|
+
if (types) {
|
|
5071
|
+
for (const [type, value] of Object.entries(types)) {
|
|
5072
|
+
if (typeof value !== "string") {
|
|
5073
|
+
files = files || [];
|
|
5074
|
+
files.push(value);
|
|
5075
|
+
continue;
|
|
5076
|
+
}
|
|
5077
|
+
try {
|
|
5078
|
+
event.clipboardData?.setData(type, value);
|
|
5079
|
+
if (event.clipboardData?.getData(type) !== value) {
|
|
5080
|
+
throw new Error(`Failed to set "${type}" as clipboardData item`);
|
|
5081
|
+
}
|
|
5082
|
+
} catch (error) {
|
|
5083
|
+
throw new Error(error.message);
|
|
5084
|
+
}
|
|
5085
|
+
}
|
|
5086
|
+
}
|
|
5087
|
+
if (files) {
|
|
5088
|
+
let idx = -1;
|
|
5089
|
+
for (const file of files) {
|
|
5090
|
+
idx++;
|
|
5091
|
+
try {
|
|
5092
|
+
event.clipboardData?.items.add(file);
|
|
5093
|
+
if (event.clipboardData?.files[idx] !== file) {
|
|
5094
|
+
throw new Error(
|
|
5095
|
+
`Failed to set file "${file.name}" as clipboardData item`
|
|
5096
|
+
);
|
|
5097
|
+
}
|
|
5098
|
+
} catch (error) {
|
|
5099
|
+
throw new Error(error.message);
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
5103
|
+
return event;
|
|
5104
|
+
};
|
|
5105
|
+
var serializeAsClipboardJSON = ({
|
|
5106
|
+
elements,
|
|
5107
|
+
files
|
|
5108
|
+
}) => {
|
|
5109
|
+
const elementsMap = arrayToMap2(elements);
|
|
5110
|
+
const framesToCopy = new Set(
|
|
5111
|
+
elements.filter((element) => isFrameLikeElement2(element))
|
|
5112
|
+
);
|
|
5113
|
+
let foundFile = false;
|
|
5114
|
+
const _files = elements.reduce((acc, element) => {
|
|
5115
|
+
if (isInitializedImageElement2(element)) {
|
|
5116
|
+
foundFile = true;
|
|
5117
|
+
if (files && files[element.fileId]) {
|
|
5118
|
+
acc[element.fileId] = files[element.fileId];
|
|
5119
|
+
}
|
|
5120
|
+
}
|
|
5121
|
+
return acc;
|
|
5122
|
+
}, {});
|
|
5123
|
+
if (foundFile && !files) {
|
|
5124
|
+
console.warn(
|
|
5125
|
+
"copyToClipboard: attempting to file element(s) without providing associated `files` object."
|
|
5126
|
+
);
|
|
5127
|
+
}
|
|
5128
|
+
const contents = {
|
|
5129
|
+
type: EXPORT_DATA_TYPES3.excalidrawClipboard,
|
|
5130
|
+
elements: elements.map((element) => {
|
|
5131
|
+
if (getContainingFrame2(element, elementsMap) && !framesToCopy.has(getContainingFrame2(element, elementsMap))) {
|
|
5132
|
+
const copiedElement = deepCopyElement(element);
|
|
5133
|
+
mutateElement(copiedElement, elementsMap, {
|
|
5134
|
+
frameId: null
|
|
5135
|
+
});
|
|
5136
|
+
return copiedElement;
|
|
5137
|
+
}
|
|
5138
|
+
return element;
|
|
5139
|
+
}),
|
|
5140
|
+
files: files ? _files : void 0
|
|
5141
|
+
};
|
|
5142
|
+
return JSON.stringify(contents);
|
|
5143
|
+
};
|
|
5144
|
+
var copyToClipboard = async (elements, files, clipboardEvent) => {
|
|
5145
|
+
await copyTextToSystemClipboard(
|
|
5146
|
+
serializeAsClipboardJSON({ elements, files }),
|
|
5147
|
+
clipboardEvent
|
|
5148
|
+
);
|
|
5149
|
+
};
|
|
5150
|
+
var parsePotentialSpreadsheet = (text) => {
|
|
5151
|
+
const result = tryParseSpreadsheet(text);
|
|
5152
|
+
if (result.type === VALID_SPREADSHEET) {
|
|
5153
|
+
return { spreadsheet: result.spreadsheet };
|
|
5154
|
+
}
|
|
5155
|
+
return null;
|
|
5156
|
+
};
|
|
5157
|
+
function parseHTMLTree(el) {
|
|
5158
|
+
let result = [];
|
|
5159
|
+
for (const node of el.childNodes) {
|
|
5160
|
+
if (node.nodeType === 3) {
|
|
5161
|
+
const text = node.textContent?.trim();
|
|
5162
|
+
if (text) {
|
|
5163
|
+
result.push({ type: "text", value: text });
|
|
5164
|
+
}
|
|
5165
|
+
} else if (node instanceof HTMLImageElement) {
|
|
5166
|
+
const url = node.getAttribute("src");
|
|
5167
|
+
if (url && url.startsWith("http")) {
|
|
5168
|
+
result.push({ type: "imageUrl", value: url });
|
|
5169
|
+
}
|
|
5170
|
+
} else {
|
|
5171
|
+
result = result.concat(parseHTMLTree(node));
|
|
5172
|
+
}
|
|
5173
|
+
}
|
|
5174
|
+
return result;
|
|
5175
|
+
}
|
|
5176
|
+
var maybeParseHTMLPaste = (event) => {
|
|
5177
|
+
const html = event.clipboardData?.getData(MIME_TYPES6.html);
|
|
5178
|
+
if (!html) {
|
|
5179
|
+
return null;
|
|
5180
|
+
}
|
|
5181
|
+
try {
|
|
5182
|
+
const doc = new DOMParser().parseFromString(html, MIME_TYPES6.html);
|
|
5183
|
+
const content = parseHTMLTree(doc.body);
|
|
5184
|
+
if (content.length) {
|
|
5185
|
+
return { type: "mixedContent", value: content };
|
|
5186
|
+
}
|
|
5187
|
+
} catch (error) {
|
|
5188
|
+
console.error(`error in parseHTMLFromPaste: ${error.message}`);
|
|
5189
|
+
}
|
|
5190
|
+
return null;
|
|
5191
|
+
};
|
|
5192
|
+
var readSystemClipboard = async () => {
|
|
5193
|
+
const types = {};
|
|
5194
|
+
let clipboardItems;
|
|
5195
|
+
try {
|
|
5196
|
+
clipboardItems = await navigator.clipboard?.read();
|
|
5197
|
+
} catch (error) {
|
|
5198
|
+
try {
|
|
5199
|
+
if (navigator.clipboard?.readText) {
|
|
5200
|
+
console.warn(
|
|
5201
|
+
`navigator.clipboard.readText() failed (${error.message}). Failling back to navigator.clipboard.read()`
|
|
5202
|
+
);
|
|
5203
|
+
const readText = await navigator.clipboard?.readText();
|
|
5204
|
+
if (readText) {
|
|
5205
|
+
return { [MIME_TYPES6.text]: readText };
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5208
|
+
} catch (error2) {
|
|
5209
|
+
if (navigator.clipboard?.read) {
|
|
5210
|
+
console.warn(
|
|
5211
|
+
`navigator.clipboard.readText() failed (${error2.message}). Failling back to navigator.clipboard.read()`
|
|
5212
|
+
);
|
|
5213
|
+
} else {
|
|
5214
|
+
if (error2.name === "DataError") {
|
|
5215
|
+
console.warn(
|
|
5216
|
+
`navigator.clipboard.read() error, clipboard is probably empty: ${error2.message}`
|
|
5217
|
+
);
|
|
5218
|
+
return types;
|
|
5219
|
+
}
|
|
5220
|
+
throw error2;
|
|
5221
|
+
}
|
|
5222
|
+
}
|
|
5223
|
+
throw error;
|
|
5224
|
+
}
|
|
5225
|
+
for (const item of clipboardItems) {
|
|
5226
|
+
for (const type of item.types) {
|
|
5227
|
+
if (!isMemberOf(ALLOWED_PASTE_MIME_TYPES, type)) {
|
|
5228
|
+
continue;
|
|
5229
|
+
}
|
|
5230
|
+
try {
|
|
5231
|
+
if (type === MIME_TYPES6.text || type === MIME_TYPES6.html) {
|
|
5232
|
+
types[type] = await (await item.getType(type)).text();
|
|
5233
|
+
} else if (isSupportedImageFileType(type)) {
|
|
5234
|
+
const imageBlob = await item.getType(type);
|
|
5235
|
+
const file = createFile(imageBlob, type, void 0);
|
|
5236
|
+
types[type] = file;
|
|
5237
|
+
} else {
|
|
5238
|
+
throw new ExcalidrawError(`Unsupported clipboard type: ${type}`);
|
|
5239
|
+
}
|
|
5240
|
+
} catch (error) {
|
|
5241
|
+
console.warn(
|
|
5242
|
+
error instanceof ExcalidrawError ? error.message : `Cannot retrieve ${type} from clipboardItem: ${error.message}`
|
|
5243
|
+
);
|
|
5244
|
+
}
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
if (Object.keys(types).length === 0) {
|
|
5248
|
+
console.warn("No clipboard data found from clipboard.read().");
|
|
5249
|
+
return types;
|
|
5250
|
+
}
|
|
5251
|
+
return types;
|
|
5252
|
+
};
|
|
5253
|
+
var parseClipboardEventTextData = async (event, isPlainPaste = false) => {
|
|
5254
|
+
try {
|
|
5255
|
+
const mixedContent = !isPlainPaste && event && maybeParseHTMLPaste(event);
|
|
5256
|
+
if (mixedContent) {
|
|
5257
|
+
if (mixedContent.value.every((item) => item.type === "text")) {
|
|
5258
|
+
return {
|
|
5259
|
+
type: "text",
|
|
5260
|
+
value: event.clipboardData?.getData(MIME_TYPES6.text) || mixedContent.value.map((item) => item.value).join("\n").trim()
|
|
5261
|
+
};
|
|
5262
|
+
}
|
|
5263
|
+
return mixedContent;
|
|
5264
|
+
}
|
|
5265
|
+
const text = event.clipboardData?.getData(MIME_TYPES6.text);
|
|
5266
|
+
return { type: "text", value: (text || "").trim() };
|
|
5267
|
+
} catch {
|
|
5268
|
+
return { type: "text", value: "" };
|
|
5269
|
+
}
|
|
5270
|
+
};
|
|
5271
|
+
var parseClipboard = async (event, isPlainPaste = false) => {
|
|
5272
|
+
const parsedEventData = await parseClipboardEventTextData(
|
|
5273
|
+
event,
|
|
5274
|
+
isPlainPaste
|
|
5275
|
+
);
|
|
5276
|
+
if (parsedEventData.type === "mixedContent") {
|
|
5277
|
+
return {
|
|
5278
|
+
mixedContent: parsedEventData.value
|
|
5279
|
+
};
|
|
5280
|
+
}
|
|
5281
|
+
try {
|
|
5282
|
+
const spreadsheetResult = !isPlainPaste && parsePotentialSpreadsheet(parsedEventData.value);
|
|
5283
|
+
if (spreadsheetResult) {
|
|
5284
|
+
return spreadsheetResult;
|
|
5285
|
+
}
|
|
5286
|
+
} catch (error) {
|
|
5287
|
+
console.error(error);
|
|
5288
|
+
}
|
|
5289
|
+
try {
|
|
5290
|
+
const systemClipboardData = JSON.parse(parsedEventData.value);
|
|
5291
|
+
const programmaticAPI = systemClipboardData.type === EXPORT_DATA_TYPES3.excalidrawClipboardWithAPI;
|
|
5292
|
+
if (clipboardContainsElements(systemClipboardData)) {
|
|
5293
|
+
return {
|
|
5294
|
+
elements: systemClipboardData.elements,
|
|
5295
|
+
files: systemClipboardData.files,
|
|
5296
|
+
text: isPlainPaste ? JSON.stringify(systemClipboardData.elements, null, 2) : void 0,
|
|
5297
|
+
programmaticAPI
|
|
5298
|
+
};
|
|
5299
|
+
}
|
|
5300
|
+
} catch {
|
|
5301
|
+
}
|
|
5302
|
+
return { text: parsedEventData.value };
|
|
5303
|
+
};
|
|
5304
|
+
var copyBlobToClipboardAsPng = async (blob) => {
|
|
5305
|
+
try {
|
|
5306
|
+
await navigator.clipboard.write([
|
|
5307
|
+
new window.ClipboardItem({
|
|
5308
|
+
[MIME_TYPES6.png]: blob
|
|
5309
|
+
})
|
|
5310
|
+
]);
|
|
5311
|
+
} catch (error) {
|
|
5312
|
+
if (isPromiseLike(blob)) {
|
|
5313
|
+
await navigator.clipboard.write([
|
|
5314
|
+
new window.ClipboardItem({
|
|
5315
|
+
[MIME_TYPES6.png]: await blob
|
|
5316
|
+
})
|
|
5317
|
+
]);
|
|
5318
|
+
} else {
|
|
5319
|
+
throw error;
|
|
5320
|
+
}
|
|
5321
|
+
}
|
|
5322
|
+
};
|
|
5323
|
+
var copyTextToSystemClipboard = async (text, clipboardEvent) => {
|
|
5324
|
+
if (probablySupportsClipboardWriteText) {
|
|
5325
|
+
try {
|
|
5326
|
+
await navigator.clipboard.writeText(text || "");
|
|
5327
|
+
return;
|
|
5328
|
+
} catch (error) {
|
|
5329
|
+
console.error(error);
|
|
5330
|
+
}
|
|
5331
|
+
}
|
|
5332
|
+
try {
|
|
5333
|
+
if (clipboardEvent) {
|
|
5334
|
+
clipboardEvent.clipboardData?.setData(MIME_TYPES6.text, text || "");
|
|
5335
|
+
if (clipboardEvent.clipboardData?.getData(MIME_TYPES6.text) !== text) {
|
|
5336
|
+
throw new Error("Failed to setData on clipboardEvent");
|
|
5337
|
+
}
|
|
5338
|
+
return;
|
|
5339
|
+
}
|
|
5340
|
+
} catch (error) {
|
|
5341
|
+
console.error(error);
|
|
5342
|
+
}
|
|
5343
|
+
if (!copyTextViaExecCommand(text)) {
|
|
5344
|
+
throw new Error("Error copying to clipboard.");
|
|
5345
|
+
}
|
|
5346
|
+
};
|
|
5347
|
+
var copyTextViaExecCommand = (text) => {
|
|
5348
|
+
if (!text) {
|
|
5349
|
+
text = " ";
|
|
5350
|
+
}
|
|
5351
|
+
const isRTL2 = document.documentElement.getAttribute("dir") === "rtl";
|
|
5352
|
+
const textarea = document.createElement("textarea");
|
|
5353
|
+
textarea.style.border = "0";
|
|
5354
|
+
textarea.style.padding = "0";
|
|
5355
|
+
textarea.style.margin = "0";
|
|
5356
|
+
textarea.style.position = "absolute";
|
|
5357
|
+
textarea.style[isRTL2 ? "right" : "left"] = "-9999px";
|
|
5358
|
+
const yPosition = window.pageYOffset || document.documentElement.scrollTop;
|
|
5359
|
+
textarea.style.top = `${yPosition}px`;
|
|
5360
|
+
textarea.style.fontSize = "12pt";
|
|
5361
|
+
textarea.setAttribute("readonly", "");
|
|
5362
|
+
textarea.value = text;
|
|
5363
|
+
document.body.appendChild(textarea);
|
|
5364
|
+
let success = false;
|
|
5365
|
+
try {
|
|
5366
|
+
textarea.select();
|
|
5367
|
+
textarea.setSelectionRange(0, textarea.value.length);
|
|
5368
|
+
success = document.execCommand("copy");
|
|
5369
|
+
} catch (error) {
|
|
5370
|
+
console.error(error);
|
|
5371
|
+
}
|
|
5372
|
+
textarea.remove();
|
|
5373
|
+
return success;
|
|
5374
|
+
};
|
|
5375
|
+
var isClipboardEvent = (event) => {
|
|
5376
|
+
return event.type === EVENT2.PASTE || event.type === EVENT2.COPY || event.type === EVENT2.CUT;
|
|
5377
|
+
};
|
|
5378
|
+
|
|
5379
|
+
// data/restore.ts
|
|
5380
|
+
import { isFiniteNumber, pointFrom as pointFrom4 } from "@excalidraw/math";
|
|
5381
|
+
import {
|
|
5382
|
+
DEFAULT_FONT_FAMILY as DEFAULT_FONT_FAMILY3,
|
|
4684
5383
|
DEFAULT_TEXT_ALIGN as DEFAULT_TEXT_ALIGN2,
|
|
4685
5384
|
DEFAULT_VERTICAL_ALIGN,
|
|
4686
5385
|
FONT_FAMILY as FONT_FAMILY3,
|
|
@@ -4689,10 +5388,10 @@ import {
|
|
|
4689
5388
|
DEFAULT_ELEMENT_PROPS as DEFAULT_ELEMENT_PROPS2,
|
|
4690
5389
|
DEFAULT_GRID_SIZE as DEFAULT_GRID_SIZE2,
|
|
4691
5390
|
DEFAULT_GRID_STEP as DEFAULT_GRID_STEP2,
|
|
4692
|
-
randomId,
|
|
5391
|
+
randomId as randomId2,
|
|
4693
5392
|
getUpdatedTimestamp,
|
|
4694
5393
|
updateActiveTool,
|
|
4695
|
-
arrayToMap as
|
|
5394
|
+
arrayToMap as arrayToMap3,
|
|
4696
5395
|
getSizeFromPoints,
|
|
4697
5396
|
normalizeLink as normalizeLink2,
|
|
4698
5397
|
getLineHeight
|
|
@@ -4744,7 +5443,7 @@ var getFontFamilyByName = (fontFamilyName) => {
|
|
|
4744
5443
|
if (Object.keys(FONT_FAMILY3).includes(fontFamilyName)) {
|
|
4745
5444
|
return FONT_FAMILY3[fontFamilyName];
|
|
4746
5445
|
}
|
|
4747
|
-
return
|
|
5446
|
+
return DEFAULT_FONT_FAMILY3;
|
|
4748
5447
|
};
|
|
4749
5448
|
var repairBinding = (element, binding) => {
|
|
4750
5449
|
if (!binding) {
|
|
@@ -4773,7 +5472,7 @@ var restoreElementWithProperties = (element, extra) => {
|
|
|
4773
5472
|
versionNonce: element.versionNonce ?? 0,
|
|
4774
5473
|
index: element.index ?? null,
|
|
4775
5474
|
isDeleted: element.isDeleted ?? false,
|
|
4776
|
-
id: element.id ||
|
|
5475
|
+
id: element.id || randomId2(),
|
|
4777
5476
|
fillStyle: element.fillStyle || DEFAULT_ELEMENT_PROPS2.fillStyle,
|
|
4778
5477
|
strokeWidth: element.strokeWidth || DEFAULT_ELEMENT_PROPS2.strokeWidth,
|
|
4779
5478
|
strokeStyle: element.strokeStyle ?? DEFAULT_ELEMENT_PROPS2.strokeStyle,
|
|
@@ -4815,7 +5514,7 @@ var restoreElementWithProperties = (element, extra) => {
|
|
|
4815
5514
|
delete ret.boundElementIds;
|
|
4816
5515
|
return ret;
|
|
4817
5516
|
};
|
|
4818
|
-
var restoreElement = (element) => {
|
|
5517
|
+
var restoreElement = (element, opts) => {
|
|
4819
5518
|
element = { ...element };
|
|
4820
5519
|
switch (element.type) {
|
|
4821
5520
|
case "text":
|
|
@@ -4847,7 +5546,7 @@ var restoreElement = (element) => {
|
|
|
4847
5546
|
autoResize: element.autoResize ?? true,
|
|
4848
5547
|
lineHeight
|
|
4849
5548
|
});
|
|
4850
|
-
if (!text && !element.isDeleted) {
|
|
5549
|
+
if (opts?.deleteInvisibleElements && !text && !element.isDeleted) {
|
|
4851
5550
|
element = { ...element, originalText: text, isDeleted: true };
|
|
4852
5551
|
element = bumpVersion(element);
|
|
4853
5552
|
}
|
|
@@ -4874,7 +5573,7 @@ var restoreElement = (element) => {
|
|
|
4874
5573
|
let y = element.y;
|
|
4875
5574
|
let points = (
|
|
4876
5575
|
// migrate old arrow model to new one
|
|
4877
|
-
!Array.isArray(element.points) || element.points.length < 2 ? [
|
|
5576
|
+
!Array.isArray(element.points) || element.points.length < 2 ? [pointFrom4(0, 0), pointFrom4(element.width, element.height)] : element.points
|
|
4878
5577
|
);
|
|
4879
5578
|
if (points[0][0] !== 0 || points[0][1] !== 0) {
|
|
4880
5579
|
({ points, x, y } = LinearElementEditor2.getNormalizeElementPointsAndCoords(element));
|
|
@@ -4900,7 +5599,7 @@ var restoreElement = (element) => {
|
|
|
4900
5599
|
let y2 = element.y;
|
|
4901
5600
|
let points2 = (
|
|
4902
5601
|
// migrate old arrow model to new one
|
|
4903
|
-
!Array.isArray(element.points) || element.points.length < 2 ? [
|
|
5602
|
+
!Array.isArray(element.points) || element.points.length < 2 ? [pointFrom4(0, 0), pointFrom4(element.width, element.height)] : element.points
|
|
4904
5603
|
);
|
|
4905
5604
|
if (points2[0][0] !== 0 || points2[0][1] !== 0) {
|
|
4906
5605
|
({ points: points2, x: x2, y: y2 } = LinearElementEditor2.getNormalizeElementPointsAndCoords(element));
|
|
@@ -4923,7 +5622,7 @@ var restoreElement = (element) => {
|
|
|
4923
5622
|
elbowed: true,
|
|
4924
5623
|
startBinding: repairBinding(element, element.startBinding),
|
|
4925
5624
|
endBinding: repairBinding(element, element.endBinding),
|
|
4926
|
-
fixedSegments: element.fixedSegments,
|
|
5625
|
+
fixedSegments: element.fixedSegments?.length && base.points.length >= 4 ? element.fixedSegments : null,
|
|
4927
5626
|
startIsSpecial: element.startIsSpecial,
|
|
4928
5627
|
endIsSpecial: element.endIsSpecial
|
|
4929
5628
|
}) : restoreElementWithProperties(element, base);
|
|
@@ -4993,25 +5692,29 @@ var repairFrameMembership = (element, elementsMap) => {
|
|
|
4993
5692
|
};
|
|
4994
5693
|
var restoreElements = (elements, localElements, opts) => {
|
|
4995
5694
|
const existingIds = /* @__PURE__ */ new Set();
|
|
4996
|
-
const localElementsMap = localElements ?
|
|
5695
|
+
const localElementsMap = localElements ? arrayToMap3(localElements) : null;
|
|
4997
5696
|
const restoredElements = syncInvalidIndices2(
|
|
4998
5697
|
(elements || []).reduce((elements2, element) => {
|
|
4999
|
-
if (element.type
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
elements2.push(migratedElement);
|
|
5698
|
+
if (element.type === "selection") {
|
|
5699
|
+
return elements2;
|
|
5700
|
+
}
|
|
5701
|
+
let migratedElement = restoreElement(element, {
|
|
5702
|
+
deleteInvisibleElements: opts?.deleteInvisibleElements
|
|
5703
|
+
});
|
|
5704
|
+
if (migratedElement) {
|
|
5705
|
+
const localElement = localElementsMap?.get(element.id);
|
|
5706
|
+
const shouldMarkAsDeleted = opts?.deleteInvisibleElements && isInvisiblySmallElement(element);
|
|
5707
|
+
if (shouldMarkAsDeleted || localElement && localElement.version > migratedElement.version) {
|
|
5708
|
+
migratedElement = bumpVersion(migratedElement, localElement?.version);
|
|
5709
|
+
}
|
|
5710
|
+
if (shouldMarkAsDeleted) {
|
|
5711
|
+
migratedElement = { ...migratedElement, isDeleted: true };
|
|
5014
5712
|
}
|
|
5713
|
+
if (existingIds.has(migratedElement.id)) {
|
|
5714
|
+
migratedElement = { ...migratedElement, id: randomId2() };
|
|
5715
|
+
}
|
|
5716
|
+
existingIds.add(migratedElement.id);
|
|
5717
|
+
elements2.push(migratedElement);
|
|
5015
5718
|
}
|
|
5016
5719
|
return elements2;
|
|
5017
5720
|
}, [])
|
|
@@ -5019,7 +5722,7 @@ var restoreElements = (elements, localElements, opts) => {
|
|
|
5019
5722
|
if (!opts?.repairBindings) {
|
|
5020
5723
|
return restoredElements;
|
|
5021
5724
|
}
|
|
5022
|
-
const restoredElementsMap =
|
|
5725
|
+
const restoredElementsMap = arrayToMap3(restoredElements);
|
|
5023
5726
|
for (const element of restoredElements) {
|
|
5024
5727
|
if (element.frameId) {
|
|
5025
5728
|
repairFrameMembership(element, restoredElementsMap);
|
|
@@ -5057,7 +5760,7 @@ var restoreElements = (elements, localElements, opts) => {
|
|
|
5057
5760
|
restoredElementsMap,
|
|
5058
5761
|
{
|
|
5059
5762
|
points: [
|
|
5060
|
-
|
|
5763
|
+
pointFrom4(0, 0),
|
|
5061
5764
|
element.points[element.points.length - 1]
|
|
5062
5765
|
]
|
|
5063
5766
|
}
|
|
@@ -5086,10 +5789,10 @@ var restoreElements = (elements, localElements, opts) => {
|
|
|
5086
5789
|
width: boundElement.width,
|
|
5087
5790
|
height: boundElement.height,
|
|
5088
5791
|
points: [
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5792
|
+
pointFrom4(0, 0),
|
|
5793
|
+
pointFrom4(0, -10),
|
|
5794
|
+
pointFrom4(boundElement.width / 2 + 5, -10),
|
|
5795
|
+
pointFrom4(
|
|
5093
5796
|
boundElement.width / 2 + 5,
|
|
5094
5797
|
boundElement.height / 2 + 5
|
|
5095
5798
|
)
|
|
@@ -5188,7 +5891,7 @@ var restoreLibraryItems = (libraryItems = [], defaultStatus) => {
|
|
|
5188
5891
|
const restoredItem = restoreLibraryItem({
|
|
5189
5892
|
status: defaultStatus,
|
|
5190
5893
|
elements: item,
|
|
5191
|
-
id:
|
|
5894
|
+
id: randomId2(),
|
|
5192
5895
|
created: Date.now()
|
|
5193
5896
|
});
|
|
5194
5897
|
if (restoredItem) {
|
|
@@ -5198,7 +5901,7 @@ var restoreLibraryItems = (libraryItems = [], defaultStatus) => {
|
|
|
5198
5901
|
const _item = item;
|
|
5199
5902
|
const restoredItem = restoreLibraryItem({
|
|
5200
5903
|
..._item,
|
|
5201
|
-
id: _item.id ||
|
|
5904
|
+
id: _item.id || randomId2(),
|
|
5202
5905
|
status: _item.status || defaultStatus,
|
|
5203
5906
|
created: _item.created || Date.now()
|
|
5204
5907
|
});
|
|
@@ -5213,9 +5916,9 @@ var restoreLibraryItems = (libraryItems = [], defaultStatus) => {
|
|
|
5213
5916
|
// data/blob.ts
|
|
5214
5917
|
var parseFileContents = async (blob) => {
|
|
5215
5918
|
let contents;
|
|
5216
|
-
if (blob.type ===
|
|
5919
|
+
if (blob.type === MIME_TYPES7.png) {
|
|
5217
5920
|
try {
|
|
5218
|
-
return await (await import("./data/image-
|
|
5921
|
+
return await (await import("./data/image-6EX7CJAB.js")).decodePngMetadata(blob);
|
|
5219
5922
|
} catch (error) {
|
|
5220
5923
|
if (error.message === "INVALID") {
|
|
5221
5924
|
throw new ImageSceneDataError(
|
|
@@ -5240,7 +5943,7 @@ var parseFileContents = async (blob) => {
|
|
|
5240
5943
|
};
|
|
5241
5944
|
});
|
|
5242
5945
|
}
|
|
5243
|
-
if (blob.type ===
|
|
5946
|
+
if (blob.type === MIME_TYPES7.svg) {
|
|
5244
5947
|
try {
|
|
5245
5948
|
return decodeSvgBase64Payload({
|
|
5246
5949
|
svg: contents
|
|
@@ -5296,7 +5999,7 @@ var loadSceneOrLibraryFromBlob = async (blob, localAppState, localElements, file
|
|
|
5296
5999
|
}
|
|
5297
6000
|
if (isValidExcalidrawData(data)) {
|
|
5298
6001
|
return {
|
|
5299
|
-
type:
|
|
6002
|
+
type: MIME_TYPES7.excalidraw,
|
|
5300
6003
|
data: restore(
|
|
5301
6004
|
{
|
|
5302
6005
|
elements: clearElementsForExport2(data.elements || []),
|
|
@@ -5310,12 +6013,16 @@ var loadSceneOrLibraryFromBlob = async (blob, localAppState, localElements, file
|
|
|
5310
6013
|
},
|
|
5311
6014
|
localAppState,
|
|
5312
6015
|
localElements,
|
|
5313
|
-
{
|
|
6016
|
+
{
|
|
6017
|
+
repairBindings: true,
|
|
6018
|
+
refreshDimensions: false,
|
|
6019
|
+
deleteInvisibleElements: true
|
|
6020
|
+
}
|
|
5314
6021
|
)
|
|
5315
6022
|
};
|
|
5316
6023
|
} else if (isValidLibrary(data)) {
|
|
5317
6024
|
return {
|
|
5318
|
-
type:
|
|
6025
|
+
type: MIME_TYPES7.excalidrawlib,
|
|
5319
6026
|
data
|
|
5320
6027
|
};
|
|
5321
6028
|
}
|
|
@@ -5334,7 +6041,7 @@ var loadFromBlob = async (blob, localAppState, localElements, fileHandle) => {
|
|
|
5334
6041
|
localElements,
|
|
5335
6042
|
fileHandle
|
|
5336
6043
|
);
|
|
5337
|
-
if (ret.type !==
|
|
6044
|
+
if (ret.type !== MIME_TYPES7.excalidraw) {
|
|
5338
6045
|
throw new Error("Error: invalid file");
|
|
5339
6046
|
}
|
|
5340
6047
|
return ret.data;
|
|
@@ -5353,7 +6060,7 @@ var loadLibraryFromBlob = async (blob, defaultStatus = "unpublished") => {
|
|
|
5353
6060
|
var canvasToBlob = async (canvas) => {
|
|
5354
6061
|
return new Promise(async (resolve, reject) => {
|
|
5355
6062
|
try {
|
|
5356
|
-
if (
|
|
6063
|
+
if (isPromiseLike2(canvas)) {
|
|
5357
6064
|
canvas = await canvas;
|
|
5358
6065
|
}
|
|
5359
6066
|
canvas.toBlob((blob) => {
|
|
@@ -5402,7 +6109,7 @@ var dataURLToString = (dataURL) => {
|
|
|
5402
6109
|
return base64ToString(dataURL.slice(dataURL.indexOf(",") + 1));
|
|
5403
6110
|
};
|
|
5404
6111
|
var resizeImageFile = async (file, opts) => {
|
|
5405
|
-
if (file.type ===
|
|
6112
|
+
if (file.type === MIME_TYPES7.svg) {
|
|
5406
6113
|
return file;
|
|
5407
6114
|
}
|
|
5408
6115
|
const [pica, imageBlobReduce] = await Promise.all([
|
|
@@ -5435,7 +6142,7 @@ var resizeImageFile = async (file, opts) => {
|
|
|
5435
6142
|
};
|
|
5436
6143
|
var SVGStringToFile = (SVGString, filename = "") => {
|
|
5437
6144
|
return new File([new TextEncoder().encode(SVGString)], filename, {
|
|
5438
|
-
type:
|
|
6145
|
+
type: MIME_TYPES7.svg
|
|
5439
6146
|
});
|
|
5440
6147
|
};
|
|
5441
6148
|
var ImageURLToFile = async (imageUrl, filename = "") => {
|
|
@@ -5455,16 +6162,37 @@ var ImageURLToFile = async (imageUrl, filename = "") => {
|
|
|
5455
6162
|
}
|
|
5456
6163
|
throw new Error("Error: unsupported file type", { cause: "UNSUPPORTED" });
|
|
5457
6164
|
};
|
|
5458
|
-
var
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
6165
|
+
var getFilesFromEvent = async (event) => {
|
|
6166
|
+
let fileList = void 0;
|
|
6167
|
+
let items = void 0;
|
|
6168
|
+
if (isClipboardEvent(event)) {
|
|
6169
|
+
fileList = event.clipboardData?.files;
|
|
6170
|
+
items = event.clipboardData?.items;
|
|
6171
|
+
} else {
|
|
6172
|
+
const dragEvent = event;
|
|
6173
|
+
fileList = dragEvent.dataTransfer?.files;
|
|
6174
|
+
items = dragEvent.dataTransfer?.items;
|
|
6175
|
+
}
|
|
6176
|
+
const files = Array.from(fileList || []);
|
|
6177
|
+
return await Promise.all(
|
|
6178
|
+
files.map(async (file, idx) => {
|
|
6179
|
+
const dataTransferItem = items?.[idx];
|
|
6180
|
+
const fileHandle = dataTransferItem ? getFileHandle(dataTransferItem) : null;
|
|
6181
|
+
return file ? {
|
|
6182
|
+
file: await normalizeFile(file),
|
|
6183
|
+
fileHandle: await fileHandle
|
|
6184
|
+
} : {
|
|
6185
|
+
file: null,
|
|
6186
|
+
fileHandle: null
|
|
6187
|
+
};
|
|
6188
|
+
})
|
|
6189
|
+
);
|
|
5462
6190
|
};
|
|
5463
6191
|
var getFileHandle = async (event) => {
|
|
5464
6192
|
if (nativeFileSystemSupported) {
|
|
5465
6193
|
try {
|
|
5466
|
-
const
|
|
5467
|
-
const handle = await
|
|
6194
|
+
const dataTransferItem = event instanceof DataTransferItem ? event : event.dataTransfer?.items?.[0];
|
|
6195
|
+
const handle = await dataTransferItem.getAsFileSystemHandle() || null;
|
|
5468
6196
|
return handle;
|
|
5469
6197
|
} catch (error) {
|
|
5470
6198
|
console.warn(error.name, error.message);
|
|
@@ -5487,11 +6215,11 @@ var getActualMimeTypeFromImage = (buffer) => {
|
|
|
5487
6215
|
gif: "71 73 70 56 57 97 "
|
|
5488
6216
|
};
|
|
5489
6217
|
if (first8Bytes === headerBytes.png) {
|
|
5490
|
-
mimeType =
|
|
6218
|
+
mimeType = MIME_TYPES7.png;
|
|
5491
6219
|
} else if (first8Bytes.startsWith(headerBytes.jpg)) {
|
|
5492
|
-
mimeType =
|
|
6220
|
+
mimeType = MIME_TYPES7.jpg;
|
|
5493
6221
|
} else if (first8Bytes.startsWith(headerBytes.gif)) {
|
|
5494
|
-
mimeType =
|
|
6222
|
+
mimeType = MIME_TYPES7.gif;
|
|
5495
6223
|
}
|
|
5496
6224
|
return mimeType;
|
|
5497
6225
|
};
|
|
@@ -5505,13 +6233,13 @@ var normalizeFile = async (file) => {
|
|
|
5505
6233
|
if (file?.name?.endsWith(".excalidrawlib")) {
|
|
5506
6234
|
file = createFile(
|
|
5507
6235
|
await blobToArrayBuffer(file),
|
|
5508
|
-
|
|
6236
|
+
MIME_TYPES7.excalidrawlib,
|
|
5509
6237
|
file.name
|
|
5510
6238
|
);
|
|
5511
6239
|
} else if (file?.name?.endsWith(".excalidraw")) {
|
|
5512
6240
|
file = createFile(
|
|
5513
6241
|
await blobToArrayBuffer(file),
|
|
5514
|
-
|
|
6242
|
+
MIME_TYPES7.excalidraw,
|
|
5515
6243
|
file.name
|
|
5516
6244
|
);
|
|
5517
6245
|
} else {
|
|
@@ -5561,7 +6289,7 @@ var encodePngMetadata = async ({
|
|
|
5561
6289
|
}) => {
|
|
5562
6290
|
const chunks = decodePng(new Uint8Array(await blobToArrayBuffer(blob)));
|
|
5563
6291
|
const metadataChunk = tEXt.encode(
|
|
5564
|
-
|
|
6292
|
+
MIME_TYPES8.excalidraw,
|
|
5565
6293
|
JSON.stringify(
|
|
5566
6294
|
encode({
|
|
5567
6295
|
text: metadata,
|
|
@@ -5570,15 +6298,15 @@ var encodePngMetadata = async ({
|
|
|
5570
6298
|
)
|
|
5571
6299
|
);
|
|
5572
6300
|
chunks.splice(-1, 0, metadataChunk);
|
|
5573
|
-
return new Blob([encodePng(chunks)], { type:
|
|
6301
|
+
return new Blob([encodePng(chunks)], { type: MIME_TYPES8.png });
|
|
5574
6302
|
};
|
|
5575
6303
|
var decodePngMetadata = async (blob) => {
|
|
5576
6304
|
const metadata = await getTEXtChunk(blob);
|
|
5577
|
-
if (metadata?.keyword ===
|
|
6305
|
+
if (metadata?.keyword === MIME_TYPES8.excalidraw) {
|
|
5578
6306
|
try {
|
|
5579
6307
|
const encodedData = JSON.parse(metadata.text);
|
|
5580
6308
|
if (!("encoded" in encodedData)) {
|
|
5581
|
-
if ("type" in encodedData && encodedData.type ===
|
|
6309
|
+
if ("type" in encodedData && encodedData.type === EXPORT_DATA_TYPES4.excalidraw) {
|
|
5582
6310
|
return metadata.text;
|
|
5583
6311
|
}
|
|
5584
6312
|
throw new Error("FAILED");
|
|
@@ -5608,7 +6336,6 @@ export {
|
|
|
5608
6336
|
canChangeRoundness,
|
|
5609
6337
|
AbortError,
|
|
5610
6338
|
ImageSceneDataError,
|
|
5611
|
-
ExcalidrawError,
|
|
5612
6339
|
Fonts,
|
|
5613
6340
|
getDefaultAppState,
|
|
5614
6341
|
isEraserActive,
|
|
@@ -5637,6 +6364,7 @@ export {
|
|
|
5637
6364
|
exportToCanvas,
|
|
5638
6365
|
exportToSvg,
|
|
5639
6366
|
getExportSize,
|
|
6367
|
+
restoreElement,
|
|
5640
6368
|
restoreElements,
|
|
5641
6369
|
restoreAppState,
|
|
5642
6370
|
restore,
|
|
@@ -5647,7 +6375,6 @@ export {
|
|
|
5647
6375
|
getFileHandleType,
|
|
5648
6376
|
isImageFileHandleType,
|
|
5649
6377
|
isImageFileHandle,
|
|
5650
|
-
isSupportedImageFileType,
|
|
5651
6378
|
isSupportedImageFile,
|
|
5652
6379
|
loadSceneOrLibraryFromBlob,
|
|
5653
6380
|
loadFromBlob,
|
|
@@ -5661,8 +6388,16 @@ export {
|
|
|
5661
6388
|
resizeImageFile,
|
|
5662
6389
|
SVGStringToFile,
|
|
5663
6390
|
ImageURLToFile,
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
6391
|
+
getFilesFromEvent,
|
|
6392
|
+
normalizeFile,
|
|
6393
|
+
renderSpreadsheet,
|
|
6394
|
+
probablySupportsClipboardWriteText,
|
|
6395
|
+
probablySupportsClipboardBlob,
|
|
6396
|
+
createPasteEvent,
|
|
6397
|
+
copyToClipboard,
|
|
6398
|
+
readSystemClipboard,
|
|
6399
|
+
parseClipboard,
|
|
6400
|
+
copyBlobToClipboardAsPng,
|
|
6401
|
+
copyTextToSystemClipboard
|
|
5667
6402
|
};
|
|
5668
|
-
//# sourceMappingURL=chunk-
|
|
6403
|
+
//# sourceMappingURL=chunk-WQARCR2O.js.map
|