ooxml-core 1.0.0 → 1.1.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/dist/{PptxHandler-G63S6YZU.mjs → PptxHandler-75LOVF7I.mjs} +2 -2
- package/dist/automation/index.cjs +2559 -1169
- package/dist/automation/index.mjs +2559 -1169
- package/dist/chart/gradient-definition.d.ts +2 -2
- package/dist/chart/gradient-definition.d.ts.map +1 -1
- package/dist/chart/index.cjs +7 -7
- package/dist/chart/index.mjs +7 -7
- package/dist/{chunk-BICQYRPW.mjs → chunk-75LA7H3F.mjs} +1339 -1435
- package/dist/{chunk-CKJSWE7N.mjs → chunk-LA7D6ZYQ.mjs} +244 -115
- package/dist/{chunk-ROM5MZ7O.mjs → chunk-OMGH6IKY.mjs} +3 -3
- package/dist/{chunk-RWXFQJVF.mjs → chunk-Q27H4HFS.mjs} +1 -1
- package/dist/{chunk-DDG5HTGX.mjs → chunk-RFX7AJDZ.mjs} +1 -1
- package/dist/crypto/index.cjs +1406 -184
- package/dist/crypto/index.mjs +1406 -184
- package/dist/diagram/dom.d.ts +1 -14
- package/dist/diagram/dom.d.ts.map +1 -1
- package/dist/diagram/index.cjs +15 -15
- package/dist/diagram/index.d.ts +12 -12
- package/dist/diagram/index.d.ts.map +1 -1
- package/dist/diagram/index.mjs +15 -15
- package/dist/diagram/types.d.ts +12 -148
- package/dist/diagram/types.d.ts.map +1 -1
- package/dist/digest/algorithm-names.d.ts +2 -2
- package/dist/digest/algorithm-names.d.ts.map +1 -1
- package/dist/digest/bit-ops.d.ts +30 -0
- package/dist/digest/bit-ops.d.ts.map +1 -0
- package/dist/digest/digest.d.ts +2 -2
- package/dist/digest/digest.d.ts.map +1 -1
- package/dist/digest/index.cjs +1319 -90
- package/dist/digest/index.d.ts +7 -1
- package/dist/digest/index.d.ts.map +1 -1
- package/dist/digest/index.mjs +1313 -91
- package/dist/digest/md2.d.ts +22 -0
- package/dist/digest/md2.d.ts.map +1 -0
- package/dist/digest/md4.d.ts +3 -0
- package/dist/digest/md4.d.ts.map +1 -0
- package/dist/digest/md5.d.ts +3 -0
- package/dist/digest/md5.d.ts.map +1 -0
- package/dist/digest/password-hash.d.ts +7 -0
- package/dist/digest/password-hash.d.ts.map +1 -1
- package/dist/digest/ripemd-functions.d.ts +18 -0
- package/dist/digest/ripemd-functions.d.ts.map +1 -0
- package/dist/digest/ripemd128.d.ts +3 -0
- package/dist/digest/ripemd128.d.ts.map +1 -0
- package/dist/digest/ripemd160.d.ts +3 -0
- package/dist/digest/ripemd160.d.ts.map +1 -0
- package/dist/digest/whirlpool-sbox.d.ts +15 -0
- package/dist/digest/whirlpool-sbox.d.ts.map +1 -0
- package/dist/digest/whirlpool-table.d.ts +12 -0
- package/dist/digest/whirlpool-table.d.ts.map +1 -0
- package/dist/digest/whirlpool.d.ts +3 -0
- package/dist/digest/whirlpool.d.ts.map +1 -0
- package/dist/docx/block-parser.d.ts.map +1 -1
- package/dist/docx/diagram-theme.d.ts +3 -3
- package/dist/docx/diagram-theme.d.ts.map +1 -1
- package/dist/docx/embedded.cjs +470 -276
- package/dist/docx/embedded.mjs +470 -276
- package/dist/docx/field-flags.d.ts +8 -0
- package/dist/docx/field-flags.d.ts.map +1 -0
- package/dist/docx/field-lock.d.ts +6 -0
- package/dist/docx/field-lock.d.ts.map +1 -0
- package/dist/docx/field-runs.d.ts +4 -1
- package/dist/docx/field-runs.d.ts.map +1 -1
- package/dist/docx/index.cjs +1029 -850
- package/dist/docx/index.d.ts +2 -0
- package/dist/docx/index.d.ts.map +1 -1
- package/dist/docx/index.mjs +1027 -850
- package/dist/docx/layout/adapter.d.ts.map +1 -1
- package/dist/docx/layout/index.cjs +61 -47
- package/dist/docx/layout/index.mjs +61 -47
- package/dist/docx/layout/page-fields.d.ts.map +1 -1
- package/dist/docx/load/index.cjs +1883 -467
- package/dist/docx/load/index.mjs +1883 -467
- package/dist/docx/model-run.d.ts +5 -0
- package/dist/docx/model-run.d.ts.map +1 -1
- package/dist/docx/numbering-model.d.ts +1 -1
- package/dist/docx/numbering-model.d.ts.map +1 -1
- package/dist/docx/numbering-package.d.ts +4 -4
- package/dist/docx/numbering-package.d.ts.map +1 -1
- package/dist/docx/numbering-start-edit.d.ts +8 -0
- package/dist/docx/numbering-start-edit.d.ts.map +1 -0
- package/dist/docx/numbering-start-patch.d.ts +13 -0
- package/dist/docx/numbering-start-patch.d.ts.map +1 -0
- package/dist/docx/theme-color.d.ts.map +1 -1
- package/dist/docx/theme-model.d.ts +3 -2
- package/dist/docx/theme-model.d.ts.map +1 -1
- package/dist/docx/theme.d.ts +5 -1
- package/dist/docx/theme.d.ts.map +1 -1
- package/dist/docx/ui/field-guard.d.ts +2 -0
- package/dist/docx/ui/field-guard.d.ts.map +1 -1
- package/dist/docx/ui/field-results.d.ts.map +1 -1
- package/dist/docx/ui/index.cjs +547 -375
- package/dist/docx/ui/index.mjs +547 -376
- package/dist/docx/ui/review-commands.d.ts.map +1 -1
- package/dist/docx/ui/run-extra-mark.d.ts +1 -1
- package/dist/docx/ui/run-extra-mark.d.ts.map +1 -1
- package/dist/docx/ui/simple-field-input.d.ts +3 -0
- package/dist/docx/ui/simple-field-input.d.ts.map +1 -1
- package/dist/docx/ui/track-changes-mode.d.ts.map +1 -1
- package/dist/docx/ui/track-paragraph-boundaries.d.ts +5 -0
- package/dist/docx/ui/track-paragraph-boundaries.d.ts.map +1 -0
- package/dist/docx/write-inline.d.ts.map +1 -1
- package/dist/docx/write-run.d.ts.map +1 -1
- package/dist/drawingml/dom.d.ts +15 -0
- package/dist/drawingml/dom.d.ts.map +1 -0
- package/dist/drawingml/drawing-color-brightness.d.ts +6 -0
- package/dist/drawingml/drawing-color-brightness.d.ts.map +1 -0
- package/dist/drawingml/drawing-color-css.d.ts.map +1 -0
- package/dist/{diagram → drawingml}/drawing-color.d.ts +5 -5
- package/dist/drawingml/drawing-color.d.ts.map +1 -0
- package/dist/{diagram → drawingml}/drawing-fill.d.ts +3 -3
- package/dist/drawingml/drawing-fill.d.ts.map +1 -0
- package/dist/{diagram → drawingml}/drawing-geometry.d.ts +4 -4
- package/dist/drawingml/drawing-geometry.d.ts.map +1 -0
- package/dist/drawingml/drawing-shadow.d.ts.map +1 -0
- package/dist/{diagram → drawingml}/drawing-text.d.ts +2 -2
- package/dist/drawingml/drawing-text.d.ts.map +1 -0
- package/dist/{diagram → drawingml}/gradient-geometry.d.ts +2 -2
- package/dist/drawingml/gradient-geometry.d.ts.map +1 -0
- package/dist/drawingml/gradient-preset-data.d.ts.map +1 -0
- package/dist/{diagram → drawingml}/gradient-presets.d.ts +3 -3
- package/dist/drawingml/gradient-presets.d.ts.map +1 -0
- package/dist/drawingml/index.cjs +1545 -0
- package/dist/drawingml/index.d.ts +19 -0
- package/dist/drawingml/index.d.ts.map +1 -0
- package/dist/drawingml/index.mjs +1497 -0
- package/dist/{diagram → drawingml}/ordered-color-transforms.d.ts +2 -2
- package/dist/drawingml/ordered-color-transforms.d.ts.map +1 -0
- package/dist/drawingml/rect-path-gradient.d.ts.map +1 -0
- package/dist/drawingml/theme-color.d.ts +19 -0
- package/dist/drawingml/theme-color.d.ts.map +1 -0
- package/dist/drawingml/theme-model.d.ts +40 -0
- package/dist/drawingml/theme-model.d.ts.map +1 -0
- package/dist/drawingml/theme.d.ts +21 -0
- package/dist/drawingml/theme.d.ts.map +1 -0
- package/dist/drawingml/types.d.ts +152 -0
- package/dist/drawingml/types.d.ts.map +1 -0
- package/dist/drawingml/write-color.d.ts +4 -0
- package/dist/drawingml/write-color.d.ts.map +1 -0
- package/dist/{diagram → drawingml}/write-fill.d.ts +2 -2
- package/dist/drawingml/write-fill.d.ts.map +1 -0
- package/dist/geometry/connector-elbow-geometry.d.ts +14 -0
- package/dist/geometry/connector-elbow-geometry.d.ts.map +1 -1
- package/dist/geometry/index.cjs +43 -0
- package/dist/geometry/index.mjs +42 -1
- package/dist/i18n/dictionary.d.ts +13 -0
- package/dist/i18n/dictionary.d.ts.map +1 -0
- package/dist/i18n/index.cjs +68 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.mjs +60 -0
- package/dist/i18n/locale.d.ts +17 -0
- package/dist/i18n/locale.d.ts.map +1 -0
- package/dist/i18n/translator.d.ts +18 -0
- package/dist/i18n/translator.d.ts.map +1 -0
- package/dist/index.cjs +3712 -2178
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +3711 -2179
- package/dist/pptx/automation/index.cjs +2852 -1568
- package/dist/pptx/automation/index.d.ts +3 -3
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/chunks/{index-C4mfzVoY.d.ts → index-BHqL5KXH.d.ts} +2 -2
- package/dist/pptx/chunks/{index-C4mfzVoY.d.ts.map → index-BHqL5KXH.d.ts.map} +1 -1
- package/dist/pptx/chunks/{index-lk7dyOPS.d.ts → index-BYkdcS8J.d.ts} +12 -16
- package/dist/pptx/chunks/index-BYkdcS8J.d.ts.map +1 -0
- package/dist/pptx/chunks/smart-art-CO2jmJFf.d.ts.map +1 -1
- package/dist/pptx/chunks/{text-operations-CDLx4hD5.d.ts → text-operations-DEJ7alZR.d.ts} +2 -2
- package/dist/pptx/chunks/text-operations-DEJ7alZR.d.ts.map +1 -0
- package/dist/pptx/cli/index.cjs +2680 -1396
- package/dist/pptx/cli/index.d.ts +1 -1
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.d.ts +1 -1
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/index.cjs +1771 -1756
- package/dist/pptx/index.d.ts +3 -3
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +144 -74
- package/dist/teams/index.mjs +144 -74
- package/dist/visio/ui/index.cjs +14 -3
- package/dist/visio/ui/index.mjs +14 -3
- package/dist/visio/ui/shape-rotation.d.ts +1 -1
- package/dist/visio/ui/shape-rotation.d.ts.map +1 -1
- package/dist/xlsx/edit/chart-series-gradient.d.ts +1 -1
- package/dist/xlsx/edit/chart-series-gradient.d.ts.map +1 -1
- package/dist/xlsx/edit/protection.d.ts +1 -1
- package/dist/xlsx/index.cjs +3222 -1886
- package/dist/xlsx/index.mjs +3222 -1886
- package/dist/xlsx/layout/chart-appearance.d.ts +1 -1
- package/dist/xlsx/layout/chart-appearance.d.ts.map +1 -1
- package/dist/xlsx/layout/chart-scale.d.ts +5 -1
- package/dist/xlsx/layout/chart-scale.d.ts.map +1 -1
- package/dist/xlsx/layout/chart-svg-legend.d.ts +13 -0
- package/dist/xlsx/layout/chart-svg-legend.d.ts.map +1 -0
- package/dist/xlsx/layout/chart-svg.d.ts.map +1 -1
- package/dist/xlsx/layout/chart-view.d.ts +3 -1
- package/dist/xlsx/layout/chart-view.d.ts.map +1 -1
- package/dist/xlsx/load/index.cjs +2110 -838
- package/dist/xlsx/load/index.mjs +2110 -838
- package/dist/xlsx/read/theme.d.ts +2 -4
- package/dist/xlsx/read/theme.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +2017 -771
- package/dist/xlsx/ui/index.mjs +2017 -771
- package/dist/xlsx/ui/locales/merge.d.ts +2 -1
- package/dist/xlsx/ui/locales/merge.d.ts.map +1 -1
- package/dist/xlsx/ui/localization.d.ts.map +1 -1
- package/dist/xlsx/write/theme.d.ts.map +1 -1
- package/package.json +11 -1
- package/dist/diagram/drawing-color-brightness.d.ts +0 -6
- package/dist/diagram/drawing-color-brightness.d.ts.map +0 -1
- package/dist/diagram/drawing-color-css.d.ts.map +0 -1
- package/dist/diagram/drawing-color.d.ts.map +0 -1
- package/dist/diagram/drawing-fill.d.ts.map +0 -1
- package/dist/diagram/drawing-geometry.d.ts.map +0 -1
- package/dist/diagram/drawing-shadow.d.ts.map +0 -1
- package/dist/diagram/drawing-text.d.ts.map +0 -1
- package/dist/diagram/gradient-geometry.d.ts.map +0 -1
- package/dist/diagram/gradient-preset-data.d.ts.map +0 -1
- package/dist/diagram/gradient-presets.d.ts.map +0 -1
- package/dist/diagram/ordered-color-transforms.d.ts.map +0 -1
- package/dist/diagram/rect-path-gradient.d.ts.map +0 -1
- package/dist/diagram/write-color.d.ts +0 -4
- package/dist/diagram/write-color.d.ts.map +0 -1
- package/dist/diagram/write-fill.d.ts.map +0 -1
- package/dist/pptx/chunks/index-lk7dyOPS.d.ts.map +0 -1
- package/dist/pptx/chunks/text-operations-CDLx4hD5.d.ts.map +0 -1
- /package/dist/{diagram → drawingml}/drawing-color-css.d.ts +0 -0
- /package/dist/{diagram → drawingml}/drawing-shadow.d.ts +0 -0
- /package/dist/{diagram → drawingml}/gradient-preset-data.d.ts +0 -0
- /package/dist/{diagram → drawingml}/rect-path-gradient.d.ts +0 -0
|
@@ -0,0 +1,1497 @@
|
|
|
1
|
+
import { XMLSerializer, DOMParser } from '@xmldom/xmldom';
|
|
2
|
+
|
|
3
|
+
// xml/namespaces.ts
|
|
4
|
+
var NS = {
|
|
5
|
+
/** DrawingML main. */
|
|
6
|
+
a: "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
7
|
+
/** Relationships (`r:id`, `r:embed`). */
|
|
8
|
+
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships"};
|
|
9
|
+
function parseXml(xml, options = {}) {
|
|
10
|
+
const label = options.label ?? "OOXML";
|
|
11
|
+
if (/<!DOCTYPE|<!ENTITY/i.test(xml))
|
|
12
|
+
throw new Error(`${label} XML with DTD or entity declarations is not supported`);
|
|
13
|
+
let parseError = "";
|
|
14
|
+
let parsed;
|
|
15
|
+
try {
|
|
16
|
+
parsed = new DOMParser({
|
|
17
|
+
onError: (level, message) => {
|
|
18
|
+
if (level !== "warning") parseError = message;
|
|
19
|
+
}
|
|
20
|
+
}).parseFromString(xml, "application/xml");
|
|
21
|
+
} catch (error) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Invalid ${label} XML: ${error instanceof Error ? error.message : String(error)}`,
|
|
24
|
+
{ cause: error }
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
if (parseError || !parsed.documentElement)
|
|
28
|
+
throw new Error(`Invalid ${label} XML: ${parseError || "missing root element"}`);
|
|
29
|
+
return parsed;
|
|
30
|
+
}
|
|
31
|
+
var buildXml = (node) => new XMLSerializer().serializeToString(node);
|
|
32
|
+
var isElement = (node) => node.nodeType === 1;
|
|
33
|
+
var elements = (parent) => Array.from(parent.childNodes).filter(isElement);
|
|
34
|
+
function named(element, local, ns, lenient = true) {
|
|
35
|
+
if (!element || element.localName !== local) return false;
|
|
36
|
+
return element.namespaceURI === ns || lenient && !element.namespaceURI;
|
|
37
|
+
}
|
|
38
|
+
var children = (parent, local, ns, lenient = true) => elements(parent).filter((element) => named(element, local, ns, lenient));
|
|
39
|
+
var first = (parent, local, ns, lenient = true) => parent ? children(parent, local, ns, lenient)[0] : void 0;
|
|
40
|
+
|
|
41
|
+
// drawingml/dom.ts
|
|
42
|
+
function attributeReader(element) {
|
|
43
|
+
return (name) => {
|
|
44
|
+
if (!element) return void 0;
|
|
45
|
+
const direct = element.getAttribute(name);
|
|
46
|
+
if (direct !== null) return direct;
|
|
47
|
+
const attributes = element.attributes;
|
|
48
|
+
for (let index = 0; index < attributes.length; index++) {
|
|
49
|
+
const candidate = attributes.item(index);
|
|
50
|
+
if (candidate && candidate.localName === name) return candidate.value;
|
|
51
|
+
}
|
|
52
|
+
return void 0;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function stringAttribute(element, name) {
|
|
56
|
+
const value = attributeReader(element)(name)?.trim();
|
|
57
|
+
return value ? value : void 0;
|
|
58
|
+
}
|
|
59
|
+
function integerAttribute(element, name) {
|
|
60
|
+
const parsed = Number.parseInt(attributeReader(element)(name) ?? "", 10);
|
|
61
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
62
|
+
}
|
|
63
|
+
function booleanAttribute(element, name) {
|
|
64
|
+
const value = attributeReader(element)(name)?.trim().toLowerCase();
|
|
65
|
+
if (value === "1" || value === "true") return true;
|
|
66
|
+
if (value === "0" || value === "false") return false;
|
|
67
|
+
return void 0;
|
|
68
|
+
}
|
|
69
|
+
function descendants(root, local) {
|
|
70
|
+
const result = [];
|
|
71
|
+
const visit = (node) => {
|
|
72
|
+
for (const child of Array.from(node.childNodes)) {
|
|
73
|
+
if (!isElement(child)) continue;
|
|
74
|
+
if (child.localName === local) result.push(child);
|
|
75
|
+
visit(child);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
visit(root);
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// color/color-primitives.ts
|
|
83
|
+
function clampUnitInterval(value) {
|
|
84
|
+
return Math.min(1, Math.max(0, value));
|
|
85
|
+
}
|
|
86
|
+
function hexToRgbChannels(color) {
|
|
87
|
+
const normalized = color.replace("#", "");
|
|
88
|
+
if (!/^[0-9a-fA-F]{6}$/.test(normalized)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
r: Number.parseInt(normalized.slice(0, 2), 16),
|
|
93
|
+
g: Number.parseInt(normalized.slice(2, 4), 16),
|
|
94
|
+
b: Number.parseInt(normalized.slice(4, 6), 16)
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function percentDivisorFor(text) {
|
|
98
|
+
return text.endsWith("%") ? 100 : 1e5;
|
|
99
|
+
}
|
|
100
|
+
function parseOoxmlPercent(value) {
|
|
101
|
+
const text = String(value ?? "").trim();
|
|
102
|
+
const divisor = percentDivisorFor(text);
|
|
103
|
+
const magnitude = Number.parseFloat(divisor === 100 ? text.slice(0, -1) : text);
|
|
104
|
+
if (!Number.isFinite(magnitude)) {
|
|
105
|
+
return void 0;
|
|
106
|
+
}
|
|
107
|
+
return magnitude / divisor;
|
|
108
|
+
}
|
|
109
|
+
function parseDrawingPercent(value) {
|
|
110
|
+
const parsed = parseOoxmlPercent(value);
|
|
111
|
+
return parsed === void 0 ? void 0 : clampUnitInterval(parsed);
|
|
112
|
+
}
|
|
113
|
+
function scrgbLinearToSrgb8(linear) {
|
|
114
|
+
const l = Math.min(1, Math.max(0, linear));
|
|
115
|
+
const companded = l <= 31308e-7 ? 12.92 * l : 1.055 * l ** (1 / 2.4) - 0.055;
|
|
116
|
+
return Math.min(255, Math.max(0, Math.round(companded * 255)));
|
|
117
|
+
}
|
|
118
|
+
function toHex(value) {
|
|
119
|
+
return Math.min(255, Math.max(0, Math.round(value))).toString(16).padStart(2, "0").toUpperCase();
|
|
120
|
+
}
|
|
121
|
+
function rgbToHsl(r, g, b) {
|
|
122
|
+
const rN = r / 255;
|
|
123
|
+
const gN = g / 255;
|
|
124
|
+
const bN = b / 255;
|
|
125
|
+
const cMax = Math.max(rN, gN, bN);
|
|
126
|
+
const cMin = Math.min(rN, gN, bN);
|
|
127
|
+
const delta = cMax - cMin;
|
|
128
|
+
const l = (cMax + cMin) / 2;
|
|
129
|
+
let s = 0;
|
|
130
|
+
if (delta !== 0) {
|
|
131
|
+
s = delta / (1 - Math.abs(2 * l - 1));
|
|
132
|
+
}
|
|
133
|
+
let h = 0;
|
|
134
|
+
if (delta !== 0) {
|
|
135
|
+
if (cMax === rN) {
|
|
136
|
+
h = 60 * ((gN - bN) / delta % 6);
|
|
137
|
+
} else if (cMax === gN) {
|
|
138
|
+
h = 60 * ((bN - rN) / delta + 2);
|
|
139
|
+
} else {
|
|
140
|
+
h = 60 * ((rN - gN) / delta + 4);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (h < 0) {
|
|
144
|
+
h += 360;
|
|
145
|
+
}
|
|
146
|
+
return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
|
|
147
|
+
}
|
|
148
|
+
function hslToRgb(h, s, l, roundChannel = Math.round, options) {
|
|
149
|
+
const sC = options?.clampSaturation === false ? s : clampUnitInterval(s);
|
|
150
|
+
const lC = clampUnitInterval(l);
|
|
151
|
+
const hN = (h % 360 + 360) % 360;
|
|
152
|
+
const c = (1 - Math.abs(2 * lC - 1)) * sC;
|
|
153
|
+
const x = c * (1 - Math.abs(hN / 60 % 2 - 1));
|
|
154
|
+
const m = lC - c / 2;
|
|
155
|
+
let rP = 0;
|
|
156
|
+
let gP = 0;
|
|
157
|
+
let bP = 0;
|
|
158
|
+
if (hN < 60) {
|
|
159
|
+
rP = c;
|
|
160
|
+
gP = x;
|
|
161
|
+
bP = 0;
|
|
162
|
+
} else if (hN < 120) {
|
|
163
|
+
rP = x;
|
|
164
|
+
gP = c;
|
|
165
|
+
bP = 0;
|
|
166
|
+
} else if (hN < 180) {
|
|
167
|
+
rP = 0;
|
|
168
|
+
gP = c;
|
|
169
|
+
bP = x;
|
|
170
|
+
} else if (hN < 240) {
|
|
171
|
+
rP = 0;
|
|
172
|
+
gP = x;
|
|
173
|
+
bP = c;
|
|
174
|
+
} else if (hN < 300) {
|
|
175
|
+
rP = x;
|
|
176
|
+
gP = 0;
|
|
177
|
+
bP = c;
|
|
178
|
+
} else {
|
|
179
|
+
rP = c;
|
|
180
|
+
gP = 0;
|
|
181
|
+
bP = x;
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
r: roundChannel((rP + m) * 255),
|
|
185
|
+
g: roundChannel((gP + m) * 255),
|
|
186
|
+
b: roundChannel((bP + m) * 255)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function parseDrawingFraction(value) {
|
|
190
|
+
return parseOoxmlPercent(value);
|
|
191
|
+
}
|
|
192
|
+
function parseDrawingHueDegrees(value) {
|
|
193
|
+
const parsed = Number.parseFloat(String(value ?? "").trim());
|
|
194
|
+
if (!Number.isFinite(parsed)) {
|
|
195
|
+
return void 0;
|
|
196
|
+
}
|
|
197
|
+
return parsed / 6e4;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// color/color-linear.ts
|
|
201
|
+
function srgb255ToLinear(channel) {
|
|
202
|
+
const c = clampUnitInterval(channel / 255);
|
|
203
|
+
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
204
|
+
}
|
|
205
|
+
function linearToSrgb255(linear) {
|
|
206
|
+
const c = clampUnitInterval(linear);
|
|
207
|
+
return 255 * (c <= 31308e-7 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// drawingml/ordered-color-transforms.ts
|
|
211
|
+
function orderedColorTransforms(channels, transforms) {
|
|
212
|
+
let { r, g, b } = channels;
|
|
213
|
+
let alpha = 1;
|
|
214
|
+
const wrap = (value) => (value % 360 + 360) % 360;
|
|
215
|
+
for (const transform of transforms) {
|
|
216
|
+
const { name, value } = transform;
|
|
217
|
+
const fraction = parseDrawingFraction(value);
|
|
218
|
+
if (name === "alpha" && fraction !== void 0) alpha = clampUnitInterval(fraction);
|
|
219
|
+
else if (name === "alphaMod" && fraction !== void 0)
|
|
220
|
+
alpha = clampUnitInterval(alpha * fraction);
|
|
221
|
+
else if (name === "alphaOff" && fraction !== void 0)
|
|
222
|
+
alpha = clampUnitInterval(alpha + fraction);
|
|
223
|
+
else if (name === "inv") [r, g, b] = [255 - r, 255 - g, 255 - b];
|
|
224
|
+
else if (name === "gray") r = g = b = 0.299 * r + 0.587 * g + 0.114 * b;
|
|
225
|
+
else if ((name === "shade" || name === "tint") && fraction !== void 0) {
|
|
226
|
+
const mix = (channel) => linearToSrgb255(
|
|
227
|
+
name === "shade" ? srgb255ToLinear(channel) * fraction : 1 - (1 - srgb255ToLinear(channel)) * fraction
|
|
228
|
+
);
|
|
229
|
+
[r, g, b] = [mix(r), mix(g), mix(b)];
|
|
230
|
+
} else {
|
|
231
|
+
const hsl = rgbToHsl(r, g, b);
|
|
232
|
+
if (name === "comp") hsl.h = wrap(hsl.h + 180);
|
|
233
|
+
else if (name === "hue") {
|
|
234
|
+
const hue = parseDrawingHueDegrees(value);
|
|
235
|
+
if (hue !== void 0) hsl.h = wrap(hue);
|
|
236
|
+
} else if (name === "hueOff") {
|
|
237
|
+
const hue = parseDrawingHueDegrees(value);
|
|
238
|
+
if (hue !== void 0) hsl.h = wrap(hsl.h + hue);
|
|
239
|
+
} else if (name === "hueMod" && fraction !== void 0) hsl.h = wrap(hsl.h * fraction);
|
|
240
|
+
else if (name === "sat" && fraction !== void 0) hsl.s = clampUnitInterval(fraction);
|
|
241
|
+
else if (name === "satMod" && fraction !== void 0) hsl.s *= fraction;
|
|
242
|
+
else if (name === "satOff" && fraction !== void 0)
|
|
243
|
+
hsl.s = clampUnitInterval(hsl.s + fraction);
|
|
244
|
+
else if (name === "lum" && fraction !== void 0) hsl.l = clampUnitInterval(fraction);
|
|
245
|
+
else if (name === "lumMod" && fraction !== void 0)
|
|
246
|
+
hsl.l = clampUnitInterval(hsl.l * fraction);
|
|
247
|
+
else if (name === "lumOff" && fraction !== void 0)
|
|
248
|
+
hsl.l = clampUnitInterval(hsl.l + fraction);
|
|
249
|
+
else continue;
|
|
250
|
+
({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, (channel) => channel, {
|
|
251
|
+
clampSaturation: false
|
|
252
|
+
}));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return { r, g, b, alpha };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// drawingml/drawing-color.ts
|
|
259
|
+
var COLOR_ELEMENTS = {
|
|
260
|
+
srgbClr: "srgb",
|
|
261
|
+
schemeClr: "scheme",
|
|
262
|
+
sysClr: "system",
|
|
263
|
+
prstClr: "preset",
|
|
264
|
+
scrgbClr: "scrgb",
|
|
265
|
+
hslClr: "hsl"
|
|
266
|
+
};
|
|
267
|
+
function colorValue(kind, element) {
|
|
268
|
+
const attribute = (name) => element.getAttribute(name) ?? "";
|
|
269
|
+
if (kind === "scrgb") return `${attribute("r")},${attribute("g")},${attribute("b")}`;
|
|
270
|
+
if (kind === "hsl") return `${attribute("hue")},${attribute("sat")},${attribute("lum")}`;
|
|
271
|
+
return attribute("val");
|
|
272
|
+
}
|
|
273
|
+
function parseDrawingColorIn(container) {
|
|
274
|
+
if (!container) return void 0;
|
|
275
|
+
for (const element of elements(container)) {
|
|
276
|
+
const kind = COLOR_ELEMENTS[element.localName];
|
|
277
|
+
if (!kind || element.namespaceURI && element.namespaceURI !== NS.a) continue;
|
|
278
|
+
return parseDrawingColor(element);
|
|
279
|
+
}
|
|
280
|
+
return void 0;
|
|
281
|
+
}
|
|
282
|
+
function parseDrawingColor(element) {
|
|
283
|
+
const kind = COLOR_ELEMENTS[element.localName];
|
|
284
|
+
if (!kind) return void 0;
|
|
285
|
+
const color = {
|
|
286
|
+
kind,
|
|
287
|
+
value: colorValue(kind, element),
|
|
288
|
+
transforms: elements(element).map((child) => ({
|
|
289
|
+
name: child.localName,
|
|
290
|
+
value: child.getAttribute("val") ?? ""
|
|
291
|
+
}))
|
|
292
|
+
};
|
|
293
|
+
const fallback = kind === "system" ? element.getAttribute("lastClr") : null;
|
|
294
|
+
if (fallback) color.fallback = fallback;
|
|
295
|
+
return color;
|
|
296
|
+
}
|
|
297
|
+
function parseDrawingColorList(container) {
|
|
298
|
+
if (!container) return [];
|
|
299
|
+
return elements(container).flatMap((element) => {
|
|
300
|
+
const color = parseDrawingColor(element);
|
|
301
|
+
return color ? [color] : [];
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
var PRESET_COLORS = {
|
|
305
|
+
black: "#000000",
|
|
306
|
+
white: "#FFFFFF",
|
|
307
|
+
red: "#FF0000",
|
|
308
|
+
green: "#008000",
|
|
309
|
+
blue: "#0000FF",
|
|
310
|
+
yellow: "#FFFF00",
|
|
311
|
+
gray: "#808080",
|
|
312
|
+
grey: "#808080"
|
|
313
|
+
};
|
|
314
|
+
function baseHex(color, theme) {
|
|
315
|
+
switch (color.kind) {
|
|
316
|
+
case "srgb":
|
|
317
|
+
return /^[0-9a-f]{6}$/i.test(color.value) ? `#${color.value.toUpperCase()}` : void 0;
|
|
318
|
+
case "scheme":
|
|
319
|
+
return theme?.scheme(color.value);
|
|
320
|
+
case "system":
|
|
321
|
+
return color.fallback && /^[0-9a-f]{6}$/i.test(color.fallback) ? `#${color.fallback.toUpperCase()}` : void 0;
|
|
322
|
+
case "preset":
|
|
323
|
+
return PRESET_COLORS[color.value];
|
|
324
|
+
case "scrgb": {
|
|
325
|
+
const [r, g, b] = color.value.split(",").map((part) => parseDrawingFraction(part));
|
|
326
|
+
if (r === void 0 || g === void 0 || b === void 0) return void 0;
|
|
327
|
+
return `#${toHex(scrgbLinearToSrgb8(r))}${toHex(scrgbLinearToSrgb8(g))}${toHex(scrgbLinearToSrgb8(b))}`;
|
|
328
|
+
}
|
|
329
|
+
case "hsl": {
|
|
330
|
+
const [h, s, l] = color.value.split(",");
|
|
331
|
+
const hue = parseDrawingHueDegrees(h);
|
|
332
|
+
const sat = parseDrawingFraction(s);
|
|
333
|
+
const lum = parseDrawingFraction(l);
|
|
334
|
+
if (hue === void 0 || sat === void 0 || lum === void 0) return void 0;
|
|
335
|
+
const { r, g, b } = hslToRgb(hue, sat, lum);
|
|
336
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
var APPLIED = /* @__PURE__ */ new Set([
|
|
341
|
+
"alpha",
|
|
342
|
+
"alphaMod",
|
|
343
|
+
"alphaOff",
|
|
344
|
+
"comp",
|
|
345
|
+
"inv",
|
|
346
|
+
"gray",
|
|
347
|
+
"shade",
|
|
348
|
+
"tint",
|
|
349
|
+
"hue",
|
|
350
|
+
"hueMod",
|
|
351
|
+
"hueOff",
|
|
352
|
+
"sat",
|
|
353
|
+
"satMod",
|
|
354
|
+
"satOff",
|
|
355
|
+
"lum",
|
|
356
|
+
"lumMod",
|
|
357
|
+
"lumOff"
|
|
358
|
+
]);
|
|
359
|
+
function resolveDrawingColor(color, theme, options) {
|
|
360
|
+
const base = baseHex(color, theme);
|
|
361
|
+
const rgb = base ? hexToRgbChannels(base) : null;
|
|
362
|
+
if (!rgb) return void 0;
|
|
363
|
+
if (options?.transformOrder === "document") {
|
|
364
|
+
const value = orderedColorTransforms(rgb, color.transforms);
|
|
365
|
+
const round = options.hslRounding === "halfDown" ? (channel) => Math.ceil(channel - 0.5) : Math.round;
|
|
366
|
+
return {
|
|
367
|
+
hex: `#${toHex(round(value.r))}${toHex(round(value.g))}${toHex(round(value.b))}`,
|
|
368
|
+
alpha: value.alpha,
|
|
369
|
+
unapplied: [...new Set(color.transforms.map((transform) => transform.name))].filter(
|
|
370
|
+
(name) => !APPLIED.has(name)
|
|
371
|
+
)
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
let { r, g, b } = rgb;
|
|
375
|
+
const find = (name) => color.transforms.find((entry) => entry.name === name)?.value;
|
|
376
|
+
const has = (name) => color.transforms.some((entry) => entry.name === name);
|
|
377
|
+
if (has("comp")) {
|
|
378
|
+
const hsl = rgbToHsl(r, g, b);
|
|
379
|
+
({ r, g, b } = hslToRgb((hsl.h + 180) % 360, hsl.s, hsl.l));
|
|
380
|
+
}
|
|
381
|
+
if (has("inv")) [r, g, b] = [255 - r, 255 - g, 255 - b];
|
|
382
|
+
if (has("gray")) r = g = b = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
|
|
383
|
+
const shade = parseDrawingPercent(find("shade"));
|
|
384
|
+
if (shade !== void 0) {
|
|
385
|
+
r = linearToSrgb255(srgb255ToLinear(r) * shade);
|
|
386
|
+
g = linearToSrgb255(srgb255ToLinear(g) * shade);
|
|
387
|
+
b = linearToSrgb255(srgb255ToLinear(b) * shade);
|
|
388
|
+
}
|
|
389
|
+
const tint = parseDrawingPercent(find("tint"));
|
|
390
|
+
if (tint !== void 0) {
|
|
391
|
+
r = linearToSrgb255(1 - (1 - srgb255ToLinear(r)) * tint);
|
|
392
|
+
g = linearToSrgb255(1 - (1 - srgb255ToLinear(g)) * tint);
|
|
393
|
+
b = linearToSrgb255(1 - (1 - srgb255ToLinear(b)) * tint);
|
|
394
|
+
}
|
|
395
|
+
if (["hue", "hueMod", "hueOff", "sat", "satMod", "satOff", "lum", "lumMod", "lumOff"].some(has)) {
|
|
396
|
+
const hsl = rgbToHsl(r, g, b);
|
|
397
|
+
const wrap = (degrees) => (degrees % 360 + 360) % 360;
|
|
398
|
+
const hueAbs = parseDrawingHueDegrees(find("hue"));
|
|
399
|
+
if (hueAbs !== void 0) hsl.h = wrap(hueAbs);
|
|
400
|
+
const hueMod = parseDrawingFraction(find("hueMod"));
|
|
401
|
+
if (hueMod !== void 0) hsl.h = wrap(hsl.h * hueMod);
|
|
402
|
+
const hueOff = parseDrawingHueDegrees(find("hueOff"));
|
|
403
|
+
if (hueOff !== void 0) hsl.h = wrap(hsl.h + hueOff);
|
|
404
|
+
const satAbs = parseDrawingFraction(find("sat"));
|
|
405
|
+
if (satAbs !== void 0) hsl.s = clampUnitInterval(satAbs);
|
|
406
|
+
const satMod = parseDrawingFraction(find("satMod"));
|
|
407
|
+
if (satMod !== void 0) hsl.s = clampUnitInterval(hsl.s * satMod);
|
|
408
|
+
const satOff = parseDrawingFraction(find("satOff"));
|
|
409
|
+
if (satOff !== void 0) hsl.s = clampUnitInterval(hsl.s + satOff);
|
|
410
|
+
const lumAbs = parseDrawingFraction(find("lum"));
|
|
411
|
+
if (lumAbs !== void 0) hsl.l = clampUnitInterval(lumAbs);
|
|
412
|
+
const lumMod = parseDrawingFraction(find("lumMod"));
|
|
413
|
+
if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
|
|
414
|
+
const lumOff = parseDrawingFraction(find("lumOff"));
|
|
415
|
+
if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
|
|
416
|
+
const round = options?.hslRounding === "halfDown" ? (value) => Math.ceil(value - 0.5) : Math.round;
|
|
417
|
+
({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l, round));
|
|
418
|
+
}
|
|
419
|
+
let alpha = parseDrawingPercent(find("alpha")) ?? 1;
|
|
420
|
+
const alphaMod = parseDrawingFraction(find("alphaMod"));
|
|
421
|
+
if (alphaMod !== void 0) alpha = clampUnitInterval(alpha * alphaMod);
|
|
422
|
+
const alphaOff = parseDrawingFraction(find("alphaOff"));
|
|
423
|
+
if (alphaOff !== void 0) alpha = clampUnitInterval(alpha + alphaOff);
|
|
424
|
+
return {
|
|
425
|
+
hex: `#${toHex(r)}${toHex(g)}${toHex(b)}`,
|
|
426
|
+
alpha,
|
|
427
|
+
unapplied: [...new Set(color.transforms.map((entry) => entry.name))].filter(
|
|
428
|
+
(name) => !APPLIED.has(name)
|
|
429
|
+
)
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// drawingml/drawing-color-css.ts
|
|
434
|
+
function drawingColorCss(value) {
|
|
435
|
+
if (!value || value.alpha === 1) return value?.hex;
|
|
436
|
+
const channels = [1, 3, 5].map(
|
|
437
|
+
(offset) => Number.parseInt(value.hex.slice(offset, offset + 2), 16)
|
|
438
|
+
);
|
|
439
|
+
return `rgba(${channels.join(",")},${value.alpha})`;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// drawingml/drawing-color-brightness.ts
|
|
443
|
+
function drawingColorBrightness(color) {
|
|
444
|
+
const transforms = color.transforms.filter(
|
|
445
|
+
(item) => ["lum", "lumMod", "lumOff"].includes(item.name)
|
|
446
|
+
);
|
|
447
|
+
if (!transforms.length) return 0;
|
|
448
|
+
const mod = transforms.find((item) => item.name === "lumMod");
|
|
449
|
+
const off = transforms.find((item) => item.name === "lumOff");
|
|
450
|
+
if (!mod || transforms[0] !== mod || transforms.length !== (off ? 2 : 1)) return void 0;
|
|
451
|
+
const multiplier = Number(mod.value);
|
|
452
|
+
const offset = off ? Number(off.value) : 0;
|
|
453
|
+
if (!mod.value || off && !off.value || !Number.isFinite(multiplier) || !Number.isFinite(offset) || multiplier < 0 || multiplier > 1e5 || offset < 0 || offset > 1e5)
|
|
454
|
+
return void 0;
|
|
455
|
+
if (off && multiplier + offset !== 1e5) return void 0;
|
|
456
|
+
return Math.round(off ? offset : multiplier - 1e5) / 1e3;
|
|
457
|
+
}
|
|
458
|
+
function withDrawingColorBrightness(color, percent) {
|
|
459
|
+
if (!Number.isFinite(percent) || percent < -100 || percent > 100)
|
|
460
|
+
throw new RangeError("Brightness must be from -100 to 100");
|
|
461
|
+
const result = structuredClone(color);
|
|
462
|
+
result.transforms = result.transforms.filter((item) => !["lumMod", "lumOff"].includes(item.name));
|
|
463
|
+
result.transforms.push({
|
|
464
|
+
name: "lumMod",
|
|
465
|
+
value: String(Math.round((100 - Math.abs(percent)) * 1e3))
|
|
466
|
+
});
|
|
467
|
+
if (percent > 0)
|
|
468
|
+
result.transforms.push({ name: "lumOff", value: String(Math.round(percent * 1e3)) });
|
|
469
|
+
return result;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// drawingml/drawing-fill.ts
|
|
473
|
+
var FILL_ELEMENTS = /* @__PURE__ */ new Set([
|
|
474
|
+
"noFill",
|
|
475
|
+
"solidFill",
|
|
476
|
+
"gradFill",
|
|
477
|
+
"pattFill",
|
|
478
|
+
"blipFill",
|
|
479
|
+
"grpFill"
|
|
480
|
+
]);
|
|
481
|
+
function fillElementOf(properties) {
|
|
482
|
+
return properties ? elements(properties).find(
|
|
483
|
+
(element) => FILL_ELEMENTS.has(element.localName) && (!element.namespaceURI || element.namespaceURI === NS.a)
|
|
484
|
+
) : void 0;
|
|
485
|
+
}
|
|
486
|
+
function parseDrawingFill(properties) {
|
|
487
|
+
const fill = fillElementOf(properties);
|
|
488
|
+
if (!fill) return void 0;
|
|
489
|
+
switch (fill.localName) {
|
|
490
|
+
case "noFill":
|
|
491
|
+
return { kind: "none" };
|
|
492
|
+
case "solidFill": {
|
|
493
|
+
const color = parseDrawingColorIn(fill);
|
|
494
|
+
return color ? { kind: "solid", color } : { kind: "unsupported", element: "solidFill" };
|
|
495
|
+
}
|
|
496
|
+
case "gradFill": {
|
|
497
|
+
const stops = children(first(fill, "gsLst", NS.a) ?? fill, "gs", NS.a).flatMap((stop) => {
|
|
498
|
+
const color = parseDrawingColorIn(stop);
|
|
499
|
+
const position = Number.parseInt(stop.getAttribute("pos") ?? "", 10);
|
|
500
|
+
return color && Number.isFinite(position) ? [{ position: position / 1e3, color }] : [];
|
|
501
|
+
});
|
|
502
|
+
const angle = Number.parseInt(first(fill, "lin", NS.a)?.getAttribute("ang") ?? "", 10);
|
|
503
|
+
const scaled = first(fill, "lin", NS.a)?.getAttribute("scaled");
|
|
504
|
+
const path = first(fill, "path", NS.a)?.getAttribute("path");
|
|
505
|
+
const focus = first(first(fill, "path", NS.a), "fillToRect", NS.a);
|
|
506
|
+
const tile = first(fill, "tileRect", NS.a);
|
|
507
|
+
const tileRect = tile ? {
|
|
508
|
+
l: Number(tile.getAttribute("l") ?? 0) / 1e5,
|
|
509
|
+
t: Number(tile.getAttribute("t") ?? 0) / 1e5,
|
|
510
|
+
r: Number(tile.getAttribute("r") ?? 0) / 1e5,
|
|
511
|
+
b: Number(tile.getAttribute("b") ?? 0) / 1e5
|
|
512
|
+
} : void 0;
|
|
513
|
+
const fillToRect = focus ? {
|
|
514
|
+
l: Number(focus.getAttribute("l") ?? 0) / 1e5,
|
|
515
|
+
t: Number(focus.getAttribute("t") ?? 0) / 1e5,
|
|
516
|
+
r: Number(focus.getAttribute("r") ?? 0) / 1e5,
|
|
517
|
+
b: Number(focus.getAttribute("b") ?? 0) / 1e5
|
|
518
|
+
} : void 0;
|
|
519
|
+
return {
|
|
520
|
+
kind: "gradient",
|
|
521
|
+
sourceXml: buildXml(fill),
|
|
522
|
+
stops,
|
|
523
|
+
...Number.isFinite(angle) ? { angle: angle / 6e4 } : {},
|
|
524
|
+
...scaled === "1" || scaled === "true" ? { scaled: true } : {},
|
|
525
|
+
...scaled === "0" || scaled === "false" ? { scaled: false } : {},
|
|
526
|
+
...path ? { path } : {},
|
|
527
|
+
...fillToRect && Object.values(fillToRect).every(Number.isFinite) ? { fillToRect } : {},
|
|
528
|
+
...tileRect && Object.values(tileRect).every(Number.isFinite) ? { tileRect } : {}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
case "pattFill": {
|
|
532
|
+
const foreground = parseDrawingColorIn(first(fill, "fgClr", NS.a));
|
|
533
|
+
const background = parseDrawingColorIn(first(fill, "bgClr", NS.a));
|
|
534
|
+
return {
|
|
535
|
+
kind: "pattern",
|
|
536
|
+
preset: fill.getAttribute("prst") ?? "",
|
|
537
|
+
...foreground ? { foreground } : {},
|
|
538
|
+
...background ? { background } : {}
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
case "blipFill": {
|
|
542
|
+
const blip = first(fill, "blip", NS.a);
|
|
543
|
+
const relId = blip?.getAttributeNS(NS.r, "embed") || blip?.getAttribute("r:embed") || void 0;
|
|
544
|
+
return { kind: "picture", ...relId ? { relId } : {} };
|
|
545
|
+
}
|
|
546
|
+
default:
|
|
547
|
+
return { kind: "unsupported", element: fill.localName };
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
function parseDrawingLine(ln) {
|
|
551
|
+
if (!ln) return void 0;
|
|
552
|
+
const line = {};
|
|
553
|
+
const width = Number.parseInt(ln.getAttribute("w") ?? "", 10);
|
|
554
|
+
if (Number.isFinite(width)) line.widthEmu = width;
|
|
555
|
+
const fill = parseDrawingFill(ln);
|
|
556
|
+
if (fill) line.fill = fill;
|
|
557
|
+
const dash = first(ln, "prstDash", NS.a)?.getAttribute("val");
|
|
558
|
+
if (dash) line.dash = dash;
|
|
559
|
+
const cap = ln.getAttribute("cap");
|
|
560
|
+
if (cap) line.cap = cap;
|
|
561
|
+
return line;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// drawingml/drawing-text.ts
|
|
565
|
+
function parseSpacing(parent) {
|
|
566
|
+
for (const [name, unit, divisor] of [
|
|
567
|
+
["spcPts", "points", 100],
|
|
568
|
+
["spcPct", "percent", 1e5]
|
|
569
|
+
]) {
|
|
570
|
+
const raw = first(parent, name, NS.a)?.getAttribute("val");
|
|
571
|
+
if (raw == null || !/^\d+$/.test(raw)) continue;
|
|
572
|
+
const value = Number(raw) / divisor;
|
|
573
|
+
if (Number.isFinite(value)) return { unit, value };
|
|
574
|
+
}
|
|
575
|
+
return void 0;
|
|
576
|
+
}
|
|
577
|
+
function parseProperties(properties) {
|
|
578
|
+
const parsed = {};
|
|
579
|
+
const size = Number.parseInt(properties?.getAttribute("sz") ?? "", 10);
|
|
580
|
+
if (Number.isFinite(size)) parsed.sizePt = size / 100;
|
|
581
|
+
const bold = booleanAttribute(properties, "b");
|
|
582
|
+
if (bold !== void 0) parsed.bold = bold;
|
|
583
|
+
const italic = booleanAttribute(properties, "i");
|
|
584
|
+
if (italic !== void 0) parsed.italic = italic;
|
|
585
|
+
const underline = properties?.getAttribute("u");
|
|
586
|
+
if (underline) parsed.underline = underline !== "none";
|
|
587
|
+
const color = parseDrawingColorIn(first(properties, "solidFill", NS.a));
|
|
588
|
+
if (color) parsed.color = color;
|
|
589
|
+
const typeface = first(properties, "latin", NS.a)?.getAttribute("typeface");
|
|
590
|
+
if (typeface) parsed.typeface = typeface;
|
|
591
|
+
return parsed;
|
|
592
|
+
}
|
|
593
|
+
function parseRun(run) {
|
|
594
|
+
return {
|
|
595
|
+
text: run.localName === "br" ? "\n" : first(run, "t", NS.a)?.textContent ?? "",
|
|
596
|
+
...parseProperties(first(run, "rPr", NS.a))
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
function parseParagraph(paragraph) {
|
|
600
|
+
const runs = [];
|
|
601
|
+
for (const child of elements(paragraph))
|
|
602
|
+
if (child.namespaceURI === NS.a && ["r", "fld", "br"].includes(child.localName))
|
|
603
|
+
runs.push(parseRun(child));
|
|
604
|
+
const properties = first(paragraph, "pPr", NS.a);
|
|
605
|
+
const align = properties?.getAttribute("algn");
|
|
606
|
+
const defaults = parseProperties(first(properties, "defRPr", NS.a));
|
|
607
|
+
const lineSpacing = parseSpacing(first(properties, "lnSpc", NS.a));
|
|
608
|
+
const spaceBefore = parseSpacing(first(properties, "spcBef", NS.a));
|
|
609
|
+
const spaceAfter = parseSpacing(first(properties, "spcAft", NS.a));
|
|
610
|
+
return {
|
|
611
|
+
...align ? { align } : {},
|
|
612
|
+
...Object.keys(defaults).length ? { defaultProperties: defaults } : {},
|
|
613
|
+
...lineSpacing ? { lineSpacing } : {},
|
|
614
|
+
...spaceBefore ? { spaceBefore } : {},
|
|
615
|
+
...spaceAfter ? { spaceAfter } : {},
|
|
616
|
+
runs
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
function parseDrawingTextBody(body) {
|
|
620
|
+
if (!body) return void 0;
|
|
621
|
+
const properties = first(body, "bodyPr", NS.a);
|
|
622
|
+
const paragraphs = children(body, "p", NS.a).map(parseParagraph);
|
|
623
|
+
const result = {
|
|
624
|
+
paragraphs,
|
|
625
|
+
text: paragraphs.map((paragraph) => paragraph.runs.map((run) => run.text).join("")).join("\n")
|
|
626
|
+
};
|
|
627
|
+
const anchor = properties?.getAttribute("anchor");
|
|
628
|
+
if (anchor) result.anchor = anchor;
|
|
629
|
+
const insets = {};
|
|
630
|
+
for (const [key, attribute] of [
|
|
631
|
+
["left", "lIns"],
|
|
632
|
+
["top", "tIns"],
|
|
633
|
+
["right", "rIns"],
|
|
634
|
+
["bottom", "bIns"]
|
|
635
|
+
]) {
|
|
636
|
+
const value = Number.parseInt(properties?.getAttribute(attribute) ?? "", 10);
|
|
637
|
+
if (Number.isFinite(value)) insets[key] = value;
|
|
638
|
+
}
|
|
639
|
+
if (Object.keys(insets).length > 0) result.insetsEmu = insets;
|
|
640
|
+
return result;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// drawingml/drawing-geometry.ts
|
|
644
|
+
var int = (element, name) => Number.parseInt(element?.getAttribute(name) ?? "", 10);
|
|
645
|
+
function parseFrame(container) {
|
|
646
|
+
const off = first(container, "off", NS.a);
|
|
647
|
+
const ext = first(container, "ext", NS.a);
|
|
648
|
+
if (!off || !ext) return void 0;
|
|
649
|
+
return {
|
|
650
|
+
x: int(off, "x") || 0,
|
|
651
|
+
y: int(off, "y") || 0,
|
|
652
|
+
width: int(ext, "cx") || 0,
|
|
653
|
+
height: int(ext, "cy") || 0
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
function parseTransform(xfrm) {
|
|
657
|
+
const frame = parseFrame(xfrm);
|
|
658
|
+
if (!frame || !xfrm) return void 0;
|
|
659
|
+
const rot = int(xfrm, "rot");
|
|
660
|
+
return {
|
|
661
|
+
frame,
|
|
662
|
+
...Number.isFinite(rot) && rot !== 0 ? { rotation: rot / 6e4 } : {},
|
|
663
|
+
...booleanAttribute(xfrm, "flipH") ? { flipHorizontal: true } : {},
|
|
664
|
+
...booleanAttribute(xfrm, "flipV") ? { flipVertical: true } : {}
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
function parsePathCommands(path) {
|
|
668
|
+
const commands = [];
|
|
669
|
+
const point = (element) => {
|
|
670
|
+
const x = int(element, "x");
|
|
671
|
+
const y = int(element, "y");
|
|
672
|
+
return Number.isFinite(x) && Number.isFinite(y) ? { x, y } : void 0;
|
|
673
|
+
};
|
|
674
|
+
for (const element of Array.from(path.childNodes)) {
|
|
675
|
+
if (element.nodeType !== 1) continue;
|
|
676
|
+
const node = element;
|
|
677
|
+
const points = children(node, "pt", NS.a).map(point);
|
|
678
|
+
if (points.some((entry) => entry === void 0)) return void 0;
|
|
679
|
+
const [p0, p1, p2] = points;
|
|
680
|
+
switch (node.localName) {
|
|
681
|
+
case "moveTo":
|
|
682
|
+
case "lnTo":
|
|
683
|
+
if (!p0) return void 0;
|
|
684
|
+
commands.push({ op: node.localName === "moveTo" ? "M" : "L", ...p0 });
|
|
685
|
+
break;
|
|
686
|
+
case "cubicBezTo":
|
|
687
|
+
if (!p0 || !p1 || !p2) return void 0;
|
|
688
|
+
commands.push({ op: "C", x1: p0.x, y1: p0.y, x2: p1.x, y2: p1.y, x: p2.x, y: p2.y });
|
|
689
|
+
break;
|
|
690
|
+
case "quadBezTo":
|
|
691
|
+
if (!p0 || !p1) return void 0;
|
|
692
|
+
commands.push({ op: "Q", x1: p0.x, y1: p0.y, x: p1.x, y: p1.y });
|
|
693
|
+
break;
|
|
694
|
+
case "arcTo": {
|
|
695
|
+
const wR = int(node, "wR");
|
|
696
|
+
const hR = int(node, "hR");
|
|
697
|
+
const startAngle = int(node, "stAng");
|
|
698
|
+
const swingAngle = int(node, "swAng");
|
|
699
|
+
if (![wR, hR, startAngle, swingAngle].every(Number.isFinite)) return void 0;
|
|
700
|
+
commands.push({
|
|
701
|
+
op: "A",
|
|
702
|
+
wR,
|
|
703
|
+
hR,
|
|
704
|
+
startAngle: startAngle / 6e4,
|
|
705
|
+
swingAngle: swingAngle / 6e4
|
|
706
|
+
});
|
|
707
|
+
break;
|
|
708
|
+
}
|
|
709
|
+
case "close":
|
|
710
|
+
commands.push({ op: "Z" });
|
|
711
|
+
break;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
return commands;
|
|
715
|
+
}
|
|
716
|
+
function parseDrawingGeometry(spPr) {
|
|
717
|
+
const preset = first(spPr, "prstGeom", NS.a);
|
|
718
|
+
const custom = first(spPr, "custGeom", NS.a);
|
|
719
|
+
if (custom) {
|
|
720
|
+
const paths = [];
|
|
721
|
+
for (const path of children(first(custom, "pathLst", NS.a) ?? custom, "path", NS.a)) {
|
|
722
|
+
const commands = parsePathCommands(path);
|
|
723
|
+
if (!commands) return { geometry: "custom", issue: "CUSTOM_GEOMETRY_GUIDES_UNSUPPORTED" };
|
|
724
|
+
const width = int(path, "w");
|
|
725
|
+
const height = int(path, "h");
|
|
726
|
+
paths.push({
|
|
727
|
+
commands,
|
|
728
|
+
...Number.isFinite(width) ? { width } : {},
|
|
729
|
+
...Number.isFinite(height) ? { height } : {},
|
|
730
|
+
...path.getAttribute("fill") ? { fill: path.getAttribute("fill") } : {},
|
|
731
|
+
...path.getAttribute("stroke") === "0" || path.getAttribute("stroke") === "false" ? { stroke: false } : {}
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
return { geometry: "custom", paths };
|
|
735
|
+
}
|
|
736
|
+
const geometry = preset?.getAttribute("prst") || "rect";
|
|
737
|
+
const adjustments = {};
|
|
738
|
+
const avLst = first(preset, "avLst", NS.a);
|
|
739
|
+
if (avLst)
|
|
740
|
+
for (const guide of children(avLst, "gd", NS.a)) {
|
|
741
|
+
const name = guide.getAttribute("name");
|
|
742
|
+
const match = /^val\s+(-?\d+)/u.exec(guide.getAttribute("fmla") ?? "");
|
|
743
|
+
if (name && match?.[1]) adjustments[name] = Number.parseInt(match[1], 10);
|
|
744
|
+
}
|
|
745
|
+
return { geometry, ...Object.keys(adjustments).length > 0 ? { adjustments } : {} };
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// units/constants.ts
|
|
749
|
+
var EMU_PER_PIXEL = 9525;
|
|
750
|
+
|
|
751
|
+
// drawingml/drawing-shadow.ts
|
|
752
|
+
function resolveDrawingShadow(effects, theme) {
|
|
753
|
+
const node = first(effects, "outerShdw", NS.a);
|
|
754
|
+
if (!node) return void 0;
|
|
755
|
+
const value = (key, fallback) => Number(node.getAttribute(key) ?? fallback);
|
|
756
|
+
if (value("sx", 1e5) !== 1e5 || value("sy", 1e5) !== 1e5 || value("kx", 0) !== 0 || value("ky", 0) !== 0)
|
|
757
|
+
return void 0;
|
|
758
|
+
const color = parseDrawingColorIn(node);
|
|
759
|
+
const resolved = color && resolveDrawingColor(color, theme, { transformOrder: "document" });
|
|
760
|
+
const blur = value("blurRad", 0) / EMU_PER_PIXEL;
|
|
761
|
+
const distance = value("dist", 0) / EMU_PER_PIXEL;
|
|
762
|
+
const angle = value("dir", 0) / 6e4 * Math.PI / 180;
|
|
763
|
+
if (!resolved || ![blur, distance, angle].every(Number.isFinite) || blur < 0 || distance < 0)
|
|
764
|
+
return void 0;
|
|
765
|
+
return {
|
|
766
|
+
color: resolved.hex,
|
|
767
|
+
opacity: resolved.alpha,
|
|
768
|
+
blur,
|
|
769
|
+
dx: Math.cos(angle) * distance,
|
|
770
|
+
dy: Math.sin(angle) * distance
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
function resolveDrawingShadowXml(xml, theme) {
|
|
774
|
+
return xml ? resolveDrawingShadow(parseXml(xml).documentElement, theme) : void 0;
|
|
775
|
+
}
|
|
776
|
+
function svgDropShadowElement(s, format) {
|
|
777
|
+
const num = format.number;
|
|
778
|
+
return `<feDropShadow dx="${num(s.dx)}" dy="${num(s.dy)}" stdDeviation="${num(s.blur / 2)}" flood-color="${format.color(s.color, "#000000")}" flood-opacity="${num(s.opacity)}" result="shadow"/>`;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// drawingml/write-color.ts
|
|
782
|
+
var ELEMENTS = {
|
|
783
|
+
srgb: "srgbClr",
|
|
784
|
+
scheme: "schemeClr",
|
|
785
|
+
system: "sysClr",
|
|
786
|
+
preset: "prstClr",
|
|
787
|
+
scrgb: "scrgbClr",
|
|
788
|
+
hsl: "hslClr"
|
|
789
|
+
};
|
|
790
|
+
function drawingColorXml(color) {
|
|
791
|
+
const local = ELEMENTS[color.kind];
|
|
792
|
+
const doc = parseXml(`<a:${local} xmlns:a="${NS.a}"/>`);
|
|
793
|
+
const root = doc.documentElement;
|
|
794
|
+
if (color.kind === "scrgb" || color.kind === "hsl") {
|
|
795
|
+
const keys = color.kind === "scrgb" ? ["r", "g", "b"] : ["hue", "sat", "lum"];
|
|
796
|
+
const values = color.value.split(",");
|
|
797
|
+
keys.forEach((key, i) => root.setAttribute(key, values[i] ?? "0"));
|
|
798
|
+
} else root.setAttribute("val", color.value);
|
|
799
|
+
if (color.fallback !== void 0 && color.kind === "system")
|
|
800
|
+
root.setAttribute("lastClr", color.fallback);
|
|
801
|
+
for (const transform of color.transforms) {
|
|
802
|
+
if (!/^[A-Za-z_][\w.-]*$/.test(transform.name))
|
|
803
|
+
throw new Error(`Invalid DrawingML transform ${transform.name}`);
|
|
804
|
+
const node = doc.createElementNS(NS.a, `a:${transform.name}`);
|
|
805
|
+
if (transform.value !== "") node.setAttribute("val", transform.value);
|
|
806
|
+
root.appendChild(node);
|
|
807
|
+
}
|
|
808
|
+
return buildXml(doc);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// drawingml/write-fill.ts
|
|
812
|
+
function setDrawingFillXml(properties, xml) {
|
|
813
|
+
const doc = properties.ownerDocument;
|
|
814
|
+
const wrapper = parseXml(`<w xmlns:a="${NS.a}">${xml}</w>`);
|
|
815
|
+
const fill = elements(wrapper.documentElement)[0];
|
|
816
|
+
const names = ["solidFill", "gradFill", "pattFill", "blipFill", "grpFill", "noFill"];
|
|
817
|
+
if (elements(wrapper.documentElement).length !== 1 || !fill || fill.namespaceURI !== NS.a || !names.includes(fill.localName))
|
|
818
|
+
throw new Error("Invalid DrawingML fill XML");
|
|
819
|
+
const existing = elements(properties).filter(
|
|
820
|
+
(node) => node.namespaceURI === NS.a && names.includes(node.localName)
|
|
821
|
+
);
|
|
822
|
+
const next = doc.importNode(fill, true);
|
|
823
|
+
if (existing[0]) properties.replaceChild(next, existing[0]);
|
|
824
|
+
else
|
|
825
|
+
properties.insertBefore(
|
|
826
|
+
next,
|
|
827
|
+
elements(properties).find(
|
|
828
|
+
(node) => node.namespaceURI === NS.a && ["ln", "effectLst", "effectDag", "scene3d", "sp3d", "extLst"].includes(node.localName)
|
|
829
|
+
) ?? null
|
|
830
|
+
);
|
|
831
|
+
for (const extra of existing.slice(1)) properties.removeChild(extra);
|
|
832
|
+
}
|
|
833
|
+
function drawingFillXml(fill) {
|
|
834
|
+
if (fill.kind === "none") return "<a:noFill/>";
|
|
835
|
+
if (fill.kind === "solid") return `<a:solidFill>${drawingColorXml(fill.color)}</a:solidFill>`;
|
|
836
|
+
if (fill.kind !== "gradient") return void 0;
|
|
837
|
+
const doc = parseXml(fill.sourceXml ?? `<a:gradFill xmlns:a="${NS.a}"/>`);
|
|
838
|
+
const root = doc.documentElement;
|
|
839
|
+
if (root.namespaceURI !== NS.a || root.localName !== "gradFill")
|
|
840
|
+
throw new Error("Invalid gradient source XML");
|
|
841
|
+
const fragment = (xml) => doc.importNode(elements(parseXml(`<w xmlns:a="${NS.a}">${xml}</w>`).documentElement)[0], true);
|
|
842
|
+
let list = first(root, "gsLst", NS.a);
|
|
843
|
+
if (!list) {
|
|
844
|
+
list = doc.createElementNS(NS.a, "a:gsLst");
|
|
845
|
+
root.insertBefore(list, root.firstChild);
|
|
846
|
+
}
|
|
847
|
+
const stops = children(list, "gs", NS.a).filter(
|
|
848
|
+
(node) => parseDrawingColorIn(node) && Number.isFinite(Number.parseInt(node.getAttribute("pos") ?? "", 10))
|
|
849
|
+
);
|
|
850
|
+
fill.stops.forEach((stop, index) => {
|
|
851
|
+
const node = stops[index] ?? doc.createElementNS(NS.a, "a:gs");
|
|
852
|
+
if (!node.parentNode) list.appendChild(node);
|
|
853
|
+
node.setAttribute("pos", String(Math.round(stop.position * 1e3)));
|
|
854
|
+
for (const old of elements(node))
|
|
855
|
+
if (old.namespaceURI === NS.a && old.localName.endsWith("Clr")) node.removeChild(old);
|
|
856
|
+
node.insertBefore(fragment(drawingColorXml(stop.color)), node.firstChild);
|
|
857
|
+
});
|
|
858
|
+
for (const stop of stops.slice(fill.stops.length)) list.removeChild(stop);
|
|
859
|
+
for (const node of elements(root))
|
|
860
|
+
if (node.namespaceURI === NS.a && (node.localName === "lin" && (fill.angle === void 0 || fill.path !== void 0) || node.localName === "path" && fill.path === void 0))
|
|
861
|
+
root.removeChild(node);
|
|
862
|
+
if (fill.angle !== void 0 && fill.path === void 0) {
|
|
863
|
+
let linear = first(root, "lin", NS.a);
|
|
864
|
+
if (!linear) {
|
|
865
|
+
linear = doc.createElementNS(NS.a, "a:lin");
|
|
866
|
+
root.insertBefore(
|
|
867
|
+
linear,
|
|
868
|
+
first(root, "tileRect", NS.a) ?? first(root, "extLst", NS.a) ?? null
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
linear.setAttribute("ang", String(Math.round(fill.angle * 6e4)));
|
|
872
|
+
if (fill.scaled !== void 0) linear.setAttribute("scaled", fill.scaled ? "1" : "0");
|
|
873
|
+
}
|
|
874
|
+
if (fill.path !== void 0) {
|
|
875
|
+
let path = first(root, "path", NS.a);
|
|
876
|
+
if (!path) {
|
|
877
|
+
path = doc.createElementNS(NS.a, "a:path");
|
|
878
|
+
root.insertBefore(path, first(root, "tileRect", NS.a) ?? first(root, "extLst", NS.a) ?? null);
|
|
879
|
+
}
|
|
880
|
+
path.setAttribute("path", fill.path);
|
|
881
|
+
if (!fill.fillToRect) {
|
|
882
|
+
const old = first(path, "fillToRect", NS.a);
|
|
883
|
+
if (old) path.removeChild(old);
|
|
884
|
+
} else {
|
|
885
|
+
let focus = first(path, "fillToRect", NS.a);
|
|
886
|
+
if (!focus) {
|
|
887
|
+
focus = doc.createElementNS(NS.a, "a:fillToRect");
|
|
888
|
+
path.appendChild(focus);
|
|
889
|
+
}
|
|
890
|
+
for (const [key, value] of Object.entries(fill.fillToRect))
|
|
891
|
+
focus.setAttribute(key, String(Math.round(value * 1e5)));
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
if (fill.tileRect) {
|
|
895
|
+
let tile = first(root, "tileRect", NS.a);
|
|
896
|
+
if (!tile) {
|
|
897
|
+
tile = doc.createElementNS(NS.a, "a:tileRect");
|
|
898
|
+
root.insertBefore(tile, first(root, "extLst", NS.a) ?? null);
|
|
899
|
+
}
|
|
900
|
+
for (const [key, value] of Object.entries(fill.tileRect))
|
|
901
|
+
tile.setAttribute(key, String(Math.round(value * 1e5)));
|
|
902
|
+
}
|
|
903
|
+
return buildXml(doc);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// drawingml/gradient-preset-data.ts
|
|
907
|
+
var OFFICE_GRADIENT_PRESET_DATA = [
|
|
908
|
+
[
|
|
909
|
+
"Early Sunset",
|
|
910
|
+
[
|
|
911
|
+
[0, "000082"],
|
|
912
|
+
[3e4, "66008F"],
|
|
913
|
+
[64999, "BA0066"],
|
|
914
|
+
[89999, "FF0000"],
|
|
915
|
+
[1e5, "FF8200"]
|
|
916
|
+
]
|
|
917
|
+
],
|
|
918
|
+
[
|
|
919
|
+
"Late Sunset",
|
|
920
|
+
[
|
|
921
|
+
[0, "000000"],
|
|
922
|
+
[2e4, "000040"],
|
|
923
|
+
[5e4, "400040"],
|
|
924
|
+
[75e3, "8F0040"],
|
|
925
|
+
[89999, "F27300"],
|
|
926
|
+
[1e5, "FFBF00"]
|
|
927
|
+
]
|
|
928
|
+
],
|
|
929
|
+
[
|
|
930
|
+
"Nightfall",
|
|
931
|
+
[
|
|
932
|
+
[0, "000000"],
|
|
933
|
+
[39999, "0A128C"],
|
|
934
|
+
[7e4, "181CC7"],
|
|
935
|
+
[88e3, "7005D4"],
|
|
936
|
+
[1e5, "8C3D91"]
|
|
937
|
+
]
|
|
938
|
+
],
|
|
939
|
+
[
|
|
940
|
+
"Daybreak",
|
|
941
|
+
[
|
|
942
|
+
[0, "5E9EFF"],
|
|
943
|
+
[39999, "85C2FF"],
|
|
944
|
+
[7e4, "C4D6EB"],
|
|
945
|
+
[1e5, "FFEBFA"]
|
|
946
|
+
]
|
|
947
|
+
],
|
|
948
|
+
[
|
|
949
|
+
"Horizon",
|
|
950
|
+
[
|
|
951
|
+
[0, "DCEBF5"],
|
|
952
|
+
[8e3, "83A7C3"],
|
|
953
|
+
[13e3, "768FB9"],
|
|
954
|
+
[21001, "83A7C3"],
|
|
955
|
+
[52e3, "FFFFFF"],
|
|
956
|
+
[56e3, "9C6563"],
|
|
957
|
+
[58e3, "80302D"],
|
|
958
|
+
[71001, "C0524E"],
|
|
959
|
+
[94e3, "EBDAD4"],
|
|
960
|
+
[1e5, "55261C"]
|
|
961
|
+
]
|
|
962
|
+
],
|
|
963
|
+
[
|
|
964
|
+
"Desert",
|
|
965
|
+
[
|
|
966
|
+
[0, "FC9FCB"],
|
|
967
|
+
[13e3, "F8B049"],
|
|
968
|
+
[21001, "F8B049"],
|
|
969
|
+
[63e3, "FEE7F2"],
|
|
970
|
+
[67e3, "F952A0"],
|
|
971
|
+
[69e3, "C50849"],
|
|
972
|
+
[82001, "B43E85"],
|
|
973
|
+
[1e5, "F8B049"]
|
|
974
|
+
]
|
|
975
|
+
],
|
|
976
|
+
[
|
|
977
|
+
"Ocean",
|
|
978
|
+
[
|
|
979
|
+
[0, "03D4A8"],
|
|
980
|
+
[25e3, "21D6E0"],
|
|
981
|
+
[75e3, "0087E6"],
|
|
982
|
+
[1e5, "005CBF"]
|
|
983
|
+
]
|
|
984
|
+
],
|
|
985
|
+
[
|
|
986
|
+
"Calm Water",
|
|
987
|
+
[
|
|
988
|
+
[0, "CCCCFF"],
|
|
989
|
+
[17999, "99CCFF"],
|
|
990
|
+
[36e3, "9966FF"],
|
|
991
|
+
[61e3, "CC99FF"],
|
|
992
|
+
[82001, "99CCFF"],
|
|
993
|
+
[1e5, "CCCCFF"]
|
|
994
|
+
]
|
|
995
|
+
],
|
|
996
|
+
[
|
|
997
|
+
"Fire",
|
|
998
|
+
[
|
|
999
|
+
[0, "FFF200"],
|
|
1000
|
+
[45e3, "FF7A00"],
|
|
1001
|
+
[7e4, "FF0300"],
|
|
1002
|
+
[1e5, "4D0808"]
|
|
1003
|
+
]
|
|
1004
|
+
],
|
|
1005
|
+
[
|
|
1006
|
+
"Fog",
|
|
1007
|
+
[
|
|
1008
|
+
[0, "8488C4"],
|
|
1009
|
+
[53e3, "D4DEFF"],
|
|
1010
|
+
[83e3, "D4DEFF"],
|
|
1011
|
+
[1e5, "96AB94"]
|
|
1012
|
+
]
|
|
1013
|
+
],
|
|
1014
|
+
[
|
|
1015
|
+
"Moss",
|
|
1016
|
+
[
|
|
1017
|
+
[0, "DDEBCF"],
|
|
1018
|
+
[5e4, "9CB86E"],
|
|
1019
|
+
[1e5, "156B13"]
|
|
1020
|
+
]
|
|
1021
|
+
],
|
|
1022
|
+
[
|
|
1023
|
+
"Peacock",
|
|
1024
|
+
[
|
|
1025
|
+
[0, "3399FF"],
|
|
1026
|
+
[16e3, "00CCCC"],
|
|
1027
|
+
[47e3, "9999FF"],
|
|
1028
|
+
[60001, "2E6792"],
|
|
1029
|
+
[71001, "3333CC"],
|
|
1030
|
+
[81e3, "1170FF"],
|
|
1031
|
+
[1e5, "006699"]
|
|
1032
|
+
]
|
|
1033
|
+
],
|
|
1034
|
+
[
|
|
1035
|
+
"Wheat",
|
|
1036
|
+
[
|
|
1037
|
+
[0, "FBEAC7"],
|
|
1038
|
+
[17999, "FEE7F2"],
|
|
1039
|
+
[36e3, "FAC77D"],
|
|
1040
|
+
[61e3, "FBA97D"],
|
|
1041
|
+
[82001, "FBD49C"],
|
|
1042
|
+
[1e5, "FEE7F2"]
|
|
1043
|
+
]
|
|
1044
|
+
],
|
|
1045
|
+
[
|
|
1046
|
+
"Parchment",
|
|
1047
|
+
[
|
|
1048
|
+
[0, "FFEFD1"],
|
|
1049
|
+
[64999, "F0EBD5"],
|
|
1050
|
+
[1e5, "D1C39F"]
|
|
1051
|
+
]
|
|
1052
|
+
],
|
|
1053
|
+
[
|
|
1054
|
+
"Mahogany",
|
|
1055
|
+
[
|
|
1056
|
+
[0, "D6B19C"],
|
|
1057
|
+
[3e4, "D49E6C"],
|
|
1058
|
+
[7e4, "A65528"],
|
|
1059
|
+
[1e5, "663012"]
|
|
1060
|
+
]
|
|
1061
|
+
],
|
|
1062
|
+
[
|
|
1063
|
+
"Rainbow",
|
|
1064
|
+
[
|
|
1065
|
+
[0, "A603AB"],
|
|
1066
|
+
[21001, "0819FB"],
|
|
1067
|
+
[35001, "1A8D48"],
|
|
1068
|
+
[52e3, "FFFF00"],
|
|
1069
|
+
[73e3, "EE3F17"],
|
|
1070
|
+
[88e3, "E81766"],
|
|
1071
|
+
[1e5, "A603AB"]
|
|
1072
|
+
]
|
|
1073
|
+
],
|
|
1074
|
+
[
|
|
1075
|
+
"Rainbow II",
|
|
1076
|
+
[
|
|
1077
|
+
[0, "FF3399"],
|
|
1078
|
+
[25e3, "FF6633"],
|
|
1079
|
+
[5e4, "FFFF00"],
|
|
1080
|
+
[75e3, "01A78F"],
|
|
1081
|
+
[1e5, "3366FF"]
|
|
1082
|
+
]
|
|
1083
|
+
],
|
|
1084
|
+
[
|
|
1085
|
+
"Gold",
|
|
1086
|
+
[
|
|
1087
|
+
[0, "E6DCAC"],
|
|
1088
|
+
[12e3, "E6D78A"],
|
|
1089
|
+
[3e4, "C7AC4C"],
|
|
1090
|
+
[45e3, "E6D78A"],
|
|
1091
|
+
[77e3, "C7AC4C"],
|
|
1092
|
+
[1e5, "E6DCAC"]
|
|
1093
|
+
]
|
|
1094
|
+
],
|
|
1095
|
+
[
|
|
1096
|
+
"Gold II",
|
|
1097
|
+
[
|
|
1098
|
+
[0, "FBE4AE"],
|
|
1099
|
+
[13e3, "BD922A"],
|
|
1100
|
+
[21001, "BD922A"],
|
|
1101
|
+
[63e3, "FBE4AE"],
|
|
1102
|
+
[67e3, "BD922A"],
|
|
1103
|
+
[69e3, "835E17"],
|
|
1104
|
+
[82001, "A28949"],
|
|
1105
|
+
[1e5, "FAE3B7"]
|
|
1106
|
+
]
|
|
1107
|
+
],
|
|
1108
|
+
[
|
|
1109
|
+
"Brass",
|
|
1110
|
+
[
|
|
1111
|
+
[0, "825600"],
|
|
1112
|
+
[13e3, "FFA800"],
|
|
1113
|
+
[28e3, "825600"],
|
|
1114
|
+
[42999, "FFA800"],
|
|
1115
|
+
[58e3, "825600"],
|
|
1116
|
+
[72e3, "FFA800"],
|
|
1117
|
+
[87e3, "825600"],
|
|
1118
|
+
[1e5, "FFA800"]
|
|
1119
|
+
]
|
|
1120
|
+
],
|
|
1121
|
+
[
|
|
1122
|
+
"Chrome",
|
|
1123
|
+
[
|
|
1124
|
+
[0, "FFFFFF"],
|
|
1125
|
+
[16e3, "1F1F1F"],
|
|
1126
|
+
[17999, "FFFFFF"],
|
|
1127
|
+
[42e3, "636363"],
|
|
1128
|
+
[53e3, "CFCFCF"],
|
|
1129
|
+
[66e3, "CFCFCF"],
|
|
1130
|
+
[75999, "1F1F1F"],
|
|
1131
|
+
[78999, "FFFFFF"],
|
|
1132
|
+
[1e5, "7F7F7F"]
|
|
1133
|
+
]
|
|
1134
|
+
],
|
|
1135
|
+
[
|
|
1136
|
+
"Chrome II",
|
|
1137
|
+
[
|
|
1138
|
+
[0, "CBCBCB"],
|
|
1139
|
+
[13e3, "5F5F5F"],
|
|
1140
|
+
[21001, "5F5F5F"],
|
|
1141
|
+
[63e3, "FFFFFF"],
|
|
1142
|
+
[67e3, "B2B2B2"],
|
|
1143
|
+
[69e3, "292929"],
|
|
1144
|
+
[82001, "777777"],
|
|
1145
|
+
[1e5, "EAEAEA"]
|
|
1146
|
+
]
|
|
1147
|
+
],
|
|
1148
|
+
[
|
|
1149
|
+
"Silver",
|
|
1150
|
+
[
|
|
1151
|
+
[0, "FFFFFF"],
|
|
1152
|
+
[7001, "E6E6E6"],
|
|
1153
|
+
[32001, "7D8496"],
|
|
1154
|
+
[47e3, "E6E6E6"],
|
|
1155
|
+
[85001, "7D8496"],
|
|
1156
|
+
[1e5, "E6E6E6"]
|
|
1157
|
+
]
|
|
1158
|
+
],
|
|
1159
|
+
[
|
|
1160
|
+
"Sapphire",
|
|
1161
|
+
[
|
|
1162
|
+
[0, "000082"],
|
|
1163
|
+
[13e3, "0047FF"],
|
|
1164
|
+
[28e3, "000082"],
|
|
1165
|
+
[42999, "0047FF"],
|
|
1166
|
+
[58e3, "000082"],
|
|
1167
|
+
[72e3, "0047FF"],
|
|
1168
|
+
[87e3, "000082"],
|
|
1169
|
+
[1e5, "0047FF"]
|
|
1170
|
+
]
|
|
1171
|
+
]
|
|
1172
|
+
];
|
|
1173
|
+
|
|
1174
|
+
// drawingml/gradient-presets.ts
|
|
1175
|
+
var OFFICE_GRADIENT_PRESETS = OFFICE_GRADIENT_PRESET_DATA.map(([label], index) => ({
|
|
1176
|
+
id: index + 1,
|
|
1177
|
+
label
|
|
1178
|
+
}));
|
|
1179
|
+
function officeGradientPresetFill(id) {
|
|
1180
|
+
const data = Number.isInteger(id) && OFFICE_GRADIENT_PRESET_DATA[id - 1];
|
|
1181
|
+
if (!data) throw new RangeError(`Unknown Office gradient preset ${id}`);
|
|
1182
|
+
return {
|
|
1183
|
+
kind: "gradient",
|
|
1184
|
+
angle: 90,
|
|
1185
|
+
scaled: true,
|
|
1186
|
+
sourceXml: `<a:gradFill xmlns:a="${NS.a}" flip="none" rotWithShape="1"><a:tileRect/></a:gradFill>`,
|
|
1187
|
+
stops: data[1].map(([position, color]) => ({
|
|
1188
|
+
position: position / 1e3,
|
|
1189
|
+
color: { kind: "srgb", value: color, transforms: [] }
|
|
1190
|
+
}))
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
function officeGradientPresetId(fill) {
|
|
1194
|
+
if (fill.kind !== "gradient" || fill.path || fill.angle !== 90 || fill.scaled !== true)
|
|
1195
|
+
return void 0;
|
|
1196
|
+
const index = OFFICE_GRADIENT_PRESET_DATA.findIndex(
|
|
1197
|
+
([, stops]) => stops.length === fill.stops.length && stops.every(([position, color], index2) => {
|
|
1198
|
+
const stop = fill.stops[index2];
|
|
1199
|
+
return stop?.position === position / 1e3 && stop.color.kind === "srgb" && stop.color.value.toUpperCase() === color && stop.color.transforms.length === 0;
|
|
1200
|
+
})
|
|
1201
|
+
);
|
|
1202
|
+
return index < 0 ? void 0 : index + 1;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
// drawingml/gradient-geometry.ts
|
|
1206
|
+
var RECT_GRADIENT_DIRECTIONS = [
|
|
1207
|
+
{ id: "center", label: "From Center", x: 0.5, y: 0.5 },
|
|
1208
|
+
{ id: "top-left", label: "From Top Left Corner", x: 0, y: 0 },
|
|
1209
|
+
{ id: "top-right", label: "From Top Right Corner", x: 1, y: 0 },
|
|
1210
|
+
{ id: "bottom-left", label: "From Bottom Left Corner", x: 0, y: 1 },
|
|
1211
|
+
{ id: "bottom-right", label: "From Bottom Right Corner", x: 1, y: 1 }
|
|
1212
|
+
];
|
|
1213
|
+
function rectGradientFocus(id) {
|
|
1214
|
+
const direction = RECT_GRADIENT_DIRECTIONS.find((direction2) => direction2.id === id);
|
|
1215
|
+
if (!direction) throw new RangeError(`Unknown rectangular gradient direction ${id}`);
|
|
1216
|
+
return { l: direction.x, t: direction.y, r: 1 - direction.x, b: 1 - direction.y };
|
|
1217
|
+
}
|
|
1218
|
+
function rectGradientDirection(focus) {
|
|
1219
|
+
return RECT_GRADIENT_DIRECTIONS.find(
|
|
1220
|
+
({ x, y }) => focus?.l === x && focus.t === y && focus.r === 1 - x && focus.b === 1 - y
|
|
1221
|
+
)?.id;
|
|
1222
|
+
}
|
|
1223
|
+
function withDrawingGradientGeometry(fill, type, direction = "center") {
|
|
1224
|
+
const next = structuredClone(fill);
|
|
1225
|
+
next.tileRect = { l: 0, t: 0, r: 0, b: 0 };
|
|
1226
|
+
if (type === "linear") {
|
|
1227
|
+
delete next.path;
|
|
1228
|
+
delete next.fillToRect;
|
|
1229
|
+
next.angle ??= 90;
|
|
1230
|
+
next.scaled = true;
|
|
1231
|
+
} else if (type === "rect" || type === "circle" || type === "shape") {
|
|
1232
|
+
next.path = type;
|
|
1233
|
+
next.fillToRect = rectGradientFocus(direction);
|
|
1234
|
+
delete next.angle;
|
|
1235
|
+
delete next.scaled;
|
|
1236
|
+
if (direction !== "center") {
|
|
1237
|
+
const { l, t } = next.fillToRect;
|
|
1238
|
+
next.tileRect = {
|
|
1239
|
+
l: l === 0 ? -1 : 0,
|
|
1240
|
+
t: t === 0 ? -1 : 0,
|
|
1241
|
+
r: l === 1 ? -1 : 0,
|
|
1242
|
+
b: t === 1 ? -1 : 0
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
} else throw new RangeError(`Unknown gradient type ${type}`);
|
|
1246
|
+
return next;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// drawingml/rect-path-gradient.ts
|
|
1250
|
+
var BAND_COUNT = 40;
|
|
1251
|
+
function hexToRgb(color) {
|
|
1252
|
+
const parsed = hexToRgbChannels(color);
|
|
1253
|
+
if (parsed) return parsed;
|
|
1254
|
+
const hex = color.replace("#", "");
|
|
1255
|
+
return {
|
|
1256
|
+
r: Number.parseInt(hex.slice(0, 2), 16) || 0,
|
|
1257
|
+
g: Number.parseInt(hex.slice(2, 4), 16) || 0,
|
|
1258
|
+
b: Number.parseInt(hex.slice(4, 6), 16) || 0
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
function toHexChannel(value) {
|
|
1262
|
+
return toHex(value).toLowerCase();
|
|
1263
|
+
}
|
|
1264
|
+
function lerpStops(a, b, t) {
|
|
1265
|
+
const ca = hexToRgb(a.color);
|
|
1266
|
+
const cb = hexToRgb(b.color);
|
|
1267
|
+
const oa = a.opacity ?? 1;
|
|
1268
|
+
const ob = b.opacity ?? 1;
|
|
1269
|
+
return {
|
|
1270
|
+
color: `#${toHexChannel(ca.r + (cb.r - ca.r) * t)}${toHexChannel(ca.g + (cb.g - ca.g) * t)}${toHexChannel(ca.b + (cb.b - ca.b) * t)}`,
|
|
1271
|
+
opacity: oa + (ob - oa) * t
|
|
1272
|
+
};
|
|
1273
|
+
}
|
|
1274
|
+
function colorAt(stops, position) {
|
|
1275
|
+
const first2 = stops[0];
|
|
1276
|
+
const last = stops[stops.length - 1];
|
|
1277
|
+
if (position <= first2.position) {
|
|
1278
|
+
return { color: first2.color, opacity: first2.opacity ?? 1 };
|
|
1279
|
+
}
|
|
1280
|
+
if (position >= last.position) {
|
|
1281
|
+
return { color: last.color, opacity: last.opacity ?? 1 };
|
|
1282
|
+
}
|
|
1283
|
+
for (let i = 0; i < stops.length - 1; i += 1) {
|
|
1284
|
+
const from = stops[i];
|
|
1285
|
+
const to = stops[i + 1];
|
|
1286
|
+
if (position >= from.position && position <= to.position) {
|
|
1287
|
+
const span = to.position - from.position;
|
|
1288
|
+
const t = span > 0 ? (position - from.position) / span : 0;
|
|
1289
|
+
return lerpStops(from, to, t);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
return { color: last.color, opacity: last.opacity ?? 1 };
|
|
1293
|
+
}
|
|
1294
|
+
function resolveInnerRect(fillToRect, focalPoint) {
|
|
1295
|
+
let centerX = 50;
|
|
1296
|
+
let centerY = 50;
|
|
1297
|
+
let width = 0;
|
|
1298
|
+
let height = 0;
|
|
1299
|
+
if (fillToRect) {
|
|
1300
|
+
const { l, t, r, b } = fillToRect;
|
|
1301
|
+
centerX = (l + (1 - r)) / 2 * 100;
|
|
1302
|
+
centerY = (t + (1 - b)) / 2 * 100;
|
|
1303
|
+
width = Math.max(0, Math.min(1, 1 - l - r)) * 100;
|
|
1304
|
+
height = Math.max(0, Math.min(1, 1 - t - b)) * 100;
|
|
1305
|
+
if (focalPoint) {
|
|
1306
|
+
centerX = (centerX + focalPoint.x * 100) / 2;
|
|
1307
|
+
centerY = (centerY + focalPoint.y * 100) / 2;
|
|
1308
|
+
}
|
|
1309
|
+
} else if (focalPoint) {
|
|
1310
|
+
centerX = focalPoint.x * 100;
|
|
1311
|
+
centerY = focalPoint.y * 100;
|
|
1312
|
+
}
|
|
1313
|
+
return {
|
|
1314
|
+
left: centerX - width / 2,
|
|
1315
|
+
top: centerY - height / 2,
|
|
1316
|
+
right: centerX + width / 2,
|
|
1317
|
+
bottom: centerY + height / 2
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
function lerpEdge(inner, outer, t) {
|
|
1321
|
+
return inner + (outer - inner) * t;
|
|
1322
|
+
}
|
|
1323
|
+
function buildRectPathGradientSvg(stops, focalPoint, fillToRect, options) {
|
|
1324
|
+
if (stops.length === 0) {
|
|
1325
|
+
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>';
|
|
1326
|
+
}
|
|
1327
|
+
const sorted = [...stops].sort((a, b) => a.position - b.position);
|
|
1328
|
+
const inner = resolveInnerRect(fillToRect, focalPoint);
|
|
1329
|
+
const rects = [];
|
|
1330
|
+
const alphaRects = [];
|
|
1331
|
+
const masked = options?.independentOpacity && sorted.some((stop) => (stop.opacity ?? 1) < 1);
|
|
1332
|
+
const bands = options?.bands ?? BAND_COUNT;
|
|
1333
|
+
if (!Number.isInteger(bands) || bands < 1) throw new RangeError("Invalid gradient band count");
|
|
1334
|
+
for (let i = bands; i >= 0; i -= 1) {
|
|
1335
|
+
const t = i / bands;
|
|
1336
|
+
const { color, opacity } = colorAt(sorted, t * 100);
|
|
1337
|
+
const left = lerpEdge(inner.left, 0, t);
|
|
1338
|
+
const top = lerpEdge(inner.top, 0, t);
|
|
1339
|
+
const right = lerpEdge(inner.right, 100, t);
|
|
1340
|
+
const bottom = lerpEdge(inner.bottom, 100, t);
|
|
1341
|
+
const opacityAttr = !masked && opacity < 1 ? ` fill-opacity="${Math.max(0, opacity).toFixed(3)}"` : "";
|
|
1342
|
+
rects.push(
|
|
1343
|
+
`<rect x="${left.toFixed(2)}" y="${top.toFixed(2)}" width="${(right - left).toFixed(2)}" height="${(bottom - top).toFixed(2)}" fill="${color}"${opacityAttr}/>`
|
|
1344
|
+
);
|
|
1345
|
+
if (masked) {
|
|
1346
|
+
const channel = toHexChannel(opacity * 255);
|
|
1347
|
+
alphaRects.push(
|
|
1348
|
+
`<rect x="${left.toFixed(2)}" y="${top.toFixed(2)}" width="${(right - left).toFixed(2)}" height="${(bottom - top).toFixed(2)}" fill="#${channel}${channel}${channel}"/>`
|
|
1349
|
+
);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
const paint = masked ? `<defs><mask id="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100" mask-type="luminance" color-interpolation="sRGB">${alphaRects.join("")}</mask></defs><g mask="url(#alpha)">${rects.join("")}</g>` : rects.join("");
|
|
1353
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none">${paint}</svg>`;
|
|
1354
|
+
}
|
|
1355
|
+
function buildRectPathGradientImage(stops, focalPoint, fillToRect) {
|
|
1356
|
+
const markup = buildRectPathGradientSvg(stops, focalPoint, fillToRect);
|
|
1357
|
+
return `url("data:image/svg+xml,${encodeURIComponent(markup)}")`;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
// drawingml/theme-model.ts
|
|
1361
|
+
var THEME_COLOR_SLOTS = [
|
|
1362
|
+
"dk1",
|
|
1363
|
+
"lt1",
|
|
1364
|
+
"dk2",
|
|
1365
|
+
"lt2",
|
|
1366
|
+
"accent1",
|
|
1367
|
+
"accent2",
|
|
1368
|
+
"accent3",
|
|
1369
|
+
"accent4",
|
|
1370
|
+
"accent5",
|
|
1371
|
+
"accent6",
|
|
1372
|
+
"hlink",
|
|
1373
|
+
"folHlink"
|
|
1374
|
+
];
|
|
1375
|
+
var DEFAULT_THEME_COLOR_MAP = {
|
|
1376
|
+
bg1: "lt1",
|
|
1377
|
+
tx1: "dk1",
|
|
1378
|
+
bg2: "lt2",
|
|
1379
|
+
tx2: "dk2"
|
|
1380
|
+
};
|
|
1381
|
+
|
|
1382
|
+
// drawingml/theme.ts
|
|
1383
|
+
var MAP_KEYS = [
|
|
1384
|
+
"bg1",
|
|
1385
|
+
"tx1",
|
|
1386
|
+
"bg2",
|
|
1387
|
+
"tx2",
|
|
1388
|
+
"accent1",
|
|
1389
|
+
"accent2",
|
|
1390
|
+
"accent3",
|
|
1391
|
+
"accent4",
|
|
1392
|
+
"accent5",
|
|
1393
|
+
"accent6",
|
|
1394
|
+
"hlink",
|
|
1395
|
+
"folHlink"
|
|
1396
|
+
];
|
|
1397
|
+
var SLOT_SET = new Set(THEME_COLOR_SLOTS);
|
|
1398
|
+
function isThemeColorSlot(value) {
|
|
1399
|
+
return SLOT_SET.has(value);
|
|
1400
|
+
}
|
|
1401
|
+
function nonEmpty(value) {
|
|
1402
|
+
return value ? value : void 0;
|
|
1403
|
+
}
|
|
1404
|
+
function parseThemeColorScheme(scheme) {
|
|
1405
|
+
const result = { colors: {} };
|
|
1406
|
+
if (!scheme) return result;
|
|
1407
|
+
const name = nonEmpty(scheme.getAttribute("name"));
|
|
1408
|
+
if (name) result.name = name;
|
|
1409
|
+
for (const slot of THEME_COLOR_SLOTS) {
|
|
1410
|
+
const color = parseDrawingColorIn(first(scheme, slot, NS.a));
|
|
1411
|
+
if (color) result.colors[slot] = color;
|
|
1412
|
+
}
|
|
1413
|
+
return result;
|
|
1414
|
+
}
|
|
1415
|
+
function parseFontCollection(collection) {
|
|
1416
|
+
const result = { scripts: {} };
|
|
1417
|
+
if (!collection) return result;
|
|
1418
|
+
const typeface = (local) => nonEmpty(first(collection, local, NS.a)?.getAttribute("typeface"));
|
|
1419
|
+
const latin = typeface("latin");
|
|
1420
|
+
const eastAsia = typeface("ea");
|
|
1421
|
+
const complexScript = typeface("cs");
|
|
1422
|
+
if (latin) result.latin = latin;
|
|
1423
|
+
if (eastAsia) result.eastAsia = eastAsia;
|
|
1424
|
+
if (complexScript) result.complexScript = complexScript;
|
|
1425
|
+
for (const font of elements(collection)) {
|
|
1426
|
+
if (font.localName !== "font") continue;
|
|
1427
|
+
const script = nonEmpty(font.getAttribute("script"));
|
|
1428
|
+
const face = nonEmpty(font.getAttribute("typeface"));
|
|
1429
|
+
if (script && face && !Object.hasOwn(result.scripts, script)) result.scripts[script] = face;
|
|
1430
|
+
}
|
|
1431
|
+
return result;
|
|
1432
|
+
}
|
|
1433
|
+
function parseThemeFontScheme(scheme) {
|
|
1434
|
+
const result = {
|
|
1435
|
+
major: parseFontCollection(first(scheme, "majorFont", NS.a)),
|
|
1436
|
+
minor: parseFontCollection(first(scheme, "minorFont", NS.a))
|
|
1437
|
+
};
|
|
1438
|
+
const name = nonEmpty(scheme?.getAttribute("name"));
|
|
1439
|
+
if (name) result.name = name;
|
|
1440
|
+
return result;
|
|
1441
|
+
}
|
|
1442
|
+
function rootOf(source) {
|
|
1443
|
+
return "documentElement" in source ? source.documentElement : source;
|
|
1444
|
+
}
|
|
1445
|
+
function parseTheme(source) {
|
|
1446
|
+
const root = rootOf(source);
|
|
1447
|
+
const holder = first(root, "themeElements", NS.a) ?? root;
|
|
1448
|
+
const theme = {
|
|
1449
|
+
colorScheme: parseThemeColorScheme(first(holder, "clrScheme", NS.a)),
|
|
1450
|
+
fontScheme: parseThemeFontScheme(first(holder, "fontScheme", NS.a))
|
|
1451
|
+
};
|
|
1452
|
+
const name = nonEmpty(root.getAttribute("name"));
|
|
1453
|
+
if (name) theme.name = name;
|
|
1454
|
+
return theme;
|
|
1455
|
+
}
|
|
1456
|
+
function parseThemeXml(xml, label = "DrawingML theme") {
|
|
1457
|
+
return parseTheme(parseXml(xml, { label }));
|
|
1458
|
+
}
|
|
1459
|
+
function parseThemeColorMap(element) {
|
|
1460
|
+
const map = {};
|
|
1461
|
+
if (!element) return map;
|
|
1462
|
+
for (const key of MAP_KEYS) {
|
|
1463
|
+
const value = element.getAttribute(key);
|
|
1464
|
+
if (value && isThemeColorSlot(value)) map[key] = value;
|
|
1465
|
+
}
|
|
1466
|
+
return map;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
// drawingml/theme-color.ts
|
|
1470
|
+
function isLogical(name) {
|
|
1471
|
+
return Object.hasOwn(DEFAULT_THEME_COLOR_MAP, name);
|
|
1472
|
+
}
|
|
1473
|
+
function themeColorSlotFor(name, colorMap = {}) {
|
|
1474
|
+
if (isLogical(name)) return colorMap[name] ?? DEFAULT_THEME_COLOR_MAP[name];
|
|
1475
|
+
if (!isThemeColorSlot(name)) return void 0;
|
|
1476
|
+
if (name === "dk1" || name === "lt1" || name === "dk2" || name === "lt2") return name;
|
|
1477
|
+
return colorMap[name] ?? name;
|
|
1478
|
+
}
|
|
1479
|
+
function resolveSchemeColor(scheme, name, colorMap) {
|
|
1480
|
+
const slot = themeColorSlotFor(name, colorMap);
|
|
1481
|
+
return slot ? scheme.colors[slot] : void 0;
|
|
1482
|
+
}
|
|
1483
|
+
function themeSlotHex(color) {
|
|
1484
|
+
if (!color) return void 0;
|
|
1485
|
+
const value = color.kind === "srgb" ? color.value : color.kind === "system" ? color.fallback : void 0;
|
|
1486
|
+
return value ? value.toUpperCase() : void 0;
|
|
1487
|
+
}
|
|
1488
|
+
function themeDrawingColorTheme(scheme, colorMap) {
|
|
1489
|
+
return {
|
|
1490
|
+
scheme(name) {
|
|
1491
|
+
const hex = scheme && themeSlotHex(resolveSchemeColor(scheme, name, colorMap));
|
|
1492
|
+
return hex ? `#${hex.replace(/^#/, "")}` : void 0;
|
|
1493
|
+
}
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
export { DEFAULT_THEME_COLOR_MAP, OFFICE_GRADIENT_PRESETS, RECT_GRADIENT_DIRECTIONS, THEME_COLOR_SLOTS, attributeReader, booleanAttribute, buildRectPathGradientImage, buildRectPathGradientSvg, descendants, drawingColorBrightness, drawingColorCss, drawingColorXml, drawingFillXml, fillElementOf, integerAttribute, isThemeColorSlot, officeGradientPresetFill, officeGradientPresetId, orderedColorTransforms, parseDrawingColor, parseDrawingColorIn, parseDrawingColorList, parseDrawingFill, parseDrawingGeometry, parseDrawingLine, parseDrawingTextBody, parseFrame, parseTheme, parseThemeColorMap, parseThemeColorScheme, parseThemeFontScheme, parseThemeXml, parseTransform, rectGradientDirection, rectGradientFocus, resolveDrawingColor, resolveDrawingShadow, resolveDrawingShadowXml, resolveSchemeColor, setDrawingFillXml, stringAttribute, svgDropShadowElement, themeColorSlotFor, themeDrawingColorTheme, themeSlotHex, withDrawingColorBrightness, withDrawingGradientGeometry };
|