@pixerate/editor 0.164.0 → 0.165.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/agent/index.cjs +54 -39
- package/dist/agent/index.js +24 -9
- package/dist/animation/index.cjs +6 -5
- package/dist/animation/index.js +5 -4
- package/dist/animation-editor/index.cjs +65 -64
- package/dist/animation-editor/index.js +8 -7
- package/dist/bridge/cli.cjs +3 -3
- package/dist/bridge/cli.js +2 -2
- package/dist/bridge/index.cjs +3 -3
- package/dist/bridge/index.js +2 -2
- package/dist/canvas/index.cjs +89 -87
- package/dist/canvas/index.js +11 -9
- package/dist/chart/controller.d.cts +31 -2
- package/dist/chart/controller.d.ts +31 -2
- package/dist/chart/index.cjs +504 -132
- package/dist/chart/index.d.cts +2 -0
- package/dist/chart/index.d.ts +2 -0
- package/dist/chart/index.js +386 -14
- package/dist/chart/layout-families.d.cts +7 -0
- package/dist/chart/layout-families.d.ts +7 -0
- package/dist/chart/links.d.cts +34 -0
- package/dist/chart/links.d.ts +34 -0
- package/dist/chart/mermaid.d.cts +9 -6
- package/dist/chart/mermaid.d.ts +9 -6
- package/dist/chart/schemas.d.cts +3 -0
- package/dist/chart/schemas.d.ts +3 -0
- package/dist/chart/spec.d.cts +3 -2
- package/dist/chart/spec.d.ts +3 -2
- package/dist/chart/style.d.cts +33 -0
- package/dist/chart/style.d.ts +33 -0
- package/dist/chart/types.d.cts +24 -2
- package/dist/chart/types.d.ts +24 -2
- package/dist/{chunk-TALQONZ5.js → chunk-2J5VLJHC.js} +3 -3
- package/dist/{chunk-3NEZJCBY.js → chunk-2ZRN43IN.js} +340 -201
- package/dist/{chunk-ZVNAMTFO.cjs → chunk-3FSUJIXN.cjs} +18 -174
- package/dist/{chunk-RQCMSEM5.cjs → chunk-4QUUHTGJ.cjs} +2 -2
- package/dist/{chunk-CIPIESX4.cjs → chunk-4ZC5QJE2.cjs} +3 -3
- package/dist/{chunk-S6X2QRVU.cjs → chunk-5UEFBM2M.cjs} +1 -138
- package/dist/{chunk-YSAGBIRW.cjs → chunk-64VWWR5U.cjs} +16 -16
- package/dist/{chunk-QYZGBVNC.js → chunk-7272D3K2.js} +10 -8
- package/dist/{chunk-462WGGXX.cjs → chunk-AMX23CSN.cjs} +27 -16
- package/dist/{chunk-3VLOOO3G.js → chunk-BDIM6NVW.js} +1 -1
- package/dist/{chunk-POR54B55.js → chunk-CRFSQWKQ.js} +4 -1
- package/dist/{chunk-GZ2FM3ZB.js → chunk-DKNEQX7T.js} +6 -162
- package/dist/{chunk-JCXMJUQO.cjs → chunk-EGZM52EO.cjs} +3 -3
- package/dist/{chunk-ES3UEVUT.cjs → chunk-EUIDTZNQ.cjs} +112 -110
- package/dist/{chunk-H3OEM3Q2.js → chunk-F6R67I3A.js} +1 -1
- package/dist/{chunk-5FNGLV2D.js → chunk-FEU2XVQH.js} +15 -3
- package/dist/{chunk-SZA42R4N.js → chunk-FRBRLKNQ.js} +154 -16
- package/dist/chunk-HIDFL5LQ.js +484 -0
- package/dist/{chunk-MKTDELCD.js → chunk-I5MRJW7B.js} +1 -1
- package/dist/{chunk-SDHZG5TF.js → chunk-ILP77UD6.js} +160 -2
- package/dist/{chunk-GKNEJ6EN.cjs → chunk-IMRXC7OA.cjs} +241 -103
- package/dist/chunk-KGRZMHZB.js +204 -0
- package/dist/{chunk-SET6KJOP.js → chunk-LPIKXPBM.js} +1 -1
- package/dist/{chunk-BQWGN5WH.js → chunk-M2TPMYJE.js} +1 -1
- package/dist/{chunk-GTELFJRE.cjs → chunk-M5GLQQWG.cjs} +2 -2
- package/dist/{chunk-4VU4CP7R.js → chunk-MHLU6GRJ.js} +1 -138
- package/dist/{chunk-D54JHQK2.cjs → chunk-MKXK6E4O.cjs} +51 -51
- package/dist/{chunk-DAPQGA55.js → chunk-N7NBGT2Y.js} +2 -2
- package/dist/chunk-O6OGNDND.js +164 -0
- package/dist/{chunk-22KLZZGH.cjs → chunk-ODFCS7HF.cjs} +8 -8
- package/dist/{chunk-PA3IMPPS.cjs → chunk-OVYQAYGH.cjs} +81 -81
- package/dist/{chunk-YXOW456B.js → chunk-PPEDZ5WR.js} +1 -1
- package/dist/{chunk-YGG7WDWT.cjs → chunk-Q25WAFTD.cjs} +21 -18
- package/dist/{chunk-SBQVEBSU.cjs → chunk-QO2T6KA5.cjs} +165 -67
- package/dist/{chunk-24M7VD6M.cjs → chunk-S4EIAIEW.cjs} +7 -7
- package/dist/{chunk-M4MIZPQI.cjs → chunk-SJ2CPTQC.cjs} +189 -15
- package/dist/chunk-TFF2GTGN.cjs +153 -0
- package/dist/chunk-TTCJPX4U.cjs +204 -0
- package/dist/{chunk-NZD2MZJC.cjs → chunk-TVQW26AV.cjs} +35 -23
- package/dist/{chunk-R3P2M7HU.cjs → chunk-UVXTOZ2B.cjs} +346 -207
- package/dist/{chunk-WI7QJA7A.cjs → chunk-UXETV2NC.cjs} +161 -3
- package/dist/{chunk-Z4P2RBMJ.js → chunk-V5GSY3NC.js} +101 -3
- package/dist/{chunk-QY4KUDMY.js → chunk-VRXXAXUT.js} +2 -2
- package/dist/chunk-VU6WQSMB.cjs +164 -0
- package/dist/{chunk-OXERWBKE.js → chunk-X5W645RI.js} +3 -3
- package/dist/{chunk-NHLYK3AX.js → chunk-XBQX76CT.js} +182 -8
- package/dist/{chunk-5AARIS3R.cjs → chunk-XCDGM7TD.cjs} +37 -37
- package/dist/{chunk-EVXQNQND.js → chunk-XZB3TJ6K.js} +16 -5
- package/dist/chunk-YBAPT7NL.js +153 -0
- package/dist/chunk-Z2UQYMPS.cjs +484 -0
- package/dist/color/index.cjs +5 -3
- package/dist/color/index.js +12 -10
- package/dist/diagram/index.cjs +55 -243
- package/dist/diagram/index.js +12 -200
- package/dist/export/index.cjs +7 -6
- package/dist/export/index.js +6 -5
- package/dist/extensions/index.cjs +12 -9
- package/dist/extensions/index.js +11 -8
- package/dist/gradient/index.cjs +29 -27
- package/dist/gradient/index.js +6 -4
- package/dist/image-editor/index.cjs +644 -643
- package/dist/image-editor/index.js +7 -6
- package/dist/index.cjs +21 -18
- package/dist/index.js +14 -11
- package/dist/paint-editor/index.cjs +19 -18
- package/dist/paint-editor/index.js +7 -6
- package/dist/parameters/index.cjs +2 -2
- package/dist/parameters/index.js +1 -1
- package/dist/persistence/assetWrites.d.cts +22 -0
- package/dist/persistence/assetWrites.d.ts +22 -0
- package/dist/persistence/assets.d.cts +71 -0
- package/dist/persistence/assets.d.ts +71 -0
- package/dist/persistence/documentStore.d.cts +17 -1
- package/dist/persistence/documentStore.d.ts +17 -1
- package/dist/persistence/documentTools.d.cts +5 -1
- package/dist/persistence/documentTools.d.ts +5 -1
- package/dist/persistence/editorAutosave.d.cts +7 -0
- package/dist/persistence/editorAutosave.d.ts +7 -0
- package/dist/persistence/index.cjs +141 -21
- package/dist/persistence/index.js +130 -10
- package/dist/persistence/storage.d.cts +13 -1
- package/dist/persistence/storage.d.ts +13 -1
- package/dist/spreadsheet/index.cjs +3 -3
- package/dist/spreadsheet/index.js +2 -2
- package/dist/tokens/index.cjs +11 -3
- package/dist/tokens/index.d.cts +1 -0
- package/dist/tokens/index.d.ts +1 -0
- package/dist/tokens/index.js +10 -2
- package/dist/tokens/style.d.cts +36 -0
- package/dist/tokens/style.d.ts +36 -0
- package/dist/tools/index.cjs +15 -3
- package/dist/tools/index.d.cts +2 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +14 -2
- package/dist/tools/style-tools.d.cts +19 -0
- package/dist/tools/style-tools.d.ts +19 -0
- package/dist/tools/style.d.cts +212 -0
- package/dist/tools/style.d.ts +212 -0
- package/dist/tools/view.d.cts +6 -0
- package/dist/tools/view.d.ts +6 -0
- package/dist/typography/index.cjs +8 -6
- package/dist/typography/index.js +5 -3
- package/dist/vector/index.cjs +953 -952
- package/dist/vector/index.js +7 -6
- package/dist/video-editor/index.cjs +8 -7
- package/dist/video-editor/index.js +6 -5
- package/package.json +1 -1
- package/dist/chunk-ERAGQL2N.cjs +0 -68
- package/dist/chunk-KMU6QJB7.js +0 -68
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import {
|
|
2
|
+
splitSource
|
|
3
|
+
} from "./chunk-O6OGNDND.js";
|
|
4
|
+
|
|
5
|
+
// src/diagram/sankey/index.ts
|
|
6
|
+
function parseSankey(source) {
|
|
7
|
+
const split = splitSource(source);
|
|
8
|
+
if (!/^\s*sankey(?:-beta)?\b/i.test(split.header)) {
|
|
9
|
+
return { error: "Not a sankey diagram: the first line should be `sankey-beta`." };
|
|
10
|
+
}
|
|
11
|
+
const firstLine = split.headerIndex + 2;
|
|
12
|
+
const kept = [];
|
|
13
|
+
split.bodyLines.forEach((text, i) => {
|
|
14
|
+
if (/^\s*%%/.test(text)) return;
|
|
15
|
+
kept.push({ text: text.trim(), line: firstLine + i });
|
|
16
|
+
});
|
|
17
|
+
const records = readRecords(kept);
|
|
18
|
+
if ("error" in records) return records;
|
|
19
|
+
const nodes = [];
|
|
20
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21
|
+
const add = (name) => {
|
|
22
|
+
if (!seen.has(name)) {
|
|
23
|
+
seen.add(name);
|
|
24
|
+
nodes.push(name);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const links = [];
|
|
28
|
+
for (const { fields, line } of records) {
|
|
29
|
+
if (fields.length !== 3) {
|
|
30
|
+
return {
|
|
31
|
+
error: `Expected three fields (source,target,value), found ${fields.length}.`,
|
|
32
|
+
line
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const [source2, target, raw] = fields;
|
|
36
|
+
const value = Number.parseFloat(raw);
|
|
37
|
+
if (!Number.isFinite(value)) {
|
|
38
|
+
return { error: `"${raw}" is not a number.`, line };
|
|
39
|
+
}
|
|
40
|
+
add(source2);
|
|
41
|
+
add(target);
|
|
42
|
+
links.push({ source: source2, target, value });
|
|
43
|
+
}
|
|
44
|
+
if (!links.length) return { error: "No links: add lines like `A,B,10`." };
|
|
45
|
+
return { data: { nodes, links } };
|
|
46
|
+
}
|
|
47
|
+
function readRecords(lines) {
|
|
48
|
+
const records = [];
|
|
49
|
+
let i = 0;
|
|
50
|
+
while (i < lines.length) {
|
|
51
|
+
const start = lines[i];
|
|
52
|
+
if (start.text === "") {
|
|
53
|
+
i++;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const fields = [];
|
|
57
|
+
let text = start.text;
|
|
58
|
+
let pos = 0;
|
|
59
|
+
let field = "";
|
|
60
|
+
let quoted = false;
|
|
61
|
+
for (; ; ) {
|
|
62
|
+
if (quoted) {
|
|
63
|
+
const close = text.indexOf('"', pos);
|
|
64
|
+
if (close < 0) {
|
|
65
|
+
field += text.slice(pos);
|
|
66
|
+
i++;
|
|
67
|
+
if (i >= lines.length)
|
|
68
|
+
return { error: "A quoted field is never closed.", line: start.line };
|
|
69
|
+
field += "\n";
|
|
70
|
+
text = lines[i].text;
|
|
71
|
+
pos = 0;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
field += text.slice(pos, close);
|
|
75
|
+
if (text[close + 1] === '"') {
|
|
76
|
+
field += '"';
|
|
77
|
+
pos = close + 2;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
quoted = false;
|
|
81
|
+
pos = close + 1;
|
|
82
|
+
const rest = /^[ \t]*/.exec(text.slice(pos))[0].length;
|
|
83
|
+
pos += rest;
|
|
84
|
+
if (pos < text.length && text[pos] !== ",") {
|
|
85
|
+
return { error: "Unexpected text after a quoted field.", line: lines[i].line };
|
|
86
|
+
}
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (pos >= text.length) {
|
|
90
|
+
fields.push(field.trim());
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
const ch = text[pos];
|
|
94
|
+
if (ch === ",") {
|
|
95
|
+
fields.push(field.trim());
|
|
96
|
+
field = "";
|
|
97
|
+
pos++;
|
|
98
|
+
} else if (ch === '"' && field.trim() === "") {
|
|
99
|
+
quoted = true;
|
|
100
|
+
field = "";
|
|
101
|
+
pos++;
|
|
102
|
+
} else if (ch === '"') {
|
|
103
|
+
return { error: "A quote inside an unquoted field.", line: lines[i].line };
|
|
104
|
+
} else {
|
|
105
|
+
field += ch;
|
|
106
|
+
pos++;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
records.push({ fields, line: start.line });
|
|
110
|
+
i++;
|
|
111
|
+
}
|
|
112
|
+
return records;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// src/diagram/treemap/index.ts
|
|
116
|
+
var NAME = String.raw`(?:"([^"]*)"|'([^']*)')`;
|
|
117
|
+
var CLASS = String.raw`(?:\s*:::\s*([A-Za-z_]\w*))?`;
|
|
118
|
+
var SECTION_RE = new RegExp(String.raw`^${NAME}${CLASS}$`);
|
|
119
|
+
var LEAF_RE = new RegExp(String.raw`^${NAME}\s*[:,]\s*([0-9_.,]+)${CLASS}$`);
|
|
120
|
+
function parseTreemap(source) {
|
|
121
|
+
const split = splitSource(source);
|
|
122
|
+
if (!/^\s*treemap(?:-beta)?\b/i.test(split.header)) {
|
|
123
|
+
return { error: "Not a treemap: the first line should be `treemap-beta`." };
|
|
124
|
+
}
|
|
125
|
+
const data = { items: [] };
|
|
126
|
+
const stack = [];
|
|
127
|
+
const firstLine = split.headerIndex + 2;
|
|
128
|
+
const lines = split.bodyLines;
|
|
129
|
+
for (let i = 0; i < lines.length; i++) {
|
|
130
|
+
const raw = lines[i];
|
|
131
|
+
const line = firstLine + i;
|
|
132
|
+
const indent = /^[ \t]*/.exec(raw)[0].length;
|
|
133
|
+
const text = stripComment(raw).trim();
|
|
134
|
+
if (!text) continue;
|
|
135
|
+
const accBlock = /^accDescr\s*\{(.*)$/.exec(text);
|
|
136
|
+
if (accBlock) {
|
|
137
|
+
let body = accBlock[1];
|
|
138
|
+
while (!body.includes("}") && i + 1 < lines.length) body += `
|
|
139
|
+
${lines[++i]}`;
|
|
140
|
+
if (!body.includes("}")) return { error: "`accDescr {` is never closed.", line };
|
|
141
|
+
data.accDescr = body.slice(0, body.indexOf("}")).trim();
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const acc = /^(accTitle|accDescr)\s*:(.*)$/.exec(text);
|
|
145
|
+
if (acc) {
|
|
146
|
+
data[acc[1]] = acc[2].trim();
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const title = /^title(?:[ \t]+(.*))?$/.exec(text);
|
|
150
|
+
if (title) {
|
|
151
|
+
data.title = (title[1] ?? "").trim() || void 0;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (/^classDef\s/.test(text)) continue;
|
|
155
|
+
let item;
|
|
156
|
+
const leaf = LEAF_RE.exec(text);
|
|
157
|
+
const section = leaf ? null : SECTION_RE.exec(text);
|
|
158
|
+
if (leaf) {
|
|
159
|
+
const value = Number.parseFloat(leaf[3].replace(/,/g, ""));
|
|
160
|
+
if (!Number.isFinite(value)) return { error: `"${leaf[3]}" is not a number.`, line };
|
|
161
|
+
item = { name: leaf[1] ?? leaf[2], value };
|
|
162
|
+
if (leaf[4]) item.className = leaf[4];
|
|
163
|
+
} else if (section) {
|
|
164
|
+
item = { name: section[1] ?? section[2], children: [] };
|
|
165
|
+
if (section[3]) item.className = section[3];
|
|
166
|
+
} else {
|
|
167
|
+
return {
|
|
168
|
+
error: /^["']/.test(text) ? 'Expected `"Name"` for a section or `"Name": value` for a leaf.' : 'Names must be in quotes, e.g. `"Sales": 120`.',
|
|
169
|
+
line
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
while (stack.length && stack[stack.length - 1].indent >= indent) stack.pop();
|
|
173
|
+
const parent = stack[stack.length - 1]?.item;
|
|
174
|
+
if (parent) parent.children.push(item);
|
|
175
|
+
else data.items.push(item);
|
|
176
|
+
if (item.children) stack.push({ item, indent });
|
|
177
|
+
}
|
|
178
|
+
if (!data.items.length) return { error: 'No items: add lines like `"Sales": 120`.' };
|
|
179
|
+
return { data };
|
|
180
|
+
}
|
|
181
|
+
function stripComment(line) {
|
|
182
|
+
let quote = null;
|
|
183
|
+
for (let i = 0; i < line.length; i++) {
|
|
184
|
+
const ch = line[i];
|
|
185
|
+
if (quote) {
|
|
186
|
+
if (ch === quote) quote = null;
|
|
187
|
+
} else if (ch === '"' || ch === "'") {
|
|
188
|
+
quote = ch;
|
|
189
|
+
} else if (ch === "%" && line[i + 1] === "%") {
|
|
190
|
+
return line.slice(0, i);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return line;
|
|
194
|
+
}
|
|
195
|
+
function treemapValue(item) {
|
|
196
|
+
if (!item.children) return item.value ?? 0;
|
|
197
|
+
return item.children.reduce((sum, child) => sum + treemapValue(child), 0);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export {
|
|
201
|
+
parseSankey,
|
|
202
|
+
parseTreemap,
|
|
203
|
+
treemapValue
|
|
204
|
+
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
var _chunkDWJJI6RTcjs = require('./chunk-DWJJI6RT.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunk4ZC5QJE2cjs = require('./chunk-4ZC5QJE2.cjs');
|
|
8
8
|
|
|
9
9
|
// src/animation/keyframes.ts
|
|
10
10
|
var ANIMATION_TIME_EPSILON = 1e-6;
|
|
@@ -46,7 +46,7 @@ function interpolateAnimationValue(from, to, t, type = "number") {
|
|
|
46
46
|
if (t <= 0) return from;
|
|
47
47
|
if (t >= 1) return to;
|
|
48
48
|
if (type === "color" || typeof from === "string" && typeof to === "string") {
|
|
49
|
-
const mixed =
|
|
49
|
+
const mixed = _chunk4ZC5QJE2cjs.mixColorsOklab.call(void 0, from, to, t);
|
|
50
50
|
if (mixed !== null) return mixed;
|
|
51
51
|
}
|
|
52
52
|
return from;
|
|
@@ -551,117 +551,6 @@ function isColor(input) {
|
|
|
551
551
|
return parseColor(input) !== null;
|
|
552
552
|
}
|
|
553
553
|
|
|
554
|
-
// src/color/gamut.ts
|
|
555
|
-
var clamp01 = (v) => Math.min(1, Math.max(0, v));
|
|
556
|
-
function inSrgbGamut(c, epsilon = 1e-5) {
|
|
557
|
-
return c.r >= -epsilon && c.r <= 1 + epsilon && c.g >= -epsilon && c.g <= 1 + epsilon && c.b >= -epsilon && c.b <= 1 + epsilon;
|
|
558
|
-
}
|
|
559
|
-
function deltaEOK(a, b) {
|
|
560
|
-
const la = rgbToOklab(a);
|
|
561
|
-
const lb = rgbToOklab(b);
|
|
562
|
-
return Math.hypot(la.l - lb.l, la.a - lb.a, la.b - lb.b);
|
|
563
|
-
}
|
|
564
|
-
function toSrgbGamut(c) {
|
|
565
|
-
const lch = oklabToOklch(rgbToOklab(c));
|
|
566
|
-
if (lch.l >= 1) return { r: 1, g: 1, b: 1, a: c.a };
|
|
567
|
-
if (lch.l <= 0) return { r: 0, g: 0, b: 0, a: c.a };
|
|
568
|
-
if (inSrgbGamut(c)) {
|
|
569
|
-
return { r: clamp01(c.r), g: clamp01(c.g), b: clamp01(c.b), a: c.a };
|
|
570
|
-
}
|
|
571
|
-
let low = 0;
|
|
572
|
-
let high = lch.c;
|
|
573
|
-
let clippedCandidate = { r: clamp01(c.r), g: clamp01(c.g), b: clamp01(c.b), a: c.a };
|
|
574
|
-
const JND = 0.02;
|
|
575
|
-
const EPS = 1e-4;
|
|
576
|
-
for (let i = 0; i < 30; i++) {
|
|
577
|
-
const mid = (low + high) / 2;
|
|
578
|
-
const candidate = oklabToRgb(oklchToOklab({ l: lch.l, c: mid, h: lch.h, alpha: c.a }));
|
|
579
|
-
const clipped = {
|
|
580
|
-
r: clamp01(candidate.r),
|
|
581
|
-
g: clamp01(candidate.g),
|
|
582
|
-
b: clamp01(candidate.b),
|
|
583
|
-
a: c.a
|
|
584
|
-
};
|
|
585
|
-
clippedCandidate = clipped;
|
|
586
|
-
const dE = deltaEOK(candidate, clipped);
|
|
587
|
-
if (dE < JND) {
|
|
588
|
-
if (JND - dE < EPS) {
|
|
589
|
-
return clipped;
|
|
590
|
-
}
|
|
591
|
-
low = mid;
|
|
592
|
-
} else {
|
|
593
|
-
high = mid;
|
|
594
|
-
}
|
|
595
|
-
if (high - low < 1e-4) {
|
|
596
|
-
break;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
return clippedCandidate;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// src/color/format.ts
|
|
603
|
-
var clamp012 = (v) => Math.min(1, Math.max(0, v));
|
|
604
|
-
var byte = (v) => Math.round(clamp012(v) * 255);
|
|
605
|
-
var hex2 = (n) => n.toString(16).padStart(2, "0");
|
|
606
|
-
var round2 = (n) => (Math.round(n * 100) / 100).toString();
|
|
607
|
-
function formatHex(c) {
|
|
608
|
-
const mapped = toSrgbGamut(c);
|
|
609
|
-
const head = `#${hex2(byte(mapped.r))}${hex2(byte(mapped.g))}${hex2(byte(mapped.b))}`;
|
|
610
|
-
const alpha = byte(mapped.a);
|
|
611
|
-
return alpha === 255 ? head : head + hex2(alpha);
|
|
612
|
-
}
|
|
613
|
-
function formatColor(c, format) {
|
|
614
|
-
switch (format) {
|
|
615
|
-
case "hex":
|
|
616
|
-
return formatHex(c);
|
|
617
|
-
case "rgb": {
|
|
618
|
-
const inGamut = toSrgbGamut(c);
|
|
619
|
-
const r = byte(inGamut.r);
|
|
620
|
-
const g = byte(inGamut.g);
|
|
621
|
-
const b = byte(inGamut.b);
|
|
622
|
-
return c.a < 1 ? `rgb(${r} ${g} ${b} / ${round2(c.a)})` : `rgb(${r} ${g} ${b})`;
|
|
623
|
-
}
|
|
624
|
-
case "hsl": {
|
|
625
|
-
const hsl = rgbToHsl(toSrgbGamut(c));
|
|
626
|
-
const h = (Math.round(hsl.h * 100) / 100).toString();
|
|
627
|
-
const s = (Math.round(hsl.s * 1e4) / 100).toString();
|
|
628
|
-
const l = (Math.round(hsl.l * 1e4) / 100).toString();
|
|
629
|
-
return c.a < 1 ? `hsl(${h} ${s}% ${l}% / ${round2(c.a)})` : `hsl(${h} ${s}% ${l}%)`;
|
|
630
|
-
}
|
|
631
|
-
case "oklch": {
|
|
632
|
-
const lch = oklabToOklch(rgbToOklab(c));
|
|
633
|
-
const l = (lch.l * 100).toFixed(2);
|
|
634
|
-
const ch = lch.c.toFixed(4);
|
|
635
|
-
const h = lch.h.toFixed(2);
|
|
636
|
-
return c.a < 1 ? `oklch(${l}% ${ch} ${h} / ${round2(c.a)})` : `oklch(${l}% ${ch} ${h})`;
|
|
637
|
-
}
|
|
638
|
-
case "oklab": {
|
|
639
|
-
const lab = rgbToOklab(c);
|
|
640
|
-
const l = (lab.l * 100).toFixed(2);
|
|
641
|
-
const a = lab.a.toFixed(4);
|
|
642
|
-
const b = lab.b.toFixed(4);
|
|
643
|
-
return c.a < 1 ? `oklab(${l}% ${a} ${b} / ${round2(c.a)})` : `oklab(${l}% ${a} ${b})`;
|
|
644
|
-
}
|
|
645
|
-
case "p3": {
|
|
646
|
-
const linSrgb = {
|
|
647
|
-
r: srgbToLinear(c.r),
|
|
648
|
-
g: srgbToLinear(c.g),
|
|
649
|
-
b: srgbToLinear(c.b),
|
|
650
|
-
a: c.a
|
|
651
|
-
};
|
|
652
|
-
const linP3 = linearSrgbToDisplayP3(linSrgb);
|
|
653
|
-
const r = linearToSrgb(linP3.r).toFixed(4);
|
|
654
|
-
const g = linearToSrgb(linP3.g).toFixed(4);
|
|
655
|
-
const b = linearToSrgb(linP3.b).toFixed(4);
|
|
656
|
-
return c.a < 1 ? `color(display-p3 ${r} ${g} ${b} / ${round2(c.a)})` : `color(display-p3 ${r} ${g} ${b})`;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
function normalizeColor(input) {
|
|
661
|
-
const parsed = parseColor(input);
|
|
662
|
-
return parsed ? formatHex(parsed) : null;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
554
|
// src/color/contrast.ts
|
|
666
555
|
var BLACK = { r: 0, g: 0, b: 0, a: 1 };
|
|
667
556
|
var WHITE = { r: 1, g: 1, b: 1, a: 1 };
|
|
@@ -720,25 +609,6 @@ function readableTextColor(background, candidates = [BLACK, WHITE]) {
|
|
|
720
609
|
return bestCandidate;
|
|
721
610
|
}
|
|
722
611
|
|
|
723
|
-
// src/color/suggest.ts
|
|
724
|
-
function suggestAccessibleForeground(foreground, background, options = {}) {
|
|
725
|
-
const large = options.large ?? false;
|
|
726
|
-
const lch = oklabToOklch(rgbToOklab(foreground));
|
|
727
|
-
const asHex = (l) => parseColor(formatHex(toSrgbGamut(oklabToRgb(oklchToOklab({ ...lch, l })))));
|
|
728
|
-
for (let d = 0.01; d <= 1; d += 0.01) {
|
|
729
|
-
const downCand = asHex(Math.max(0, lch.l - d));
|
|
730
|
-
const upCand = asHex(Math.min(1, lch.l + d));
|
|
731
|
-
const downRatio = contrastRatio(downCand, background);
|
|
732
|
-
const upRatio = contrastRatio(upCand, background);
|
|
733
|
-
const downPass = contrastLevel(downRatio, { large }) !== "fail";
|
|
734
|
-
const upPass = contrastLevel(upRatio, { large }) !== "fail";
|
|
735
|
-
if (downPass && upPass) return formatHex(downRatio >= upRatio ? downCand : upCand);
|
|
736
|
-
if (downPass) return formatHex(downCand);
|
|
737
|
-
if (upPass) return formatHex(upCand);
|
|
738
|
-
}
|
|
739
|
-
return void 0;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
612
|
export {
|
|
743
613
|
srgbToLinear,
|
|
744
614
|
linearToSrgb,
|
|
@@ -755,15 +625,8 @@ export {
|
|
|
755
625
|
NAMED_COLORS,
|
|
756
626
|
parseColor,
|
|
757
627
|
isColor,
|
|
758
|
-
inSrgbGamut,
|
|
759
|
-
deltaEOK,
|
|
760
|
-
toSrgbGamut,
|
|
761
|
-
formatHex,
|
|
762
|
-
formatColor,
|
|
763
|
-
normalizeColor,
|
|
764
628
|
relativeLuminance,
|
|
765
629
|
contrastRatio,
|
|
766
630
|
contrastLevel,
|
|
767
|
-
readableTextColor
|
|
768
|
-
suggestAccessibleForeground
|
|
631
|
+
readableTextColor
|
|
769
632
|
};
|