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