pptx-viewer-core 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/{SvgExporter-CWAfTaRU.d.mts → SvgExporter-Csx19PZz.d.mts} +1 -1
- package/dist/{SvgExporter-CVRYDmB3.d.ts → SvgExporter-CxE3LpEi.d.ts} +1 -1
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +30715 -23031
- package/dist/cli/index.mjs +30716 -23032
- package/dist/converter/index.d.mts +3 -3
- package/dist/converter/index.d.ts +3 -3
- package/dist/converter/index.js +1921 -42
- package/dist/converter/index.mjs +1921 -42
- package/dist/index.d.mts +506 -276
- package/dist/index.d.ts +506 -276
- package/dist/index.js +21226 -13049
- package/dist/index.mjs +21213 -13050
- package/dist/{presentation-BAMjUmQZ.d.mts → presentation-BLbjWKxK.d.mts} +498 -27
- package/dist/{presentation-BAMjUmQZ.d.ts → presentation-BLbjWKxK.d.ts} +498 -27
- package/dist/{text-operations-DZ1WQcRn.d.ts → text-operations-B0rbI4l2.d.ts} +1 -1
- package/dist/{text-operations-BkiHFUME.d.mts → text-operations-Beui0_5d.d.mts} +1 -1
- package/package.json +3 -3
package/dist/converter/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
require('fast-xml-parser');
|
|
4
|
+
require('jszip');
|
|
5
|
+
require('emf-converter');
|
|
6
|
+
|
|
3
7
|
// src/converter/media-context.ts
|
|
4
8
|
var MIME_TO_EXT = {
|
|
5
9
|
"image/png": "png",
|
|
@@ -522,6 +526,8 @@ var FallbackElementProcessor = class {
|
|
|
522
526
|
} else {
|
|
523
527
|
parts.push(`*[Zoom to Section (Slide ${slideNumber})]*`);
|
|
524
528
|
}
|
|
529
|
+
} else if (zoomElement.zoomType === "summary") {
|
|
530
|
+
parts.push(`*[Summary Zoom starting at Slide ${slideNumber}]*`);
|
|
525
531
|
} else {
|
|
526
532
|
parts.push(`*[Zoom to Slide ${slideNumber}]*`);
|
|
527
533
|
}
|
|
@@ -3313,6 +3319,40 @@ ${footer}`;
|
|
|
3313
3319
|
}
|
|
3314
3320
|
};
|
|
3315
3321
|
|
|
3322
|
+
// src/converter/svg-image-effect-values.ts
|
|
3323
|
+
function clamp(value, minimum, maximum) {
|
|
3324
|
+
return value < minimum ? minimum : value > maximum ? maximum : value;
|
|
3325
|
+
}
|
|
3326
|
+
function clamp01to2(value) {
|
|
3327
|
+
return clamp(value, 0, 2);
|
|
3328
|
+
}
|
|
3329
|
+
function fmt(value) {
|
|
3330
|
+
return Number.isFinite(value) ? Number(value.toFixed(4)).toString() : "0";
|
|
3331
|
+
}
|
|
3332
|
+
function stepTable10(threshold) {
|
|
3333
|
+
return Array.from({ length: 10 }, (_, index) => index / 10 >= threshold ? "1" : "0").join(" ");
|
|
3334
|
+
}
|
|
3335
|
+
function biLevelTable(threshold) {
|
|
3336
|
+
const cutoff = clamp(threshold, 0, 100);
|
|
3337
|
+
return Array.from({ length: 101 }, (_, index) => index >= cutoff ? "1" : "0").join(" ");
|
|
3338
|
+
}
|
|
3339
|
+
function luminanceTransfer(amount) {
|
|
3340
|
+
const normalized = clamp(amount / 100, -1, 1);
|
|
3341
|
+
return normalized >= 0 ? { slope: 1 - normalized, intercept: normalized } : { slope: 1 + normalized, intercept: 0 };
|
|
3342
|
+
}
|
|
3343
|
+
function parseHexRgb(hex) {
|
|
3344
|
+
const match = /^#?([0-9a-f]{6})/iu.exec(hex.trim());
|
|
3345
|
+
if (!match) {
|
|
3346
|
+
return { r: 0, g: 0, b: 0 };
|
|
3347
|
+
}
|
|
3348
|
+
const value = parseInt(match[1] ?? "000000", 16);
|
|
3349
|
+
return {
|
|
3350
|
+
r: (value >> 16 & 255) / 255,
|
|
3351
|
+
g: (value >> 8 & 255) / 255,
|
|
3352
|
+
b: (value & 255) / 255
|
|
3353
|
+
};
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3316
3356
|
// src/converter/svg-image-effects.ts
|
|
3317
3357
|
function buildImageEffectsFilter(effects, idSuffix) {
|
|
3318
3358
|
if (!effects) {
|
|
@@ -3337,6 +3377,20 @@ function buildImageEffectsFilter(effects, idSuffix) {
|
|
|
3337
3377
|
`<feColorMatrix in="__IN__" type="hueRotate" values="${fmt(effects.hsl.hue)}" result="__OUT__"/>`
|
|
3338
3378
|
);
|
|
3339
3379
|
}
|
|
3380
|
+
if (typeof effects.hsl?.sat === "number") {
|
|
3381
|
+
const saturation = clamp01to2(1 + effects.hsl.sat / 100);
|
|
3382
|
+
next(
|
|
3383
|
+
"p3s",
|
|
3384
|
+
`<feColorMatrix in="__IN__" type="saturate" values="${fmt(saturation)}" result="__OUT__"/>`
|
|
3385
|
+
);
|
|
3386
|
+
}
|
|
3387
|
+
if (typeof effects.hsl?.lum === "number") {
|
|
3388
|
+
const { slope, intercept } = luminanceTransfer(effects.hsl.lum);
|
|
3389
|
+
next(
|
|
3390
|
+
"p3l",
|
|
3391
|
+
`<feComponentTransfer in="__IN__" result="__OUT__"><feFuncR type="linear" slope="${fmt(slope)}" intercept="${fmt(intercept)}"/><feFuncG type="linear" slope="${fmt(slope)}" intercept="${fmt(intercept)}"/><feFuncB type="linear" slope="${fmt(slope)}" intercept="${fmt(intercept)}"/></feComponentTransfer>`
|
|
3392
|
+
);
|
|
3393
|
+
}
|
|
3340
3394
|
if (typeof effects.brightness === "number" || typeof effects.contrast === "number") {
|
|
3341
3395
|
const b = (effects.brightness ?? 0) / 100;
|
|
3342
3396
|
const c = 1 + (effects.contrast ?? 0) / 100;
|
|
@@ -3359,10 +3413,10 @@ function buildImageEffectsFilter(effects, idSuffix) {
|
|
|
3359
3413
|
}
|
|
3360
3414
|
if (typeof effects.biLevel === "number") {
|
|
3361
3415
|
next("p6a", `<feColorMatrix in="__IN__" type="saturate" values="0" result="__OUT__"/>`);
|
|
3362
|
-
const
|
|
3416
|
+
const table = biLevelTable(effects.biLevel);
|
|
3363
3417
|
next(
|
|
3364
3418
|
"p6b",
|
|
3365
|
-
`<feComponentTransfer in="__IN__" result="__OUT__"><feFuncR type="discrete" tableValues="${
|
|
3419
|
+
`<feComponentTransfer in="__IN__" result="__OUT__"><feFuncR type="discrete" tableValues="${table}"/><feFuncG type="discrete" tableValues="${table}"/><feFuncB type="discrete" tableValues="${table}"/></feComponentTransfer>`
|
|
3366
3420
|
);
|
|
3367
3421
|
}
|
|
3368
3422
|
if (effects.duotone) {
|
|
@@ -3375,19 +3429,17 @@ function buildImageEffectsFilter(effects, idSuffix) {
|
|
|
3375
3429
|
);
|
|
3376
3430
|
}
|
|
3377
3431
|
if (effects.tint && typeof effects.tint.amt === "number") {
|
|
3378
|
-
const amt = clamp(effects.tint.amt / 100, -1, 1);
|
|
3379
|
-
if (amt < 0) {
|
|
3380
|
-
next(
|
|
3381
|
-
"p8",
|
|
3382
|
-
`<feColorMatrix in="__IN__" type="saturate" values="${fmt(1 + amt)}" result="__OUT__"/>`
|
|
3383
|
-
);
|
|
3384
|
-
}
|
|
3385
3432
|
if (typeof effects.tint.hue === "number") {
|
|
3386
3433
|
next(
|
|
3387
3434
|
"p8h",
|
|
3388
3435
|
`<feColorMatrix in="__IN__" type="hueRotate" values="${fmt(effects.tint.hue)}" result="__OUT__"/>`
|
|
3389
3436
|
);
|
|
3390
3437
|
}
|
|
3438
|
+
const { slope, intercept } = luminanceTransfer(effects.tint.amt);
|
|
3439
|
+
next(
|
|
3440
|
+
"p8",
|
|
3441
|
+
`<feComponentTransfer in="__IN__" result="__OUT__"><feFuncR type="linear" slope="${fmt(slope)}" intercept="${fmt(intercept)}"/><feFuncG type="linear" slope="${fmt(slope)}" intercept="${fmt(intercept)}"/><feFuncB type="linear" slope="${fmt(slope)}" intercept="${fmt(intercept)}"/></feComponentTransfer>`
|
|
3442
|
+
);
|
|
3391
3443
|
}
|
|
3392
3444
|
if (effects.clrRepl) {
|
|
3393
3445
|
const c = parseHexRgb(effects.clrRepl.color);
|
|
@@ -3461,36 +3513,1849 @@ function buildImageEffectsFilter(effects, idSuffix) {
|
|
|
3461
3513
|
const defsXml = `<filter id="${filterId}" x="-10%" y="-10%" width="120%" height="120%">${primitives.join("")}</filter>`;
|
|
3462
3514
|
return { defsXml, filterId };
|
|
3463
3515
|
}
|
|
3464
|
-
|
|
3465
|
-
|
|
3516
|
+
|
|
3517
|
+
// src/core/utils/color-xml-preservation.ts
|
|
3518
|
+
var COLOR_CHOICE_NAMES = [
|
|
3519
|
+
"srgbClr",
|
|
3520
|
+
"schemeClr",
|
|
3521
|
+
"sysClr",
|
|
3522
|
+
"prstClr",
|
|
3523
|
+
"scrgbClr",
|
|
3524
|
+
"hslClr"
|
|
3525
|
+
];
|
|
3526
|
+
function extractColorChoiceXml(parent) {
|
|
3527
|
+
if (!parent) {
|
|
3528
|
+
return void 0;
|
|
3529
|
+
}
|
|
3530
|
+
for (const [key, value] of Object.entries(parent)) {
|
|
3531
|
+
if (COLOR_CHOICE_NAMES.includes(key.split(":").at(-1) ?? key)) {
|
|
3532
|
+
return { [key]: value };
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
return void 0;
|
|
3466
3536
|
}
|
|
3467
|
-
|
|
3468
|
-
|
|
3537
|
+
|
|
3538
|
+
// src/core/utils/smartart-helpers.ts
|
|
3539
|
+
function buildForest(nodes) {
|
|
3540
|
+
const map = /* @__PURE__ */ new Map();
|
|
3541
|
+
for (const n of nodes) {
|
|
3542
|
+
map.set(n.id, { node: n, children: [] });
|
|
3543
|
+
}
|
|
3544
|
+
const roots = [];
|
|
3545
|
+
for (const n of nodes) {
|
|
3546
|
+
const tn = map.get(n.id);
|
|
3547
|
+
if (n.parentId && map.has(n.parentId)) {
|
|
3548
|
+
map.get(n.parentId).children.push(tn);
|
|
3549
|
+
} else {
|
|
3550
|
+
roots.push(tn);
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
return roots;
|
|
3469
3554
|
}
|
|
3470
|
-
|
|
3471
|
-
|
|
3555
|
+
var MAX_TREE_DEPTH = 256;
|
|
3556
|
+
function treeWidth(t, depth = 0) {
|
|
3557
|
+
if (depth >= MAX_TREE_DEPTH) {
|
|
3558
|
+
return 1;
|
|
3559
|
+
}
|
|
3560
|
+
if (t.children.length === 0) {
|
|
3561
|
+
return 1;
|
|
3562
|
+
}
|
|
3563
|
+
let sum = 0;
|
|
3564
|
+
for (const c of t.children) {
|
|
3565
|
+
sum += treeWidth(c, depth + 1);
|
|
3566
|
+
}
|
|
3567
|
+
return sum;
|
|
3568
|
+
}
|
|
3569
|
+
function treeDepth(t, depth = 0) {
|
|
3570
|
+
if (depth >= MAX_TREE_DEPTH) {
|
|
3571
|
+
return 0;
|
|
3572
|
+
}
|
|
3573
|
+
if (t.children.length === 0) {
|
|
3574
|
+
return 1;
|
|
3575
|
+
}
|
|
3576
|
+
let max = 0;
|
|
3577
|
+
for (const c of t.children) {
|
|
3578
|
+
const d = treeDepth(c, depth + 1);
|
|
3579
|
+
if (d > max) {
|
|
3580
|
+
max = d;
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
return 1 + max;
|
|
3472
3584
|
}
|
|
3473
|
-
function
|
|
3474
|
-
return
|
|
3585
|
+
function getContentNodes(nodes) {
|
|
3586
|
+
return nodes.filter((n) => n.text.length > 0);
|
|
3475
3587
|
}
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3588
|
+
|
|
3589
|
+
// src/core/utils/smartart-layout-engine-algorithms.ts
|
|
3590
|
+
function computeSnakeLayout(nodes, constraints, bounds) {
|
|
3591
|
+
const items = getContentNodes(nodes);
|
|
3592
|
+
if (items.length === 0) {
|
|
3593
|
+
return [];
|
|
3480
3594
|
}
|
|
3481
|
-
|
|
3595
|
+
const cols = constraints.cols ?? Math.min(4, items.length);
|
|
3596
|
+
const rows = Math.ceil(items.length / cols);
|
|
3597
|
+
const sibSp = (constraints.sibSp ?? 0.02) * bounds.width;
|
|
3598
|
+
const secSibSp = (constraints.secSibSp ?? 0.03) * bounds.height;
|
|
3599
|
+
const begPad = (constraints.begPad ?? 0.02) * bounds.width;
|
|
3600
|
+
const endPad = (constraints.endPad ?? 0.02) * bounds.width;
|
|
3601
|
+
const usableW = bounds.width - begPad - endPad;
|
|
3602
|
+
const usableH = bounds.height - begPad - endPad;
|
|
3603
|
+
const cellW = (usableW - sibSp * (cols - 1)) / cols;
|
|
3604
|
+
const cellH = (usableH - secSibSp * (rows - 1)) / rows;
|
|
3605
|
+
const nodeW = constraints.w ? constraints.w * bounds.width : cellW * 0.85;
|
|
3606
|
+
const nodeH = constraints.h ? constraints.h * bounds.height : cellH * 0.7;
|
|
3607
|
+
return items.map((node, i) => {
|
|
3608
|
+
const row = Math.floor(i / cols);
|
|
3609
|
+
const colInRow = i % cols;
|
|
3610
|
+
const col = row % 2 === 0 ? colInRow : cols - 1 - colInRow;
|
|
3611
|
+
const cx = bounds.x + begPad + col * (cellW + sibSp) + cellW / 2;
|
|
3612
|
+
const cy = bounds.y + begPad + row * (cellH + secSibSp) + cellH / 2;
|
|
3613
|
+
return {
|
|
3614
|
+
nodeId: node.id,
|
|
3615
|
+
x: Math.round(cx - nodeW / 2),
|
|
3616
|
+
y: Math.round(cy - nodeH / 2),
|
|
3617
|
+
width: Math.round(nodeW),
|
|
3618
|
+
height: Math.round(nodeH)
|
|
3619
|
+
};
|
|
3620
|
+
});
|
|
3482
3621
|
}
|
|
3483
|
-
function
|
|
3484
|
-
const
|
|
3485
|
-
if (
|
|
3486
|
-
return
|
|
3622
|
+
function computeLinearLayout(nodes, constraints, bounds) {
|
|
3623
|
+
const items = getContentNodes(nodes);
|
|
3624
|
+
if (items.length === 0) {
|
|
3625
|
+
return [];
|
|
3626
|
+
}
|
|
3627
|
+
const isVertical = (constraints.aspectRatio ?? 1) < 0.5;
|
|
3628
|
+
const sibSp = constraints.sibSp ?? 0.03;
|
|
3629
|
+
const begPad = constraints.begPad ?? 0.02;
|
|
3630
|
+
const endPad = constraints.endPad ?? 0.02;
|
|
3631
|
+
if (isVertical) {
|
|
3632
|
+
const padTop = begPad * bounds.height;
|
|
3633
|
+
const padBot = endPad * bounds.height;
|
|
3634
|
+
const gap2 = sibSp * bounds.height;
|
|
3635
|
+
const usableH = bounds.height - padTop - padBot;
|
|
3636
|
+
const nodeH2 = (usableH - gap2 * (items.length - 1)) / items.length;
|
|
3637
|
+
const nodeW2 = constraints.w ? constraints.w * bounds.width : bounds.width * 0.8;
|
|
3638
|
+
const xOffset = bounds.x + (bounds.width - nodeW2) / 2;
|
|
3639
|
+
return items.map((node, i) => ({
|
|
3640
|
+
nodeId: node.id,
|
|
3641
|
+
x: Math.round(xOffset),
|
|
3642
|
+
y: Math.round(bounds.y + padTop + i * (nodeH2 + gap2)),
|
|
3643
|
+
width: Math.round(nodeW2),
|
|
3644
|
+
height: Math.round(nodeH2)
|
|
3645
|
+
}));
|
|
3646
|
+
}
|
|
3647
|
+
const padLeft = begPad * bounds.width;
|
|
3648
|
+
const padRight = endPad * bounds.width;
|
|
3649
|
+
const gap = sibSp * bounds.width;
|
|
3650
|
+
const usableW = bounds.width - padLeft - padRight;
|
|
3651
|
+
const nodeW = (usableW - gap * (items.length - 1)) / items.length;
|
|
3652
|
+
const nodeH = constraints.h ? constraints.h * bounds.height : bounds.height * 0.6;
|
|
3653
|
+
const yOffset = bounds.y + (bounds.height - nodeH) / 2;
|
|
3654
|
+
const shapes = items.map((node, i) => ({
|
|
3655
|
+
nodeId: node.id,
|
|
3656
|
+
x: Math.round(bounds.x + padLeft + i * (nodeW + gap)),
|
|
3657
|
+
y: Math.round(yOffset),
|
|
3658
|
+
width: Math.round(nodeW),
|
|
3659
|
+
height: Math.round(nodeH)
|
|
3660
|
+
}));
|
|
3661
|
+
if (constraints.dir === "rev") {
|
|
3662
|
+
shapes.reverse();
|
|
3663
|
+
const positions = shapes.map((s) => ({ x: s.x, y: s.y }));
|
|
3664
|
+
for (let i = 0; i < shapes.length; i++) {
|
|
3665
|
+
shapes[i].x = positions[shapes.length - 1 - i].x;
|
|
3666
|
+
shapes[i].y = positions[shapes.length - 1 - i].y;
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
return shapes;
|
|
3670
|
+
}
|
|
3671
|
+
function computeHierarchyLayout(nodes, constraints, bounds) {
|
|
3672
|
+
const roots = buildForest(nodes);
|
|
3673
|
+
if (roots.length === 0) {
|
|
3674
|
+
return computeLinearLayout(nodes, constraints, bounds);
|
|
3675
|
+
}
|
|
3676
|
+
const totalLeaves = roots.reduce((s, r) => s + treeWidth(r), 0);
|
|
3677
|
+
const depth = Math.max(...roots.map(treeDepth));
|
|
3678
|
+
const begPad = (constraints.begPad ?? 0.02) * bounds.width;
|
|
3679
|
+
(constraints.sibSp ?? 0.02) * bounds.width;
|
|
3680
|
+
(constraints.secSibSp ?? 0.03) * bounds.height;
|
|
3681
|
+
const usableW = bounds.width - begPad * 2;
|
|
3682
|
+
const usableH = bounds.height - begPad * 2;
|
|
3683
|
+
const cellW = usableW / Math.max(totalLeaves, 1);
|
|
3684
|
+
const cellH = usableH / Math.max(depth, 1);
|
|
3685
|
+
const nodeW = constraints.w ? constraints.w * bounds.width : Math.min(cellW * 0.8, 140);
|
|
3686
|
+
const nodeH = constraints.h ? constraints.h * bounds.height : Math.min(cellH * 0.35, 50);
|
|
3687
|
+
const shapes = [];
|
|
3688
|
+
const MAX_WALK_DEPTH = 256;
|
|
3689
|
+
function walk(t, xOffset, level) {
|
|
3690
|
+
if (level >= MAX_WALK_DEPTH) {
|
|
3691
|
+
return 1;
|
|
3692
|
+
}
|
|
3693
|
+
const w = treeWidth(t);
|
|
3694
|
+
const cx = bounds.x + begPad + (xOffset + w / 2) * cellW;
|
|
3695
|
+
const cy = bounds.y + begPad + level * cellH + cellH / 2;
|
|
3696
|
+
shapes.push({
|
|
3697
|
+
nodeId: t.node.id,
|
|
3698
|
+
x: Math.round(cx - nodeW / 2),
|
|
3699
|
+
y: Math.round(cy - nodeH / 2),
|
|
3700
|
+
width: Math.round(nodeW),
|
|
3701
|
+
height: Math.round(nodeH)
|
|
3702
|
+
});
|
|
3703
|
+
let childOffset = xOffset;
|
|
3704
|
+
for (const child2 of t.children) {
|
|
3705
|
+
walk(child2, childOffset, level + 1);
|
|
3706
|
+
childOffset += treeWidth(child2);
|
|
3707
|
+
}
|
|
3708
|
+
return w;
|
|
3709
|
+
}
|
|
3710
|
+
let offset = 0;
|
|
3711
|
+
for (const root of roots) {
|
|
3712
|
+
offset += walk(root, offset, 0);
|
|
3713
|
+
}
|
|
3714
|
+
return shapes;
|
|
3715
|
+
}
|
|
3716
|
+
function computeCycleLayout(nodes, constraints, bounds) {
|
|
3717
|
+
const items = getContentNodes(nodes);
|
|
3718
|
+
if (items.length === 0) {
|
|
3719
|
+
return [];
|
|
3720
|
+
}
|
|
3721
|
+
const size = Math.min(bounds.width, bounds.height);
|
|
3722
|
+
const cx = bounds.x + bounds.width / 2;
|
|
3723
|
+
const cy = bounds.y + bounds.height / 2;
|
|
3724
|
+
const radius = size * 0.32;
|
|
3725
|
+
const nodeW = constraints.w ? constraints.w * bounds.width : Math.max(size * 0.18, Math.min(size * 0.28, 300 / items.length));
|
|
3726
|
+
const nodeH = constraints.h ? constraints.h * bounds.height : nodeW * 0.6;
|
|
3727
|
+
return items.map((node, i) => {
|
|
3728
|
+
const angle = i / items.length * Math.PI * 2 - Math.PI / 2;
|
|
3729
|
+
const nx = cx + radius * Math.cos(angle) - nodeW / 2;
|
|
3730
|
+
const ny = cy + radius * Math.sin(angle) - nodeH / 2;
|
|
3731
|
+
return {
|
|
3732
|
+
nodeId: node.id,
|
|
3733
|
+
x: Math.round(nx),
|
|
3734
|
+
y: Math.round(ny),
|
|
3735
|
+
width: Math.round(nodeW),
|
|
3736
|
+
height: Math.round(nodeH)
|
|
3737
|
+
};
|
|
3738
|
+
});
|
|
3739
|
+
}
|
|
3740
|
+
function computePyramidLayout(nodes, constraints, bounds) {
|
|
3741
|
+
const items = getContentNodes(nodes);
|
|
3742
|
+
if (items.length === 0) {
|
|
3743
|
+
return [];
|
|
3744
|
+
}
|
|
3745
|
+
const begPad = (constraints.begPad ?? 0.02) * bounds.height;
|
|
3746
|
+
const sibSp = (constraints.sibSp ?? 0.01) * bounds.height;
|
|
3747
|
+
const usableH = bounds.height - begPad * 2;
|
|
3748
|
+
const bandH = (usableH - sibSp * (items.length - 1)) / items.length;
|
|
3749
|
+
const maxW = bounds.width - begPad * 2;
|
|
3750
|
+
return items.map((node, i) => {
|
|
3751
|
+
const widthFraction = 0.3 + i / Math.max(items.length - 1, 1) * 0.7;
|
|
3752
|
+
const w = maxW * widthFraction;
|
|
3753
|
+
const x = bounds.x + (bounds.width - w) / 2;
|
|
3754
|
+
const y = bounds.y + begPad + i * (bandH + sibSp);
|
|
3755
|
+
return {
|
|
3756
|
+
nodeId: node.id,
|
|
3757
|
+
x: Math.round(x),
|
|
3758
|
+
y: Math.round(y),
|
|
3759
|
+
width: Math.round(w),
|
|
3760
|
+
height: Math.round(bandH)
|
|
3761
|
+
};
|
|
3762
|
+
});
|
|
3763
|
+
}
|
|
3764
|
+
function computeMatrixLayout(nodes, constraints, bounds) {
|
|
3765
|
+
const items = getContentNodes(nodes);
|
|
3766
|
+
if (items.length === 0) {
|
|
3767
|
+
return [];
|
|
3768
|
+
}
|
|
3769
|
+
const cols = constraints.cols ?? Math.ceil(Math.sqrt(items.length));
|
|
3770
|
+
const rows = Math.ceil(items.length / cols);
|
|
3771
|
+
const begPad = (constraints.begPad ?? 0.02) * Math.min(bounds.width, bounds.height);
|
|
3772
|
+
const sibSp = (constraints.sibSp ?? 0.02) * bounds.width;
|
|
3773
|
+
const secSibSp = (constraints.secSibSp ?? 0.02) * bounds.height;
|
|
3774
|
+
const usableW = bounds.width - begPad * 2;
|
|
3775
|
+
const usableH = bounds.height - begPad * 2;
|
|
3776
|
+
const cellW = (usableW - sibSp * (cols - 1)) / cols;
|
|
3777
|
+
const cellH = (usableH - secSibSp * (rows - 1)) / rows;
|
|
3778
|
+
return items.map((node, i) => {
|
|
3779
|
+
const col = i % cols;
|
|
3780
|
+
const row = Math.floor(i / cols);
|
|
3781
|
+
return {
|
|
3782
|
+
nodeId: node.id,
|
|
3783
|
+
x: Math.round(bounds.x + begPad + col * (cellW + sibSp)),
|
|
3784
|
+
y: Math.round(bounds.y + begPad + row * (cellH + secSibSp)),
|
|
3785
|
+
width: Math.round(cellW),
|
|
3786
|
+
height: Math.round(cellH)
|
|
3787
|
+
};
|
|
3788
|
+
});
|
|
3789
|
+
}
|
|
3790
|
+
function computeByLayoutType(type, nodes, constraints, bounds) {
|
|
3791
|
+
switch (type) {
|
|
3792
|
+
case "list":
|
|
3793
|
+
return computeLinearLayout(nodes, { ...constraints, aspectRatio: 0.3 }, bounds);
|
|
3794
|
+
case "cycle":
|
|
3795
|
+
case "relationship":
|
|
3796
|
+
case "venn":
|
|
3797
|
+
case "target":
|
|
3798
|
+
return computeCycleLayout(nodes, constraints, bounds);
|
|
3799
|
+
case "hierarchy":
|
|
3800
|
+
return computeHierarchyLayout(nodes, constraints, bounds);
|
|
3801
|
+
case "matrix":
|
|
3802
|
+
return computeMatrixLayout(nodes, constraints, bounds);
|
|
3803
|
+
case "pyramid":
|
|
3804
|
+
case "funnel":
|
|
3805
|
+
return computePyramidLayout(nodes, constraints, bounds);
|
|
3806
|
+
case "bending":
|
|
3807
|
+
return computeSnakeLayout(nodes, constraints, bounds);
|
|
3808
|
+
case "gear":
|
|
3809
|
+
return computeCycleLayout(nodes, { ...constraints, w: 0.2 }, bounds);
|
|
3810
|
+
default:
|
|
3811
|
+
return computeLinearLayout(nodes, constraints, bounds);
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
function resolveLayoutTypeFromString(value) {
|
|
3815
|
+
const type = value?.toLowerCase() ?? "";
|
|
3816
|
+
if (type.includes("hierarchy") || type.includes("org")) {
|
|
3817
|
+
return "hierarchy";
|
|
3818
|
+
}
|
|
3819
|
+
if (type.includes("cycle") || type.includes("radial")) {
|
|
3820
|
+
return "cycle";
|
|
3821
|
+
}
|
|
3822
|
+
if (type.includes("snake") || type.includes("bending") || type.includes("zigzag")) {
|
|
3823
|
+
return "bending";
|
|
3824
|
+
}
|
|
3825
|
+
if (type.includes("process") || type.includes("chevron") || type.includes("arrow")) {
|
|
3826
|
+
return "process";
|
|
3827
|
+
}
|
|
3828
|
+
if (type.includes("venn") || type.includes("relationship")) {
|
|
3829
|
+
return "relationship";
|
|
3830
|
+
}
|
|
3831
|
+
if (type.includes("matrix")) {
|
|
3832
|
+
return "matrix";
|
|
3833
|
+
}
|
|
3834
|
+
if (type.includes("pyramid")) {
|
|
3835
|
+
return "pyramid";
|
|
3836
|
+
}
|
|
3837
|
+
if (type.includes("funnel")) {
|
|
3838
|
+
return "funnel";
|
|
3839
|
+
}
|
|
3840
|
+
if (type.includes("timeline")) {
|
|
3841
|
+
return "timeline";
|
|
3842
|
+
}
|
|
3843
|
+
if (type.includes("target") || type.includes("bullseye")) {
|
|
3844
|
+
return "target";
|
|
3845
|
+
}
|
|
3846
|
+
if (type.includes("gear")) {
|
|
3847
|
+
return "gear";
|
|
3848
|
+
}
|
|
3849
|
+
return "list";
|
|
3850
|
+
}
|
|
3851
|
+
function getDefaultShapeType(type) {
|
|
3852
|
+
if (["cycle", "target", "gear", "relationship", "venn"].includes(type)) {
|
|
3853
|
+
return "ellipse";
|
|
3854
|
+
}
|
|
3855
|
+
if (type === "chevron") {
|
|
3856
|
+
return "chevron";
|
|
3857
|
+
}
|
|
3858
|
+
if (type === "pyramid" || type === "funnel") {
|
|
3859
|
+
return "trapezoid";
|
|
3860
|
+
}
|
|
3861
|
+
return "roundRect";
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3864
|
+
// src/core/utils/smartart-layout-rule-evaluator.ts
|
|
3865
|
+
var TYPES = {
|
|
3866
|
+
w: "w",
|
|
3867
|
+
h: "h",
|
|
3868
|
+
primfontsz: "primFontSz",
|
|
3869
|
+
sp: "sp",
|
|
3870
|
+
sibsp: "sibSp",
|
|
3871
|
+
secsibsp: "secSibSp",
|
|
3872
|
+
begpad: "begPad",
|
|
3873
|
+
endpad: "endPad",
|
|
3874
|
+
cols: "cols",
|
|
3875
|
+
aspectratio: "aspectRatio",
|
|
3876
|
+
ar: "aspectRatio",
|
|
3877
|
+
dir: "dir"
|
|
3878
|
+
};
|
|
3879
|
+
function finite(value) {
|
|
3880
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
3881
|
+
}
|
|
3882
|
+
function nextValue(current, rule) {
|
|
3883
|
+
let value = finite(rule.val) ? rule.val : current;
|
|
3884
|
+
if (!finite(value) && finite(rule.max)) {
|
|
3885
|
+
value = rule.max;
|
|
3886
|
+
}
|
|
3887
|
+
if (!finite(value)) {
|
|
3888
|
+
return void 0;
|
|
3889
|
+
}
|
|
3890
|
+
if (finite(rule.fact)) {
|
|
3891
|
+
value *= rule.fact;
|
|
3892
|
+
}
|
|
3893
|
+
if (finite(rule.max)) {
|
|
3894
|
+
value = Math.min(value, rule.max);
|
|
3895
|
+
}
|
|
3896
|
+
return Number.isFinite(value) ? value : void 0;
|
|
3897
|
+
}
|
|
3898
|
+
function pointTypeMatches(node, filter) {
|
|
3899
|
+
if (!filter || filter === "all") {
|
|
3900
|
+
return true;
|
|
3901
|
+
}
|
|
3902
|
+
const values = new Set(filter.split(/\s+/u).map((value) => value.toLowerCase()));
|
|
3903
|
+
const type = (node.nodeType || "node").toLowerCase();
|
|
3904
|
+
if (values.has(type)) {
|
|
3905
|
+
return true;
|
|
3906
|
+
}
|
|
3907
|
+
if (values.has("node") && (type === "node" || type === "norm")) {
|
|
3908
|
+
return true;
|
|
3909
|
+
}
|
|
3910
|
+
if (values.has("nonasst") && type !== "asst") {
|
|
3911
|
+
return true;
|
|
3912
|
+
}
|
|
3913
|
+
return values.has("nonnorm") && type !== "norm" && type !== "node";
|
|
3914
|
+
}
|
|
3915
|
+
function relationshipMatches(node, rule) {
|
|
3916
|
+
const relation = rule.for?.toLowerCase();
|
|
3917
|
+
if (!relation) {
|
|
3918
|
+
return true;
|
|
3919
|
+
}
|
|
3920
|
+
if (relation === "self") {
|
|
3921
|
+
return !node.parentId;
|
|
3922
|
+
}
|
|
3923
|
+
if (relation === "ch" || relation === "des") {
|
|
3924
|
+
return Boolean(node.parentId);
|
|
3925
|
+
}
|
|
3926
|
+
return true;
|
|
3927
|
+
}
|
|
3928
|
+
function matchingNodes(rule, nodes) {
|
|
3929
|
+
const named = rule.forName?.trim();
|
|
3930
|
+
const exactName = named ? nodes.some((node) => node.id === named) : false;
|
|
3931
|
+
return nodes.filter(
|
|
3932
|
+
(node) => (!exactName || node.id === named) && pointTypeMatches(node, rule.ptType) && relationshipMatches(node, rule)
|
|
3933
|
+
);
|
|
3934
|
+
}
|
|
3935
|
+
function applyNumeric(target, type, rule, fallback) {
|
|
3936
|
+
const value = nextValue(target[type] ?? fallback, rule);
|
|
3937
|
+
if (value === void 0) {
|
|
3938
|
+
return;
|
|
3939
|
+
}
|
|
3940
|
+
target[type] = type === "cols" ? Math.max(1, Math.round(value)) : Math.max(0, value);
|
|
3941
|
+
}
|
|
3942
|
+
function evaluateLayoutRules(base, rules, nodes) {
|
|
3943
|
+
const constraints = { ...base };
|
|
3944
|
+
const nodeConstraints = /* @__PURE__ */ new Map();
|
|
3945
|
+
for (const rule of rules) {
|
|
3946
|
+
const type = TYPES[rule.type.toLowerCase()];
|
|
3947
|
+
if (!type) {
|
|
3948
|
+
continue;
|
|
3949
|
+
}
|
|
3950
|
+
const matches = matchingNodes(rule, nodes);
|
|
3951
|
+
const canTargetNode = type === "w" || type === "h" || type === "primFontSz";
|
|
3952
|
+
const targeted = canTargetNode && Boolean(rule.for || rule.forName || rule.ptType);
|
|
3953
|
+
if (targeted && matches.length > 0) {
|
|
3954
|
+
for (const node of matches) {
|
|
3955
|
+
const override = nodeConstraints.get(node.id) ?? {};
|
|
3956
|
+
applyNumeric(override, type, rule, constraints[type]);
|
|
3957
|
+
nodeConstraints.set(node.id, override);
|
|
3958
|
+
}
|
|
3959
|
+
} else if (type === "dir") {
|
|
3960
|
+
const value = nextValue(constraints.dir === "rev" ? 1 : 0, rule);
|
|
3961
|
+
if (value !== void 0) {
|
|
3962
|
+
constraints.dir = value > 0 ? "rev" : "norm";
|
|
3963
|
+
}
|
|
3964
|
+
} else {
|
|
3965
|
+
applyNumeric(constraints, type, rule);
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3968
|
+
if (constraints.sp !== void 0 && constraints.sibSp === void 0) {
|
|
3969
|
+
constraints.sibSp = constraints.sp;
|
|
3970
|
+
}
|
|
3971
|
+
return { constraints, nodeConstraints };
|
|
3972
|
+
}
|
|
3973
|
+
function applyNodeLayoutRules(shapes, overrides, bounds, global) {
|
|
3974
|
+
return shapes.map((shape) => {
|
|
3975
|
+
const rule = overrides.get(shape.nodeId);
|
|
3976
|
+
const widthRule = rule?.w ?? global.w;
|
|
3977
|
+
const heightRule = rule?.h ?? global.h;
|
|
3978
|
+
const width = widthRule !== void 0 ? widthRule * bounds.width : shape.width;
|
|
3979
|
+
const height = heightRule !== void 0 ? heightRule * bounds.height : shape.height;
|
|
3980
|
+
return {
|
|
3981
|
+
...shape,
|
|
3982
|
+
x: Math.round(shape.x + (shape.width - width) / 2),
|
|
3983
|
+
y: Math.round(shape.y + (shape.height - height) / 2),
|
|
3984
|
+
width: Math.round(width),
|
|
3985
|
+
height: Math.round(height),
|
|
3986
|
+
fontSize: rule?.primFontSz ?? global.primFontSz
|
|
3987
|
+
};
|
|
3988
|
+
});
|
|
3989
|
+
}
|
|
3990
|
+
|
|
3991
|
+
// src/core/core/runtime/smartart-text-paragraphs.ts
|
|
3992
|
+
function smartArtParagraphsText(paragraphs) {
|
|
3993
|
+
return paragraphs.map(
|
|
3994
|
+
(paragraph) => paragraph.items.map((item) => {
|
|
3995
|
+
if (item.kind === "run") {
|
|
3996
|
+
return item.run.text;
|
|
3997
|
+
}
|
|
3998
|
+
if (item.kind === "field") {
|
|
3999
|
+
return item.text;
|
|
4000
|
+
}
|
|
4001
|
+
if (item.kind === "break") {
|
|
4002
|
+
return "\n";
|
|
4003
|
+
}
|
|
4004
|
+
return item.kind === "tab" ? " " : "";
|
|
4005
|
+
}).join("")
|
|
4006
|
+
).join("\n");
|
|
4007
|
+
}
|
|
4008
|
+
|
|
4009
|
+
// src/core/core/runtime/smartart-text-reconciliation.ts
|
|
4010
|
+
function clone(value) {
|
|
4011
|
+
return JSON.parse(JSON.stringify(value));
|
|
4012
|
+
}
|
|
4013
|
+
function itemText(item) {
|
|
4014
|
+
if (item.kind === "run") {
|
|
4015
|
+
return item.run.text;
|
|
4016
|
+
}
|
|
4017
|
+
return item.kind === "field" ? item.text : void 0;
|
|
4018
|
+
}
|
|
4019
|
+
function setItemText(item, text) {
|
|
4020
|
+
if (item.kind === "run") {
|
|
4021
|
+
item.run.text = text;
|
|
4022
|
+
} else if (item.kind === "field") {
|
|
4023
|
+
item.text = text;
|
|
4024
|
+
}
|
|
4025
|
+
}
|
|
4026
|
+
function commonEdges(before, after) {
|
|
4027
|
+
let prefix = 0;
|
|
4028
|
+
while (prefix < before.length && prefix < after.length && before[prefix] === after[prefix]) {
|
|
4029
|
+
prefix++;
|
|
4030
|
+
}
|
|
4031
|
+
let suffix = 0;
|
|
4032
|
+
while (suffix < before.length - prefix && suffix < after.length - prefix && before[before.length - 1 - suffix] === after[after.length - 1 - suffix]) {
|
|
4033
|
+
suffix++;
|
|
4034
|
+
}
|
|
4035
|
+
return { prefix, suffix };
|
|
4036
|
+
}
|
|
4037
|
+
function separators(text) {
|
|
4038
|
+
return [...text].filter((character) => character === "\n" || character === " ").join("");
|
|
4039
|
+
}
|
|
4040
|
+
function textRegions(paragraphs) {
|
|
4041
|
+
const regions = [];
|
|
4042
|
+
let current = [];
|
|
4043
|
+
for (const paragraph of paragraphs) {
|
|
4044
|
+
for (const item of paragraph.items) {
|
|
4045
|
+
if (item.kind === "tab" || item.kind === "break") {
|
|
4046
|
+
regions.push(current);
|
|
4047
|
+
current = [];
|
|
4048
|
+
} else if (itemText(item) !== void 0) {
|
|
4049
|
+
current.push(item);
|
|
4050
|
+
}
|
|
4051
|
+
}
|
|
4052
|
+
regions.push(current);
|
|
4053
|
+
current = [];
|
|
4054
|
+
}
|
|
4055
|
+
return regions;
|
|
4056
|
+
}
|
|
4057
|
+
function desiredRegions(text) {
|
|
4058
|
+
return text.split(/[\t\n]/u);
|
|
4059
|
+
}
|
|
4060
|
+
function reconcileRegion(items, desired) {
|
|
4061
|
+
if (items.length === 0) {
|
|
4062
|
+
return;
|
|
4063
|
+
}
|
|
4064
|
+
const texts = items.map((item) => itemText(item) ?? "");
|
|
4065
|
+
const before = texts.join("");
|
|
4066
|
+
if (before === desired) {
|
|
4067
|
+
return;
|
|
4068
|
+
}
|
|
4069
|
+
const { prefix, suffix } = commonEdges(before, desired);
|
|
4070
|
+
const removeStart = prefix;
|
|
4071
|
+
const removeEnd = before.length - suffix;
|
|
4072
|
+
const insertion = desired.slice(prefix, desired.length - suffix);
|
|
4073
|
+
let offset = 0;
|
|
4074
|
+
const affected = [];
|
|
4075
|
+
for (let index = 0; index < texts.length; index++) {
|
|
4076
|
+
const start = offset;
|
|
4077
|
+
const end = start + texts[index].length;
|
|
4078
|
+
const localStart = Math.max(0, removeStart - start);
|
|
4079
|
+
const localEnd = Math.min(texts[index].length, removeEnd - start);
|
|
4080
|
+
if (localEnd > localStart) {
|
|
4081
|
+
affected.push({ index, start: localStart, end: localEnd, removed: localEnd - localStart });
|
|
4082
|
+
}
|
|
4083
|
+
offset = end;
|
|
4084
|
+
}
|
|
4085
|
+
if (affected.length === 0) {
|
|
4086
|
+
let owner = 0;
|
|
4087
|
+
let cursor = 0;
|
|
4088
|
+
for (let index = 0; index < texts.length; index++) {
|
|
4089
|
+
if (removeStart <= cursor + texts[index].length) {
|
|
4090
|
+
owner = index;
|
|
4091
|
+
break;
|
|
4092
|
+
}
|
|
4093
|
+
cursor += texts[index].length;
|
|
4094
|
+
}
|
|
4095
|
+
affected.push({
|
|
4096
|
+
index: owner,
|
|
4097
|
+
start: removeStart - cursor,
|
|
4098
|
+
end: removeStart - cursor,
|
|
4099
|
+
removed: 0
|
|
4100
|
+
});
|
|
4101
|
+
}
|
|
4102
|
+
let insertionOffset = 0;
|
|
4103
|
+
for (let affectedIndex = 0; affectedIndex < affected.length; affectedIndex++) {
|
|
4104
|
+
const entry = affected[affectedIndex];
|
|
4105
|
+
const isLast = affectedIndex === affected.length - 1;
|
|
4106
|
+
const take = isLast ? insertion.length - insertionOffset : Math.min(entry.removed, insertion.length - insertionOffset);
|
|
4107
|
+
const allocated = insertion.slice(insertionOffset, insertionOffset + Math.max(0, take));
|
|
4108
|
+
insertionOffset += Math.max(0, take);
|
|
4109
|
+
const original = texts[entry.index];
|
|
4110
|
+
setItemText(
|
|
4111
|
+
items[entry.index],
|
|
4112
|
+
original.slice(0, entry.start) + allocated + original.slice(entry.end)
|
|
4113
|
+
);
|
|
4114
|
+
}
|
|
4115
|
+
}
|
|
4116
|
+
function reconcileWithoutStructuralChange(paragraphs, desired) {
|
|
4117
|
+
const regions = textRegions(paragraphs);
|
|
4118
|
+
const targets = desiredRegions(desired);
|
|
4119
|
+
for (let index = 0; index < regions.length; index++) {
|
|
4120
|
+
reconcileRegion(regions[index], targets[index] ?? "");
|
|
4121
|
+
}
|
|
4122
|
+
}
|
|
4123
|
+
function atoms(paragraphs) {
|
|
4124
|
+
const result = [];
|
|
4125
|
+
for (let paragraph = 0; paragraph < paragraphs.length; paragraph++) {
|
|
4126
|
+
for (let item = 0; item < paragraphs[paragraph].items.length; item++) {
|
|
4127
|
+
const entry = paragraphs[paragraph].items[item];
|
|
4128
|
+
const text = itemText(entry);
|
|
4129
|
+
if (text !== void 0) {
|
|
4130
|
+
for (let character = 0; character < text.length; character++) {
|
|
4131
|
+
result.push({ kind: "text", paragraph, item, character });
|
|
4132
|
+
}
|
|
4133
|
+
} else if (entry.kind === "tab" || entry.kind === "break") {
|
|
4134
|
+
result.push({ kind: "item", paragraph, item });
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
if (paragraph < paragraphs.length - 1) {
|
|
4138
|
+
result.push({ kind: "paragraph", paragraph });
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
return result;
|
|
4142
|
+
}
|
|
4143
|
+
function removeRange(paragraphs, start, end) {
|
|
4144
|
+
const selected = atoms(paragraphs).slice(start, end);
|
|
4145
|
+
for (const atom of selected.reverse()) {
|
|
4146
|
+
if (atom.kind === "text") {
|
|
4147
|
+
const item = paragraphs[atom.paragraph]?.items[atom.item];
|
|
4148
|
+
const text = item ? itemText(item) : void 0;
|
|
4149
|
+
if (item && text !== void 0) {
|
|
4150
|
+
setItemText(item, text.slice(0, atom.character) + text.slice(atom.character + 1));
|
|
4151
|
+
}
|
|
4152
|
+
} else if (atom.kind === "item") {
|
|
4153
|
+
paragraphs[atom.paragraph]?.items.splice(atom.item, 1);
|
|
4154
|
+
} else {
|
|
4155
|
+
const left = paragraphs[atom.paragraph];
|
|
4156
|
+
const right = paragraphs[atom.paragraph + 1];
|
|
4157
|
+
if (left && right) {
|
|
4158
|
+
left.items.push(...right.items);
|
|
4159
|
+
left.endParaRPr = right.endParaRPr ?? left.endParaRPr;
|
|
4160
|
+
paragraphs.splice(atom.paragraph + 1, 1);
|
|
4161
|
+
}
|
|
4162
|
+
}
|
|
4163
|
+
}
|
|
4164
|
+
}
|
|
4165
|
+
function textTemplate(paragraph) {
|
|
4166
|
+
const existing = paragraph.items.find((item) => itemText(item) !== void 0);
|
|
4167
|
+
return existing ? clone(existing) : { kind: "run", run: { text: "" } };
|
|
4168
|
+
}
|
|
4169
|
+
function insertAt(paragraphs, offset, value) {
|
|
4170
|
+
const location = atoms(paragraphs)[offset - 1];
|
|
4171
|
+
let paragraphIndex = location?.paragraph ?? 0;
|
|
4172
|
+
let itemIndex = location?.kind === "paragraph" ? paragraphs[paragraphIndex].items.length : location?.item ?? -1;
|
|
4173
|
+
let textOffset = location?.kind === "text" ? location.character + 1 : void 0;
|
|
4174
|
+
for (const part of value.split(/([\t\n])/u).filter((segment) => segment.length > 0)) {
|
|
4175
|
+
const paragraph = paragraphs[paragraphIndex] ??= { items: [] };
|
|
4176
|
+
let splitRight;
|
|
4177
|
+
if ((part === " " || part === "\n") && textOffset !== void 0) {
|
|
4178
|
+
const item = paragraph.items[itemIndex];
|
|
4179
|
+
const text = item ? itemText(item) : void 0;
|
|
4180
|
+
if (item && text !== void 0 && textOffset > 0 && textOffset < text.length) {
|
|
4181
|
+
splitRight = clone(item);
|
|
4182
|
+
setItemText(item, text.slice(0, textOffset));
|
|
4183
|
+
setItemText(splitRight, text.slice(textOffset));
|
|
4184
|
+
paragraph.items.splice(itemIndex + 1, 0, splitRight);
|
|
4185
|
+
}
|
|
4186
|
+
}
|
|
4187
|
+
if (part === " ") {
|
|
4188
|
+
paragraph.items.splice(++itemIndex, 0, { kind: "tab" });
|
|
4189
|
+
if (splitRight) {
|
|
4190
|
+
itemIndex++;
|
|
4191
|
+
textOffset = 0;
|
|
4192
|
+
} else {
|
|
4193
|
+
textOffset = void 0;
|
|
4194
|
+
}
|
|
4195
|
+
} else if (part === "\n") {
|
|
4196
|
+
const rightItems = paragraph.items.splice(itemIndex + 1);
|
|
4197
|
+
const next = clone(paragraph);
|
|
4198
|
+
next.items = rightItems;
|
|
4199
|
+
paragraphs.splice(paragraphIndex + 1, 0, next);
|
|
4200
|
+
paragraphIndex++;
|
|
4201
|
+
itemIndex = -1;
|
|
4202
|
+
textOffset = void 0;
|
|
4203
|
+
} else {
|
|
4204
|
+
let item = paragraph.items[itemIndex];
|
|
4205
|
+
if (!item || itemText(item) === void 0) {
|
|
4206
|
+
item = textTemplate(paragraph);
|
|
4207
|
+
setItemText(item, "");
|
|
4208
|
+
paragraph.items.splice(++itemIndex, 0, item);
|
|
4209
|
+
}
|
|
4210
|
+
const text = itemText(item) ?? "";
|
|
4211
|
+
const insertionPoint = textOffset ?? text.length;
|
|
4212
|
+
setItemText(item, text.slice(0, insertionPoint) + part + text.slice(insertionPoint));
|
|
4213
|
+
textOffset = insertionPoint + part.length;
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
function reconcileSmartArtTextParagraphs(paragraphs, desired) {
|
|
4218
|
+
const result = clone(paragraphs);
|
|
4219
|
+
const before = smartArtParagraphsText(result);
|
|
4220
|
+
if (before === desired) {
|
|
4221
|
+
return result;
|
|
4222
|
+
}
|
|
4223
|
+
if (separators(before) === separators(desired)) {
|
|
4224
|
+
reconcileWithoutStructuralChange(result, desired);
|
|
4225
|
+
return result;
|
|
4226
|
+
}
|
|
4227
|
+
const { prefix, suffix } = commonEdges(before, desired);
|
|
4228
|
+
removeRange(result, prefix, before.length - suffix);
|
|
4229
|
+
insertAt(result, prefix, desired.slice(prefix, desired.length - suffix));
|
|
4230
|
+
return result.length > 0 ? result : [{ items: [] }];
|
|
4231
|
+
}
|
|
4232
|
+
|
|
4233
|
+
// src/core/utils/paragraph-properties-parser.ts
|
|
4234
|
+
var EMU_PER_PX2 = 9525;
|
|
4235
|
+
function parseBoolAttr(value) {
|
|
4236
|
+
if (value === void 0 || value === null) {
|
|
4237
|
+
return void 0;
|
|
4238
|
+
}
|
|
4239
|
+
const normalized = String(value).trim().toLowerCase();
|
|
4240
|
+
if (normalized.length === 0) {
|
|
4241
|
+
return void 0;
|
|
4242
|
+
}
|
|
4243
|
+
return normalized === "1" || normalized === "true";
|
|
4244
|
+
}
|
|
4245
|
+
function pointsToPixels(points) {
|
|
4246
|
+
return points * (96 / 72);
|
|
4247
|
+
}
|
|
4248
|
+
var ALIGN_MAP = {
|
|
4249
|
+
l: "left",
|
|
4250
|
+
ctr: "center",
|
|
4251
|
+
r: "right",
|
|
4252
|
+
just: "justify",
|
|
4253
|
+
justify: "justify",
|
|
4254
|
+
justLow: "justLow",
|
|
4255
|
+
dist: "dist",
|
|
4256
|
+
thaiDist: "thaiDist"
|
|
4257
|
+
};
|
|
4258
|
+
function parseAlignmentAttr(algn) {
|
|
4259
|
+
if (!algn) {
|
|
4260
|
+
return void 0;
|
|
4261
|
+
}
|
|
4262
|
+
return ALIGN_MAP[algn] || void 0;
|
|
4263
|
+
}
|
|
4264
|
+
function parseParagraphSpacingPx(spacingNode) {
|
|
4265
|
+
if (!spacingNode) {
|
|
4266
|
+
return void 0;
|
|
4267
|
+
}
|
|
4268
|
+
const spcPts = spacingNode["a:spcPts"];
|
|
4269
|
+
const raw = Number.parseInt(String(spcPts?.["@_val"] || ""), 10);
|
|
4270
|
+
if (Number.isFinite(raw)) {
|
|
4271
|
+
return pointsToPixels(raw / 100);
|
|
4272
|
+
}
|
|
4273
|
+
return void 0;
|
|
4274
|
+
}
|
|
4275
|
+
function parseLineSpacingMultiplier(lineSpacingNode) {
|
|
4276
|
+
if (!lineSpacingNode) {
|
|
4277
|
+
return void 0;
|
|
4278
|
+
}
|
|
4279
|
+
const spcPct = lineSpacingNode["a:spcPct"];
|
|
4280
|
+
const raw = Number.parseInt(String(spcPct?.["@_val"] || ""), 10);
|
|
4281
|
+
if (Number.isFinite(raw)) {
|
|
4282
|
+
return Math.max(0.1, Math.min(5, raw / 1e5));
|
|
4283
|
+
}
|
|
4284
|
+
return void 0;
|
|
4285
|
+
}
|
|
4286
|
+
function parseLineSpacingExactPt(lineSpacingNode) {
|
|
4287
|
+
if (!lineSpacingNode) {
|
|
4288
|
+
return void 0;
|
|
4289
|
+
}
|
|
4290
|
+
const spcPts = lineSpacingNode["a:spcPts"];
|
|
4291
|
+
const raw = Number.parseInt(String(spcPts?.["@_val"] || ""), 10);
|
|
4292
|
+
if (Number.isFinite(raw) && raw > 0) {
|
|
4293
|
+
return raw / 100;
|
|
3487
4294
|
}
|
|
3488
|
-
|
|
4295
|
+
return void 0;
|
|
4296
|
+
}
|
|
4297
|
+
function parseParagraphMargins(pPr) {
|
|
4298
|
+
const result = {};
|
|
4299
|
+
if (!pPr) {
|
|
4300
|
+
return result;
|
|
4301
|
+
}
|
|
4302
|
+
if (pPr["@_marL"] !== void 0) {
|
|
4303
|
+
const marL = Number.parseInt(String(pPr["@_marL"]), 10);
|
|
4304
|
+
if (Number.isFinite(marL)) {
|
|
4305
|
+
result.paragraphMarginLeft = marL / EMU_PER_PX2;
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4308
|
+
if (pPr["@_marR"] !== void 0) {
|
|
4309
|
+
const marR = Number.parseInt(String(pPr["@_marR"]), 10);
|
|
4310
|
+
if (Number.isFinite(marR)) {
|
|
4311
|
+
result.paragraphMarginRight = marR / EMU_PER_PX2;
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
if (pPr["@_indent"] !== void 0) {
|
|
4315
|
+
const indent = Number.parseInt(String(pPr["@_indent"]), 10);
|
|
4316
|
+
if (Number.isFinite(indent)) {
|
|
4317
|
+
result.paragraphIndent = indent / EMU_PER_PX2;
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
return result;
|
|
4321
|
+
}
|
|
4322
|
+
function parseParagraphRtl(pPr) {
|
|
4323
|
+
if (!pPr) {
|
|
4324
|
+
return void 0;
|
|
4325
|
+
}
|
|
4326
|
+
return parseBoolAttr(pPr["@_rtl"]);
|
|
4327
|
+
}
|
|
4328
|
+
function parseParagraphLevel(pPr) {
|
|
4329
|
+
if (!pPr) {
|
|
4330
|
+
return 0;
|
|
4331
|
+
}
|
|
4332
|
+
const level = Number.parseInt(String(pPr["@_lvl"] || "0"), 10);
|
|
4333
|
+
return Number.isFinite(level) ? Math.min(Math.max(level, 0), 8) : 0;
|
|
4334
|
+
}
|
|
4335
|
+
function parseTabStops(pPr) {
|
|
4336
|
+
if (!pPr) {
|
|
4337
|
+
return void 0;
|
|
4338
|
+
}
|
|
4339
|
+
const tabLst = pPr["a:tabLst"];
|
|
4340
|
+
if (!tabLst) {
|
|
4341
|
+
return void 0;
|
|
4342
|
+
}
|
|
4343
|
+
const tabNodes = Array.isArray(tabLst["a:tab"]) ? tabLst["a:tab"] : tabLst["a:tab"] ? [tabLst["a:tab"]] : [];
|
|
4344
|
+
if (tabNodes.length === 0) {
|
|
4345
|
+
return void 0;
|
|
4346
|
+
}
|
|
4347
|
+
return tabNodes.filter((t) => t?.["@_pos"] !== void 0).map((t) => {
|
|
4348
|
+
const posRaw = Number.parseInt(String(t["@_pos"]), 10);
|
|
4349
|
+
const position = Number.isFinite(posRaw) ? posRaw / EMU_PER_PX2 : 0;
|
|
4350
|
+
const algn = String(t["@_algn"] || "l").trim();
|
|
4351
|
+
const align = algn === "ctr" || algn === "r" || algn === "dec" ? algn : "l";
|
|
4352
|
+
const leaderVal = String(t["@_leader"] || "").trim();
|
|
4353
|
+
const leader = leaderVal === "dot" || leaderVal === "hyphen" || leaderVal === "underscore" ? leaderVal : void 0;
|
|
4354
|
+
return { position, align, ...leader ? { leader } : {} };
|
|
4355
|
+
});
|
|
4356
|
+
}
|
|
4357
|
+
function parseParagraphExtraAttributes(pPr) {
|
|
4358
|
+
const result = {};
|
|
4359
|
+
if (!pPr) {
|
|
4360
|
+
return result;
|
|
4361
|
+
}
|
|
4362
|
+
if (pPr["@_defTabSz"] !== void 0) {
|
|
4363
|
+
const defTabSz = Number.parseInt(String(pPr["@_defTabSz"]), 10);
|
|
4364
|
+
if (Number.isFinite(defTabSz)) {
|
|
4365
|
+
result.defaultTabSize = defTabSz / EMU_PER_PX2;
|
|
4366
|
+
}
|
|
4367
|
+
}
|
|
4368
|
+
const eaVal = parseBoolAttr(pPr["@_eaLnBrk"]);
|
|
4369
|
+
if (eaVal !== void 0) {
|
|
4370
|
+
result.eaLineBreak = eaVal;
|
|
4371
|
+
}
|
|
4372
|
+
const latVal = parseBoolAttr(pPr["@_latinLnBrk"]);
|
|
4373
|
+
if (latVal !== void 0) {
|
|
4374
|
+
result.latinLineBreak = latVal;
|
|
4375
|
+
}
|
|
4376
|
+
if (pPr["@_fontAlgn"] !== void 0) {
|
|
4377
|
+
const fontAlgn = String(pPr["@_fontAlgn"]).trim();
|
|
4378
|
+
if (fontAlgn) {
|
|
4379
|
+
result.fontAlignment = fontAlgn;
|
|
4380
|
+
}
|
|
4381
|
+
}
|
|
4382
|
+
const hpVal = parseBoolAttr(pPr["@_hangingPunct"]);
|
|
4383
|
+
if (hpVal !== void 0) {
|
|
4384
|
+
result.hangingPunctuation = hpVal;
|
|
4385
|
+
}
|
|
4386
|
+
return result;
|
|
4387
|
+
}
|
|
4388
|
+
function parseBulletInfo(pPr, paragraphIndex = 0) {
|
|
4389
|
+
if (!pPr) {
|
|
4390
|
+
return null;
|
|
4391
|
+
}
|
|
4392
|
+
if (pPr["a:buNone"]) {
|
|
4393
|
+
return { none: true };
|
|
4394
|
+
}
|
|
4395
|
+
const buFont = pPr["a:buFont"];
|
|
4396
|
+
const fontFamily = buFont?.["@_typeface"] ? String(buFont["@_typeface"]) : void 0;
|
|
4397
|
+
const buSzPct = pPr["a:buSzPct"];
|
|
4398
|
+
let sizePercent;
|
|
4399
|
+
if (buSzPct?.["@_val"] !== void 0) {
|
|
4400
|
+
const pctRaw = Number.parseInt(String(buSzPct["@_val"]), 10);
|
|
4401
|
+
if (Number.isFinite(pctRaw)) {
|
|
4402
|
+
sizePercent = pctRaw / 1e3;
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
const buSzPts = pPr["a:buSzPts"];
|
|
4406
|
+
let sizePts;
|
|
4407
|
+
if (buSzPts?.["@_val"] !== void 0) {
|
|
4408
|
+
const ptsRaw = Number.parseInt(String(buSzPts["@_val"]), 10);
|
|
4409
|
+
if (Number.isFinite(ptsRaw)) {
|
|
4410
|
+
sizePts = ptsRaw / 100;
|
|
4411
|
+
}
|
|
4412
|
+
}
|
|
4413
|
+
const buClr = pPr["a:buClr"];
|
|
4414
|
+
let color2;
|
|
4415
|
+
if (buClr) {
|
|
4416
|
+
const srgb = buClr["a:srgbClr"];
|
|
4417
|
+
if (srgb?.["@_val"]) {
|
|
4418
|
+
color2 = String(srgb["@_val"]);
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4421
|
+
const buChar = pPr["a:buChar"];
|
|
4422
|
+
if (buChar?.["@_char"]) {
|
|
4423
|
+
const char = String(buChar["@_char"]);
|
|
4424
|
+
if (char.length > 0) {
|
|
4425
|
+
return { char, fontFamily, sizePercent, sizePts, color: color2 };
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
const autoNum = pPr["a:buAutoNum"];
|
|
4429
|
+
if (autoNum) {
|
|
4430
|
+
const autoNumType = autoNum["@_type"] ? String(autoNum["@_type"]) : void 0;
|
|
4431
|
+
const startAtRaw = Number.parseInt(String(autoNum["@_startAt"] || "1"), 10);
|
|
4432
|
+
const autoNumStartAt = Number.isFinite(startAtRaw) ? startAtRaw : 1;
|
|
4433
|
+
return {
|
|
4434
|
+
autoNumType,
|
|
4435
|
+
autoNumStartAt,
|
|
4436
|
+
paragraphIndex,
|
|
4437
|
+
fontFamily,
|
|
4438
|
+
sizePercent,
|
|
4439
|
+
sizePts,
|
|
4440
|
+
color: color2
|
|
4441
|
+
};
|
|
4442
|
+
}
|
|
4443
|
+
return null;
|
|
4444
|
+
}
|
|
4445
|
+
|
|
4446
|
+
// src/core/utils/text-run-properties-parser.ts
|
|
4447
|
+
function parseBoolAttr2(value) {
|
|
4448
|
+
if (value === void 0 || value === null) {
|
|
4449
|
+
return void 0;
|
|
4450
|
+
}
|
|
4451
|
+
const normalized = String(value).trim().toLowerCase();
|
|
4452
|
+
if (normalized.length === 0) {
|
|
4453
|
+
return void 0;
|
|
4454
|
+
}
|
|
4455
|
+
return normalized === "1" || normalized === "true";
|
|
4456
|
+
}
|
|
4457
|
+
function parseRunPropertyAttributes(rPr) {
|
|
4458
|
+
const style = {};
|
|
4459
|
+
if (!rPr) {
|
|
4460
|
+
return style;
|
|
4461
|
+
}
|
|
4462
|
+
if (rPr["@_sz"] !== void 0) {
|
|
4463
|
+
const hundredths = parseInt(String(rPr["@_sz"]), 10);
|
|
4464
|
+
if (Number.isFinite(hundredths)) {
|
|
4465
|
+
const points = hundredths / 100;
|
|
4466
|
+
style.fontSize = points * (96 / 72);
|
|
4467
|
+
}
|
|
4468
|
+
}
|
|
4469
|
+
if (rPr["@_b"] !== void 0) {
|
|
4470
|
+
style.bold = rPr["@_b"] === "1";
|
|
4471
|
+
}
|
|
4472
|
+
if (rPr["@_i"] !== void 0) {
|
|
4473
|
+
style.italic = rPr["@_i"] === "1";
|
|
4474
|
+
}
|
|
4475
|
+
if (rPr["@_u"] !== void 0) {
|
|
4476
|
+
const underlineToken = String(rPr["@_u"] || "").trim().toLowerCase();
|
|
4477
|
+
style.underline = underlineToken.length > 0 && underlineToken !== "none" && underlineToken !== "0" && underlineToken !== "false";
|
|
4478
|
+
if (style.underline) {
|
|
4479
|
+
const rawU = String(rPr["@_u"] || "").trim();
|
|
4480
|
+
if (rawU.length > 0 && rawU !== "none") {
|
|
4481
|
+
style.underlineStyle = rawU;
|
|
4482
|
+
}
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4485
|
+
if (rPr["@_strike"] !== void 0) {
|
|
4486
|
+
const strikeToken = String(rPr["@_strike"] || "").trim().toLowerCase();
|
|
4487
|
+
style.strikethrough = strikeToken.length > 0 && strikeToken !== "nostrike" && strikeToken !== "none" && strikeToken !== "0" && strikeToken !== "false";
|
|
4488
|
+
if (style.strikethrough) {
|
|
4489
|
+
style.strikeType = strikeToken === "dblstrike" ? "dblStrike" : "sngStrike";
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
const capAttr = String(rPr["@_cap"] || "").trim().toLowerCase();
|
|
4493
|
+
if (capAttr === "all" || capAttr === "small") {
|
|
4494
|
+
style.textCaps = capAttr;
|
|
4495
|
+
}
|
|
4496
|
+
if (rPr["@_baseline"] !== void 0) {
|
|
4497
|
+
const baselineVal = Number.parseInt(String(rPr["@_baseline"]), 10);
|
|
4498
|
+
if (Number.isFinite(baselineVal) && baselineVal !== 0) {
|
|
4499
|
+
style.baseline = baselineVal;
|
|
4500
|
+
}
|
|
4501
|
+
}
|
|
4502
|
+
if (rPr["@_spc"] !== void 0) {
|
|
4503
|
+
const spcVal = Number.parseInt(String(rPr["@_spc"]), 10);
|
|
4504
|
+
if (Number.isFinite(spcVal)) {
|
|
4505
|
+
style.characterSpacing = spcVal;
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
if (rPr["@_kern"] !== void 0) {
|
|
4509
|
+
const kernVal = Number.parseInt(String(rPr["@_kern"]), 10);
|
|
4510
|
+
if (Number.isFinite(kernVal)) {
|
|
4511
|
+
style.kerning = kernVal;
|
|
4512
|
+
}
|
|
4513
|
+
}
|
|
4514
|
+
const langAttr = String(rPr["@_lang"] || "").trim();
|
|
4515
|
+
if (langAttr) {
|
|
4516
|
+
style.language = langAttr;
|
|
4517
|
+
}
|
|
4518
|
+
const runRtl = parseBoolAttr2(rPr["@_rtl"]);
|
|
4519
|
+
if (runRtl !== void 0) {
|
|
4520
|
+
style.rtl = runRtl;
|
|
4521
|
+
}
|
|
4522
|
+
const kumimoji = parseBoolAttr2(rPr["@_kumimoji"]);
|
|
4523
|
+
if (kumimoji !== void 0) {
|
|
4524
|
+
style.kumimoji = kumimoji;
|
|
4525
|
+
}
|
|
4526
|
+
const normalizeH = parseBoolAttr2(rPr["@_normalizeH"]);
|
|
4527
|
+
if (normalizeH !== void 0) {
|
|
4528
|
+
style.normalizeHeight = normalizeH;
|
|
4529
|
+
}
|
|
4530
|
+
const noProof = parseBoolAttr2(rPr["@_noProof"]);
|
|
4531
|
+
if (noProof !== void 0) {
|
|
4532
|
+
style.noProof = noProof;
|
|
4533
|
+
}
|
|
4534
|
+
const dirty = parseBoolAttr2(rPr["@_dirty"]);
|
|
4535
|
+
if (dirty !== void 0) {
|
|
4536
|
+
style.dirty = dirty;
|
|
4537
|
+
}
|
|
4538
|
+
const err = parseBoolAttr2(rPr["@_err"]);
|
|
4539
|
+
if (err !== void 0) {
|
|
4540
|
+
style.spellingError = err;
|
|
4541
|
+
}
|
|
4542
|
+
const smtClean = parseBoolAttr2(rPr["@_smtClean"]);
|
|
4543
|
+
if (smtClean !== void 0) {
|
|
4544
|
+
style.smartTagClean = smtClean;
|
|
4545
|
+
}
|
|
4546
|
+
const bmk = String(rPr["@_bmk"] || "").trim();
|
|
4547
|
+
if (bmk) {
|
|
4548
|
+
style.bookmark = bmk;
|
|
4549
|
+
}
|
|
4550
|
+
const altLang = String(rPr["@_altLang"] || "").trim();
|
|
4551
|
+
if (altLang) {
|
|
4552
|
+
style.altLanguage = altLang;
|
|
4553
|
+
}
|
|
4554
|
+
if (rPr["@_smtId"] !== void 0) {
|
|
4555
|
+
const smtIdRaw = Number.parseInt(String(rPr["@_smtId"]), 10);
|
|
4556
|
+
if (Number.isFinite(smtIdRaw)) {
|
|
4557
|
+
style.smartTagId = smtIdRaw;
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4560
|
+
return style;
|
|
4561
|
+
}
|
|
4562
|
+
function parseTextFontMetadata(node) {
|
|
4563
|
+
if (!node) {
|
|
4564
|
+
return {};
|
|
4565
|
+
}
|
|
4566
|
+
const out = {};
|
|
4567
|
+
const panose = String(node["@_panose"] || "").trim();
|
|
4568
|
+
if (panose) {
|
|
4569
|
+
out.panose = panose;
|
|
4570
|
+
}
|
|
4571
|
+
if (node["@_pitchFamily"] !== void 0) {
|
|
4572
|
+
const pitchRaw = Number.parseInt(String(node["@_pitchFamily"]), 10);
|
|
4573
|
+
if (Number.isFinite(pitchRaw)) {
|
|
4574
|
+
out.pitchFamily = pitchRaw;
|
|
4575
|
+
}
|
|
4576
|
+
}
|
|
4577
|
+
if (node["@_charset"] !== void 0) {
|
|
4578
|
+
const charsetRaw = Number.parseInt(String(node["@_charset"]), 10);
|
|
4579
|
+
if (Number.isFinite(charsetRaw)) {
|
|
4580
|
+
out.charset = charsetRaw;
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4583
|
+
return out;
|
|
4584
|
+
}
|
|
4585
|
+
function parseRunFontElements(rPr) {
|
|
4586
|
+
const result = {};
|
|
4587
|
+
if (!rPr) {
|
|
4588
|
+
return result;
|
|
4589
|
+
}
|
|
4590
|
+
const latin = rPr["a:latin"];
|
|
4591
|
+
const eastAsian = rPr["a:ea"];
|
|
4592
|
+
const complexScript = rPr["a:cs"];
|
|
4593
|
+
const chosenTypeface = latin?.["@_typeface"] || eastAsian?.["@_typeface"] || complexScript?.["@_typeface"];
|
|
4594
|
+
if (typeof chosenTypeface === "string" && chosenTypeface.trim().length > 0) {
|
|
4595
|
+
result.fontFamily = chosenTypeface.trim();
|
|
4596
|
+
}
|
|
4597
|
+
if (typeof eastAsian?.["@_typeface"] === "string" && eastAsian["@_typeface"].trim().length > 0) {
|
|
4598
|
+
result.eastAsiaFont = eastAsian["@_typeface"].trim();
|
|
4599
|
+
}
|
|
4600
|
+
if (typeof complexScript?.["@_typeface"] === "string" && complexScript["@_typeface"].trim().length > 0) {
|
|
4601
|
+
result.complexScriptFont = complexScript["@_typeface"].trim();
|
|
4602
|
+
}
|
|
4603
|
+
const latinMeta = parseTextFontMetadata(latin);
|
|
4604
|
+
if (latinMeta.panose !== void 0) {
|
|
4605
|
+
result.latinFontPanose = latinMeta.panose;
|
|
4606
|
+
}
|
|
4607
|
+
if (latinMeta.pitchFamily !== void 0) {
|
|
4608
|
+
result.latinFontPitchFamily = latinMeta.pitchFamily;
|
|
4609
|
+
}
|
|
4610
|
+
if (latinMeta.charset !== void 0) {
|
|
4611
|
+
result.latinFontCharset = latinMeta.charset;
|
|
4612
|
+
}
|
|
4613
|
+
const eaMeta = parseTextFontMetadata(eastAsian);
|
|
4614
|
+
if (eaMeta.panose !== void 0) {
|
|
4615
|
+
result.eastAsiaFontPanose = eaMeta.panose;
|
|
4616
|
+
}
|
|
4617
|
+
if (eaMeta.pitchFamily !== void 0) {
|
|
4618
|
+
result.eastAsiaFontPitchFamily = eaMeta.pitchFamily;
|
|
4619
|
+
}
|
|
4620
|
+
if (eaMeta.charset !== void 0) {
|
|
4621
|
+
result.eastAsiaFontCharset = eaMeta.charset;
|
|
4622
|
+
}
|
|
4623
|
+
const csMeta = parseTextFontMetadata(complexScript);
|
|
4624
|
+
if (csMeta.panose !== void 0) {
|
|
4625
|
+
result.complexScriptFontPanose = csMeta.panose;
|
|
4626
|
+
}
|
|
4627
|
+
if (csMeta.pitchFamily !== void 0) {
|
|
4628
|
+
result.complexScriptFontPitchFamily = csMeta.pitchFamily;
|
|
4629
|
+
}
|
|
4630
|
+
if (csMeta.charset !== void 0) {
|
|
4631
|
+
result.complexScriptFontCharset = csMeta.charset;
|
|
4632
|
+
}
|
|
4633
|
+
return result;
|
|
4634
|
+
}
|
|
4635
|
+
function parseRunSolidFillColor(rPr) {
|
|
4636
|
+
if (!rPr) {
|
|
4637
|
+
return void 0;
|
|
4638
|
+
}
|
|
4639
|
+
const solidFill = rPr["a:solidFill"];
|
|
4640
|
+
if (!solidFill) {
|
|
4641
|
+
return void 0;
|
|
4642
|
+
}
|
|
4643
|
+
const srgb = solidFill["a:srgbClr"];
|
|
4644
|
+
if (srgb?.["@_val"]) {
|
|
4645
|
+
return String(srgb["@_val"]);
|
|
4646
|
+
}
|
|
4647
|
+
return void 0;
|
|
4648
|
+
}
|
|
4649
|
+
function parseRunSolidFillColorXml(rPr) {
|
|
4650
|
+
if (!rPr) {
|
|
4651
|
+
return void 0;
|
|
4652
|
+
}
|
|
4653
|
+
const solidFill = rPr["a:solidFill"];
|
|
4654
|
+
if (!solidFill) {
|
|
4655
|
+
return void 0;
|
|
4656
|
+
}
|
|
4657
|
+
return extractColorChoiceXml(solidFill);
|
|
4658
|
+
}
|
|
4659
|
+
|
|
4660
|
+
// src/core/utils/smartart-node-text-projection.ts
|
|
4661
|
+
function child(node, name) {
|
|
4662
|
+
if (!node) {
|
|
4663
|
+
return void 0;
|
|
4664
|
+
}
|
|
4665
|
+
const key = Object.keys(node).find((candidate) => candidate.split(":").pop() === name);
|
|
4666
|
+
const value = key ? node[key] : void 0;
|
|
4667
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
4668
|
+
}
|
|
4669
|
+
function runStyle(rPr, fallback) {
|
|
4670
|
+
const xml = rPr;
|
|
4671
|
+
const color2 = parseRunSolidFillColor(xml);
|
|
4672
|
+
const extLst = child(rPr, "extLst");
|
|
3489
4673
|
return {
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
4674
|
+
...fallback,
|
|
4675
|
+
...parseRunPropertyAttributes(xml),
|
|
4676
|
+
...parseRunFontElements(xml),
|
|
4677
|
+
...color2 ? { color: color2.startsWith("#") ? color2 : `#${color2}` } : {},
|
|
4678
|
+
...parseRunSolidFillColorXml(xml) ? { colorXml: parseRunSolidFillColorXml(xml) } : {},
|
|
4679
|
+
...extLst ? { runPropertiesExtLstXml: extLst } : {},
|
|
4680
|
+
...xml ? { runPropertiesXml: xml } : {}
|
|
4681
|
+
};
|
|
4682
|
+
}
|
|
4683
|
+
function resolvedRunStyle(rPr, resolved, fallback) {
|
|
4684
|
+
return {
|
|
4685
|
+
...runStyle(rPr, fallback),
|
|
4686
|
+
...resolved,
|
|
4687
|
+
...rPr ? { runPropertiesXml: rPr } : {}
|
|
4688
|
+
};
|
|
4689
|
+
}
|
|
4690
|
+
function paragraphStyle(paragraph, fallback) {
|
|
4691
|
+
const pPr = paragraph.pPr;
|
|
4692
|
+
const align = parseAlignmentAttr(pPr?.["@_algn"]);
|
|
4693
|
+
const rtl = parseParagraphRtl(pPr);
|
|
4694
|
+
const tabStops = parseTabStops(pPr);
|
|
4695
|
+
const extLst = child(paragraph.pPr, "extLst");
|
|
4696
|
+
return {
|
|
4697
|
+
...fallback,
|
|
4698
|
+
...align ? { align } : {},
|
|
4699
|
+
...parseParagraphMargins(pPr),
|
|
4700
|
+
...parseParagraphExtraAttributes(pPr),
|
|
4701
|
+
...rtl !== void 0 ? { rtl } : {},
|
|
4702
|
+
...tabStops ? { tabStops } : {},
|
|
4703
|
+
...parseParagraphSpacingPx(child(paragraph.pPr, "spcBef")) !== void 0 ? { paragraphSpacingBefore: parseParagraphSpacingPx(child(paragraph.pPr, "spcBef")) } : {},
|
|
4704
|
+
...parseParagraphSpacingPx(child(paragraph.pPr, "spcAft")) !== void 0 ? { paragraphSpacingAfter: parseParagraphSpacingPx(child(paragraph.pPr, "spcAft")) } : {},
|
|
4705
|
+
...parseLineSpacingMultiplier(child(paragraph.pPr, "lnSpc")) !== void 0 ? { lineSpacing: parseLineSpacingMultiplier(child(paragraph.pPr, "lnSpc")) } : {},
|
|
4706
|
+
...parseLineSpacingExactPt(child(paragraph.pPr, "lnSpc")) !== void 0 ? { lineSpacingExactPt: parseLineSpacingExactPt(child(paragraph.pPr, "lnSpc")) } : {},
|
|
4707
|
+
...extLst ? { paragraphPropertiesExtLstXml: extLst } : {},
|
|
4708
|
+
...child(paragraph.pPr, "defRPr") ? { paragraphDefaultRunPropertiesXml: child(paragraph.pPr, "defRPr") } : {}
|
|
4709
|
+
};
|
|
4710
|
+
}
|
|
4711
|
+
function paragraphMetadata(paragraph, paragraphIndex) {
|
|
4712
|
+
const pPr = paragraph.pPr;
|
|
4713
|
+
const bulletInfo = parseBulletInfo(pPr, paragraphIndex) ?? void 0;
|
|
4714
|
+
return {
|
|
4715
|
+
...bulletInfo ? { bulletInfo } : {},
|
|
4716
|
+
paragraphLevel: parseParagraphLevel(pPr),
|
|
4717
|
+
...paragraph.endParaRPr ? { endParaRunProperties: paragraph.endParaRPr } : {}
|
|
4718
|
+
};
|
|
4719
|
+
}
|
|
4720
|
+
function projectSmartArtNodeText(node, fallbackStyle = {}) {
|
|
4721
|
+
if (!node.paragraphs?.length) {
|
|
4722
|
+
return [{ text: node.text, style: fallbackStyle }];
|
|
4723
|
+
}
|
|
4724
|
+
const paragraphs = reconcileSmartArtTextParagraphs(node.paragraphs, node.text);
|
|
4725
|
+
const segments = [];
|
|
4726
|
+
for (let paragraphIndex = 0; paragraphIndex < paragraphs.length; paragraphIndex++) {
|
|
4727
|
+
const paragraph = paragraphs[paragraphIndex];
|
|
4728
|
+
const pStyle = paragraphStyle(paragraph, fallbackStyle);
|
|
4729
|
+
const metadata = paragraphMetadata(paragraph, paragraphIndex);
|
|
4730
|
+
let first = true;
|
|
4731
|
+
const push = (segment) => {
|
|
4732
|
+
segments.push(first ? { ...segment, ...metadata } : segment);
|
|
4733
|
+
first = false;
|
|
4734
|
+
};
|
|
4735
|
+
for (const item of paragraph.items) {
|
|
4736
|
+
if (item.kind === "run") {
|
|
4737
|
+
push({
|
|
4738
|
+
text: item.run.text,
|
|
4739
|
+
style: resolvedRunStyle(item.run.rPr, item.run.style, pStyle)
|
|
4740
|
+
});
|
|
4741
|
+
} else if (item.kind === "field") {
|
|
4742
|
+
push({
|
|
4743
|
+
text: item.text,
|
|
4744
|
+
style: resolvedRunStyle(item.rPr, item.style, pStyle),
|
|
4745
|
+
fieldType: item.fieldType,
|
|
4746
|
+
fieldGuid: item.id,
|
|
4747
|
+
fieldParagraphPropertiesXml: item.pPr
|
|
4748
|
+
});
|
|
4749
|
+
} else if (item.kind === "break") {
|
|
4750
|
+
push({
|
|
4751
|
+
text: "\n",
|
|
4752
|
+
style: resolvedRunStyle(item.rPr, item.style, pStyle),
|
|
4753
|
+
isLineBreak: true,
|
|
4754
|
+
breakRunProperties: item.rPr
|
|
4755
|
+
});
|
|
4756
|
+
} else if (item.kind === "tab") {
|
|
4757
|
+
push({ text: " ", style: pStyle });
|
|
4758
|
+
}
|
|
4759
|
+
}
|
|
4760
|
+
if (first) {
|
|
4761
|
+
push({ text: "", style: { ...pStyle, ...paragraph.endParaStyle } });
|
|
4762
|
+
}
|
|
4763
|
+
if (paragraphIndex < paragraphs.length - 1) {
|
|
4764
|
+
segments.push({
|
|
4765
|
+
text: "",
|
|
4766
|
+
style: { ...pStyle, ...paragraph.endParaStyle },
|
|
4767
|
+
isParagraphBreak: true
|
|
4768
|
+
});
|
|
4769
|
+
}
|
|
4770
|
+
}
|
|
4771
|
+
return segments;
|
|
4772
|
+
}
|
|
4773
|
+
|
|
4774
|
+
// src/core/utils/smartart-layout-engine.ts
|
|
4775
|
+
function computeSmartArtLayout(data, bounds, layoutDef) {
|
|
4776
|
+
const nodes = data.nodes;
|
|
4777
|
+
if (!nodes || nodes.length === 0) {
|
|
4778
|
+
return void 0;
|
|
4779
|
+
}
|
|
4780
|
+
const contentNodes = getContentNodes(nodes);
|
|
4781
|
+
if (contentNodes.length === 0) {
|
|
4782
|
+
return void 0;
|
|
4783
|
+
}
|
|
4784
|
+
const evaluated = evaluateLayoutRules(
|
|
4785
|
+
{},
|
|
4786
|
+
[],
|
|
4787
|
+
contentNodes
|
|
4788
|
+
);
|
|
4789
|
+
const constraints = evaluated.constraints;
|
|
4790
|
+
const resolvedType = data.resolvedLayoutType;
|
|
4791
|
+
const shapes = resolvedType ? computeByLayoutType(resolvedType, nodes, constraints, bounds) : computeByLayoutType(
|
|
4792
|
+
resolveLayoutTypeFromString(data.layoutType),
|
|
4793
|
+
nodes,
|
|
4794
|
+
constraints,
|
|
4795
|
+
bounds
|
|
4796
|
+
);
|
|
4797
|
+
return applyNodeLayoutRules(shapes, evaluated.nodeConstraints, bounds, constraints);
|
|
4798
|
+
}
|
|
4799
|
+
function layoutEngineShapesToDrawingShapes(engineShapes, nodes, layoutType) {
|
|
4800
|
+
const nodeMap = /* @__PURE__ */ new Map();
|
|
4801
|
+
for (const n of nodes) {
|
|
4802
|
+
nodeMap.set(n.id, n);
|
|
4803
|
+
}
|
|
4804
|
+
return engineShapes.map((shape) => {
|
|
4805
|
+
const node = nodeMap.get(shape.nodeId);
|
|
4806
|
+
const shapeType = getDefaultShapeType(layoutType);
|
|
4807
|
+
return {
|
|
4808
|
+
id: `engine-${shape.nodeId}`,
|
|
4809
|
+
shapeType,
|
|
4810
|
+
x: shape.x,
|
|
4811
|
+
y: shape.y,
|
|
4812
|
+
width: shape.width,
|
|
4813
|
+
height: shape.height,
|
|
4814
|
+
fontSize: shape.fontSize,
|
|
4815
|
+
text: node?.text,
|
|
4816
|
+
textSegments: node ? projectSmartArtNodeText(node, {
|
|
4817
|
+
...shape.fontSize !== void 0 ? { fontSize: shape.fontSize * (96 / 72) } : {}
|
|
4818
|
+
}) : void 0
|
|
4819
|
+
};
|
|
4820
|
+
});
|
|
4821
|
+
}
|
|
4822
|
+
|
|
4823
|
+
// src/core/utils/mc-capabilities.ts
|
|
4824
|
+
var MC_NAMESPACE_CAPABILITIES = {
|
|
4825
|
+
p14: /* @__PURE__ */ new Set([
|
|
4826
|
+
"transition",
|
|
4827
|
+
"conveyor",
|
|
4828
|
+
"pan",
|
|
4829
|
+
"glitter",
|
|
4830
|
+
"prism",
|
|
4831
|
+
"vortex",
|
|
4832
|
+
"switch",
|
|
4833
|
+
"flip",
|
|
4834
|
+
"gallery",
|
|
4835
|
+
"honeycomb",
|
|
4836
|
+
"flash",
|
|
4837
|
+
"shred",
|
|
4838
|
+
"warp",
|
|
4839
|
+
"flythrough",
|
|
4840
|
+
"doors",
|
|
4841
|
+
"window",
|
|
4842
|
+
"ferris",
|
|
4843
|
+
"newsflash",
|
|
4844
|
+
"wheelReverse",
|
|
4845
|
+
"rotate",
|
|
4846
|
+
"orbit",
|
|
4847
|
+
"cube",
|
|
4848
|
+
"media",
|
|
4849
|
+
"trim",
|
|
4850
|
+
"fade",
|
|
4851
|
+
"bmkLst",
|
|
4852
|
+
"bmk",
|
|
4853
|
+
"hiddenFill",
|
|
4854
|
+
"hiddenLine"
|
|
4855
|
+
]),
|
|
4856
|
+
a14: /* @__PURE__ */ new Set(["m", "hiddenFill", "hiddenLine", "imgEffect", "imgLayer"]),
|
|
4857
|
+
a16: /* @__PURE__ */ new Set(["svgBlip", "colId"]),
|
|
4858
|
+
asvg: /* @__PURE__ */ new Set(["svgBlip"]),
|
|
4859
|
+
aink: /* @__PURE__ */ new Set(["ink", "inkBrush", "trace"]),
|
|
4860
|
+
p16: /* @__PURE__ */ new Set(["model3D", "spPr", "model3Drel", "posterImage"]),
|
|
4861
|
+
pslz: /* @__PURE__ */ new Set(["sldZm", "sldZmObj", "zmPr", "extLst"]),
|
|
4862
|
+
psezm: /* @__PURE__ */ new Set(["sectionZm", "sectionZmObj", "zmPr", "extLst"]),
|
|
4863
|
+
psuz: /* @__PURE__ */ new Set(["summaryZm", "summaryZmObj", "zmPr", "gridLayout", "fixedLayout", "extLst"]),
|
|
4864
|
+
cx: /* @__PURE__ */ new Set(["chart", "plotArea", "plotAreaRegion", "series", "data", "numDim", "strDim"])
|
|
4865
|
+
};
|
|
4866
|
+
new Set(Object.keys(MC_NAMESPACE_CAPABILITIES));
|
|
4867
|
+
|
|
4868
|
+
// src/core/utils/vml-parser.ts
|
|
4869
|
+
var VML_SHAPE_TAGS = /* @__PURE__ */ new Set([
|
|
4870
|
+
"v:shape",
|
|
4871
|
+
"v:rect",
|
|
4872
|
+
"v:oval",
|
|
4873
|
+
"v:line",
|
|
4874
|
+
"v:roundrect",
|
|
4875
|
+
"v:polyline",
|
|
4876
|
+
"v:arc",
|
|
4877
|
+
"v:group",
|
|
4878
|
+
"v:image"
|
|
4879
|
+
]);
|
|
4880
|
+
|
|
4881
|
+
// src/core/utils/alternate-content.ts
|
|
4882
|
+
/* @__PURE__ */ new Set([
|
|
4883
|
+
"p:sp",
|
|
4884
|
+
"p:pic",
|
|
4885
|
+
"p:graphicFrame",
|
|
4886
|
+
"p:grpSp",
|
|
4887
|
+
"p:cxnSp",
|
|
4888
|
+
"p:contentPart",
|
|
4889
|
+
"p16:model3D",
|
|
4890
|
+
"pslz:sldZm",
|
|
4891
|
+
"psezm:sectionZm",
|
|
4892
|
+
"psuz:summaryZm",
|
|
4893
|
+
...VML_SHAPE_TAGS
|
|
4894
|
+
]);
|
|
4895
|
+
|
|
4896
|
+
// src/core/utils/strict-namespace-map.ts
|
|
4897
|
+
var NAMESPACE_PAIRS = [
|
|
4898
|
+
// -- PresentationML --
|
|
4899
|
+
[
|
|
4900
|
+
"http://purl.oclc.org/ooxml/presentationml/main",
|
|
4901
|
+
"http://schemas.openxmlformats.org/presentationml/2006/main"
|
|
4902
|
+
],
|
|
4903
|
+
// -- DrawingML --
|
|
4904
|
+
[
|
|
4905
|
+
"http://purl.oclc.org/ooxml/drawingml/main",
|
|
4906
|
+
"http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
4907
|
+
],
|
|
4908
|
+
[
|
|
4909
|
+
"http://purl.oclc.org/ooxml/drawingml/chart",
|
|
4910
|
+
"http://schemas.openxmlformats.org/drawingml/2006/chart"
|
|
4911
|
+
],
|
|
4912
|
+
[
|
|
4913
|
+
"http://purl.oclc.org/ooxml/drawingml/chartDrawing",
|
|
4914
|
+
"http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"
|
|
4915
|
+
],
|
|
4916
|
+
[
|
|
4917
|
+
"http://purl.oclc.org/ooxml/drawingml/diagram",
|
|
4918
|
+
"http://schemas.openxmlformats.org/drawingml/2006/diagram"
|
|
4919
|
+
],
|
|
4920
|
+
[
|
|
4921
|
+
"http://purl.oclc.org/ooxml/drawingml/lockedCanvas",
|
|
4922
|
+
"http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas"
|
|
4923
|
+
],
|
|
4924
|
+
[
|
|
4925
|
+
"http://purl.oclc.org/ooxml/drawingml/picture",
|
|
4926
|
+
"http://schemas.openxmlformats.org/drawingml/2006/picture"
|
|
4927
|
+
],
|
|
4928
|
+
[
|
|
4929
|
+
"http://purl.oclc.org/ooxml/drawingml/spreadsheetDrawing",
|
|
4930
|
+
"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
|
|
4931
|
+
],
|
|
4932
|
+
[
|
|
4933
|
+
"http://purl.oclc.org/ooxml/drawingml/wordprocessingDrawing",
|
|
4934
|
+
"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
|
|
4935
|
+
],
|
|
4936
|
+
// -- Relationships --
|
|
4937
|
+
[
|
|
4938
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships",
|
|
4939
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
4940
|
+
],
|
|
4941
|
+
[
|
|
4942
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/chart",
|
|
4943
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
|
|
4944
|
+
],
|
|
4945
|
+
[
|
|
4946
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/comments",
|
|
4947
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
|
|
4948
|
+
],
|
|
4949
|
+
[
|
|
4950
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/customXml",
|
|
4951
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"
|
|
4952
|
+
],
|
|
4953
|
+
[
|
|
4954
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/diagramColors",
|
|
4955
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramColors"
|
|
4956
|
+
],
|
|
4957
|
+
[
|
|
4958
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/diagramData",
|
|
4959
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramData"
|
|
4960
|
+
],
|
|
4961
|
+
[
|
|
4962
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/diagramLayout",
|
|
4963
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramLayout"
|
|
4964
|
+
],
|
|
4965
|
+
[
|
|
4966
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/diagramStyle",
|
|
4967
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramStyle"
|
|
4968
|
+
],
|
|
4969
|
+
[
|
|
4970
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/extended-properties",
|
|
4971
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"
|
|
4972
|
+
],
|
|
4973
|
+
[
|
|
4974
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/font",
|
|
4975
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/font"
|
|
4976
|
+
],
|
|
4977
|
+
[
|
|
4978
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/handoutMaster",
|
|
4979
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/handoutMaster"
|
|
4980
|
+
],
|
|
4981
|
+
[
|
|
4982
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/hyperlink",
|
|
4983
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
|
|
4984
|
+
],
|
|
4985
|
+
[
|
|
4986
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/image",
|
|
4987
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
|
|
4988
|
+
],
|
|
4989
|
+
[
|
|
4990
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/media",
|
|
4991
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/media"
|
|
4992
|
+
],
|
|
4993
|
+
[
|
|
4994
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/notesMaster",
|
|
4995
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster"
|
|
4996
|
+
],
|
|
4997
|
+
[
|
|
4998
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/notesSlide",
|
|
4999
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide"
|
|
5000
|
+
],
|
|
5001
|
+
[
|
|
5002
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/oleObject",
|
|
5003
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"
|
|
5004
|
+
],
|
|
5005
|
+
[
|
|
5006
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/presProps",
|
|
5007
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps"
|
|
5008
|
+
],
|
|
5009
|
+
[
|
|
5010
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/slide",
|
|
5011
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"
|
|
5012
|
+
],
|
|
5013
|
+
[
|
|
5014
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/slideLayout",
|
|
5015
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"
|
|
5016
|
+
],
|
|
5017
|
+
[
|
|
5018
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/slideMaster",
|
|
5019
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"
|
|
5020
|
+
],
|
|
5021
|
+
[
|
|
5022
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/tags",
|
|
5023
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/tags"
|
|
5024
|
+
],
|
|
5025
|
+
[
|
|
5026
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/theme",
|
|
5027
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
|
|
5028
|
+
],
|
|
5029
|
+
[
|
|
5030
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/themeOverride",
|
|
5031
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/themeOverride"
|
|
5032
|
+
],
|
|
5033
|
+
[
|
|
5034
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/video",
|
|
5035
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"
|
|
5036
|
+
],
|
|
5037
|
+
[
|
|
5038
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/audio",
|
|
5039
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio"
|
|
5040
|
+
],
|
|
5041
|
+
[
|
|
5042
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/viewProps",
|
|
5043
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps"
|
|
5044
|
+
],
|
|
5045
|
+
[
|
|
5046
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/tableStyles",
|
|
5047
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles"
|
|
5048
|
+
],
|
|
5049
|
+
// -- OfficeDocument core --
|
|
5050
|
+
[
|
|
5051
|
+
"http://purl.oclc.org/ooxml/officeDocument/math",
|
|
5052
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/math"
|
|
5053
|
+
],
|
|
5054
|
+
[
|
|
5055
|
+
"http://purl.oclc.org/ooxml/officeDocument/bibliography",
|
|
5056
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
|
|
5057
|
+
],
|
|
5058
|
+
[
|
|
5059
|
+
"http://purl.oclc.org/ooxml/officeDocument/custom-properties",
|
|
5060
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
|
|
5061
|
+
],
|
|
5062
|
+
[
|
|
5063
|
+
"http://purl.oclc.org/ooxml/officeDocument/extended-properties",
|
|
5064
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
|
|
5065
|
+
],
|
|
5066
|
+
[
|
|
5067
|
+
"http://purl.oclc.org/ooxml/officeDocument/docPropsVTypes",
|
|
5068
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
|
|
5069
|
+
],
|
|
5070
|
+
// -- OfficeDocument document relationship --
|
|
5071
|
+
// (Other OPC-defined relationship types - package/relationships,
|
|
5072
|
+
// core-properties, digital-signature - are conformance-independent and
|
|
5073
|
+
// intentionally omitted; see the module header.)
|
|
5074
|
+
[
|
|
5075
|
+
"http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument",
|
|
5076
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
|
|
5077
|
+
],
|
|
5078
|
+
// -- Schema Library --
|
|
5079
|
+
[
|
|
5080
|
+
"http://purl.oclc.org/ooxml/schemaLibrary/main",
|
|
5081
|
+
"http://schemas.openxmlformats.org/schemaLibrary/2006/main"
|
|
5082
|
+
],
|
|
5083
|
+
// -- Content-type descriptions (note the distinct transitional host) --
|
|
5084
|
+
[
|
|
5085
|
+
"http://purl.oclc.org/ooxml/descriptions/base",
|
|
5086
|
+
"http://descriptions.openxmlformats.org/description/base"
|
|
5087
|
+
],
|
|
5088
|
+
[
|
|
5089
|
+
"http://purl.oclc.org/ooxml/descriptions/full",
|
|
5090
|
+
"http://descriptions.openxmlformats.org/description/full"
|
|
5091
|
+
],
|
|
5092
|
+
// -- SpreadsheetML (for embedded charts / workbooks) --
|
|
5093
|
+
[
|
|
5094
|
+
"http://purl.oclc.org/ooxml/spreadsheetml/main",
|
|
5095
|
+
"http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
5096
|
+
],
|
|
5097
|
+
// -- WordprocessingML (for embedded docs) --
|
|
5098
|
+
[
|
|
5099
|
+
"http://purl.oclc.org/ooxml/wordprocessingml/main",
|
|
5100
|
+
"http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
|
5101
|
+
]
|
|
5102
|
+
];
|
|
5103
|
+
new Map(NAMESPACE_PAIRS);
|
|
5104
|
+
new Map(
|
|
5105
|
+
NAMESPACE_PAIRS.map(([strict, transitional]) => [transitional, strict])
|
|
5106
|
+
);
|
|
5107
|
+
|
|
5108
|
+
// src/core/utils/smartart-constraint-values.ts
|
|
5109
|
+
/* @__PURE__ */ new Set([
|
|
5110
|
+
"none",
|
|
5111
|
+
"alignOff",
|
|
5112
|
+
"begMarg",
|
|
5113
|
+
"bendDist",
|
|
5114
|
+
"begPad",
|
|
5115
|
+
"b",
|
|
5116
|
+
"bMarg",
|
|
5117
|
+
"bOff",
|
|
5118
|
+
"ctrX",
|
|
5119
|
+
"ctrXOff",
|
|
5120
|
+
"ctrY",
|
|
5121
|
+
"ctrYOff",
|
|
5122
|
+
"connDist",
|
|
5123
|
+
"diam",
|
|
5124
|
+
"endMarg",
|
|
5125
|
+
"endPad",
|
|
5126
|
+
"h",
|
|
5127
|
+
"hArH",
|
|
5128
|
+
"hOff",
|
|
5129
|
+
"l",
|
|
5130
|
+
"lMarg",
|
|
5131
|
+
"lOff",
|
|
5132
|
+
"r",
|
|
5133
|
+
"rMarg",
|
|
5134
|
+
"rOff",
|
|
5135
|
+
"primFontSz",
|
|
5136
|
+
"pyraAcctRatio",
|
|
5137
|
+
"secFontSz",
|
|
5138
|
+
"sibSp",
|
|
5139
|
+
"secSibSp",
|
|
5140
|
+
"sp",
|
|
5141
|
+
"stemThick",
|
|
5142
|
+
"t",
|
|
5143
|
+
"tMarg",
|
|
5144
|
+
"tOff",
|
|
5145
|
+
...Array.from({ length: 26 }, (_, index) => `user${String.fromCharCode(65 + index)}`),
|
|
5146
|
+
"w",
|
|
5147
|
+
"wArH",
|
|
5148
|
+
"wOff"
|
|
5149
|
+
]);
|
|
5150
|
+
|
|
5151
|
+
// src/core/utils/smartart-relayout.ts
|
|
5152
|
+
function relayoutSmartArt(smartArtData, containerWidth, containerHeight) {
|
|
5153
|
+
if (!smartArtData.nodes || smartArtData.nodes.length === 0) {
|
|
5154
|
+
return [];
|
|
5155
|
+
}
|
|
5156
|
+
const bounds = {
|
|
5157
|
+
x: 0,
|
|
5158
|
+
y: 0,
|
|
5159
|
+
width: containerWidth,
|
|
5160
|
+
height: containerHeight
|
|
3493
5161
|
};
|
|
5162
|
+
const engineShapes = computeSmartArtLayout(smartArtData, bounds);
|
|
5163
|
+
if (engineShapes && engineShapes.length > 0) {
|
|
5164
|
+
const layoutType = smartArtData.resolvedLayoutType ?? "list";
|
|
5165
|
+
return layoutEngineShapesToDrawingShapes(engineShapes, smartArtData.nodes, layoutType);
|
|
5166
|
+
}
|
|
5167
|
+
return smartArtData.drawingShapes ?? [];
|
|
5168
|
+
}
|
|
5169
|
+
|
|
5170
|
+
// src/converter/svg-chart-extended.ts
|
|
5171
|
+
var DEFAULT_COLORS = ["#4472C4", "#ED7D31", "#A5A5A5", "#FFC000", "#5B9BD5", "#70AD47"];
|
|
5172
|
+
function esc(value) {
|
|
5173
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
5174
|
+
}
|
|
5175
|
+
function renderFunnelChartSvg(element, x, y, width, height) {
|
|
5176
|
+
const series = element.chartData?.series[0];
|
|
5177
|
+
if (!series?.values.length) {
|
|
5178
|
+
return "";
|
|
5179
|
+
}
|
|
5180
|
+
const values = series.values.map((value) => Math.max(value, 0));
|
|
5181
|
+
const maximum = Math.max(...values, 1);
|
|
5182
|
+
const stageHeight = height / values.length;
|
|
5183
|
+
const widthFor = (value) => width * Math.max(value / maximum, 0.08);
|
|
5184
|
+
return values.map((value, index) => {
|
|
5185
|
+
const topWidth = widthFor(value);
|
|
5186
|
+
const nextValue2 = values[index + 1] ?? value * 0.72;
|
|
5187
|
+
const bottomWidth = widthFor(nextValue2);
|
|
5188
|
+
const center = x + width / 2;
|
|
5189
|
+
const top = y + index * stageHeight;
|
|
5190
|
+
const bottom = top + Math.max(stageHeight - 1, 0.5);
|
|
5191
|
+
const pointColor = series.dataPoints?.find((point) => point.idx === index)?.spPr?.fillColor;
|
|
5192
|
+
const fill = pointColor ?? series.color ?? DEFAULT_COLORS[index % DEFAULT_COLORS.length];
|
|
5193
|
+
const points = [
|
|
5194
|
+
`${center - topWidth / 2},${top}`,
|
|
5195
|
+
`${center + topWidth / 2},${top}`,
|
|
5196
|
+
`${center + bottomWidth / 2},${bottom}`,
|
|
5197
|
+
`${center - bottomWidth / 2},${bottom}`
|
|
5198
|
+
].join(" ");
|
|
5199
|
+
return `<polygon data-chart-mark="funnel" data-chart-point="${index}" points="${points}" fill="${esc(fill)}" />`;
|
|
5200
|
+
}).join("");
|
|
5201
|
+
}
|
|
5202
|
+
|
|
5203
|
+
// src/converter/svg-rich-elements.ts
|
|
5204
|
+
function esc2(value) {
|
|
5205
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
5206
|
+
}
|
|
5207
|
+
function color(series, index) {
|
|
5208
|
+
const palette = ["#4472C4", "#ED7D31", "#A5A5A5", "#FFC000", "#5B9BD5", "#70AD47"];
|
|
5209
|
+
return series.color ?? palette[index % palette.length];
|
|
5210
|
+
}
|
|
5211
|
+
function chartValues(element) {
|
|
5212
|
+
return element.chartData?.series.flatMap((series) => series.values).filter(Number.isFinite) ?? [];
|
|
5213
|
+
}
|
|
5214
|
+
function renderBars(element, x, y, w, h) {
|
|
5215
|
+
const data = element.chartData;
|
|
5216
|
+
const values = chartValues(element);
|
|
5217
|
+
const min = Math.min(0, ...values);
|
|
5218
|
+
const max = Math.max(0, ...values);
|
|
5219
|
+
const span = max - min || 1;
|
|
5220
|
+
const zeroY = y + max / span * h;
|
|
5221
|
+
const categoryCount = Math.max(
|
|
5222
|
+
data.categories.length,
|
|
5223
|
+
...data.series.map((s) => s.values.length),
|
|
5224
|
+
1
|
|
5225
|
+
);
|
|
5226
|
+
const clusterWidth = w / categoryCount;
|
|
5227
|
+
const barWidth = clusterWidth * 0.72 / Math.max(data.series.length, 1);
|
|
5228
|
+
const parts = [`<line x1="${x}" y1="${zeroY}" x2="${x + w}" y2="${zeroY}" stroke="#666666" />`];
|
|
5229
|
+
data.series.forEach((series, seriesIndex) => {
|
|
5230
|
+
series.values.forEach((value, categoryIndex) => {
|
|
5231
|
+
const valueY = y + (max - value) / span * h;
|
|
5232
|
+
parts.push(
|
|
5233
|
+
`<rect data-chart-mark="bar" x="${x + categoryIndex * clusterWidth + clusterWidth * 0.14 + seriesIndex * barWidth}" y="${Math.min(valueY, zeroY)}" width="${Math.max(barWidth - 1, 1)}" height="${Math.max(Math.abs(zeroY - valueY), 0.5)}" fill="${esc2(color(series, seriesIndex))}" />`
|
|
5234
|
+
);
|
|
5235
|
+
});
|
|
5236
|
+
});
|
|
5237
|
+
return parts.join("");
|
|
5238
|
+
}
|
|
5239
|
+
function renderLines(element, x, y, w, h) {
|
|
5240
|
+
const data = element.chartData;
|
|
5241
|
+
const values = chartValues(element);
|
|
5242
|
+
const min = Math.min(...values);
|
|
5243
|
+
const max = Math.max(...values);
|
|
5244
|
+
const span = max - min || 1;
|
|
5245
|
+
return data.series.map((series, seriesIndex) => {
|
|
5246
|
+
const denominator = Math.max(series.values.length - 1, 1);
|
|
5247
|
+
const points = series.values.map((value, index) => `${x + index / denominator * w},${y + (max - value) / span * h}`).join(" ");
|
|
5248
|
+
return `<polyline data-chart-mark="line" points="${points}" fill="none" stroke="${esc2(color(series, seriesIndex))}" stroke-width="2" />`;
|
|
5249
|
+
}).join("");
|
|
5250
|
+
}
|
|
5251
|
+
function polar(cx, cy, radius, angle) {
|
|
5252
|
+
const radians = (angle - 90) * Math.PI / 180;
|
|
5253
|
+
return [cx + radius * Math.cos(radians), cy + radius * Math.sin(radians)];
|
|
5254
|
+
}
|
|
5255
|
+
function renderPie(element, x, y, w, h) {
|
|
5256
|
+
const series = element.chartData.series[0];
|
|
5257
|
+
if (!series) {
|
|
5258
|
+
return "";
|
|
5259
|
+
}
|
|
5260
|
+
const values = series.values.map((value) => Math.max(value, 0));
|
|
5261
|
+
const total = values.reduce((sum, value) => sum + value, 0);
|
|
5262
|
+
if (total <= 0) {
|
|
5263
|
+
return "";
|
|
5264
|
+
}
|
|
5265
|
+
const cx = x + w / 2;
|
|
5266
|
+
const cy = y + h / 2;
|
|
5267
|
+
const radius = Math.max(Math.min(w, h) / 2, 1);
|
|
5268
|
+
let angle = 0;
|
|
5269
|
+
return values.map((value, index) => {
|
|
5270
|
+
const sweep = value / total * 360;
|
|
5271
|
+
const [sx, sy] = polar(cx, cy, radius, angle);
|
|
5272
|
+
const [ex, ey] = polar(cx, cy, radius, angle + sweep);
|
|
5273
|
+
const pointColor = series.dataPoints?.find((point) => point.idx === index)?.spPr?.fillColor;
|
|
5274
|
+
const path = `<path data-chart-mark="slice" d="M ${cx} ${cy} L ${sx} ${sy} A ${radius} ${radius} 0 ${sweep > 180 ? 1 : 0} 1 ${ex} ${ey} Z" fill="${esc2(color({ ...series, color: pointColor ?? series.color }, index))}" />`;
|
|
5275
|
+
angle += sweep;
|
|
5276
|
+
return path;
|
|
5277
|
+
}).join("");
|
|
5278
|
+
}
|
|
5279
|
+
function renderChartSvg(element) {
|
|
5280
|
+
const data = element.chartData;
|
|
5281
|
+
if (!data || data.series.length === 0 || chartValues(element).length === 0) {
|
|
5282
|
+
return null;
|
|
5283
|
+
}
|
|
5284
|
+
const titleHeight = data.title ? Math.min(element.height * 0.16, 28) : 0;
|
|
5285
|
+
const x = Math.max(element.width * 0.08, 8);
|
|
5286
|
+
const y = titleHeight + Math.max(element.height * 0.06, 6);
|
|
5287
|
+
const w = Math.max(element.width - x * 1.5, 1);
|
|
5288
|
+
const h = Math.max(element.height - y - Math.max(element.height * 0.1, 10), 1);
|
|
5289
|
+
const pie = data.chartType === "pie" || data.chartType === "pie3D" || data.chartType === "doughnut";
|
|
5290
|
+
const line = data.chartType === "line" || data.chartType === "line3D" || data.chartType === "scatter";
|
|
5291
|
+
const marks = data.chartType === "funnel" ? renderFunnelChartSvg(element, x, y, w, h) : pie ? renderPie(element, x, y, w, h) : line ? renderLines(element, x, y, w, h) : renderBars(element, x, y, w, h);
|
|
5292
|
+
const title = data.title ? `<text x="${element.width / 2}" y="${Math.max(titleHeight * 0.75, 14)}" text-anchor="middle" font-family="Arial" font-size="14" fill="#222222">${esc2(data.title)}</text>` : "";
|
|
5293
|
+
return `<g data-pptx-element="chart" data-chart-type="${esc2(data.chartType)}"><rect width="${element.width}" height="${element.height}" fill="#FFFFFF" />${title}${marks}</g>`;
|
|
5294
|
+
}
|
|
5295
|
+
function renderSmartArtShape(shape) {
|
|
5296
|
+
const fill = esc2(shape.fillColor ?? "#4472C4");
|
|
5297
|
+
const stroke = esc2(shape.strokeColor ?? "#FFFFFF");
|
|
5298
|
+
const transform = shape.rotation ? ` transform="rotate(${shape.rotation} ${shape.x + shape.width / 2} ${shape.y + shape.height / 2})"` : "";
|
|
5299
|
+
let geometry;
|
|
5300
|
+
if (shape.shapeType === "ellipse") {
|
|
5301
|
+
geometry = `<ellipse cx="${shape.x + shape.width / 2}" cy="${shape.y + shape.height / 2}" rx="${shape.width / 2}" ry="${shape.height / 2}" fill="${fill}" stroke="${stroke}" />`;
|
|
5302
|
+
} else if (shape.shapeType === "diamond") {
|
|
5303
|
+
geometry = `<polygon points="${shape.x + shape.width / 2},${shape.y} ${shape.x + shape.width},${shape.y + shape.height / 2} ${shape.x + shape.width / 2},${shape.y + shape.height} ${shape.x},${shape.y + shape.height / 2}" fill="${fill}" stroke="${stroke}" />`;
|
|
5304
|
+
} else {
|
|
5305
|
+
geometry = `<rect x="${shape.x}" y="${shape.y}" width="${shape.width}" height="${shape.height}" rx="${shape.shapeType === "roundRect" ? Math.min(shape.width, shape.height) * 0.12 : 0}" fill="${fill}" stroke="${stroke}" stroke-width="${shape.strokeWidth ?? 1}" />`;
|
|
5306
|
+
}
|
|
5307
|
+
const text = shape.text ? `<text x="${shape.x + shape.width / 2}" y="${shape.y + shape.height / 2}" text-anchor="middle" dominant-baseline="central" font-family="Arial" font-size="${shape.fontSize ?? 12}" fill="${esc2(shape.fontColor ?? "#FFFFFF")}">${esc2(shape.text)}</text>` : "";
|
|
5308
|
+
return `<g data-smartart-shape="${esc2(shape.id)}"${transform}>${geometry}${text}</g>`;
|
|
5309
|
+
}
|
|
5310
|
+
function renderSmartArtSvg(element) {
|
|
5311
|
+
const data = element.smartArtData;
|
|
5312
|
+
if (!data) {
|
|
5313
|
+
return null;
|
|
5314
|
+
}
|
|
5315
|
+
const shapes = data.drawingShapes?.length ? data.drawingShapes : relayoutSmartArt(data, element.width, element.height);
|
|
5316
|
+
if (shapes.length === 0) {
|
|
5317
|
+
return null;
|
|
5318
|
+
}
|
|
5319
|
+
const chrome = data.chrome;
|
|
5320
|
+
const background = chrome?.backgroundColor ? `<rect width="${element.width}" height="${element.height}" fill="${esc2(chrome.backgroundColor)}" stroke="${esc2(chrome.outlineColor ?? "none")}" stroke-width="${chrome.outlineWidth ?? 0}" />` : "";
|
|
5321
|
+
return `<g data-pptx-element="smartArt">${background}${shapes.map(renderSmartArtShape).join("")}</g>`;
|
|
5322
|
+
}
|
|
5323
|
+
function previewImage(source, kind, width, height) {
|
|
5324
|
+
if (!source || !source.startsWith("data:image/")) {
|
|
5325
|
+
return null;
|
|
5326
|
+
}
|
|
5327
|
+
return `<image data-pptx-element="${kind}" width="${width}" height="${height}" preserveAspectRatio="none" href="${esc2(source)}" />`;
|
|
5328
|
+
}
|
|
5329
|
+
function renderMediaPreviewSvg(element) {
|
|
5330
|
+
return previewImage(element.posterFrameData, "media", element.width, element.height);
|
|
5331
|
+
}
|
|
5332
|
+
function renderOlePreviewSvg(element) {
|
|
5333
|
+
return previewImage(
|
|
5334
|
+
element.previewImageData ?? element.previewImage,
|
|
5335
|
+
"ole",
|
|
5336
|
+
element.width,
|
|
5337
|
+
element.height
|
|
5338
|
+
);
|
|
5339
|
+
}
|
|
5340
|
+
function renderModel3DPreviewSvg(element) {
|
|
5341
|
+
return previewImage(
|
|
5342
|
+
element.posterImage ?? element.svgData ?? element.imageData,
|
|
5343
|
+
"model3d",
|
|
5344
|
+
element.width,
|
|
5345
|
+
element.height
|
|
5346
|
+
);
|
|
5347
|
+
}
|
|
5348
|
+
function renderContentPartSvg(element) {
|
|
5349
|
+
if (!element.inkStrokes?.length) {
|
|
5350
|
+
return null;
|
|
5351
|
+
}
|
|
5352
|
+
const strokes = element.inkStrokes.map(
|
|
5353
|
+
(stroke) => `<path data-content-part="ink" d="${esc2(stroke.path)}" fill="none" stroke="${esc2(stroke.color)}" stroke-width="${stroke.width}" stroke-opacity="${stroke.opacity}" stroke-linecap="round" stroke-linejoin="round" />`
|
|
5354
|
+
).join("");
|
|
5355
|
+
return `<g data-pptx-element="contentPart">${strokes}</g>`;
|
|
5356
|
+
}
|
|
5357
|
+
function renderZoomPreviewSvg(element) {
|
|
5358
|
+
return previewImage(element.svgData ?? element.imageData, "zoom", element.width, element.height);
|
|
3494
5359
|
}
|
|
3495
5360
|
|
|
3496
5361
|
// src/converter/SvgExporter.ts
|
|
@@ -3523,14 +5388,14 @@ function createRenderContext(slideIndex = 0) {
|
|
|
3523
5388
|
filterCounter: 0
|
|
3524
5389
|
};
|
|
3525
5390
|
}
|
|
3526
|
-
function getOrCreateArrowMarker(ctx,
|
|
3527
|
-
const key =
|
|
5391
|
+
function getOrCreateArrowMarker(ctx, color2) {
|
|
5392
|
+
const key = color2;
|
|
3528
5393
|
const cached = ctx.markerCache.get(key);
|
|
3529
5394
|
if (cached) {
|
|
3530
5395
|
return cached;
|
|
3531
5396
|
}
|
|
3532
5397
|
const id = `arrow_${++ctx.markerIdCounter}`;
|
|
3533
|
-
const svg = `<marker id="${id}" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto" markerUnits="strokeWidth"><polygon points="0 0, 10 3.5, 0 7" fill="${escXml(
|
|
5398
|
+
const svg = `<marker id="${id}" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto" markerUnits="strokeWidth"><polygon points="0 0, 10 3.5, 0 7" fill="${escXml(color2)}" /></marker>`;
|
|
3534
5399
|
ctx.defs.push(svg);
|
|
3535
5400
|
ctx.markerCache.set(key, id);
|
|
3536
5401
|
return id;
|
|
@@ -3561,7 +5426,7 @@ function renderText(el, defaults) {
|
|
|
3561
5426
|
const style = el.textStyle;
|
|
3562
5427
|
const fontFamily = style?.fontFamily ?? defaults.defaultFontFamily;
|
|
3563
5428
|
const fontSize = style?.fontSize ?? defaults.defaultFontSize;
|
|
3564
|
-
const
|
|
5429
|
+
const color2 = style?.color ?? "#000000";
|
|
3565
5430
|
const align = style?.align ?? "left";
|
|
3566
5431
|
let textAnchor = "start";
|
|
3567
5432
|
let textX = 4;
|
|
@@ -3580,7 +5445,7 @@ function renderText(el, defaults) {
|
|
|
3580
5445
|
"text-anchor": textAnchor,
|
|
3581
5446
|
"font-family": fontFamily,
|
|
3582
5447
|
"font-size": fontSize,
|
|
3583
|
-
fill:
|
|
5448
|
+
fill: color2
|
|
3584
5449
|
})}>`
|
|
3585
5450
|
);
|
|
3586
5451
|
let dy = fontSize * 1.2;
|
|
@@ -3607,7 +5472,7 @@ function renderText(el, defaults) {
|
|
|
3607
5472
|
if (segStyle.fontSize && segStyle.fontSize !== fontSize) {
|
|
3608
5473
|
segAttrs["font-size"] = segStyle.fontSize;
|
|
3609
5474
|
}
|
|
3610
|
-
if (segStyle.color && segStyle.color !==
|
|
5475
|
+
if (segStyle.color && segStyle.color !== color2) {
|
|
3611
5476
|
segAttrs.fill = segStyle.color;
|
|
3612
5477
|
}
|
|
3613
5478
|
if (segStyle.bold) {
|
|
@@ -3634,7 +5499,7 @@ function renderText(el, defaults) {
|
|
|
3634
5499
|
"text-anchor": textAnchor,
|
|
3635
5500
|
"font-family": fontFamily,
|
|
3636
5501
|
"font-size": fontSize,
|
|
3637
|
-
fill:
|
|
5502
|
+
fill: color2,
|
|
3638
5503
|
"font-weight": bold ? "bold" : void 0,
|
|
3639
5504
|
"font-style": italic ? "italic" : void 0
|
|
3640
5505
|
})}>`
|
|
@@ -3823,8 +5688,8 @@ function renderGroup(el, defaults, ctx) {
|
|
|
3823
5688
|
return "";
|
|
3824
5689
|
}
|
|
3825
5690
|
const parts = [];
|
|
3826
|
-
for (const
|
|
3827
|
-
parts.push(renderElement(
|
|
5691
|
+
for (const child2 of el.children) {
|
|
5692
|
+
parts.push(renderElement(child2, defaults, ctx));
|
|
3828
5693
|
}
|
|
3829
5694
|
return parts.join("");
|
|
3830
5695
|
}
|
|
@@ -3835,14 +5700,14 @@ function renderInk(el) {
|
|
|
3835
5700
|
const parts = [];
|
|
3836
5701
|
for (let i = 0; i < el.inkPaths.length; i++) {
|
|
3837
5702
|
const path = el.inkPaths[i];
|
|
3838
|
-
const
|
|
5703
|
+
const color2 = el.inkColors?.[i] ?? "#000000";
|
|
3839
5704
|
const width = el.inkWidths?.[i] ?? 1;
|
|
3840
5705
|
const opacity = el.inkOpacities?.[i];
|
|
3841
5706
|
parts.push(
|
|
3842
5707
|
`<path${attrs({
|
|
3843
5708
|
d: path,
|
|
3844
5709
|
fill: "none",
|
|
3845
|
-
stroke:
|
|
5710
|
+
stroke: color2,
|
|
3846
5711
|
"stroke-width": width,
|
|
3847
5712
|
"stroke-opacity": opacity,
|
|
3848
5713
|
"stroke-linecap": "round"
|
|
@@ -3900,12 +5765,26 @@ function renderElement(el, defaults, ctx) {
|
|
|
3900
5765
|
inner = renderInk(el);
|
|
3901
5766
|
break;
|
|
3902
5767
|
case "chart":
|
|
5768
|
+
inner = renderChartSvg(el) ?? renderPlaceholder(el);
|
|
5769
|
+
break;
|
|
3903
5770
|
case "smartArt":
|
|
5771
|
+
inner = renderSmartArtSvg(el) ?? renderPlaceholder(el);
|
|
5772
|
+
break;
|
|
3904
5773
|
case "ole":
|
|
5774
|
+
inner = renderOlePreviewSvg(el) ?? renderPlaceholder(el);
|
|
5775
|
+
break;
|
|
3905
5776
|
case "media":
|
|
5777
|
+
inner = renderMediaPreviewSvg(el) ?? renderPlaceholder(el);
|
|
5778
|
+
break;
|
|
5779
|
+
case "model3d":
|
|
5780
|
+
inner = renderModel3DPreviewSvg(el) ?? renderPlaceholder(el);
|
|
5781
|
+
break;
|
|
3906
5782
|
case "contentPart":
|
|
5783
|
+
inner = renderContentPartSvg(el) ?? renderPlaceholder(el);
|
|
5784
|
+
break;
|
|
3907
5785
|
case "zoom":
|
|
3908
|
-
|
|
5786
|
+
inner = renderZoomPreviewSvg(el) ?? renderPlaceholder(el);
|
|
5787
|
+
break;
|
|
3909
5788
|
case "unknown":
|
|
3910
5789
|
inner = renderPlaceholder(el);
|
|
3911
5790
|
break;
|