@mce/bigesj 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +917 -516
  2. package/package.json +2 -6
package/dist/index.js CHANGED
@@ -1,110 +1,132 @@
1
- import { useEditor as rt, definePlugin as nt } from "mce";
2
- import { assets as B, Element2D as ot } from "modern-canvas";
3
- import { ref as Z, effectScope as it, getCurrentScope as ft, onScopeDispose as ct, onBeforeUnmount as lt } from "vue";
4
- import { idGenerator as F, normalizeCRLF as Mt, isGradient as dt } from "modern-idoc";
5
- import { gunzipSync as Lt } from "fflate";
6
- const X = Z([]);
7
- function wt(e, r) {
8
- const o = [];
9
- for (let t = 0; t <= r.length; t++)
10
- o[t] = [t];
11
- for (let t = 0; t <= e.length; t++)
12
- o[0][t] = t;
13
- for (let t = 1; t <= r.length; t++)
14
- for (let s = 1; s <= e.length; s++) {
15
- const i = e[s - 1] === r[t - 1] ? 0 : 1;
16
- o[t][s] = Math.min(o[t - 1][s] + 1, o[t][s - 1] + 1, o[t - 1][s - 1] + i);
1
+ import { useEditor, definePlugin } from "mce";
2
+ import { assets, Element2D } from "modern-canvas";
3
+ import { ref, onBeforeUnmount } from "vue";
4
+ import { createSharedComposable } from "@vueuse/core";
5
+ import { idGenerator, normalizeCRLF, isGradient } from "modern-idoc";
6
+ import { gunzipSync } from "fflate";
7
+ const bigeFonts = ref([]);
8
+ function levenshteinDistance(a, b) {
9
+ const matrix = [];
10
+ for (let i = 0; i <= b.length; i++) {
11
+ matrix[i] = [i];
12
+ }
13
+ for (let j = 0; j <= a.length; j++) {
14
+ matrix[0][j] = j;
15
+ }
16
+ for (let i = 1; i <= b.length; i++) {
17
+ for (let j = 1; j <= a.length; j++) {
18
+ const cost = a[j - 1] === b[i - 1] ? 0 : 1;
19
+ matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);
17
20
  }
18
- return o[r.length][e.length];
21
+ }
22
+ return matrix[b.length][a.length];
19
23
  }
20
- function mt() {
24
+ function useFonts() {
21
25
  const {
22
- loadFont: e
23
- } = rt(), r = Z(/* @__PURE__ */ new Map());
24
- async function o(i) {
25
- let n = X.value;
26
- return n.length || (n = await fetch(i).then((f) => f.json()).then((f) => f.data.datalist), X.value = n), n;
26
+ loadFont: baseLoadFont
27
+ } = useEditor();
28
+ const fontPromises = ref(/* @__PURE__ */ new Map());
29
+ async function loadBigeFonts(url) {
30
+ let result = bigeFonts.value;
31
+ if (!result.length) {
32
+ result = await fetch(url).then((rep) => rep.json()).then((res) => res.data.datalist);
33
+ bigeFonts.value = result;
34
+ }
35
+ return result;
27
36
  }
28
- function t(i, n = X.value) {
29
- const f = new Map(n.map((a, M) => [a.id, M])), c = new Map(
30
- n.flatMap((a, M) => [...a.en_name.split(","), ...a.name.split(",")].map((L) => [L, M]))
31
- ), d = i.replace(/"/g, "").split(",");
32
- let l;
33
- if (d.forEach((a) => {
34
- l ??= f.get(a), l ??= c.get(a);
35
- }), l === void 0) {
36
- let a;
37
- d.forEach((M) => {
38
- let L = M;
39
- L.endsWith(" R") ? L = `${L.substring(0, L.length - 2)}常规` : L.endsWith(" B") && (L = `${L.substring(0, L.length - 2)}粗体`);
40
- const w = L.length;
41
- c.forEach((h, u) => {
42
- const C = wt(L, u);
43
- if (w <= C)
37
+ function searchBigeFont(keyword, fonts = bigeFonts.value) {
38
+ const idIndexMap = new Map(fonts.map((item, index2) => [item.id, index2]));
39
+ const nameIndexMap = new Map(
40
+ fonts.flatMap((item, index2) => {
41
+ return [...item.en_name.split(","), ...item.name.split(",")].map((name) => {
42
+ return [name, index2];
43
+ });
44
+ })
45
+ );
46
+ const fontFamilies = keyword.replace(/"/g, "").split(",");
47
+ let index;
48
+ fontFamilies.forEach((fontFamily) => {
49
+ index ??= idIndexMap.get(fontFamily);
50
+ index ??= nameIndexMap.get(fontFamily);
51
+ });
52
+ if (index === void 0) {
53
+ let prevWeight;
54
+ fontFamilies.forEach((rawA) => {
55
+ let a = rawA;
56
+ if (a.endsWith(" R")) {
57
+ a = `${a.substring(0, a.length - 2)}常规`;
58
+ } else if (a.endsWith(" B")) {
59
+ a = `${a.substring(0, a.length - 2)}粗体`;
60
+ }
61
+ const aLen = a.length;
62
+ nameIndexMap.forEach((i, b) => {
63
+ const dist = levenshteinDistance(a, b);
64
+ if (aLen <= dist) {
44
65
  return;
45
- const m = -(C * 0.9 + (u.endsWith("常规") ? 0 : 1) * 0.1);
46
- (a === void 0 || m > a) && (a = m, l = h);
66
+ }
67
+ const weight = -(dist * 0.9 + (b.endsWith("常规") ? 0 : 1) * 0.1);
68
+ if (prevWeight === void 0 || weight > prevWeight) {
69
+ prevWeight = weight;
70
+ index = i;
71
+ }
47
72
  });
48
73
  });
49
74
  }
50
- return l !== void 0 ? n[l] : void 0;
75
+ return index !== void 0 ? fonts[index] : void 0;
51
76
  }
52
- async function s(i) {
53
- const n = typeof i == "string" ? [i] : i, f = [];
54
- for (const c of n) {
55
- let d = r.value.get(c);
56
- if (!d) {
57
- const l = t(c);
58
- if (l && (d = r.value.get(l.en_name), !d)) {
59
- const a = Array.from(
60
- new Set(
61
- [c, l.en_name].filter(Boolean).map((M) => M.replace(/"/g, ""))
62
- )
63
- );
64
- d = e({
65
- family: a,
66
- src: l.fonturl
67
- }), a.forEach((M) => r.value.set(M, d)), r.value.set(String(c), d);
77
+ async function loadFont(name) {
78
+ const names = typeof name === "string" ? [name] : name;
79
+ const result = [];
80
+ for (const name2 of names) {
81
+ let promise = fontPromises.value.get(name2);
82
+ if (!promise) {
83
+ const font = searchBigeFont(name2);
84
+ if (font) {
85
+ promise = fontPromises.value.get(font.en_name);
86
+ if (!promise) {
87
+ const names2 = Array.from(
88
+ new Set(
89
+ [name2, font.en_name].filter(Boolean).map((v) => v.replace(/"/g, ""))
90
+ )
91
+ );
92
+ promise = baseLoadFont({
93
+ family: names2,
94
+ src: font.fonturl
95
+ });
96
+ names2.forEach((name3) => fontPromises.value.set(name3, promise));
97
+ fontPromises.value.set(String(name2), promise);
98
+ }
68
99
  }
69
100
  }
70
- d && f.push(d);
101
+ promise && result.push(promise);
71
102
  }
72
- return await Promise.all(f);
103
+ return await Promise.all(result);
73
104
  }
74
105
  return {
75
- bigeFonts: X,
76
- searchBigeFont: t,
77
- loadBigeFonts: o,
78
- loadFont: s
106
+ bigeFonts,
107
+ searchBigeFont,
108
+ loadBigeFonts,
109
+ loadFont
79
110
  };
80
111
  }
81
- function ut(e, r) {
82
- return ft() ? (ct(e, r), !0) : !1;
83
- }
84
- const gt = typeof window < "u" && typeof document < "u";
85
- typeof WorkerGlobalScope < "u" && globalThis instanceof WorkerGlobalScope;
86
- // @__NO_SIDE_EFFECTS__
87
- function yt(e) {
88
- if (!gt) return e;
89
- let r = 0, o, t;
90
- const s = () => {
91
- r -= 1, t && r <= 0 && (t.stop(), o = void 0, t = void 0);
92
- };
93
- return ((...i) => (r += 1, t || (t = it(!0), o = t.run(() => e(...i))), ut(s), o));
94
- }
95
- const _ = /* @__PURE__ */ yt(() => {
96
- const e = /* @__PURE__ */ new Map();
97
- function r(t, s) {
98
- let i = e.get(t);
99
- return i || (i = fetch(t).then(s), e.set(t, i)), i;
112
+ const useSharedTextAssets = createSharedComposable(() => {
113
+ const requests = /* @__PURE__ */ new Map();
114
+ function baseFetch(url, handle) {
115
+ let rep = requests.get(url);
116
+ if (!rep) {
117
+ rep = fetch(url).then(handle);
118
+ requests.set(url, rep);
119
+ }
120
+ return rep;
100
121
  }
101
- async function o(t) {
102
- return r(t, (s) => s.text());
122
+ async function fetchToText(url) {
123
+ return baseFetch(url, (rep) => rep.text());
103
124
  }
104
125
  return {
105
- fetchToText: o
126
+ fetchToText
106
127
  };
107
- }), Y = {
128
+ });
129
+ const animations = {
108
130
  easing: {
109
131
  匀速: "linear",
110
132
  加速: "cubic-bezier(0.55, 0, 1, 0.45)",
@@ -437,406 +459,699 @@ const _ = /* @__PURE__ */ yt(() => {
437
459
  ]
438
460
  }
439
461
  };
440
- function U(e, r, o) {
462
+ function convertAnimation(el, animation, type) {
441
463
  const {
442
- name: t,
443
- delay: s = 0,
444
- duration: i,
445
- iterations: n,
446
- mode: f,
447
- easing: c,
448
- path: d,
449
- offsetRotate: l,
450
- ...a
451
- } = r;
452
- let M;
453
- if (t === "自定义路径" && d) {
454
- let L = `M ${e.style.width / 2} ${e.style.height / 2}`;
455
- d.forEach((h) => {
456
- const u = Object.keys(h);
457
- L += ` ${u[0]}${h[u[0]].join(" ")}`;
464
+ name,
465
+ delay = 0,
466
+ duration,
467
+ iterations,
468
+ mode,
469
+ easing,
470
+ path,
471
+ offsetRotate,
472
+ ...meta
473
+ } = animation;
474
+ let keyframes;
475
+ if (name === "自定义路径" && path) {
476
+ let d = `M ${el.style.width / 2} ${el.style.height / 2}`;
477
+ path.forEach((v) => {
478
+ const keys = Object.keys(v);
479
+ d += ` ${keys[0]}${v[keys[0]].join(" ")}`;
458
480
  });
459
- const w = `path("${L}")`;
460
- switch (o) {
481
+ const offsetPath = `path("${d}")`;
482
+ switch (type) {
461
483
  case "in":
462
- M = [
463
- { opacity: 0, offsetDistance: "100%", offsetPath: w, offsetRotate: l },
464
- { offsetDistance: "0%", offsetPath: w, offsetRotate: l }
484
+ keyframes = [
485
+ { opacity: 0, offsetDistance: "100%", offsetPath, offsetRotate },
486
+ { offsetDistance: "0%", offsetPath, offsetRotate }
465
487
  ];
466
488
  break;
467
489
  case "stay":
468
- M = [
469
- { offsetDistance: "0%", offsetPath: w, offsetRotate: l },
470
- { offsetDistance: "100%", offsetPath: w, offsetRotate: l }
490
+ keyframes = [
491
+ { offsetDistance: "0%", offsetPath, offsetRotate },
492
+ { offsetDistance: "100%", offsetPath, offsetRotate }
471
493
  ];
472
494
  break;
473
495
  case "out":
474
- M = [
475
- { offsetDistance: "0%", offsetPath: w, offsetRotate: l },
476
- { opacity: 0, offsetDistance: "100%", offsetPath: w, offsetRotate: l }
496
+ keyframes = [
497
+ { offsetDistance: "0%", offsetPath, offsetRotate },
498
+ { opacity: 0, offsetDistance: "100%", offsetPath, offsetRotate }
477
499
  ];
478
500
  break;
479
501
  }
480
- } else
481
- switch (o) {
502
+ } else {
503
+ switch (type) {
482
504
  case "in":
483
- M = Y.textIn[t]?.[0] ?? Y.in[t];
505
+ keyframes = animations.textIn[name]?.[0] ?? animations.in[name];
484
506
  break;
485
507
  case "stay":
486
- M = Y.stay[t];
508
+ keyframes = animations.stay[name];
487
509
  break;
488
510
  case "out":
489
- M = Y.out[t];
511
+ keyframes = animations.out[name];
490
512
  break;
491
513
  }
514
+ }
492
515
  return {
493
- id: F(),
494
- name: r.name ?? r.title ?? r.id,
495
- delay: s,
496
- duration: t ? i * (n || 1) : 0,
497
- effectMode: f === "逐字" || f === "逐行" ? "sibling" : "parent",
498
- keyframes: M ?? [],
499
- easing: Y.easing[c],
516
+ id: idGenerator(),
517
+ name: animation.name ?? animation.title ?? animation.id,
518
+ delay,
519
+ duration: name ? duration * (iterations || 1) : 0,
520
+ effectMode: mode === "逐字" || mode === "逐行" ? "sibling" : "parent",
521
+ keyframes: keyframes ?? [],
522
+ easing: animations.easing[easing],
500
523
  meta: {
501
- ...a,
524
+ ...meta,
502
525
  inCanvasIs: "Animation",
503
526
  inPptIs: "Animation",
504
527
  inEditorIs: "Node"
505
528
  }
506
529
  };
507
530
  }
508
- function jt(e) {
509
- if (!e.animations?.length)
531
+ function parseAnimations(el) {
532
+ if (!el.animations?.length) {
510
533
  return {
511
534
  delay: 0,
512
535
  duration: 0,
513
536
  animations: []
514
537
  };
515
- let r, o, t;
516
- e.animations[0].in ? (r = e.animations[0].in, o = e.animations[0].stay, t = e.animations[0].out) : (r = e.animations?.find((f) => f.category === "in"), o = e.animations?.find((f) => f.category === "stay"), t = e.animations?.find((f) => f.category === "out"));
517
- const s = r?.delay ?? 0, i = t ? t.delay - s + t.duration : 0, n = [];
518
- return r && n.push(
519
- U(e, {
520
- ...r,
521
- delay: 0
522
- }, "in")
523
- ), o && n.push(
524
- U(e, {
525
- ...o,
526
- delay: o.delay - s
527
- }, "stay")
528
- ), t && n.push(
529
- U(e, {
530
- ...t,
531
- delay: t.delay - s
532
- }, "out")
533
- ), {
534
- delay: s,
535
- duration: i - s,
536
- animations: n.filter((f) => !!f?.keyframes)
538
+ }
539
+ let _animIn;
540
+ let _animStay;
541
+ let _animOut;
542
+ if (el.animations[0].in) {
543
+ _animIn = el.animations[0].in;
544
+ _animStay = el.animations[0].stay;
545
+ _animOut = el.animations[0].out;
546
+ } else {
547
+ _animIn = el.animations?.find((v) => v.category === "in");
548
+ _animStay = el.animations?.find((v) => v.category === "stay");
549
+ _animOut = el.animations?.find((v) => v.category === "out");
550
+ }
551
+ const startTime = _animIn?.delay ?? 0;
552
+ const endTime = _animOut ? _animOut.delay - startTime + _animOut.duration : 0;
553
+ const animations2 = [];
554
+ if (_animIn) {
555
+ animations2.push(
556
+ convertAnimation(el, {
557
+ ..._animIn,
558
+ delay: 0
559
+ }, "in")
560
+ );
561
+ }
562
+ if (_animStay) {
563
+ animations2.push(
564
+ convertAnimation(el, {
565
+ ..._animStay,
566
+ delay: _animStay.delay - startTime
567
+ }, "stay")
568
+ );
569
+ }
570
+ if (_animOut) {
571
+ animations2.push(
572
+ convertAnimation(el, {
573
+ ..._animOut,
574
+ delay: _animOut.delay - startTime
575
+ }, "out")
576
+ );
577
+ }
578
+ return {
579
+ delay: startTime,
580
+ duration: endTime - startTime,
581
+ animations: animations2.filter((v) => !!v?.keyframes)
537
582
  };
538
583
  }
539
- async function V(e) {
584
+ async function convertImageElementToUrl(el) {
585
+ const {
586
+ transform = {},
587
+ style = {},
588
+ maskUrl,
589
+ imageEffects = [],
590
+ imageEffectsRatio = 1
591
+ } = el;
592
+ const url = el.clipUrl || el.url;
593
+ const {
594
+ translateX = 0,
595
+ translateY = 0,
596
+ zoom = 1
597
+ } = transform ?? {};
598
+ const {
599
+ scaleX = 1,
600
+ scaleY = 1,
601
+ filter
602
+ } = style;
603
+ if (translateX === 0 && translateY === 0 && zoom === 1 && scaleX === 1 && scaleY === 1 && !maskUrl && !filter && !imageEffects.length) {
604
+ return url;
605
+ }
606
+ const img = await assets.fetchImageBitmap(url);
607
+ const {
608
+ originWidth = img.width,
609
+ originHeight = img.height,
610
+ imageWidth = originWidth,
611
+ imageHeight = originHeight
612
+ } = transform;
540
613
  const {
541
- transform: r = {},
542
- style: o = {},
543
- maskUrl: t,
544
- imageEffects: s = [],
545
- imageEffectsRatio: i = 1
546
- } = e, n = e.clipUrl || e.url, {
547
- translateX: f = 0,
548
- translateY: c = 0,
549
- zoom: d = 1
550
- } = r ?? {}, {
551
- scaleX: l = 1,
552
- scaleY: a = 1,
553
- filter: M
554
- } = o;
555
- if (f === 0 && c === 0 && d === 1 && l === 1 && a === 1 && !t && !M && !s.length)
556
- return n;
557
- const L = await B.fetchImageBitmap(n), {
558
- originWidth: w = L.width,
559
- originHeight: h = L.height,
560
- imageWidth: u = w,
561
- imageHeight: C = h
562
- } = r, {
563
- width: m = w,
564
- height: g = h
565
- } = o, T = window.devicePixelRatio || 1, [j, y] = W(m, g, T);
566
- if (M && (y.filter = M), y.scale(l, a), y.translate(l < 0 ? -m : 0, a < 0 ? -g : 0), t) {
567
- const D = await B.fetchImageBitmap(t);
568
- y.drawImage(D, 0, 0, D.width, D.height, 0, 0, m, g), D.close(), y.globalCompositeOperation = "source-in";
614
+ width = originWidth,
615
+ height = originHeight
616
+ } = style;
617
+ const dpr = window.devicePixelRatio || 1;
618
+ const [canvas, ctx] = createCanvas(width, height, dpr);
619
+ if (filter)
620
+ ctx.filter = filter;
621
+ ctx.scale(scaleX, scaleY);
622
+ ctx.translate(scaleX < 0 ? -width : 0, scaleY < 0 ? -height : 0);
623
+ if (maskUrl) {
624
+ const mask = await assets.fetchImageBitmap(maskUrl);
625
+ ctx.drawImage(mask, 0, 0, mask.width, mask.height, 0, 0, width, height);
626
+ mask.close();
627
+ ctx.globalCompositeOperation = "source-in";
569
628
  }
570
- const A = u * d, k = C * d, tt = -(A / 2 - u / 2) + f, et = -(k / 2 - C / 2) + c;
571
- if (y.drawImage(L, 0, 0, L.width, L.height, tt, et, A, k), L.close(), y.globalCompositeOperation = "source-over", s.length > 0) {
572
- const S = {
573
- x: (m - m * 0.9) / 2,
574
- y: (g - g * 0.9) / 2
575
- }, v = await createImageBitmap(j);
576
- y.clearRect(0, 0, j.width, j.height), y.scale(0.9, 0.9);
577
- for (let G = s.length - 1; G >= 0; G--) {
578
- const { filling: b, offset: R, stroke: at } = s[G];
579
- let z = v;
580
- if (b) {
581
- const [I, x] = W(m, g, T);
582
- if (x.drawImage(z, 0, 0, m, g), x.globalCompositeOperation = "source-in", b.color) {
583
- const [p, N] = W(m, g, T);
584
- N.fillStyle = b.color, N.fillRect(0, 0, m, g), x.drawImage(p, 0, 0, m, g);
585
- } else if (b.imageContent?.image) {
586
- const p = await B.fetchImageBitmap(b.imageContent.image);
587
- x.drawImage(p, 0, 0, m, g), p.close();
629
+ const dw = imageWidth * zoom;
630
+ const dh = imageHeight * zoom;
631
+ const dx = -(dw / 2 - imageWidth / 2) + translateX;
632
+ const dy = -(dh / 2 - imageHeight / 2) + translateY;
633
+ ctx.drawImage(img, 0, 0, img.width, img.height, dx, dy, dw, dh);
634
+ img.close();
635
+ ctx.globalCompositeOperation = "source-over";
636
+ if (imageEffects.length > 0) {
637
+ const scale = 0.9;
638
+ const center = {
639
+ x: (width - width * scale) / 2,
640
+ y: (height - height * scale) / 2
641
+ };
642
+ const canvasBitmap = await createImageBitmap(canvas);
643
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
644
+ ctx.scale(scale, scale);
645
+ for (let i = imageEffects.length - 1; i >= 0; i--) {
646
+ const { filling, offset, stroke } = imageEffects[i];
647
+ let effectCanvas = canvasBitmap;
648
+ if (filling) {
649
+ const [canvas1, ctx1] = createCanvas(width, height, dpr);
650
+ ctx1.drawImage(effectCanvas, 0, 0, width, height);
651
+ ctx1.globalCompositeOperation = "source-in";
652
+ if (filling.color) {
653
+ const [canvas2, ctx2] = createCanvas(width, height, dpr);
654
+ ctx2.fillStyle = filling.color;
655
+ ctx2.fillRect(0, 0, width, height);
656
+ ctx1.drawImage(canvas2, 0, 0, width, height);
657
+ } else if (filling.imageContent?.image) {
658
+ const img2 = await assets.fetchImageBitmap(filling.imageContent.image);
659
+ ctx1.drawImage(img2, 0, 0, width, height);
660
+ img2.close();
588
661
  }
589
- z = I;
662
+ effectCanvas = canvas1;
590
663
  }
591
- if (at?.forEach(({ width: I, color: x }) => {
592
- z = new ht().use((p, N, O) => {
593
- const [, J] = W(N.width, N.height);
594
- J.drawImage(N, 0, 0);
595
- const st = Ct(J), $ = O.thickness, H = O.thickness;
596
- p.strokeStyle = O.color, p.lineWidth = O.thickness * 2, p.lineJoin = "round", st.forEach((E) => {
597
- p.beginPath(), p.moveTo($ + E[0].x, H + E[1].y);
598
- for (let Q = 1; Q < E.length; Q++)
599
- p.lineTo($ + E[Q].x, H + E[Q].y);
600
- p.closePath();
601
- }), p.stroke();
602
- }).make(z, {
603
- color: x,
604
- thickness: I / 50 * i
664
+ stroke?.forEach(({ width: width2, color }) => {
665
+ effectCanvas = new ImageStroke().use((ctx2, image, options) => {
666
+ const [, ctx1] = createCanvas(image.width, image.height);
667
+ ctx1.drawImage(image, 0, 0);
668
+ const paths = getContours(ctx1);
669
+ const x = options.thickness;
670
+ const y = options.thickness;
671
+ ctx2.strokeStyle = options.color;
672
+ ctx2.lineWidth = options.thickness * 2;
673
+ ctx2.lineJoin = "round";
674
+ paths.forEach((path) => {
675
+ ctx2.beginPath();
676
+ ctx2.moveTo(x + path[0].x, y + path[1].y);
677
+ for (let i2 = 1; i2 < path.length; i2++) {
678
+ ctx2.lineTo(x + path[i2].x, y + path[i2].y);
679
+ }
680
+ ctx2.closePath();
681
+ });
682
+ ctx2.stroke();
683
+ }).make(effectCanvas, {
684
+ color,
685
+ thickness: width2 / 50 * imageEffectsRatio
605
686
  });
606
- }), R) {
607
- let { x: I, y: x } = R;
608
- I = I / 50 * i * 200, x = x / 50 * i * 200, y.drawImage(z, I + S.x, x + S.y, m, g);
609
- } else
610
- y.drawImage(z, S.x, S.y, m, g);
687
+ });
688
+ if (offset) {
689
+ let { x, y } = offset;
690
+ x = x / 50 * imageEffectsRatio * 200;
691
+ y = y / 50 * imageEffectsRatio * 200;
692
+ ctx.drawImage(effectCanvas, x + center.x, y + center.y, width, height);
693
+ } else {
694
+ ctx.drawImage(effectCanvas, center.x, center.y, width, height);
695
+ }
611
696
  }
612
- v.close();
697
+ canvasBitmap.close();
613
698
  }
614
- return await new Promise((D) => {
615
- j.toBlob((S) => {
699
+ return await new Promise((resolve) => {
700
+ canvas.toBlob((blob) => {
616
701
  try {
617
- D(URL.createObjectURL(S));
618
- } catch (v) {
619
- console.error(`Failed to URL.createObjectURL, url: ${n}`, v), D(n);
702
+ resolve(URL.createObjectURL(blob));
703
+ } catch (e) {
704
+ console.error(`Failed to URL.createObjectURL, url: ${url}`, e);
705
+ resolve(url);
620
706
  }
621
707
  });
622
708
  });
623
709
  }
624
- function W(e, r, o = 1) {
625
- const t = document.createElement("canvas");
626
- t.width = e * o, t.height = r * o, t.style.width = `${e}px`, t.style.height = `${r}px`;
627
- const s = t.getContext("2d");
628
- return s.scale(o, o), [t, s];
710
+ function createCanvas(width, height, ratio = 1) {
711
+ const canvas = document.createElement("canvas");
712
+ canvas.width = width * ratio;
713
+ canvas.height = height * ratio;
714
+ canvas.style.width = `${width}px`;
715
+ canvas.style.height = `${height}px`;
716
+ const ctx = canvas.getContext("2d");
717
+ ctx.scale(ratio, ratio);
718
+ return [canvas, ctx];
629
719
  }
630
- class ht {
720
+ class ImageStroke {
631
721
  canvas = document.createElement("canvas");
632
722
  method;
633
- use(r) {
634
- return this.method = r, this;
723
+ use(method) {
724
+ this.method = method;
725
+ return this;
635
726
  }
636
- make(r, o) {
637
- const { canvas: t } = this, s = this.canvas.getContext("2d"), i = o.thickness * 2, [n, f] = [r.width, r.height].map((c) => c + i);
638
- return (n !== t.width || f !== t.height) && (t.width = n, t.height = f), s.clearRect(0, 0, s.canvas.width, s.canvas.height), this.method(s, r, o), s.drawImage(r, o.thickness, o.thickness), t;
727
+ make(image, options) {
728
+ const { canvas } = this;
729
+ const ctx = this.canvas.getContext("2d");
730
+ const strokeSize = options.thickness * 2;
731
+ const [resultWidth, resultHeight] = [image.width, image.height].map((val) => val + strokeSize);
732
+ if (resultWidth !== canvas.width || resultHeight !== canvas.height) {
733
+ canvas.width = resultWidth;
734
+ canvas.height = resultHeight;
735
+ }
736
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
737
+ this.method(ctx, image, options);
738
+ ctx.drawImage(image, options.thickness, options.thickness);
739
+ return canvas;
639
740
  }
640
741
  }
641
- function Ct(e) {
642
- const t = e.canvas.width, s = e.canvas.height, i = [];
643
- let n = 3;
644
- const f = 100;
645
- return (() => {
646
- const d = [], l = new Uint32Array(e.getImageData(0, 0, t, s).data.buffer);
647
- let a, M, L, w, h = -1, u, C = 9;
648
- const m = [9, 0, 3, 3, 2, 0, 9, 3, 1, 9, 1, 1, 2, 0, 2, 9];
649
- function g(j, y) {
650
- return j >= 0 && y >= 0 && j < t && y < s ? l[y * t + j] >>> 24 > f : !1;
742
+ function getContours(ctx) {
743
+ const cx = 0;
744
+ const cy = 0;
745
+ const canvasWidth = ctx.canvas.width;
746
+ const canvasHeight = ctx.canvas.height;
747
+ const paths = [];
748
+ let lastPos = 3;
749
+ const alpha = 100;
750
+ const trace = () => {
751
+ const path = [];
752
+ const data = new Uint32Array(ctx.getImageData(cx, cy, canvasWidth, canvasHeight).data.buffer);
753
+ let x;
754
+ let y;
755
+ let startX;
756
+ let startY;
757
+ let startPos = -1;
758
+ let step;
759
+ let prevStep = 9;
760
+ const steps = [9, 0, 3, 3, 2, 0, 9, 3, 1, 9, 1, 1, 2, 0, 2, 9];
761
+ function getState(x2, y2) {
762
+ return x2 >= 0 && y2 >= 0 && x2 < canvasWidth && y2 < canvasHeight ? data[y2 * canvasWidth + x2] >>> 24 > alpha : false;
651
763
  }
652
- function T(j, y) {
653
- let A = 0;
654
- return g(j - 1, y - 1) && (A += 1), g(j, y - 1) && (A += 2), g(j - 1, y) && (A += 4), g(j, y) && (A += 8), A === 6 ? C === 0 ? 2 : 3 : A === 9 ? C === 3 ? 0 : 1 : m[A];
764
+ function getNextStep(x2, y2) {
765
+ let v = 0;
766
+ if (getState(x2 - 1, y2 - 1)) {
767
+ v += 1;
768
+ }
769
+ if (getState(x2, y2 - 1)) {
770
+ v += 2;
771
+ }
772
+ if (getState(x2 - 1, y2)) {
773
+ v += 4;
774
+ }
775
+ if (getState(x2, y2)) {
776
+ v += 8;
777
+ }
778
+ if (v === 6)
779
+ return prevStep === 0 ? 2 : 3;
780
+ else if (v === 9)
781
+ return prevStep === 3 ? 0 : 1;
782
+ else
783
+ return steps[v];
655
784
  }
656
- for (let j = n; j < l.length; j++)
657
- if (l[j] >>> 24 > f) {
658
- h = n = j;
785
+ for (let i = lastPos; i < data.length; i++) {
786
+ if (data[i] >>> 24 > alpha) {
787
+ startPos = lastPos = i;
659
788
  break;
660
789
  }
661
- if (h >= 0) {
662
- a = L = h % t, M = w = Math.floor(h / t);
663
- do
664
- u = T(a, M), u === 0 ? M-- : u === 1 ? M++ : u === 2 ? a-- : u === 3 && a++, u !== C && (d.push({ x: a + 0, y: M + 0 }), C = u);
665
- while (a !== L || M !== w);
666
790
  }
667
- return i.push(d), d;
668
- })(), i;
791
+ if (startPos >= 0) {
792
+ x = startX = startPos % canvasWidth;
793
+ y = startY = Math.floor(startPos / canvasWidth);
794
+ do {
795
+ step = getNextStep(x, y);
796
+ if (step === 0)
797
+ y--;
798
+ else if (step === 1)
799
+ y++;
800
+ else if (step === 2)
801
+ x--;
802
+ else if (step === 3)
803
+ x++;
804
+ if (step !== prevStep) {
805
+ path.push({ x: x + cx, y: y + cy });
806
+ prevStep = step;
807
+ }
808
+ } while (x !== startX || y !== startY);
809
+ }
810
+ paths.push(path);
811
+ return path;
812
+ };
813
+ trace();
814
+ return paths;
669
815
  }
670
- async function pt(e) {
816
+ async function convertSvgElementToUrl(el) {
671
817
  const {
672
- id: r,
673
- doc: o,
674
- url: t,
675
- style: s = {},
676
- background: i = {}
677
- } = e;
678
- let n = o;
679
- n || (n = await fetch(t).then((c) => c.text()));
680
- const f = new DOMParser().parseFromString(
681
- n.replace(new RegExp(`#el-${r} `, "gi"), "").replace(/data-colors\s/, " ").replace(/[a-z-]+="([^\s<]*<\S*)"/gi, ""),
818
+ id,
819
+ doc,
820
+ url,
821
+ style = {},
822
+ background = {}
823
+ } = el;
824
+ let xml = doc;
825
+ if (!xml) {
826
+ xml = await fetch(url).then((rep) => rep.text());
827
+ }
828
+ const svg = new DOMParser().parseFromString(
829
+ xml.replace(new RegExp(`#el-${id} `, "gi"), "").replace(/data-colors\s/, " ").replace(/[a-z-]+="([^\s<]*<\S*)"/gi, ""),
682
830
  "image/svg+xml"
683
831
  ).documentElement;
684
- if (!(f instanceof SVGElement))
685
- throw new TypeError(`Failed to DOMParser, parse svg to DOM error: ${n}`);
686
- if (i.src) {
687
- const c = `#${r}-fill-blip`, d = f.querySelector(c), l = d?.querySelector("image");
688
- if (d && l)
832
+ if (!(svg instanceof SVGElement)) {
833
+ throw new TypeError(`Failed to DOMParser, parse svg to DOM error: ${xml}`);
834
+ }
835
+ if (background.src) {
836
+ const fillId = `#${id}-fill-blip`;
837
+ const fillPattern = svg.querySelector(fillId);
838
+ const fillImage = fillPattern?.querySelector("image");
839
+ if (fillPattern && fillImage) {
689
840
  try {
690
- const a = await B.fetchImageBitmap(i.src).then((M) => {
691
- const L = document.createElement("canvas");
692
- return L.width = M.width, L.height = M.height, L.getContext("2d")?.drawImage(M, 0, 0), M.close(), L.toDataURL("image/png");
841
+ const base64Url = await assets.fetchImageBitmap(background.src).then((bitmap) => {
842
+ const canvas = document.createElement("canvas");
843
+ canvas.width = bitmap.width;
844
+ canvas.height = bitmap.height;
845
+ canvas.getContext("2d")?.drawImage(bitmap, 0, 0);
846
+ bitmap.close();
847
+ return canvas.toDataURL("image/png");
693
848
  });
694
- l?.setAttribute("href", a), d?.setAttribute("fill", c);
695
- } catch (a) {
696
- console.error(a);
849
+ fillImage?.setAttribute("href", base64Url);
850
+ fillPattern?.setAttribute("fill", fillId);
851
+ } catch (e) {
852
+ console.error(e);
697
853
  }
854
+ }
698
855
  }
699
- return s.width && f.setAttribute("width", String(s.width * 2)), s.height && f.setAttribute("height", String(s.height * 2)), await V({
700
- ...e,
856
+ if (style.width)
857
+ svg.setAttribute("width", String(style.width * 2));
858
+ if (style.height)
859
+ svg.setAttribute("height", String(style.height * 2));
860
+ return await convertImageElementToUrl({
861
+ ...el,
701
862
  transform: {
702
- ...e.transform,
703
- originWidth: s.width,
704
- originHeight: s.height
863
+ ...el.transform,
864
+ originWidth: style.width,
865
+ originHeight: style.height
705
866
  },
706
- url: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(f.outerHTML)}`
867
+ url: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg.outerHTML)}`
707
868
  });
708
869
  }
709
- const At = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNzIgNzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDcyIDcyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTE5LjMsMzguMWMwLjIsMC41LDAuNCwwLjksMC43LDEuNGMwLjIsMC4zLDAuNCwwLjQsMC44LDAuNGMwLjMsMCwwLjUtMC4xLDAuNi0wLjRjMC4xLTAuMywwLjEtMC42LDAuMi0wLjkgICBjMC0wLjIsMC4xLTAuNCwwLjMtMC41YzAuMi0wLjEsMC40LTAuMiwwLjYtMC4xYzAuMiwwLDAuNCwwLjEsMC41LDAuM2MwLjEsMC4yLDAuMiwwLjQsMC4xLDAuNmMtMC4xLDAuNi0wLjIsMS4yLTAuNCwxLjcgICBjLTAuMywwLjgtMC45LDEuMi0xLjcsMS4yYy0wLjksMC0xLjYtMC40LTIuMS0xLjJjLTAuMy0wLjQtMC41LTAuOC0wLjctMS4zYy0wLjQsMC4zLTEsMC42LTEuNywxYy0wLjUsMC4yLTAuOCwwLjEtMS4xLTAuMyAgIGMtMC4yLTAuNS0wLjEtMC45LDAuMy0xLjFjMC43LTAuNCwxLjQtMC44LDEuOS0xLjFjLTAuMi0wLjktMC40LTIuMS0wLjUtMy43TDE1LjksMzRjLTAuMiwwLTAuNCwwLTAuNi0wLjEgICBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4yLDAtMC40LDAuMi0wLjZzMC4zLTAuMywwLjUtMC4zbDEuMi0wLjFjLTAuMS0wLjktMC4xLTEuOS0wLjEtMi45YzAtMC4yLDAuMS0wLjQsMC4yLTAuNiAgIGMwLjItMC4xLDAuMy0wLjIsMC42LTAuMmMwLjIsMCwwLjQsMC4xLDAuNiwwLjJjMC4yLDAuMSwwLjIsMC4zLDAuMywwLjZjMCwwLjEsMCwxLDAuMSwyLjdsMy4yLTAuNGMwLjIsMCwwLjQsMCwwLjUsMC4xICAgYzAuMiwwLjEsMC4zLDAuMywwLjMsMC41czAsMC40LTAuMSwwLjVjLTAuMSwwLjItMC4zLDAuMy0wLjUsMC4zbC0zLjMsMC40YzAuMSwxLjIsMC4yLDIuMSwwLjMsMi44YzAuNy0wLjYsMS40LTEuNCwyLTIuMiAgIGMwLjMtMC40LDAuNy0wLjQsMS4xLTAuMmMwLjQsMC4zLDAuNCwwLjcsMC4yLDFDMjEuMywzNi4zLDIwLjQsMzcuMywxOS4zLDM4LjF6IE0yMC42LDMxLjFjLTAuMy0wLjItMC43LTAuNS0xLjEtMC44ICAgYy0wLjMtMC4zLTAuMy0wLjYtMC4xLTAuOWMwLjMtMC4zLDAuNi0wLjQsMS0wLjJjMC40LDAuMiwwLjcsMC41LDEuMSwwLjdjMC40LDAuMywwLjQsMC42LDAuMiwxQzIxLjMsMzEuMywyMSwzMS4zLDIwLjYsMzEuMXogICAgTTIzLjMsMzAuOWMwLTAuMiwwLjEtMC40LDAuMi0wLjVjMC4xLTAuMSwwLjMtMC4yLDAuNi0wLjJzMC40LDAuMSwwLjYsMC4yYzAuMSwwLjEsMC4yLDAuMywwLjIsMC41djYuNWMwLDAuMi0wLjEsMC40LTAuMiwwLjUgICBjLTAuMSwwLjEtMC4zLDAuMi0wLjYsMC4ycy0wLjQtMC4xLTAuNi0wLjJjLTAuMS0wLjEtMC4yLTAuMy0wLjItMC41VjMwLjl6IE0yNC4zLDQxLjZjLTAuMiwwLTAuNC0wLjEtMC42LTAuMiAgIGMtMC4yLTAuMS0wLjItMC4zLTAuMi0wLjZjMC0wLjIsMC4xLTAuNCwwLjItMC42YzAuMi0wLjEsMC4zLTAuMiwwLjYtMC4yaDAuOWMwLjYsMCwxLTAuNCwxLTEuMXYtOS40YzAtMC4yLDAuMS0wLjQsMC4yLTAuNiAgIGMwLjItMC4xLDAuMy0wLjIsMC42LTAuMmMwLjIsMCwwLjQsMC4xLDAuNiwwLjJjMC4yLDAuMSwwLjIsMC4zLDAuMiwwLjZWMzljMCwwLjgtMC4yLDEuNS0wLjcsMS45cy0xLjEsMC43LTEuOCwwLjdIMjQuM3oiLz4KCTxwYXRoIGQ9Ik00MC42LDM3LjdoLTMuOHYwLjdoNC40YzAuMSwwLDAuMywwLjEsMC40LDAuMmMwLjEsMC4xLDAuMiwwLjIsMC4yLDAuNGMwLDAuMS0wLjEsMC4zLTAuMiwwLjRjLTAuMSwwLjEtMC4yLDAuMi0wLjQsMC4yICAgaC00LjR2MC43SDQyYzAuMiwwLDAuMywwLjEsMC40LDAuMmMwLjEsMC4xLDAuMiwwLjIsMC4yLDAuNHMtMC4xLDAuMy0wLjIsMC40Yy0wLjEsMC4xLTAuMiwwLjItMC40LDAuMkgzMGMtMC4yLDAtMC4zLTAuMS0wLjQtMC4yICAgYy0wLjEtMC4xLTAuMi0wLjItMC4yLTAuNHMwLjEtMC4zLDAuMi0wLjRjMC4xLTAuMSwwLjItMC4yLDAuNC0wLjJoNS4ydi0wLjdoLTQuNGMtMC4xLDAtMC4zLTAuMS0wLjQtMC4ycy0wLjItMC4yLTAuMi0wLjQgICBjMC0wLjEsMC4xLTAuMywwLjItMC40czAuMi0wLjIsMC40LTAuMmg0LjR2LTAuN2gtMy43aDBjLTAuMiwwLTAuNC0wLjEtMC42LTAuMnMtMC4yLTAuMy0wLjItMC42di0zLjFjMC0wLjIsMC4xLTAuNCwwLjItMC42ICAgYzAuMS0wLjEsMC4zLTAuMiwwLjYtMC4yaDMuOHYtMC44SDMwYy0wLjIsMC0wLjMtMC4xLTAuNC0wLjJjLTAuMS0wLjEtMC4yLTAuMi0wLjItMC40czAuMS0wLjMsMC4yLTAuNGMwLjEtMC4xLDAuMi0wLjIsMC40LTAuMiAgIGg1LjJ2LTAuOGMtMS40LDAtMi45LDAuMS00LjMsMC4xYy0wLjIsMC0wLjMsMC0wLjQtMC4xYy0wLjEtMC4xLTAuMi0wLjItMC4yLTAuNGMwLTAuMiwwLTAuMywwLjItMC40YzAuMS0wLjEsMC4zLTAuMiwwLjQtMC4yICAgYzMuMywwLDYuOC0wLjEsMTAuMi0wLjNjMC4yLDAsMC4zLDAsMC40LDAuMmMwLjEsMC4xLDAuMiwwLjMsMC4yLDAuNGMwLDAuMiwwLDAuMy0wLjEsMC40Yy0wLjEsMC4xLTAuMiwwLjItMC40LDAuMiAgIGMtMS4xLDAtMi41LDAuMS00LjMsMC4xdjAuOGg1LjFjMC4yLDAsMC4zLDAuMSwwLjQsMC4yYzAuMSwwLjEsMC4yLDAuMiwwLjIsMC40cy0wLjEsMC4zLTAuMiwwLjRjLTAuMSwwLjEtMC4yLDAuMi0wLjQsMC4yaC01LjEgICB2MC44aDMuOGMwLjIsMCwwLjQsMC4xLDAuNiwwLjJjMC4xLDAuMSwwLjIsMC4zLDAuMiwwLjZ2My4xYzAsMC4yLTAuMSwwLjQtMC4yLDAuNkM0MSwzNy43LDQwLjgsMzcuNyw0MC42LDM3Ljd6IE0zNS4xLDM0LjlWMzQgICBoLTIuOXYwLjlIMzUuMXogTTM1LjEsMzYuN3YtMC45aC0yLjl2MC45SDM1LjF6IE0zOS44LDM0LjlWMzRoLTIuOXYwLjlIMzkuOHogTTM5LjgsMzYuN3YtMC45aC0yLjl2MC45SDM5Ljh6Ii8+Cgk8cGF0aCBkPSJNNDUuNSw0MS4xYy0wLjMsMC40LTAuNywwLjUtMS4xLDAuM2MtMC40LTAuMy0wLjUtMC43LTAuMy0xLjFsMS0xLjdjMC4zLTAuNCwwLjctMC41LDEuMS0wLjNjMC40LDAuMywwLjUsMC43LDAuMywxLjEgICBMNDUuNSw0MS4xeiBNNTUsMzcuN2MtMC4xLDAtMC4xLDAtMC4yLDBoLTguOWMtMC4zLDAtMC41LTAuMS0wLjYtMC4yYy0wLjItMC4yLTAuMi0wLjQtMC4yLTAuNnYtMy40YzAtMC4yLDAuMS0wLjQsMC4yLTAuNiAgIGMwLjEtMC4xLDAuMy0wLjIsMC42LTAuMmgzLjN2LTMuMWMwLTAuMiwwLjEtMC40LDAuMi0wLjZjMC4yLTAuMiwwLjQtMC4yLDAuNi0wLjJzMC40LDAuMSwwLjYsMC4yYzAuMiwwLjIsMC4yLDAuNCwwLjIsMC42djAuM0g1NiAgIGMwLjIsMCwwLjQsMC4xLDAuNiwwLjJjMC4xLDAuMSwwLjIsMC4zLDAuMiwwLjZzLTAuMSwwLjQtMC4yLDAuNWMtMC4xLDAuMS0wLjMsMC4yLTAuNiwwLjJoLTUuMnYxLjNoNGMwLjIsMCwwLjQsMC4xLDAuNiwwLjIgICBjMC4xLDAuMSwwLjIsMC4zLDAuMiwwLjZ2My40QzU1LjYsMzcuMyw1NS40LDM3LjYsNTUsMzcuN3ogTTUzLjksMzYuMnYtMmgtNy4xdjJINTMuOXogTTQ5LjYsNDAuN2MwLDAuMy0wLjEsMC41LTAuMiwwLjYgICBjLTAuMiwwLjEtMC40LDAuMi0wLjYsMC4yYy0wLjIsMC0wLjQtMC4xLTAuNi0wLjJjLTAuMS0wLjItMC4yLTAuNC0wLjItMC42bDAtMS42YzAtMC4yLDAuMS0wLjQsMC4yLTAuNmMwLjItMC4yLDAuMy0wLjIsMC42LTAuMiAgIHMwLjQsMC4xLDAuNiwwLjJjMC4yLDAuMiwwLjIsMC40LDAuMiwwLjZWNDAuN3ogTTUyLjgsNDAuN2MwLDAuMi0wLjEsMC40LTAuMiwwLjZjLTAuMiwwLjEtMC40LDAuMi0wLjYsMC4yICAgYy0wLjIsMC0wLjQtMC4xLTAuNi0wLjJjLTAuMi0wLjEtMC4yLTAuMy0wLjItMC42bDAtMS42YzAtMC4yLDAuMS0wLjQsMC4yLTAuNmMwLjItMC4yLDAuMy0wLjIsMC42LTAuMmMwLjIsMCwwLjQsMC4xLDAuNiwwLjIgICBjMC4yLDAuMiwwLjIsMC40LDAuMiwwLjZWNDAuN3ogTTU2LjYsNDAuM2MwLjIsMC40LDAuMSwwLjgtMC4zLDEuMWMtMC41LDAuMy0wLjgsMC4yLTEuMS0wLjNsLTEtMS43Yy0wLjItMC41LTAuMS0wLjgsMC4zLTEuMSAgIGMwLjUtMC4yLDAuOS0wLjEsMS4xLDAuM0w1Ni42LDQwLjN6Ii8+CjwvZz4KPC9zdmc+";
710
- async function xt(e, r = !1) {
711
- const { fetchToText: o } = _(), t = {
712
- ...e.style,
713
- highlightReferImage: At,
870
+ const highlightReferImage = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNzIgNzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDcyIDcyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTE5LjMsMzguMWMwLjIsMC41LDAuNCwwLjksMC43LDEuNGMwLjIsMC4zLDAuNCwwLjQsMC44LDAuNGMwLjMsMCwwLjUtMC4xLDAuNi0wLjRjMC4xLTAuMywwLjEtMC42LDAuMi0wLjkgICBjMC0wLjIsMC4xLTAuNCwwLjMtMC41YzAuMi0wLjEsMC40LTAuMiwwLjYtMC4xYzAuMiwwLDAuNCwwLjEsMC41LDAuM2MwLjEsMC4yLDAuMiwwLjQsMC4xLDAuNmMtMC4xLDAuNi0wLjIsMS4yLTAuNCwxLjcgICBjLTAuMywwLjgtMC45LDEuMi0xLjcsMS4yYy0wLjksMC0xLjYtMC40LTIuMS0xLjJjLTAuMy0wLjQtMC41LTAuOC0wLjctMS4zYy0wLjQsMC4zLTEsMC42LTEuNywxYy0wLjUsMC4yLTAuOCwwLjEtMS4xLTAuMyAgIGMtMC4yLTAuNS0wLjEtMC45LDAuMy0xLjFjMC43LTAuNCwxLjQtMC44LDEuOS0xLjFjLTAuMi0wLjktMC40LTIuMS0wLjUtMy43TDE1LjksMzRjLTAuMiwwLTAuNCwwLTAuNi0wLjEgICBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4yLDAtMC40LDAuMi0wLjZzMC4zLTAuMywwLjUtMC4zbDEuMi0wLjFjLTAuMS0wLjktMC4xLTEuOS0wLjEtMi45YzAtMC4yLDAuMS0wLjQsMC4yLTAuNiAgIGMwLjItMC4xLDAuMy0wLjIsMC42LTAuMmMwLjIsMCwwLjQsMC4xLDAuNiwwLjJjMC4yLDAuMSwwLjIsMC4zLDAuMywwLjZjMCwwLjEsMCwxLDAuMSwyLjdsMy4yLTAuNGMwLjIsMCwwLjQsMCwwLjUsMC4xICAgYzAuMiwwLjEsMC4zLDAuMywwLjMsMC41czAsMC40LTAuMSwwLjVjLTAuMSwwLjItMC4zLDAuMy0wLjUsMC4zbC0zLjMsMC40YzAuMSwxLjIsMC4yLDIuMSwwLjMsMi44YzAuNy0wLjYsMS40LTEuNCwyLTIuMiAgIGMwLjMtMC40LDAuNy0wLjQsMS4xLTAuMmMwLjQsMC4zLDAuNCwwLjcsMC4yLDFDMjEuMywzNi4zLDIwLjQsMzcuMywxOS4zLDM4LjF6IE0yMC42LDMxLjFjLTAuMy0wLjItMC43LTAuNS0xLjEtMC44ICAgYy0wLjMtMC4zLTAuMy0wLjYtMC4xLTAuOWMwLjMtMC4zLDAuNi0wLjQsMS0wLjJjMC40LDAuMiwwLjcsMC41LDEuMSwwLjdjMC40LDAuMywwLjQsMC42LDAuMiwxQzIxLjMsMzEuMywyMSwzMS4zLDIwLjYsMzEuMXogICAgTTIzLjMsMzAuOWMwLTAuMiwwLjEtMC40LDAuMi0wLjVjMC4xLTAuMSwwLjMtMC4yLDAuNi0wLjJzMC40LDAuMSwwLjYsMC4yYzAuMSwwLjEsMC4yLDAuMywwLjIsMC41djYuNWMwLDAuMi0wLjEsMC40LTAuMiwwLjUgICBjLTAuMSwwLjEtMC4zLDAuMi0wLjYsMC4ycy0wLjQtMC4xLTAuNi0wLjJjLTAuMS0wLjEtMC4yLTAuMy0wLjItMC41VjMwLjl6IE0yNC4zLDQxLjZjLTAuMiwwLTAuNC0wLjEtMC42LTAuMiAgIGMtMC4yLTAuMS0wLjItMC4zLTAuMi0wLjZjMC0wLjIsMC4xLTAuNCwwLjItMC42YzAuMi0wLjEsMC4zLTAuMiwwLjYtMC4yaDAuOWMwLjYsMCwxLTAuNCwxLTEuMXYtOS40YzAtMC4yLDAuMS0wLjQsMC4yLTAuNiAgIGMwLjItMC4xLDAuMy0wLjIsMC42LTAuMmMwLjIsMCwwLjQsMC4xLDAuNiwwLjJjMC4yLDAuMSwwLjIsMC4zLDAuMiwwLjZWMzljMCwwLjgtMC4yLDEuNS0wLjcsMS45cy0xLjEsMC43LTEuOCwwLjdIMjQuM3oiLz4KCTxwYXRoIGQ9Ik00MC42LDM3LjdoLTMuOHYwLjdoNC40YzAuMSwwLDAuMywwLjEsMC40LDAuMmMwLjEsMC4xLDAuMiwwLjIsMC4yLDAuNGMwLDAuMS0wLjEsMC4zLTAuMiwwLjRjLTAuMSwwLjEtMC4yLDAuMi0wLjQsMC4yICAgaC00LjR2MC43SDQyYzAuMiwwLDAuMywwLjEsMC40LDAuMmMwLjEsMC4xLDAuMiwwLjIsMC4yLDAuNHMtMC4xLDAuMy0wLjIsMC40Yy0wLjEsMC4xLTAuMiwwLjItMC40LDAuMkgzMGMtMC4yLDAtMC4zLTAuMS0wLjQtMC4yICAgYy0wLjEtMC4xLTAuMi0wLjItMC4yLTAuNHMwLjEtMC4zLDAuMi0wLjRjMC4xLTAuMSwwLjItMC4yLDAuNC0wLjJoNS4ydi0wLjdoLTQuNGMtMC4xLDAtMC4zLTAuMS0wLjQtMC4ycy0wLjItMC4yLTAuMi0wLjQgICBjMC0wLjEsMC4xLTAuMywwLjItMC40czAuMi0wLjIsMC40LTAuMmg0LjR2LTAuN2gtMy43aDBjLTAuMiwwLTAuNC0wLjEtMC42LTAuMnMtMC4yLTAuMy0wLjItMC42di0zLjFjMC0wLjIsMC4xLTAuNCwwLjItMC42ICAgYzAuMS0wLjEsMC4zLTAuMiwwLjYtMC4yaDMuOHYtMC44SDMwYy0wLjIsMC0wLjMtMC4xLTAuNC0wLjJjLTAuMS0wLjEtMC4yLTAuMi0wLjItMC40czAuMS0wLjMsMC4yLTAuNGMwLjEtMC4xLDAuMi0wLjIsMC40LTAuMiAgIGg1LjJ2LTAuOGMtMS40LDAtMi45LDAuMS00LjMsMC4xYy0wLjIsMC0wLjMsMC0wLjQtMC4xYy0wLjEtMC4xLTAuMi0wLjItMC4yLTAuNGMwLTAuMiwwLTAuMywwLjItMC40YzAuMS0wLjEsMC4zLTAuMiwwLjQtMC4yICAgYzMuMywwLDYuOC0wLjEsMTAuMi0wLjNjMC4yLDAsMC4zLDAsMC40LDAuMmMwLjEsMC4xLDAuMiwwLjMsMC4yLDAuNGMwLDAuMiwwLDAuMy0wLjEsMC40Yy0wLjEsMC4xLTAuMiwwLjItMC40LDAuMiAgIGMtMS4xLDAtMi41LDAuMS00LjMsMC4xdjAuOGg1LjFjMC4yLDAsMC4zLDAuMSwwLjQsMC4yYzAuMSwwLjEsMC4yLDAuMiwwLjIsMC40cy0wLjEsMC4zLTAuMiwwLjRjLTAuMSwwLjEtMC4yLDAuMi0wLjQsMC4yaC01LjEgICB2MC44aDMuOGMwLjIsMCwwLjQsMC4xLDAuNiwwLjJjMC4xLDAuMSwwLjIsMC4zLDAuMiwwLjZ2My4xYzAsMC4yLTAuMSwwLjQtMC4yLDAuNkM0MSwzNy43LDQwLjgsMzcuNyw0MC42LDM3Ljd6IE0zNS4xLDM0LjlWMzQgICBoLTIuOXYwLjlIMzUuMXogTTM1LjEsMzYuN3YtMC45aC0yLjl2MC45SDM1LjF6IE0zOS44LDM0LjlWMzRoLTIuOXYwLjlIMzkuOHogTTM5LjgsMzYuN3YtMC45aC0yLjl2MC45SDM5Ljh6Ii8+Cgk8cGF0aCBkPSJNNDUuNSw0MS4xYy0wLjMsMC40LTAuNywwLjUtMS4xLDAuM2MtMC40LTAuMy0wLjUtMC43LTAuMy0xLjFsMS0xLjdjMC4zLTAuNCwwLjctMC41LDEuMS0wLjNjMC40LDAuMywwLjUsMC43LDAuMywxLjEgICBMNDUuNSw0MS4xeiBNNTUsMzcuN2MtMC4xLDAtMC4xLDAtMC4yLDBoLTguOWMtMC4zLDAtMC41LTAuMS0wLjYtMC4yYy0wLjItMC4yLTAuMi0wLjQtMC4yLTAuNnYtMy40YzAtMC4yLDAuMS0wLjQsMC4yLTAuNiAgIGMwLjEtMC4xLDAuMy0wLjIsMC42LTAuMmgzLjN2LTMuMWMwLTAuMiwwLjEtMC40LDAuMi0wLjZjMC4yLTAuMiwwLjQtMC4yLDAuNi0wLjJzMC40LDAuMSwwLjYsMC4yYzAuMiwwLjIsMC4yLDAuNCwwLjIsMC42djAuM0g1NiAgIGMwLjIsMCwwLjQsMC4xLDAuNiwwLjJjMC4xLDAuMSwwLjIsMC4zLDAuMiwwLjZzLTAuMSwwLjQtMC4yLDAuNWMtMC4xLDAuMS0wLjMsMC4yLTAuNiwwLjJoLTUuMnYxLjNoNGMwLjIsMCwwLjQsMC4xLDAuNiwwLjIgICBjMC4xLDAuMSwwLjIsMC4zLDAuMiwwLjZ2My40QzU1LjYsMzcuMyw1NS40LDM3LjYsNTUsMzcuN3ogTTUzLjksMzYuMnYtMmgtNy4xdjJINTMuOXogTTQ5LjYsNDAuN2MwLDAuMy0wLjEsMC41LTAuMiwwLjYgICBjLTAuMiwwLjEtMC40LDAuMi0wLjYsMC4yYy0wLjIsMC0wLjQtMC4xLTAuNi0wLjJjLTAuMS0wLjItMC4yLTAuNC0wLjItMC42bDAtMS42YzAtMC4yLDAuMS0wLjQsMC4yLTAuNmMwLjItMC4yLDAuMy0wLjIsMC42LTAuMiAgIHMwLjQsMC4xLDAuNiwwLjJjMC4yLDAuMiwwLjIsMC40LDAuMiwwLjZWNDAuN3ogTTUyLjgsNDAuN2MwLDAuMi0wLjEsMC40LTAuMiwwLjZjLTAuMiwwLjEtMC40LDAuMi0wLjYsMC4yICAgYy0wLjIsMC0wLjQtMC4xLTAuNi0wLjJjLTAuMi0wLjEtMC4yLTAuMy0wLjItMC42bDAtMS42YzAtMC4yLDAuMS0wLjQsMC4yLTAuNmMwLjItMC4yLDAuMy0wLjIsMC42LTAuMmMwLjIsMCwwLjQsMC4xLDAuNiwwLjIgICBjMC4yLDAuMiwwLjIsMC40LDAuMiwwLjZWNDAuN3ogTTU2LjYsNDAuM2MwLjIsMC40LDAuMSwwLjgtMC4zLDEuMWMtMC41LDAuMy0wLjgsMC4yLTEuMS0wLjNsLTEtMS43Yy0wLjItMC41LTAuMS0wLjgsMC4zLTEuMSAgIGMwLjUtMC4yLDAuOS0wLjEsMS4xLDAuM0w1Ni42LDQwLjN6Ii8+CjwvZz4KPC9zdmc+";
871
+ async function convertTextStyle(el, isByWord = false) {
872
+ const { fetchToText } = useSharedTextAssets();
873
+ const style = {
874
+ ...el.style,
875
+ highlightReferImage,
714
876
  listStyleType: "none",
715
877
  listStyleImage: "none"
716
878
  };
717
- return e.style.fontSize && (t.fontSize = Math.floor(e.style.fontSize)), e.listStyle?.colormap && (t.listStyleColormap = e.listStyle?.colormap), r || (e.listMode ? t.listStyleType = "disc" : e.listStyle && (t.listStyleImage = await o(e.listStyle.image), t.listStyleSize = `${e.listStyle.size * 100}%`)), e.background?.enabled ? (t.backgroundImage = e.background.image, t.backgroundSize = e.background.size, t.backgroundColormap = e.background.colormap, t.padding = e.background.padding) : t.padding = 0, t;
879
+ if (el.style.fontSize) {
880
+ style.fontSize = Math.floor(el.style.fontSize);
881
+ }
882
+ if (el.listStyle?.colormap) {
883
+ style.listStyleColormap = el.listStyle?.colormap;
884
+ }
885
+ if (!isByWord) {
886
+ if (el.listMode) {
887
+ style.listStyleType = "disc";
888
+ } else if (el.listStyle) {
889
+ style.listStyleImage = await fetchToText(el.listStyle.image);
890
+ style.listStyleSize = `${el.listStyle.size * 100}%`;
891
+ }
892
+ }
893
+ if (el.background?.enabled) {
894
+ style.backgroundImage = el.background.image;
895
+ style.backgroundSize = el.background.size;
896
+ style.backgroundColormap = el.background.colormap;
897
+ style.padding = el.background.padding;
898
+ } else {
899
+ style.padding = 0;
900
+ }
901
+ return style;
718
902
  }
719
- async function Tt(e) {
720
- const r = e.textEffects ?? [];
721
- if (r.length)
722
- return await Promise.all(
723
- [...r].reverse().map(async (o) => {
724
- const t = {}, { offset: s, skew: i, stroke: n, shadow: f, filling: c } = o;
725
- if (s && (t.translateX = s.x, t.translateY = s.y), i && (t.skewX = i.x, t.skewY = i.y), n?.color && n.width && (t.textStrokeWidth = n.width, t.textStrokeColor = n.color), f && (t.shadowOffsetX = f.offsetX, t.shadowOffsetY = f.offsetY, t.shadowBlur = f.blur, t.shadowColor = f.color), c) {
726
- const { color: d, imageContent: l, gradient: a } = c;
727
- l?.image || (a ? t.color = `linear-gradient(${90 - a.angle}deg, ${a.stops.map((M) => `${M.color} ${M.offset * 100}%`).join(",")})` : d && (t.color = d));
903
+ async function convertTextEffects(el) {
904
+ const effects = el.textEffects ?? [];
905
+ if (!effects.length) {
906
+ return void 0;
907
+ }
908
+ return await Promise.all(
909
+ [...effects].reverse().map(async (effect) => {
910
+ const result = {};
911
+ const { offset, skew, stroke, shadow, filling } = effect;
912
+ if (offset) {
913
+ result.translateX = offset.x;
914
+ result.translateY = offset.y;
915
+ }
916
+ if (skew) {
917
+ result.skewX = skew.x;
918
+ result.skewY = skew.y;
919
+ }
920
+ if (stroke?.color && stroke.width) {
921
+ result.textStrokeWidth = stroke.width;
922
+ result.textStrokeColor = stroke.color;
923
+ }
924
+ if (shadow) {
925
+ result.shadowOffsetX = shadow.offsetX;
926
+ result.shadowOffsetY = shadow.offsetY;
927
+ result.shadowBlur = shadow.blur;
928
+ result.shadowColor = shadow.color;
929
+ }
930
+ if (filling) {
931
+ const { color, imageContent, gradient } = filling;
932
+ if (imageContent?.image) ;
933
+ else if (gradient) {
934
+ result.color = `linear-gradient(${90 - gradient.angle}deg, ${gradient.stops.map((stop) => `${stop.color} ${stop.offset * 100}%`).join(",")})`;
935
+ } else if (color) {
936
+ result.color = color;
728
937
  }
729
- return t;
730
- })
731
- );
938
+ }
939
+ return result;
940
+ })
941
+ );
732
942
  }
733
- function Dt(e) {
734
- return e.version ? e.contents : e.contents.map((r) => {
735
- let o;
736
- return r.map((t, s) => {
737
- let i = t.content;
738
- i = i.replace(/ |\r\n|\n\r|[\n\r\t\v]/g, " "), i = i.replace(/<br\/>/g, `
739
- `);
740
- let n = "", f = 0;
741
- for (const c of Array.from(i))
742
- s === 0 && f === 0 && c === " " || o === " " && c === " " || (n += c), o = c, f++;
943
+ function getTextContents(el) {
944
+ if (el.version) {
945
+ return el.contents;
946
+ }
947
+ return el.contents.map((p) => {
948
+ let prevChar;
949
+ return p.map((f, fIndex) => {
950
+ let content = f.content;
951
+ content = content.replace(/ |\r\n|\n\r|[\n\r\t\v]/g, " ");
952
+ content = content.replace(/<br\/>/g, "\n");
953
+ let newContent = "";
954
+ let cIndex = 0;
955
+ for (const char of Array.from(content)) {
956
+ if (fIndex === 0 && cIndex === 0 && char === " ") ;
957
+ else if (prevChar === " " && char === " ") ;
958
+ else {
959
+ newContent += char;
960
+ }
961
+ prevChar = char;
962
+ cIndex++;
963
+ }
743
964
  return {
744
- ...t,
745
- content: n
965
+ ...f,
966
+ content: newContent
746
967
  };
747
- }).filter((t) => t.content);
968
+ }).filter((f) => f.content);
748
969
  });
749
970
  }
750
- async function It(e, r = !1) {
751
- const { fetchToText: o } = _(), t = Dt(e), s = [];
752
- for (let i = 0, n = t.length; i < n; i++) {
753
- const f = t[i], c = {
971
+ async function convertTextContent(el, isByWord = false) {
972
+ const { fetchToText } = useSharedTextAssets();
973
+ const bigeContents = getTextContents(el);
974
+ const paragraphs = [];
975
+ for (let i = 0, len = bigeContents.length; i < len; i++) {
976
+ const bigeParagraphs = bigeContents[i];
977
+ const paragraph = {
754
978
  fragments: []
755
979
  };
756
- s.push(c);
757
- for (let d = 0, l = f.length; d < l; d++) {
758
- const a = {}, M = f[d];
759
- for (const w in M)
760
- w !== "id" && M[w] !== "" && (a[w] = M[w]);
761
- a.fontSize && (a.fontSize = Math.floor(a.fontSize)), a.content = Mt(a.content), a.highlight && (a.highlightImage = await o(a.highlight.image), r ? a.highlightSize = "cover" : a.highlight.size && (a.highlightSize = `${a.highlight.size}rem`), a.highlight.colormap && (a.highlightColormap = a.highlight.colormap), a.highlight.line && (a.highlightLine = a.highlight.line), a.highlight.thickness && (a.highlightThickness = `${a.highlight.thickness}%`), delete a.highlight), r || (a.listMode ? c.listStyleType = "disc" : a.listStyle && (c.listStyleImage = await o(a.listStyle.image), c.listStyleSize = `${a.listStyle.size * 100}%`));
762
- const L = c.fragments[c.fragments.length - 1];
763
- L && Object.keys(L).length === 1 && L.content && Object.keys(a).length === 1 && a.content ? L.content += a.content : c.fragments.push(a);
980
+ paragraphs.push(paragraph);
981
+ for (let i2 = 0, len2 = bigeParagraphs.length; i2 < len2; i2++) {
982
+ const fragment = {};
983
+ const raw = bigeParagraphs[i2];
984
+ for (const key in raw) {
985
+ if (key !== "id" && raw[key] !== "") {
986
+ fragment[key] = raw[key];
987
+ }
988
+ }
989
+ if (fragment.fontSize) {
990
+ fragment.fontSize = Math.floor(fragment.fontSize);
991
+ }
992
+ fragment.content = normalizeCRLF(fragment.content);
993
+ if (fragment.highlight) {
994
+ fragment.highlightImage = await fetchToText(fragment.highlight.image);
995
+ if (isByWord) {
996
+ fragment.highlightSize = "cover";
997
+ } else {
998
+ if (fragment.highlight.size) {
999
+ fragment.highlightSize = `${fragment.highlight.size}rem`;
1000
+ }
1001
+ }
1002
+ if (fragment.highlight.colormap) {
1003
+ fragment.highlightColormap = fragment.highlight.colormap;
1004
+ }
1005
+ if (fragment.highlight.line) {
1006
+ fragment.highlightLine = fragment.highlight.line;
1007
+ }
1008
+ if (fragment.highlight.thickness) {
1009
+ fragment.highlightThickness = `${fragment.highlight.thickness}%`;
1010
+ }
1011
+ delete fragment.highlight;
1012
+ }
1013
+ if (!isByWord) {
1014
+ if (fragment.listMode) {
1015
+ paragraph.listStyleType = "disc";
1016
+ } else if (fragment.listStyle) {
1017
+ paragraph.listStyleImage = await fetchToText(fragment.listStyle.image);
1018
+ paragraph.listStyleSize = `${fragment.listStyle.size * 100}%`;
1019
+ }
1020
+ }
1021
+ const prev = paragraph.fragments[paragraph.fragments.length - 1];
1022
+ if (prev && Object.keys(prev).length === 1 && prev.content && Object.keys(fragment).length === 1 && fragment.content) {
1023
+ prev.content += fragment.content;
1024
+ } else {
1025
+ paragraph.fragments.push(fragment);
1026
+ }
764
1027
  }
765
1028
  }
766
- return s;
1029
+ return paragraphs;
767
1030
  }
768
- const P = (e) => (Number.parseFloat(e) || 0) / 100;
769
- async function q(e, r, o) {
770
- const t = { ...e.style ?? e };
771
- delete t.bottom, delete t.right;
772
- const s = {
1031
+ const percentageToPx = (per) => (Number.parseFloat(per) || 0) / 100;
1032
+ async function convertElement(el, parent, context) {
1033
+ const style = { ...el.style ?? el };
1034
+ delete style.bottom;
1035
+ delete style.right;
1036
+ const meta = {
773
1037
  inPptIs: "Shape",
774
1038
  inEditorIs: "Element"
775
1039
  };
776
- e.id && (s.rawId = e.id), e.name && (s.rawName = e.name);
777
- const i = {
778
- id: F(),
779
- name: e.name ?? e.title ?? e.id,
780
- style: t,
781
- meta: s,
1040
+ if (el.id) {
1041
+ meta.rawId = el.id;
1042
+ }
1043
+ if (el.name) {
1044
+ meta.rawName = el.name;
1045
+ }
1046
+ const element = {
1047
+ id: idGenerator(),
1048
+ name: el.name ?? el.title ?? el.id,
1049
+ style,
1050
+ meta,
782
1051
  children: []
783
1052
  };
784
- if (t.borderRadius && (t.borderRadius = t.borderRadius * 0.01 * Math.max(t.height, t.width)), r && e.groupStyle && (t.width = r.style.width * P(e.groupStyle.width), t.height = r.style.height * P(e.groupStyle.height), t.left = r.style.width * P(e.groupStyle.left), t.top = r.style.height * P(e.groupStyle.top)), e.editable === !1 && (t.visibility = "hidden"), e.lock === !0 && (s.lock = !0), e.animations?.length) {
785
- const n = jt(e);
786
- i.delay = n.delay, i.duration = n.duration, i.children.push(...n.animations), o && (n.animations.forEach((f) => {
787
- o.endTime = Math.max(
788
- o.endTime,
789
- n.delay + f.delay + f.duration
790
- );
791
- }), o.endTime = Math.max(o.endTime, n.delay + n.duration));
1053
+ if (style.borderRadius) {
1054
+ style.borderRadius = style.borderRadius * 0.01 * Math.max(style.height, style.width);
1055
+ }
1056
+ if (parent && el.groupStyle) {
1057
+ style.width = parent.style.width * percentageToPx(el.groupStyle.width);
1058
+ style.height = parent.style.height * percentageToPx(el.groupStyle.height);
1059
+ style.left = parent.style.width * percentageToPx(el.groupStyle.left);
1060
+ style.top = parent.style.height * percentageToPx(el.groupStyle.top);
1061
+ }
1062
+ if (el.editable === false) {
1063
+ style.visibility = "hidden";
792
1064
  }
793
- switch (e.type) {
1065
+ if (el.lock === true) {
1066
+ meta.lock = true;
1067
+ }
1068
+ if (el.animations?.length) {
1069
+ const parsed = parseAnimations(el);
1070
+ element.delay = parsed.delay;
1071
+ element.duration = parsed.duration;
1072
+ element.children.push(...parsed.animations);
1073
+ if (context) {
1074
+ parsed.animations.forEach((animation) => {
1075
+ context.endTime = Math.max(
1076
+ context.endTime,
1077
+ parsed.delay + animation.delay + animation.duration
1078
+ );
1079
+ });
1080
+ context.endTime = Math.max(context.endTime, parsed.delay + parsed.duration);
1081
+ }
1082
+ }
1083
+ switch (el.type) {
794
1084
  case "image":
795
- if (s.inPptIs = "Picture", i.foreground = {
796
- image: await V(e),
797
- fillWithShape: !0
798
- }, e.clipUrl && (s.rawForegroundImage = e.url), e.cropping) {
799
- const n = e.style.width, f = e.style.height, {
800
- imageWidth: c,
801
- imageHeight: d,
802
- maskWidth: l = n,
803
- maskHeight: a = f,
804
- translateX: M,
805
- translateY: L,
806
- zoom: w = 1
807
- } = e.cropping, h = c * w, u = d * w, C = (h - l) / 2 - M, m = (u - a) / 2 - L, g = C + l / 2, T = m + a / 2, j = -(n / 2 - g), y = -(f / 2 - T), A = h - (j + n), k = u - (y + f);
808
- i.foreground.cropRect = {
809
- left: j / h,
810
- top: y / u,
811
- right: A / h,
812
- bottom: k / u
1085
+ meta.inPptIs = "Picture";
1086
+ element.foreground = {
1087
+ image: await convertImageElementToUrl(el),
1088
+ fillWithShape: true
1089
+ };
1090
+ if (el.clipUrl) {
1091
+ meta.rawForegroundImage = el.url;
1092
+ }
1093
+ if (el.cropping) {
1094
+ const width = el.style.width;
1095
+ const height = el.style.height;
1096
+ const {
1097
+ imageWidth,
1098
+ imageHeight,
1099
+ maskWidth = width,
1100
+ maskHeight = height,
1101
+ translateX,
1102
+ translateY,
1103
+ zoom = 1
1104
+ } = el.cropping;
1105
+ const cvsWidth = imageWidth * zoom;
1106
+ const cvsHeight = imageHeight * zoom;
1107
+ const distX = (cvsWidth - maskWidth) / 2 - translateX;
1108
+ const distY = (cvsHeight - maskHeight) / 2 - translateY;
1109
+ const originX = distX + maskWidth / 2;
1110
+ const originY = distY + maskHeight / 2;
1111
+ const left = -(width / 2 - originX);
1112
+ const top = -(height / 2 - originY);
1113
+ const right = cvsWidth - (left + width);
1114
+ const bottom = cvsHeight - (top + height);
1115
+ element.foreground.cropRect = {
1116
+ left: left / cvsWidth,
1117
+ top: top / cvsHeight,
1118
+ right: right / cvsWidth,
1119
+ bottom: bottom / cvsHeight
813
1120
  };
814
1121
  }
815
1122
  break;
816
1123
  case "svg": {
817
- s.inPptIs = "Picture", i.foreground = {
818
- image: await pt(e),
819
- fillWithShape: !0
1124
+ meta.inPptIs = "Picture";
1125
+ element.foreground = {
1126
+ image: await convertSvgElementToUrl(el),
1127
+ fillWithShape: true
820
1128
  };
821
1129
  break;
822
1130
  }
823
1131
  case "text": {
824
- s.inPptIs = "Shape", t.writingMode === "horizontal-tb" ? t.width = Math.ceil(t.width + t.letterSpacing) : t.height = Math.ceil(t.height + t.letterSpacing), i.text = {
825
- content: await It(e),
826
- style: await xt(e),
827
- effects: await Tt(e)
1132
+ meta.inPptIs = "Shape";
1133
+ if (style.writingMode === "horizontal-tb") {
1134
+ style.width = Math.ceil(style.width + style.letterSpacing);
1135
+ } else {
1136
+ style.height = Math.ceil(style.height + style.letterSpacing);
1137
+ }
1138
+ element.text = {
1139
+ content: await convertTextContent(el),
1140
+ style: await convertTextStyle(el),
1141
+ effects: await convertTextEffects(el)
828
1142
  // plugins: [deformation(el.deformation?.type?.endsWith("byWord") ? -1 : 999, () => el.deformation)],
829
1143
  };
830
1144
  break;
831
1145
  }
832
1146
  case "com":
833
- s.inPptIs = "GroupShape", i.children = (await Promise.all(
834
- e.children.map(async (n) => {
1147
+ meta.inPptIs = "GroupShape";
1148
+ element.children = (await Promise.all(
1149
+ el.children.map(async (child) => {
835
1150
  try {
836
- return await q(n, e, o);
837
- } catch (f) {
838
- console.warn(f);
839
- return;
1151
+ return await convertElement(child, el, context);
1152
+ } catch (e) {
1153
+ console.warn(e);
1154
+ return void 0;
840
1155
  }
841
1156
  })
842
1157
  )).filter(Boolean);
@@ -863,193 +1178,279 @@ async function q(e, r, o) {
863
1178
  case "collage":
864
1179
  case "imageWall":
865
1180
  default:
866
- console.warn(e);
1181
+ console.warn(el);
867
1182
  break;
868
1183
  }
869
- return i;
1184
+ return element;
870
1185
  }
871
- async function St(e, r = !0, o) {
872
- const t = F(), s = {
873
- ...e.style ?? e
1186
+ async function convertLayout(layout, isFrame = true, context) {
1187
+ const id = idGenerator();
1188
+ const style = {
1189
+ ...layout.style ?? layout
874
1190
  };
875
- delete s.right, delete s.bottom, r && (s.overflow = "hidden");
876
- const i = {
877
- inPptIs: r ? "Slide" : "GroupShape",
878
- inEditorIs: r ? "Frame" : "Element"
1191
+ delete style.right;
1192
+ delete style.bottom;
1193
+ if (isFrame) {
1194
+ style.overflow = "hidden";
1195
+ }
1196
+ const meta = {
1197
+ inPptIs: isFrame ? "Slide" : "GroupShape",
1198
+ inEditorIs: isFrame ? "Frame" : "Element"
879
1199
  };
880
- e.id && (i.rawId = e.id), e.name && (i.rawName = e.name);
881
- let n;
882
- return e.background && (e.background.color && (n ??= {}, dt(e.background.color ?? "") ? n.image = e.background.color : n.color = e.background.color), e.background.image && (n ??= {}, n.image = e.background.image)), {
883
- id: t,
884
- name: r ? `Frame ${t}` : e.name,
885
- style: s,
1200
+ if (layout.id) {
1201
+ meta.rawId = layout.id;
1202
+ }
1203
+ if (layout.name) {
1204
+ meta.rawName = layout.name;
1205
+ }
1206
+ let background;
1207
+ if (layout.background) {
1208
+ if (layout.background.color) {
1209
+ background ??= {};
1210
+ if (isGradient(layout.background.color ?? "")) {
1211
+ background.image = layout.background.color;
1212
+ } else {
1213
+ background.color = layout.background.color;
1214
+ }
1215
+ }
1216
+ if (layout.background.image) {
1217
+ background ??= {};
1218
+ background.image = layout.background.image;
1219
+ }
1220
+ }
1221
+ return {
1222
+ id,
1223
+ name: isFrame ? `Frame ${id}` : layout.name,
1224
+ style,
886
1225
  // TODO 过滤掉部分属性
887
- background: n,
1226
+ background,
888
1227
  children: (await Promise.all(
889
- e.elements.map(async (f) => {
1228
+ layout.elements.map(async (element) => {
890
1229
  try {
891
- return await q(f, void 0, o);
892
- } catch (c) {
893
- console.warn(c);
894
- return;
1230
+ return await convertElement(element, void 0, context);
1231
+ } catch (e) {
1232
+ console.warn(e);
1233
+ return void 0;
895
1234
  }
896
1235
  })
897
1236
  )).filter(Boolean),
898
- meta: i
1237
+ meta
899
1238
  };
900
1239
  }
901
- async function K(e, r = 0) {
1240
+ async function convertDoc(doc, gap = 0) {
902
1241
  const {
903
- layouts: o,
904
- metas: t = {}
905
- } = e, s = {
1242
+ layouts,
1243
+ metas = {}
1244
+ } = doc;
1245
+ const context = {
906
1246
  endTime: 0
907
1247
  };
908
- let i = await Promise.all(
909
- o.map(async (c, d) => ({
910
- index: d,
911
- element: await St(c, !0, s)
912
- }))
913
- ), n = 0;
914
- i = i.sort((c, d) => c.index - d.index).map((c, d) => {
915
- const l = c.element;
916
- return l.style && (l.style.top = n, n += Number(l.style.height) + r), l.name = `Frame ${d + 1}`, l;
1248
+ let children = await Promise.all(
1249
+ layouts.map(async (layout, index) => {
1250
+ return {
1251
+ index,
1252
+ element: await convertLayout(layout, true, context)
1253
+ };
1254
+ })
1255
+ );
1256
+ let top = 0;
1257
+ children = children.sort((a, b) => a.index - b.index).map((v, index) => {
1258
+ const element = v.element;
1259
+ if (element.style) {
1260
+ element.style.top = top;
1261
+ top += Number(element.style.height) + gap;
1262
+ }
1263
+ element.name = `Frame ${index + 1}`;
1264
+ return element;
917
1265
  });
918
- const f = i.reduce((c) => {
919
- const d = c.style?.left ?? 0, l = c.style?.top ?? 0, a = c.style?.width ?? 0, M = c.style?.height ?? 0;
1266
+ const minmax = children.reduce((child) => {
1267
+ const left = child.style?.left ?? 0;
1268
+ const top2 = child.style?.top ?? 0;
1269
+ const width = child.style?.width ?? 0;
1270
+ const height = child.style?.height ?? 0;
920
1271
  return {
921
- minX: d,
922
- minY: l,
923
- maxX: d + a,
924
- maxY: l + M
1272
+ minX: left,
1273
+ minY: top2,
1274
+ maxX: left + width,
1275
+ maxY: top2 + height
925
1276
  };
926
1277
  }, { minX: 0, minY: 0, maxX: 0, maxY: 0 });
927
1278
  return {
928
- id: F(),
929
- name: t.name || "doc",
1279
+ id: idGenerator(),
1280
+ name: metas.name || "doc",
930
1281
  style: {
931
- width: t?.width ?? f.maxX - f.minX,
932
- height: t?.height ?? f.maxY - f.minY
1282
+ width: metas?.width ?? minmax.maxX - minmax.minX,
1283
+ height: metas?.height ?? minmax.maxY - minmax.minY
933
1284
  },
934
- children: i,
1285
+ children,
935
1286
  meta: {
936
- ...t,
937
- endTime: s.endTime,
1287
+ ...metas,
1288
+ endTime: context.endTime,
938
1289
  inEditorIs: "Doc"
939
1290
  }
940
1291
  };
941
1292
  }
942
- function zt(e, r) {
943
- const { config: o } = e;
1293
+ function bidTidLoader(editor, api) {
1294
+ const { config } = editor;
944
1295
  return {
945
1296
  name: "bigesj:bidTid",
946
- test: (t) => typeof t == "object" && t && !!(t.bid || t.tid),
947
- load: async (t) => {
948
- const s = t.bid ?? t.tid ?? "", i = async (l) => await fetch(
949
- (t.bid ? r.bid : r.tid).replace("%d", l)
950
- ).then((a) => a.json()).then((a) => a.data);
951
- let n = 0;
952
- const f = await Promise.all(
953
- s.split("|").map(async (l) => {
954
- let [a, M] = l.split("[");
955
- M && (M = M.substring(0, M.length - 1));
956
- const L = M ? M.split(",").map((g) => Number(g)) : void 0, w = await i(a), { content: h, ...u } = w, C = JSON.parse(h);
957
- L !== void 0 && (C.layouts = C.layouts.filter((g, T) => L.includes(T)));
958
- const m = await K(C);
959
- return m.meta.raw = u, n = Math.max(n, m.meta?.maxTime ?? 0), m;
1297
+ test: (source) => typeof source === "object" && source && !!(source.bid || source.tid),
1298
+ load: async (source) => {
1299
+ const text = source.bid ?? source.tid ?? "";
1300
+ const load = async (id) => {
1301
+ return await fetch(
1302
+ (source.bid ? api.bid : api.tid).replace("%d", id)
1303
+ ).then((rep) => rep.json()).then((res) => res.data);
1304
+ };
1305
+ let maxTime = 0;
1306
+ const docs = await Promise.all(
1307
+ text.split("|").map(async (text1) => {
1308
+ let [id, text2] = text1.split("[");
1309
+ if (text2) {
1310
+ text2 = text2.substring(0, text2.length - 1);
1311
+ }
1312
+ const included = text2 ? text2.split(",").map((v) => Number(v)) : void 0;
1313
+ const bigeDoc = await load(id);
1314
+ const { content: _content, ...raw } = bigeDoc;
1315
+ const content = JSON.parse(_content);
1316
+ if (included !== void 0) {
1317
+ content.layouts = content.layouts.filter((_, index) => included.includes(index));
1318
+ }
1319
+ const doc2 = await convertDoc(content);
1320
+ doc2.meta.raw = raw;
1321
+ maxTime = Math.max(maxTime, doc2.meta?.maxTime ?? 0);
1322
+ return doc2;
960
1323
  })
961
- ), c = { ...f[0], id: s, children: [] };
962
- c.meta ??= {}, c.meta.maxTime = n, c.meta.inEditorIs = "Doc";
963
- let d = 0;
964
- return f.forEach((l) => {
965
- let a = 0;
966
- l.children?.forEach((M) => {
967
- M.style && (M.style.left = d, a = Math.max(a, Number(M.style.width)), c.children.push(M));
968
- }), d += a + o.value.frameGap;
969
- }), c;
1324
+ );
1325
+ const doc = { ...docs[0], id: text, children: [] };
1326
+ doc.meta ??= {};
1327
+ doc.meta.maxTime = maxTime;
1328
+ doc.meta.inEditorIs = "Doc";
1329
+ let left = 0;
1330
+ docs.forEach((_doc) => {
1331
+ let width = 0;
1332
+ _doc.children?.forEach((element) => {
1333
+ if (element.style) {
1334
+ element.style.left = left;
1335
+ width = Math.max(width, Number(element.style.width));
1336
+ doc.children.push(element);
1337
+ }
1338
+ });
1339
+ left += width + config.value.frameGap;
1340
+ });
1341
+ return doc;
970
1342
  }
971
1343
  };
972
1344
  }
973
- function Nt() {
1345
+ function bigeLoader() {
974
1346
  return {
975
1347
  name: "bigesj:bige",
976
1348
  accept: ".bige",
977
- test: (e) => e instanceof File && e.name.endsWith(".bige"),
978
- load: async (e) => {
979
- const r = JSON.parse(
1349
+ test: (file) => {
1350
+ return file instanceof File && file.name.endsWith(".bige");
1351
+ },
1352
+ load: async (file) => {
1353
+ const bigeDoc = JSON.parse(
980
1354
  new TextDecoder().decode(
981
- Lt(new Uint8Array(await e.arrayBuffer()))
1355
+ gunzipSync(new Uint8Array(await file.arrayBuffer()))
982
1356
  )
983
- ), { content: o, ...t } = r, s = await K(o);
984
- return s.meta.raw = t, s;
1357
+ );
1358
+ const { content, ...raw } = bigeDoc;
1359
+ const doc = await convertDoc(content);
1360
+ doc.meta.raw = raw;
1361
+ return doc;
985
1362
  }
986
1363
  };
987
1364
  }
988
- function Qt(e = {}) {
1365
+ function plugin(options = {}) {
989
1366
  const {
990
- font: r,
991
- api: o
992
- } = e, t = {
1367
+ font,
1368
+ api
1369
+ } = options;
1370
+ const _api = {
993
1371
  fonts: "/new/design/fonts",
994
1372
  bid: "/new/udesign/info/%d",
995
1373
  tid: "/new/design/info/%d",
996
- ...o
1374
+ ...api
997
1375
  };
998
- return nt((s) => ({
999
- name: "bigesj",
1000
- loaders: [
1001
- Nt(),
1002
- zt(s, t)
1003
- ],
1004
- setup: async () => {
1005
- r && await bt(s, t);
1006
- }
1007
- }));
1376
+ return definePlugin((editor) => {
1377
+ return {
1378
+ name: "bigesj",
1379
+ loaders: [
1380
+ bigeLoader(),
1381
+ bidTidLoader(editor, _api)
1382
+ ],
1383
+ setup: async () => {
1384
+ if (font) {
1385
+ await setupFonts(editor, _api);
1386
+ }
1387
+ }
1388
+ };
1389
+ });
1008
1390
  }
1009
- async function bt(e, r) {
1391
+ async function setupFonts(editor, api) {
1010
1392
  const {
1011
- on: o,
1012
- off: t,
1013
- root: s
1014
- } = e, {
1015
- loadBigeFonts: i,
1016
- loadFont: n
1017
- } = mt();
1018
- function f(l) {
1019
- l instanceof ot && (l.style.fontFamily && n(l.style.fontFamily).then(() => l.text.update()), l.text.content.forEach((a) => {
1020
- a.fragments.forEach((M) => {
1021
- M.fontFamily && n(M.fontFamily).then(() => l.text.update());
1022
- }), a.fontFamily && n(a.fontFamily).then(() => l.text.update());
1023
- }));
1393
+ on,
1394
+ off,
1395
+ root
1396
+ } = editor;
1397
+ const {
1398
+ loadBigeFonts,
1399
+ loadFont
1400
+ } = useFonts();
1401
+ function preloadNode(node) {
1402
+ if (node instanceof Element2D) {
1403
+ if (node.style.fontFamily) {
1404
+ loadFont(node.style.fontFamily).then(() => node.text.update());
1405
+ }
1406
+ node.text.content.forEach((p) => {
1407
+ p.fragments.forEach((f) => {
1408
+ if (f.fontFamily) {
1409
+ loadFont(f.fontFamily).then(() => node.text.update());
1410
+ }
1411
+ });
1412
+ if (p.fontFamily) {
1413
+ loadFont(p.fontFamily).then(() => node.text.update());
1414
+ }
1415
+ });
1416
+ }
1024
1417
  }
1025
- function c(l) {
1026
- l.forEach((a) => {
1027
- f(a), a.findOne((M) => (f(M), !1));
1418
+ function preloadNodes(node) {
1419
+ node.forEach((child) => {
1420
+ preloadNode(child);
1421
+ child.findOne((descendant) => {
1422
+ preloadNode(descendant);
1423
+ return false;
1424
+ });
1028
1425
  });
1029
1426
  }
1030
- async function d() {
1031
- s.value && c([s.value]);
1427
+ async function preload() {
1428
+ root.value && preloadNodes([root.value]);
1032
1429
  }
1033
- lt(() => {
1034
- t("setDoc", d), t("addElement", c);
1035
- }), o("setDoc", d), o("addElement", c), await i(r.fonts);
1430
+ onBeforeUnmount(() => {
1431
+ off("setDoc", preload);
1432
+ off("addElement", preloadNodes);
1433
+ });
1434
+ on("setDoc", preload);
1435
+ on("addElement", preloadNodes);
1436
+ await loadBigeFonts(api.fonts);
1036
1437
  }
1037
1438
  export {
1038
- zt as bidTidLoader,
1039
- Nt as bigeLoader,
1040
- U as convertAnimation,
1041
- K as convertDoc,
1042
- q as convertElement,
1043
- V as convertImageElementToUrl,
1044
- St as convertLayout,
1045
- pt as convertSvgElementToUrl,
1046
- It as convertTextContent,
1047
- Tt as convertTextEffects,
1048
- xt as convertTextStyle,
1049
- Qt as default,
1050
- Dt as getTextContents,
1051
- jt as parseAnimations,
1052
- Qt as plugin,
1053
- mt as useFonts,
1054
- _ as useSharedTextAssets
1439
+ bidTidLoader,
1440
+ bigeLoader,
1441
+ convertAnimation,
1442
+ convertDoc,
1443
+ convertElement,
1444
+ convertImageElementToUrl,
1445
+ convertLayout,
1446
+ convertSvgElementToUrl,
1447
+ convertTextContent,
1448
+ convertTextEffects,
1449
+ convertTextStyle,
1450
+ plugin as default,
1451
+ getTextContents,
1452
+ parseAnimations,
1453
+ plugin,
1454
+ useFonts,
1455
+ useSharedTextAssets
1055
1456
  };