@weft-js/plugin-surface-keel 0.1.1 → 0.1.4
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/README.md +312 -3
- package/package.json +13 -4
- package/src/index.d.ts +5 -1
- package/src/index.mjs +20 -5
- package/src/runtime.mjs +6 -2
- package/vendor/README.md +7 -4
- package/vendor/keel-render/core-primitives.mjs +478 -0
- package/vendor/keel-render/effects-world.mjs +439 -0
- package/vendor/keel-render/indexed-render.mjs +516 -0
- package/vendor/keel-render/pixel-raster.mjs +512 -0
- package/vendor/keel-render/render-passes.mjs +530 -0
- package/vendor/keel-render/renderer-api.mjs +121 -0
- package/vendor/keel-render.mjs +1 -2268
- package/vendor/keel-theme/codec-runtime.mjs +549 -0
- package/vendor/keel-theme/collection-codecs.mjs +360 -0
- package/vendor/keel-theme/color-font.mjs +471 -0
- package/vendor/keel-theme/glyph-theme.mjs +529 -0
- package/vendor/keel-theme/icon-schema.mjs +540 -0
- package/vendor/keel-theme/scalar-codecs.mjs +535 -0
- package/vendor/keel-theme/schema-codec.mjs +515 -0
- package/vendor/keel-theme/schema-theme.mjs +533 -0
- package/vendor/keel-theme.mjs +1 -3571
package/vendor/keel-theme.mjs
CHANGED
|
@@ -1,3571 +1 @@
|
|
|
1
|
-
|
|
2
|
-
function srgb8ToLinear(byte) {
|
|
3
|
-
const value = byte / 255;
|
|
4
|
-
return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
// ../../../../../../keel-engine/packages/core/src/rng.ts
|
|
8
|
-
var HEX_SEED = /^0x[0-9a-f]{64}$/u;
|
|
9
|
-
function normalizeSeed(value) {
|
|
10
|
-
const clean = String(value ?? "").toLowerCase().replace(/^0x/u, "");
|
|
11
|
-
if (!/^[0-9a-f]+$/u.test(clean) || clean.length > 64) {
|
|
12
|
-
throw new TypeError("Seed must be one to sixty-four hexadecimal digits.");
|
|
13
|
-
}
|
|
14
|
-
const seed = `0x${clean.padStart(64, "0")}`;
|
|
15
|
-
if (!HEX_SEED.test(seed)) throw new TypeError("Seed must resolve to bytes32.");
|
|
16
|
-
return seed;
|
|
17
|
-
}
|
|
18
|
-
function seedBytes(seed) {
|
|
19
|
-
const clean = normalizeSeed(seed).slice(2);
|
|
20
|
-
const bytes2 = new Uint8Array(32);
|
|
21
|
-
for (let at = 0; at < 32; at += 1) bytes2[at] = Number.parseInt(clean.slice(at * 2, at * 2 + 2), 16);
|
|
22
|
-
return bytes2;
|
|
23
|
-
}
|
|
24
|
-
function expand(bytes2, slot) {
|
|
25
|
-
let state = 2166136261;
|
|
26
|
-
for (const byte of bytes2) state = Math.imul(state ^ byte, 16777619) >>> 0;
|
|
27
|
-
for (let shift = 0; shift < 32; shift += 8) {
|
|
28
|
-
state = Math.imul(state ^ slot >>> shift & 255, 16777619) >>> 0;
|
|
29
|
-
}
|
|
30
|
-
state = (state ^ state >>> 15) >>> 0;
|
|
31
|
-
return state & 65535;
|
|
32
|
-
}
|
|
33
|
-
function draw(entries, ticket) {
|
|
34
|
-
for (const [value, weight] of entries) {
|
|
35
|
-
if (ticket < weight) return value;
|
|
36
|
-
ticket -= weight;
|
|
37
|
-
}
|
|
38
|
-
return entries[entries.length - 1][0];
|
|
39
|
-
}
|
|
40
|
-
var totalOf = (entries) => {
|
|
41
|
-
let total = 0;
|
|
42
|
-
for (const [, weight] of entries) total += weight;
|
|
43
|
-
return total;
|
|
44
|
-
};
|
|
45
|
-
function createRoll(seed) {
|
|
46
|
-
const bytes2 = seedBytes(seed);
|
|
47
|
-
const words = new Uint16Array(16);
|
|
48
|
-
for (let at2 = 0; at2 < 16; at2 += 1) words[at2] = bytes2[at2 * 2] << 8 | bytes2[at2 * 2 + 1];
|
|
49
|
-
const at = (slot) => slot < 16 ? words[slot] : expand(bytes2, slot);
|
|
50
|
-
const api = {
|
|
51
|
-
seed: normalizeSeed(seed),
|
|
52
|
-
at,
|
|
53
|
-
/** Uniform-enough over a 16-bit draw: every table here is far under 256 wide. */
|
|
54
|
-
pick: (slot, list) => list[at(slot) % list.length],
|
|
55
|
-
index: (slot, length) => at(slot) % length,
|
|
56
|
-
range: (slot, low, high) => low + at(slot) % (high - low + 1),
|
|
57
|
-
chance: (slot, numerator, denominator = 100) => at(slot) % denominator < numerator,
|
|
58
|
-
weighted: (slot, entries) => draw(entries, at(slot) % totalOf(entries)),
|
|
59
|
-
/** A private stream off one slot: sub(slot).next() walks its own words. */
|
|
60
|
-
sub(slot) {
|
|
61
|
-
let cursor = 0;
|
|
62
|
-
const base = 65536 + slot * 4096;
|
|
63
|
-
const next = () => expand(bytes2, base + cursor++);
|
|
64
|
-
return {
|
|
65
|
-
next,
|
|
66
|
-
index: (length) => next() % length,
|
|
67
|
-
pick: (list) => list[next() % list.length],
|
|
68
|
-
range: (low, high) => low + next() % (high - low + 1),
|
|
69
|
-
chance: (numerator, denominator = 100) => next() % denominator < numerator,
|
|
70
|
-
weighted: (entries) => draw(entries, next() % totalOf(entries))
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
return api;
|
|
75
|
-
}
|
|
76
|
-
function stream(roll, slot) {
|
|
77
|
-
const sub2 = roll.sub(slot);
|
|
78
|
-
const f = () => sub2.next() / 65536;
|
|
79
|
-
return {
|
|
80
|
-
f,
|
|
81
|
-
between: (a, b) => a + (b - a) * f(),
|
|
82
|
-
int: (a, b) => a + Math.floor(f() * (b - a + 1)),
|
|
83
|
-
pick: (list) => list[Math.floor(f() * list.length)],
|
|
84
|
-
chance: (p) => f() < p,
|
|
85
|
-
// (The total is summed before the draw, as the original does: the draw order is part of the stream.)
|
|
86
|
-
weighted: (entries) => {
|
|
87
|
-
const total = totalOf(entries);
|
|
88
|
-
return draw(entries, f() * total);
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
function deriveSeed(seed, label) {
|
|
93
|
-
let h = 2166136261;
|
|
94
|
-
const text = `${seed}:${label}`;
|
|
95
|
-
let hex2 = "";
|
|
96
|
-
for (let w = 0; w < 8; w += 1) {
|
|
97
|
-
for (let i = 0; i < text.length; i += 1) h = Math.imul(h ^ text.charCodeAt(i), 16777619) >>> 0;
|
|
98
|
-
h = Math.imul(h ^ w, 16777619) >>> 0;
|
|
99
|
-
hex2 += (h >>> 0).toString(16).padStart(8, "0");
|
|
100
|
-
}
|
|
101
|
-
return `0x${hex2}`;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// ../../../../../../keel-engine/packages/core/src/dmath.ts
|
|
105
|
-
var F64 = new Float64Array(1);
|
|
106
|
-
var U32 = new Uint32Array(F64.buffer);
|
|
107
|
-
F64[0] = 1;
|
|
108
|
-
var HI = U32[1] === 1072693248 ? 1 : 0;
|
|
109
|
-
var LO = 1 - HI;
|
|
110
|
-
|
|
111
|
-
// ../../../../../../keel-engine/packages/core/src/frame.ts
|
|
112
|
-
var FRONT = Object.freeze([0, 0, 1]);
|
|
113
|
-
var RIGHT = Object.freeze([1, 0, 0]);
|
|
114
|
-
var UP = Object.freeze([0, 1, 0]);
|
|
115
|
-
|
|
116
|
-
// ../../../../../../keel-engine/packages/core/src/math.ts
|
|
117
|
-
var TAU = Math.PI * 2;
|
|
118
|
-
var clamp = (v, a, b) => v < a ? a : v > b ? b : v;
|
|
119
|
-
var fract = (v) => v - Math.floor(v);
|
|
120
|
-
var tri = (v) => 1 - Math.abs(2 * fract(v) - 1);
|
|
121
|
-
|
|
122
|
-
// ../../../../../../keel-engine/packages/core/src/curl.ts
|
|
123
|
-
var FLOW_PERIOD = 4096;
|
|
124
|
-
var FLOW_SPEED = 0.35;
|
|
125
|
-
var FLOW_R = FLOW_PERIOD * FLOW_SPEED / (2 * Math.PI);
|
|
126
|
-
var W = new Float64Array(8);
|
|
127
|
-
var IO = new Float64Array(7);
|
|
128
|
-
var CURL_GLSL = `
|
|
129
|
-
float curlLat(ivec3 i, uint s) {
|
|
130
|
-
uint h = (uint(i.x) * 0x8da6b343u) ^ (uint(i.y) * 0xd8163841u) ^ (uint(i.z) * 0xcb1ab31fu) ^ s;
|
|
131
|
-
h ^= h >> 16; h *= 0x7feb352du; h ^= h >> 15; h *= 0x846ca68bu; h ^= h >> 16;
|
|
132
|
-
return float(h) / 2147483647.5 - 1.0;
|
|
133
|
-
}
|
|
134
|
-
vec3 curlGrad(vec3 x, uint s) {
|
|
135
|
-
vec3 fi = floor(x); ivec3 i = ivec3(fi); vec3 f = x - fi;
|
|
136
|
-
vec3 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
|
|
137
|
-
vec3 du = 30.0 * f * f * (f * (f - 2.0) + 1.0);
|
|
138
|
-
float a = curlLat(i, s), b = curlLat(i + ivec3(1, 0, 0), s), c = curlLat(i + ivec3(0, 1, 0), s), d = curlLat(i + ivec3(1, 1, 0), s);
|
|
139
|
-
float e = curlLat(i + ivec3(0, 0, 1), s), ff = curlLat(i + ivec3(1, 0, 1), s), g = curlLat(i + ivec3(0, 1, 1), s), h = curlLat(i + ivec3(1, 1, 1), s);
|
|
140
|
-
float k1 = b - a, k2 = c - a, k3 = e - a, k4 = a - b - c + d, k5 = a - c - e + g, k6 = a - b - e + ff, k7 = -a + b + c - d + e - ff - g + h;
|
|
141
|
-
return du * vec3(k1 + k4 * u.y + k6 * u.z + k7 * u.y * u.z, k2 + k5 * u.z + k4 * u.x + k7 * u.z * u.x, k3 + k6 * u.x + k5 * u.y + k7 * u.x * u.y);
|
|
142
|
-
}
|
|
143
|
-
vec3 curlNoiseN(vec3 p, float t, int octaves) {
|
|
144
|
-
float th = t / ${FLOW_PERIOD.toFixed(1)} * 6.283185307;
|
|
145
|
-
p += vec3(${FLOW_R.toFixed(4)} * cos(th), 0.0, ${FLOW_R.toFixed(4)} * sin(th));
|
|
146
|
-
vec3 a = vec3(0.0), b = vec3(0.0);
|
|
147
|
-
float f = 1.0, w = 1.0;
|
|
148
|
-
for (int k = 0; k < 2; k++) {
|
|
149
|
-
if (k >= octaves) break;
|
|
150
|
-
a += curlGrad(p * f, 0x2545f491u + uint(k)) * f * w;
|
|
151
|
-
b += curlGrad(p * f + vec3(31.4, 17.7, 5.9), 0x68e31da4u + uint(k)) * f * w;
|
|
152
|
-
f *= 2.03; w *= 0.5;
|
|
153
|
-
}
|
|
154
|
-
return cross(a, b) * 0.25;
|
|
155
|
-
}
|
|
156
|
-
vec3 curlNoise(vec3 p, float t) { return curlNoiseN(p, t, 2); }`;
|
|
157
|
-
|
|
158
|
-
// ../../../../../../keel-engine/packages/core/src/palette.ts
|
|
159
|
-
function oklabToLinear(L, a, b) {
|
|
160
|
-
const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
|
|
161
|
-
const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
|
|
162
|
-
const s_ = L - 0.0894841775 * a - 1.291485548 * b;
|
|
163
|
-
const l = l_ ** 3;
|
|
164
|
-
const m = m_ ** 3;
|
|
165
|
-
const s = s_ ** 3;
|
|
166
|
-
return [
|
|
167
|
-
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
168
|
-
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
169
|
-
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
170
|
-
];
|
|
171
|
-
}
|
|
172
|
-
var inGamut = (rgb) => rgb.every((c) => c >= -5e-4 && c <= 1.0005);
|
|
173
|
-
var encode = (c) => {
|
|
174
|
-
const v = clamp(c, 0, 1);
|
|
175
|
-
return Math.round(255 * (v <= 31308e-7 ? 12.92 * v : 1.055 * v ** (1 / 2.4) - 0.055));
|
|
176
|
-
};
|
|
177
|
-
var encodeRgb = (rgb) => [encode(rgb[0]), encode(rgb[1]), encode(rgb[2])];
|
|
178
|
-
function oklch(L, C, hueDeg) {
|
|
179
|
-
const h = hueDeg * Math.PI / 180;
|
|
180
|
-
let rgb = oklabToLinear(L, C * Math.cos(h), C * Math.sin(h));
|
|
181
|
-
if (!inGamut(rgb)) {
|
|
182
|
-
let lo = 0;
|
|
183
|
-
let hi = C;
|
|
184
|
-
for (let step = 0; step < 18; step += 1) {
|
|
185
|
-
const mid = (lo + hi) / 2;
|
|
186
|
-
if (inGamut(oklabToLinear(L, mid * Math.cos(h), mid * Math.sin(h)))) lo = mid;
|
|
187
|
-
else hi = mid;
|
|
188
|
-
}
|
|
189
|
-
rgb = oklabToLinear(L, lo * Math.cos(h), lo * Math.sin(h));
|
|
190
|
-
}
|
|
191
|
-
return encodeRgb(rgb);
|
|
192
|
-
}
|
|
193
|
-
function ramp(S, hues, extra = {}) {
|
|
194
|
-
return {
|
|
195
|
-
hues,
|
|
196
|
-
chroma: S.between(0.11, 0.19),
|
|
197
|
-
lift: S.between(0.04, 0.09),
|
|
198
|
-
top: S.between(0.94, 0.985),
|
|
199
|
-
gamma: S.between(1, 1.35),
|
|
200
|
-
shift: S.between(6, 20),
|
|
201
|
-
...extra
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
var accentRamp = (S, hue2, extra = {}) => ({
|
|
205
|
-
hues: [hue2 - 6, hue2 + 6],
|
|
206
|
-
chroma: S.between(0.15, 0.23),
|
|
207
|
-
lift: 0.32,
|
|
208
|
-
top: 0.96,
|
|
209
|
-
gamma: 0.9,
|
|
210
|
-
shift: 4,
|
|
211
|
-
...extra
|
|
212
|
-
});
|
|
213
|
-
var SCHEMES = [
|
|
214
|
-
["Monochrome", 3, (S, h) => ({
|
|
215
|
-
key: ramp(S, [h - 4, h + 4]),
|
|
216
|
-
accent: accentRamp(S, h + S.between(-10, 10), { chroma: S.between(0.18, 0.25) })
|
|
217
|
-
})],
|
|
218
|
-
["Nocturne", 9, (S, h) => ({
|
|
219
|
-
key: ramp(S, [h - 9, h + 9]),
|
|
220
|
-
accent: accentRamp(S, h + 180 + S.between(-35, 35))
|
|
221
|
-
})],
|
|
222
|
-
["Duotone", 5, (S, h) => {
|
|
223
|
-
const d = S.pick([-1, 1]) * S.between(45, 85);
|
|
224
|
-
return { key: ramp(S, [h - d / 2, h + d / 2]), accent: accentRamp(S, h + 180 + S.between(-25, 25)) };
|
|
225
|
-
}],
|
|
226
|
-
["Split", 3, (S, h) => ({
|
|
227
|
-
key: ramp(S, [h - 12, h + 12]),
|
|
228
|
-
accent: accentRamp(S, h + S.pick([-1, 1]) * S.between(125, 155))
|
|
229
|
-
})],
|
|
230
|
-
["Triad", 3, (S, h) => {
|
|
231
|
-
const dir = S.pick([-1, 1]);
|
|
232
|
-
return { key: ramp(S, [h, h + dir * 120]), accent: accentRamp(S, h - dir * 120 + S.between(-15, 15)) };
|
|
233
|
-
}],
|
|
234
|
-
["Two Worlds", 7.5, (S, h) => {
|
|
235
|
-
const inside = h + 180 + S.between(-40, 40);
|
|
236
|
-
return {
|
|
237
|
-
outside: ramp(S, [h - 10, h + 10], { chroma: S.between(0.12, 0.2), top: 0.9 }),
|
|
238
|
-
key: ramp(S, [inside - 12, inside + 12]),
|
|
239
|
-
accent: accentRamp(S, inside + S.pick([-1, 1]) * S.between(25, 60))
|
|
240
|
-
};
|
|
241
|
-
}],
|
|
242
|
-
["Neon Noir", 2, (S, h) => ({
|
|
243
|
-
// Near-neutral room, one vivid ink. Contrast by placement, not by volume.
|
|
244
|
-
key: ramp(S, [h - 5, h + 5], { chroma: S.between(0.025, 0.05), shift: 4 }),
|
|
245
|
-
accent: accentRamp(S, h + S.pick([0, 150, 180, 210]), { chroma: 0.3, lift: 0.4 })
|
|
246
|
-
})],
|
|
247
|
-
["Spectrum", 1.5, (S, h) => {
|
|
248
|
-
const span = S.pick([-1, 1]) * S.between(150, 220);
|
|
249
|
-
return {
|
|
250
|
-
key: ramp(S, [h, h + span / 3, h + span * 2 / 3, h + span], { chroma: S.between(0.13, 0.18) }),
|
|
251
|
-
accent: accentRamp(S, h + span / 2 + 180)
|
|
252
|
-
};
|
|
253
|
-
}],
|
|
254
|
-
["Prism", 0.6, (S, h) => ({
|
|
255
|
-
key: ramp(S, [h, h + 90, h + 180, h + 270, h + 360], { chroma: S.between(0.13, 0.17), shift: 0 }),
|
|
256
|
-
accent: accentRamp(S, h + 45, { chroma: 0.12 })
|
|
257
|
-
})]
|
|
258
|
-
];
|
|
259
|
-
var SCHEME_NAMES = SCHEMES.map(([n]) => n);
|
|
260
|
-
|
|
261
|
-
// ../../../../../../keel-engine/packages/core/src/look.ts
|
|
262
|
-
var DRAWS = new Float64Array(16);
|
|
263
|
-
var WEIGHTS = [1, 0.8, 0.5];
|
|
264
|
-
var W_NORM = Math.sqrt(WEIGHTS.reduce((a, b) => a + b, 0));
|
|
265
|
-
|
|
266
|
-
// ../../../../../../keel-engine/packages/core/src/dither.ts
|
|
267
|
-
var BAYER2 = [0, 2, 3, 1];
|
|
268
|
-
var BAYER4 = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5];
|
|
269
|
-
var BAYER8 = (() => {
|
|
270
|
-
const out = new Array(64);
|
|
271
|
-
for (let y = 0; y < 8; y += 1) {
|
|
272
|
-
for (let x = 0; x < 8; x += 1) {
|
|
273
|
-
const q = BAYER4[(y & 3) * 4 + (x & 3)];
|
|
274
|
-
const b = BAYER2[(y >> 2) * 2 + (x >> 2)];
|
|
275
|
-
out[y * 8 + x] = q * 4 + b;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return out;
|
|
279
|
-
})();
|
|
280
|
-
var b2 = (i) => BAYER2[i];
|
|
281
|
-
var b4 = (i) => BAYER4[i];
|
|
282
|
-
var b8 = (i) => BAYER8[i];
|
|
283
|
-
function equalize(shape, w, h, tie = (x, y) => b8((y & 7) * 8 + (x & 7))) {
|
|
284
|
-
const cells = [];
|
|
285
|
-
for (let y = 0; y < h; y += 1) for (let x = 0; x < w; x += 1) cells.push([Math.round(shape(x, y) * 1e6), tie(x, y), y * w + x]);
|
|
286
|
-
cells.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2]);
|
|
287
|
-
const table = new Float32Array(w * h);
|
|
288
|
-
cells.forEach(([, , k], rank) => {
|
|
289
|
-
table[k] = (rank + 0.5) / cells.length;
|
|
290
|
-
});
|
|
291
|
-
return (x, y) => table[(y % h + h) % h * w + (x % w + w) % w];
|
|
292
|
-
}
|
|
293
|
-
var ALONG = [0, 4, 2, 6, 1, 5, 3, 7];
|
|
294
|
-
var along = (x) => ALONG[x & 7];
|
|
295
|
-
function dotScreen([ax, ay], [bx, by], w, h) {
|
|
296
|
-
const det = ax * by - ay * bx;
|
|
297
|
-
const coords = (x, y) => [(x * by - y * bx) / det, (y * ax - x * ay) / det];
|
|
298
|
-
const shape = (x, y) => {
|
|
299
|
-
const [u2, v] = coords(x, y);
|
|
300
|
-
return -(Math.cos(2 * Math.PI * u2) + Math.cos(2 * Math.PI * v));
|
|
301
|
-
};
|
|
302
|
-
const tie = (x, y) => {
|
|
303
|
-
const [u2, v] = coords(x, y);
|
|
304
|
-
const [i, j] = [Math.round(u2), Math.round(v)];
|
|
305
|
-
const dx = x - (i * ax + j * bx);
|
|
306
|
-
const dy = y - (i * ay + j * by);
|
|
307
|
-
const oct = Math.floor((Math.atan2(dy, dx) + 2 * Math.PI) % (2 * Math.PI) / (Math.PI / 4) + 1e-9) & 7;
|
|
308
|
-
return ALONG[oct];
|
|
309
|
-
};
|
|
310
|
-
return equalize(shape, w, h, tie);
|
|
311
|
-
}
|
|
312
|
-
var BLUE_NOISE = (() => {
|
|
313
|
-
const s = atob("5mkewUkqf948qxhk/1Z7InJdnyjRPMYG7J5vuSVFfs4icUOTeFyxR58dPbIYZuANoGHAbEzFDJw5+ljabO1AJ643o3lg9rRoBovgpDXGlNyt+kC2evOhaYJS+QPXqpU1uO3UK/Ib4Qf4wG7wUJM5tydE9Bi0eVrYHHQqnBKOt3fNj+sA2xmZT9EsSXQdqwxOMRJu2AlWHjPQFT2GZ+RWCGaHD1SdvYFlky2LBMSp/VvIepgujv9BrIzJsuZPxRlKDFgut0SHMu16vfaQ12LtiM6X7UqRr+C+keOkxy8YwP+hPa/fa0Ex0kzmW9omcBCD5gjbX9EAKOZgRQlqNf6A4mn1gtNvrccOnh9bAblFI3C2XB3DLWR9Q14ic1HqjHVKzRl8yAD8qRC2G6N6ONBKpTRUsT2mb8OCFfaV1apgK6E6mhBQJP1cQWzdrjzogMT3BDuBoOoX/AGo8boSnzyxJZHwWimWUIXsb8tD+bWN7yK/i/gaheFJojO9eiGIArjbILPG4qESkum4MYpvEZkyVafR43FIs47TLoNG2GLzA+BtN7Tlc8QhW5owiQxhF1fechBqyixZEfJm21Q+7NBIdY1hQH1nN89/B1X70ahf1xyKZSgQyjJuUMFmCZInxoRY1BOgQxbZO7IE8lLZqsmYP6LXRa3pmrqJJKcMsVyYE/nLBe4orOZOJqLHG0cp7Hq0P/68k1vcohblm/qwdUOpMLx++mGIneh402S7JHUyfgLwL5JiC3Y1yUl0/McufbtSMNiUvAuKwXbwZZR/vU4O358HS+18C/VAfCU6VuIO95dNBs0tvA5OKow9n+NK9s9ktVXHIfxH2QPknByMbfEhpYRDcVP0XxpC3DCyC/dsyS9cd7E2pymMtF/dvhXMgGEf6W2aU+1rrfrFG3AJkhedKYIR4Im6p4NptFg71wZF3mix/xehOdCzmARU1j+jIZaD684e2mXDTs8NoYVrmS6xxYo9tRnSPoAIWKnst2DBUNX6pUFpMFYX9CuR72SuxZQPWyjF3nwkavx9v2iH41e6RRSbVYoD6nYy/Ukg8EHnTwzWKvR1kSThldgmRIQz5ng9IHHCBOXOm0LTEcAnf1Q06buKTQGU5kYVpyjvETLNAPVxOcH6Qp8crolnxqcA0mihelqlAsBMtDVkfMz3HqIGs49Y7ZV6I2CucIRPpuwcz3I98ahiNa3EWN+PTZ10q2OO3KgnZ4HUWeUH1y9ZeY8p/hrcQuVg/HAV7qUBV5DXYvHJFDSuSO/CC/4y4ABojaEIfxnTdu4RinE60B7H/kDVLFEN5rMQNr9xQJO49xeswEiJu5cxhA2eyE+9OnK/RyuBSp7VZRCHOZNSuZbLNvpM2GebLbpI2Cv4B3qxVg1/GJ/EdYxM9JAfpPMUf0ngN1/sCWkgy6xF138ljeKeE/+pDeR2I/u13GnPIXYVSXu7JK43/FYJgaJhlLzqYy6WuuJe+jy8JaFq20/FYiedbckgeKXTVHLyHF43+BFjLcyFark4wlGQLksDquRd8ajcClnnF42qxvIbz0sYP4fS7WtJJIYF4FrPOwF+Mq3s0wSHst4/K+oEirvfl7d1pulZPyHuXYYSzW6f9n8zw4gnZZ6Kx0vWbyZdOnuu4J0jqwU4krLRbqcZern9l+MNiztb+00OkLV9o0kuawhSyEYFsZHVmgDgou8cv1YZmkYNuT73L3O4A0Hdmb3rAVp0+099wfURTu82lutQKmfMU3Cowi+ga/FX2SHK/rCE7yDXfvMYc0yyNGNGgTngccrzV+J5xBHlXp71hQ5tLI3WNLcb3l8sooIgwmYJjrAaP7si8BB80ibAEjpqj1cXQKA0k187wSz7e8ghrdSUCbMoZ6qOHU6khiHLLk+t/0emEsdlkKRE5W3MWqriR9l385t63kyXYudGi3j1qwvmeMLcbb4U355k0BWR8nQSXfmGQdEFNdVo8DvdeGPDH9Be43lL7wrVIYkB9zoQgyzGEVbVA480zB6vAaXWTb0005clVAf7qk2IC0KlVDe93UmjH+t7nP62ggyxkgjvnII3kxqzKYY6c6zGS5eycvCZXac4tyln/7mDWPcwYBWVdUhj9KiMMXki7LDccOcEZ5svyWusUBdeQibHVUasGEPdBL5q+Zvav1X7MGffKNFAuB75cIfkpVIKPtpzmsfjKe8Dtho/513Vu2sygx+3jf4XeegHOOHDlOagc/iH5XG2XHroPlEHYh6UDYG4E5BXBGqO1AlExRt865MltQxCbIbDoYDObsQUmkIC+E7LXz2sUbyRYLWIKWwA0TIcYDjNKvKXJqnSgLbpQcha7j93/sHiLlCb62Ew061pxlGJ8aoZTjjiUiqGrVLkkcSgDtoof+AlQPQQ10byhVew2sKZGoNJDslvG/MteKjcJp3Qrx2fRH7KsxWDn0oQNvoW3TNbzfVoEZn9Bt4teB5aNXXuk8IGb82ifVWpFbw+kwpLaf2k1rFZOYuiSF4CiGwRUzJmiAztIGU7+7ly6I9dnXm6CJV7JbrUdEG+YvOz1oiwFmVJ95tXMh7Hb90n+m3nLLoCVi9z9tu5FN+88TnD44/xvt5bqXOU2VUB1yi/RM8jathAs+aHMlylkBiDRQn8S8wzqHwT3rf9jjebWoIUpovsd92QHZoFTWmEIZhOryl7BUcmzTL3EsMtjmCmgAbnr0z+KmAATKwP2O84zqVkKnCX6iHQQYhkBUrqC861RtRfPBe0R843e8X9NNVwC/dj16C0dpBSu0J9q+8/GPZuNo8OgqPTkfi/dyhQbhDskdq8AF22au8nrdR5p2Q08HMgrcqC9Wes7V6hD6xYxoakPR1Z+RXnBJ9j6QtszbJPnMle7cVxGDxpHOiGyJe7VSA+fuFHjA/CUpgZ5CfDhg+a5QiWTyoHhBbhKI1F7hYx5XnNlTFpr4XeI9BPmCaF2C0WqT4fTt6pylSePgX/M3bMrhahKvSlNnjMPVmT+0qxWDP5ZeO/nUK2UdB33GqZulITtkbawh1NNHWnN8L5DmTyftFtvJf1CYkt1rhdrRyL6F/6a9JTgOII+Gy8AnIi4M5/tR86dtHzbpM6AbYiP9Ru/4wAg17zmMf9GI5beUa4k00C6S9+Xjhw6xRsgd9Ong1FMJIKxB9gsY0rqNs3n2MVQnHakhNaLhvC7qNc9n4Iqytg6yamPHsIZrHrBNukHjbfoFiwEdfEspRG9SA5zWzBq9x2tECc1koX5kZ8yO+Lw6IAUr3/poneYBOFSsGS5EvPo75Q4xa82VQ7fyzKaunAdCiD90SNJFIG0J+7iAP4I4JOGeVm+TF0yWKcHVcKSizzmSd8Qwq1N3ivK9kONWYedzoTec1qiyqc5L2WQhGJXAvYvRxv5KD9g2YuUOOwWTvumsgthQKPpvIKvuqVuHjWX7Lty2rbVPDJR/yZcrL0nN+P9povs0n4EHAaWvGiS/+rPpZTzA5iM9oZyXkXb5bSagpcrOtRxSNCgDVuKPwThD4OjTUbhZskBIliH8xUFsNXB2ZG6gxhxahK1nzCMNIZf2boMah8u0uvkvGpQusuE6rdNnge1G20WN+Q0Udlo8Hhclyp6b5AcaThvD3pikJ/L6vWI6TckTeB7yauAm2PtSrIBYz5IuACdD1bCIzItX5Eivu/nT4P/6AYugKr2zNUJMb7SgVh1fg0Vg95rAOiz/xwwIZRdCDQCGWUO/lV3kH0Ua9uQ1yVyvYjv9ljH0/yyyVTB2XijnoxaPVTfhuS8J87HZC4Kn0Wsc+V9C9o5SBPDzzyBLD+R7nhUsZ+IaMKdJ3aGM61L4ZPpIIy/J53AGeWuIDMTSK72EOLJsrpbAV8r9lo5J3ITIdkHUjWtliVe7mbXssvmGyFIqMN57dfzociOfB+C+hmEuJtDbg+4qk15xz0L63rVwen5bJhP75N0F8LgzlVCeow26Rwiw45x+0u2xqB51QS7TjXa0STL+RIvWeWU6ZDxq840JlZhRXUUbB1RZ8Ma5LKdhY2hhKb+C2h7iWr+nWZwQ/8JcDygBdnSoyraD+1zp5ds4kW83IPrOoAxCv6diKK9U0d7sssbI0K2V2H0zz5K0qe9M63chyJUMFv1Rq5PF2ATq5gQ5nSpwLjJ8cMjyh1Afssv1HJl1l9QdqNENSdXgd9v2hDl7v+P8AX57Mff77fWW8KUdc83xM1lkVjjiPjnjHSCucpVf1zt1j2fNXvO8VOmXbdHzb9FadvWrlLNObKoSqrBehaJH6ZMXJQm2EDqh2R4SygfrT/d+IFy/BwyADujWmleb4cNoVDoCBMYaOE5A87pmW3hdIt8xzhdLAZbT33itd7FKbhY/fLDe7ZRYT9QK5m8wJhyCmvWZwTSKhVdz3EGNpFj8zsCsRusgjbHlyx9owD5ERhwJo+iAT/jlXcFl5IuDfSSwKqQIonunDRLcN7Gr5DjKVNgvY1voct2boh9lmVCa5dJpXjM/+QvjFv0SNSwXQjkAlTzaZexSScuXfOI/JsiL0qe8NapjgPmmMI7laW2x/lDNMbdd5c/RWSZakz5Wz4fNxIW4AbRHjwoEKA6TOj8bTcdSXqOH1I7TUBr42gCljolPMR4Hf2U+iySKHUMnNbO7pmlUSkB7N6ReIGg8ZMGzq0E6TA2a5UFMoGl2DTDUxrMfeED7TfFMuCUftkLt2zHDZoSZgdyY0ZdcwjgQv5m4TxMMrsJWnSM6DJVbclotaKynLuAWcn6Itk+bYZfZvKG6pJwphuU6ViluAdRMSBQXfYpc8wYqpB3zSR61HGtRetcQFTgMGPTOoYa/o/d+gFYyNQjz+dfcc5rEwu4kD+WYrWA2E21CvxCjC/eKPqEpnxVgVz/LoJg1/AAGk6jmJHItSathQ69QywiCuaE5JSvZz80i3E+E0J2x56wpBtJro5duOm+xmBxXKwTdgHa1PLGrDFJoFO1PApmP6r4SfM51c3/WXhqFpzzlbnv9pn9CxAeBGnYhu4kW2e61cA0akM7JQpVIu1S5U5+RqJOrf+M4RDkOk8nCBxrkZXFHKeBnyoiRpGeinbnB1BewE4sBqE3bdT64bhM1j1PhOw30WCX8dIEs1xBtkg5GOiVeOTHqpu1WEUtuFbyA3ThbvZNPS/EOm+lMsEhjb7tqJci89HpAtoljkGdK7RJMSHaSyV8h9zn/W5POlXqn0I07wne1/dDPMroW8DjjV59TwaW5JLaD1xLF3xrU/IZg7V7CVu8FrG9iLWwEiYEHunUPzJFlOv2jBkgiKYastEkjZr7AHBPpi5Vsz6R73mpiSX6neyJNiYz6kSO23oJJR2MEudtBWRNH9Mq2v+K91j5Qs4o3a9PIwD5k+s/Q4puPQSnEmo91Ehhzp9H5ZkFk1ow0fODfiBBlD7h9WdD7tW8sOEB9NB57wC5IwUW4izRCjNjl3oD/hcpMIUzziJ2HRZ3YDPK4tz0uoGp94x7oHQrwOIMaNewA==");
|
|
314
|
-
const t = new Uint8Array(s.length);
|
|
315
|
-
for (let i = 0; i < s.length; i += 1) t[i] = s.charCodeAt(i);
|
|
316
|
-
return t;
|
|
317
|
-
})();
|
|
318
|
-
var SCREENS = {
|
|
319
|
-
bayer2: { name: "Bayer 2", at: (x, y) => (b2((y & 1) * 2 + (x & 1)) + 0.5) / 4 },
|
|
320
|
-
bayer4: { name: "Bayer 4", at: (x, y) => (b4((y & 3) * 4 + (x & 3)) + 0.5) / 16 },
|
|
321
|
-
bayer8: { name: "Bayer 8", at: (x, y) => (b8((y & 7) * 8 + (x & 7)) + 0.5) / 64 },
|
|
322
|
-
chunky: { name: "Chunky", at: (x, y) => (b4((y >> 1 & 3) * 4 + (x >> 1 & 3)) + 0.5) / 16 },
|
|
323
|
-
// (As fine as the old screen: a dot every 18 pixels, now truly at 45°.)
|
|
324
|
-
halftone: { name: "Halftone", at: dotScreen([3, 3], [3, -3], 6, 6) },
|
|
325
|
-
// (The coarse dot keeps its nine flat levels for now: equalized, at 26.6°
|
|
326
|
-
// or square, its dots read as blotches to every critic. The owner's call.)
|
|
327
|
-
coarseDot: { name: "Coarse Dot", at: (x, y) => (Math.cos((x + y) / 6 * Math.PI) * Math.cos((x - y) / 6 * Math.PI) + 1) * 0.5 },
|
|
328
|
-
// (Line screen, crosshatch, checker and weave keep their few flat levels
|
|
329
|
-
// for now: equalized, a night sky's gradient turns to dashes, hatching lies
|
|
330
|
-
// across the objects and a checker becomes a lattice of specks -- and blind
|
|
331
|
-
// critics preferred the flat fills every time. The owner's call.)
|
|
332
|
-
lines: { name: "Line Screen", at: (x, y) => tri(y / 3 + 0.5) * 0.9 + b2((y & 1) * 2 + (x & 1)) / 4 * 0.1 },
|
|
333
|
-
diagonal: { name: "Diagonal", at: equalize((x, y) => [3, 1, 0, 2][x + y & 3], 8, 8, (x, y) => along(x + 4 * (x + y >> 2))) },
|
|
334
|
-
hatch: { name: "Crosshatch", at: (x, y) => (tri((x + y) / 4) + tri((x - y) / 4)) * 0.5 },
|
|
335
|
-
stipple: { name: "Stipple", at: (x, y) => (BLUE_NOISE[(y & 63) * 64 + (x & 63)] + 0.5) / 256 },
|
|
336
|
-
ign: { name: "Interleaved", at: (x, y) => fract(52.9829189 * fract(0.06711056 * x + 583715e-8 * y)) },
|
|
337
|
-
checker: { name: "Checker", at: (x, y) => x + y & 1 ? 0.3 : 0.7 },
|
|
338
|
-
weave: { name: "Weave", at: (x, y) => ((x >> 1) + (y >> 1) & 1 ? tri(x / 4) : tri(y / 4)) * 0.94 + 0.03 }
|
|
339
|
-
};
|
|
340
|
-
var SCREEN_IDS = Object.keys(SCREENS);
|
|
341
|
-
function measureScreen(at, T = 24) {
|
|
342
|
-
const vals = [];
|
|
343
|
-
for (let y = 0; y < T; y += 1) for (let x = 0; x < T; x += 1) vals.push(at(x, y));
|
|
344
|
-
const levels = new Set(vals.map((v) => v.toFixed(4))).size;
|
|
345
|
-
const bins = new Array(16).fill(0);
|
|
346
|
-
for (const v of vals) {
|
|
347
|
-
const b = Math.min(15, Math.floor(v * 16));
|
|
348
|
-
bins[b] = bins[b] + 1;
|
|
349
|
-
}
|
|
350
|
-
const maxBin = Math.max(...bins) / vals.length;
|
|
351
|
-
const mean = vals.reduce((a, v) => a + v, 0) / vals.length;
|
|
352
|
-
const varr = vals.reduce((a, v) => a + (v - mean) ** 2, 0) / vals.length || 1;
|
|
353
|
-
const corr = (dx, dy) => {
|
|
354
|
-
let acc = 0;
|
|
355
|
-
let n = 0;
|
|
356
|
-
for (let y = 0; y < T - 8; y += 1) for (let x = 8; x < T - 8; x += 1) {
|
|
357
|
-
acc += (at(x, y) - mean) * (at(x + dx, y + dy) - mean);
|
|
358
|
-
n += 1;
|
|
359
|
-
}
|
|
360
|
-
return acc / n / varr;
|
|
361
|
-
};
|
|
362
|
-
const shifts = [];
|
|
363
|
-
for (let dy = 0; dy <= 8; dy += 1) for (let dx = -8; dx <= 8; dx += 1) if (dy > 0 || dx > 0) shifts.push({ r: corr(dx, dy), dx, dy });
|
|
364
|
-
const rMax = Math.max(...shifts.map((s) => s.r));
|
|
365
|
-
const best = shifts.filter((s) => s.r > rMax - 0.02).sort((a, b) => Math.hypot(a.dx, a.dy) - Math.hypot(b.dx, b.dy))[0];
|
|
366
|
-
const angle = (Math.atan2(best.dy, best.dx) * 180 / Math.PI + 180) % 180;
|
|
367
|
-
const unit2 = [[0, 1, 0], [45, 1, 1], [90, 0, 1], [135, -1, 1]].map(([a, dx, dy]) => [a, corr(dx, dy)]);
|
|
368
|
-
const top = Math.max(...unit2.map(([, r]) => r));
|
|
369
|
-
return {
|
|
370
|
-
levels,
|
|
371
|
-
maxBin,
|
|
372
|
-
period: +Math.hypot(best.dx, best.dy).toFixed(2),
|
|
373
|
-
angle: +angle.toFixed(1),
|
|
374
|
-
r: +best.r.toFixed(2),
|
|
375
|
-
// (Every direction within a hair of the smoothest counts: a crosshatch runs both diagonals.)
|
|
376
|
-
lines: unit2.filter(([, r]) => r > top - 0.02).map(([a]) => a)
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
var SCREEN_GEOM = Object.fromEntries(SCREEN_IDS.map((id2) => {
|
|
380
|
-
const m = measureScreen(SCREENS[id2].at);
|
|
381
|
-
return [id2, { period: m.period, angle: m.angle, r: m.r, lines: m.lines }];
|
|
382
|
-
}));
|
|
383
|
-
|
|
384
|
-
// ../../../../../../keel-engine/packages/core/src/quantize.ts
|
|
385
|
-
var BAYER4Q = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5].map((v) => (v + 0.5) / 16);
|
|
386
|
-
|
|
387
|
-
// ../../../../../../keel-engine/packages/core/src/gif.ts
|
|
388
|
-
var DICT = new Int32Array(1 << 17).fill(-1);
|
|
389
|
-
var DICT_TOUCHED = new Int32Array(1 << 12);
|
|
390
|
-
|
|
391
|
-
// ../../../../../../keel-engine/packages/core/src/targets.ts
|
|
392
|
-
var preset = (id2, label, kind, width, height, paletteLimit, channelBits, screen, hardware = null) => Object.freeze({ id: id2, label, kind, width, height, paletteLimit, channelBits, screen, dither: screen ? 0.9 : 0, hardware });
|
|
393
|
-
var TARGET_PROFILES = Object.freeze({
|
|
394
|
-
native: preset("native", "Original", "native", 128, 128, 65536, 8, 4),
|
|
395
|
-
"8-bit": preset("8-bit", "8-bit style", "style", 256, 240, 16, 8, 2),
|
|
396
|
-
"16-bit": preset("16-bit", "16-bit style", "style", 320, 240, 256, 5, 4),
|
|
397
|
-
"32-bit": preset("32-bit", "32-bit style", "style", 512, 384, 32768, 5, 4),
|
|
398
|
-
"64-bit": preset("64-bit", "64-bit style", "style", 640, 480, 65536, 8, 8),
|
|
399
|
-
"game-boy": preset("game-boy", "Game Boy", "hardware", 160, 144, 4, 8, 2, "game-boy"),
|
|
400
|
-
"game-boy-color": preset("game-boy-color", "Game Boy Color", "hardware", 160, 144, 32, 5, 2, "game-boy-color"),
|
|
401
|
-
chromatic: preset("chromatic", "ModRetro Chromatic", "hardware", 160, 144, 32, 5, 2, "game-boy-color")
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
// ../../../../../../keel-engine/packages/ui/src/color.ts
|
|
405
|
-
var rgba = (r, g, b, a = 255) => (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
406
|
-
var rgbOf = (c) => [c & 255, c >>> 8 & 255, c >>> 16 & 255];
|
|
407
|
-
var fromRgb = (rgb) => rgba(rgb[0] ?? 0, rgb[1] ?? 0, rgb[2] ?? 0);
|
|
408
|
-
var fromOklch = (L, C, h) => fromRgb(oklch(L, C, h));
|
|
409
|
-
var toHex = (c) => `#${rgbOf(c).map((v) => v.toString(16).padStart(2, "0")).join("")}`;
|
|
410
|
-
function luminance(c) {
|
|
411
|
-
const [r, g, b] = rgbOf(c);
|
|
412
|
-
return 0.2126 * srgb8ToLinear(r) + 0.7152 * srgb8ToLinear(g) + 0.0722 * srgb8ToLinear(b);
|
|
413
|
-
}
|
|
414
|
-
function contrast(a, b) {
|
|
415
|
-
const la = luminance(a);
|
|
416
|
-
const lb = luminance(b);
|
|
417
|
-
return (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
// ../../../../../../keel-engine/packages/ui/src/raster.ts
|
|
421
|
-
function ellipse(cx, cy, rx, ry = rx, segments = 0) {
|
|
422
|
-
const n = segments || Math.max(12, Math.ceil(Math.max(rx, ry) * 4));
|
|
423
|
-
const out = [];
|
|
424
|
-
for (let i = 0; i < n; i += 1) {
|
|
425
|
-
const a = i / n * Math.PI * 2;
|
|
426
|
-
out.push(cx + Math.cos(a) * rx, cy + Math.sin(a) * ry);
|
|
427
|
-
}
|
|
428
|
-
return out;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// ../../../../../../keel-engine/packages/ui/src/genfont.ts
|
|
432
|
-
var SERIFS = ["none", "slab", "foot"];
|
|
433
|
-
var ZEROS = ["plain", "dot", "slash"];
|
|
434
|
-
var SOFTS = ["all", "top", "bottom"];
|
|
435
|
-
var DEFAULT_FONT_RANGES = { width: [0.52, 0.86], xHeight: [0.56, 0.8], round: [0, 1, 2], stroke: [0.08, 0.22], serif: [["none", 3], ["slab", 2], ["foot", 1]], slant: 0.15, tracking: [1, 2] };
|
|
436
|
-
function fontParamsOf(S, ranges = DEFAULT_FONT_RANGES, pins = {}) {
|
|
437
|
-
const drawn = {
|
|
438
|
-
width: round2(S.between(ranges.width[0], ranges.width[1])),
|
|
439
|
-
xHeight: round2(S.between(ranges.xHeight[0], ranges.xHeight[1])),
|
|
440
|
-
descender: round2(S.between(0.2, 0.34)),
|
|
441
|
-
round: S.pick(ranges.round),
|
|
442
|
-
stroke: round2(S.between(ranges.stroke[0], ranges.stroke[1])),
|
|
443
|
-
serif: S.weighted(ranges.serif),
|
|
444
|
-
slant: S.chance(ranges.slant) ? 1 : 0,
|
|
445
|
-
tracking: S.pick(ranges.tracking),
|
|
446
|
-
zero: S.pick(ZEROS),
|
|
447
|
-
ascend: S.chance(0.4) ? 1 : 0,
|
|
448
|
-
soft: S.weighted([["all", 3], ["top", 1], ["bottom", 1]]),
|
|
449
|
-
capWidth: S.chance(0.3) ? 2 : 0
|
|
450
|
-
};
|
|
451
|
-
return { ...drawn, ...pins };
|
|
452
|
-
}
|
|
453
|
-
var round2 = (v) => Math.round(v * 100) / 100;
|
|
454
|
-
var GLYPHS = [
|
|
455
|
-
// Capitals.
|
|
456
|
-
[65, "n", "M0,b L0,c~ L1,c~ L1,b M0,h L1,h"],
|
|
457
|
-
// (B, D, O, S and I are at least 5 wide -- wider than the figures in a narrow family's small sizes -- so none of
|
|
458
|
-
// them is ever an 8, a 0, a 5 or a 1.)
|
|
459
|
-
[66, "o", "M0,b L0,c L1,c^ L1,h^ L0,h M0,h L1,h^ L1,b^ L0,b"],
|
|
460
|
-
[67, "n", "M1,c L0,c~ L0,b~ L1,b"],
|
|
461
|
-
[68, "o", "M0,b L0,c L1,c^ L1,b^ L0,b"],
|
|
462
|
-
[69, "n", "M1,c L0,c L0,b L1,b M0,h L1-1,h"],
|
|
463
|
-
[70, "n", "M1,c L0,c L0,b M0,h L1-1,h"],
|
|
464
|
-
// (G: open at the top-right -- its top stops short of the corner and never turns down -- the right side rises from
|
|
465
|
-
// the baseline to the middle, and a bar comes in from it; never reaching the left side, so no B-like join. At least
|
|
466
|
-
// 5 px wide, room for the gap between that bar and the left stem.)
|
|
467
|
-
[71, "o", "M1-2,c L0,c^ L0,b^ L1,b^ L1,h L.5+1,h"],
|
|
468
|
-
[72, "n", "M0,b L0,c M1,b L1,c M0,h L1,h"],
|
|
469
|
-
[73, "I", "M0,c L1,c M.5,c L.5,b M0,b L1,b"],
|
|
470
|
-
[74, "n", "M1,c L1,b~ L0,b~ L0,.25"],
|
|
471
|
-
[75, "n", "M0,b L0,c M1,c L0+1,h L1,b"],
|
|
472
|
-
[76, "n", "M0,c L0,b L1,b"],
|
|
473
|
-
[77, "w", "M0,b L0,c L.5,.45 L1,c L1,b"],
|
|
474
|
-
[78, "n", "M0,b L0,c L1,b L1,c"],
|
|
475
|
-
[79, "o", "M0,b~ L0,c~ L1,c~ L1,b~ Z"],
|
|
476
|
-
[80, "n", "M0,b L0,c L1,c~ L1,h~ L0,h"],
|
|
477
|
-
[81, "n", "M0,b~ L0,c~ L1,c~ L1,b~ Z M.5,.3 L1,b-1"],
|
|
478
|
-
[82, "n", "M0,b L0,c L1,c~ L1,h^ L0,h M0+1,h L1,b"],
|
|
479
|
-
[83, "o", "M1,c L0,c^ L0,h^ L1,h^ L1,b^ L0,b"],
|
|
480
|
-
[84, "n", "M0,c L1,c M.5,c L.5,b"],
|
|
481
|
-
[85, "n", "M0,c L0,b~ L1,b~ L1,c"],
|
|
482
|
-
[86, "n", "M0,c L0,.3 L.5,b L1,.3 L1,c"],
|
|
483
|
-
[87, "w", "M0,c L0,b L.5,.55 L1,b L1,c"],
|
|
484
|
-
[88, "n", "M0,c L0,.75 L1,.25 L1,b M1,c L1,.75 L0,.25 L0,b"],
|
|
485
|
-
[89, "n", "M0,c L0,.75 L.5,h L1,.75 L1,c M.5,h L.5,b"],
|
|
486
|
-
[90, "n", "M0,c L1,c L1,.8 L0,.2 L0,b L1,b"],
|
|
487
|
-
// Lower case.
|
|
488
|
-
[97, "n", "M0+1,x L1,x~ L1,b M1,k L0,k~ L0,b~ L1,b"],
|
|
489
|
-
[98, "n", "M0,a L0,b L1,b~ L1,x~ L0,x"],
|
|
490
|
-
[99, "n", "M1,x L0,x~ L0,b~ L1,b"],
|
|
491
|
-
[100, "n", "M1,a L1,b L0,b~ L0,x~ L1,x"],
|
|
492
|
-
[101, "n", "M0,k L1,k L1,x~ L0,x~ L0,b~ L1-1,b"],
|
|
493
|
-
[102, "s", "M1,a L.5,a~ L.5,b M0,x L1-1,x"],
|
|
494
|
-
[103, "n", "M1,b L0,b~ L0,x~ L1,x L1,d~ L0,d"],
|
|
495
|
-
[104, "n", "M0,a L0,b M0,x L1,x~ L1,b"],
|
|
496
|
-
[105, "i", "M0,b L0,s M0,c"],
|
|
497
|
-
[106, "t", "M1,s L1,d~ L0,d M1,c"],
|
|
498
|
-
[107, "n", "M0,a L0,b M1,x L0+1,k L1,b"],
|
|
499
|
-
[108, "i", "M0,a L0,b"],
|
|
500
|
-
[109, "w", "M0,b L0,x L1,x~ L1,b M.5,x L.5,b"],
|
|
501
|
-
[110, "n", "M0,b L0,x L1,x~ L1,b"],
|
|
502
|
-
[111, "n", "M0,b~ L0,x~ L1,x~ L1,b~ Z"],
|
|
503
|
-
[112, "n", "M0,d L0,x L1,x~ L1,b~ L0,b"],
|
|
504
|
-
[113, "n", "M1,d L1,x L0,x~ L0,b~ L1,b"],
|
|
505
|
-
[114, "t", "M0,b L0,x L1,x"],
|
|
506
|
-
[115, "n", "M1,x L0,x~ L0,.6x L1,.4x L1,b~ L0,b"],
|
|
507
|
-
// (t: a crossbar through the stem at the x-height, both sides; the stem only a little above it -- well under l's
|
|
508
|
-
// ascender -- and a foot turned right, always cut, square fonts too: never an l.)
|
|
509
|
-
[116, "s", "M.5,t L.5,b^ L1,b M0,x L1,x"],
|
|
510
|
-
[117, "n", "M0,x L0,b~ L1,b L1,x"],
|
|
511
|
-
[118, "n", "M0,x L0,.4x L.5,b L1,.4x L1,x"],
|
|
512
|
-
[119, "w", "M0,x L0,b L.5,k L1,b L1,x"],
|
|
513
|
-
[120, "n", "M0,x L1,b M1,x L0,b"],
|
|
514
|
-
[121, "n", "M0,x L0,b~ L1,b M1,x L1,d~ L0,d"],
|
|
515
|
-
[122, "n", "M0,x L1,x L0,b L1,b"],
|
|
516
|
-
// Figures (tabular: all one width).
|
|
517
|
-
// (Figures: 0 narrower than its cell where there's room -- an oval, never an O; 8 two stacked loops, the upper one
|
|
518
|
-
// narrower, pinched at the waist -- never a flat-sided B; 1 a long flag and a foot; 5 a flat top over a bowl.)
|
|
519
|
-
[48, "d", "M0+i,b^ L0+i,c^ L1-i,c^ L1-i,b^ Z"],
|
|
520
|
-
[49, "d", "M0,c-2 L0,c-1 L.5,c L.5,b M0,b L1,b"],
|
|
521
|
-
[50, "d", "M0,c L1,c~ L1,h~ L0,h~ L0,b L1,b"],
|
|
522
|
-
[51, "d", "M0,c L1,c^ L1,h^ L.5,h M.5,h L1,h^ L1,b^ L0,b"],
|
|
523
|
-
[52, "d", "M0,c L0,h L1,h M1,c L1,b"],
|
|
524
|
-
[53, "d", "M1,c L0,c L0,.7 L1,.7~ L1,b~ L0,b"],
|
|
525
|
-
[54, "d", "M1,c L0,c~ L0,b~ L1,b~ L1,h~ L0,h"],
|
|
526
|
-
[55, "d", "M0,c L1,c L1,.75 L.5,.35 L.5,b"],
|
|
527
|
-
[56, "d", "M0+i,h L0+i,c^ L1-i,c^ L1-i,h Z M0+i,h L0,h-1 L0,b^ L1,b^ L1,h-1 L1-i,h"],
|
|
528
|
-
[57, "d", "M.5,b L1,b~ L1,c~ L0,c~ L0,h~ L1,h"],
|
|
529
|
-
// Punctuation and symbols.
|
|
530
|
-
[33, "i", "M0,c L0,b+2 M0,b"],
|
|
531
|
-
[34, "s", "M0,c L0,c-1 M1,c L1,c-1"],
|
|
532
|
-
[35, "w", "M.25,c L.25,b M.75,c L.75,b M0,.7 L1,.7 M0,.3 L1,.3"],
|
|
533
|
-
[36, "n", "M1,c-1 L0,c-1~ L0,h~ L1,h~ L1,b+1~ L0,b+1 M.5,c L.5,b"],
|
|
534
|
-
[37, "n", "M0,c M1,c L0,b M1,b"],
|
|
535
|
-
[38, "n", "M1,b L0,.55 L0,c~ L1-1,c~ L1-1,.7 L0,.3 L0,b~ L1-1,b L1,.3"],
|
|
536
|
-
[39, "i", "M0,c L0,c-1"],
|
|
537
|
-
[40, "t", "M1,c L0,c-1 L0,b+1 L1,b"],
|
|
538
|
-
[41, "t", "M0,c L1,c-1 L1,b+1 L0,b"],
|
|
539
|
-
[42, "n", "M0,.75 L1,.25 M1,.75 L0,.25 M.5,.85 L.5,.15"],
|
|
540
|
-
// (+: at least 5 wide, its arms as long as the room allows each way -- a cross, never a t without its foot.)
|
|
541
|
-
[43, "o", "M0,h L1,h M.5,h+r L.5,h-r"],
|
|
542
|
-
[44, "t", "M1,b L0,b-1"],
|
|
543
|
-
[45, "s", "M0,h L1,h"],
|
|
544
|
-
[46, "i", "M0,b"],
|
|
545
|
-
[47, "n", "M1,c L0,b"],
|
|
546
|
-
[58, "i", "M0,b M0,.75x"],
|
|
547
|
-
[59, "t", "M1,.75x M1,b L0,b-1"],
|
|
548
|
-
[60, "s", "M1,c-1 L0,h L1,b+1"],
|
|
549
|
-
[61, "s", "M0,.65 L1,.65 M0,.35 L1,.35"],
|
|
550
|
-
[62, "s", "M0,c-1 L1,h L0,b+1"],
|
|
551
|
-
[63, "n", "M0,c L1,c~ L1,h~ L.5,h L.5,b+2 M.5,b"],
|
|
552
|
-
[64, "w", "M1,.3 L1,c~ L0,c~ L0,b~ L1,b M.75,.3 L.35,.3 L.35,.7 L.75,.7 L.75,.3"],
|
|
553
|
-
[91, "t", "M1,c L0,c L0,b L1,b"],
|
|
554
|
-
[92, "n", "M0,c L1,b"],
|
|
555
|
-
[93, "t", "M0,c L1,c L1,b L0,b"],
|
|
556
|
-
[94, "s", "M0,.7 L.5,c L1,.7"],
|
|
557
|
-
[95, "n", "M0,b-1 L1,b-1"],
|
|
558
|
-
[96, "t", "M0,c L1,c-1"],
|
|
559
|
-
[123, "s", "M1,c L.5,c~ L.5,h+1 L0,h L.5,h-1 L.5,b~ L1,b"],
|
|
560
|
-
[124, "i", "M0,c L0,b-1"],
|
|
561
|
-
[125, "s", "M0,c L.5,c~ L.5,h+1 L1,h L.5,h-1 L.5,b~ L0,b"],
|
|
562
|
-
[126, "w", "M0,h L.25,h+1 L.5,h L.75,h-1 L1,h"],
|
|
563
|
-
// The UI's own: ellipsis, bullet, multiply, divide, degree, arrows, triangles, squares, tick, heart, star.
|
|
564
|
-
[8230, "w", "M0,b M.5,b M1,b"],
|
|
565
|
-
[8226, "s", "FM0,h-1 L1,h-1 L1,h+1 L0,h+1 Z"],
|
|
566
|
-
[215, "s", "M0,.7 L1,.3 M0,.3 L1,.7"],
|
|
567
|
-
[247, "s", "M0,h L1,h M.5,h+2 M.5,h-2"],
|
|
568
|
-
[176, "t", "M0,c L1,c L1,c-1 L0,c-1 Z"],
|
|
569
|
-
[8592, "w", "M0,h L1,h M0+2,h+2 L0,h L0+2,h-2"],
|
|
570
|
-
[8594, "w", "M0,h L1,h M1-2,h+2 L1,h L1-2,h-2"],
|
|
571
|
-
[8593, "n", "M.5,c L.5,b M0,c-1 L.5,c L1,c-1"],
|
|
572
|
-
[8595, "n", "M.5,c L.5,b M0,b+1 L.5,b L1,b+1"],
|
|
573
|
-
[9650, "n", "FM0,.15 L.5,.85 L1,.15 Z"],
|
|
574
|
-
[9660, "n", "FM0,.85 L.5,.15 L1,.85 Z"],
|
|
575
|
-
[9664, "n", "FM1,.9 L0,h L1,.1 Z"],
|
|
576
|
-
[9654, "n", "FM0,.9 L1,h L0,.1 Z"],
|
|
577
|
-
[9632, "n", "FM0,.8 L1,.8 L1,.2 L0,.2 Z"],
|
|
578
|
-
[9633, "n", "M0,.8 L1,.8 L1,.2 L0,.2 Z"],
|
|
579
|
-
[10003, "n", "M0,h L.4,b+1 L1,c-1"],
|
|
580
|
-
[9829, "n", "FM.5,.05 L0,.55 L0,.78 L.25,.95 L.5,.78 L.75,.95 L1,.78 L1,.55 Z"],
|
|
581
|
-
[9733, "w", "FM.5,1 L.62,.62 L1,.62 L.69,.38 L.81,0 L.5,.24 L.19,0 L.31,.38 L0,.62 L.38,.62 Z"]
|
|
582
|
-
];
|
|
583
|
-
var GENERATED_CODES = [32, ...GLYPHS.map(([c]) => c)].sort((a, b) => a - b);
|
|
584
|
-
|
|
585
|
-
// ../../../../../../keel-engine/packages/ui/src/theme.ts
|
|
586
|
-
var THEME_GENERATOR = "keel/ui/theme@1";
|
|
587
|
-
var CULTURES = ["industrial", "organic", "crystalline", "arcane", "brutal", "clean"];
|
|
588
|
-
var CORNERS = ["flat", "bevel", "inset", "notched", "rivets", "glow", "round"];
|
|
589
|
-
var FILLS = ["solid", "dither", "gradient", "scan"];
|
|
590
|
-
var MOTIONS = ["snappy", "bouncy", "none"];
|
|
591
|
-
var ICON_STYLES = ["solid", "outline", "duotone"];
|
|
592
|
-
var TONES = ["dark", "light"];
|
|
593
|
-
var F = DEFAULT_FONT_RANGES;
|
|
594
|
-
var CULTURE_SPECS = {
|
|
595
|
-
industrial: {
|
|
596
|
-
surfaceHue: [[[200, 245], 4], [[30, 60], 1]],
|
|
597
|
-
surfaceChroma: [0.012, 0.035],
|
|
598
|
-
surfaceL: [0.27, 0.35],
|
|
599
|
-
accentHue: [[[55, 88], 4], [[25, 45], 2]],
|
|
600
|
-
accentChroma: [0.13, 0.18],
|
|
601
|
-
shift: 8,
|
|
602
|
-
light: 0,
|
|
603
|
-
corners: [["rivets", 4], ["bevel", 3], ["notched", 1]],
|
|
604
|
-
border: [2, 2, 3],
|
|
605
|
-
bevel: [1, 1, 2],
|
|
606
|
-
inner: 0.5,
|
|
607
|
-
fills: [["dither", 3], ["scan", 2], ["gradient", 2], ["solid", 1]],
|
|
608
|
-
screens: ["diagonal", "lines", "bayer4", "hatch"],
|
|
609
|
-
shadow: [1, 1, 2],
|
|
610
|
-
font: { ...F, width: [0.62, 0.85], xHeight: [0.66, 0.78], round: [0, 0, 1], stroke: [0.1, 0.2], serif: [["none", 5], ["slab", 1]], slant: 0 },
|
|
611
|
-
caps: 0.75,
|
|
612
|
-
body: [7, 7, 8],
|
|
613
|
-
ratio: [1.25, 1.5],
|
|
614
|
-
unit: [2, 3],
|
|
615
|
-
motion: [["snappy", 5], ["none", 1]],
|
|
616
|
-
icon: [["solid", 3], ["duotone", 2]],
|
|
617
|
-
iconStroke: [1, 2]
|
|
618
|
-
},
|
|
619
|
-
organic: {
|
|
620
|
-
surfaceHue: [[[95, 155], 4], [[35, 70], 2]],
|
|
621
|
-
surfaceChroma: [0.03, 0.065],
|
|
622
|
-
surfaceL: [0.25, 0.33],
|
|
623
|
-
accentHue: [[[65, 105], 3], [[130, 170], 2], [[330, 360], 1]],
|
|
624
|
-
accentChroma: [0.12, 0.17],
|
|
625
|
-
shift: 14,
|
|
626
|
-
light: 0.05,
|
|
627
|
-
corners: [["round", 6], ["glow", 1], ["inset", 1]],
|
|
628
|
-
border: [1, 2],
|
|
629
|
-
bevel: [0, 1],
|
|
630
|
-
inner: 0.3,
|
|
631
|
-
fills: [["dither", 3], ["gradient", 2], ["solid", 1]],
|
|
632
|
-
screens: ["stipple", "halftone", "weave", "coarseDot"],
|
|
633
|
-
shadow: [0, 1, 1],
|
|
634
|
-
font: { ...F, width: [0.7, 0.86], round: [2, 2, 3], stroke: [0.08, 0.15], serif: [["none", 3], ["foot", 2]], slant: 0.05, tracking: [1] },
|
|
635
|
-
caps: 0.2,
|
|
636
|
-
body: [8, 8, 9],
|
|
637
|
-
ratio: [1.3, 1.5],
|
|
638
|
-
unit: [3, 4],
|
|
639
|
-
motion: [["bouncy", 5], ["snappy", 2]],
|
|
640
|
-
icon: [["duotone", 3], ["solid", 2]],
|
|
641
|
-
iconStroke: [1]
|
|
642
|
-
},
|
|
643
|
-
crystalline: {
|
|
644
|
-
surfaceHue: [[[190, 235], 3], [[260, 305], 2]],
|
|
645
|
-
surfaceChroma: [0.035, 0.075],
|
|
646
|
-
surfaceL: [0.2, 0.28],
|
|
647
|
-
accentHue: [[[165, 205], 3], [[290, 330], 2]],
|
|
648
|
-
accentChroma: [0.13, 0.19],
|
|
649
|
-
shift: -12,
|
|
650
|
-
light: 0.05,
|
|
651
|
-
corners: [["notched", 6], ["glow", 2], ["bevel", 1]],
|
|
652
|
-
border: [1, 1, 2],
|
|
653
|
-
bevel: [1],
|
|
654
|
-
inner: 0.6,
|
|
655
|
-
fills: [["gradient", 3], ["dither", 2], ["solid", 1]],
|
|
656
|
-
screens: ["bayer4", "bayer8", "checker", "diagonal"],
|
|
657
|
-
shadow: [0, 1],
|
|
658
|
-
font: { ...F, width: [0.5, 0.66], round: [0], stroke: [0.08, 0.14], serif: [["none", 1]], slant: 0.35 },
|
|
659
|
-
caps: 0.6,
|
|
660
|
-
body: [7, 8],
|
|
661
|
-
ratio: [1.3, 1.6],
|
|
662
|
-
unit: [2, 3],
|
|
663
|
-
motion: [["snappy", 5], ["bouncy", 1]],
|
|
664
|
-
icon: [["outline", 3], ["duotone", 2]],
|
|
665
|
-
iconStroke: [1]
|
|
666
|
-
},
|
|
667
|
-
arcane: {
|
|
668
|
-
surfaceHue: [[[270, 325], 4], [[230, 265], 2]],
|
|
669
|
-
surfaceChroma: [0.045, 0.085],
|
|
670
|
-
surfaceL: [0.2, 0.28],
|
|
671
|
-
accentHue: [[[70, 98], 4], [[160, 195], 2]],
|
|
672
|
-
accentChroma: [0.12, 0.17],
|
|
673
|
-
shift: 16,
|
|
674
|
-
light: 0,
|
|
675
|
-
corners: [["glow", 4], ["round", 2], ["notched", 1], ["inset", 1]],
|
|
676
|
-
border: [1, 2],
|
|
677
|
-
bevel: [0, 1],
|
|
678
|
-
inner: 0.7,
|
|
679
|
-
fills: [["dither", 3], ["gradient", 2]],
|
|
680
|
-
screens: ["halftone", "weave", "hatch", "coarseDot"],
|
|
681
|
-
shadow: [1],
|
|
682
|
-
font: { ...F, round: [1, 2], serif: [["slab", 4], ["foot", 2], ["none", 1]], slant: 0.2 },
|
|
683
|
-
caps: 0.5,
|
|
684
|
-
body: [7, 8],
|
|
685
|
-
ratio: [1.35, 1.6],
|
|
686
|
-
unit: [3, 4],
|
|
687
|
-
motion: [["bouncy", 4], ["snappy", 2]],
|
|
688
|
-
icon: [["duotone", 4], ["outline", 1]],
|
|
689
|
-
iconStroke: [1]
|
|
690
|
-
},
|
|
691
|
-
brutal: {
|
|
692
|
-
surfaceHue: [[[0, 35], 3], [[340, 360], 2], [[90, 120], 1]],
|
|
693
|
-
surfaceChroma: [8e-3, 0.04],
|
|
694
|
-
surfaceL: [0.16, 0.24],
|
|
695
|
-
accentHue: [[[20, 40], 4], [[92, 112], 2]],
|
|
696
|
-
accentChroma: [0.16, 0.22],
|
|
697
|
-
shift: 4,
|
|
698
|
-
light: 0,
|
|
699
|
-
corners: [["flat", 6], ["inset", 2], ["notched", 1]],
|
|
700
|
-
border: [2, 3, 3],
|
|
701
|
-
bevel: [0],
|
|
702
|
-
inner: 0.2,
|
|
703
|
-
fills: [["solid", 3], ["scan", 2], ["dither", 1]],
|
|
704
|
-
screens: ["chunky", "hatch", "lines"],
|
|
705
|
-
shadow: [2, 2, 1],
|
|
706
|
-
font: { ...F, width: [0.7, 0.9], stroke: [0.16, 0.25], round: [0], serif: [["none", 5], ["slab", 2]], slant: 0.1, tracking: [1] },
|
|
707
|
-
caps: 0.9,
|
|
708
|
-
body: [7, 8, 9],
|
|
709
|
-
ratio: [1.3, 1.7],
|
|
710
|
-
unit: [2, 3],
|
|
711
|
-
motion: [["none", 3], ["snappy", 3]],
|
|
712
|
-
icon: [["solid", 5]],
|
|
713
|
-
iconStroke: [2]
|
|
714
|
-
},
|
|
715
|
-
clean: {
|
|
716
|
-
surfaceHue: [[[215, 262], 3], [[175, 215], 2], [[0, 360], 1]],
|
|
717
|
-
surfaceChroma: [8e-3, 0.03],
|
|
718
|
-
surfaceL: [0.27, 0.36],
|
|
719
|
-
accentHue: [[[200, 262], 3], [[140, 180], 2], [[15, 45], 1]],
|
|
720
|
-
accentChroma: [0.11, 0.16],
|
|
721
|
-
shift: 3,
|
|
722
|
-
light: 0.2,
|
|
723
|
-
corners: [["round", 4], ["flat", 3], ["bevel", 1]],
|
|
724
|
-
border: [1],
|
|
725
|
-
bevel: [0, 1],
|
|
726
|
-
inner: 0.1,
|
|
727
|
-
fills: [["solid", 5], ["gradient", 2]],
|
|
728
|
-
screens: ["bayer4", "ign", "bayer8"],
|
|
729
|
-
shadow: [0, 1],
|
|
730
|
-
font: { ...F, width: [0.55, 0.7], round: [1], stroke: [0.08, 0.13], serif: [["none", 1]], slant: 0 },
|
|
731
|
-
caps: 0.15,
|
|
732
|
-
body: [7, 7, 8],
|
|
733
|
-
ratio: [1.25, 1.45],
|
|
734
|
-
unit: [3, 4],
|
|
735
|
-
motion: [["snappy", 5], ["bouncy", 1]],
|
|
736
|
-
icon: [["outline", 3], ["solid", 2]],
|
|
737
|
-
iconStroke: [1]
|
|
738
|
-
}
|
|
739
|
-
};
|
|
740
|
-
var wrapHue = (h) => (h % 360 + 360) % 360;
|
|
741
|
-
var r3 = (v) => Math.round(v * 1e3) / 1e3;
|
|
742
|
-
var pickRange = (S, ranges) => {
|
|
743
|
-
const [a, b] = S.weighted(ranges);
|
|
744
|
-
return S.between(a, b);
|
|
745
|
-
};
|
|
746
|
-
function ramp2(n, hue2, chroma, lo, hi, shift) {
|
|
747
|
-
const out = [];
|
|
748
|
-
for (let i = 0; i < n; i += 1) {
|
|
749
|
-
const t = n === 1 ? 0.5 : i / (n - 1);
|
|
750
|
-
const L = lo + (hi - lo) * t;
|
|
751
|
-
const C = chroma * (1 - 0.45 * Math.abs(t - 0.5) * 2 * (t > 0.5 ? 1 : 0.5));
|
|
752
|
-
out.push(fromOklch(L, C, wrapHue(hue2 + shift * (t - 0.5) * 2)));
|
|
753
|
-
}
|
|
754
|
-
return out;
|
|
755
|
-
}
|
|
756
|
-
function readable(L, chroma, hue2, on, min, dir) {
|
|
757
|
-
let c = fromOklch(L, chroma, hue2);
|
|
758
|
-
for (let step = 0; step < 60 && on.some((s) => contrast(c, s) < min); step += 1) {
|
|
759
|
-
L = Math.max(0, Math.min(1, L + dir * 0.012));
|
|
760
|
-
c = fromOklch(L, chroma * (step > 30 ? 0.5 : 1), hue2);
|
|
761
|
-
}
|
|
762
|
-
return c;
|
|
763
|
-
}
|
|
764
|
-
function recipeKey(r) {
|
|
765
|
-
const text = JSON.stringify([r.generator, r.seed, r.culture, sortPins(r.pins)]);
|
|
766
|
-
let h = 2166136261;
|
|
767
|
-
for (let i = 0; i < text.length; i += 1) h = Math.imul(h ^ text.charCodeAt(i), 16777619) >>> 0;
|
|
768
|
-
return `theme:${h.toString(16).padStart(8, "0")}`;
|
|
769
|
-
}
|
|
770
|
-
function sortPins(p) {
|
|
771
|
-
const o = {};
|
|
772
|
-
for (const k of Object.keys(p).sort()) {
|
|
773
|
-
const v = p[k];
|
|
774
|
-
if (v === void 0) continue;
|
|
775
|
-
o[k] = v && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => a < b ? -1 : 1)) : v;
|
|
776
|
-
}
|
|
777
|
-
return o;
|
|
778
|
-
}
|
|
779
|
-
function themeOf(recipe) {
|
|
780
|
-
if (recipe.generator !== THEME_GENERATOR) throw new RangeError(`This is ${THEME_GENERATOR}; the recipe names ${recipe.generator}.`);
|
|
781
|
-
const spec = CULTURE_SPECS[recipe.culture];
|
|
782
|
-
if (!spec) throw new RangeError(`"${recipe.culture}" isn't a culture (${CULTURES.join(", ")}).`);
|
|
783
|
-
const P = recipe.pins;
|
|
784
|
-
const S = (name) => stream(createRoll(deriveSeed(`${recipe.seed}/${recipe.culture}`, `ui/theme/${name}`)), 0);
|
|
785
|
-
const sp = S("palette");
|
|
786
|
-
const drawnTone = sp.chance(spec.light) ? "light" : "dark";
|
|
787
|
-
const drawnHue = pickRange(sp, spec.surfaceHue);
|
|
788
|
-
const drawnChroma = sp.between(spec.surfaceChroma[0], spec.surfaceChroma[1]);
|
|
789
|
-
const drawnL = sp.between(spec.surfaceL[0], spec.surfaceL[1]);
|
|
790
|
-
const drawnAccent = pickRange(sp, spec.accentHue);
|
|
791
|
-
const accentChroma = sp.between(spec.accentChroma[0], spec.accentChroma[1]);
|
|
792
|
-
const semanticNudge = sp.between(-8, 8);
|
|
793
|
-
const teamStart = sp.between(0, 360);
|
|
794
|
-
const tone = P.tone ?? drawnTone;
|
|
795
|
-
const hue2 = wrapHue(P.hue ?? drawnHue);
|
|
796
|
-
const chroma = P.chroma ?? drawnChroma;
|
|
797
|
-
const accentHue = wrapHue(P.accentHue ?? drawnAccent);
|
|
798
|
-
const shift = spec.shift;
|
|
799
|
-
const dark = tone === "dark";
|
|
800
|
-
const base = dark ? drawnL : 0.9 - (drawnL - 0.25) * 0.4;
|
|
801
|
-
const surface = dark ? ramp2(6, hue2, chroma, Math.max(0.06, base - 0.15), Math.min(0.72, base + 0.27), shift).map((c, i) => i === 2 ? fromOklch(base, chroma, hue2) : c) : ramp2(6, hue2, chroma * 0.8, 0.58, 0.99, shift).map((c, i) => i === 2 ? fromOklch(base, chroma * 0.6, hue2) : c);
|
|
802
|
-
const panels = [surface[1], surface[2], surface[3]];
|
|
803
|
-
const ink = dark ? [readable(0.74, 0.025, hue2, panels, 4.6, 1), readable(0.9, 0.02, hue2, panels, 5.5, 1), readable(0.97, 0.015, hue2, panels, 7, 1)] : [readable(0.46, 0.03, hue2, panels, 4.6, -1), readable(0.28, 0.03, hue2, panels, 6, -1), readable(0.16, 0.03, hue2, panels, 8, -1)];
|
|
804
|
-
const accent = ramp2(5, accentHue, accentChroma, 0.36, 0.9, shift * 0.6);
|
|
805
|
-
const semantic = (h, c) => ramp2(5, h + semanticNudge, c, 0.36, 0.9, shift * 0.4);
|
|
806
|
-
const teams = Math.max(1, Math.min(24, P.teams ?? 8));
|
|
807
|
-
const team = [];
|
|
808
|
-
for (let i = 0; i < teams; i += 1) {
|
|
809
|
-
const th = P.teamHues?.[i] ?? wrapHue(teamStart + i * 137.508);
|
|
810
|
-
const lift = teams > 12 && i % 2 ? 0.08 : 0;
|
|
811
|
-
team.push(ramp2(5, th, 0.16, 0.38 + lift, 0.9, 6));
|
|
812
|
-
}
|
|
813
|
-
const labels = [ink[2], surface[0], fromOklch(0.99, 0.01, accentHue), fromOklch(0.14, 0.02, accentHue)];
|
|
814
|
-
const accentText = labels.reduce((b, c) => contrast(c, accent[1]) > contrast(b, accent[1]) ? c : b);
|
|
815
|
-
const fr = S("frame");
|
|
816
|
-
const drawn = {
|
|
817
|
-
corner: fr.weighted(spec.corners),
|
|
818
|
-
border: fr.pick(spec.border),
|
|
819
|
-
bevel: fr.pick(spec.bevel),
|
|
820
|
-
inner: fr.chance(spec.inner),
|
|
821
|
-
fill: fr.weighted(spec.fills),
|
|
822
|
-
screen: fr.pick(spec.screens),
|
|
823
|
-
shadow: fr.pick(spec.shadow),
|
|
824
|
-
radius: fr.int(2, 4),
|
|
825
|
-
rivets: fr.pick([0, 12, 16, 24])
|
|
826
|
-
};
|
|
827
|
-
const corner = P.corner ?? drawn.corner;
|
|
828
|
-
const frame = {
|
|
829
|
-
corner,
|
|
830
|
-
radius: P.radius ?? (corner === "notched" ? Math.min(drawn.radius, 3) : drawn.radius),
|
|
831
|
-
border: Math.max(1, Math.min(3, P.border ?? drawn.border)),
|
|
832
|
-
bevel: P.bevel ?? (corner === "bevel" || corner === "rivets" ? Math.max(1, drawn.bevel) : drawn.bevel),
|
|
833
|
-
inner: drawn.inner,
|
|
834
|
-
shadow: P.shadow ?? drawn.shadow,
|
|
835
|
-
glow: P.glow ?? (corner === "glow" ? 2 : 0),
|
|
836
|
-
fill: P.fill ?? drawn.fill,
|
|
837
|
-
screen: P.screen && SCREEN_IDS.includes(P.screen) ? P.screen : drawn.screen,
|
|
838
|
-
rivets: corner === "rivets" ? drawn.rivets || 16 : 0
|
|
839
|
-
};
|
|
840
|
-
const outline = corner === "glow" ? accent[0] : dark ? surface[0] : fromOklch(0.3, chroma, hue2);
|
|
841
|
-
const ty = S("type");
|
|
842
|
-
const font = fontParamsOf(ty, spec.font, P.font);
|
|
843
|
-
const drawnBody = ty.pick(spec.body);
|
|
844
|
-
const ratio = ty.between(spec.ratio[0], spec.ratio[1]);
|
|
845
|
-
const drawnCaps = ty.chance(spec.caps);
|
|
846
|
-
const body = Math.max(5, Math.min(12, P.body ?? drawnBody));
|
|
847
|
-
const title = Math.min(16, Math.max(body + 2, Math.round(body * ratio)));
|
|
848
|
-
const type = { small: Math.max(5, body - 2), body, title, display: Math.min(16, Math.max(title + 2, Math.round(title * ratio))), font, caps: P.caps ?? drawnCaps };
|
|
849
|
-
const mo = S("motion");
|
|
850
|
-
const drawnUnit = mo.pick(spec.unit);
|
|
851
|
-
const drawnMotion = mo.weighted(spec.motion);
|
|
852
|
-
const drawnIcon = mo.weighted(spec.icon);
|
|
853
|
-
const iconStroke = mo.pick(spec.iconStroke);
|
|
854
|
-
const overshoot = r3(mo.between(0.15, 0.35));
|
|
855
|
-
const unit2 = P.unit ?? drawnUnit;
|
|
856
|
-
const kind = P.motion ?? drawnMotion;
|
|
857
|
-
return {
|
|
858
|
-
recipe,
|
|
859
|
-
culture: recipe.culture,
|
|
860
|
-
palette: {
|
|
861
|
-
tone,
|
|
862
|
-
surface,
|
|
863
|
-
ink,
|
|
864
|
-
accent,
|
|
865
|
-
good: semantic(145, 0.15),
|
|
866
|
-
warn: semantic(82, 0.15),
|
|
867
|
-
bad: semantic(27, 0.18),
|
|
868
|
-
team,
|
|
869
|
-
outline,
|
|
870
|
-
onAccent: accentText,
|
|
871
|
-
hues: { surface: r3(hue2), accent: r3(accentHue) }
|
|
872
|
-
},
|
|
873
|
-
frame,
|
|
874
|
-
type,
|
|
875
|
-
space: { unit: unit2, pad: unit2 + frame.border + (frame.bevel ? 1 : 0), gap: unit2 },
|
|
876
|
-
icon: { style: P.icon ?? drawnIcon, stroke: iconStroke },
|
|
877
|
-
motion: { kind, press: kind === "none" ? 0 : 1, ms: kind === "snappy" ? 90 : kind === "bouncy" ? 180 : 0, overshoot: kind === "bouncy" ? overshoot : 0 },
|
|
878
|
-
key: recipeKey(recipe)
|
|
879
|
-
};
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
// ../../../../../../keel-engine/packages/ui/src/frames.ts
|
|
883
|
-
var FRAME_KINDS = ["panel", "button", "inset", "tooltip", "badge", "tab", "header"];
|
|
884
|
-
|
|
885
|
-
// ../../../../../../keel-engine/packages/ui/src/icons.ts
|
|
886
|
-
var poly = (...pts) => pts.flatMap(([x, y]) => [x, y]);
|
|
887
|
-
var rect = (x0, y0, x1, y1) => poly([x0, y0], [x1, y0], [x1, y1], [x0, y1]);
|
|
888
|
-
var disc = (cx, cy, r, ry = r) => ellipse(cx, cy, r, ry, 40);
|
|
889
|
-
function seg(x0, y0, x1, y1, w) {
|
|
890
|
-
const dx = x1 - x0, dy = y1 - y0, l = Math.hypot(dx, dy) || 1;
|
|
891
|
-
const nx = -dy / l * (w / 2), ny = dx / l * (w / 2);
|
|
892
|
-
return poly([x0 + nx, y0 + ny], [x1 + nx, y1 + ny], [x1 - nx, y1 - ny], [x0 - nx, y0 - ny]);
|
|
893
|
-
}
|
|
894
|
-
var strokes = (pts, w, closed = false) => {
|
|
895
|
-
const out = [];
|
|
896
|
-
const n = pts.length;
|
|
897
|
-
for (let i = 0; i < (closed ? n : n - 1); i += 1) {
|
|
898
|
-
const a = pts[i], b = pts[(i + 1) % n];
|
|
899
|
-
out.push(seg(a[0], a[1], b[0], b[1], w));
|
|
900
|
-
}
|
|
901
|
-
for (const p of pts) out.push(disc(p[0], p[1], w / 2));
|
|
902
|
-
return out;
|
|
903
|
-
};
|
|
904
|
-
function star(cx, cy, r0, r1, n, rot = -Math.PI / 2) {
|
|
905
|
-
const pts = [];
|
|
906
|
-
for (let i = 0; i < n * 2; i += 1) {
|
|
907
|
-
const a = rot + i * Math.PI / n;
|
|
908
|
-
const r = i % 2 ? r1 : r0;
|
|
909
|
-
pts.push([cx + Math.cos(a) * r, cy + Math.sin(a) * r]);
|
|
910
|
-
}
|
|
911
|
-
return poly(...pts);
|
|
912
|
-
}
|
|
913
|
-
function gear(cx, cy, r, teeth, depth) {
|
|
914
|
-
const pts = [];
|
|
915
|
-
const steps = teeth * 4;
|
|
916
|
-
for (let i = 0; i < steps; i += 1) {
|
|
917
|
-
const a = i / steps * Math.PI * 2;
|
|
918
|
-
const rr = i % 4 < 2 ? r : r - depth;
|
|
919
|
-
pts.push([cx + Math.cos(a) * rr, cy + Math.sin(a) * rr]);
|
|
920
|
-
}
|
|
921
|
-
return poly(...pts);
|
|
922
|
-
}
|
|
923
|
-
var arrowHead = (tipX, tipY, dirX, dirY, size3) => {
|
|
924
|
-
const l = Math.hypot(dirX, dirY) || 1, ux = dirX / l, uy = dirY / l;
|
|
925
|
-
return poly([tipX, tipY], [tipX - ux * size3 - uy * size3 * 0.8, tipY - uy * size3 + ux * size3 * 0.8], [tipX - ux * size3 + uy * size3 * 0.8, tipY - uy * size3 - ux * size3 * 0.8]);
|
|
926
|
-
};
|
|
927
|
-
var add2 = (...shape) => ({ shape });
|
|
928
|
-
var cut = (...shape) => ({ cut: true, shape });
|
|
929
|
-
var mirror = (ops) => ops.map((o) => ({ ...o, shape: o.shape.map((c) => c.map((v, i) => i % 2 ? v : 1 - v)) }));
|
|
930
|
-
function sword(S, w, flip) {
|
|
931
|
-
const len2 = S.between(0.62, 0.78);
|
|
932
|
-
const bw = w * S.between(1.2, 1.6);
|
|
933
|
-
const tip = [0.86, 0.14];
|
|
934
|
-
const hilt = [tip[0] - len2 * 0.7071, tip[1] + len2 * 0.7071];
|
|
935
|
-
const guard = S.between(0.14, 0.22);
|
|
936
|
-
const ops = [
|
|
937
|
-
add2(seg(hilt[0], hilt[1], tip[0] - 0.03, tip[1] + 0.03, bw), poly([tip[0], tip[1]], [tip[0] - 0.12, tip[1] + 0.03], [tip[0] - 0.03, tip[1] + 0.12])),
|
|
938
|
-
add2(seg(hilt[0] - guard * 0.7071, hilt[1] - guard * 0.7071, hilt[0] + guard * 0.7071, hilt[1] + guard * 0.7071, w * 1.3)),
|
|
939
|
-
add2(seg(hilt[0], hilt[1], hilt[0] - 0.16, hilt[1] + 0.16, w * 1.1), disc(hilt[0] - 0.18, hilt[1] + 0.18, w * 0.9))
|
|
940
|
-
];
|
|
941
|
-
return flip ? mirror(ops) : ops;
|
|
942
|
-
}
|
|
943
|
-
var ICON_RECIPES = {
|
|
944
|
-
attack: { tone: "bad", variants: [
|
|
945
|
-
(S, w) => sword(S, w, S.chance(0.5)),
|
|
946
|
-
(S, w) => [...sword(S, w, false), ...sword(S, w, true)],
|
|
947
|
-
(S, w) => {
|
|
948
|
-
const r = S.between(0.28, 0.34);
|
|
949
|
-
return [add2(...strokes([[0.5, 0.08], [0.5, 0.3]], w), ...strokes([[0.5, 0.7], [0.5, 0.92]], w), ...strokes([[0.08, 0.5], [0.3, 0.5]], w), ...strokes([[0.7, 0.5], [0.92, 0.5]], w), disc(0.5, 0.5, r)), cut(disc(0.5, 0.5, r - w)), add2(disc(0.5, 0.5, w * 0.7))];
|
|
950
|
-
}
|
|
951
|
-
] },
|
|
952
|
-
move: { tone: "good", variants: [
|
|
953
|
-
(S, w) => {
|
|
954
|
-
const t = S.between(0.2, 0.3);
|
|
955
|
-
return [add2(seg(0.18, 0.82, 0.72, 0.28, w * 1.4), arrowHead(0.86, 0.14, 1, -1, t + 0.1))];
|
|
956
|
-
},
|
|
957
|
-
(S, w) => [add2(...strokes([[0.18, 0.2], [0.46, 0.5], [0.18, 0.8]], w * 1.4)), add2(...strokes([[0.5, 0.2], [0.78, 0.5], [0.5, 0.8]], w * 1.4))],
|
|
958
|
-
(S, w) => {
|
|
959
|
-
const h = S.between(0.14, 0.2);
|
|
960
|
-
return [add2(seg(0.5, 0.18, 0.5, 0.82, w * 1.2), seg(0.18, 0.5, 0.82, 0.5, w * 1.2), arrowHead(0.5, 0.06, 0, -1, h), arrowHead(0.5, 0.94, 0, 1, h), arrowHead(0.06, 0.5, -1, 0, h), arrowHead(0.94, 0.5, 1, 0, h))];
|
|
961
|
-
}
|
|
962
|
-
] },
|
|
963
|
-
stop: { tone: "bad", variants: [
|
|
964
|
-
(S) => {
|
|
965
|
-
const r = S.between(0.4, 0.44);
|
|
966
|
-
return [add2(star(0.5, 0.5, r, r, 4, Math.PI / 8))];
|
|
967
|
-
},
|
|
968
|
-
(S) => {
|
|
969
|
-
const m = S.between(0.14, 0.2);
|
|
970
|
-
return [add2(rect(m, m, 1 - m, 1 - m))];
|
|
971
|
-
}
|
|
972
|
-
] },
|
|
973
|
-
hold: { tone: "accent", variants: [
|
|
974
|
-
(S) => {
|
|
975
|
-
const n = S.between(0.62, 0.72);
|
|
976
|
-
return [add2(poly([0.14, 0.14], [0.86, 0.14], [0.86, n - 0.1], [0.5, 0.92], [0.14, n - 0.1]))];
|
|
977
|
-
},
|
|
978
|
-
(S, w) => [add2(rect(0.2, 0.44, 0.8, 0.88), ...strokes([[0.32, 0.46], [0.32, 0.28], [0.5, 0.12], [0.68, 0.28], [0.68, 0.46]], w * 1.2))]
|
|
979
|
-
] },
|
|
980
|
-
patrol: { tone: "accent", variants: [
|
|
981
|
-
(S, w) => [add2(seg(0.14, 0.34, 0.74, 0.34, w * 1.3), arrowHead(0.9, 0.34, 1, 0, 0.2), seg(0.26, 0.68, 0.86, 0.68, w * 1.3), arrowHead(0.1, 0.68, -1, 0, 0.2))],
|
|
982
|
-
(S, w) => [add2(disc(0.5, 0.5, 0.38)), cut(disc(0.5, 0.5, 0.38 - w * 1.4), rect(0.5, 0, 1, 0.5)), add2(arrowHead(0.5 + 0.38 - w * 0.7, 0.62, 0, -1, 0.22))]
|
|
983
|
-
] },
|
|
984
|
-
build: { tone: "warn", variants: [
|
|
985
|
-
(S, w) => {
|
|
986
|
-
const h = S.between(0.18, 0.24);
|
|
987
|
-
return [add2(seg(0.24, 0.86, 0.62, 0.36, w * 1.4)), add2(poly([0.38, 0.28], [0.62, 0.06], [0.94, 0.38], [0.72, 0.6]), seg(0.46, 0.2, 0.46 - h, 0.2 - h * 0.2, w))];
|
|
988
|
-
},
|
|
989
|
-
(S, w) => [add2(seg(0.2, 0.82, 0.6, 0.42, w * 1.6), disc(0.68, 0.32, 0.22)), cut(poly([0.68, 0.32], [0.95, 0.1], [0.95, 0.4]), disc(0.2, 0.82, w * 0.4))],
|
|
990
|
-
() => [add2(rect(0.08, 0.2, 0.46, 0.44), rect(0.54, 0.2, 0.92, 0.44), rect(0.08, 0.52, 0.28, 0.76), rect(0.36, 0.52, 0.64, 0.76), rect(0.72, 0.52, 0.92, 0.76))]
|
|
991
|
-
] },
|
|
992
|
-
upgrade: { tone: "good", variants: [
|
|
993
|
-
(S, w) => [add2(rect(0.36, 0.44, 0.64, 0.9), poly([0.5, 0.08], [0.9, 0.5], [0.1, 0.5]))],
|
|
994
|
-
(S, w) => [add2(...strokes([[0.16, 0.5], [0.5, 0.2], [0.84, 0.5]], w * 1.6)), add2(...strokes([[0.16, 0.82], [0.5, 0.52], [0.84, 0.82]], w * 1.6))],
|
|
995
|
-
(S, w) => [add2(star(0.44, 0.52, 0.4, 0.18, 5)), add2(seg(0.8, 0.08, 0.8, 0.34, w), seg(0.67, 0.21, 0.93, 0.21, w))]
|
|
996
|
-
] },
|
|
997
|
-
supply: { tone: "warn", variants: [
|
|
998
|
-
(S) => {
|
|
999
|
-
const r = S.between(0.4, 0.5);
|
|
1000
|
-
return [add2(poly([0.5, 0.08], [0.92, r], [0.8, r], [0.8, 0.9], [0.2, 0.9], [0.2, r], [0.08, r])), cut(rect(0.42, 0.62, 0.58, 0.9))];
|
|
1001
|
-
},
|
|
1002
|
-
() => [add2(disc(0.5, 0.28, 0.18), poly([0.16, 0.92], [0.2, 0.6], [0.36, 0.5], [0.64, 0.5], [0.8, 0.6], [0.84, 0.92]))],
|
|
1003
|
-
(S, w) => [add2(rect(0.12, 0.18, 0.88, 0.86)), cut(rect(0.12 + w, 0.18 + w, 0.88 - w, 0.86 - w)), add2(seg(0.12, 0.18, 0.88, 0.86, w), seg(0.88, 0.18, 0.12, 0.86, w))]
|
|
1004
|
-
] },
|
|
1005
|
-
resource: { tone: "accent", variants: [
|
|
1006
|
-
(S) => {
|
|
1007
|
-
const t = S.between(0.3, 0.4);
|
|
1008
|
-
return [add2(poly([0.5, 0.06], [0.88, t], [0.5, 0.94], [0.12, t]))];
|
|
1009
|
-
},
|
|
1010
|
-
() => [add2(poly([0.3, 0.9], [0.22, 0.4], [0.36, 0.12], [0.5, 0.4], [0.46, 0.9]), poly([0.5, 0.9], [0.56, 0.3], [0.7, 0.06], [0.82, 0.32], [0.76, 0.9]))]
|
|
1011
|
-
] },
|
|
1012
|
-
mass: { tone: "accent", variants: [
|
|
1013
|
-
() => [add2(poly([0.5, 0.08], [0.9, 0.28], [0.9, 0.72], [0.5, 0.92], [0.1, 0.72], [0.1, 0.28]))],
|
|
1014
|
-
() => [add2(poly([0.2, 0.36], [0.8, 0.36], [0.94, 0.76], [0.06, 0.76]))]
|
|
1015
|
-
] },
|
|
1016
|
-
energy: { tone: "warn", variants: [
|
|
1017
|
-
(S) => {
|
|
1018
|
-
const k = S.between(0.44, 0.54);
|
|
1019
|
-
return [add2(poly([0.62, 0.04], [0.2, k + 0.06], [0.48, k + 0.06], [0.36, 0.96], [0.82, k - 0.08], [0.54, k - 0.08]))];
|
|
1020
|
-
},
|
|
1021
|
-
(S, w) => [add2(disc(0.5, 0.5, 0.22), disc(0.5, 0.5, 0.44, 0.2)), cut(disc(0.5, 0.5, 0.44 - w, 0.2 - w)), add2(disc(0.5, 0.5, 0.22))]
|
|
1022
|
-
] },
|
|
1023
|
-
biomass: { tone: "good", variants: [
|
|
1024
|
-
(S, w) => [add2(poly([0.14, 0.86], [0.2, 0.4], [0.5, 0.14], [0.9, 0.1], [0.84, 0.5], [0.6, 0.8])), cut(seg(0.2, 0.8, 0.7, 0.3, w * 0.8))],
|
|
1025
|
-
() => [add2(poly([0.5, 0.06], [0.78, 0.5], [0.7, 0.8], [0.5, 0.92], [0.3, 0.8], [0.22, 0.5]), disc(0.5, 0.64, 0.28))]
|
|
1026
|
-
] },
|
|
1027
|
-
salvage: { tone: "ink", variants: [
|
|
1028
|
-
(S, w) => {
|
|
1029
|
-
const t = S.pick([6, 7, 8]);
|
|
1030
|
-
return [add2(gear(0.5, 0.5, 0.46, t, 0.12)), cut(disc(0.5, 0.5, 0.14))];
|
|
1031
|
-
},
|
|
1032
|
-
() => [add2(star(0.5, 0.5, 0.44, 0.44, 3, Math.PI / 2)), cut(disc(0.5, 0.5, 0.14))]
|
|
1033
|
-
] },
|
|
1034
|
-
gather: { tone: "warn", variants: [
|
|
1035
|
-
(S, w) => [add2(seg(0.22, 0.88, 0.62, 0.36, w * 1.3)), add2(...strokes([[0.18, 0.3], [0.48, 0.14], [0.66, 0.2], [0.84, 0.44]], w * 1.5))]
|
|
1036
|
-
] },
|
|
1037
|
-
repair: { tone: "good", variants: [
|
|
1038
|
-
(S, w) => [add2(seg(0.2, 0.82, 0.6, 0.42, w * 1.6), disc(0.68, 0.32, 0.22)), cut(poly([0.68, 0.32], [0.95, 0.1], [0.95, 0.4]))],
|
|
1039
|
-
(S) => {
|
|
1040
|
-
const t = S.between(0.14, 0.18);
|
|
1041
|
-
return [add2(rect(0.5 - t, 0.12, 0.5 + t, 0.88), rect(0.12, 0.5 - t, 0.88, 0.5 + t))];
|
|
1042
|
-
}
|
|
1043
|
-
] },
|
|
1044
|
-
cancel: { tone: "bad", variants: [(S, w) => [add2(seg(0.16, 0.16, 0.84, 0.84, w * 1.8), seg(0.84, 0.16, 0.16, 0.84, w * 1.8))]] },
|
|
1045
|
-
rally: { tone: "accent", variants: [
|
|
1046
|
-
(S, w) => [add2(seg(0.24, 0.08, 0.24, 0.94, w * 1.2), poly([0.24, 0.1], [0.86, 0.26], [0.24, 0.5]))],
|
|
1047
|
-
(S, w) => [add2(seg(0.24, 0.08, 0.24, 0.94, w * 1.2), poly([0.24, 0.1], [0.84, 0.1], [0.7, 0.28], [0.84, 0.46], [0.24, 0.46]))]
|
|
1048
|
-
] },
|
|
1049
|
-
research: { tone: "accent", variants: [
|
|
1050
|
-
() => [add2(poly([0.38, 0.08], [0.62, 0.08], [0.62, 0.36], [0.9, 0.9], [0.1, 0.9], [0.38, 0.36]))],
|
|
1051
|
-
(S, w) => [add2(rect(0.14, 0.14, 0.86, 0.86)), cut(seg(0.5, 0.2, 0.5, 0.86, w)), cut(rect(0.14 + w, 0.26, 0.44, 0.3), rect(0.56, 0.26, 0.86 - w, 0.3))]
|
|
1052
|
-
] },
|
|
1053
|
-
train: { tone: "ink", variants: [
|
|
1054
|
-
() => [add2(disc(0.5, 0.26, 0.18), poly([0.18, 0.92], [0.24, 0.56], [0.5, 0.46], [0.76, 0.56], [0.82, 0.92]))],
|
|
1055
|
-
(S, w) => [add2(disc(0.5, 0.56, 0.36), rect(0.1, 0.56, 0.9, 0.7)), cut(rect(0, 0.7, 1, 1), rect(0.34, 0.5, 0.66, 0.6))]
|
|
1056
|
-
] },
|
|
1057
|
-
ability: { tone: "accent", variants: [
|
|
1058
|
-
(S) => {
|
|
1059
|
-
const n = S.pick([4, 5, 6]);
|
|
1060
|
-
return [add2(star(0.5, 0.5, 0.46, S.between(0.16, 0.24), n))];
|
|
1061
|
-
},
|
|
1062
|
-
(S, w) => [add2(poly([0.5, 0.06], [0.9, 0.5], [0.5, 0.94], [0.1, 0.5])), cut(poly([0.5, 0.06 + w * 2], [0.9 - w * 2, 0.5], [0.5, 0.94 - w * 2], [0.1 + w * 2, 0.5])), add2(seg(0.5, 0.26, 0.5, 0.74, w))]
|
|
1063
|
-
] },
|
|
1064
|
-
vision: { tone: "ink", variants: [
|
|
1065
|
-
(S, w) => [add2(disc(0.5, 0.5, 0.46, 0.26)), cut(disc(0.5, 0.5, 0.46 - w, 0.26 - w)), add2(disc(0.5, 0.5, 0.14))]
|
|
1066
|
-
] },
|
|
1067
|
-
cloak: { tone: "dim", variants: [
|
|
1068
|
-
(S, w) => [add2(disc(0.5, 0.5, 0.46, 0.26)), cut(disc(0.5, 0.5, 0.46 - w, 0.26 - w)), add2(disc(0.5, 0.5, 0.14), seg(0.14, 0.86, 0.86, 0.14, w))]
|
|
1069
|
-
] },
|
|
1070
|
-
scan: { tone: "good", variants: [
|
|
1071
|
-
(S, w) => [add2(disc(0.5, 0.5, 0.44)), cut(disc(0.5, 0.5, 0.44 - w)), add2(disc(0.5, 0.5, 0.22)), cut(disc(0.5, 0.5, 0.22 - w)), add2(seg(0.5, 0.5, 0.82, 0.2, w), disc(0.5, 0.5, w))]
|
|
1072
|
-
] },
|
|
1073
|
-
armor: { tone: "ink", variants: [
|
|
1074
|
-
() => [add2(poly([0.14, 0.14], [0.86, 0.14], [0.86, 0.52], [0.5, 0.92], [0.14, 0.52]))],
|
|
1075
|
-
(S, w) => [add2(poly([0.14, 0.14], [0.86, 0.14], [0.86, 0.52], [0.5, 0.92], [0.14, 0.52])), cut(seg(0.5, 0.14, 0.5, 0.92, w * 0.8))]
|
|
1076
|
-
] },
|
|
1077
|
-
damage: { tone: "bad", variants: [
|
|
1078
|
-
(S) => {
|
|
1079
|
-
const n = S.pick([7, 8, 9]);
|
|
1080
|
-
return [add2(star(0.5, 0.5, 0.48, S.between(0.2, 0.28), n, S.between(0, 1)))];
|
|
1081
|
-
}
|
|
1082
|
-
] },
|
|
1083
|
-
speed: { tone: "good", variants: [
|
|
1084
|
-
(S, w) => [add2(poly([0.08, 0.16], [0.46, 0.5], [0.08, 0.84], [0.22, 0.5])), add2(poly([0.46, 0.16], [0.9, 0.5], [0.46, 0.84], [0.6, 0.5]))]
|
|
1085
|
-
] },
|
|
1086
|
-
range: { tone: "accent", variants: [
|
|
1087
|
-
(S, w) => [add2(disc(0.5, 0.5, 0.46)), cut(disc(0.5, 0.5, 0.46 - w)), add2(disc(0.5, 0.5, 0.3)), cut(disc(0.5, 0.5, 0.3 - w)), add2(disc(0.5, 0.5, 0.12))]
|
|
1088
|
-
] },
|
|
1089
|
-
health: { tone: "good", variants: [
|
|
1090
|
-
() => [add2(poly([0.5, 0.9], [0.08, 0.46], [0.08, 0.26], [0.26, 0.1], [0.5, 0.26], [0.74, 0.1], [0.92, 0.26], [0.92, 0.46]))],
|
|
1091
|
-
(S) => {
|
|
1092
|
-
const t = S.between(0.14, 0.18);
|
|
1093
|
-
return [add2(rect(0.5 - t, 0.12, 0.5 + t, 0.88), rect(0.12, 0.5 - t, 0.88, 0.5 + t))];
|
|
1094
|
-
}
|
|
1095
|
-
] },
|
|
1096
|
-
timer: { tone: "ink", variants: [
|
|
1097
|
-
(S, w) => [add2(disc(0.5, 0.54, 0.4)), cut(disc(0.5, 0.54, 0.4 - w)), add2(seg(0.5, 0.54, 0.5, 0.3, w), seg(0.5, 0.54, 0.68, 0.62, w), rect(0.4, 0.04, 0.6, 0.12))]
|
|
1098
|
-
] },
|
|
1099
|
-
// (Three bars, never so heavy they run together: each at most a sixth of the square.)
|
|
1100
|
-
menu: { tone: "ink", variants: [(S, w0) => {
|
|
1101
|
-
const w = Math.min(w0, 0.12);
|
|
1102
|
-
return [add2(rect(0.14, 0.16, 0.86, 0.16 + w * 1.4), rect(0.14, 0.5 - w * 0.7, 0.86, 0.5 + w * 0.7), rect(0.14, 0.84 - w * 1.4, 0.86, 0.84))];
|
|
1103
|
-
}] },
|
|
1104
|
-
settings: { tone: "ink", variants: [(S, w) => [add2(gear(0.5, 0.5, 0.46, 8, 0.12)), cut(disc(0.5, 0.5, 0.16))]] },
|
|
1105
|
-
alert: { tone: "warn", variants: [(S, w) => [add2(poly([0.5, 0.06], [0.95, 0.9], [0.05, 0.9])), cut(seg(0.5, 0.34, 0.5, 0.62, w * 1.2), disc(0.5, 0.76, w * 0.7))]] },
|
|
1106
|
-
worker: { tone: "warn", variants: [
|
|
1107
|
-
(S) => [add2(disc(0.5, 0.6, 0.38)), cut(rect(0, 0.62, 1, 1)), add2(rect(0.06, 0.58, 0.94, 0.7), rect(0.42, 0.14, 0.58, 0.26))],
|
|
1108
|
-
(S, w) => [add2(seg(0.22, 0.88, 0.62, 0.36, w * 1.3)), add2(...strokes([[0.18, 0.3], [0.48, 0.14], [0.66, 0.2], [0.84, 0.44]], w * 1.5))]
|
|
1109
|
-
] },
|
|
1110
|
-
unload: { tone: "ink", variants: [(S, w) => [add2(rect(0.12, 0.62, 0.88, 0.9), seg(0.5, 0.08, 0.5, 0.44, w * 1.5), arrowHead(0.5, 0.58, 0, 1, 0.22))]] },
|
|
1111
|
-
load: { tone: "ink", variants: [(S, w) => [add2(rect(0.12, 0.62, 0.88, 0.9), seg(0.5, 0.22, 0.5, 0.58, w * 1.5), arrowHead(0.5, 0.06, 0, -1, 0.22))]] },
|
|
1112
|
-
"attack-move": { tone: "bad", variants: [
|
|
1113
|
-
(S, w) => [...sword(S, w * 0.9, false).map((o) => ({ ...o, shape: o.shape.map((c) => c.map((v, i) => i % 2 ? v * 0.72 : v * 0.72 + 0.28)) })), add2(seg(0.1, 0.9, 0.34, 0.66, w * 1.2), arrowHead(0.08, 0.92, -1, 1, 0.16))]
|
|
1114
|
-
] },
|
|
1115
|
-
crystal: { tone: "accent", variants: [
|
|
1116
|
-
() => [add2(poly([0.3, 0.9], [0.22, 0.4], [0.36, 0.12], [0.5, 0.4], [0.46, 0.9]), poly([0.5, 0.9], [0.56, 0.3], [0.7, 0.06], [0.82, 0.32], [0.76, 0.9]))]
|
|
1117
|
-
] },
|
|
1118
|
-
flux: { tone: "accent", variants: [
|
|
1119
|
-
(S, w) => [add2(disc(0.5, 0.5, 0.24), disc(0.5, 0.5, 0.46, 0.18)), cut(disc(0.5, 0.5, 0.46 - w, 0.18 - w)), add2(disc(0.5, 0.5, 0.24))]
|
|
1120
|
-
] },
|
|
1121
|
-
pause: { tone: "ink", variants: [(S) => [add2(rect(0.2, 0.14, 0.42, 0.86), rect(0.58, 0.14, 0.8, 0.86))]] },
|
|
1122
|
-
play: { tone: "ink", variants: [() => [add2(poly([0.2, 0.1], [0.86, 0.5], [0.2, 0.9]))]] },
|
|
1123
|
-
close: { tone: "ink", variants: [(S, w) => [add2(seg(0.2, 0.2, 0.8, 0.8, w * 1.5), seg(0.8, 0.2, 0.2, 0.8, w * 1.5))]] },
|
|
1124
|
-
check: { tone: "good", variants: [(S, w) => [add2(...strokes([[0.14, 0.52], [0.4, 0.78], [0.86, 0.22]], w * 1.6))]] },
|
|
1125
|
-
chat: { tone: "ink", variants: [() => [add2(rect(0.1, 0.14, 0.9, 0.66), poly([0.26, 0.6], [0.5, 0.6], [0.22, 0.9]))]] },
|
|
1126
|
-
ping: { tone: "warn", variants: [(S, w) => [add2(disc(0.5, 0.4, 0.3), poly([0.24, 0.5], [0.5, 0.94], [0.76, 0.5])), cut(disc(0.5, 0.4, 0.12))]] }
|
|
1127
|
-
};
|
|
1128
|
-
var ICON_NAMES = Object.keys(ICON_RECIPES);
|
|
1129
|
-
|
|
1130
|
-
// ../../../../../../keel-engine/packages/ui/src/node.ts
|
|
1131
|
-
var WIDGETS = [
|
|
1132
|
-
"root",
|
|
1133
|
-
"canvas",
|
|
1134
|
-
"row",
|
|
1135
|
-
"col",
|
|
1136
|
-
"grid",
|
|
1137
|
-
"panel",
|
|
1138
|
-
"button",
|
|
1139
|
-
"label",
|
|
1140
|
-
"icon",
|
|
1141
|
-
"bar",
|
|
1142
|
-
"list",
|
|
1143
|
-
"tooltip",
|
|
1144
|
-
"minimap",
|
|
1145
|
-
"portrait",
|
|
1146
|
-
"tabs",
|
|
1147
|
-
"toast",
|
|
1148
|
-
"modal",
|
|
1149
|
-
"slider",
|
|
1150
|
-
"toggle",
|
|
1151
|
-
"spinner",
|
|
1152
|
-
"spacer",
|
|
1153
|
-
"image",
|
|
1154
|
-
"driving"
|
|
1155
|
-
];
|
|
1156
|
-
var DRIVING_KINDS = ["wheel", "accelerator", "brake", "handbrake", "boost", "speedometer", "tachometer", "combined", "shift-up", "shift-down"];
|
|
1157
|
-
var DRIVING_VARIANTS = ["touring", "track"];
|
|
1158
|
-
var ANCHORS = ["tl", "t", "tr", "l", "c", "r", "bl", "b", "br"];
|
|
1159
|
-
|
|
1160
|
-
// ../../../../../../keel-engine/packages/ui/src/driving.ts
|
|
1161
|
-
var TAU2 = Math.PI * 2;
|
|
1162
|
-
|
|
1163
|
-
// ../../../../../../keel-engine/packages/ui/src/gauges.ts
|
|
1164
|
-
var GLYPH_BYTES = 128 * 1024;
|
|
1165
|
-
|
|
1166
|
-
// ../../../../../../keel-engine/packages/ui/src/prompts.ts
|
|
1167
|
-
var DEFAULT = { face: rgba(26, 32, 52), rim: rgba(150, 170, 210), ink: rgba(240, 244, 255), lit: rgba(255, 190, 70) };
|
|
1168
|
-
|
|
1169
|
-
// ../../../../../../keel-engine/packages/codec/src/bits.ts
|
|
1170
|
-
var F2 = new DataView(new ArrayBuffer(8));
|
|
1171
|
-
var P32 = 2 ** 32;
|
|
1172
|
-
var BitError = class extends RangeError {
|
|
1173
|
-
bit;
|
|
1174
|
-
constructor(message, bit) {
|
|
1175
|
-
super(message);
|
|
1176
|
-
this.name = "BitError";
|
|
1177
|
-
this.bit = bit;
|
|
1178
|
-
}
|
|
1179
|
-
};
|
|
1180
|
-
function bitsFor(n) {
|
|
1181
|
-
if (n <= 1) return 0;
|
|
1182
|
-
if (n <= 4294967296) return 32 - Math.clz32(n - 1);
|
|
1183
|
-
let b = 32;
|
|
1184
|
-
let v = Math.floor((n - 1) / 4294967296);
|
|
1185
|
-
while (v >= 1) {
|
|
1186
|
-
v = Math.floor(v / 2);
|
|
1187
|
-
b += 1;
|
|
1188
|
-
}
|
|
1189
|
-
return b;
|
|
1190
|
-
}
|
|
1191
|
-
var lengthOf = (x) => x < 4294967296 ? 32 - Math.clz32(x) : 32 + lengthOf(Math.floor(x / 4294967296));
|
|
1192
|
-
function toHalf(v) {
|
|
1193
|
-
F2.setFloat32(0, v);
|
|
1194
|
-
const x = F2.getUint32(0);
|
|
1195
|
-
const sign = x >>> 16 & 32768;
|
|
1196
|
-
const exp = x >>> 23 & 255;
|
|
1197
|
-
let mant = x & 8388607;
|
|
1198
|
-
if (exp === 255) return sign | 31744 | (mant ? 512 : 0);
|
|
1199
|
-
const e = exp - 127 + 15;
|
|
1200
|
-
if (e >= 31) return sign | 31744;
|
|
1201
|
-
if (e <= 0) {
|
|
1202
|
-
if (e < -10) return sign;
|
|
1203
|
-
mant |= 8388608;
|
|
1204
|
-
const shift = 14 - e;
|
|
1205
|
-
let h2 = mant >>> shift;
|
|
1206
|
-
const rem2 = mant & (1 << shift) - 1;
|
|
1207
|
-
const half = 1 << shift - 1;
|
|
1208
|
-
if (rem2 > half || rem2 === half && h2 & 1) h2 += 1;
|
|
1209
|
-
return sign | h2;
|
|
1210
|
-
}
|
|
1211
|
-
let h = e << 10 | mant >>> 13;
|
|
1212
|
-
const rem = mant & 8191;
|
|
1213
|
-
if (rem > 4096 || rem === 4096 && h & 1) h += 1;
|
|
1214
|
-
return sign | h;
|
|
1215
|
-
}
|
|
1216
|
-
function fromHalf(h) {
|
|
1217
|
-
const sign = h & 32768 ? -1 : 1;
|
|
1218
|
-
const exp = h >>> 10 & 31;
|
|
1219
|
-
const mant = h & 1023;
|
|
1220
|
-
if (exp === 0) return sign * mant * 2 ** -24;
|
|
1221
|
-
if (exp === 31) return mant ? NaN : sign * Infinity;
|
|
1222
|
-
return sign * (1 + mant / 1024) * 2 ** (exp - 15);
|
|
1223
|
-
}
|
|
1224
|
-
var BitWriter = class {
|
|
1225
|
-
buf;
|
|
1226
|
-
pos = 0;
|
|
1227
|
-
bit = 0;
|
|
1228
|
-
constructor(capacity = 256) {
|
|
1229
|
-
this.buf = new Uint8Array(Math.max(16, capacity));
|
|
1230
|
-
}
|
|
1231
|
-
/** Bits written so far. */
|
|
1232
|
-
get length() {
|
|
1233
|
-
return this.pos * 8 + this.bit;
|
|
1234
|
-
}
|
|
1235
|
-
room(bytes2) {
|
|
1236
|
-
if (this.pos + bytes2 < this.buf.length) return;
|
|
1237
|
-
let n = this.buf.length * 2;
|
|
1238
|
-
while (n <= this.pos + bytes2) n *= 2;
|
|
1239
|
-
const next = new Uint8Array(n);
|
|
1240
|
-
next.set(this.buf.subarray(0, this.pos + 1));
|
|
1241
|
-
this.buf = next;
|
|
1242
|
-
}
|
|
1243
|
-
/** Write the low `n` bits of `v` (0 <= n <= 32; v an unsigned integer below 2^n). */
|
|
1244
|
-
bits(v, n) {
|
|
1245
|
-
if (n === 0) return;
|
|
1246
|
-
this.room(5);
|
|
1247
|
-
const buf = this.buf;
|
|
1248
|
-
let pos = this.pos;
|
|
1249
|
-
let bit = this.bit;
|
|
1250
|
-
while (n > 0) {
|
|
1251
|
-
const free = 8 - bit;
|
|
1252
|
-
if (n >= free) {
|
|
1253
|
-
n -= free;
|
|
1254
|
-
buf[pos] = buf[pos] | v >>> n & (1 << free) - 1;
|
|
1255
|
-
pos += 1;
|
|
1256
|
-
bit = 0;
|
|
1257
|
-
} else {
|
|
1258
|
-
buf[pos] = buf[pos] | (v & (1 << n) - 1) << free - n;
|
|
1259
|
-
bit += n;
|
|
1260
|
-
n = 0;
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
this.pos = pos;
|
|
1264
|
-
this.bit = bit;
|
|
1265
|
-
}
|
|
1266
|
-
/** Up to 53 bits. */
|
|
1267
|
-
wide(v, n) {
|
|
1268
|
-
if (n <= 32) {
|
|
1269
|
-
this.bits(v >>> 0, n);
|
|
1270
|
-
return;
|
|
1271
|
-
}
|
|
1272
|
-
const hi = Math.floor(v / P32);
|
|
1273
|
-
this.bits(hi, n - 32);
|
|
1274
|
-
this.bits(v >>> 0, 32);
|
|
1275
|
-
}
|
|
1276
|
-
bool(b) {
|
|
1277
|
-
this.bits(b ? 1 : 0, 1);
|
|
1278
|
-
}
|
|
1279
|
-
/** A bigint's low `n` bits. */
|
|
1280
|
-
big(v, n) {
|
|
1281
|
-
let left = n;
|
|
1282
|
-
while (left > 32) {
|
|
1283
|
-
left -= 32;
|
|
1284
|
-
this.bits(Number(v >> BigInt(left) & 0xffffffffn), 32);
|
|
1285
|
-
}
|
|
1286
|
-
this.bits(Number(v & (1n << BigInt(left)) - 1n), left);
|
|
1287
|
-
}
|
|
1288
|
-
/** Exp-Golomb of order k (k = 0: Elias-gamma of v + 1): small numbers in few bits, any size up to 2^53. */
|
|
1289
|
-
golomb(v, k) {
|
|
1290
|
-
const x = v + (k < 31 ? 1 << k : 2 ** k);
|
|
1291
|
-
const len2 = lengthOf(x);
|
|
1292
|
-
const zeros = len2 - 1 - k;
|
|
1293
|
-
if (zeros > 0) {
|
|
1294
|
-
this.room((zeros >>> 3) + 6);
|
|
1295
|
-
const at = this.pos * 8 + this.bit + zeros;
|
|
1296
|
-
this.pos = at >>> 3;
|
|
1297
|
-
this.bit = at & 7;
|
|
1298
|
-
}
|
|
1299
|
-
if (len2 <= 32) this.bits(x >>> 0, len2);
|
|
1300
|
-
else this.wide(x, len2);
|
|
1301
|
-
}
|
|
1302
|
-
/** LEB-style groups: `g` bits of the number then a "more" bit, least significant group first. */
|
|
1303
|
-
groups(v, g) {
|
|
1304
|
-
const span = 2 ** g;
|
|
1305
|
-
do {
|
|
1306
|
-
const part = v % span;
|
|
1307
|
-
v = Math.floor(v / span);
|
|
1308
|
-
this.bits(part, g);
|
|
1309
|
-
this.bool(v > 0);
|
|
1310
|
-
} while (v > 0);
|
|
1311
|
-
}
|
|
1312
|
-
f16(v) {
|
|
1313
|
-
this.bits(toHalf(v), 16);
|
|
1314
|
-
}
|
|
1315
|
-
f32(v) {
|
|
1316
|
-
F2.setFloat32(0, v);
|
|
1317
|
-
this.bits(F2.getUint32(0), 32);
|
|
1318
|
-
}
|
|
1319
|
-
f64(v) {
|
|
1320
|
-
F2.setFloat64(0, v);
|
|
1321
|
-
this.bits(F2.getUint32(0), 32);
|
|
1322
|
-
this.bits(F2.getUint32(4), 32);
|
|
1323
|
-
}
|
|
1324
|
-
/** Raw bytes (a fast copy when the stream is on a byte boundary). */
|
|
1325
|
-
bytes(b) {
|
|
1326
|
-
if (this.bit === 0) {
|
|
1327
|
-
this.room(b.length + 1);
|
|
1328
|
-
this.buf.set(b, this.pos);
|
|
1329
|
-
this.pos += b.length;
|
|
1330
|
-
return;
|
|
1331
|
-
}
|
|
1332
|
-
for (let i = 0; i < b.length; i += 1) this.bits(b[i], 8);
|
|
1333
|
-
}
|
|
1334
|
-
/** Another writer's bits, appended. */
|
|
1335
|
-
append(other) {
|
|
1336
|
-
const n = other.length;
|
|
1337
|
-
const src = other.buf;
|
|
1338
|
-
const full = n >>> 3;
|
|
1339
|
-
if (this.bit === 0) {
|
|
1340
|
-
this.room(full + 2);
|
|
1341
|
-
this.buf.set(src.subarray(0, full), this.pos);
|
|
1342
|
-
this.pos += full;
|
|
1343
|
-
} else for (let i = 0; i < full; i += 1) this.bits(src[i], 8);
|
|
1344
|
-
const rest = n & 7;
|
|
1345
|
-
if (rest) this.bits(src[full] >>> 8 - rest, rest);
|
|
1346
|
-
}
|
|
1347
|
-
/** Pad with zero bits to the next byte. */
|
|
1348
|
-
align() {
|
|
1349
|
-
if (this.bit) {
|
|
1350
|
-
this.pos += 1;
|
|
1351
|
-
this.bit = 0;
|
|
1352
|
-
this.room(1);
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
/** The bytes (a copy), zero-padded to a whole byte. */
|
|
1356
|
-
finish() {
|
|
1357
|
-
return this.buf.slice(0, this.pos + (this.bit ? 1 : 0));
|
|
1358
|
-
}
|
|
1359
|
-
/** Empty it for reuse (keeps its buffer). */
|
|
1360
|
-
reset() {
|
|
1361
|
-
this.buf.fill(0, 0, this.pos + 1);
|
|
1362
|
-
this.pos = 0;
|
|
1363
|
-
this.bit = 0;
|
|
1364
|
-
}
|
|
1365
|
-
};
|
|
1366
|
-
|
|
1367
|
-
// ../../../../../../keel-engine/packages/codec/src/schema.ts
|
|
1368
|
-
var SchemaError = class extends TypeError {
|
|
1369
|
-
constructor(message) {
|
|
1370
|
-
super(message);
|
|
1371
|
-
this.name = "SchemaError";
|
|
1372
|
-
}
|
|
1373
|
-
};
|
|
1374
|
-
var bad = (why) => {
|
|
1375
|
-
throw new SchemaError(why);
|
|
1376
|
-
};
|
|
1377
|
-
var whole = (v, lo, hi, what) => {
|
|
1378
|
-
if (!Number.isInteger(v) || v < lo || v > hi) bad(`${what} must be a whole number in ${lo}..${hi} (got ${v}).`);
|
|
1379
|
-
return v;
|
|
1380
|
-
};
|
|
1381
|
-
var node = (n) => Object.freeze(n);
|
|
1382
|
-
var asNode = (t) => t;
|
|
1383
|
-
var uint = (bits) => node({ kind: "uint", bits: whole(bits, 1, 53, "uint bits") });
|
|
1384
|
-
var int = (bits) => node({ kind: "int", bits: whole(bits, 2, 53, "int bits") });
|
|
1385
|
-
var bool = () => node({ kind: "bool" });
|
|
1386
|
-
function fixed(min, max, step, { off = "round", k = -1, delta: delta2 = false } = {}) {
|
|
1387
|
-
if (![min, max, step].every(Number.isFinite)) bad("fixed(min, max, step) takes finite numbers.");
|
|
1388
|
-
if (!(step > 0)) bad(`fixed step must be positive (got ${step}).`);
|
|
1389
|
-
if (!(max > min)) bad(`fixed max must be above min (got ${min}..${max}).`);
|
|
1390
|
-
const steps = Math.round((max - min) / step);
|
|
1391
|
-
if (steps > 2 ** 52) bad(`fixed(${min}, ${max}, ${step}) has more than 2^52 steps.`);
|
|
1392
|
-
if (!["round", "strict", "exact"].includes(off)) bad(`fixed off must be "round", "strict" or "exact" (got ${off}).`);
|
|
1393
|
-
if (delta2 && k < 0) bad("fixed delta needs a Golomb k (the differences are Golomb-coded).");
|
|
1394
|
-
return node({ kind: "fixed", min, max, step, off, k: whole(k, -1, 31, "fixed k"), delta: delta2 });
|
|
1395
|
-
}
|
|
1396
|
-
var varuint = ({ k = 0, group = 0 } = {}) => node({ kind: "varuint", k: whole(k, 0, 31, "varuint k"), group: whole(group, 0, 31, "varuint group") });
|
|
1397
|
-
var varint = ({ k = 0, group = 0 } = {}) => node({ kind: "varint", k: whole(k, 0, 31, "varint k"), group: whole(group, 0, 31, "varint group") });
|
|
1398
|
-
var num = () => node({ kind: "num" });
|
|
1399
|
-
function enumOf(values, { capacity = 0, open = false, other = false } = {}) {
|
|
1400
|
-
if (!values.length) bad("An enum needs values.");
|
|
1401
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1402
|
-
for (const v of values) {
|
|
1403
|
-
const key = `${typeof v}:${String(v)}`;
|
|
1404
|
-
if (!["string", "number", "boolean"].includes(typeof v)) bad(`Enum values are strings, numbers or booleans (got ${typeof v}).`);
|
|
1405
|
-
if (seen.has(key)) bad(`Enum value ${JSON.stringify(v)} is listed twice.`);
|
|
1406
|
-
seen.add(key);
|
|
1407
|
-
}
|
|
1408
|
-
if (capacity && capacity < values.length) bad(`Enum capacity ${capacity} is below its ${values.length} values.`);
|
|
1409
|
-
return node({ kind: "enum", values: Object.freeze([...values]), capacity: whole(capacity, 0, 2 ** 32, "enum capacity"), open, other });
|
|
1410
|
-
}
|
|
1411
|
-
var string = ({ max = 0, packHex = false } = {}) => node({ kind: "string", max: whole(max, 0, 2 ** 32, "string max"), packHex });
|
|
1412
|
-
var ref = (table = "str", { packHex = false } = {}) => node({ kind: "ref", table: table || bad("ref needs a table name."), packHex });
|
|
1413
|
-
var bytes = ({ length = 0 } = {}) => node({ kind: "bytes", length: whole(length, 0, 2 ** 32, "bytes length") });
|
|
1414
|
-
var dyn = () => node({ kind: "dyn" });
|
|
1415
|
-
function array(of, { length = 0, max = 0 } = {}) {
|
|
1416
|
-
if (length && max) bad("An array has a fixed length or a max, not both.");
|
|
1417
|
-
return node({ kind: "array", of: asNode(of), length: whole(length, 0, 2 ** 32, "array length"), max: whole(max, 0, 2 ** 32, "array max") });
|
|
1418
|
-
}
|
|
1419
|
-
var optional = (of) => node({ kind: "optional", of: asNode(of), optional: true });
|
|
1420
|
-
var fieldsOf = (fields, what) => {
|
|
1421
|
-
const out = [];
|
|
1422
|
-
for (const [name, type] of Object.entries(fields)) {
|
|
1423
|
-
if (!name) bad(`${what}: a field needs a name.`);
|
|
1424
|
-
if (!type || typeof type.kind !== "string") bad(`${what}: field ${name} is not a schema.`);
|
|
1425
|
-
out.push(Object.freeze({ name, type: asNode(type) }));
|
|
1426
|
-
}
|
|
1427
|
-
return out;
|
|
1428
|
-
};
|
|
1429
|
-
function struct(fields, { open = false } = {}) {
|
|
1430
|
-
return node({ kind: "struct", fields: Object.freeze(fieldsOf(fields, "struct")), open, ext: Object.freeze([]) });
|
|
1431
|
-
}
|
|
1432
|
-
function extend(base, fields) {
|
|
1433
|
-
if (base.kind !== "struct") bad("extend() takes a struct.");
|
|
1434
|
-
if (!base.open) bad("Only an open struct can be extended: declare it struct({...}, { open: true }) from its first version.");
|
|
1435
|
-
const group = fieldsOf(fields, "extend");
|
|
1436
|
-
if (!group.length) bad("extend() needs at least one field.");
|
|
1437
|
-
const names = new Set([...base.fields, ...base.ext.flat()].map((f) => f.name));
|
|
1438
|
-
for (const f of group) {
|
|
1439
|
-
if (names.has(f.name)) bad(`extend(): the struct already has a field ${f.name}.`);
|
|
1440
|
-
if (f.type.kind !== "optional" && f.type.kind !== "default") bad(`extend(): new field ${f.name} must be optional() or withDefault() (old data doesn't carry it).`);
|
|
1441
|
-
}
|
|
1442
|
-
return node({ kind: "struct", fields: base.fields, open: true, ext: Object.freeze([...base.ext, Object.freeze(group)]) });
|
|
1443
|
-
}
|
|
1444
|
-
var tuple = (items) => node({ kind: "tuple", items: Object.freeze(items.map(asNode)) });
|
|
1445
|
-
function union(tag, variants, { capacity = 0 } = {}) {
|
|
1446
|
-
const list = fieldsOf(variants, "union");
|
|
1447
|
-
if (!list.length) bad("A union needs variants.");
|
|
1448
|
-
for (const v of list) {
|
|
1449
|
-
if (v.type.kind !== "struct") bad(`Union variant ${v.name} must be a struct.`);
|
|
1450
|
-
const st = v.type;
|
|
1451
|
-
if ([...st.fields, ...st.ext.flat()].some((f) => f.name === tag)) bad(`Union variant ${v.name} has a field called ${tag}, its tag.`);
|
|
1452
|
-
}
|
|
1453
|
-
if (capacity && capacity < list.length) bad(`Union capacity ${capacity} is below its ${list.length} variants.`);
|
|
1454
|
-
return node({ kind: "union", tag, variants: Object.freeze(list), capacity: whole(capacity, 0, 2 ** 16, "union capacity") });
|
|
1455
|
-
}
|
|
1456
|
-
function alt(of) {
|
|
1457
|
-
if (of.length < 2) bad("alt() takes two or more types.");
|
|
1458
|
-
const cats = of.map((t) => categoryOf(asNode(t)));
|
|
1459
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1460
|
-
for (const c of cats) {
|
|
1461
|
-
if (c === "any") bad("alt() branches must have a definite category (not dyn, optional or a recursion).");
|
|
1462
|
-
if (seen.has(c)) bad(`alt() has two ${c} branches: nothing tells them apart.`);
|
|
1463
|
-
seen.add(c);
|
|
1464
|
-
}
|
|
1465
|
-
return node({ kind: "alt", of: Object.freeze(of.map(asNode)) });
|
|
1466
|
-
}
|
|
1467
|
-
var planes = (bits) => node({ kind: "planes", bits: whole(bits, 1, 32, "planes bits") });
|
|
1468
|
-
var named = (name, of, { version = 1, doc = "" } = {}) => node({ kind: "named", name: name || bad("named() needs a name."), version: whole(version, 0, 2 ** 32, "version"), doc, of: asNode(of) });
|
|
1469
|
-
function recursive(build2) {
|
|
1470
|
-
const placeholder = Object.freeze({ kind: "self", depth: -1 });
|
|
1471
|
-
const body = asNode(build2(placeholder));
|
|
1472
|
-
const fix = (n, depth) => {
|
|
1473
|
-
if (n === placeholder) return node({ kind: "self", depth });
|
|
1474
|
-
return mapChildren(n, (c) => fix(c, depth + (n.kind === "rec" ? 1 : 0)));
|
|
1475
|
-
};
|
|
1476
|
-
return node({ kind: "rec", of: fix(body, 0) });
|
|
1477
|
-
}
|
|
1478
|
-
function mapChildren(n, f) {
|
|
1479
|
-
const fl = (fs) => {
|
|
1480
|
-
let changed = false;
|
|
1481
|
-
const out = fs.map((x) => {
|
|
1482
|
-
const t = f(x.type);
|
|
1483
|
-
if (t !== x.type) changed = true;
|
|
1484
|
-
return t === x.type ? x : Object.freeze({ name: x.name, type: t });
|
|
1485
|
-
});
|
|
1486
|
-
return changed ? Object.freeze(out) : fs;
|
|
1487
|
-
};
|
|
1488
|
-
switch (n.kind) {
|
|
1489
|
-
case "array":
|
|
1490
|
-
case "optional":
|
|
1491
|
-
case "nullable":
|
|
1492
|
-
case "default":
|
|
1493
|
-
case "delta":
|
|
1494
|
-
case "runs":
|
|
1495
|
-
case "named":
|
|
1496
|
-
case "rec":
|
|
1497
|
-
case "lz": {
|
|
1498
|
-
const of = f(n.of);
|
|
1499
|
-
return of === n.of ? n : node({ ...n, of });
|
|
1500
|
-
}
|
|
1501
|
-
case "struct": {
|
|
1502
|
-
const fields = fl(n.fields);
|
|
1503
|
-
const ext = n.ext.map(fl);
|
|
1504
|
-
return fields === n.fields && ext.every((g, i) => g === n.ext[i]) ? n : node({ ...n, fields, ext: Object.freeze(ext) });
|
|
1505
|
-
}
|
|
1506
|
-
case "union": {
|
|
1507
|
-
const variants = fl(n.variants);
|
|
1508
|
-
return variants === n.variants ? n : node({ ...n, variants });
|
|
1509
|
-
}
|
|
1510
|
-
case "tuple": {
|
|
1511
|
-
const items = n.items.map(f);
|
|
1512
|
-
return items.every((x, i) => x === n.items[i]) ? n : node({ ...n, items: Object.freeze(items) });
|
|
1513
|
-
}
|
|
1514
|
-
case "alt": {
|
|
1515
|
-
const of = n.of.map(f);
|
|
1516
|
-
return of.every((x, i) => x === n.of[i]) ? n : node({ ...n, of: Object.freeze(of) });
|
|
1517
|
-
}
|
|
1518
|
-
case "map": {
|
|
1519
|
-
const key = f(n.key);
|
|
1520
|
-
const value = f(n.value);
|
|
1521
|
-
return key === n.key && value === n.value ? n : node({ ...n, key, value });
|
|
1522
|
-
}
|
|
1523
|
-
case "grow": {
|
|
1524
|
-
const base = f(n.base);
|
|
1525
|
-
const of = f(n.of);
|
|
1526
|
-
return base === n.base && of === n.of ? n : node({ ...n, base, of });
|
|
1527
|
-
}
|
|
1528
|
-
default:
|
|
1529
|
-
return n;
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
function categoryOf(n) {
|
|
1533
|
-
switch (n.kind) {
|
|
1534
|
-
case "uint":
|
|
1535
|
-
case "int":
|
|
1536
|
-
case "fixed":
|
|
1537
|
-
case "float":
|
|
1538
|
-
case "varuint":
|
|
1539
|
-
case "varint":
|
|
1540
|
-
case "num":
|
|
1541
|
-
return "number";
|
|
1542
|
-
case "bool":
|
|
1543
|
-
return "boolean";
|
|
1544
|
-
case "string":
|
|
1545
|
-
case "ref":
|
|
1546
|
-
case "hex":
|
|
1547
|
-
return "string";
|
|
1548
|
-
case "biguint":
|
|
1549
|
-
return "bigint";
|
|
1550
|
-
case "bytes":
|
|
1551
|
-
return "bytes";
|
|
1552
|
-
case "array":
|
|
1553
|
-
case "delta":
|
|
1554
|
-
case "runs":
|
|
1555
|
-
case "planes":
|
|
1556
|
-
case "tuple":
|
|
1557
|
-
case "lz":
|
|
1558
|
-
case "grow":
|
|
1559
|
-
return "array";
|
|
1560
|
-
case "struct":
|
|
1561
|
-
case "union":
|
|
1562
|
-
case "map":
|
|
1563
|
-
return "object";
|
|
1564
|
-
case "nullable":
|
|
1565
|
-
return "any";
|
|
1566
|
-
case "enum": {
|
|
1567
|
-
const c = /* @__PURE__ */ new Set([...n.values.map((v) => typeof v), ...n.other ? ["string"] : []]);
|
|
1568
|
-
return c.size === 1 ? [...c][0] : "any";
|
|
1569
|
-
}
|
|
1570
|
-
case "const":
|
|
1571
|
-
return n.value === null ? "null" : Array.isArray(n.value) ? "array" : typeof n.value;
|
|
1572
|
-
case "named":
|
|
1573
|
-
case "default":
|
|
1574
|
-
return categoryOf(n.of);
|
|
1575
|
-
default:
|
|
1576
|
-
return "any";
|
|
1577
|
-
}
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
// ../../../../../../keel-engine/packages/codec/src/schemas/common.ts
|
|
1581
|
-
var coord = fixed(-8192, 8192, 1e-3);
|
|
1582
|
-
var local = fixed(-8192, 8192, 1e-3, { k: 10 });
|
|
1583
|
-
var localDelta = fixed(-8192, 8192, 1e-3, { k: 9, delta: true });
|
|
1584
|
-
var size = fixed(0, 1024, 1e-3, { k: 9 });
|
|
1585
|
-
var sizeDelta = fixed(0, 1024, 1e-3, { k: 9, delta: true });
|
|
1586
|
-
var yaw = fixed(-Math.PI, Math.PI, Math.PI / 32768);
|
|
1587
|
-
var unit = fixed(0, 1, 1 / 1024);
|
|
1588
|
-
var signed = fixed(-1, 1, 1e-3);
|
|
1589
|
-
var vec3 = tuple([coord, coord, coord]);
|
|
1590
|
-
var lvec3 = tuple([local, local, local]);
|
|
1591
|
-
var dvec3 = tuple([localDelta, localDelta, localDelta]);
|
|
1592
|
-
var dhalf3 = tuple([sizeDelta, sizeDelta, sizeDelta]);
|
|
1593
|
-
var half3 = tuple([size, size, size]);
|
|
1594
|
-
var dir3 = tuple([signed, signed, signed]);
|
|
1595
|
-
var seedText = ref("str", { packHex: true });
|
|
1596
|
-
var seedAny = alt([num(), seedText]);
|
|
1597
|
-
var oklch2 = tuple([fixed(0, 1, 1e-3, { off: "exact" }), fixed(0, 0.5, 1e-3, { off: "exact" }), fixed(0, 360, 0.01, { off: "exact" })]);
|
|
1598
|
-
var id = ref("ids");
|
|
1599
|
-
var count8 = uint(8);
|
|
1600
|
-
|
|
1601
|
-
// ../../../../../../keel-engine/packages/codec/src/codec-primitives.ts
|
|
1602
|
-
var CodecError = class _CodecError extends Error {
|
|
1603
|
-
/** Field names and indices from the root ("parts", 3, "shape(box)", "h", 1). */
|
|
1604
|
-
path;
|
|
1605
|
-
/** The reason, without the path. */
|
|
1606
|
-
why;
|
|
1607
|
-
/** Decoding: the bit it happened at. */
|
|
1608
|
-
bit;
|
|
1609
|
-
constructor(why, path = [], bit = null) {
|
|
1610
|
-
super(why);
|
|
1611
|
-
this.name = "CodecError";
|
|
1612
|
-
this.why = why;
|
|
1613
|
-
this.path = path;
|
|
1614
|
-
this.bit = bit;
|
|
1615
|
-
this.message = _CodecError.format(why, path, bit);
|
|
1616
|
-
}
|
|
1617
|
-
static format(why, path, bit) {
|
|
1618
|
-
const p = pathText(path);
|
|
1619
|
-
return `${p ? `${p}: ` : ""}${why}${bit !== null ? ` (at bit ${bit})` : ""}`;
|
|
1620
|
-
}
|
|
1621
|
-
};
|
|
1622
|
-
function pathText(path) {
|
|
1623
|
-
let out = "";
|
|
1624
|
-
for (const k of path) out += typeof k === "number" ? `[${k}]` : out ? `.${k}` : k;
|
|
1625
|
-
return out;
|
|
1626
|
-
}
|
|
1627
|
-
var fail = (why) => {
|
|
1628
|
-
throw new CodecError(why);
|
|
1629
|
-
};
|
|
1630
|
-
function under(e, label, bit = null) {
|
|
1631
|
-
if (e instanceof CodecError) {
|
|
1632
|
-
e.path.unshift(label);
|
|
1633
|
-
if (e.bit === null && bit !== null) e.bit = bit;
|
|
1634
|
-
e.message = CodecError.format(e.why, e.path, e.bit);
|
|
1635
|
-
return e;
|
|
1636
|
-
}
|
|
1637
|
-
if (e instanceof BitError) return new CodecError(e.message.replace(/ at bit \d+/, ""), [label], e.bit);
|
|
1638
|
-
if (e instanceof Error) return new CodecError(e.message, [label]);
|
|
1639
|
-
return new CodecError(String(e), [label]);
|
|
1640
|
-
}
|
|
1641
|
-
var Tables = class {
|
|
1642
|
-
m = /* @__PURE__ */ new Map();
|
|
1643
|
-
constructor(init = {}) {
|
|
1644
|
-
for (const [name, list] of Object.entries(init)) for (const s of list) this.add(name, s);
|
|
1645
|
-
}
|
|
1646
|
-
table(name) {
|
|
1647
|
-
let t = this.m.get(name);
|
|
1648
|
-
if (!t) {
|
|
1649
|
-
t = { list: [], index: /* @__PURE__ */ new Map() };
|
|
1650
|
-
this.m.set(name, t);
|
|
1651
|
-
}
|
|
1652
|
-
return t;
|
|
1653
|
-
}
|
|
1654
|
-
add(name, s) {
|
|
1655
|
-
const t = this.table(name);
|
|
1656
|
-
const have = t.index.get(s);
|
|
1657
|
-
if (have !== void 0) return have;
|
|
1658
|
-
t.list.push(s);
|
|
1659
|
-
t.index.set(s, t.list.length - 1);
|
|
1660
|
-
return t.list.length - 1;
|
|
1661
|
-
}
|
|
1662
|
-
n = /* @__PURE__ */ new Map();
|
|
1663
|
-
/** A table of numbers (dyn()'s fractional numbers: a repeated one is its index). */
|
|
1664
|
-
numbers(name) {
|
|
1665
|
-
let t = this.n.get(name);
|
|
1666
|
-
if (!t) {
|
|
1667
|
-
t = { list: [], index: /* @__PURE__ */ new Map() };
|
|
1668
|
-
this.n.set(name, t);
|
|
1669
|
-
}
|
|
1670
|
-
return t;
|
|
1671
|
-
}
|
|
1672
|
-
sh = /* @__PURE__ */ new Map();
|
|
1673
|
-
/** A table of object shapes (dyn()'s key lists: an object shaped like one before is its index, then its values). */
|
|
1674
|
-
shapes(name) {
|
|
1675
|
-
let t = this.sh.get(name);
|
|
1676
|
-
if (!t) {
|
|
1677
|
-
t = { list: [], index: /* @__PURE__ */ new Map() };
|
|
1678
|
-
this.sh.set(name, t);
|
|
1679
|
-
}
|
|
1680
|
-
return t;
|
|
1681
|
-
}
|
|
1682
|
-
/** Every table's strings, by name (what a pack stores once when its documents share tables). */
|
|
1683
|
-
toJSON() {
|
|
1684
|
-
return Object.fromEntries([...this.m.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => [k, [...v.list]]));
|
|
1685
|
-
}
|
|
1686
|
-
};
|
|
1687
|
-
var fresh = () => ({ tables: new Tables(), trace: null, strict: true, text: new BitWriter(64), tr: null, last: null });
|
|
1688
|
-
var lastOf = (x) => x.last ??= /* @__PURE__ */ new Map();
|
|
1689
|
-
function wr(c, o, v, x, label) {
|
|
1690
|
-
try {
|
|
1691
|
-
c.w(o, v, x);
|
|
1692
|
-
} catch (e) {
|
|
1693
|
-
throw under(e, label, null);
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
function rd(c, i, x, label) {
|
|
1697
|
-
const start = i.at;
|
|
1698
|
-
try {
|
|
1699
|
-
if (x.trace === null) return c.r(i, x);
|
|
1700
|
-
x.trace.open(label, c.node, start);
|
|
1701
|
-
const v = c.r(i, x);
|
|
1702
|
-
x.trace.close(v, i.at);
|
|
1703
|
-
return v;
|
|
1704
|
-
} catch (e) {
|
|
1705
|
-
throw under(e, label, start);
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
var meta = (x, label, start, i, value, note = "") => {
|
|
1709
|
-
x.trace?.meta(label, start, i.at - start, value, note);
|
|
1710
|
-
};
|
|
1711
|
-
function same(a, b) {
|
|
1712
|
-
if (typeof a === "number" || typeof b === "number") return Object.is(a, b);
|
|
1713
|
-
if (a === b) return true;
|
|
1714
|
-
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
|
|
1715
|
-
if (a instanceof Uint8Array || b instanceof Uint8Array) {
|
|
1716
|
-
if (!(a instanceof Uint8Array && b instanceof Uint8Array) || a.length !== b.length) return false;
|
|
1717
|
-
for (let k = 0; k < a.length; k += 1) if (a[k] !== b[k]) return false;
|
|
1718
|
-
return true;
|
|
1719
|
-
}
|
|
1720
|
-
const aa = Array.isArray(a) || ArrayBuffer.isView(a);
|
|
1721
|
-
if (aa !== (Array.isArray(b) || ArrayBuffer.isView(b))) return false;
|
|
1722
|
-
if (aa) {
|
|
1723
|
-
const x = a, y = b;
|
|
1724
|
-
if (x.length !== y.length) return false;
|
|
1725
|
-
for (let k = 0; k < x.length; k += 1) if (!same(x[k], y[k])) return false;
|
|
1726
|
-
return true;
|
|
1727
|
-
}
|
|
1728
|
-
const ka = Object.keys(a).filter((k) => a[k] !== void 0);
|
|
1729
|
-
const kb = Object.keys(b).filter((k) => b[k] !== void 0);
|
|
1730
|
-
if (ka.length !== kb.length) return false;
|
|
1731
|
-
for (const k of ka) if (!same(a[k], b[k])) return false;
|
|
1732
|
-
return true;
|
|
1733
|
-
}
|
|
1734
|
-
function put(o, k, v) {
|
|
1735
|
-
if (k === "__proto__") Object.defineProperty(o, k, { value: v, enumerable: true, writable: true, configurable: true });
|
|
1736
|
-
else o[k] = v;
|
|
1737
|
-
}
|
|
1738
|
-
var zig = (v) => v >= 0 ? v * 2 : -v * 2 - 1;
|
|
1739
|
-
var unzig = (u2) => u2 % 2 ? -(u2 + 1) / 2 : u2 / 2;
|
|
1740
|
-
var describe = (v) => typeof v === "string" ? JSON.stringify(v.length > 40 ? `${v.slice(0, 40)}...` : v) : typeof v === "bigint" ? `${v}n` : Array.isArray(v) ? `an array of ${v.length}` : v instanceof Uint8Array ? `${v.length} bytes` : v === null ? "null" : typeof v === "object" ? "an object" : String(v);
|
|
1741
|
-
var GRIDS = /* @__PURE__ */ new WeakMap();
|
|
1742
|
-
function gridOf(n) {
|
|
1743
|
-
const have = GRIDS.get(n);
|
|
1744
|
-
if (have) return have;
|
|
1745
|
-
const inv = 1 / n.step;
|
|
1746
|
-
const den = Math.abs(inv - Math.round(inv)) < 1e-9 * Math.max(1, inv) ? Math.round(inv) : 0;
|
|
1747
|
-
const value = den ? (k) => k / den : (k) => k * n.step;
|
|
1748
|
-
const units = den ? (v) => Math.round(v * den) : (v) => Math.round(v / n.step);
|
|
1749
|
-
const near = (x) => Math.abs(x - Math.round(x)) <= 1e-9 * Math.max(1, Math.abs(x)) ? Math.round(x) : null;
|
|
1750
|
-
const lo = near(n.min / n.step) ?? Math.ceil(n.min / n.step);
|
|
1751
|
-
const hi = near(n.max / n.step) ?? Math.floor(n.max / n.step);
|
|
1752
|
-
let places = -1;
|
|
1753
|
-
if (den) {
|
|
1754
|
-
for (let p = 0, ten = 1; p <= 15; p += 1, ten *= 10) if (ten % den === 0) {
|
|
1755
|
-
places = p;
|
|
1756
|
-
break;
|
|
1757
|
-
}
|
|
1758
|
-
}
|
|
1759
|
-
const g = { lo, hi, bits: bitsFor(hi - lo + 1), den, step: n.step, places, value, units };
|
|
1760
|
-
GRIDS.set(n, g);
|
|
1761
|
-
return g;
|
|
1762
|
-
}
|
|
1763
|
-
function intCheck(v, what) {
|
|
1764
|
-
if (typeof v !== "number" || !Number.isInteger(v)) fail(`${describe(v)} is not a whole number (${what}).`);
|
|
1765
|
-
return v;
|
|
1766
|
-
}
|
|
1767
|
-
var NUM_KINDS = ["int", "decimal", "float32", "float64"];
|
|
1768
|
-
var TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8];
|
|
1769
|
-
function placesOf(v) {
|
|
1770
|
-
if (!Number.isFinite(v) || Object.is(v, -0) || Math.abs(v) > 2 ** 40) return 0;
|
|
1771
|
-
for (let p = 1; p <= 8; p += 1) {
|
|
1772
|
-
const m = Math.round(v * TEN[p]);
|
|
1773
|
-
if (Math.abs(m) <= 2 ** 51 && m / TEN[p] === v) return p;
|
|
1774
|
-
}
|
|
1775
|
-
return 0;
|
|
1776
|
-
}
|
|
1777
|
-
function writeNum(o, v, tagBits) {
|
|
1778
|
-
if (Number.isSafeInteger(v) && !Object.is(v, -0) && Math.abs(v) <= 2 ** 51) {
|
|
1779
|
-
o.bits(0, tagBits);
|
|
1780
|
-
o.golomb(zig(v), 0);
|
|
1781
|
-
return;
|
|
1782
|
-
}
|
|
1783
|
-
const p = placesOf(v);
|
|
1784
|
-
if (p) {
|
|
1785
|
-
o.bits(1, tagBits);
|
|
1786
|
-
o.bits(p - 1, 3);
|
|
1787
|
-
o.golomb(zig(Math.round(v * TEN[p])), 0);
|
|
1788
|
-
return;
|
|
1789
|
-
}
|
|
1790
|
-
if (Number.isNaN(v) || Object.is(Math.fround(v), v)) {
|
|
1791
|
-
o.bits(2, tagBits);
|
|
1792
|
-
o.f32(v);
|
|
1793
|
-
return;
|
|
1794
|
-
}
|
|
1795
|
-
o.bits(3, tagBits);
|
|
1796
|
-
o.f64(v);
|
|
1797
|
-
}
|
|
1798
|
-
function readNum(i, tag) {
|
|
1799
|
-
if (tag === 0) return unzig(i.golomb(0));
|
|
1800
|
-
if (tag === 1) {
|
|
1801
|
-
const p = i.bits(3) + 1;
|
|
1802
|
-
const m = unzig(i.golomb(0));
|
|
1803
|
-
const v = m / TEN[p];
|
|
1804
|
-
if (Number.isInteger(v) || placesOf(v) !== p) throw new CodecError(`A decimal with ${p} places that isn't its shortest spelling (not canonical).`);
|
|
1805
|
-
return v;
|
|
1806
|
-
}
|
|
1807
|
-
if (tag === 2) return i.f32();
|
|
1808
|
-
return i.f64();
|
|
1809
|
-
}
|
|
1810
|
-
var COMPILED = /* @__PURE__ */ new WeakMap();
|
|
1811
|
-
function compiled(root, compile2) {
|
|
1812
|
-
const have = COMPILED.get(root);
|
|
1813
|
-
if (have) return have;
|
|
1814
|
-
const c = compile2(root, []);
|
|
1815
|
-
COMPILED.set(root, c);
|
|
1816
|
-
return c;
|
|
1817
|
-
}
|
|
1818
|
-
var enc = new TextEncoder();
|
|
1819
|
-
function utf8(s) {
|
|
1820
|
-
const n = s.length;
|
|
1821
|
-
if (n < 64) {
|
|
1822
|
-
let ascii = true;
|
|
1823
|
-
for (let k = 0; k < n; k += 1) if (s.charCodeAt(k) > 127) {
|
|
1824
|
-
ascii = false;
|
|
1825
|
-
break;
|
|
1826
|
-
}
|
|
1827
|
-
if (ascii) {
|
|
1828
|
-
const b = new Uint8Array(n);
|
|
1829
|
-
for (let k = 0; k < n; k += 1) b[k] = s.charCodeAt(k);
|
|
1830
|
-
return b;
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
return enc.encode(s);
|
|
1834
|
-
}
|
|
1835
|
-
function fromUtf8(tr, len2) {
|
|
1836
|
-
const b = tr.bytes(len2);
|
|
1837
|
-
if (len2 < 64) {
|
|
1838
|
-
let ascii = true;
|
|
1839
|
-
for (let k = 0; k < len2; k += 1) if (b[k] > 127) {
|
|
1840
|
-
ascii = false;
|
|
1841
|
-
break;
|
|
1842
|
-
}
|
|
1843
|
-
if (ascii) return String.fromCharCode.apply(null, b);
|
|
1844
|
-
}
|
|
1845
|
-
return dec.decode(b);
|
|
1846
|
-
}
|
|
1847
|
-
var LONE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
1848
|
-
var wellFormed = (s) => !LONE.test(s);
|
|
1849
|
-
var SCRATCH = new BitWriter(64);
|
|
1850
|
-
var dec = new TextDecoder("utf-8", { fatal: true });
|
|
1851
|
-
|
|
1852
|
-
// ../../../../../../keel-engine/packages/codec/src/codec.ts
|
|
1853
|
-
function compiled2(root) {
|
|
1854
|
-
return compiled(root, compile);
|
|
1855
|
-
}
|
|
1856
|
-
function compile(n, recs) {
|
|
1857
|
-
switch (n.kind) {
|
|
1858
|
-
case "uint": {
|
|
1859
|
-
const max = 2 ** n.bits;
|
|
1860
|
-
const what = `uint(${n.bits})`;
|
|
1861
|
-
return {
|
|
1862
|
-
node: n,
|
|
1863
|
-
w(o, v) {
|
|
1864
|
-
const k = intCheck(v, what);
|
|
1865
|
-
if (k < 0 || k >= max) fail(`${k} is outside ${what}'s 0..${max - 1}.`);
|
|
1866
|
-
o.wide(k, n.bits);
|
|
1867
|
-
},
|
|
1868
|
-
r: (i) => i.bits(n.bits)
|
|
1869
|
-
};
|
|
1870
|
-
}
|
|
1871
|
-
case "int": {
|
|
1872
|
-
const half = 2 ** (n.bits - 1);
|
|
1873
|
-
const what = `int(${n.bits})`;
|
|
1874
|
-
return {
|
|
1875
|
-
node: n,
|
|
1876
|
-
w(o, v) {
|
|
1877
|
-
const k = intCheck(v, what);
|
|
1878
|
-
if (k < -half || k >= half) fail(`${k} is outside ${what}'s ${-half}..${half - 1}.`);
|
|
1879
|
-
o.wide(zig(k), n.bits);
|
|
1880
|
-
},
|
|
1881
|
-
r: (i) => unzig(i.bits(n.bits))
|
|
1882
|
-
};
|
|
1883
|
-
}
|
|
1884
|
-
case "bool":
|
|
1885
|
-
return {
|
|
1886
|
-
node: n,
|
|
1887
|
-
w(o, v) {
|
|
1888
|
-
if (typeof v !== "boolean") fail(`${describe(v)} is not a boolean.`);
|
|
1889
|
-
o.bool(v);
|
|
1890
|
-
},
|
|
1891
|
-
r: (i) => i.bool()
|
|
1892
|
-
};
|
|
1893
|
-
case "fixed": {
|
|
1894
|
-
const g = gridOf(n);
|
|
1895
|
-
const what = `fixed(${n.min}, ${n.max}, ${n.step})`;
|
|
1896
|
-
const exact = n.off === "exact";
|
|
1897
|
-
const signed2 = g.lo < 0;
|
|
1898
|
-
const self = {};
|
|
1899
|
-
const put2 = n.delta ? (o, k, x) => {
|
|
1900
|
-
const m = lastOf(x);
|
|
1901
|
-
const d = k - (m.get(self) ?? 0);
|
|
1902
|
-
if (d === 0) o.bool(false);
|
|
1903
|
-
else {
|
|
1904
|
-
o.bool(true);
|
|
1905
|
-
o.golomb(zig(d) - 1, n.k);
|
|
1906
|
-
}
|
|
1907
|
-
m.set(self, k);
|
|
1908
|
-
} : n.k >= 0 ? (o, k) => o.golomb(signed2 ? zig(k) : k, n.k) : (o, k) => o.wide(k - g.lo, g.bits);
|
|
1909
|
-
const get = n.delta ? (i, x) => {
|
|
1910
|
-
const m = lastOf(x);
|
|
1911
|
-
const k = (m.get(self) ?? 0) + (i.bool() ? unzig(i.golomb(n.k) + 1) : 0);
|
|
1912
|
-
if (k < g.lo || k > g.hi) fail(`${g.value(k)} is outside ${what} (corrupt data).`);
|
|
1913
|
-
m.set(self, k);
|
|
1914
|
-
return k;
|
|
1915
|
-
} : n.k >= 0 ? (i) => {
|
|
1916
|
-
const u2 = i.golomb(n.k);
|
|
1917
|
-
const k = signed2 ? unzig(u2) : u2;
|
|
1918
|
-
if (k < g.lo || k > g.hi) fail(`${g.value(k)} is outside ${what} (corrupt data).`);
|
|
1919
|
-
return k;
|
|
1920
|
-
} : (i) => i.wide(g.bits) + g.lo;
|
|
1921
|
-
return {
|
|
1922
|
-
node: n,
|
|
1923
|
-
w(o, v, ctx) {
|
|
1924
|
-
if (typeof v !== "number") fail(`${describe(v)} is not a number (${what}).`);
|
|
1925
|
-
const x = v;
|
|
1926
|
-
if (exact) {
|
|
1927
|
-
const k2 = Number.isFinite(x) ? g.units(x) : NaN;
|
|
1928
|
-
if (k2 >= g.lo && k2 <= g.hi && Object.is(g.value(k2) === 0 ? 0 : g.value(k2), x)) {
|
|
1929
|
-
o.bool(false);
|
|
1930
|
-
put2(o, k2, ctx);
|
|
1931
|
-
return;
|
|
1932
|
-
}
|
|
1933
|
-
o.bool(true);
|
|
1934
|
-
o.f64(x);
|
|
1935
|
-
return;
|
|
1936
|
-
}
|
|
1937
|
-
if (!Number.isFinite(x)) fail(`${x} is not a finite number (${what}).`);
|
|
1938
|
-
const k = g.units(x);
|
|
1939
|
-
if (k < g.lo) fail(`${x} is below ${what}'s min ${n.min}.`);
|
|
1940
|
-
if (k > g.hi) fail(`${x} is above ${what}'s max ${n.max}.`);
|
|
1941
|
-
if (n.off === "strict" && g.value(k) !== x) fail(`${x} is not on ${what}'s grid (nearest ${g.value(k)}).`);
|
|
1942
|
-
put2(o, k, ctx);
|
|
1943
|
-
},
|
|
1944
|
-
r(i, x) {
|
|
1945
|
-
if (exact) {
|
|
1946
|
-
const s = i.at;
|
|
1947
|
-
const whole2 = i.bool();
|
|
1948
|
-
if (x.trace) meta(x, "exact", s, i, whole2, whole2 ? "off the grid: a float64" : "on the grid");
|
|
1949
|
-
if (whole2) return i.f64();
|
|
1950
|
-
}
|
|
1951
|
-
const v = g.value(get(i, x));
|
|
1952
|
-
return v === 0 ? 0 : v;
|
|
1953
|
-
}
|
|
1954
|
-
};
|
|
1955
|
-
}
|
|
1956
|
-
case "float": {
|
|
1957
|
-
const bits = n.bits;
|
|
1958
|
-
return {
|
|
1959
|
-
node: n,
|
|
1960
|
-
w(o, v) {
|
|
1961
|
-
if (typeof v !== "number") fail(`${describe(v)} is not a number.`);
|
|
1962
|
-
const x = v;
|
|
1963
|
-
if (bits === 32) {
|
|
1964
|
-
if (!Number.isNaN(x) && !Object.is(Math.fround(x), x)) fail(`${x} is not exactly a float32 (use float64 or fixed()).`);
|
|
1965
|
-
o.f32(x);
|
|
1966
|
-
} else if (bits === 16) {
|
|
1967
|
-
if (!Number.isNaN(x) && !Object.is(fromHalf(toHalf(x)), x)) fail(`${x} is not exactly a float16 (use float32, float64 or fixed()).`);
|
|
1968
|
-
o.f16(x);
|
|
1969
|
-
} else o.f64(x);
|
|
1970
|
-
},
|
|
1971
|
-
r: (i) => bits === 32 ? i.f32() : bits === 16 ? i.f16() : i.f64()
|
|
1972
|
-
};
|
|
1973
|
-
}
|
|
1974
|
-
case "varuint":
|
|
1975
|
-
case "varint": {
|
|
1976
|
-
const signed2 = n.kind === "varint";
|
|
1977
|
-
const put2 = n.group ? (o, u2) => o.groups(u2, n.group) : (o, u2) => o.golomb(u2, n.k);
|
|
1978
|
-
const get = n.group ? (i) => i.groups(n.group) : (i) => i.golomb(n.k);
|
|
1979
|
-
return {
|
|
1980
|
-
node: n,
|
|
1981
|
-
w(o, v) {
|
|
1982
|
-
const k = intCheck(v, n.kind);
|
|
1983
|
-
if (!Number.isSafeInteger(k)) fail(`${k} is beyond a safe integer.`);
|
|
1984
|
-
if (!signed2 && k < 0) fail(`${k} is negative (a varuint).`);
|
|
1985
|
-
if (signed2 && Math.abs(k) > 2 ** 51) fail(`${k} is beyond a varint's \xB12^51.`);
|
|
1986
|
-
put2(o, signed2 ? zig(k) : k);
|
|
1987
|
-
},
|
|
1988
|
-
r: (i) => signed2 ? unzig(get(i)) : get(i)
|
|
1989
|
-
};
|
|
1990
|
-
}
|
|
1991
|
-
case "num":
|
|
1992
|
-
return {
|
|
1993
|
-
node: n,
|
|
1994
|
-
w(o, v) {
|
|
1995
|
-
if (typeof v !== "number") fail(`${describe(v)} is not a number.`);
|
|
1996
|
-
writeNum(o, v, 2);
|
|
1997
|
-
},
|
|
1998
|
-
r(i, x) {
|
|
1999
|
-
const s = i.at;
|
|
2000
|
-
const tag = i.bits(2);
|
|
2001
|
-
if (x.trace) meta(x, "kind", s, i, NUM_KINDS[tag], "");
|
|
2002
|
-
return readNum(i, tag);
|
|
2003
|
-
}
|
|
2004
|
-
};
|
|
2005
|
-
case "biguint": {
|
|
2006
|
-
const lim = 1n << BigInt(n.bits);
|
|
2007
|
-
return {
|
|
2008
|
-
node: n,
|
|
2009
|
-
w(o, v) {
|
|
2010
|
-
if (typeof v !== "bigint") fail(`${describe(v)} is not a bigint (biguint(${n.bits})).`);
|
|
2011
|
-
if (v < 0n || v >= lim) fail(`${v}n is outside biguint(${n.bits}).`);
|
|
2012
|
-
o.big(v, n.bits);
|
|
2013
|
-
},
|
|
2014
|
-
r: (i) => i.big(n.bits)
|
|
2015
|
-
};
|
|
2016
|
-
}
|
|
2017
|
-
case "enum": {
|
|
2018
|
-
const index = new Map(n.values.map((v, k) => [v, k]));
|
|
2019
|
-
const limit = n.capacity || n.values.length;
|
|
2020
|
-
const width = bitsFor(limit + (n.other ? 1 : 0));
|
|
2021
|
-
const str = n.other ? compile({ kind: "string", max: 0 }, []) : null;
|
|
2022
|
-
return {
|
|
2023
|
-
node: n,
|
|
2024
|
-
w(o, v, x) {
|
|
2025
|
-
const k = index.get(v);
|
|
2026
|
-
if (k === void 0) {
|
|
2027
|
-
if (str && typeof v === "string") {
|
|
2028
|
-
if (n.open) o.golomb(limit, 0);
|
|
2029
|
-
else o.bits(limit, width);
|
|
2030
|
-
str.w(o, v, x);
|
|
2031
|
-
return;
|
|
2032
|
-
}
|
|
2033
|
-
fail(`${describe(v)} is not one of ${JSON.stringify(n.values.length > 12 ? [...n.values.slice(0, 12), "..."] : n.values)}.`);
|
|
2034
|
-
}
|
|
2035
|
-
if (n.open) o.golomb(k, 0);
|
|
2036
|
-
else o.bits(k, width);
|
|
2037
|
-
},
|
|
2038
|
-
r(i, x) {
|
|
2039
|
-
const s = i.at;
|
|
2040
|
-
const k = n.open ? i.golomb(0) : i.bits(width);
|
|
2041
|
-
if (str && k === limit) {
|
|
2042
|
-
if (x.trace) meta(x, "other", s, i, k, "not in the list: written out");
|
|
2043
|
-
return str.r(i, x);
|
|
2044
|
-
}
|
|
2045
|
-
if (k >= n.values.length) fail(`Enum index ${k} is not a value this reader knows (it knows ${n.values.length}: data from a newer schema?).`);
|
|
2046
|
-
return n.values[k];
|
|
2047
|
-
}
|
|
2048
|
-
};
|
|
2049
|
-
}
|
|
2050
|
-
case "string": {
|
|
2051
|
-
const lw = n.max ? bitsFor(n.max + 1) : -1;
|
|
2052
|
-
const HEX = /^0x(?:[0-9a-f]{2})+$/;
|
|
2053
|
-
return {
|
|
2054
|
-
node: n,
|
|
2055
|
-
w(o, v, x) {
|
|
2056
|
-
if (typeof v !== "string") fail(`${describe(v)} is not a string.`);
|
|
2057
|
-
const s = v;
|
|
2058
|
-
const text = x.text;
|
|
2059
|
-
if (n.packHex) {
|
|
2060
|
-
const packed = HEX.test(s);
|
|
2061
|
-
o.bool(packed);
|
|
2062
|
-
if (packed) {
|
|
2063
|
-
const len2 = (s.length - 2) / 2;
|
|
2064
|
-
o.golomb(len2 - 1, 0);
|
|
2065
|
-
for (let k = 0; k < len2; k += 1) text.bits(parseInt(s.slice(2 + k * 2, 4 + k * 2), 16), 8);
|
|
2066
|
-
return;
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
if (!wellFormed(s)) fail("The string has a lone surrogate (not UTF-8 encodable).");
|
|
2070
|
-
const b = utf8(s);
|
|
2071
|
-
if (n.max && b.length > n.max) fail(`The string is ${b.length} bytes; the max is ${n.max}.`);
|
|
2072
|
-
if (lw >= 0) o.bits(b.length, lw);
|
|
2073
|
-
else o.golomb(b.length, 0);
|
|
2074
|
-
text.bytes(b);
|
|
2075
|
-
},
|
|
2076
|
-
r(i, x) {
|
|
2077
|
-
const tr = x.tr;
|
|
2078
|
-
if (n.packHex) {
|
|
2079
|
-
const s0 = i.at;
|
|
2080
|
-
const packed = i.bool();
|
|
2081
|
-
if (x.trace) meta(x, "hex", s0, i, packed, packed ? "0x hex, packed as bytes" : "text");
|
|
2082
|
-
if (packed) {
|
|
2083
|
-
const s1 = i.at;
|
|
2084
|
-
const len3 = i.golomb(0) + 1;
|
|
2085
|
-
if (x.trace) meta(x, "length", s1, i, len3, `${len3} bytes`);
|
|
2086
|
-
const t02 = tr.at;
|
|
2087
|
-
let out2 = "0x";
|
|
2088
|
-
for (let k = 0; k < len3; k += 1) out2 += tr.bits(8).toString(16).padStart(2, "0");
|
|
2089
|
-
if (x.trace) x.trace.meta("text", t02, len3 * 8, out2, `${len3} bytes in the text section`);
|
|
2090
|
-
return out2;
|
|
2091
|
-
}
|
|
2092
|
-
}
|
|
2093
|
-
const s = i.at;
|
|
2094
|
-
const len2 = lw >= 0 ? i.bits(lw) : i.golomb(0);
|
|
2095
|
-
if (x.trace) meta(x, "length", s, i, len2, `${len2} bytes`);
|
|
2096
|
-
if (n.max && len2 > n.max) fail(`The string is ${len2} bytes; the max is ${n.max}.`);
|
|
2097
|
-
const t0 = tr.at;
|
|
2098
|
-
const out = fromUtf8(tr, len2);
|
|
2099
|
-
if (x.trace) x.trace.meta("text", t0, len2 * 8, out, `${len2} bytes in the text section`);
|
|
2100
|
-
return out;
|
|
2101
|
-
}
|
|
2102
|
-
};
|
|
2103
|
-
}
|
|
2104
|
-
case "ref": {
|
|
2105
|
-
const text = compile({ kind: "string", max: 0, packHex: n.packHex }, []);
|
|
2106
|
-
return {
|
|
2107
|
-
node: n,
|
|
2108
|
-
w(o, v, x) {
|
|
2109
|
-
if (typeof v !== "string") fail(`${describe(v)} is not a string (ref "${n.table}").`);
|
|
2110
|
-
const s = v;
|
|
2111
|
-
const t = x.tables.table(n.table);
|
|
2112
|
-
const k = t.index.get(s);
|
|
2113
|
-
const size3 = t.list.length;
|
|
2114
|
-
if (k !== void 0) {
|
|
2115
|
-
o.bits(k, bitsFor(size3 + 1));
|
|
2116
|
-
return;
|
|
2117
|
-
}
|
|
2118
|
-
o.bits(size3, bitsFor(size3 + 1));
|
|
2119
|
-
text.w(o, s, x);
|
|
2120
|
-
t.list.push(s);
|
|
2121
|
-
t.index.set(s, size3);
|
|
2122
|
-
},
|
|
2123
|
-
r(i, x) {
|
|
2124
|
-
const t = x.tables.table(n.table);
|
|
2125
|
-
const size3 = t.list.length;
|
|
2126
|
-
const s0 = i.at;
|
|
2127
|
-
const k = i.bits(bitsFor(size3 + 1));
|
|
2128
|
-
if (k < size3) {
|
|
2129
|
-
if (x.trace) meta(x, "index", s0, i, k, `table ${n.table} #${k} of ${size3}`);
|
|
2130
|
-
return t.list[k];
|
|
2131
|
-
}
|
|
2132
|
-
if (k > size3) fail(`Table ${n.table} has ${size3} strings; the data names #${k}.`);
|
|
2133
|
-
if (x.trace) meta(x, "index", s0, i, k, `new: table ${n.table} #${k}`);
|
|
2134
|
-
const s = text.r(i, x);
|
|
2135
|
-
if (t.index.has(s)) fail(`${JSON.stringify(s)} written again in full (not canonical: it's table ${n.table} #${t.index.get(s)}).`);
|
|
2136
|
-
t.list.push(s);
|
|
2137
|
-
t.index.set(s, size3);
|
|
2138
|
-
return s;
|
|
2139
|
-
}
|
|
2140
|
-
};
|
|
2141
|
-
}
|
|
2142
|
-
case "bytes":
|
|
2143
|
-
return {
|
|
2144
|
-
node: n,
|
|
2145
|
-
w(o, v) {
|
|
2146
|
-
if (!(v instanceof Uint8Array)) fail(`${describe(v)} is not a Uint8Array.`);
|
|
2147
|
-
const b = v;
|
|
2148
|
-
if (n.length) {
|
|
2149
|
-
if (b.length !== n.length) fail(`${b.length} bytes; this is exactly ${n.length}.`);
|
|
2150
|
-
} else o.golomb(b.length, 0);
|
|
2151
|
-
o.bytes(b);
|
|
2152
|
-
},
|
|
2153
|
-
r(i, x) {
|
|
2154
|
-
const s = i.at;
|
|
2155
|
-
const len2 = n.length || i.golomb(0);
|
|
2156
|
-
if (!n.length) {
|
|
2157
|
-
if (x.trace) meta(x, "length", s, i, len2, `${len2} bytes`);
|
|
2158
|
-
}
|
|
2159
|
-
return i.bytes(len2);
|
|
2160
|
-
}
|
|
2161
|
-
};
|
|
2162
|
-
case "hex": {
|
|
2163
|
-
const re = /^0x(?:[0-9a-f]{2})*$/;
|
|
2164
|
-
return {
|
|
2165
|
-
node: n,
|
|
2166
|
-
w(o, v) {
|
|
2167
|
-
if (typeof v !== "string" || !re.test(v)) fail(`${describe(v)} is not "0x" + lower-case hex byte pairs.`);
|
|
2168
|
-
const s = v;
|
|
2169
|
-
const len2 = (s.length - 2) / 2;
|
|
2170
|
-
if (n.bytes) {
|
|
2171
|
-
if (len2 !== n.bytes) fail(`${len2} bytes of hex; this is exactly ${n.bytes}.`);
|
|
2172
|
-
} else o.golomb(len2, 0);
|
|
2173
|
-
for (let k = 0; k < len2; k += 1) o.bits(parseInt(s.slice(2 + k * 2, 4 + k * 2), 16), 8);
|
|
2174
|
-
},
|
|
2175
|
-
r(i, x) {
|
|
2176
|
-
const s = i.at;
|
|
2177
|
-
const len2 = n.bytes || i.golomb(0);
|
|
2178
|
-
if (!n.bytes) {
|
|
2179
|
-
if (x.trace) meta(x, "length", s, i, len2, `${len2} bytes`);
|
|
2180
|
-
}
|
|
2181
|
-
let out = "0x";
|
|
2182
|
-
for (let k = 0; k < len2; k += 1) out += i.bits(8).toString(16).padStart(2, "0");
|
|
2183
|
-
return out;
|
|
2184
|
-
}
|
|
2185
|
-
};
|
|
2186
|
-
}
|
|
2187
|
-
case "const":
|
|
2188
|
-
return {
|
|
2189
|
-
node: n,
|
|
2190
|
-
w(_o, v) {
|
|
2191
|
-
if (!same(v, n.value)) fail(`${describe(v)} is not the constant ${JSON.stringify(n.value)}.`);
|
|
2192
|
-
},
|
|
2193
|
-
r: () => structuredClone(n.value)
|
|
2194
|
-
};
|
|
2195
|
-
case "dyn":
|
|
2196
|
-
return dynCodec(n);
|
|
2197
|
-
case "array": {
|
|
2198
|
-
const of = compile(n.of, recs);
|
|
2199
|
-
const lw = n.max ? bitsFor(n.max + 1) : -1;
|
|
2200
|
-
return {
|
|
2201
|
-
node: n,
|
|
2202
|
-
w(o, v, x) {
|
|
2203
|
-
if (!Array.isArray(v) && !(ArrayBuffer.isView(v) && !(v instanceof DataView))) fail(`${describe(v)} is not an array.`);
|
|
2204
|
-
const a = v;
|
|
2205
|
-
if (n.length) {
|
|
2206
|
-
if (a.length !== n.length) fail(`${a.length} items; this is exactly ${n.length}.`);
|
|
2207
|
-
} else if (lw >= 0) {
|
|
2208
|
-
if (a.length > n.max) fail(`${a.length} items; the max is ${n.max}.`);
|
|
2209
|
-
o.bits(a.length, lw);
|
|
2210
|
-
} else o.golomb(a.length, 0);
|
|
2211
|
-
let k = 0;
|
|
2212
|
-
try {
|
|
2213
|
-
for (; k < a.length; k += 1) of.w(o, a[k], x);
|
|
2214
|
-
} catch (e) {
|
|
2215
|
-
throw under(e, k, null);
|
|
2216
|
-
}
|
|
2217
|
-
},
|
|
2218
|
-
r(i, x) {
|
|
2219
|
-
const s = i.at;
|
|
2220
|
-
const len2 = n.length || (lw >= 0 ? i.bits(lw) : i.golomb(0));
|
|
2221
|
-
if (!n.length) {
|
|
2222
|
-
if (x.trace) meta(x, "length", s, i, len2, `${len2} items`);
|
|
2223
|
-
}
|
|
2224
|
-
if (n.max && len2 > n.max) fail(`${len2} items; the max is ${n.max}.`);
|
|
2225
|
-
if (len2 > 2 ** 28) fail(`${len2} items: corrupt data.`);
|
|
2226
|
-
const out = new Array(len2);
|
|
2227
|
-
if (x.trace !== null) {
|
|
2228
|
-
for (let k2 = 0; k2 < len2; k2 += 1) out[k2] = rd(of, i, x, k2);
|
|
2229
|
-
return out;
|
|
2230
|
-
}
|
|
2231
|
-
let k = 0;
|
|
2232
|
-
try {
|
|
2233
|
-
for (; k < len2; k += 1) out[k] = of.r(i, x);
|
|
2234
|
-
} catch (e) {
|
|
2235
|
-
throw under(e, k, null);
|
|
2236
|
-
}
|
|
2237
|
-
return out;
|
|
2238
|
-
}
|
|
2239
|
-
};
|
|
2240
|
-
}
|
|
2241
|
-
case "grow": {
|
|
2242
|
-
const b = n.base;
|
|
2243
|
-
const item = compile(b.of, recs);
|
|
2244
|
-
const next = compile(n.of, recs);
|
|
2245
|
-
const lw = bitsFor(b.max + 1);
|
|
2246
|
-
const spare = 2 ** lw - 1;
|
|
2247
|
-
const above = recs.map((c) => c.node);
|
|
2248
|
-
return {
|
|
2249
|
-
node: n,
|
|
2250
|
-
w(o, v, x) {
|
|
2251
|
-
if (!holds(b, v, above)) {
|
|
2252
|
-
o.bits(spare, lw);
|
|
2253
|
-
next.w(o, v, x);
|
|
2254
|
-
return;
|
|
2255
|
-
}
|
|
2256
|
-
if (!Array.isArray(v) && !(ArrayBuffer.isView(v) && !(v instanceof DataView))) fail(`${describe(v)} is not an array.`);
|
|
2257
|
-
const a = v;
|
|
2258
|
-
o.bits(a.length, lw);
|
|
2259
|
-
let k = 0;
|
|
2260
|
-
try {
|
|
2261
|
-
for (; k < a.length; k += 1) item.w(o, a[k], x);
|
|
2262
|
-
} catch (e) {
|
|
2263
|
-
throw under(e, k, null);
|
|
2264
|
-
}
|
|
2265
|
-
},
|
|
2266
|
-
r(i, x) {
|
|
2267
|
-
const s = i.at;
|
|
2268
|
-
const len2 = i.bits(lw);
|
|
2269
|
-
if (len2 === spare) {
|
|
2270
|
-
if (x.trace) meta(x, "grown", s, i, len2, "the spare length code: the grown layout follows");
|
|
2271
|
-
const v = next.r(i, x);
|
|
2272
|
-
if (holds(b, v, above)) fail("Written in the grown layout, but the original layout holds it (not canonical).");
|
|
2273
|
-
return v;
|
|
2274
|
-
}
|
|
2275
|
-
if (x.trace) meta(x, "length", s, i, len2, `${len2} items`);
|
|
2276
|
-
if (len2 > b.max) fail(`${len2} items; the max is ${b.max}.`);
|
|
2277
|
-
const out = new Array(len2);
|
|
2278
|
-
if (x.trace !== null) {
|
|
2279
|
-
for (let k2 = 0; k2 < len2; k2 += 1) out[k2] = rd(item, i, x, k2);
|
|
2280
|
-
return out;
|
|
2281
|
-
}
|
|
2282
|
-
let k = 0;
|
|
2283
|
-
try {
|
|
2284
|
-
for (; k < len2; k += 1) out[k] = item.r(i, x);
|
|
2285
|
-
} catch (e) {
|
|
2286
|
-
throw under(e, k, null);
|
|
2287
|
-
}
|
|
2288
|
-
return out;
|
|
2289
|
-
}
|
|
2290
|
-
};
|
|
2291
|
-
}
|
|
2292
|
-
case "optional":
|
|
2293
|
-
case "nullable": {
|
|
2294
|
-
const of = compile(n.of, recs);
|
|
2295
|
-
const none = n.kind === "optional" ? void 0 : null;
|
|
2296
|
-
return {
|
|
2297
|
-
node: n,
|
|
2298
|
-
w(o, v, x) {
|
|
2299
|
-
const has = n.kind === "optional" ? v !== void 0 : v !== null;
|
|
2300
|
-
if (n.kind === "nullable" && v === void 0 && n.of.kind !== "optional" && n.of.kind !== "default") fail("undefined is not a value here (nullable: give null).");
|
|
2301
|
-
o.bool(has);
|
|
2302
|
-
if (has) of.w(o, v, x);
|
|
2303
|
-
},
|
|
2304
|
-
r(i, x) {
|
|
2305
|
-
const s = i.at;
|
|
2306
|
-
const has = i.bool();
|
|
2307
|
-
if (x.trace) meta(x, "present", s, i, has, has ? "present" : n.kind === "optional" ? "absent" : "null");
|
|
2308
|
-
return has ? of.r(i, x) : none;
|
|
2309
|
-
}
|
|
2310
|
-
};
|
|
2311
|
-
}
|
|
2312
|
-
case "default": {
|
|
2313
|
-
const of = compile(n.of, recs);
|
|
2314
|
-
try {
|
|
2315
|
-
of.w(new BitWriter(16), n.value, fresh());
|
|
2316
|
-
} catch (e) {
|
|
2317
|
-
throw new SchemaError(`withDefault(): the default isn't a value of its type: ${e.message}`);
|
|
2318
|
-
}
|
|
2319
|
-
return {
|
|
2320
|
-
node: n,
|
|
2321
|
-
w(o, v, x) {
|
|
2322
|
-
if (v === void 0 || same(v, n.value)) {
|
|
2323
|
-
o.bool(false);
|
|
2324
|
-
return;
|
|
2325
|
-
}
|
|
2326
|
-
o.bool(true);
|
|
2327
|
-
of.w(o, v, x);
|
|
2328
|
-
},
|
|
2329
|
-
r(i, x) {
|
|
2330
|
-
const s = i.at;
|
|
2331
|
-
const given = i.bool();
|
|
2332
|
-
if (x.trace) meta(x, "given", s, i, given, given ? "not the default" : "the default");
|
|
2333
|
-
return given ? of.r(i, x) : structuredClone(n.value);
|
|
2334
|
-
}
|
|
2335
|
-
};
|
|
2336
|
-
}
|
|
2337
|
-
case "struct":
|
|
2338
|
-
return structCodec(n.fields, n.open, n.ext, recs, n, null);
|
|
2339
|
-
case "tuple": {
|
|
2340
|
-
const items = n.items.map((it) => compile(it, recs));
|
|
2341
|
-
return {
|
|
2342
|
-
node: n,
|
|
2343
|
-
w(o, v, x) {
|
|
2344
|
-
if (!Array.isArray(v)) fail(`${describe(v)} is not a tuple (an array of ${items.length}).`);
|
|
2345
|
-
const a = v;
|
|
2346
|
-
if (a.length !== items.length) fail(`A tuple of ${items.length}; got ${a.length} items.`);
|
|
2347
|
-
for (let k = 0; k < items.length; k += 1) wr(items[k], o, a[k], x, k);
|
|
2348
|
-
},
|
|
2349
|
-
r(i, x) {
|
|
2350
|
-
const out = new Array(items.length);
|
|
2351
|
-
for (let k = 0; k < items.length; k += 1) out[k] = rd(items[k], i, x, k);
|
|
2352
|
-
return out;
|
|
2353
|
-
}
|
|
2354
|
-
};
|
|
2355
|
-
}
|
|
2356
|
-
case "union": {
|
|
2357
|
-
const variants = n.variants.map((f) => {
|
|
2358
|
-
const s = f.type;
|
|
2359
|
-
return { name: f.name, c: structCodec(s.fields, s.open, s.ext, recs, s, n.tag) };
|
|
2360
|
-
});
|
|
2361
|
-
const index = new Map(variants.map((v, k) => [v.name, k]));
|
|
2362
|
-
const width = bitsFor(n.capacity || variants.length);
|
|
2363
|
-
return {
|
|
2364
|
-
node: n,
|
|
2365
|
-
w(o, v, x) {
|
|
2366
|
-
if (typeof v !== "object" || v === null) fail(`${describe(v)} is not an object (a union by "${n.tag}").`);
|
|
2367
|
-
const tag = v[n.tag];
|
|
2368
|
-
const k = typeof tag === "string" ? index.get(tag) : void 0;
|
|
2369
|
-
if (k === void 0) fail(`${n.tag} ${describe(tag)} is not one of ${variants.map((x2) => x2.name).join(", ")}.`);
|
|
2370
|
-
o.bits(k, width);
|
|
2371
|
-
wr(variants[k].c, o, v, x, `${n.tag}(${String(tag)})`);
|
|
2372
|
-
},
|
|
2373
|
-
r(i, x) {
|
|
2374
|
-
const s = i.at;
|
|
2375
|
-
const k = i.bits(width);
|
|
2376
|
-
const vt = variants[k];
|
|
2377
|
-
if (!vt) fail(`Union tag ${k} is not a variant this reader knows (it knows ${variants.length}: data from a newer schema?).`);
|
|
2378
|
-
if (x.trace) meta(x, n.tag, s, i, vt.name, `variant ${k}: ${vt.name}`);
|
|
2379
|
-
const body = rd(vt.c, i, x, `${n.tag}(${vt.name})`);
|
|
2380
|
-
const out = { [n.tag]: vt.name };
|
|
2381
|
-
for (const key in body) put(out, key, body[key]);
|
|
2382
|
-
return out;
|
|
2383
|
-
}
|
|
2384
|
-
};
|
|
2385
|
-
}
|
|
2386
|
-
case "alt": {
|
|
2387
|
-
const branches = n.of.map((b) => ({ cat: categoryOf(b), c: compile(b, recs) }));
|
|
2388
|
-
const width = bitsFor(branches.length);
|
|
2389
|
-
return {
|
|
2390
|
-
node: n,
|
|
2391
|
-
w(o, v, x) {
|
|
2392
|
-
const cat = valueCategory(v);
|
|
2393
|
-
const k = branches.findIndex((b) => b.cat === cat);
|
|
2394
|
-
if (k < 0) fail(`${describe(v)} (${cat}) matches none of ${branches.map((b) => b.cat).join(", ")}.`);
|
|
2395
|
-
o.bits(k, width);
|
|
2396
|
-
wr(branches[k].c, o, v, x, `(${cat})`);
|
|
2397
|
-
},
|
|
2398
|
-
r(i, x) {
|
|
2399
|
-
const s = i.at;
|
|
2400
|
-
const k = i.bits(width);
|
|
2401
|
-
const b = branches[k];
|
|
2402
|
-
if (!b) fail(`Alt branch ${k} doesn't exist.`);
|
|
2403
|
-
if (x.trace) meta(x, "branch", s, i, b.cat, `branch ${k}: ${b.cat}`);
|
|
2404
|
-
return rd(b.c, i, x, `(${b.cat})`);
|
|
2405
|
-
}
|
|
2406
|
-
};
|
|
2407
|
-
}
|
|
2408
|
-
case "map": {
|
|
2409
|
-
const kc = compile(n.key, recs);
|
|
2410
|
-
const vc = compile(n.value, recs);
|
|
2411
|
-
return {
|
|
2412
|
-
node: n,
|
|
2413
|
-
w(o, v, x) {
|
|
2414
|
-
if (typeof v !== "object" || v === null || Array.isArray(v)) fail(`${describe(v)} is not a record.`);
|
|
2415
|
-
const rec = v;
|
|
2416
|
-
const keys = Object.keys(rec).filter((k) => rec[k] !== void 0);
|
|
2417
|
-
if (n.order === "sorted") keys.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
2418
|
-
o.golomb(keys.length, 0);
|
|
2419
|
-
for (const k of keys) {
|
|
2420
|
-
wr(kc, o, k, x, `${k}(key)`);
|
|
2421
|
-
wr(vc, o, rec[k], x, k);
|
|
2422
|
-
}
|
|
2423
|
-
},
|
|
2424
|
-
r(i, x) {
|
|
2425
|
-
const s = i.at;
|
|
2426
|
-
const count = i.golomb(0);
|
|
2427
|
-
if (x.trace) meta(x, "count", s, i, count, `${count} entries`);
|
|
2428
|
-
const out = {};
|
|
2429
|
-
let last = null;
|
|
2430
|
-
for (let k = 0; k < count; k += 1) {
|
|
2431
|
-
const key = rd(kc, i, x, `#${k}(key)`);
|
|
2432
|
-
if (Object.hasOwn(out, key)) fail(`The key ${JSON.stringify(key)} is in the map twice.`);
|
|
2433
|
-
if (n.order === "sorted" && last !== null && !(last < key)) fail(`Map keys out of order (${JSON.stringify(last)} before ${JSON.stringify(key)}): not canonical.`);
|
|
2434
|
-
last = key;
|
|
2435
|
-
put(out, key, rd(vc, i, x, key));
|
|
2436
|
-
}
|
|
2437
|
-
return out;
|
|
2438
|
-
}
|
|
2439
|
-
};
|
|
2440
|
-
}
|
|
2441
|
-
case "delta": {
|
|
2442
|
-
const first = compile(n.of, recs);
|
|
2443
|
-
const of = n.of;
|
|
2444
|
-
const g = of.kind === "fixed" ? gridOf(of) : null;
|
|
2445
|
-
const toUnits = g ? (v) => g.units(v) : (v) => v;
|
|
2446
|
-
const fromUnits = g ? (k) => {
|
|
2447
|
-
const v = g.value(k);
|
|
2448
|
-
return v === 0 ? 0 : v;
|
|
2449
|
-
} : (k) => k;
|
|
2450
|
-
const lo = g ? g.lo : of.kind === "uint" || of.kind === "varuint" ? 0 : -Infinity;
|
|
2451
|
-
const hi = g ? g.hi : of.kind === "uint" ? 2 ** of.bits - 1 : of.kind === "int" ? 2 ** (of.bits - 1) - 1 : Infinity;
|
|
2452
|
-
const lo2 = of.kind === "int" ? -(2 ** (of.bits - 1)) : lo;
|
|
2453
|
-
return {
|
|
2454
|
-
node: n,
|
|
2455
|
-
w(o, v, x) {
|
|
2456
|
-
if (!Array.isArray(v) && !ArrayBuffer.isView(v)) fail(`${describe(v)} is not an array.`);
|
|
2457
|
-
const a = v;
|
|
2458
|
-
o.golomb(a.length, 0);
|
|
2459
|
-
if (!a.length) return;
|
|
2460
|
-
wr(first, o, a[0], x, 0);
|
|
2461
|
-
let prev = toUnits(a[0]);
|
|
2462
|
-
for (let k = 1; k < a.length; k += 1) {
|
|
2463
|
-
const e = a[k];
|
|
2464
|
-
SCRATCH.reset();
|
|
2465
|
-
try {
|
|
2466
|
-
first.w(SCRATCH, e, x);
|
|
2467
|
-
} catch (err) {
|
|
2468
|
-
throw under(err, k, null);
|
|
2469
|
-
}
|
|
2470
|
-
const u2 = toUnits(e);
|
|
2471
|
-
o.golomb(zig(u2 - prev), n.k);
|
|
2472
|
-
prev = u2;
|
|
2473
|
-
}
|
|
2474
|
-
},
|
|
2475
|
-
r(i, x) {
|
|
2476
|
-
const s = i.at;
|
|
2477
|
-
const len2 = i.golomb(0);
|
|
2478
|
-
if (x.trace) meta(x, "length", s, i, len2, `${len2} items`);
|
|
2479
|
-
const out = new Array(len2);
|
|
2480
|
-
if (!len2) return out;
|
|
2481
|
-
out[0] = rd(first, i, x, 0);
|
|
2482
|
-
let prev = toUnits(out[0]);
|
|
2483
|
-
for (let k = 1; k < len2; k += 1) {
|
|
2484
|
-
const s1 = i.at;
|
|
2485
|
-
const d = unzig(i.golomb(n.k));
|
|
2486
|
-
prev += d;
|
|
2487
|
-
if (prev < lo2 || prev > hi) throw under(new CodecError(`A delta walks out of range (${prev}).`), k, s1);
|
|
2488
|
-
out[k] = fromUnits(prev);
|
|
2489
|
-
if (x.trace) meta(x, `[${k}]`, s1, i, out[k], `${d >= 0 ? "+" : ""}${d}`);
|
|
2490
|
-
}
|
|
2491
|
-
return out;
|
|
2492
|
-
}
|
|
2493
|
-
};
|
|
2494
|
-
}
|
|
2495
|
-
case "runs": {
|
|
2496
|
-
const of = compile(n.of, recs);
|
|
2497
|
-
return {
|
|
2498
|
-
node: n,
|
|
2499
|
-
w(o, v, x) {
|
|
2500
|
-
if (!Array.isArray(v) && !ArrayBuffer.isView(v)) fail(`${describe(v)} is not an array.`);
|
|
2501
|
-
const a = v;
|
|
2502
|
-
o.golomb(a.length, 0);
|
|
2503
|
-
let k = 0;
|
|
2504
|
-
while (k < a.length) {
|
|
2505
|
-
let j = k + 1;
|
|
2506
|
-
while (j < a.length && same(a[j], a[k])) j += 1;
|
|
2507
|
-
wr(of, o, a[k], x, k);
|
|
2508
|
-
o.golomb(j - k - 1, 0);
|
|
2509
|
-
k = j;
|
|
2510
|
-
}
|
|
2511
|
-
},
|
|
2512
|
-
r(i, x) {
|
|
2513
|
-
const s = i.at;
|
|
2514
|
-
const len2 = i.golomb(0);
|
|
2515
|
-
if (x.trace) meta(x, "length", s, i, len2, `${len2} items`);
|
|
2516
|
-
const out = new Array(len2);
|
|
2517
|
-
let k = 0;
|
|
2518
|
-
let prev = void 0;
|
|
2519
|
-
while (k < len2) {
|
|
2520
|
-
const v = rd(of, i, x, k);
|
|
2521
|
-
if (k > 0 && same(v, prev)) fail(`Two runs of the same value at ${k}: not canonical.`);
|
|
2522
|
-
const s1 = i.at;
|
|
2523
|
-
const run = i.golomb(0) + 1;
|
|
2524
|
-
if (x.trace) meta(x, "run", s1, i, run, `x${run}`);
|
|
2525
|
-
if (k + run > len2) fail(`A run of ${run} overruns the ${len2} items.`);
|
|
2526
|
-
for (let j = 0; j < run; j += 1) out[k + j] = j === 0 ? v : structuredClone(v);
|
|
2527
|
-
k += run;
|
|
2528
|
-
prev = v;
|
|
2529
|
-
}
|
|
2530
|
-
return out;
|
|
2531
|
-
}
|
|
2532
|
-
};
|
|
2533
|
-
}
|
|
2534
|
-
case "lz": {
|
|
2535
|
-
const of = compile(n.of, recs);
|
|
2536
|
-
const MIN = n.min;
|
|
2537
|
-
const WINDOW = 1 << 16;
|
|
2538
|
-
const CHAIN = 48;
|
|
2539
|
-
return {
|
|
2540
|
-
node: n,
|
|
2541
|
-
w(o, v, x) {
|
|
2542
|
-
if (!Array.isArray(v) && !ArrayBuffer.isView(v)) fail(`${describe(v)} is not an array.`);
|
|
2543
|
-
const a = v;
|
|
2544
|
-
const L = a.length;
|
|
2545
|
-
o.golomb(L, 0);
|
|
2546
|
-
const heads = /* @__PURE__ */ new Map();
|
|
2547
|
-
const keyAt = (p) => {
|
|
2548
|
-
let key = "";
|
|
2549
|
-
for (let q = 0; q < MIN; q += 1) key += `${typeof a[p + q] === "string" ? "s" : ""}${String(a[p + q])}\0`;
|
|
2550
|
-
return key;
|
|
2551
|
-
};
|
|
2552
|
-
const insert = (p) => {
|
|
2553
|
-
if (p + MIN > L) return;
|
|
2554
|
-
const key = keyAt(p);
|
|
2555
|
-
let c = heads.get(key);
|
|
2556
|
-
if (!c) {
|
|
2557
|
-
c = [];
|
|
2558
|
-
heads.set(key, c);
|
|
2559
|
-
}
|
|
2560
|
-
c.push(p);
|
|
2561
|
-
if (c.length > CHAIN * 2) c.splice(0, c.length - CHAIN);
|
|
2562
|
-
};
|
|
2563
|
-
let i = 0;
|
|
2564
|
-
while (i < L) {
|
|
2565
|
-
let bestLen = 0, bestDist = 0;
|
|
2566
|
-
if (i + MIN <= L) {
|
|
2567
|
-
const c = heads.get(keyAt(i));
|
|
2568
|
-
if (c) for (let q = c.length - 1, tries = 0; q >= 0 && tries < CHAIN; q -= 1, tries += 1) {
|
|
2569
|
-
const j = c[q];
|
|
2570
|
-
if (i - j > WINDOW) break;
|
|
2571
|
-
let len2 = 0;
|
|
2572
|
-
while (i + len2 < L && a[j + len2] === a[i + len2]) len2 += 1;
|
|
2573
|
-
if (len2 > bestLen) {
|
|
2574
|
-
bestLen = len2;
|
|
2575
|
-
bestDist = i - j;
|
|
2576
|
-
if (i + len2 === L) break;
|
|
2577
|
-
}
|
|
2578
|
-
}
|
|
2579
|
-
}
|
|
2580
|
-
if (bestLen >= MIN) {
|
|
2581
|
-
o.bool(true);
|
|
2582
|
-
o.golomb(bestDist - 1, 0);
|
|
2583
|
-
o.golomb(bestLen - MIN, 0);
|
|
2584
|
-
for (let q = 0; q < bestLen; q += 1) insert(i + q);
|
|
2585
|
-
i += bestLen;
|
|
2586
|
-
} else {
|
|
2587
|
-
o.bool(false);
|
|
2588
|
-
wr(of, o, a[i], x, i);
|
|
2589
|
-
insert(i);
|
|
2590
|
-
i += 1;
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2593
|
-
},
|
|
2594
|
-
r(i, x) {
|
|
2595
|
-
const s = i.at;
|
|
2596
|
-
const L = i.golomb(0);
|
|
2597
|
-
if (x.trace) meta(x, "length", s, i, L, `${L} items`);
|
|
2598
|
-
const out = new Array(L);
|
|
2599
|
-
let k = 0;
|
|
2600
|
-
while (k < L) {
|
|
2601
|
-
const s1 = i.at;
|
|
2602
|
-
if (i.bool()) {
|
|
2603
|
-
const dist = i.golomb(0) + 1;
|
|
2604
|
-
const len2 = i.golomb(0) + MIN;
|
|
2605
|
-
if (x.trace) meta(x, "copy", s1, i, len2, `${len2} items from ${dist} back`);
|
|
2606
|
-
if (dist > k) fail(`A copy from ${dist} back at item ${k} reaches before the start.`);
|
|
2607
|
-
if (k + len2 > L) fail(`A copy of ${len2} at item ${k} overruns the ${L} items.`);
|
|
2608
|
-
for (let q = 0; q < len2; q += 1) out[k + q] = out[k + q - dist];
|
|
2609
|
-
k += len2;
|
|
2610
|
-
} else {
|
|
2611
|
-
if (x.trace) meta(x, "literal", s1, i, null, "a literal item");
|
|
2612
|
-
out[k] = rd(of, i, x, k);
|
|
2613
|
-
k += 1;
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
return out;
|
|
2617
|
-
}
|
|
2618
|
-
};
|
|
2619
|
-
}
|
|
2620
|
-
case "planes": {
|
|
2621
|
-
const lim = 2 ** n.bits;
|
|
2622
|
-
return {
|
|
2623
|
-
node: n,
|
|
2624
|
-
w(o, v) {
|
|
2625
|
-
if (!Array.isArray(v) && !ArrayBuffer.isView(v)) fail(`${describe(v)} is not an array.`);
|
|
2626
|
-
const a = v;
|
|
2627
|
-
for (let k = 0; k < a.length; k += 1) {
|
|
2628
|
-
const e = a[k];
|
|
2629
|
-
if (typeof e !== "number" || !Number.isInteger(e) || e < 0 || e >= lim) throw under(new CodecError(`${describe(e)} is outside planes(${n.bits})'s 0..${lim - 1}.`), k, null);
|
|
2630
|
-
}
|
|
2631
|
-
o.golomb(a.length, 0);
|
|
2632
|
-
for (let b = n.bits - 1; b >= 0; b -= 1) {
|
|
2633
|
-
const m = 2 ** b;
|
|
2634
|
-
for (let k = 0; k < a.length; k += 1) o.bits(Math.floor(a[k] / m) % 2, 1);
|
|
2635
|
-
}
|
|
2636
|
-
},
|
|
2637
|
-
r(i, x) {
|
|
2638
|
-
const s = i.at;
|
|
2639
|
-
const len2 = i.golomb(0);
|
|
2640
|
-
if (x.trace) meta(x, "length", s, i, len2, `${len2} items`);
|
|
2641
|
-
const out = new Array(len2).fill(0);
|
|
2642
|
-
for (let b = n.bits - 1; b >= 0; b -= 1) {
|
|
2643
|
-
const s1 = i.at;
|
|
2644
|
-
const m = 2 ** b;
|
|
2645
|
-
for (let k = 0; k < len2; k += 1) if (i.bool()) out[k] = out[k] + m;
|
|
2646
|
-
if (x.trace) meta(x, `plane ${b}`, s1, i, null, `bit ${b} of every value`);
|
|
2647
|
-
}
|
|
2648
|
-
return out;
|
|
2649
|
-
}
|
|
2650
|
-
};
|
|
2651
|
-
}
|
|
2652
|
-
case "named": {
|
|
2653
|
-
const of = compile(n.of, recs);
|
|
2654
|
-
return { node: n, w: (o, v, x) => of.w(o, v, x), r: (i, x) => of.r(i, x) };
|
|
2655
|
-
}
|
|
2656
|
-
case "rec": {
|
|
2657
|
-
const fwd = { c: null };
|
|
2658
|
-
const self = { node: n, w: (o, v, x) => fwd.c.w(o, v, x), r: (i, x) => fwd.c.r(i, x) };
|
|
2659
|
-
fwd.c = compile(n.of, [...recs, self]);
|
|
2660
|
-
return self;
|
|
2661
|
-
}
|
|
2662
|
-
case "self": {
|
|
2663
|
-
const target = recs[recs.length - 1 - n.depth];
|
|
2664
|
-
if (!target) throw new SchemaError(`A self node (depth ${n.depth}) outside its recursive().`);
|
|
2665
|
-
return { node: n, w: (o, v, x) => target.w(o, v, x), r: (i, x) => target.r(i, x) };
|
|
2666
|
-
}
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2669
|
-
function holds(n, v, recs = []) {
|
|
2670
|
-
const fields = (fs, ext, tag) => {
|
|
2671
|
-
if (typeof v !== "object" || v === null || Array.isArray(v)) return true;
|
|
2672
|
-
const rec = v;
|
|
2673
|
-
const all = [...fs, ...ext.flat()];
|
|
2674
|
-
for (const key in rec) if (rec[key] !== void 0 && key !== tag && !all.some((f) => f.name === key)) return false;
|
|
2675
|
-
return all.every((f) => rec[f.name] === void 0 || holds(f.type, rec[f.name], recs));
|
|
2676
|
-
};
|
|
2677
|
-
switch (n.kind) {
|
|
2678
|
-
case "named":
|
|
2679
|
-
case "default":
|
|
2680
|
-
case "optional":
|
|
2681
|
-
return v === void 0 || holds(n.of, v, recs);
|
|
2682
|
-
case "nullable":
|
|
2683
|
-
return v === void 0 || v === null || holds(n.of, v, recs);
|
|
2684
|
-
case "rec":
|
|
2685
|
-
return holds(n.of, v, [...recs, n]);
|
|
2686
|
-
case "self": {
|
|
2687
|
-
const at = recs.length - 1 - n.depth;
|
|
2688
|
-
return at < 0 || holds(recs[at], v, recs.slice(0, at));
|
|
2689
|
-
}
|
|
2690
|
-
case "array":
|
|
2691
|
-
case "runs":
|
|
2692
|
-
case "lz": {
|
|
2693
|
-
if (!Array.isArray(v) && !(ArrayBuffer.isView(v) && !(v instanceof DataView))) return true;
|
|
2694
|
-
const a = v;
|
|
2695
|
-
if (n.kind === "array" && n.max && a.length > n.max) return false;
|
|
2696
|
-
for (let k = 0; k < a.length; k += 1) if (!holds(n.of, a[k], recs)) return false;
|
|
2697
|
-
return true;
|
|
2698
|
-
}
|
|
2699
|
-
case "tuple":
|
|
2700
|
-
return !Array.isArray(v) || n.items.every((t, k) => holds(t, v[k], recs));
|
|
2701
|
-
case "struct":
|
|
2702
|
-
return fields(n.fields, n.ext, null);
|
|
2703
|
-
case "union": {
|
|
2704
|
-
const tag = typeof v === "object" && v !== null ? v[n.tag] : void 0;
|
|
2705
|
-
const variant = n.variants.find((x) => x.name === tag)?.type;
|
|
2706
|
-
return !variant || fields(variant.fields, variant.ext, n.tag);
|
|
2707
|
-
}
|
|
2708
|
-
case "alt": {
|
|
2709
|
-
const cat = valueCategory(v);
|
|
2710
|
-
const b = n.of.find((x) => categoryOf(x) === cat);
|
|
2711
|
-
return !b || holds(b, v, recs);
|
|
2712
|
-
}
|
|
2713
|
-
case "map":
|
|
2714
|
-
return typeof v !== "object" || v === null || Array.isArray(v) || Object.values(v).every((x) => x === void 0 || holds(n.value, x, recs));
|
|
2715
|
-
case "grow":
|
|
2716
|
-
return holds(n.of, v, recs);
|
|
2717
|
-
default:
|
|
2718
|
-
return true;
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2721
|
-
function valueCategory(v) {
|
|
2722
|
-
if (v === null) return "null";
|
|
2723
|
-
if (Array.isArray(v)) return "array";
|
|
2724
|
-
if (v instanceof Uint8Array) return "bytes";
|
|
2725
|
-
const t = typeof v;
|
|
2726
|
-
if (t === "number" || t === "string" || t === "boolean" || t === "bigint") return t;
|
|
2727
|
-
return "object";
|
|
2728
|
-
}
|
|
2729
|
-
function structCodec(fields, open, ext, recs, node2, tagKey) {
|
|
2730
|
-
const fs = fields.map((f) => ({ name: f.name, c: compile(f.type, recs), optional: f.type.kind === "optional" }));
|
|
2731
|
-
const groups = ext.map((g) => g.map((f) => ({ name: f.name, c: compile(f.type, recs), optional: f.type.kind === "optional", node: f.type })));
|
|
2732
|
-
const known = new Set([...fields, ...ext.flat()].map((f) => f.name));
|
|
2733
|
-
if (tagKey !== null) known.add(tagKey);
|
|
2734
|
-
const proto = known.has("__proto__");
|
|
2735
|
-
const scratch = [];
|
|
2736
|
-
const empty = (g, v) => g.every((f) => v[f.name] === void 0 || f.node.kind === "default" && same(v[f.name], f.node.value));
|
|
2737
|
-
return {
|
|
2738
|
-
node: node2,
|
|
2739
|
-
w(o, v, x) {
|
|
2740
|
-
if (typeof v !== "object" || v === null || Array.isArray(v)) fail(`${describe(v)} is not an object.`);
|
|
2741
|
-
const rec = v;
|
|
2742
|
-
let k = 0;
|
|
2743
|
-
let given = tagKey !== null && rec[tagKey] !== void 0 ? 1 : 0;
|
|
2744
|
-
try {
|
|
2745
|
-
for (; k < fs.length; k += 1) {
|
|
2746
|
-
const f = fs[k];
|
|
2747
|
-
const fv = rec[f.name];
|
|
2748
|
-
if (fv !== void 0) given += 1;
|
|
2749
|
-
f.c.w(o, fv, x);
|
|
2750
|
-
}
|
|
2751
|
-
} catch (e) {
|
|
2752
|
-
throw under(e, fs[k].name, null);
|
|
2753
|
-
}
|
|
2754
|
-
if (x.strict) {
|
|
2755
|
-
let all = 0;
|
|
2756
|
-
for (const key in rec) if (rec[key] !== void 0) all += 1;
|
|
2757
|
-
if (all > given) {
|
|
2758
|
-
for (const g of groups) for (const f of g) if (rec[f.name] !== void 0) given += 1;
|
|
2759
|
-
if (all > given) {
|
|
2760
|
-
for (const key in rec) if (!known.has(key) && rec[key] !== void 0) fail(`Unknown field ${JSON.stringify(key)} (the fields are ${[...known].join(", ")}).`);
|
|
2761
|
-
}
|
|
2762
|
-
}
|
|
2763
|
-
}
|
|
2764
|
-
if (!open) return;
|
|
2765
|
-
let count = groups.length;
|
|
2766
|
-
while (count > 0 && empty(groups[count - 1], rec)) count -= 1;
|
|
2767
|
-
o.golomb(count, 0);
|
|
2768
|
-
for (let g = 0; g < count; g += 1) {
|
|
2769
|
-
const s = scratch.pop() ?? new BitWriter(64);
|
|
2770
|
-
s.reset();
|
|
2771
|
-
const t0 = x.text.length;
|
|
2772
|
-
for (const f of groups[g]) wr(f.c, s, rec[f.name], x, f.name);
|
|
2773
|
-
o.golomb(s.length, 0);
|
|
2774
|
-
o.golomb((x.text.length - t0) / 8, 0);
|
|
2775
|
-
o.append(s);
|
|
2776
|
-
scratch.push(s);
|
|
2777
|
-
}
|
|
2778
|
-
},
|
|
2779
|
-
r(i, x) {
|
|
2780
|
-
const out = {};
|
|
2781
|
-
if (x.trace !== null || proto) {
|
|
2782
|
-
for (let k = 0; k < fs.length; k += 1) {
|
|
2783
|
-
const f = fs[k];
|
|
2784
|
-
const v = rd(f.c, i, x, f.name);
|
|
2785
|
-
if (v !== void 0 || !f.optional) put(out, f.name, v);
|
|
2786
|
-
}
|
|
2787
|
-
} else {
|
|
2788
|
-
let k = 0;
|
|
2789
|
-
try {
|
|
2790
|
-
for (; k < fs.length; k += 1) {
|
|
2791
|
-
const f = fs[k];
|
|
2792
|
-
const v = f.c.r(i, x);
|
|
2793
|
-
if (v !== void 0 || !f.optional) out[f.name] = v;
|
|
2794
|
-
}
|
|
2795
|
-
} catch (e) {
|
|
2796
|
-
throw under(e, fs[k].name, null);
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
if (!open) return out;
|
|
2800
|
-
const s0 = i.at;
|
|
2801
|
-
const count = i.golomb(0);
|
|
2802
|
-
if (x.trace) meta(x, "groups", s0, i, count, `${count} extension group${count === 1 ? "" : "s"}`);
|
|
2803
|
-
for (let g = 0; g < Math.max(count, groups.length); g += 1) {
|
|
2804
|
-
const group = groups[g];
|
|
2805
|
-
if (g >= count) {
|
|
2806
|
-
for (const f of group) if (f.node.kind === "default") out[f.name] = structuredClone(f.node.value);
|
|
2807
|
-
continue;
|
|
2808
|
-
}
|
|
2809
|
-
const s1 = i.at;
|
|
2810
|
-
const len2 = i.golomb(0);
|
|
2811
|
-
const textLen = i.golomb(0);
|
|
2812
|
-
if (x.trace) meta(x, `group ${g + 1}`, s1, i, len2, `${len2} bits, ${textLen} bytes of text`);
|
|
2813
|
-
const start = i.at;
|
|
2814
|
-
const t0 = x.tr.at;
|
|
2815
|
-
if (!group) {
|
|
2816
|
-
i.skip(len2);
|
|
2817
|
-
x.tr.skip(textLen * 8);
|
|
2818
|
-
if (x.trace) {
|
|
2819
|
-
meta(x, `group ${g + 1} (unknown)`, start, i, null, "skipped: a newer schema's fields");
|
|
2820
|
-
if (textLen) x.trace.meta(`group ${g + 1} text (unknown)`, t0, textLen * 8, null, "skipped");
|
|
2821
|
-
}
|
|
2822
|
-
continue;
|
|
2823
|
-
}
|
|
2824
|
-
for (const f of group) {
|
|
2825
|
-
const v = rd(f.c, i, x, f.name);
|
|
2826
|
-
if (v !== void 0 || !f.optional) out[f.name] = v;
|
|
2827
|
-
}
|
|
2828
|
-
if (i.at - start !== len2) fail(`Extension group ${g + 1} is ${len2} bits long but its fields read ${i.at - start}.`);
|
|
2829
|
-
if (x.tr.at - t0 !== textLen * 8) fail(`Extension group ${g + 1} has ${textLen} bytes of text but its fields read ${(x.tr.at - t0) / 8}.`);
|
|
2830
|
-
}
|
|
2831
|
-
return out;
|
|
2832
|
-
}
|
|
2833
|
-
};
|
|
2834
|
-
}
|
|
2835
|
-
var DYN_TABLE = "str";
|
|
2836
|
-
var DYN_NUMS = "$dyn";
|
|
2837
|
-
function dynCodec(n) {
|
|
2838
|
-
const str = compile({ kind: "ref", table: DYN_TABLE, packHex: false }, []);
|
|
2839
|
-
const w = (o, v, x) => {
|
|
2840
|
-
if (v === null) {
|
|
2841
|
-
o.bits(0, 3);
|
|
2842
|
-
return;
|
|
2843
|
-
}
|
|
2844
|
-
switch (typeof v) {
|
|
2845
|
-
case "boolean":
|
|
2846
|
-
o.bits(v ? 2 : 1, 3);
|
|
2847
|
-
return;
|
|
2848
|
-
case "number":
|
|
2849
|
-
if (Number.isSafeInteger(v) && !Object.is(v, -0) && Math.abs(v) <= 2 ** 51) {
|
|
2850
|
-
o.bits(3, 3);
|
|
2851
|
-
o.golomb(zig(v), 0);
|
|
2852
|
-
return;
|
|
2853
|
-
}
|
|
2854
|
-
o.bits(4, 3);
|
|
2855
|
-
{
|
|
2856
|
-
const t = x.tables.numbers(DYN_NUMS);
|
|
2857
|
-
const at = t.index.get(v);
|
|
2858
|
-
if (at !== void 0) {
|
|
2859
|
-
o.bits(0, 2);
|
|
2860
|
-
o.bits(at, bitsFor(t.list.length));
|
|
2861
|
-
return;
|
|
2862
|
-
}
|
|
2863
|
-
writeNum(o, v, 2);
|
|
2864
|
-
t.index.set(v, t.list.length);
|
|
2865
|
-
t.list.push(v);
|
|
2866
|
-
}
|
|
2867
|
-
return;
|
|
2868
|
-
case "string":
|
|
2869
|
-
o.bits(5, 3);
|
|
2870
|
-
str.w(o, v, x);
|
|
2871
|
-
return;
|
|
2872
|
-
case "object": {
|
|
2873
|
-
if (Array.isArray(v)) {
|
|
2874
|
-
o.bits(6, 3);
|
|
2875
|
-
o.golomb(v.length, 0);
|
|
2876
|
-
for (let k = 0; k < v.length; k += 1) {
|
|
2877
|
-
try {
|
|
2878
|
-
w(o, v[k], x);
|
|
2879
|
-
} catch (e) {
|
|
2880
|
-
throw under(e, k, null);
|
|
2881
|
-
}
|
|
2882
|
-
}
|
|
2883
|
-
return;
|
|
2884
|
-
}
|
|
2885
|
-
if (ArrayBuffer.isView(v)) fail("A typed array isn't JSON-like (dyn): give an array, or a typed schema.");
|
|
2886
|
-
const rec = v;
|
|
2887
|
-
const keys = Object.keys(rec).filter((k) => rec[k] !== void 0);
|
|
2888
|
-
o.bits(7, 3);
|
|
2889
|
-
const t = x.tables.shapes(DYN_NUMS);
|
|
2890
|
-
const sig = JSON.stringify(keys);
|
|
2891
|
-
const at = keys.length ? t.index.get(sig) : void 0;
|
|
2892
|
-
if (at !== void 0) {
|
|
2893
|
-
o.bool(true);
|
|
2894
|
-
o.bits(at, bitsFor(t.list.length));
|
|
2895
|
-
} else {
|
|
2896
|
-
o.bool(false);
|
|
2897
|
-
o.golomb(keys.length, 0);
|
|
2898
|
-
for (const k of keys) str.w(o, k, x);
|
|
2899
|
-
if (keys.length) {
|
|
2900
|
-
t.index.set(sig, t.list.length);
|
|
2901
|
-
t.list.push(keys);
|
|
2902
|
-
}
|
|
2903
|
-
}
|
|
2904
|
-
for (const k of keys) {
|
|
2905
|
-
try {
|
|
2906
|
-
w(o, rec[k], x);
|
|
2907
|
-
} catch (e) {
|
|
2908
|
-
throw under(e, k, null);
|
|
2909
|
-
}
|
|
2910
|
-
}
|
|
2911
|
-
return;
|
|
2912
|
-
}
|
|
2913
|
-
default:
|
|
2914
|
-
fail(`${typeof v} isn't JSON-like (dyn).`);
|
|
2915
|
-
}
|
|
2916
|
-
};
|
|
2917
|
-
const TAGS = ["null", "false", "true", "int", "number", "string", "array", "object"];
|
|
2918
|
-
const r = (i, x) => {
|
|
2919
|
-
const s = i.at;
|
|
2920
|
-
const tag = i.bits(3);
|
|
2921
|
-
if (x.trace) meta(x, "type", s, i, TAGS[tag], TAGS[tag]);
|
|
2922
|
-
switch (tag) {
|
|
2923
|
-
case 0:
|
|
2924
|
-
return null;
|
|
2925
|
-
case 1:
|
|
2926
|
-
return false;
|
|
2927
|
-
case 2:
|
|
2928
|
-
return true;
|
|
2929
|
-
case 3:
|
|
2930
|
-
return unzig(i.golomb(0));
|
|
2931
|
-
case 4: {
|
|
2932
|
-
const s1 = i.at;
|
|
2933
|
-
const k = i.bits(2);
|
|
2934
|
-
const t = x.tables.numbers(DYN_NUMS);
|
|
2935
|
-
if (k === 0) {
|
|
2936
|
-
const at = i.bits(bitsFor(t.list.length));
|
|
2937
|
-
if (x.trace) meta(x, "repeat", s1, i, at, `the number #${at} again`);
|
|
2938
|
-
if (at >= t.list.length) fail(`The number #${at} again, of ${t.list.length}.`);
|
|
2939
|
-
return t.list[at];
|
|
2940
|
-
}
|
|
2941
|
-
if (x.trace) meta(x, "kind", s1, i, NUM_KINDS[k], "");
|
|
2942
|
-
const v = readNum(i, k);
|
|
2943
|
-
if (t.index.has(v)) fail("A number written again in full (not canonical: it repeats by index).");
|
|
2944
|
-
t.index.set(v, t.list.length);
|
|
2945
|
-
t.list.push(v);
|
|
2946
|
-
return v;
|
|
2947
|
-
}
|
|
2948
|
-
case 5:
|
|
2949
|
-
return str.r(i, x);
|
|
2950
|
-
case 6: {
|
|
2951
|
-
const s1 = i.at;
|
|
2952
|
-
const len2 = i.golomb(0);
|
|
2953
|
-
if (x.trace) meta(x, "length", s1, i, len2, `${len2} items`);
|
|
2954
|
-
const out = new Array(len2);
|
|
2955
|
-
for (let k = 0; k < len2; k += 1) out[k] = x.trace ? rd(self, i, x, k) : r(i, x);
|
|
2956
|
-
return out;
|
|
2957
|
-
}
|
|
2958
|
-
default: {
|
|
2959
|
-
const t = x.tables.shapes(DYN_NUMS);
|
|
2960
|
-
const s1 = i.at;
|
|
2961
|
-
let keys;
|
|
2962
|
-
if (i.bool()) {
|
|
2963
|
-
const at = i.bits(bitsFor(t.list.length));
|
|
2964
|
-
if (at >= t.list.length) fail(`Object shape #${at} of ${t.list.length}.`);
|
|
2965
|
-
keys = t.list[at];
|
|
2966
|
-
if (x.trace) meta(x, "shape", s1, i, at, `shaped like object #${at}: ${keys.length} keys`);
|
|
2967
|
-
} else {
|
|
2968
|
-
const count = i.golomb(0);
|
|
2969
|
-
if (x.trace) meta(x, "keys", s1, i, count, `${count} keys, a new shape`);
|
|
2970
|
-
keys = [];
|
|
2971
|
-
for (let k = 0; k < count; k += 1) {
|
|
2972
|
-
const key = str.r(i, x);
|
|
2973
|
-
if (keys.includes(key)) fail(`The key ${JSON.stringify(key)} is in the object twice.`);
|
|
2974
|
-
keys.push(key);
|
|
2975
|
-
}
|
|
2976
|
-
if (count) {
|
|
2977
|
-
const sig = JSON.stringify(keys);
|
|
2978
|
-
if (t.index.has(sig)) fail("An object's keys written again in full (not canonical: its shape repeats by index).");
|
|
2979
|
-
t.index.set(sig, t.list.length);
|
|
2980
|
-
t.list.push(keys);
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
|
-
const out = {};
|
|
2984
|
-
for (const key of keys) put(out, key, x.trace ? rd(self, i, x, key) : r(i, x));
|
|
2985
|
-
return out;
|
|
2986
|
-
}
|
|
2987
|
-
}
|
|
2988
|
-
};
|
|
2989
|
-
const self = { node: n, w, r };
|
|
2990
|
-
return self;
|
|
2991
|
-
}
|
|
2992
|
-
var WRITER = new BitWriter(4096);
|
|
2993
|
-
var TEXT = new BitWriter(1024);
|
|
2994
|
-
var OUT = new BitWriter(4096);
|
|
2995
|
-
var writerBusy = false;
|
|
2996
|
-
function writeBody(o, c, value, x, bits) {
|
|
2997
|
-
c.w(bits, value, x);
|
|
2998
|
-
const text = x.text;
|
|
2999
|
-
let n = text.length / 8;
|
|
3000
|
-
o.align();
|
|
3001
|
-
do {
|
|
3002
|
-
const b = n % 128;
|
|
3003
|
-
n = Math.floor(n / 128);
|
|
3004
|
-
o.bits(b | (n > 0 ? 128 : 0), 8);
|
|
3005
|
-
} while (n > 0);
|
|
3006
|
-
o.append(bits);
|
|
3007
|
-
o.align();
|
|
3008
|
-
o.append(text);
|
|
3009
|
-
}
|
|
3010
|
-
function encodeRaw(schema, value, opts = {}) {
|
|
3011
|
-
const reuse = !writerBusy;
|
|
3012
|
-
const bits = reuse ? WRITER : new BitWriter(256);
|
|
3013
|
-
const text = reuse ? TEXT : new BitWriter(64);
|
|
3014
|
-
const out = reuse ? OUT : new BitWriter(256);
|
|
3015
|
-
if (reuse) {
|
|
3016
|
-
writerBusy = true;
|
|
3017
|
-
bits.reset();
|
|
3018
|
-
text.reset();
|
|
3019
|
-
out.reset();
|
|
3020
|
-
}
|
|
3021
|
-
try {
|
|
3022
|
-
writeBody(out, compiled2(schema), value, { tables: opts.tables ?? new Tables(), trace: null, strict: opts.strict ?? true, text, tr: null, last: null }, bits);
|
|
3023
|
-
return out.finish();
|
|
3024
|
-
} finally {
|
|
3025
|
-
if (reuse) writerBusy = false;
|
|
3026
|
-
}
|
|
3027
|
-
}
|
|
3028
|
-
|
|
3029
|
-
// ../../../../../../keel-engine/packages/codec/src/sha256.ts
|
|
3030
|
-
var K = new Uint32Array([
|
|
3031
|
-
1116352408,
|
|
3032
|
-
1899447441,
|
|
3033
|
-
3049323471,
|
|
3034
|
-
3921009573,
|
|
3035
|
-
961987163,
|
|
3036
|
-
1508970993,
|
|
3037
|
-
2453635748,
|
|
3038
|
-
2870763221,
|
|
3039
|
-
3624381080,
|
|
3040
|
-
310598401,
|
|
3041
|
-
607225278,
|
|
3042
|
-
1426881987,
|
|
3043
|
-
1925078388,
|
|
3044
|
-
2162078206,
|
|
3045
|
-
2614888103,
|
|
3046
|
-
3248222580,
|
|
3047
|
-
3835390401,
|
|
3048
|
-
4022224774,
|
|
3049
|
-
264347078,
|
|
3050
|
-
604807628,
|
|
3051
|
-
770255983,
|
|
3052
|
-
1249150122,
|
|
3053
|
-
1555081692,
|
|
3054
|
-
1996064986,
|
|
3055
|
-
2554220882,
|
|
3056
|
-
2821834349,
|
|
3057
|
-
2952996808,
|
|
3058
|
-
3210313671,
|
|
3059
|
-
3336571891,
|
|
3060
|
-
3584528711,
|
|
3061
|
-
113926993,
|
|
3062
|
-
338241895,
|
|
3063
|
-
666307205,
|
|
3064
|
-
773529912,
|
|
3065
|
-
1294757372,
|
|
3066
|
-
1396182291,
|
|
3067
|
-
1695183700,
|
|
3068
|
-
1986661051,
|
|
3069
|
-
2177026350,
|
|
3070
|
-
2456956037,
|
|
3071
|
-
2730485921,
|
|
3072
|
-
2820302411,
|
|
3073
|
-
3259730800,
|
|
3074
|
-
3345764771,
|
|
3075
|
-
3516065817,
|
|
3076
|
-
3600352804,
|
|
3077
|
-
4094571909,
|
|
3078
|
-
275423344,
|
|
3079
|
-
430227734,
|
|
3080
|
-
506948616,
|
|
3081
|
-
659060556,
|
|
3082
|
-
883997877,
|
|
3083
|
-
958139571,
|
|
3084
|
-
1322822218,
|
|
3085
|
-
1537002063,
|
|
3086
|
-
1747873779,
|
|
3087
|
-
1955562222,
|
|
3088
|
-
2024104815,
|
|
3089
|
-
2227730452,
|
|
3090
|
-
2361852424,
|
|
3091
|
-
2428436474,
|
|
3092
|
-
2756734187,
|
|
3093
|
-
3204031479,
|
|
3094
|
-
3329325298
|
|
3095
|
-
]);
|
|
3096
|
-
function sha256(data) {
|
|
3097
|
-
const h = new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]);
|
|
3098
|
-
const len2 = data.length;
|
|
3099
|
-
const padded = new Uint8Array(Math.ceil((len2 + 9) / 64) * 64);
|
|
3100
|
-
padded.set(data);
|
|
3101
|
-
padded[len2] = 128;
|
|
3102
|
-
const view = new DataView(padded.buffer);
|
|
3103
|
-
view.setUint32(padded.length - 8, Math.floor(len2 * 8 / 2 ** 32));
|
|
3104
|
-
view.setUint32(padded.length - 4, len2 * 8 >>> 0);
|
|
3105
|
-
const w = new Uint32Array(64);
|
|
3106
|
-
for (let off = 0; off < padded.length; off += 64) {
|
|
3107
|
-
for (let i = 0; i < 16; i += 1) w[i] = view.getUint32(off + i * 4);
|
|
3108
|
-
for (let i = 16; i < 64; i += 1) {
|
|
3109
|
-
const a2 = w[i - 15], b3 = w[i - 2];
|
|
3110
|
-
const s0 = (a2 >>> 7 | a2 << 25) ^ (a2 >>> 18 | a2 << 14) ^ a2 >>> 3;
|
|
3111
|
-
const s1 = (b3 >>> 17 | b3 << 15) ^ (b3 >>> 19 | b3 << 13) ^ b3 >>> 10;
|
|
3112
|
-
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
3113
|
-
}
|
|
3114
|
-
let a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f = h[5], g = h[6], hh = h[7];
|
|
3115
|
-
for (let i = 0; i < 64; i += 1) {
|
|
3116
|
-
const S1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7);
|
|
3117
|
-
const ch = e & f ^ ~e & g;
|
|
3118
|
-
const t1 = hh + S1 + ch + K[i] + w[i] >>> 0;
|
|
3119
|
-
const S0 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10);
|
|
3120
|
-
const maj = a & b ^ a & c ^ b & c;
|
|
3121
|
-
const t2 = S0 + maj >>> 0;
|
|
3122
|
-
hh = g;
|
|
3123
|
-
g = f;
|
|
3124
|
-
f = e;
|
|
3125
|
-
e = d + t1 >>> 0;
|
|
3126
|
-
d = c;
|
|
3127
|
-
c = b;
|
|
3128
|
-
b = a;
|
|
3129
|
-
a = t1 + t2 >>> 0;
|
|
3130
|
-
}
|
|
3131
|
-
h[0] = h[0] + a >>> 0;
|
|
3132
|
-
h[1] = h[1] + b >>> 0;
|
|
3133
|
-
h[2] = h[2] + c >>> 0;
|
|
3134
|
-
h[3] = h[3] + d >>> 0;
|
|
3135
|
-
h[4] = h[4] + e >>> 0;
|
|
3136
|
-
h[5] = h[5] + f >>> 0;
|
|
3137
|
-
h[6] = h[6] + g >>> 0;
|
|
3138
|
-
h[7] = h[7] + hh >>> 0;
|
|
3139
|
-
}
|
|
3140
|
-
const out = new Uint8Array(32);
|
|
3141
|
-
const ov = new DataView(out.buffer);
|
|
3142
|
-
for (let i = 0; i < 8; i += 1) ov.setUint32(i * 4, h[i]);
|
|
3143
|
-
return out;
|
|
3144
|
-
}
|
|
3145
|
-
var toHex2 = (b) => {
|
|
3146
|
-
let s = "";
|
|
3147
|
-
for (let i = 0; i < b.length; i += 1) s += b[i].toString(16).padStart(2, "0");
|
|
3148
|
-
return s;
|
|
3149
|
-
};
|
|
3150
|
-
|
|
3151
|
-
// ../../../../../../keel-engine/packages/codec/src/canonical.ts
|
|
3152
|
-
var NAMES = "$names";
|
|
3153
|
-
var field = (self) => struct({ name: ref(NAMES), type: self });
|
|
3154
|
-
var SCHEMA_SCHEMA = named("keel/codec/schema", recursive((self) => union("kind", {
|
|
3155
|
-
uint: struct({ bits: uint(6) }),
|
|
3156
|
-
int: struct({ bits: uint(6) }),
|
|
3157
|
-
bool: struct({}),
|
|
3158
|
-
fixed: struct({ min: num(), max: num(), step: num(), off: enumOf(["round", "strict", "exact"]), k: int(7), delta: bool() }),
|
|
3159
|
-
float: struct({ bits: enumOf([16, 32, 64]) }),
|
|
3160
|
-
enum: struct({ values: array(alt([string(), num(), bool()])), capacity: varuint(), open: bool(), other: bool() }),
|
|
3161
|
-
varuint: struct({ k: uint(5), group: uint(5) }),
|
|
3162
|
-
varint: struct({ k: uint(5), group: uint(5) }),
|
|
3163
|
-
string: struct({ max: varuint(), packHex: bool() }),
|
|
3164
|
-
ref: struct({ table: ref(NAMES), packHex: bool() }),
|
|
3165
|
-
bytes: struct({ length: varuint() }),
|
|
3166
|
-
hex: struct({ bytes: varuint() }),
|
|
3167
|
-
biguint: struct({ bits: uint(9) }),
|
|
3168
|
-
array: struct({ of: self, length: varuint(), max: varuint() }),
|
|
3169
|
-
optional: struct({ of: self }),
|
|
3170
|
-
nullable: struct({ of: self }),
|
|
3171
|
-
default: struct({ of: self, value: bytes() }),
|
|
3172
|
-
struct: struct({ fields: array(field(self)), open: bool(), ext: array(array(field(self))) }),
|
|
3173
|
-
tuple: struct({ items: array(self) }),
|
|
3174
|
-
union: struct({ tag: ref(NAMES), variants: array(field(self)), capacity: varuint() }),
|
|
3175
|
-
alt: struct({ of: array(self) }),
|
|
3176
|
-
map: struct({ key: self, value: self, order: enumOf(["sorted", "kept"]) }),
|
|
3177
|
-
delta: struct({ of: self, k: uint(5) }),
|
|
3178
|
-
runs: struct({ of: self }),
|
|
3179
|
-
planes: struct({ bits: uint(6) }),
|
|
3180
|
-
dyn: struct({}),
|
|
3181
|
-
num: struct({}),
|
|
3182
|
-
const: struct({ value: dyn() }),
|
|
3183
|
-
named: struct({ name: ref(NAMES), version: varuint(), doc: string(), of: self }),
|
|
3184
|
-
rec: struct({ of: self }),
|
|
3185
|
-
self: struct({ depth: varuint() }),
|
|
3186
|
-
lz: struct({ of: self, min: uint(4) }),
|
|
3187
|
-
grow: struct({ base: self, of: self })
|
|
3188
|
-
}, { capacity: 64 })), { doc: "Every schema, as data: a document can carry its own." });
|
|
3189
|
-
function toRecord(type, { docs = true } = {}) {
|
|
3190
|
-
const walk = (n) => {
|
|
3191
|
-
const fl = (fs) => fs.map((f) => ({ name: f.name, type: walk(f.type) }));
|
|
3192
|
-
switch (n.kind) {
|
|
3193
|
-
case "uint":
|
|
3194
|
-
case "int":
|
|
3195
|
-
case "biguint":
|
|
3196
|
-
case "planes":
|
|
3197
|
-
return { kind: n.kind, bits: n.bits };
|
|
3198
|
-
case "bool":
|
|
3199
|
-
case "dyn":
|
|
3200
|
-
case "num":
|
|
3201
|
-
return { kind: n.kind };
|
|
3202
|
-
case "fixed":
|
|
3203
|
-
return { kind: "fixed", min: n.min, max: n.max, step: n.step, off: n.off, k: n.k, delta: n.delta };
|
|
3204
|
-
case "float":
|
|
3205
|
-
return { kind: "float", bits: n.bits };
|
|
3206
|
-
case "enum":
|
|
3207
|
-
return { kind: "enum", values: [...n.values], capacity: n.capacity, open: n.open, other: n.other };
|
|
3208
|
-
case "varuint":
|
|
3209
|
-
case "varint":
|
|
3210
|
-
return { kind: n.kind, k: n.k, group: n.group };
|
|
3211
|
-
case "string":
|
|
3212
|
-
return { kind: "string", max: n.max, packHex: n.packHex };
|
|
3213
|
-
case "ref":
|
|
3214
|
-
return { kind: "ref", table: n.table, packHex: n.packHex };
|
|
3215
|
-
case "bytes":
|
|
3216
|
-
return { kind: "bytes", length: n.length };
|
|
3217
|
-
case "hex":
|
|
3218
|
-
return { kind: "hex", bytes: n.bytes };
|
|
3219
|
-
case "array":
|
|
3220
|
-
return { kind: "array", of: walk(n.of), length: n.length, max: n.max };
|
|
3221
|
-
case "optional":
|
|
3222
|
-
case "nullable":
|
|
3223
|
-
case "runs":
|
|
3224
|
-
case "rec":
|
|
3225
|
-
return { kind: n.kind, of: walk(n.of) };
|
|
3226
|
-
case "default": {
|
|
3227
|
-
let value;
|
|
3228
|
-
try {
|
|
3229
|
-
value = encodeRaw(n.of, n.value);
|
|
3230
|
-
} catch (e) {
|
|
3231
|
-
throw new SchemaError(`A default can't be written as data: ${e.message}`);
|
|
3232
|
-
}
|
|
3233
|
-
return { kind: "default", of: walk(n.of), value };
|
|
3234
|
-
}
|
|
3235
|
-
case "struct":
|
|
3236
|
-
return { kind: "struct", fields: fl(n.fields), open: n.open, ext: n.ext.map((g) => fl(g)) };
|
|
3237
|
-
case "tuple":
|
|
3238
|
-
return { kind: "tuple", items: n.items.map((x) => walk(x)) };
|
|
3239
|
-
case "union":
|
|
3240
|
-
return { kind: "union", tag: n.tag, variants: fl(n.variants), capacity: n.capacity };
|
|
3241
|
-
case "alt":
|
|
3242
|
-
return { kind: "alt", of: n.of.map((x) => walk(x)) };
|
|
3243
|
-
case "map":
|
|
3244
|
-
return { kind: "map", key: walk(n.key), value: walk(n.value), order: n.order };
|
|
3245
|
-
case "delta":
|
|
3246
|
-
return { kind: "delta", of: walk(n.of), k: n.k };
|
|
3247
|
-
case "const":
|
|
3248
|
-
return { kind: "const", value: n.value };
|
|
3249
|
-
case "named":
|
|
3250
|
-
return { kind: "named", name: n.name, version: n.version, doc: docs ? n.doc : "", of: walk(n.of) };
|
|
3251
|
-
case "self":
|
|
3252
|
-
return { kind: "self", depth: n.depth };
|
|
3253
|
-
case "lz":
|
|
3254
|
-
return { kind: "lz", of: walk(n.of), min: n.min };
|
|
3255
|
-
case "grow":
|
|
3256
|
-
return { kind: "grow", base: walk(n.base), of: walk(n.of) };
|
|
3257
|
-
}
|
|
3258
|
-
};
|
|
3259
|
-
return walk(type);
|
|
3260
|
-
}
|
|
3261
|
-
var encodeSchema = (type, opts = {}) => encodeRaw(SCHEMA_SCHEMA, toRecord(type, opts));
|
|
3262
|
-
var IDS = /* @__PURE__ */ new WeakMap();
|
|
3263
|
-
function schemaId(type) {
|
|
3264
|
-
const have = IDS.get(type);
|
|
3265
|
-
if (have) return have;
|
|
3266
|
-
const id2 = toHex2(sha256(encodeSchema(type, { docs: false })));
|
|
3267
|
-
IDS.set(type, id2);
|
|
3268
|
-
return id2;
|
|
3269
|
-
}
|
|
3270
|
-
function schemaName(type) {
|
|
3271
|
-
const n = type;
|
|
3272
|
-
return n.kind === "named" ? { name: n.name, version: n.version, doc: n.doc } : null;
|
|
3273
|
-
}
|
|
3274
|
-
|
|
3275
|
-
// ../../../../../../keel-engine/packages/codec/src/document.ts
|
|
3276
|
-
function createRegistry() {
|
|
3277
|
-
const byId = /* @__PURE__ */ new Map();
|
|
3278
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
3279
|
-
const reg = {
|
|
3280
|
-
register(schema, alias) {
|
|
3281
|
-
const id2 = schemaId(schema);
|
|
3282
|
-
const named2 = schemaName(schema);
|
|
3283
|
-
const have = byId.get(id2);
|
|
3284
|
-
const aliases = new Set(have?.aliases ?? []);
|
|
3285
|
-
if (alias) {
|
|
3286
|
-
const other = byKey.get(alias);
|
|
3287
|
-
if (other && other.id !== id2) throw new RangeError(`The name ${alias} is already schema ${other.short}.`);
|
|
3288
|
-
aliases.add(alias);
|
|
3289
|
-
}
|
|
3290
|
-
const entry = { id: id2, short: id2.slice(0, 8), schema: have?.schema ?? schema, name: named2?.name ?? null, version: named2?.version ?? null, aliases: [...aliases] };
|
|
3291
|
-
const clash = byKey.get(entry.short);
|
|
3292
|
-
if (clash && clash.id !== id2) throw new RangeError(`Two schemas share the short id ${entry.short} (${clash.id} and ${id2}): a header can't tell them apart.`);
|
|
3293
|
-
byId.set(id2, entry);
|
|
3294
|
-
for (const k of [id2, entry.short, ...aliases, ...named2 ? [`${named2.name}@${named2.version}`] : []]) byKey.set(k, entry);
|
|
3295
|
-
return id2;
|
|
3296
|
-
},
|
|
3297
|
-
get: (key) => byKey.get(key),
|
|
3298
|
-
has: (key) => byKey.has(key),
|
|
3299
|
-
list: () => [...byId.values()]
|
|
3300
|
-
};
|
|
3301
|
-
return reg;
|
|
3302
|
-
}
|
|
3303
|
-
var defaultRegistry = createRegistry();
|
|
3304
|
-
function registerSchema(a, b) {
|
|
3305
|
-
return typeof a === "string" ? defaultRegistry.register(b, a) : defaultRegistry.register(a);
|
|
3306
|
-
}
|
|
3307
|
-
|
|
3308
|
-
// ../../../../../../keel-engine/packages/ui/src/schemas.ts
|
|
3309
|
-
var hue = fixed(0, 360, 0.01, { off: "exact" });
|
|
3310
|
-
var share = fixed(0, 1, 0.01, { off: "exact" });
|
|
3311
|
-
var FONT_PARAMS = struct({
|
|
3312
|
-
width: share,
|
|
3313
|
-
xHeight: share,
|
|
3314
|
-
descender: share,
|
|
3315
|
-
round: uint(2),
|
|
3316
|
-
stroke: fixed(0, 0.5, 0.01, { off: "exact" }),
|
|
3317
|
-
serif: enumOf(SERIFS, { capacity: 8 }),
|
|
3318
|
-
slant: uint(1),
|
|
3319
|
-
tracking: uint(2),
|
|
3320
|
-
zero: enumOf(ZEROS, { capacity: 4 }),
|
|
3321
|
-
ascend: uint(1),
|
|
3322
|
-
soft: enumOf(SOFTS, { capacity: 4 }),
|
|
3323
|
-
capWidth: uint(2)
|
|
3324
|
-
});
|
|
3325
|
-
var FONT_PINS = struct({
|
|
3326
|
-
width: optional(share),
|
|
3327
|
-
xHeight: optional(share),
|
|
3328
|
-
descender: optional(share),
|
|
3329
|
-
round: optional(uint(2)),
|
|
3330
|
-
stroke: optional(fixed(0, 0.5, 0.01, { off: "exact" })),
|
|
3331
|
-
serif: optional(enumOf(SERIFS, { capacity: 8 })),
|
|
3332
|
-
slant: optional(uint(1)),
|
|
3333
|
-
tracking: optional(uint(2)),
|
|
3334
|
-
zero: optional(enumOf(ZEROS, { capacity: 4 })),
|
|
3335
|
-
ascend: optional(uint(1)),
|
|
3336
|
-
soft: optional(enumOf(SOFTS, { capacity: 4 })),
|
|
3337
|
-
capWidth: optional(uint(2))
|
|
3338
|
-
});
|
|
3339
|
-
var THEME_PINS = struct({
|
|
3340
|
-
tone: optional(enumOf(TONES, { capacity: 4 })),
|
|
3341
|
-
hue: optional(hue),
|
|
3342
|
-
accentHue: optional(hue),
|
|
3343
|
-
chroma: optional(fixed(0, 0.5, 1e-3, { off: "exact" })),
|
|
3344
|
-
corner: optional(enumOf(CORNERS, { capacity: 16 })),
|
|
3345
|
-
radius: optional(uint(3)),
|
|
3346
|
-
border: optional(uint(2)),
|
|
3347
|
-
bevel: optional(uint(2)),
|
|
3348
|
-
fill: optional(enumOf(FILLS, { capacity: 8 })),
|
|
3349
|
-
screen: optional(enumOf(SCREEN_IDS, { capacity: 32 })),
|
|
3350
|
-
shadow: optional(uint(2)),
|
|
3351
|
-
glow: optional(uint(2)),
|
|
3352
|
-
motion: optional(enumOf(MOTIONS, { capacity: 8 })),
|
|
3353
|
-
body: optional(uint(5)),
|
|
3354
|
-
caps: optional(bool()),
|
|
3355
|
-
font: optional(FONT_PINS),
|
|
3356
|
-
icon: optional(enumOf(ICON_STYLES, { capacity: 8 })),
|
|
3357
|
-
unit: optional(uint(4)),
|
|
3358
|
-
teams: optional(uint(5)),
|
|
3359
|
-
teamHues: optional(array(hue, { max: 24 }))
|
|
3360
|
-
}, { open: true });
|
|
3361
|
-
var UI_THEME = named("keel/ui/theme", struct({
|
|
3362
|
-
generator: ref("modules"),
|
|
3363
|
-
seed: seedText,
|
|
3364
|
-
culture: enumOf(CULTURES, { capacity: 16 }),
|
|
3365
|
-
pins: THEME_PINS
|
|
3366
|
-
}, { open: true }), { doc: "A UI theme as its recipe: generator@version, seed, culture and sparse pins." });
|
|
3367
|
-
var GLYPH = struct({
|
|
3368
|
-
code: fixed(0, 1114111, 1, { k: 2, delta: true }),
|
|
3369
|
-
w: uint(6),
|
|
3370
|
-
h: uint(6),
|
|
3371
|
-
ox: varint(),
|
|
3372
|
-
oy: varint(),
|
|
3373
|
-
adv: uint(7),
|
|
3374
|
-
bits: planes(1)
|
|
3375
|
-
});
|
|
3376
|
-
var UI_FONT = named("keel/ui/font", struct({
|
|
3377
|
-
name: string(),
|
|
3378
|
-
size: uint(6),
|
|
3379
|
-
ascent: uint(7),
|
|
3380
|
-
descent: uint(6),
|
|
3381
|
-
lineHeight: uint(7),
|
|
3382
|
-
source: enumOf(["generated", "ttf", "bmfont", "grid", "browser", "codec"], { capacity: 16 }),
|
|
3383
|
-
glyphs: array(GLYPH),
|
|
3384
|
-
kern: array(tuple([varuint({ k: 5 }), varuint({ k: 5 }), varint()]))
|
|
3385
|
-
}, { open: true }), { doc: "A pixel font: metrics, 1-bit glyphs, kerning pairs." });
|
|
3386
|
-
var UI_FONT_RECIPE = named("keel/ui/font-recipe", struct({
|
|
3387
|
-
generator: ref("modules"),
|
|
3388
|
-
params: FONT_PARAMS,
|
|
3389
|
-
sizes: array(uint(6), { max: 31 })
|
|
3390
|
-
}, { open: true }), { doc: "A generated pixel font as its recipe: the family's parameters and the sizes used." });
|
|
3391
|
-
var size2 = alt([varint(), ref("sizes")]);
|
|
3392
|
-
var u = () => optional(varuint());
|
|
3393
|
-
function nodeSchema(driving) {
|
|
3394
|
-
return recursive((self) => {
|
|
3395
|
-
const legacy = extend(struct({
|
|
3396
|
-
type: enumOf(driving ? WIDGETS : WIDGETS.slice(0, -1), { capacity: 64 }),
|
|
3397
|
-
id: optional(ref("ids")),
|
|
3398
|
-
anchor: optional(enumOf(ANCHORS, { capacity: 16 })),
|
|
3399
|
-
x: optional(varint()),
|
|
3400
|
-
y: optional(varint()),
|
|
3401
|
-
w: optional(size2),
|
|
3402
|
-
h: optional(size2),
|
|
3403
|
-
minW: u(),
|
|
3404
|
-
maxW: u(),
|
|
3405
|
-
minH: u(),
|
|
3406
|
-
maxH: u(),
|
|
3407
|
-
dir: optional(enumOf(["free", "row", "col", "grid"], { capacity: 8 })),
|
|
3408
|
-
gap: u(),
|
|
3409
|
-
pad: u(),
|
|
3410
|
-
align: optional(enumOf(["start", "center", "end", "stretch"], { capacity: 8 })),
|
|
3411
|
-
justify: optional(enumOf(["start", "center", "end", "between"], { capacity: 8 })),
|
|
3412
|
-
grow: u(),
|
|
3413
|
-
cols: u(),
|
|
3414
|
-
cellH: u(),
|
|
3415
|
-
hidden: optional(bool()),
|
|
3416
|
-
frame: optional(enumOf([...FRAME_KINDS, "none"], { capacity: 16 })),
|
|
3417
|
-
mesh: optional(bool()),
|
|
3418
|
-
tone: optional(ref("tones")),
|
|
3419
|
-
font: optional(enumOf(["small", "body", "title", "display"], { capacity: 8 })),
|
|
3420
|
-
textAlign: optional(enumOf(["left", "center", "right"], { capacity: 4 })),
|
|
3421
|
-
wrap: optional(bool()),
|
|
3422
|
-
maxLines: u(),
|
|
3423
|
-
caps: optional(bool()),
|
|
3424
|
-
shadow: optional(bool()),
|
|
3425
|
-
text: optional(string()),
|
|
3426
|
-
title: optional(string()),
|
|
3427
|
-
icon: optional(ref("icons")),
|
|
3428
|
-
iconSize: u(),
|
|
3429
|
-
value: optional(num()),
|
|
3430
|
-
max: optional(num()),
|
|
3431
|
-
segments: u(),
|
|
3432
|
-
trail: optional(num()),
|
|
3433
|
-
hotkey: optional(ref("keys")),
|
|
3434
|
-
cooldown: optional(fixed(0, 1, 1 / 64, { off: "exact" })),
|
|
3435
|
-
count: u(),
|
|
3436
|
-
disabled: optional(bool()),
|
|
3437
|
-
active: optional(bool()),
|
|
3438
|
-
primary: optional(bool()),
|
|
3439
|
-
items: optional(array(string())),
|
|
3440
|
-
selected: optional(varint()),
|
|
3441
|
-
view: optional(tuple([fixed(0, 1, 1 / 1024, { off: "exact" }), fixed(0, 1, 1 / 1024, { off: "exact" }), fixed(0, 1, 1 / 1024, { off: "exact" }), fixed(0, 1, 1 / 1024, { off: "exact" })])),
|
|
3442
|
-
tip: optional(string()),
|
|
3443
|
-
focusable: optional(bool()),
|
|
3444
|
-
action: optional(ref("actions")),
|
|
3445
|
-
hole: optional(bool()),
|
|
3446
|
-
children: optional(array(self))
|
|
3447
|
-
}, { open: true }), {
|
|
3448
|
-
// (Added later, as an extension group: old records read as before.)
|
|
3449
|
-
tipDock: optional(bool()),
|
|
3450
|
-
trim: optional(string()),
|
|
3451
|
-
edge: optional(string()),
|
|
3452
|
-
scrim: optional(enumOf(["solid", "dither"], { capacity: 4 })),
|
|
3453
|
-
reflow: optional(bool()),
|
|
3454
|
-
iconFill: optional(bool()),
|
|
3455
|
-
hp: optional(num())
|
|
3456
|
-
});
|
|
3457
|
-
return driving ? extend(legacy, {
|
|
3458
|
-
// A separate extension group keeps the original group's field bitmap unchanged.
|
|
3459
|
-
drivingKind: optional(enumOf(DRIVING_KINDS, { capacity: 16 })),
|
|
3460
|
-
drivingVariant: optional(enumOf(DRIVING_VARIANTS, { capacity: 4 })),
|
|
3461
|
-
secondaryValue: optional(num()),
|
|
3462
|
-
secondaryMax: optional(num()),
|
|
3463
|
-
drivingRedline: optional(num())
|
|
3464
|
-
}) : legacy;
|
|
3465
|
-
});
|
|
3466
|
-
}
|
|
3467
|
-
var UI_NODE = nodeSchema(true);
|
|
3468
|
-
var LEGACY_UI_NODE = nodeSchema(false);
|
|
3469
|
-
var screenSchema = (root, version) => named("keel/ui/screen", struct({
|
|
3470
|
-
screen: string(),
|
|
3471
|
-
theme: optional(struct({ generator: ref("modules"), seed: seedText, culture: enumOf(CULTURES, { capacity: 16 }), pins: THEME_PINS }, { open: true })),
|
|
3472
|
-
root
|
|
3473
|
-
}, { open: true }), { version, doc: "A UI screen: its layout tree (and the theme recipe it was made with)." });
|
|
3474
|
-
var UI_SCREEN_V1 = screenSchema(LEGACY_UI_NODE, 1);
|
|
3475
|
-
var UI_SCREEN = screenSchema(UI_NODE, 2);
|
|
3476
|
-
registerSchema(UI_SCREEN_V1);
|
|
3477
|
-
registerSchema(UI_SCREEN);
|
|
3478
|
-
|
|
3479
|
-
// ../../../../../../keel-engine/packages/ui/src/import/inflate.ts
|
|
3480
|
-
function build(lengths, off, n) {
|
|
3481
|
-
const counts = new Uint16Array(16);
|
|
3482
|
-
const symbols = new Uint16Array(n);
|
|
3483
|
-
for (let i = 0; i < n; i += 1) counts[lengths[off + i]] += 1;
|
|
3484
|
-
counts[0] = 0;
|
|
3485
|
-
const offs = new Uint16Array(16);
|
|
3486
|
-
for (let i = 1; i < 16; i += 1) offs[i] = offs[i - 1] + counts[i - 1];
|
|
3487
|
-
for (let i = 0; i < n; i += 1) {
|
|
3488
|
-
const l = lengths[off + i];
|
|
3489
|
-
if (l) symbols[offs[l]++] = i;
|
|
3490
|
-
}
|
|
3491
|
-
return { counts, symbols };
|
|
3492
|
-
}
|
|
3493
|
-
var FIXED = (() => {
|
|
3494
|
-
const l = new Uint8Array(288);
|
|
3495
|
-
l.fill(8, 0, 144);
|
|
3496
|
-
l.fill(9, 144, 256);
|
|
3497
|
-
l.fill(7, 256, 280);
|
|
3498
|
-
l.fill(8, 280, 288);
|
|
3499
|
-
const d = new Uint8Array(30).fill(5);
|
|
3500
|
-
return { lit: build(l, 0, 288), dist: build(d, 0, 30) };
|
|
3501
|
-
})();
|
|
3502
|
-
|
|
3503
|
-
// ../../../../../../keel-engine/packages/ui/src/import/png.ts
|
|
3504
|
-
var CRC = (() => {
|
|
3505
|
-
const t = new Uint32Array(256);
|
|
3506
|
-
for (let n = 0; n < 256; n += 1) {
|
|
3507
|
-
let c = n;
|
|
3508
|
-
for (let k = 0; k < 8; k += 1) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
3509
|
-
t[n] = c >>> 0;
|
|
3510
|
-
}
|
|
3511
|
-
return t;
|
|
3512
|
-
})();
|
|
3513
|
-
|
|
3514
|
-
// ../../../../../../keel-engine/packages/ui/src/import/ttf.ts
|
|
3515
|
-
var DEFAULT_CODES = [...Array.from({ length: 95 }, (_, i) => 32 + i), 8230, 8226, 215, 176, 8592, 8593, 8594, 8595];
|
|
3516
|
-
|
|
3517
|
-
// ../../../../../../keel-engine/packages/react/src/design.ts
|
|
3518
|
-
var DESIGN_LANGUAGE = Object.freeze({
|
|
3519
|
-
id: "keel/react-design@1",
|
|
3520
|
-
rules: ["Canonical KEEL generators and renderer own the scene.", "React binds state, lifecycle and accessible controls to the same world.", "Controls stay on their authored world surfaces; DOM counterparts retain their placement.", "Theme recipes provide semantic palette, spacing, type, frames and motion.", "Pixel scenes use integer scale and nearest-neighbour sampling.", "Project-owned fonts and assets retain provenance.", "Seed and frame clocks are explicit; captures export real source geometry and state."],
|
|
3521
|
-
references: ["REDLINE: React host callbacks into the shared engine world.", "CRUCIBLE: React state controls a genuine KEEL pixel-rendered package room."],
|
|
3522
|
-
limitations: ["DOM primitives expose semantic theme roles, not every pixel UI frame decoration.", "A CSS font must be supplied by the project; generated pixel glyphs are available through keel/ui.", "The React adapter is host tooling, not an onchain registered React runtime."]
|
|
3523
|
-
});
|
|
3524
|
-
function themeTokens(theme, scale2 = 2) {
|
|
3525
|
-
if (!Number.isInteger(scale2) || scale2 < 1 || scale2 > 16) throw new RangeError("UI scale must be an integer from 1 to 16.");
|
|
3526
|
-
const p = theme.palette, hex2 = (r, i) => toHex(r[i] ?? r[0] ?? 0);
|
|
3527
|
-
const values = {
|
|
3528
|
-
"--keel-surface": hex2(p.surface, 2),
|
|
3529
|
-
"--keel-raised": hex2(p.surface, 3),
|
|
3530
|
-
"--keel-ink": hex2(p.ink, 1),
|
|
3531
|
-
"--keel-muted": hex2(p.ink, 0),
|
|
3532
|
-
"--keel-accent": hex2(p.accent, 2),
|
|
3533
|
-
"--keel-on-accent": toHex(p.onAccent),
|
|
3534
|
-
"--keel-outline": toHex(p.outline),
|
|
3535
|
-
"--keel-good": hex2(p.good, 2),
|
|
3536
|
-
"--keel-warn": hex2(p.warn, 2),
|
|
3537
|
-
"--keel-bad": hex2(p.bad, 2),
|
|
3538
|
-
"--keel-px": `${scale2}px`,
|
|
3539
|
-
"--keel-border": `${theme.frame.border * scale2}px`,
|
|
3540
|
-
"--keel-pad": `${theme.space.pad * scale2}px`,
|
|
3541
|
-
"--keel-gap": `${theme.space.gap * scale2}px`,
|
|
3542
|
-
"--keel-body": `${theme.type.body * scale2}px`,
|
|
3543
|
-
"--keel-motion": `${theme.motion.ms}ms`
|
|
3544
|
-
};
|
|
3545
|
-
for (const [name, ramp3] of Object.entries(p)) if (Array.isArray(ramp3) && typeof ramp3[0] === "number") ramp3.forEach((value, i) => {
|
|
3546
|
-
values[`--keel-${name}-${i}`] = toHex(value);
|
|
3547
|
-
});
|
|
3548
|
-
return values;
|
|
3549
|
-
}
|
|
3550
|
-
function recipeTheme(input = {}) {
|
|
3551
|
-
if (!input || typeof input !== "object" || Array.isArray(input)) throw new TypeError("Theme recipe must be an object.");
|
|
3552
|
-
const value = input;
|
|
3553
|
-
for (const key of Object.keys(value)) if (!["seed", "culture", "pins"].includes(key)) throw new TypeError(`Unknown recipe field ${key}.`);
|
|
3554
|
-
const seed = value.seed ?? "keel/react", culture = value.culture ?? "clean";
|
|
3555
|
-
if (typeof seed !== "string" || seed.length > 256 || !CULTURES.includes(culture)) throw new TypeError("Invalid seed or culture.");
|
|
3556
|
-
const pins = value.pins ?? {};
|
|
3557
|
-
if (!pins || typeof pins !== "object" || Array.isArray(pins)) throw new TypeError("Pins must be an object.");
|
|
3558
|
-
const allowed = { tone: ["dark", "light"], hue: [0, 360], accentHue: [0, 360], motion: ["snappy", "bouncy", "none"], corner: ["flat", "bevel", "inset", "notched", "rivets", "glow", "round"], body: [5, 16], unit: [1, 8], border: [1, 3], bevel: [0, 2], fill: ["solid", "dither", "gradient", "scan"], shadow: [0, 2], glow: [0, 2], caps: [true, false] };
|
|
3559
|
-
for (const [key, pin] of Object.entries(pins)) {
|
|
3560
|
-
const range = allowed[key];
|
|
3561
|
-
if (!range) throw new TypeError(`Unsupported pin ${key}.`);
|
|
3562
|
-
if (typeof range[0] === "number") {
|
|
3563
|
-
if (typeof pin !== "number" || !Number.isFinite(pin) || pin < range[0] || pin > range[1] || !key.endsWith("Hue") && key !== "hue" && !Number.isInteger(pin)) throw new TypeError(`Invalid pin ${key}.`);
|
|
3564
|
-
} else if (!range.includes(pin)) throw new TypeError(`Invalid pin ${key}.`);
|
|
3565
|
-
}
|
|
3566
|
-
return themeOf({ generator: THEME_GENERATOR, seed, culture, pins });
|
|
3567
|
-
}
|
|
3568
|
-
export {
|
|
3569
|
-
recipeTheme,
|
|
3570
|
-
themeTokens
|
|
3571
|
-
};
|
|
1
|
+
export { recipeTheme, themeTokens } from './keel-theme/schema-theme.mjs';
|