@andrew_l/vue-stdout 0.0.2

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/index.mjs ADDED
@@ -0,0 +1,1584 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: true });
6
+ };
7
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
+
9
+ // src/components/Box.tsx
10
+ import { resolveComponent as _resolveComponent, createVNode as _createVNode } from "vue";
11
+ var Box = (props, {
12
+ slots
13
+ }) => {
14
+ return _createVNode(_resolveComponent("box"), props, {
15
+ default: () => slots.default?.()
16
+ });
17
+ };
18
+ Box.displayName = "Box";
19
+
20
+ // src/components/NewLine.tsx
21
+ import { resolveComponent as _resolveComponent2, isVNode as _isVNode, createVNode as _createVNode2 } from "vue";
22
+ function _isSlot(s) {
23
+ return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !_isVNode(s);
24
+ }
25
+ var NewLine = ({
26
+ count = 1
27
+ }) => {
28
+ let _slot;
29
+ return _createVNode2(_resolveComponent2("stdout-text"), null, _isSlot(_slot = "\n".repeat(count)) ? _slot : {
30
+ default: () => [_slot]
31
+ });
32
+ };
33
+ NewLine.displayName = "NewLine";
34
+
35
+ // src/components/ProgressBar.tsx
36
+ import { computed, defineComponent, shallowRef as shallowRef2, createVNode as _createVNode3 } from "vue";
37
+
38
+ // src/hooks/useContainerSize.ts
39
+ import { ref, toValue as toValue2, watch as watch2 } from "vue";
40
+
41
+ // src/hooks/useEventListener.ts
42
+ import { onScopeDispose, toValue, watch } from "vue";
43
+ function useEventListener(target, eventName, listener) {
44
+ const cleanups = [];
45
+ const cleanup = () => {
46
+ cleanups.forEach((fn) => fn());
47
+ cleanups.length = 0;
48
+ };
49
+ const register = (el, event, listener2) => {
50
+ el.on(event, listener2);
51
+ return () => {
52
+ el.off(event, listener2);
53
+ };
54
+ };
55
+ const stopWatch = watch(() => toValue(target), (el) => {
56
+ cleanup();
57
+ if (!el) return;
58
+ cleanups.push(register(el, eventName, listener));
59
+ }, {
60
+ immediate: true,
61
+ flush: "post"
62
+ });
63
+ const stop = () => {
64
+ stopWatch();
65
+ cleanup();
66
+ };
67
+ onScopeDispose(stop);
68
+ return stop;
69
+ }
70
+
71
+ // src/hooks/useContainerSize.ts
72
+ function useContainerSize(target) {
73
+ const width = ref(0);
74
+ const height = ref(0);
75
+ const computeSize = (node) => {
76
+ const box = node.getBoundingClientRect();
77
+ width.value = box.width;
78
+ height.value = box.height;
79
+ };
80
+ useEventListener(target, "resize", () => {
81
+ computeSize(toValue2(target));
82
+ });
83
+ watch2(() => toValue2(target), (newNode) => {
84
+ if (newNode) computeSize(newNode);
85
+ }, {
86
+ immediate: true
87
+ });
88
+ return {
89
+ width,
90
+ height
91
+ };
92
+ }
93
+
94
+ // src/hooks/useDOMElement.ts
95
+ import { getCurrentInstance, onMounted, shallowRef } from "vue";
96
+ function useDOMElement() {
97
+ const instance = getCurrentInstance();
98
+ const node = shallowRef(null);
99
+ onMounted(() => {
100
+ node.value = instance.vnode?.el ?? null;
101
+ });
102
+ return node;
103
+ }
104
+
105
+ // src/components/ProgressBar.tsx
106
+ var remainingCharacter = "\u2591";
107
+ var completedCharacter = "\u2588";
108
+ var ProgressBar = defineComponent((props) => {
109
+ const progressElement = shallowRef2(null);
110
+ const {
111
+ width
112
+ } = useContainerSize(progressElement);
113
+ const percent = computed(() => {
114
+ const min = props.min ?? 0;
115
+ const max = props.max ?? 100;
116
+ return Math.min((props.value - min) / max, 1);
117
+ });
118
+ const percentText = computed(() => {
119
+ return Math.floor(percent.value * 100) + "%";
120
+ });
121
+ const chars = computed(() => {
122
+ let availableSpace = Math.max(width.value - percentText.value.length - 1, 0);
123
+ if (!availableSpace) return "";
124
+ const completeChars = Math.floor(availableSpace * percent.value);
125
+ const renamingChars = availableSpace - completeChars;
126
+ return completedCharacter.repeat(completeChars) + remainingCharacter.repeat(renamingChars);
127
+ });
128
+ return () => {
129
+ const borderStyle = props.variant ?? "round";
130
+ return _createVNode3(Box, {
131
+ "borderStyle": borderStyle,
132
+ "flexDirection": "row",
133
+ "justifyContent": "space-between",
134
+ "gap": 1,
135
+ "ref": progressElement
136
+ }, {
137
+ default: () => [_createVNode3(Box, {
138
+ "flexGrow": 1
139
+ }, {
140
+ default: () => [_createVNode3("span", {
141
+ "color": props.color
142
+ }, [chars.value])]
143
+ }), _createVNode3(Box, {
144
+ "width": 4
145
+ }, {
146
+ default: () => [props.showPercent && _createVNode3("span", {
147
+ "color": props.color
148
+ }, [percentText.value])]
149
+ })]
150
+ });
151
+ };
152
+ }, {
153
+ name: "ProgressBar",
154
+ props: ["min", "max", "value", "color", "backgroundColor", "showPercent", "variant"]
155
+ });
156
+
157
+ // src/components/Text.tsx
158
+ import { createVNode as _createVNode4 } from "vue";
159
+ var Text = (props, {
160
+ slots
161
+ }) => {
162
+ return _createVNode4("span", props, [slots.default?.()]);
163
+ };
164
+ Text.displayName = "Text";
165
+
166
+ // src/Container.ts
167
+ import ansiEscapes from "ansi-escapes";
168
+
169
+ // src/stdout.ts
170
+ import { isString } from "@andrew_l/toolkit";
171
+ function cleanLines(fromNumber, toNumber) {
172
+ for (let line = fromNumber; line < toNumber; line++) {
173
+ process.stdout.cursorTo(0, line);
174
+ process.stdout.clearLine(1);
175
+ }
176
+ }
177
+ function writeCleaner(stdout, y) {
178
+ let prevHeight = 0;
179
+ return (...args) => {
180
+ const text = args.map((v) => isString(v) ? v : JSON.stringify(v, null, 2)).join("\n\n");
181
+ stdout.cursorTo(0, y);
182
+ stdout.write(text);
183
+ const lineHeight = stdout.columns;
184
+ const newLength = text.split("\n").map((v) => Math.max(v.length / lineHeight, 1)).reduce((a, b) => a + b, 0);
185
+ cleanLines(y + prevHeight, y + newLength);
186
+ prevHeight = newLength;
187
+ };
188
+ }
189
+
190
+ // src/tree/NodeTree.ts
191
+ import { EventEmitter } from "node:events";
192
+ var NodeTree = class extends EventEmitter {
193
+ constructor() {
194
+ super(...arguments);
195
+ __publicField(this, "nodeName", "NodeTree");
196
+ __publicField(this, "parentNode", null);
197
+ __publicField(this, "childNodes", []);
198
+ }
199
+ getDisplayName() {
200
+ return this.nodeName;
201
+ }
202
+ getDisplayData() {
203
+ return {};
204
+ }
205
+ toJSON() {
206
+ return {
207
+ ...this.getDisplayData(),
208
+ childNodes: this.childNodes.map((v) => v.toJSON())
209
+ };
210
+ }
211
+ get lastChild() {
212
+ return this.childNodes.at(-1) ?? null;
213
+ }
214
+ get firstChild() {
215
+ return this.childNodes.at(0) ?? null;
216
+ }
217
+ get nextSibling() {
218
+ const parent = this.parentNode;
219
+ if (!parent) {
220
+ return null;
221
+ }
222
+ const i = parent.childNodes.indexOf(this);
223
+ return parent.childNodes[i + 1] || null;
224
+ }
225
+ get previousSibling() {
226
+ const parent = this.parentNode;
227
+ if (!parent) {
228
+ return null;
229
+ }
230
+ const i = parent.childNodes.indexOf(this);
231
+ return parent.childNodes[i - 1] || null;
232
+ }
233
+ appendChild(node) {
234
+ this.insertBefore(node);
235
+ }
236
+ removeChild(node) {
237
+ const i = this.childNodes.indexOf(node);
238
+ if (i > -1) {
239
+ node.remove();
240
+ }
241
+ }
242
+ insertBefore(child, ref2) {
243
+ const parent = this;
244
+ let refIndex;
245
+ if (ref2) {
246
+ refIndex = this.childNodes.indexOf(ref2);
247
+ if (refIndex === -1) {
248
+ throw new Error("ref is not a child of parent");
249
+ }
250
+ }
251
+ child.remove();
252
+ child.parentNode = parent;
253
+ refIndex = ref2 ? parent.childNodes.indexOf(ref2) : -1;
254
+ if (refIndex === -1) {
255
+ parent.childNodes.push(child);
256
+ } else {
257
+ parent.childNodes.splice(refIndex, 0, child);
258
+ }
259
+ }
260
+ remove() {
261
+ const parent = this.parentNode;
262
+ if (!parent) return;
263
+ const i = parent.childNodes.indexOf(this);
264
+ if (i > -1) {
265
+ parent.childNodes.splice(i, 1);
266
+ } else {
267
+ throw Error("target is not a childNode of parent");
268
+ }
269
+ this.parentNode = null;
270
+ }
271
+ /** @internal */
272
+ destroy() {
273
+ this.remove();
274
+ this.childNodes.forEach((c) => c.destroy());
275
+ this.childNodes = [];
276
+ }
277
+ };
278
+
279
+ // src/tree/DOMTree/DOMNode.ts
280
+ var nodeId = 0;
281
+ var DOMNodeType = /* @__PURE__ */ ((DOMNodeType2) => {
282
+ DOMNodeType2[DOMNodeType2["DOCUMENT"] = 0] = "DOCUMENT";
283
+ DOMNodeType2[DOMNodeType2["ELEMENT_NODE"] = 1] = "ELEMENT_NODE";
284
+ DOMNodeType2[DOMNodeType2["TEXT_NODE"] = 3] = "TEXT_NODE";
285
+ DOMNodeType2[DOMNodeType2["COMMENT_NODE"] = 8] = "COMMENT_NODE";
286
+ return DOMNodeType2;
287
+ })(DOMNodeType || {});
288
+ var DOMNode = class extends NodeTree {
289
+ constructor() {
290
+ super();
291
+ __publicField(this, "id");
292
+ __publicField(this, "nodeType", 1 /* ELEMENT_NODE */);
293
+ __publicField(this, "nodeName", "DOMNode");
294
+ /** @internal */
295
+ __publicField(this, "computedBoundingClientRect", {
296
+ x: 0,
297
+ y: 0,
298
+ width: 0,
299
+ height: 0
300
+ });
301
+ /** @internal */
302
+ __publicField(this, "root");
303
+ this.root = null;
304
+ this.id = nodeId++;
305
+ }
306
+ insertBefore(child, ref2) {
307
+ super.insertBefore(child, ref2);
308
+ child.setRootDocument(this.root);
309
+ this.emitRoot("DOMChanged");
310
+ }
311
+ remove() {
312
+ super.remove();
313
+ this.setRootDocument(null);
314
+ }
315
+ setRootDocument(document) {
316
+ this.root = document;
317
+ for (const child of this.childNodes) {
318
+ child.setRootDocument(document);
319
+ }
320
+ }
321
+ getBoundingClientRect() {
322
+ return {
323
+ ...this.computedBoundingClientRect
324
+ };
325
+ }
326
+ getDisplayData() {
327
+ return {
328
+ id: this.id,
329
+ nodeType: DOMNodeType[this.nodeType],
330
+ ...super.getDisplayData()
331
+ };
332
+ }
333
+ emitRoot(eventName, ...args) {
334
+ if (this.root) {
335
+ this.root.emit(eventName, ...args);
336
+ }
337
+ }
338
+ get textContent() {
339
+ return null;
340
+ }
341
+ set textContent(value) {
342
+ return;
343
+ }
344
+ };
345
+
346
+ // src/tree/DOMTree/DOMComment.ts
347
+ var DOMComment = class extends DOMNode {
348
+ constructor(data = null) {
349
+ super();
350
+ __publicField(this, "nodeType", 8 /* COMMENT_NODE */);
351
+ __publicField(this, "nodeName", "DOMComment");
352
+ /** @internal */
353
+ __publicField(this, "textValue");
354
+ this.textValue = data;
355
+ }
356
+ get textContent() {
357
+ return this.textValue;
358
+ }
359
+ set textContent(value) {
360
+ this.textValue = value;
361
+ }
362
+ getDisplayData() {
363
+ return {
364
+ ...super.getDisplayData(),
365
+ textContent: this.textContent
366
+ };
367
+ }
368
+ };
369
+
370
+ // src/tree/utils/treeToText.ts
371
+ var treeToText = (root, tab = "") => {
372
+ let str = root.getDisplayName();
373
+ let last = root.childNodes.length - 1;
374
+ for (; last >= 0; last--) if (root.childNodes[last]) break;
375
+ for (let i = 0; i <= last; i++) {
376
+ const childNode = root.childNodes[i];
377
+ if (!childNode) continue;
378
+ const isLast = i === last;
379
+ const child = treeToText(childNode, tab + (isLast ? " " : "\u2502") + " ");
380
+ const branch = child ? isLast ? "\u2514\u2500" : "\u251C\u2500" : "\u2502";
381
+ str += "\n" + tab + branch + (child ? " " + child : "");
382
+ }
383
+ return str;
384
+ };
385
+
386
+ // src/tree/DOMTree/DOMText.ts
387
+ var DOMText = class extends DOMNode {
388
+ constructor(data = "") {
389
+ super();
390
+ __publicField(this, "nodeType", 3 /* TEXT_NODE */);
391
+ __publicField(this, "nodeName", "DOMText");
392
+ /** @internal */
393
+ __publicField(this, "textValue");
394
+ this.textValue = data;
395
+ }
396
+ get textContent() {
397
+ return this.textValue;
398
+ }
399
+ set textContent(value) {
400
+ this.textValue = value;
401
+ }
402
+ getDisplayData() {
403
+ return {
404
+ ...super.getDisplayData(),
405
+ textContent: this.textContent
406
+ };
407
+ }
408
+ getDisplayName() {
409
+ return `${this.nodeName}(${this.textValue?.length})`;
410
+ }
411
+ };
412
+
413
+ // src/tree/DOMTree/DOMElement.ts
414
+ var DOMElement = class extends DOMNode {
415
+ constructor(tagName) {
416
+ super();
417
+ __publicField(this, "nodeType", 1 /* ELEMENT_NODE */);
418
+ __publicField(this, "nodeName", "DOMElement");
419
+ __publicField(this, "tagName");
420
+ __publicField(this, "attributes", {});
421
+ this.tagName = tagName;
422
+ }
423
+ getDisplayName() {
424
+ return `${this.nodeName}(${this.tagName})`;
425
+ }
426
+ getDisplayData() {
427
+ return {
428
+ ...super.getDisplayData(),
429
+ tagName: this.tagName,
430
+ attributes: this.attributes
431
+ };
432
+ }
433
+ getAttribute(name) {
434
+ return this.attributes[name];
435
+ }
436
+ setAttribute(name, value) {
437
+ this.attributes[name] = value;
438
+ this.emitRoot("DOMChanged");
439
+ }
440
+ removeAttribute(name) {
441
+ delete this.attributes[name];
442
+ }
443
+ set textContent(value) {
444
+ this.childNodes.forEach((c) => c.destroy());
445
+ if (!value) return;
446
+ const textNode = new DOMText(value);
447
+ this.appendChild(textNode);
448
+ }
449
+ get textContent() {
450
+ let text = "";
451
+ for (let index = 0; index < this.childNodes.length; index++) {
452
+ const childNode = this.childNodes[index];
453
+ let nodeText = "";
454
+ if (childNode.nodeType === 8 /* COMMENT_NODE */) continue;
455
+ nodeText = childNode.textContent ?? "";
456
+ text += nodeText;
457
+ }
458
+ return text;
459
+ }
460
+ };
461
+
462
+ // src/tree/DOMTree/DOMDocument.ts
463
+ var DOMDocument = class _DOMDocument extends DOMNode {
464
+ constructor() {
465
+ super(...arguments);
466
+ __publicField(this, "nodeType", 0 /* DOCUMENT */);
467
+ __publicField(this, "nodeName", "DOMDocument");
468
+ }
469
+ static createDocument() {
470
+ return new _DOMDocument();
471
+ }
472
+ static createTextNode(data) {
473
+ return new DOMText(data);
474
+ }
475
+ static createComment(data) {
476
+ return new DOMComment(data);
477
+ }
478
+ static createElement(tagName) {
479
+ return new DOMElement(tagName);
480
+ }
481
+ insertBefore(child, ref2) {
482
+ super.insertBefore(child, ref2);
483
+ child.setRootDocument(this);
484
+ }
485
+ get treeText() {
486
+ return treeToText(this);
487
+ }
488
+ };
489
+
490
+ // src/tree/DOMTree/index.ts
491
+ var DOM = Object.freeze({
492
+ Document: DOMDocument,
493
+ Text: DOMText,
494
+ Comment: DOMComment,
495
+ Element: DOMElement,
496
+ Node: DOMNode,
497
+ Type: DOMNodeType,
498
+ createDocument: DOMDocument.createDocument.bind(DOMDocument),
499
+ createComment: DOMDocument.createComment.bind(DOMDocument),
500
+ createTextNode: DOMDocument.createTextNode.bind(DOMDocument),
501
+ createElement: DOMDocument.createElement.bind(DOMDocument)
502
+ });
503
+
504
+ // src/tree/RenderTree/RenderBlock.ts
505
+ import chalk2 from "chalk";
506
+ import cliBoxes from "cli-boxes";
507
+ import Yoga3 from "yoga-wasm-web/auto";
508
+
509
+ // src/tree/RenderTree/RenderNode.ts
510
+ import Yoga2 from "yoga-wasm-web/auto";
511
+
512
+ // src/tree/RenderTree/utils/applyStyles.ts
513
+ import Yoga from "yoga-wasm-web/auto";
514
+ var applyPositionStyles = (node, style) => {
515
+ if ("position" in style) {
516
+ node.setPositionType(style.position === "absolute" ? Yoga.POSITION_TYPE_ABSOLUTE : Yoga.POSITION_TYPE_RELATIVE);
517
+ }
518
+ };
519
+ var applyMarginStyles = (node, style) => {
520
+ if ("margin" in style) {
521
+ node.setMargin(Yoga.EDGE_ALL, style.margin ?? 0);
522
+ }
523
+ if ("marginX" in style) {
524
+ node.setMargin(Yoga.EDGE_HORIZONTAL, style.marginX ?? 0);
525
+ }
526
+ if ("marginY" in style) {
527
+ node.setMargin(Yoga.EDGE_VERTICAL, style.marginY ?? 0);
528
+ }
529
+ if ("marginLeft" in style) {
530
+ node.setMargin(Yoga.EDGE_START, style.marginLeft || 0);
531
+ }
532
+ if ("marginRight" in style) {
533
+ node.setMargin(Yoga.EDGE_END, style.marginRight || 0);
534
+ }
535
+ if ("marginTop" in style) {
536
+ node.setMargin(Yoga.EDGE_TOP, style.marginTop || 0);
537
+ }
538
+ if ("marginBottom" in style) {
539
+ node.setMargin(Yoga.EDGE_BOTTOM, style.marginBottom || 0);
540
+ }
541
+ };
542
+ var applyPaddingStyles = (node, style) => {
543
+ if ("padding" in style) {
544
+ node.setPadding(Yoga.EDGE_ALL, style.padding ?? 0);
545
+ }
546
+ if ("paddingX" in style) {
547
+ node.setPadding(Yoga.EDGE_HORIZONTAL, style.paddingX ?? 0);
548
+ }
549
+ if ("paddingY" in style) {
550
+ node.setPadding(Yoga.EDGE_VERTICAL, style.paddingY ?? 0);
551
+ }
552
+ if ("paddingLeft" in style) {
553
+ node.setPadding(Yoga.EDGE_LEFT, style.paddingLeft || 0);
554
+ }
555
+ if ("paddingRight" in style) {
556
+ node.setPadding(Yoga.EDGE_RIGHT, style.paddingRight || 0);
557
+ }
558
+ if ("paddingTop" in style) {
559
+ node.setPadding(Yoga.EDGE_TOP, style.paddingTop || 0);
560
+ }
561
+ if ("paddingBottom" in style) {
562
+ node.setPadding(Yoga.EDGE_BOTTOM, style.paddingBottom || 0);
563
+ }
564
+ };
565
+ var applyFlexStyles = (node, style) => {
566
+ if ("flexGrow" in style) {
567
+ node.setFlexGrow(style.flexGrow ?? 0);
568
+ }
569
+ if ("flexShrink" in style) {
570
+ node.setFlexShrink(typeof style.flexShrink === "number" ? style.flexShrink : 1);
571
+ }
572
+ if ("flexWrap" in style) {
573
+ if (style.flexWrap === "nowrap") {
574
+ node.setFlexWrap(Yoga.WRAP_NO_WRAP);
575
+ }
576
+ if (style.flexWrap === "wrap") {
577
+ node.setFlexWrap(Yoga.WRAP_WRAP);
578
+ }
579
+ if (style.flexWrap === "wrap-reverse") {
580
+ node.setFlexWrap(Yoga.WRAP_WRAP_REVERSE);
581
+ }
582
+ }
583
+ if ("flexDirection" in style) {
584
+ if (style.flexDirection === "row") {
585
+ node.setFlexDirection(Yoga.FLEX_DIRECTION_ROW);
586
+ }
587
+ if (style.flexDirection === "row-reverse") {
588
+ node.setFlexDirection(Yoga.FLEX_DIRECTION_ROW_REVERSE);
589
+ }
590
+ if (style.flexDirection === "column") {
591
+ node.setFlexDirection(Yoga.FLEX_DIRECTION_COLUMN);
592
+ }
593
+ if (style.flexDirection === "column-reverse") {
594
+ node.setFlexDirection(Yoga.FLEX_DIRECTION_COLUMN_REVERSE);
595
+ }
596
+ }
597
+ if ("flexBasis" in style) {
598
+ if (typeof style.flexBasis === "number") {
599
+ node.setFlexBasis(style.flexBasis);
600
+ } else if (typeof style.flexBasis === "string") {
601
+ node.setFlexBasisPercent(Number.parseInt(style.flexBasis, 10));
602
+ } else {
603
+ node.setFlexBasisAuto();
604
+ }
605
+ }
606
+ if ("alignItems" in style) {
607
+ if (style.alignItems === "stretch" || !style.alignItems) {
608
+ node.setAlignItems(Yoga.ALIGN_STRETCH);
609
+ }
610
+ if (style.alignItems === "flex-start") {
611
+ node.setAlignItems(Yoga.ALIGN_FLEX_START);
612
+ }
613
+ if (style.alignItems === "center") {
614
+ node.setAlignItems(Yoga.ALIGN_CENTER);
615
+ }
616
+ if (style.alignItems === "flex-end") {
617
+ node.setAlignItems(Yoga.ALIGN_FLEX_END);
618
+ }
619
+ }
620
+ if ("alignSelf" in style) {
621
+ if (style.alignSelf === "auto" || !style.alignSelf) {
622
+ node.setAlignSelf(Yoga.ALIGN_AUTO);
623
+ }
624
+ if (style.alignSelf === "flex-start") {
625
+ node.setAlignSelf(Yoga.ALIGN_FLEX_START);
626
+ }
627
+ if (style.alignSelf === "center") {
628
+ node.setAlignSelf(Yoga.ALIGN_CENTER);
629
+ }
630
+ if (style.alignSelf === "flex-end") {
631
+ node.setAlignSelf(Yoga.ALIGN_FLEX_END);
632
+ }
633
+ }
634
+ if ("justifyContent" in style) {
635
+ if (style.justifyContent === "flex-start" || !style.justifyContent) {
636
+ node.setJustifyContent(Yoga.JUSTIFY_FLEX_START);
637
+ }
638
+ if (style.justifyContent === "center") {
639
+ node.setJustifyContent(Yoga.JUSTIFY_CENTER);
640
+ }
641
+ if (style.justifyContent === "flex-end") {
642
+ node.setJustifyContent(Yoga.JUSTIFY_FLEX_END);
643
+ }
644
+ if (style.justifyContent === "space-between") {
645
+ node.setJustifyContent(Yoga.JUSTIFY_SPACE_BETWEEN);
646
+ }
647
+ if (style.justifyContent === "space-around") {
648
+ node.setJustifyContent(Yoga.JUSTIFY_SPACE_AROUND);
649
+ }
650
+ if (style.justifyContent === "space-evenly") {
651
+ node.setJustifyContent(Yoga.JUSTIFY_SPACE_EVENLY);
652
+ }
653
+ }
654
+ };
655
+ var applyDimensionStyles = (node, style) => {
656
+ if ("width" in style) {
657
+ if (typeof style.width === "number") {
658
+ node.setWidth(style.width);
659
+ } else if (typeof style.width === "string") {
660
+ node.setWidthPercent(Number.parseInt(style.width, 10));
661
+ } else {
662
+ node.setWidthAuto();
663
+ }
664
+ }
665
+ if ("height" in style) {
666
+ if (typeof style.height === "number") {
667
+ node.setHeight(style.height);
668
+ } else if (typeof style.height === "string") {
669
+ node.setHeightPercent(Number.parseInt(style.height, 10));
670
+ } else {
671
+ node.setHeightAuto();
672
+ }
673
+ }
674
+ if ("minWidth" in style) {
675
+ if (typeof style.minWidth === "string") {
676
+ node.setMinWidthPercent(Number.parseInt(style.minWidth, 10));
677
+ } else {
678
+ node.setMinWidth(style.minWidth ?? 0);
679
+ }
680
+ }
681
+ if ("minHeight" in style) {
682
+ if (typeof style.minHeight === "string") {
683
+ node.setMinHeightPercent(Number.parseInt(style.minHeight, 10));
684
+ } else {
685
+ node.setMinHeight(style.minHeight ?? 0);
686
+ }
687
+ }
688
+ };
689
+ var applyDisplayStyles = (node, style) => {
690
+ if ("display" in style) {
691
+ node.setDisplay(style.display === "flex" ? Yoga.DISPLAY_FLEX : Yoga.DISPLAY_NONE);
692
+ }
693
+ };
694
+ var applyBorderStyles = (node, style) => {
695
+ if ("borderStyle" in style) {
696
+ const borderWidth = style.borderStyle ? 1 : 0;
697
+ if (style.borderTop !== false) {
698
+ node.setBorder(Yoga.EDGE_TOP, borderWidth);
699
+ }
700
+ if (style.borderBottom !== false) {
701
+ node.setBorder(Yoga.EDGE_BOTTOM, borderWidth);
702
+ }
703
+ if (style.borderLeft !== false) {
704
+ node.setBorder(Yoga.EDGE_LEFT, borderWidth);
705
+ }
706
+ if (style.borderRight !== false) {
707
+ node.setBorder(Yoga.EDGE_RIGHT, borderWidth);
708
+ }
709
+ }
710
+ };
711
+ var applyGapStyles = (node, style) => {
712
+ if ("gap" in style) {
713
+ node.setGap(Yoga.GUTTER_ALL, style.gap ?? 0);
714
+ }
715
+ if ("columnGap" in style) {
716
+ node.setGap(Yoga.GUTTER_COLUMN, style.columnGap ?? 0);
717
+ }
718
+ if ("rowGap" in style) {
719
+ node.setGap(Yoga.GUTTER_ROW, style.rowGap ?? 0);
720
+ }
721
+ };
722
+ var applyStyles = (node, style = {}) => {
723
+ applyPositionStyles(node, style);
724
+ applyMarginStyles(node, style);
725
+ applyPaddingStyles(node, style);
726
+ applyFlexStyles(node, style);
727
+ applyDimensionStyles(node, style);
728
+ applyDisplayStyles(node, style);
729
+ applyBorderStyles(node, style);
730
+ applyGapStyles(node, style);
731
+ };
732
+
733
+ // src/tree/RenderTree/RenderNode.ts
734
+ var RenderNodeType = /* @__PURE__ */ ((RenderNodeType2) => {
735
+ RenderNodeType2[RenderNodeType2["NODE"] = 1] = "NODE";
736
+ RenderNodeType2[RenderNodeType2["BLOCK"] = 2] = "BLOCK";
737
+ RenderNodeType2[RenderNodeType2["INLINE"] = 3] = "INLINE";
738
+ RenderNodeType2[RenderNodeType2["TEXT"] = 4] = "TEXT";
739
+ return RenderNodeType2;
740
+ })(RenderNodeType || {});
741
+ var nodeId2 = 0;
742
+ var RenderNode = class extends NodeTree {
743
+ constructor() {
744
+ super();
745
+ __publicField(this, "id");
746
+ __publicField(this, "nodeType", 1 /* NODE */);
747
+ __publicField(this, "nodeName", "RenderNode");
748
+ __publicField(this, "transformers", []);
749
+ /** @internal */
750
+ __publicField(this, "domNode");
751
+ /** @internal */
752
+ __publicField(this, "yogaNode");
753
+ __publicField(this, "realX");
754
+ __publicField(this, "realY");
755
+ this.id = nodeId2++;
756
+ this.yogaNode = Yoga2.Node.create();
757
+ this.domNode = null;
758
+ this.realX = 0;
759
+ this.realY = 0;
760
+ }
761
+ getDisplayName() {
762
+ const {
763
+ x,
764
+ y,
765
+ width,
766
+ height
767
+ } = this.getComputedRect();
768
+ const rectText = `x=${this.realX},y=${y}/${this.realY}, w=${width},h=${height},t=${this.transformers.length}`;
769
+ return `${this.nodeName}` + (this.domNode ? `(${this.domNode.getDisplayName()})` : "") + " " + rectText;
770
+ }
771
+ getDisplayData() {
772
+ return {
773
+ id: this.id,
774
+ nodeType: RenderNodeType[this.nodeType],
775
+ ...super.getDisplayData()
776
+ };
777
+ }
778
+ remove() {
779
+ super.remove();
780
+ this.parentNode?.yogaNode.removeChild(this.yogaNode);
781
+ }
782
+ destroy() {
783
+ super.destroy();
784
+ this.yogaNode.free();
785
+ }
786
+ insertBefore(child, ref2) {
787
+ super.insertBefore(child, ref2);
788
+ const parent = this;
789
+ if (!ref2) {
790
+ parent.yogaNode.insertChild(child.yogaNode, parent.yogaNode.getChildCount());
791
+ } else {
792
+ const refIndex = parent.childNodes.indexOf(child);
793
+ parent.yogaNode.insertChild(child.yogaNode, refIndex);
794
+ }
795
+ }
796
+ getComputedRect() {
797
+ const {
798
+ yogaNode
799
+ } = this;
800
+ return {
801
+ x: yogaNode.getComputedLeft(),
802
+ y: yogaNode.getComputedTop(),
803
+ width: yogaNode.getComputedWidth(),
804
+ height: yogaNode.getComputedHeight()
805
+ };
806
+ }
807
+ getContentRect() {
808
+ const {
809
+ yogaNode
810
+ } = this;
811
+ const rect = this.getComputedRect();
812
+ const borderLeft = yogaNode.getComputedBorder(Yoga2.EDGE_LEFT);
813
+ const borderRight = yogaNode.getComputedBorder(Yoga2.EDGE_RIGHT);
814
+ const borderTop = yogaNode.getComputedBorder(Yoga2.EDGE_TOP);
815
+ const borderBottom = yogaNode.getComputedBorder(Yoga2.EDGE_BOTTOM);
816
+ const paddingLeft = yogaNode.getComputedPadding(Yoga2.EDGE_LEFT);
817
+ const paddingRight = yogaNode.getComputedPadding(Yoga2.EDGE_RIGHT);
818
+ const paddingTop = yogaNode.getComputedPadding(Yoga2.EDGE_TOP);
819
+ const paddingBottom = yogaNode.getComputedPadding(Yoga2.EDGE_BOTTOM);
820
+ return {
821
+ x: rect.x + borderLeft + paddingLeft,
822
+ y: rect.y + borderTop + paddingTop,
823
+ width: rect.width - borderLeft - borderRight - paddingLeft - paddingRight,
824
+ height: rect.height - borderTop - borderBottom - paddingBottom - paddingTop
825
+ };
826
+ }
827
+ renderToLayer(layer) {
828
+ }
829
+ computeStyles() {
830
+ this.transformers = [];
831
+ if (this.domNode) {
832
+ const attributes = this.domNode.attributes ?? {};
833
+ applyStyles(this.yogaNode, attributes);
834
+ }
835
+ }
836
+ };
837
+
838
+ // src/tree/RenderTree/utils/colorize.ts
839
+ import chalk from "chalk";
840
+ var rgbRegex = /^rgb\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/;
841
+ var ansiRegex = /^ansi256\(\s?(\d+)\s?\)$/;
842
+ var isNamedColor = (color) => {
843
+ return color in chalk;
844
+ };
845
+ var colorize = (str, color, type) => {
846
+ if (!color) {
847
+ return str;
848
+ }
849
+ if (isNamedColor(color)) {
850
+ if (type === "foreground") {
851
+ return chalk[color](str);
852
+ }
853
+ const methodName = `bg${color[0].toUpperCase() + color.slice(1)}`;
854
+ return chalk[methodName](str);
855
+ }
856
+ if (color.startsWith("#")) {
857
+ return type === "foreground" ? chalk.hex(color)(str) : chalk.bgHex(color)(str);
858
+ }
859
+ if (color.startsWith("ansi256")) {
860
+ const matches = ansiRegex.exec(color);
861
+ if (!matches) {
862
+ return str;
863
+ }
864
+ const value = Number(matches[1]);
865
+ return type === "foreground" ? chalk.ansi256(value)(str) : chalk.bgAnsi256(value)(str);
866
+ }
867
+ if (color.startsWith("rgb")) {
868
+ const matches = rgbRegex.exec(color);
869
+ if (!matches) {
870
+ return str;
871
+ }
872
+ const firstValue = Number(matches[1]);
873
+ const secondValue = Number(matches[2]);
874
+ const thirdValue = Number(matches[3]);
875
+ return type === "foreground" ? chalk.rgb(firstValue, secondValue, thirdValue)(str) : chalk.bgRgb(firstValue, secondValue, thirdValue)(str);
876
+ }
877
+ return str;
878
+ };
879
+
880
+ // src/tree/RenderTree/RenderBlock.ts
881
+ var RenderBlock = class extends RenderNode {
882
+ constructor() {
883
+ super();
884
+ __publicField(this, "nodeType", 2 /* BLOCK */);
885
+ __publicField(this, "nodeName", "RenderBlock");
886
+ }
887
+ renderToLayer(layer) {
888
+ const {
889
+ yogaNode,
890
+ domNode
891
+ } = this;
892
+ const props = domNode?.attributes ?? {};
893
+ const {
894
+ width,
895
+ height
896
+ } = this.getComputedRect();
897
+ const x = this.realX;
898
+ const y = this.realY;
899
+ let clipped = false;
900
+ if (props.borderStyle) {
901
+ const box = typeof props.borderStyle === "string" ? cliBoxes[props.borderStyle] : props.borderStyle;
902
+ const topBorderColor = props.borderTopColor ?? props.borderColor;
903
+ const bottomBorderColor = props.borderBottomColor ?? props.borderColor;
904
+ const leftBorderColor = props.borderLeftColor ?? props.borderColor;
905
+ const rightBorderColor = props.borderRightColor ?? props.borderColor;
906
+ const dimTopBorderColor = props.borderTopDimColor ?? props.borderDimColor;
907
+ const dimBottomBorderColor = props.borderBottomDimColor ?? props.borderDimColor;
908
+ const dimLeftBorderColor = props.borderLeftDimColor ?? props.borderDimColor;
909
+ const dimRightBorderColor = props.borderRightDimColor ?? props.borderDimColor;
910
+ const showTopBorder = props.borderTop !== false;
911
+ const showBottomBorder = props.borderBottom !== false;
912
+ const showLeftBorder = props.borderLeft !== false;
913
+ const showRightBorder = props.borderRight !== false;
914
+ const contentWidth = width - (showLeftBorder ? 1 : 0) - (showRightBorder ? 1 : 0);
915
+ let topBorder = showTopBorder ? colorize((showLeftBorder ? box.topLeft : "") + box.top.repeat(contentWidth) + (showRightBorder ? box.topRight : ""), topBorderColor, "foreground") : void 0;
916
+ if (showTopBorder && dimTopBorderColor) {
917
+ topBorder = chalk2.dim(topBorder);
918
+ }
919
+ let verticalBorderHeight = height;
920
+ if (showTopBorder) {
921
+ verticalBorderHeight -= 1;
922
+ }
923
+ if (showBottomBorder) {
924
+ verticalBorderHeight -= 1;
925
+ }
926
+ let leftBorder = (colorize(box.left, leftBorderColor, "foreground") + "\n").repeat(verticalBorderHeight);
927
+ if (dimLeftBorderColor) {
928
+ leftBorder = chalk2.dim(leftBorder);
929
+ }
930
+ let rightBorder = (colorize(box.right, rightBorderColor, "foreground") + "\n").repeat(verticalBorderHeight);
931
+ if (dimRightBorderColor) {
932
+ rightBorder = chalk2.dim(rightBorder);
933
+ }
934
+ let bottomBorder = showBottomBorder ? colorize((showLeftBorder ? box.bottomLeft : "") + box.bottom.repeat(contentWidth) + (showRightBorder ? box.bottomRight : ""), bottomBorderColor, "foreground") : void 0;
935
+ if (showBottomBorder && dimBottomBorderColor) {
936
+ bottomBorder = chalk2.dim(bottomBorder);
937
+ }
938
+ const offsetY = showTopBorder ? 1 : 0;
939
+ if (topBorder) {
940
+ layer.write(x, y, topBorder, {
941
+ transformers: []
942
+ });
943
+ }
944
+ if (showLeftBorder) {
945
+ layer.write(x, y + offsetY, leftBorder, {
946
+ transformers: []
947
+ });
948
+ }
949
+ if (showRightBorder) {
950
+ layer.write(x + width - 1, y + offsetY, rightBorder, {
951
+ transformers: []
952
+ });
953
+ }
954
+ if (bottomBorder) {
955
+ layer.write(x, y + height - 1, bottomBorder, {
956
+ transformers: []
957
+ });
958
+ }
959
+ }
960
+ const clipHorizontally = props.overflowX === "hidden" || props.overflow === "hidden";
961
+ const clipVertically = props.overflowY === "hidden" || props.overflow === "hidden";
962
+ if (clipHorizontally || clipVertically) {
963
+ const x1 = clipHorizontally ? x + yogaNode.getComputedBorder(Yoga3.EDGE_LEFT) : void 0;
964
+ const x2 = clipHorizontally ? x + yogaNode.getComputedWidth() - yogaNode.getComputedBorder(Yoga3.EDGE_RIGHT) : void 0;
965
+ const y1 = clipVertically ? y + yogaNode.getComputedBorder(Yoga3.EDGE_TOP) : void 0;
966
+ const y2 = clipVertically ? y + yogaNode.getComputedHeight() - yogaNode.getComputedBorder(Yoga3.EDGE_BOTTOM) : void 0;
967
+ layer.clip({
968
+ x1,
969
+ x2,
970
+ y1,
971
+ y2
972
+ });
973
+ clipped = true;
974
+ }
975
+ }
976
+ };
977
+
978
+ // src/tree/RenderTree/RenderFlow.ts
979
+ import Yoga5 from "yoga-wasm-web/auto";
980
+
981
+ // src/tree/RenderTree/Layer.ts
982
+ import { styledCharsFromTokens, styledCharsToString, tokenize } from "@alcalzone/ansi-tokenize";
983
+ import sliceAnsi from "slice-ansi";
984
+ import stringWidth from "string-width";
985
+ import widestLine from "widest-line";
986
+ var Layer = class {
987
+ constructor(options) {
988
+ __publicField(this, "width");
989
+ __publicField(this, "height");
990
+ __publicField(this, "frame");
991
+ __publicField(this, "frameHeight");
992
+ __publicField(this, "operations", []);
993
+ const {
994
+ width,
995
+ height
996
+ } = options;
997
+ this.width = width;
998
+ this.height = height;
999
+ this.frame = "";
1000
+ this.frameHeight = 0;
1001
+ }
1002
+ write(x, y, text, options) {
1003
+ const {
1004
+ transformers
1005
+ } = options;
1006
+ if (!text) {
1007
+ return;
1008
+ }
1009
+ this.operations.push({
1010
+ type: "write",
1011
+ x,
1012
+ y,
1013
+ text,
1014
+ transformers
1015
+ });
1016
+ }
1017
+ clip(clip) {
1018
+ this.operations.push({
1019
+ type: "clip",
1020
+ clip
1021
+ });
1022
+ }
1023
+ unclip() {
1024
+ this.operations.push({
1025
+ type: "unclip"
1026
+ });
1027
+ }
1028
+ compute() {
1029
+ const output = [];
1030
+ for (let y = 0; y < this.height; y++) {
1031
+ const row = [];
1032
+ for (let x = 0; x < this.width; x++) {
1033
+ row.push({
1034
+ type: "char",
1035
+ value: " ",
1036
+ fullWidth: false,
1037
+ styles: []
1038
+ });
1039
+ }
1040
+ output.push(row);
1041
+ }
1042
+ const clips = [];
1043
+ for (const operation of this.operations) {
1044
+ if (operation.type === "clip") {
1045
+ clips.push(operation.clip);
1046
+ }
1047
+ if (operation.type === "unclip") {
1048
+ clips.pop();
1049
+ }
1050
+ if (operation.type === "write") {
1051
+ const {
1052
+ text,
1053
+ transformers
1054
+ } = operation;
1055
+ let {
1056
+ x,
1057
+ y
1058
+ } = operation;
1059
+ let lines = text.split("\n");
1060
+ const clip = clips.at(-1);
1061
+ if (clip) {
1062
+ const clipHorizontally = typeof clip?.x1 === "number" && typeof clip?.x2 === "number";
1063
+ const clipVertically = typeof clip?.y1 === "number" && typeof clip?.y2 === "number";
1064
+ if (clipHorizontally) {
1065
+ const width = widestLine(text);
1066
+ if (x + width < clip.x1 || x > clip.x2) {
1067
+ continue;
1068
+ }
1069
+ }
1070
+ if (clipVertically) {
1071
+ const height = lines.length;
1072
+ if (y + height < clip.y1 || y > clip.y2) {
1073
+ continue;
1074
+ }
1075
+ }
1076
+ if (clipHorizontally) {
1077
+ lines = lines.map((line) => {
1078
+ const from = x < clip.x1 ? clip.x1 - x : 0;
1079
+ const width = stringWidth(line);
1080
+ const to = x + width > clip.x2 ? clip.x2 - x : width;
1081
+ return sliceAnsi(line, from, to);
1082
+ });
1083
+ if (x < clip.x1) {
1084
+ x = clip.x1;
1085
+ }
1086
+ }
1087
+ if (clipVertically) {
1088
+ const from = y < clip.y1 ? clip.y1 - y : 0;
1089
+ const height = lines.length;
1090
+ const to = y + height > clip.y2 ? clip.y2 - y : height;
1091
+ lines = lines.slice(from, to);
1092
+ if (y < clip.y1) {
1093
+ y = clip.y1;
1094
+ }
1095
+ }
1096
+ }
1097
+ let offsetY = 0;
1098
+ for (let [index, line] of lines.entries()) {
1099
+ const currentLine = output[y + offsetY];
1100
+ if (!currentLine) {
1101
+ continue;
1102
+ }
1103
+ for (const transformer of transformers) {
1104
+ line = transformer(line, index);
1105
+ }
1106
+ const characters = styledCharsFromTokens(tokenize(line));
1107
+ let offsetX = x;
1108
+ for (const character of characters) {
1109
+ currentLine[offsetX] = character;
1110
+ const isWideCharacter = character.fullWidth || character.value.length > 1;
1111
+ if (isWideCharacter) {
1112
+ currentLine[offsetX + 1] = {
1113
+ type: "char",
1114
+ value: "",
1115
+ fullWidth: false,
1116
+ styles: character.styles
1117
+ };
1118
+ }
1119
+ offsetX += isWideCharacter ? 2 : 1;
1120
+ }
1121
+ offsetY++;
1122
+ }
1123
+ }
1124
+ }
1125
+ const generatedOutput = output.map((line) => {
1126
+ const lineWithoutEmptyItems = line.filter((item) => item !== void 0);
1127
+ return styledCharsToString(lineWithoutEmptyItems).trimEnd();
1128
+ }).join("\n");
1129
+ this.frame = generatedOutput;
1130
+ this.frameHeight = generatedOutput.length;
1131
+ this.operations.length = 0;
1132
+ }
1133
+ };
1134
+
1135
+ // src/tree/RenderTree/RenderInline.ts
1136
+ import Yoga4 from "yoga-wasm-web/auto";
1137
+ var RenderInline = class extends RenderNode {
1138
+ constructor() {
1139
+ super();
1140
+ __publicField(this, "nodeType", 3 /* INLINE */);
1141
+ __publicField(this, "nodeName", "RenderInline");
1142
+ this.yogaNode.setDisplay(Yoga4.DISPLAY_FLEX);
1143
+ this.yogaNode.setGap(Yoga4.GUTTER_ALL, 0);
1144
+ this.yogaNode.setFlexDirection(Yoga4.FLEX_DIRECTION_ROW);
1145
+ this.yogaNode.setFlexWrap(Yoga4.WRAP_WRAP);
1146
+ }
1147
+ };
1148
+
1149
+ // src/tree/RenderTree/RenderText.ts
1150
+ import { withCache as withCache2 } from "@andrew_l/toolkit";
1151
+ import chalk3 from "chalk";
1152
+ import widestLine2 from "widest-line";
1153
+
1154
+ // src/tree/RenderTree/utils/wrapText.ts
1155
+ import { withCache } from "@andrew_l/toolkit";
1156
+ import cliTruncate from "cli-truncate";
1157
+ import wrapAnsi from "wrap-ansi";
1158
+ var wrapText = withCache((text, maxWidth, wrapType) => {
1159
+ let wrappedText = text;
1160
+ if (wrapType === "wrap") {
1161
+ wrappedText = wrapAnsi(text, maxWidth, {
1162
+ trim: false,
1163
+ hard: true
1164
+ });
1165
+ }
1166
+ if (wrapType.startsWith("truncate")) {
1167
+ let position = "end";
1168
+ if (wrapType === "truncate-middle") {
1169
+ position = "middle";
1170
+ }
1171
+ if (wrapType === "truncate-start") {
1172
+ position = "start";
1173
+ }
1174
+ wrappedText = cliTruncate(text, maxWidth, {
1175
+ position
1176
+ });
1177
+ }
1178
+ return wrappedText;
1179
+ });
1180
+
1181
+ // src/tree/RenderTree/RenderText.ts
1182
+ var _RenderText = class _RenderText extends RenderNode {
1183
+ constructor() {
1184
+ super();
1185
+ __publicField(this, "nodeType", 4 /* TEXT */);
1186
+ __publicField(this, "nodeName", "RenderText");
1187
+ this.yogaNode.setMeasureFunc(this.measure.bind(this));
1188
+ }
1189
+ getDisplayName() {
1190
+ return super.getDisplayName() + "/" + this.getTextWrapStyle();
1191
+ }
1192
+ /**
1193
+ * Measure the dimensions of the text associated
1194
+ * callback for css-layout
1195
+ * @param: width - input width extents
1196
+ * @param: widthMeasureMode - mode to constrain width CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_UNDEFINED
1197
+ * @param: height - input height extents
1198
+ * @param: heightMeasureMode - mode to constrain height CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_UNDEFINED
1199
+ * @return: object containing measured width and height
1200
+ */
1201
+ measure(width, widthMeasureMode, height, heightMeasureMode) {
1202
+ const text = this.domNode?.textContent;
1203
+ if (!text) return {
1204
+ width: 0,
1205
+ height: 0
1206
+ };
1207
+ const dimensions = _RenderText.measureText(text);
1208
+ if (dimensions.width <= width) {
1209
+ return dimensions;
1210
+ }
1211
+ if (dimensions.width >= 1 && width > 0 && width < 1) {
1212
+ return dimensions;
1213
+ }
1214
+ const wrappedText = wrapText(text, width, this.getTextWrapStyle());
1215
+ return _RenderText.measureText(wrappedText);
1216
+ }
1217
+ getTextWrapStyle() {
1218
+ return this.domNode?.parentNode?.attributes?.textWrap ?? "wrap";
1219
+ }
1220
+ renderToLayer(layer) {
1221
+ const {
1222
+ domNode
1223
+ } = this;
1224
+ const {
1225
+ width: maxWidth
1226
+ } = this.getContentRect();
1227
+ const x = this.realX;
1228
+ const y = this.realY;
1229
+ if (!domNode) return;
1230
+ let text = domNode.textContent;
1231
+ if (text && text.length > 0) {
1232
+ const currentWidth = widestLine2(text);
1233
+ if (currentWidth > maxWidth) {
1234
+ text = wrapText(text, maxWidth, this.getTextWrapStyle());
1235
+ }
1236
+ layer.write(x, y, text, {
1237
+ transformers: this.transformers
1238
+ });
1239
+ }
1240
+ }
1241
+ computeStyles() {
1242
+ this.transformers = [];
1243
+ const attributes = (this.domNode?.parentNode).attributes ?? {};
1244
+ if (attributes.dimColor) {
1245
+ this.transformers.push((v) => chalk3.dim(v));
1246
+ }
1247
+ if (attributes.color) {
1248
+ this.transformers.push((v) => colorize(v, attributes.color, "foreground"));
1249
+ }
1250
+ if (attributes.backgroundColor) {
1251
+ this.transformers.push((v) => colorize(v, attributes.backgroundColor, "background"));
1252
+ }
1253
+ if (attributes.bold) {
1254
+ this.transformers.push((v) => chalk3.bold(v));
1255
+ }
1256
+ if (attributes.italic) {
1257
+ this.transformers.push((v) => chalk3.italic(v));
1258
+ }
1259
+ if (attributes.underline) {
1260
+ this.transformers.push((v) => chalk3.underline(v));
1261
+ }
1262
+ if (attributes.strikethrough) {
1263
+ this.transformers.push((v) => chalk3.strikethrough(v));
1264
+ }
1265
+ if (attributes.inverse) {
1266
+ this.transformers.push((v) => chalk3.inverse(v));
1267
+ }
1268
+ }
1269
+ };
1270
+ __publicField(_RenderText, "measureText", withCache2((text) => {
1271
+ if (text.length === 0) {
1272
+ return {
1273
+ width: 0,
1274
+ height: 0
1275
+ };
1276
+ }
1277
+ const width = widestLine2(text);
1278
+ const height = text.split("\n").length;
1279
+ return {
1280
+ width,
1281
+ height
1282
+ };
1283
+ }));
1284
+ var RenderText = _RenderText;
1285
+
1286
+ // src/tree/RenderTree/RenderFlow.ts
1287
+ var INLINE_ELEMENT_TAGS = /* @__PURE__ */ new Set(["span", "b", "a"]);
1288
+ var RenderFlow = class extends RenderNode {
1289
+ constructor({
1290
+ document,
1291
+ width,
1292
+ height
1293
+ }) {
1294
+ super();
1295
+ /** @internal */
1296
+ __publicField(this, "document");
1297
+ __publicField(this, "nodeType", 1 /* NODE */);
1298
+ __publicField(this, "nodeName", "RenderFlow");
1299
+ __publicField(this, "height");
1300
+ __publicField(this, "width");
1301
+ __publicField(this, "layer");
1302
+ __publicField(this, "reflowScheduled", false);
1303
+ this.document = document;
1304
+ this.width = width;
1305
+ this.height = height;
1306
+ this.layer = new Layer({
1307
+ width,
1308
+ height
1309
+ });
1310
+ document.on("DOMChanged", this.onDOMChanged.bind(this));
1311
+ }
1312
+ get treeText() {
1313
+ return treeToText(this);
1314
+ }
1315
+ /** @internal */
1316
+ onDOMChanged() {
1317
+ this.reflowSchedule();
1318
+ }
1319
+ render() {
1320
+ this.realX = 0;
1321
+ this.realY = 0;
1322
+ this.layer.width = this.width;
1323
+ this.layer.height = this.yogaNode.getComputedHeight();
1324
+ this.renderNode(this);
1325
+ this.layer.compute();
1326
+ return this.layer.frame;
1327
+ }
1328
+ /** @internal */
1329
+ renderNode(node) {
1330
+ for (const childNode of node.childNodes) {
1331
+ const {
1332
+ domNode
1333
+ } = childNode;
1334
+ const {
1335
+ x,
1336
+ y
1337
+ } = childNode.getComputedRect();
1338
+ if (domNode) {
1339
+ const clientRect = childNode.getContentRect();
1340
+ if (domNode.computedBoundingClientRect.width !== clientRect.width || domNode.computedBoundingClientRect.height !== this.height) {
1341
+ domNode.computedBoundingClientRect = clientRect;
1342
+ domNode.emit("resize");
1343
+ }
1344
+ }
1345
+ childNode.realX = x + node.realX;
1346
+ childNode.realY = y + node.realY;
1347
+ childNode.renderToLayer(this.layer);
1348
+ this.renderNode(childNode);
1349
+ }
1350
+ }
1351
+ reflow() {
1352
+ for (const childNode of this.childNodes) {
1353
+ childNode.destroy();
1354
+ }
1355
+ this.childNodes = [];
1356
+ for (const domNode of this.document.childNodes) {
1357
+ this.reflowNode(domNode, this);
1358
+ }
1359
+ this.yogaNode.setWidth(this.width);
1360
+ this.yogaNode.calculateLayout(void 0, void 0, Yoga5.DIRECTION_LTR);
1361
+ }
1362
+ reflowSchedule() {
1363
+ if (this.reflowScheduled) return;
1364
+ this.reflowScheduled = true;
1365
+ process.nextTick(() => {
1366
+ this.reflow();
1367
+ const output = this.render();
1368
+ this.reflowScheduled = false;
1369
+ this.emit("frame", output);
1370
+ });
1371
+ }
1372
+ /** @internal */
1373
+ reflowNode(domNode, renderNode) {
1374
+ switch (domNode.nodeType) {
1375
+ case 8 /* COMMENT_NODE */: {
1376
+ break;
1377
+ }
1378
+ case 1 /* ELEMENT_NODE */: {
1379
+ if (INLINE_ELEMENT_TAGS.has(domNode.tagName)) {
1380
+ this.reflowAsInline(domNode, renderNode);
1381
+ break;
1382
+ }
1383
+ this.reflowAsBlock(domNode, renderNode);
1384
+ break;
1385
+ }
1386
+ case 0 /* DOCUMENT */: {
1387
+ this.reflowAsBlock(domNode, renderNode);
1388
+ break;
1389
+ }
1390
+ case 3 /* TEXT_NODE */: {
1391
+ this.reflowAsInline(domNode, renderNode);
1392
+ break;
1393
+ }
1394
+ }
1395
+ }
1396
+ /** @internal */
1397
+ reflowAsBlock(domNode, renderNode) {
1398
+ const block = new RenderBlock();
1399
+ block.domNode = domNode;
1400
+ block.computeStyles();
1401
+ renderNode.insertBefore(block);
1402
+ for (const childDom of domNode.childNodes) {
1403
+ this.reflowNode(childDom, block);
1404
+ }
1405
+ }
1406
+ /** @internal */
1407
+ reflowAsInline(domNode, renderNode) {
1408
+ let newRenderNode = renderNode;
1409
+ let nodeReplaced = false;
1410
+ if (renderNode.nodeType !== 3 /* INLINE */) {
1411
+ const lastChild = renderNode.lastChild;
1412
+ if (lastChild?.nodeType === 3 /* INLINE */) {
1413
+ newRenderNode = lastChild;
1414
+ } else {
1415
+ newRenderNode = new RenderInline();
1416
+ nodeReplaced = true;
1417
+ }
1418
+ }
1419
+ if (domNode.nodeType === 3 /* TEXT_NODE */) {
1420
+ if (!domNode.textContent) return;
1421
+ const text = new RenderText();
1422
+ text.domNode = domNode;
1423
+ text.computeStyles();
1424
+ if (nodeReplaced) {
1425
+ renderNode.insertBefore(newRenderNode);
1426
+ }
1427
+ newRenderNode.insertBefore(text);
1428
+ return;
1429
+ }
1430
+ for (const childDom of domNode.childNodes) {
1431
+ this.reflowNode(childDom, newRenderNode);
1432
+ }
1433
+ if (nodeReplaced && newRenderNode.childNodes.length) {
1434
+ renderNode.insertBefore(newRenderNode);
1435
+ }
1436
+ }
1437
+ };
1438
+
1439
+ // src/tree/RenderTree/index.ts
1440
+ var Render = Object.freeze({
1441
+ Flow: RenderFlow,
1442
+ Block: RenderBlock,
1443
+ Inline: RenderInline,
1444
+ RenderText,
1445
+ Type: RenderNodeType
1446
+ });
1447
+
1448
+ // src/Container.ts
1449
+ var Container = class extends DOMDocument {
1450
+ constructor({
1451
+ debug,
1452
+ exitOnCtrlC,
1453
+ stderr,
1454
+ stdin,
1455
+ stdout
1456
+ }) {
1457
+ super();
1458
+ __publicField(this, "tagName", "#container");
1459
+ __publicField(this, "stdout");
1460
+ __publicField(this, "stdin");
1461
+ __publicField(this, "stderr");
1462
+ __publicField(this, "exitOnCtrlC");
1463
+ __publicField(this, "flow");
1464
+ __publicField(this, "write");
1465
+ this.write = writeCleaner(stdout, 0);
1466
+ this.stdout = stdout;
1467
+ this.stdin = stdin;
1468
+ this.stderr = stderr;
1469
+ this.exitOnCtrlC = exitOnCtrlC;
1470
+ this.flow = new Render.Flow({
1471
+ document: this,
1472
+ height: 0,
1473
+ width: 0
1474
+ });
1475
+ this.stdout.on("resize", this.onResize.bind(this));
1476
+ this.flow.on("frame", this.onFrame.bind(this));
1477
+ this.onResize();
1478
+ }
1479
+ onResize() {
1480
+ this.stdout.write(ansiEscapes.clearTerminal);
1481
+ this.flow.width = this.stdout.columns || 80;
1482
+ this.flow.height = this.stdout.rows || 20;
1483
+ this.flow.reflowSchedule();
1484
+ }
1485
+ onFrame() {
1486
+ if (this.flow.reflowScheduled) return;
1487
+ this.write(this.flow.layer.frame);
1488
+ }
1489
+ };
1490
+ function createContainer(options) {
1491
+ const instance = new Container({
1492
+ debug: false,
1493
+ exitOnCtrlC: true,
1494
+ stdin: process.stdin,
1495
+ stdout: process.stdout,
1496
+ stderr: process.stderr,
1497
+ ...options ?? {}
1498
+ });
1499
+ return instance;
1500
+ }
1501
+
1502
+ // src/createApp.ts
1503
+ import { createRenderer } from "@vue/runtime-core";
1504
+
1505
+ // src/nodeOps.ts
1506
+ var nodeOps_exports = {};
1507
+ __export(nodeOps_exports, {
1508
+ createComment: () => createComment,
1509
+ createElement: () => createElement,
1510
+ createText: () => createText,
1511
+ insert: () => insert,
1512
+ nextSibling: () => nextSibling,
1513
+ parentNode: () => parentNode,
1514
+ patchProp: () => patchProp,
1515
+ querySelector: () => querySelector,
1516
+ remove: () => remove,
1517
+ setElementText: () => setElementText,
1518
+ setScopeId: () => setScopeId,
1519
+ setText: () => setText
1520
+ });
1521
+ function patchProp(el, key, prevValue, nextValue) {
1522
+ if (nextValue === void 0) {
1523
+ el.removeAttribute(key);
1524
+ } else {
1525
+ el.setAttribute(key, nextValue);
1526
+ }
1527
+ }
1528
+ function insert(child, parent, ref2) {
1529
+ parent.insertBefore(child, ref2);
1530
+ }
1531
+ function remove(child) {
1532
+ child.remove();
1533
+ }
1534
+ function setText(node, text) {
1535
+ node.textContent = text;
1536
+ }
1537
+ function createElement(tagName) {
1538
+ return DOM.Document.createElement(tagName);
1539
+ }
1540
+ function createComment(text) {
1541
+ return DOM.Document.createComment(text);
1542
+ }
1543
+ function createText(text) {
1544
+ return DOM.Document.createTextNode(text);
1545
+ }
1546
+ function setElementText(el, text) {
1547
+ el.textContent = text;
1548
+ }
1549
+ function parentNode(node) {
1550
+ return node.parentNode;
1551
+ }
1552
+ function nextSibling(node) {
1553
+ return node.nextSibling;
1554
+ }
1555
+ function setScopeId(el, id) {
1556
+ el.setAttribute(id, "");
1557
+ }
1558
+ function querySelector() {
1559
+ throw new Error("querySelector not supported in stdout renderer.");
1560
+ }
1561
+
1562
+ // src/createApp.ts
1563
+ var {
1564
+ createApp
1565
+ } = createRenderer(nodeOps_exports);
1566
+ export {
1567
+ Box,
1568
+ DOM,
1569
+ DOMComment,
1570
+ DOMDocument,
1571
+ DOMElement,
1572
+ DOMNode,
1573
+ DOMNodeType,
1574
+ DOMText,
1575
+ NewLine,
1576
+ ProgressBar,
1577
+ Render,
1578
+ Text,
1579
+ createApp,
1580
+ createContainer,
1581
+ useContainerSize,
1582
+ useDOMElement,
1583
+ useEventListener
1584
+ };