@aethervtt/shard-ui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/flex.js ADDED
@@ -0,0 +1,751 @@
1
+ const L = {
2
+ width: 0,
3
+ height: 1,
4
+ minWidth: 2,
5
+ maxWidth: 3,
6
+ minHeight: 4,
7
+ maxHeight: 5,
8
+ left: 6,
9
+ top: 7,
10
+ right: 8,
11
+ bottom: 9,
12
+ basis: 10
13
+ };
14
+ const LENGTHS = 11;
15
+ const Dir = { Row: 0, Column: 1, RowReverse: 2, ColumnReverse: 3 };
16
+ const Justify = {
17
+ Start: 0,
18
+ Center: 1,
19
+ End: 2,
20
+ SpaceBetween: 3,
21
+ SpaceAround: 4,
22
+ SpaceEvenly: 5
23
+ };
24
+ const Align = { Stretch: 0, Start: 1, Center: 2, End: 3 };
25
+ const PX = 0;
26
+ const PERCENT = 1;
27
+ function grow(a, n) {
28
+ if (a.length >= n) return a;
29
+ let len = Math.max(64, a.length * 2);
30
+ while (len < n) len *= 2;
31
+ const out = new a.constructor(len);
32
+ out.set(a);
33
+ return out;
34
+ }
35
+ const same = (a, b) => a === b || Number.isNaN(a) && Number.isNaN(b);
36
+ class FlexTree {
37
+ count = 0;
38
+ firstChild = new Int32Array(64);
39
+ nextSibling = new Int32Array(64);
40
+ /** 1: display none (skipped with its subtree). */
41
+ hidden = new Uint8Array(64);
42
+ absolute = new Uint8Array(64);
43
+ direction = new Uint8Array(64);
44
+ wrap = new Uint8Array(64);
45
+ justify = new Uint8Array(64);
46
+ alignItems = new Uint8Array(64);
47
+ alignSelf = new Uint8Array(64);
48
+ /** Per node, LENGTHS × (value, unit). */
49
+ lengths = new Float32Array(64 * LENGTHS * 2);
50
+ /** top, right, bottom, left. */
51
+ padding = new Float32Array(64 * 4);
52
+ margin = new Float32Array(64 * 4);
53
+ /** horizontal, vertical. */
54
+ gap = new Float32Array(64 * 2);
55
+ flexGrow = new Float32Array(64);
56
+ flexShrink = new Float32Array(64);
57
+ /** 1: a leaf measured by the Measure callback (text, image). */
58
+ measured = new Uint8Array(64);
59
+ /** 1: positioned by `anchorX/Y` (root coordinates) minus pivot × size, ignoring its parent. */
60
+ anchored = new Uint8Array(64);
61
+ anchorX = new Float32Array(64);
62
+ anchorY = new Float32Array(64);
63
+ pivotX = new Float32Array(64);
64
+ pivotY = new Float32Array(64);
65
+ /** Output: position relative to the parent's border box, and border-box size. */
66
+ x = new Float32Array(64);
67
+ y = new Float32Array(64);
68
+ w = new Float32Array(64);
69
+ h = new Float32Array(64);
70
+ /** Measure-only results, and the inputs they were measured for. */
71
+ mw = new Float32Array(64);
72
+ mh = new Float32Array(64);
73
+ cache = new Float32Array(64 * 6);
74
+ cacheValid = new Uint8Array(64);
75
+ /** Layout calls this pass (measure and perform), for describe. */
76
+ calls = 0;
77
+ reserve(n) {
78
+ if (this.firstChild.length >= n) return;
79
+ this.firstChild = grow(this.firstChild, n);
80
+ this.nextSibling = grow(this.nextSibling, n);
81
+ this.hidden = grow(this.hidden, n);
82
+ this.absolute = grow(this.absolute, n);
83
+ this.direction = grow(this.direction, n);
84
+ this.wrap = grow(this.wrap, n);
85
+ this.justify = grow(this.justify, n);
86
+ this.alignItems = grow(this.alignItems, n);
87
+ this.alignSelf = grow(this.alignSelf, n);
88
+ this.lengths = grow(this.lengths, n * LENGTHS * 2);
89
+ this.padding = grow(this.padding, n * 4);
90
+ this.margin = grow(this.margin, n * 4);
91
+ this.gap = grow(this.gap, n * 2);
92
+ this.flexGrow = grow(this.flexGrow, n);
93
+ this.flexShrink = grow(this.flexShrink, n);
94
+ this.measured = grow(this.measured, n);
95
+ this.anchored = grow(this.anchored, n);
96
+ this.anchorX = grow(this.anchorX, n);
97
+ this.anchorY = grow(this.anchorY, n);
98
+ this.pivotX = grow(this.pivotX, n);
99
+ this.pivotY = grow(this.pivotY, n);
100
+ this.x = grow(this.x, n);
101
+ this.y = grow(this.y, n);
102
+ this.w = grow(this.w, n);
103
+ this.h = grow(this.h, n);
104
+ this.mw = grow(this.mw, n);
105
+ this.mh = grow(this.mh, n);
106
+ this.cache = grow(this.cache, n * 6);
107
+ this.cacheValid = grow(this.cacheValid, n);
108
+ }
109
+ /** Clears to `n` nodes with default inputs (row, stretch, auto sizes, shrink 1). */
110
+ reset(n) {
111
+ this.reserve(n);
112
+ this.count = n;
113
+ this.firstChild.fill(-1, 0, n);
114
+ this.nextSibling.fill(-1, 0, n);
115
+ this.hidden.fill(0, 0, n);
116
+ this.absolute.fill(0, 0, n);
117
+ this.direction.fill(0, 0, n);
118
+ this.wrap.fill(0, 0, n);
119
+ this.justify.fill(0, 0, n);
120
+ this.alignItems.fill(0, 0, n);
121
+ this.alignSelf.fill(0, 0, n);
122
+ const len = this.lengths;
123
+ for (let i = 0; i < n * LENGTHS; i++) {
124
+ len[i * 2] = 0;
125
+ len[i * 2 + 1] = 2;
126
+ }
127
+ this.padding.fill(0, 0, n * 4);
128
+ this.margin.fill(0, 0, n * 4);
129
+ this.gap.fill(0, 0, n * 2);
130
+ this.flexGrow.fill(0, 0, n);
131
+ this.flexShrink.fill(1, 0, n);
132
+ this.measured.fill(0, 0, n);
133
+ this.anchored.fill(0, 0, n);
134
+ }
135
+ /** Sets a length slot: unit 0 px, 1 percent, 2 auto. */
136
+ setLength(node, slot, value, unit) {
137
+ const o = (node * LENGTHS + slot) * 2;
138
+ this.lengths[o] = value;
139
+ this.lengths[o + 1] = unit;
140
+ }
141
+ /** Appends `child` to `parent`'s children (after its last). */
142
+ append(parent, child, last) {
143
+ if (last[parent] < 0) this.firstChild[parent] = child;
144
+ else this.nextSibling[last[parent]] = child;
145
+ last[parent] = child;
146
+ }
147
+ }
148
+ let itemNode = new Int32Array(256);
149
+ let itemF = new Float32Array(256 * 8);
150
+ let top = 0;
151
+ let lineStart = new Int32Array(64);
152
+ let lineCount = new Int32Array(64);
153
+ let lineCross = new Float32Array(64);
154
+ let lineTop = 0;
155
+ const measureOut = new Float32Array(2);
156
+ let frozenFlags = new Uint8Array(256);
157
+ let violationFlags = new Uint8Array(256);
158
+ const F_BASE = 0;
159
+ const F_HYP = 1;
160
+ const F_TARGET = 2;
161
+ const F_MIN = 3;
162
+ const F_MAX = 4;
163
+ const F_CROSS = 5;
164
+ const F_MARGIN = 6;
165
+ const F_DEFINITE_CROSS = 7;
166
+ function reserveItems(n) {
167
+ const start = top;
168
+ top += n;
169
+ if (itemNode.length < top) {
170
+ itemNode = grow(itemNode, top);
171
+ itemF = grow(itemF, top * 8);
172
+ }
173
+ return start;
174
+ }
175
+ function reserveLines(n) {
176
+ const start = lineTop;
177
+ lineTop += n;
178
+ if (lineStart.length < lineTop) {
179
+ lineStart = grow(lineStart, lineTop);
180
+ lineCount = grow(lineCount, lineTop);
181
+ lineCross = grow(lineCross, lineTop);
182
+ }
183
+ return start;
184
+ }
185
+ function resolve(t, n, slot, ref) {
186
+ const o = (n * LENGTHS + slot) * 2;
187
+ const unit = t.lengths[o + 1];
188
+ if (unit === PX) return t.lengths[o];
189
+ if (unit === PERCENT) return ref * t.lengths[o] / 100;
190
+ return Number.NaN;
191
+ }
192
+ function clampSize(t, n, size, minSlot, maxSlot, ref, pad) {
193
+ const max = resolve(t, n, maxSlot, ref);
194
+ if (!Number.isNaN(max) && size > max) size = max;
195
+ const min = resolve(t, n, minSlot, ref);
196
+ if (!Number.isNaN(min) && size < min) size = min;
197
+ return size < pad ? pad : size;
198
+ }
199
+ const isRow = (d) => d === Dir.Row || d === Dir.RowReverse;
200
+ const isReverse = (d) => d === Dir.RowReverse || d === Dir.ColumnReverse;
201
+ function alignOf(t, parent, child) {
202
+ const self = t.alignSelf[child];
203
+ return self === 0 ? t.alignItems[parent] : self - 1;
204
+ }
205
+ function layoutTree(t, width, height, measure) {
206
+ t.calls = 0;
207
+ t.cacheValid.fill(0, 0, t.count);
208
+ frozenFlags = grow(frozenFlags, t.count);
209
+ violationFlags = grow(violationFlags, t.count);
210
+ top = 0;
211
+ lineTop = 0;
212
+ t.x[0] = 0;
213
+ t.y[0] = 0;
214
+ layoutNode(t, measure, 0, width, height, width, height, width, height, true);
215
+ }
216
+ function layoutNode(t, measure, n, knownW, knownH, availW, availH, ownerW, ownerH, perform) {
217
+ if (!perform && t.cacheValid[n]) {
218
+ const c = t.cache;
219
+ const o = n * 6;
220
+ if (same(c[o], knownW) && same(c[o + 1], knownH) && same(c[o + 2], availW) && same(c[o + 3], availH) && same(c[o + 4], ownerW) && same(c[o + 5], ownerH))
221
+ return;
222
+ }
223
+ t.calls++;
224
+ const p = t.padding;
225
+ const padT = p[n * 4];
226
+ const padR = p[n * 4 + 1];
227
+ const padB = p[n * 4 + 2];
228
+ const padL = p[n * 4 + 3];
229
+ const padH = padL + padR;
230
+ const padV = padT + padB;
231
+ let w = knownW;
232
+ let h = knownH;
233
+ if (Number.isNaN(w)) {
234
+ w = resolve(t, n, L.width, ownerW);
235
+ if (!Number.isNaN(w)) w = clampSize(t, n, w, L.minWidth, L.maxWidth, ownerW, padH);
236
+ }
237
+ if (Number.isNaN(h)) {
238
+ h = resolve(t, n, L.height, ownerH);
239
+ if (!Number.isNaN(h)) h = clampSize(t, n, h, L.minHeight, L.maxHeight, ownerH, padV);
240
+ }
241
+ if (!perform && !Number.isNaN(w) && !Number.isNaN(h)) {
242
+ finishMeasure(t, n, w, h, knownW, knownH, availW, availH, ownerW, ownerH);
243
+ return;
244
+ }
245
+ if (!Number.isNaN(availW)) {
246
+ const max = resolve(t, n, L.maxWidth, ownerW);
247
+ if (!Number.isNaN(max) && availW > max) availW = max;
248
+ }
249
+ const dir = t.direction[n];
250
+ const row = isRow(dir);
251
+ const gapMain = row ? t.gap[n * 2] : t.gap[n * 2 + 1];
252
+ const gapCross = row ? t.gap[n * 2 + 1] : t.gap[n * 2];
253
+ let k = 0;
254
+ let absolutes = 0;
255
+ for (let c = t.firstChild[n]; c >= 0; c = t.nextSibling[c]) {
256
+ if (t.hidden[c]) continue;
257
+ if (t.absolute[c] || t.anchored[c]) absolutes++;
258
+ else k++;
259
+ }
260
+ if (k === 0 && t.measured[n] && (Number.isNaN(w) || Number.isNaN(h))) {
261
+ const innerW2 = !Number.isNaN(w) ? w - padH : !Number.isNaN(availW) ? Math.max(0, availW - padH) : Number.NaN;
262
+ measure(n, innerW2, measureOut);
263
+ if (Number.isNaN(w)) {
264
+ w = clampSize(t, n, measureOut[0] + padH, L.minWidth, L.maxWidth, ownerW, padH);
265
+ if (measureOut[0] + padH !== w) measure(n, w - padH, measureOut);
266
+ }
267
+ if (Number.isNaN(h))
268
+ h = clampSize(t, n, measureOut[1] + padV, L.minHeight, L.maxHeight, ownerH, padV);
269
+ if (!perform) {
270
+ finishMeasure(t, n, w, h, knownW, knownH, availW, availH, ownerW, ownerH);
271
+ return;
272
+ }
273
+ t.w[n] = w;
274
+ t.h[n] = h;
275
+ if (absolutes > 0) placeAbsolutes(t, measure, n, w, h);
276
+ return;
277
+ }
278
+ let innerW = !Number.isNaN(w) ? w - padH : Number.NaN;
279
+ let innerH = !Number.isNaN(h) ? h - padV : Number.NaN;
280
+ let mainInner = row ? innerW : innerH;
281
+ let crossInner = row ? innerH : innerW;
282
+ const availCrossInner = row ? !Number.isNaN(availH) ? availH - padV : Number.NaN : !Number.isNaN(availW) ? availW - padH : Number.NaN;
283
+ const _availMainInner = row ? !Number.isNaN(availW) ? availW - padH : Number.NaN : !Number.isNaN(availH) ? availH - padV : Number.NaN;
284
+ const start = reserveItems(k);
285
+ const f = itemF;
286
+ {
287
+ let i = start;
288
+ for (let c = t.firstChild[n]; c >= 0; c = t.nextSibling[c]) {
289
+ if (t.hidden[c] || t.absolute[c] || t.anchored[c]) continue;
290
+ itemNode[i++] = c;
291
+ }
292
+ }
293
+ const wrap = t.wrap[n] !== 0;
294
+ for (let i = start; i < start + k; i++) {
295
+ const c = itemNode[i];
296
+ const m = t.margin;
297
+ const mMain = row ? m[c * 4 + 3] + m[c * 4 + 1] : m[c * 4] + m[c * 4 + 2];
298
+ const mCross = row ? m[c * 4] + m[c * 4 + 2] : m[c * 4 + 3] + m[c * 4 + 1];
299
+ const cp = t.padding;
300
+ const cPadMain = row ? cp[c * 4 + 3] + cp[c * 4 + 1] : cp[c * 4] + cp[c * 4 + 2];
301
+ const cPadCross = row ? cp[c * 4] + cp[c * 4 + 2] : cp[c * 4 + 3] + cp[c * 4 + 1];
302
+ let crossKnown = resolve(t, c, row ? L.height : L.width, crossInner);
303
+ if (!Number.isNaN(crossKnown)) {
304
+ crossKnown = clampSize(
305
+ t,
306
+ c,
307
+ crossKnown,
308
+ row ? L.minHeight : L.minWidth,
309
+ row ? L.maxHeight : L.maxWidth,
310
+ crossInner,
311
+ cPadCross
312
+ );
313
+ }
314
+ f[i * 8 + F_DEFINITE_CROSS] = crossKnown;
315
+ if (Number.isNaN(crossKnown) && !wrap && !Number.isNaN(crossInner) && alignOf(t, n, c) === Align.Stretch) {
316
+ crossKnown = clampSize(
317
+ t,
318
+ c,
319
+ Math.max(0, crossInner - mCross),
320
+ row ? L.minHeight : L.minWidth,
321
+ row ? L.maxHeight : L.maxWidth,
322
+ crossInner,
323
+ cPadCross
324
+ );
325
+ }
326
+ let base = resolve(t, c, L.basis, mainInner);
327
+ if (Number.isNaN(base)) base = resolve(t, c, row ? L.width : L.height, mainInner);
328
+ let content = Number.NaN;
329
+ if (Number.isNaN(base)) {
330
+ if (row) {
331
+ layoutNode(
332
+ t,
333
+ measure,
334
+ c,
335
+ Number.NaN,
336
+ crossKnown,
337
+ Number.NaN,
338
+ availCrossInner - mCross,
339
+ innerW,
340
+ innerH,
341
+ false
342
+ );
343
+ base = t.mw[c];
344
+ } else {
345
+ const aw = !Number.isNaN(crossKnown) ? crossKnown : availCrossInner - mCross;
346
+ layoutNode(t, measure, c, crossKnown, Number.NaN, aw, Number.NaN, innerW, innerH, false);
347
+ base = t.mh[c];
348
+ }
349
+ content = base;
350
+ }
351
+ let min = resolve(t, c, row ? L.minWidth : L.minHeight, mainInner);
352
+ if (Number.isNaN(min)) {
353
+ min = 0;
354
+ if (t.measured[c] && t.firstChild[c] < 0) {
355
+ if (row) {
356
+ measure(c, 0, measureOut);
357
+ min = measureOut[0] + cPadMain;
358
+ } else {
359
+ if (Number.isNaN(content)) {
360
+ const aw = !Number.isNaN(crossKnown) ? crossKnown : availCrossInner - mCross;
361
+ layoutNode(t, measure, c, crossKnown, Number.NaN, aw, Number.NaN, innerW, innerH, false);
362
+ content = t.mh[c];
363
+ }
364
+ min = content;
365
+ }
366
+ const specified = resolve(t, c, row ? L.width : L.height, mainInner);
367
+ if (!Number.isNaN(specified) && specified < min) min = specified;
368
+ const max2 = resolve(t, c, row ? L.maxWidth : L.maxHeight, mainInner);
369
+ if (!Number.isNaN(max2) && max2 < min) min = max2;
370
+ }
371
+ }
372
+ if (min < cPadMain) min = cPadMain;
373
+ let max = resolve(t, c, row ? L.maxWidth : L.maxHeight, mainInner);
374
+ if (Number.isNaN(max)) max = Number.POSITIVE_INFINITY;
375
+ let hyp = base;
376
+ if (hyp > max) hyp = max;
377
+ if (hyp < min) hyp = min;
378
+ f[i * 8 + F_BASE] = base;
379
+ f[i * 8 + F_HYP] = hyp;
380
+ f[i * 8 + F_TARGET] = hyp;
381
+ f[i * 8 + F_MIN] = min;
382
+ f[i * 8 + F_MAX] = max;
383
+ f[i * 8 + F_CROSS] = crossKnown;
384
+ f[i * 8 + F_MARGIN] = mMain;
385
+ }
386
+ if (Number.isNaN(mainInner)) {
387
+ let content = gapMain * Math.max(0, k - 1);
388
+ for (let i = start; i < start + k; i++) content += f[i * 8 + F_HYP] + f[i * 8 + F_MARGIN];
389
+ if (row) {
390
+ w = clampSize(t, n, content + padH, L.minWidth, L.maxWidth, ownerW, padH);
391
+ innerW = w - padH;
392
+ mainInner = innerW;
393
+ } else {
394
+ h = clampSize(t, n, content + padV, L.minHeight, L.maxHeight, ownerH, padV);
395
+ innerH = h - padV;
396
+ mainInner = innerH;
397
+ }
398
+ }
399
+ const lines = reserveLines(Math.max(1, k));
400
+ let lineN = 0;
401
+ const limit = mainInner;
402
+ {
403
+ let used = 0;
404
+ let inLine = 0;
405
+ for (let i = start; i < start + k; i++) {
406
+ const outer = f[i * 8 + F_HYP] + f[i * 8 + F_MARGIN];
407
+ if (wrap && inLine > 0 && !Number.isNaN(limit) && used + gapMain + outer > limit + 1e-3) {
408
+ lineN++;
409
+ used = 0;
410
+ inLine = 0;
411
+ }
412
+ if (inLine === 0) {
413
+ lineStart[lines + lineN] = i;
414
+ lineCount[lines + lineN] = 0;
415
+ }
416
+ used += (inLine > 0 ? gapMain : 0) + outer;
417
+ lineCount[lines + lineN]++;
418
+ inLine++;
419
+ }
420
+ if (k > 0) lineN++;
421
+ }
422
+ for (let l = lines; l < lines + lineN; l++)
423
+ resolveFlexible(t, lineStart[l], lineCount[l], mainInner, gapMain);
424
+ for (let i = start; i < start + k; i++) {
425
+ const c = itemNode[i];
426
+ let cross = f[i * 8 + F_DEFINITE_CROSS];
427
+ if (Number.isNaN(cross)) {
428
+ const m = t.margin;
429
+ const mCross = row ? m[c * 4] + m[c * 4 + 2] : m[c * 4 + 3] + m[c * 4 + 1];
430
+ const main = f[i * 8 + F_TARGET];
431
+ if (row) {
432
+ layoutNode(
433
+ t,
434
+ measure,
435
+ c,
436
+ main,
437
+ Number.NaN,
438
+ main,
439
+ availCrossInner - mCross,
440
+ innerW,
441
+ innerH,
442
+ false
443
+ );
444
+ cross = t.mh[c];
445
+ } else {
446
+ const aw = !Number.isNaN(crossInner) ? crossInner - mCross : availCrossInner - mCross;
447
+ layoutNode(t, measure, c, Number.NaN, main, aw, main, innerW, innerH, false);
448
+ cross = t.mw[c];
449
+ }
450
+ }
451
+ f[i * 8 + F_CROSS] = cross;
452
+ }
453
+ let crossSum = 0;
454
+ for (let l = lines; l < lines + lineN; l++) {
455
+ let lc = 0;
456
+ for (let i = lineStart[l]; i < lineStart[l] + lineCount[l]; i++) {
457
+ const c = itemNode[i];
458
+ const m = t.margin;
459
+ const mCross = row ? m[c * 4] + m[c * 4 + 2] : m[c * 4 + 3] + m[c * 4 + 1];
460
+ const outer = f[i * 8 + F_CROSS] + mCross;
461
+ if (outer > lc) lc = outer;
462
+ }
463
+ lineCross[l] = lc;
464
+ crossSum += lc;
465
+ }
466
+ crossSum += gapCross * Math.max(0, lineN - 1);
467
+ if (Number.isNaN(crossInner)) {
468
+ if (row) {
469
+ h = clampSize(t, n, crossSum + padV, L.minHeight, L.maxHeight, ownerH, padV);
470
+ innerH = h - padV;
471
+ crossInner = innerH;
472
+ } else {
473
+ w = clampSize(t, n, crossSum + padH, L.minWidth, L.maxWidth, ownerW, padH);
474
+ innerW = w - padH;
475
+ crossInner = innerW;
476
+ }
477
+ }
478
+ if (!wrap && lineN === 1) lineCross[lines] = crossInner;
479
+ else if (lineN > 0 && crossInner > crossSum) {
480
+ const extra = (crossInner - crossSum) / lineN;
481
+ for (let l = lines; l < lines + lineN; l++) lineCross[l] = lineCross[l] + extra;
482
+ }
483
+ if (!perform) {
484
+ top = start;
485
+ lineTop = lines;
486
+ finishMeasure(t, n, w, h, knownW, knownH, availW, availH, ownerW, ownerH);
487
+ return;
488
+ }
489
+ t.w[n] = w;
490
+ t.h[n] = h;
491
+ const reverse = isReverse(dir);
492
+ const justify = t.justify[n];
493
+ let lineOffset = 0;
494
+ for (let l = lines; l < lines + lineN; l++) {
495
+ const first = lineStart[l];
496
+ const count = lineCount[l];
497
+ let used = gapMain * Math.max(0, count - 1);
498
+ for (let i = first; i < first + count; i++) {
499
+ const c = itemNode[i];
500
+ const m = t.margin;
501
+ used += f[i * 8 + F_TARGET] + (row ? m[c * 4 + 3] + m[c * 4 + 1] : m[c * 4] + m[c * 4 + 2]);
502
+ }
503
+ const free = mainInner - used;
504
+ let pos = 0;
505
+ let between = gapMain;
506
+ let mode = justify;
507
+ if (free < 0 && mode >= Justify.SpaceBetween) mode = Justify.Start;
508
+ if (mode === Justify.Center) pos = free / 2;
509
+ else if (mode === Justify.End) pos = free;
510
+ else if (mode === Justify.SpaceBetween) between += count > 1 ? free / (count - 1) : 0;
511
+ else if (mode === Justify.SpaceAround) {
512
+ pos = free / count / 2;
513
+ between += free / count;
514
+ } else if (mode === Justify.SpaceEvenly) {
515
+ pos = free / (count + 1);
516
+ between += free / (count + 1);
517
+ }
518
+ const lc = lineCross[l];
519
+ for (let i = first; i < first + count; i++) {
520
+ const c = itemNode[i];
521
+ const m = t.margin;
522
+ const mA = row ? m[c * 4 + 3] : m[c * 4];
523
+ const mB = row ? m[c * 4 + 1] : m[c * 4 + 2];
524
+ const mStart = reverse ? mB : mA;
525
+ const mEnd = reverse ? mA : mB;
526
+ const mCrossStart = row ? m[c * 4] : m[c * 4 + 3];
527
+ const mCrossEnd = row ? m[c * 4 + 2] : m[c * 4 + 1];
528
+ const main = f[i * 8 + F_TARGET];
529
+ let cross = f[i * 8 + F_CROSS];
530
+ const align = alignOf(t, n, c);
531
+ if (align === Align.Stretch && Number.isNaN(f[i * 8 + F_DEFINITE_CROSS])) {
532
+ const cp = t.padding;
533
+ const cPadCross = row ? cp[c * 4] + cp[c * 4 + 2] : cp[c * 4 + 3] + cp[c * 4 + 1];
534
+ cross = clampSize(
535
+ t,
536
+ c,
537
+ Math.max(0, lc - mCrossStart - mCrossEnd),
538
+ row ? L.minHeight : L.minWidth,
539
+ row ? L.maxHeight : L.maxWidth,
540
+ crossInner,
541
+ cPadCross
542
+ );
543
+ }
544
+ const free2 = lc - cross - mCrossStart - mCrossEnd;
545
+ const crossPos = lineOffset + mCrossStart + (align === Align.Center ? free2 / 2 : align === Align.End ? free2 : 0);
546
+ let mainPos = pos + mStart;
547
+ if (reverse) mainPos = mainInner - mainPos - main;
548
+ pos += mStart + main + mEnd + between;
549
+ let x;
550
+ let y;
551
+ let cw;
552
+ let ch;
553
+ if (row) {
554
+ x = padL + mainPos;
555
+ y = padT + crossPos;
556
+ cw = main;
557
+ ch = cross;
558
+ } else {
559
+ x = padL + crossPos;
560
+ y = padT + mainPos;
561
+ cw = cross;
562
+ ch = main;
563
+ }
564
+ const left = resolve(t, c, L.left, innerW);
565
+ const right = resolve(t, c, L.right, innerW);
566
+ const topO = resolve(t, c, L.top, innerH);
567
+ const bottom = resolve(t, c, L.bottom, innerH);
568
+ if (!Number.isNaN(left)) x += left;
569
+ else if (!Number.isNaN(right)) x -= right;
570
+ if (!Number.isNaN(topO)) y += topO;
571
+ else if (!Number.isNaN(bottom)) y -= bottom;
572
+ t.x[c] = x;
573
+ t.y[c] = y;
574
+ layoutNode(t, measure, c, cw, ch, Number.NaN, Number.NaN, innerW, innerH, true);
575
+ }
576
+ lineOffset += lc + gapCross;
577
+ }
578
+ top = start;
579
+ lineTop = lines;
580
+ if (absolutes > 0) placeAbsolutes(t, measure, n, w, h);
581
+ }
582
+ function finishMeasure(t, n, w, h, knownW, knownH, availW, availH, ownerW, ownerH) {
583
+ t.mw[n] = w;
584
+ t.mh[n] = h;
585
+ const c = t.cache;
586
+ const o = n * 6;
587
+ c[o] = knownW;
588
+ c[o + 1] = knownH;
589
+ c[o + 2] = availW;
590
+ c[o + 3] = availH;
591
+ c[o + 4] = ownerW;
592
+ c[o + 5] = ownerH;
593
+ t.cacheValid[n] = 1;
594
+ }
595
+ function resolveFlexible(t, first, count, inner, gap) {
596
+ const f = itemF;
597
+ let sumHyp = gap * Math.max(0, count - 1);
598
+ for (let i = first; i < first + count; i++) sumHyp += f[i * 8 + F_HYP] + f[i * 8 + F_MARGIN];
599
+ const growing = sumHyp < inner;
600
+ let unfrozen = 0;
601
+ for (let i = first; i < first + count; i++) {
602
+ const c = itemNode[i];
603
+ const factor = growing ? t.flexGrow[c] : t.flexShrink[c];
604
+ const base = f[i * 8 + F_BASE];
605
+ const hyp = f[i * 8 + F_HYP];
606
+ const frozen = factor === 0 || growing && base > hyp || !growing && base < hyp;
607
+ frozenFlags[i - first] = frozen ? 1 : 0;
608
+ f[i * 8 + F_TARGET] = hyp;
609
+ if (!frozen) unfrozen++;
610
+ }
611
+ if (unfrozen === 0) return;
612
+ let initialFree = inner - gap * Math.max(0, count - 1);
613
+ for (let i = first; i < first + count; i++) {
614
+ const margin = f[i * 8 + F_MARGIN];
615
+ initialFree -= margin + (frozenFlags[i - first] ? f[i * 8 + F_TARGET] : f[i * 8 + F_BASE]);
616
+ }
617
+ for (let iteration = 0; iteration < count + 1 && unfrozen > 0; iteration++) {
618
+ let free = inner - gap * Math.max(0, count - 1);
619
+ let sumFactor = 0;
620
+ let sumScaled = 0;
621
+ for (let i = first; i < first + count; i++) {
622
+ const c = itemNode[i];
623
+ const margin = f[i * 8 + F_MARGIN];
624
+ if (frozenFlags[i - first]) free -= margin + f[i * 8 + F_TARGET];
625
+ else {
626
+ free -= margin + f[i * 8 + F_BASE];
627
+ sumFactor += growing ? t.flexGrow[c] : t.flexShrink[c];
628
+ sumScaled += t.flexShrink[c] * f[i * 8 + F_BASE];
629
+ }
630
+ }
631
+ if (sumFactor < 1) {
632
+ const scaled = initialFree * sumFactor;
633
+ if (Math.abs(scaled) < Math.abs(free)) free = scaled;
634
+ }
635
+ let violation = 0;
636
+ for (let i = first; i < first + count; i++) {
637
+ if (frozenFlags[i - first]) continue;
638
+ const c = itemNode[i];
639
+ const base = f[i * 8 + F_BASE];
640
+ let target = base;
641
+ if (growing) {
642
+ if (sumFactor > 0) target = base + free * t.flexGrow[c] / sumFactor;
643
+ } else if (sumScaled > 0) {
644
+ target = base + free * t.flexShrink[c] * base / sumScaled;
645
+ }
646
+ const min = f[i * 8 + F_MIN];
647
+ const max = f[i * 8 + F_MAX];
648
+ let clamped = target;
649
+ if (clamped > max) clamped = max;
650
+ if (clamped < min) clamped = min;
651
+ violation += clamped - target;
652
+ f[i * 8 + F_TARGET] = clamped;
653
+ violationFlags[i - first] = clamped > target ? 1 : clamped < target ? 2 : 0;
654
+ }
655
+ for (let i = first; i < first + count; i++) {
656
+ if (frozenFlags[i - first]) continue;
657
+ const v = violationFlags[i - first];
658
+ if (Math.abs(violation) < 1e-6 || violation > 0 && v === 1 || violation < 0 && v === 2) {
659
+ frozenFlags[i - first] = 1;
660
+ unfrozen--;
661
+ }
662
+ }
663
+ }
664
+ }
665
+ function placeAbsolutes(t, measure, n, w, h) {
666
+ const p = t.padding;
667
+ const padT = p[n * 4];
668
+ const padR = p[n * 4 + 1];
669
+ const padB = p[n * 4 + 2];
670
+ const padL = p[n * 4 + 3];
671
+ const dir = t.direction[n];
672
+ const row = isRow(dir);
673
+ const reverse = isReverse(dir);
674
+ for (let c = t.firstChild[n]; c >= 0; c = t.nextSibling[c]) {
675
+ if (t.hidden[c] || !(t.absolute[c] || t.anchored[c])) continue;
676
+ const m = t.margin;
677
+ const mT = m[c * 4];
678
+ const mR = m[c * 4 + 1];
679
+ const mB = m[c * 4 + 2];
680
+ const mL = m[c * 4 + 3];
681
+ const anchored = t.anchored[c] !== 0;
682
+ const left = anchored ? Number.NaN : resolve(t, c, L.left, w);
683
+ const right = anchored ? Number.NaN : resolve(t, c, L.right, w);
684
+ const topO = anchored ? Number.NaN : resolve(t, c, L.top, h);
685
+ const bottom = anchored ? Number.NaN : resolve(t, c, L.bottom, h);
686
+ const cp = t.padding;
687
+ const cPadH = cp[c * 4 + 1] + cp[c * 4 + 3];
688
+ const cPadV = cp[c * 4] + cp[c * 4 + 2];
689
+ let cw = resolve(t, c, L.width, w);
690
+ if (Number.isNaN(cw) && !Number.isNaN(left) && !Number.isNaN(right))
691
+ cw = Math.max(0, w - left - right - mL - mR);
692
+ if (!Number.isNaN(cw)) cw = clampSize(t, c, cw, L.minWidth, L.maxWidth, w, cPadH);
693
+ let ch = resolve(t, c, L.height, h);
694
+ if (Number.isNaN(ch) && !Number.isNaN(topO) && !Number.isNaN(bottom))
695
+ ch = Math.max(0, h - topO - bottom - mT - mB);
696
+ if (!Number.isNaN(ch)) ch = clampSize(t, c, ch, L.minHeight, L.maxHeight, h, cPadV);
697
+ if (Number.isNaN(cw) || Number.isNaN(ch)) {
698
+ const aw = w - (!Number.isNaN(left) ? left : 0) - (!Number.isNaN(right) ? right : 0) - mL - mR;
699
+ layoutNode(t, measure, c, cw, ch, aw, Number.NaN, w, h, false);
700
+ if (Number.isNaN(cw)) cw = t.mw[c];
701
+ if (Number.isNaN(ch)) {
702
+ layoutNode(t, measure, c, cw, Number.NaN, cw, Number.NaN, w, h, false);
703
+ ch = t.mh[c];
704
+ }
705
+ }
706
+ let x;
707
+ let y;
708
+ if (anchored) {
709
+ x = t.anchorX[c] - t.pivotX[c] * cw;
710
+ y = t.anchorY[c] - t.pivotY[c] * ch;
711
+ } else {
712
+ const innerW = w - padL - padR;
713
+ const innerH = h - padT - padB;
714
+ let justify = t.justify[n];
715
+ if (justify === Justify.SpaceBetween) justify = Justify.Start;
716
+ else if (justify >= Justify.SpaceAround) justify = Justify.Center;
717
+ if (reverse)
718
+ justify = justify === Justify.Start ? Justify.End : justify === Justify.End ? Justify.Start : justify;
719
+ let align = alignOf(t, n, c);
720
+ if (align === Align.Stretch) align = Align.Start;
721
+ const mainMode = justify === Justify.Start ? 0 : justify === Justify.Center ? 1 : 2;
722
+ const crossMode = align === Align.Start ? 0 : align === Align.Center ? 1 : 2;
723
+ const xMode = row ? mainMode : crossMode;
724
+ const yMode = row ? crossMode : mainMode;
725
+ if (!Number.isNaN(left)) x = left + mL;
726
+ else if (!Number.isNaN(right)) x = w - right - mR - cw;
727
+ else {
728
+ const free = innerW - cw - mL - mR;
729
+ x = padL + mL + (xMode === 1 ? free / 2 : xMode === 2 ? free : 0);
730
+ }
731
+ if (!Number.isNaN(topO)) y = topO + mT;
732
+ else if (!Number.isNaN(bottom)) y = h - bottom - mB - ch;
733
+ else {
734
+ const free = innerH - ch - mT - mB;
735
+ y = padT + mT + (yMode === 1 ? free / 2 : yMode === 2 ? free : 0);
736
+ }
737
+ }
738
+ t.x[c] = x;
739
+ t.y[c] = y;
740
+ layoutNode(t, measure, c, cw, ch, Number.NaN, Number.NaN, w, h, true);
741
+ }
742
+ }
743
+ export {
744
+ Align,
745
+ Dir,
746
+ FlexTree,
747
+ Justify,
748
+ L,
749
+ LENGTHS,
750
+ layoutTree
751
+ };