@promptctl/rich-js 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +31 -30
  2. package/dist/core/box.d.ts +3 -3
  3. package/dist/core/box.d.ts.map +1 -1
  4. package/dist/core/box.js.map +1 -1
  5. package/dist/core/cells.d.ts +46 -1
  6. package/dist/core/cells.d.ts.map +1 -1
  7. package/dist/core/cells.js +55 -14
  8. package/dist/core/cells.js.map +1 -1
  9. package/dist/core/console.d.ts +28 -10
  10. package/dist/core/console.d.ts.map +1 -1
  11. package/dist/core/console.js +141 -80
  12. package/dist/core/console.js.map +1 -1
  13. package/dist/core/markup.d.ts +0 -2
  14. package/dist/core/markup.d.ts.map +1 -1
  15. package/dist/core/markup.js +31 -17
  16. package/dist/core/markup.js.map +1 -1
  17. package/dist/core/measure.d.ts +11 -0
  18. package/dist/core/measure.d.ts.map +1 -1
  19. package/dist/core/measure.js +15 -3
  20. package/dist/core/measure.js.map +1 -1
  21. package/dist/core/oklch.d.ts +22 -0
  22. package/dist/core/oklch.d.ts.map +1 -1
  23. package/dist/core/oklch.js +62 -18
  24. package/dist/core/oklch.js.map +1 -1
  25. package/dist/core/pretty.d.ts +87 -0
  26. package/dist/core/pretty.d.ts.map +1 -0
  27. package/dist/core/pretty.js +304 -0
  28. package/dist/core/pretty.js.map +1 -0
  29. package/dist/core/protocol.d.ts +64 -0
  30. package/dist/core/protocol.d.ts.map +1 -1
  31. package/dist/core/protocol.js +72 -0
  32. package/dist/core/protocol.js.map +1 -1
  33. package/dist/core/segment.d.ts +21 -0
  34. package/dist/core/segment.d.ts.map +1 -1
  35. package/dist/core/segment.js +40 -1
  36. package/dist/core/segment.js.map +1 -1
  37. package/dist/core/subscription.d.ts +13 -0
  38. package/dist/core/subscription.d.ts.map +1 -0
  39. package/dist/core/subscription.js +13 -0
  40. package/dist/core/subscription.js.map +1 -0
  41. package/dist/core/text.d.ts.map +1 -1
  42. package/dist/core/text.js +45 -13
  43. package/dist/core/text.js.map +1 -1
  44. package/dist/host/host-stream.d.ts +31 -0
  45. package/dist/host/host-stream.d.ts.map +1 -0
  46. package/dist/host/host-stream.js +36 -0
  47. package/dist/host/host-stream.js.map +1 -0
  48. package/dist/host/index.d.ts +4 -0
  49. package/dist/host/index.d.ts.map +1 -0
  50. package/dist/host/index.js +3 -0
  51. package/dist/host/index.js.map +1 -0
  52. package/dist/host/terminal-host.d.ts +144 -0
  53. package/dist/host/terminal-host.d.ts.map +1 -0
  54. package/dist/host/terminal-host.js +133 -0
  55. package/dist/host/terminal-host.js.map +1 -0
  56. package/dist/index.d.ts +10 -33
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +33 -21
  59. package/dist/index.js.map +1 -1
  60. package/dist/node/terminal-host.d.ts +85 -0
  61. package/dist/node/terminal-host.d.ts.map +1 -0
  62. package/dist/node/terminal-host.js +161 -0
  63. package/dist/node/terminal-host.js.map +1 -0
  64. package/dist/node/traceback.d.ts +28 -0
  65. package/dist/node/traceback.d.ts.map +1 -0
  66. package/dist/node/traceback.js +113 -0
  67. package/dist/node/traceback.js.map +1 -0
  68. package/dist/renderables/columns.d.ts +24 -2
  69. package/dist/renderables/columns.d.ts.map +1 -1
  70. package/dist/renderables/columns.js +91 -32
  71. package/dist/renderables/columns.js.map +1 -1
  72. package/dist/renderables/layout.d.ts +61 -5
  73. package/dist/renderables/layout.d.ts.map +1 -1
  74. package/dist/renderables/layout.js +191 -19
  75. package/dist/renderables/layout.js.map +1 -1
  76. package/dist/renderables/padding.d.ts +15 -2
  77. package/dist/renderables/padding.d.ts.map +1 -1
  78. package/dist/renderables/padding.js +92 -37
  79. package/dist/renderables/padding.js.map +1 -1
  80. package/dist/renderables/panel.d.ts +44 -3
  81. package/dist/renderables/panel.d.ts.map +1 -1
  82. package/dist/renderables/panel.js +149 -80
  83. package/dist/renderables/panel.js.map +1 -1
  84. package/dist/renderables/table.d.ts +40 -4
  85. package/dist/renderables/table.d.ts.map +1 -1
  86. package/dist/renderables/table.js +276 -158
  87. package/dist/renderables/table.js.map +1 -1
  88. package/dist/renderables/traceback.d.ts +6 -2
  89. package/dist/renderables/traceback.d.ts.map +1 -1
  90. package/dist/renderables/traceback.js +6 -10
  91. package/dist/renderables/traceback.js.map +1 -1
  92. package/dist/renderables/tree.d.ts +27 -2
  93. package/dist/renderables/tree.d.ts.map +1 -1
  94. package/dist/renderables/tree.js +82 -23
  95. package/dist/renderables/tree.js.map +1 -1
  96. package/dist/template-bindings/color-funcs.d.ts +3 -3
  97. package/dist/template-bindings/color-funcs.js +3 -3
  98. package/dist/template-bindings/index.d.ts +6 -7
  99. package/dist/template-bindings/index.d.ts.map +1 -1
  100. package/dist/template-bindings/index.js +6 -7
  101. package/dist/template-bindings/index.js.map +1 -1
  102. package/dist/template-bindings/palette-funcs.d.ts +17 -5
  103. package/dist/template-bindings/palette-funcs.d.ts.map +1 -1
  104. package/dist/template-bindings/palette-funcs.js +69 -6
  105. package/dist/template-bindings/palette-funcs.js.map +1 -1
  106. package/dist/template-bindings/style-funcs.d.ts +1 -1
  107. package/dist/template-bindings/style-funcs.js +1 -1
  108. package/dist/themes/ramp.d.ts +84 -0
  109. package/dist/themes/ramp.d.ts.map +1 -0
  110. package/dist/themes/ramp.js +123 -0
  111. package/dist/themes/ramp.js.map +1 -0
  112. package/dist/widgets/dropdown.d.ts +1 -1
  113. package/dist/widgets/dropdown.js +1 -1
  114. package/dist/widgets/event-router.d.ts +3 -2
  115. package/dist/widgets/event-router.d.ts.map +1 -1
  116. package/dist/widgets/focus-manager.d.ts +2 -1
  117. package/dist/widgets/focus-manager.d.ts.map +1 -1
  118. package/dist/widgets/index.d.ts +3 -6
  119. package/dist/widgets/index.d.ts.map +1 -1
  120. package/dist/widgets/index.js +4 -3
  121. package/dist/widgets/index.js.map +1 -1
  122. package/dist/widgets/screen.d.ts +1 -1
  123. package/dist/widgets/screen.d.ts.map +1 -1
  124. package/dist/widgets/terminal-host.d.ts +13 -63
  125. package/dist/widgets/terminal-host.d.ts.map +1 -1
  126. package/dist/widgets/terminal-host.js +11 -142
  127. package/dist/widgets/terminal-host.js.map +1 -1
  128. package/dist/widgets/text-input.d.ts +2 -3
  129. package/dist/widgets/text-input.d.ts.map +1 -1
  130. package/dist/widgets/text-input.js +4 -12
  131. package/dist/widgets/text-input.js.map +1 -1
  132. package/dist/widgets/types.d.ts +1 -1
  133. package/dist/widgets/types.d.ts.map +1 -1
  134. package/dist/widgets/types.js.map +1 -1
  135. package/dist/widgets/widget-base.d.ts +2 -1
  136. package/dist/widgets/widget-base.d.ts.map +1 -1
  137. package/package.json +20 -4
@@ -4,7 +4,8 @@
4
4
  import { Segment } from "../core/segment.js";
5
5
  import { Measurement } from "../core/measure.js";
6
6
  import { RichText } from "../core/text.js";
7
- import { isMeasurable } from "../core/protocol.js";
7
+ import { isMeasurable, withBoundedWidth, withCellWidth } from "../core/protocol.js";
8
+ import { cellCount } from "../core/cells.js";
8
9
  function toRenderable(item) {
9
10
  if (typeof item === "object" && item !== null && "render" in item) {
10
11
  return item;
@@ -22,41 +23,29 @@ export class Columns {
22
23
  this.renderables = items ? [...items].map(toRenderable) : [];
23
24
  this.expand = options?.expand ?? false;
24
25
  this.equal = options?.equal ?? false;
25
- this.colWidth = options?.width;
26
+ // A declared column width is a cell count like any other, and it reaches
27
+ // the layout without passing through `withCellWidth`, which parses only
28
+ // what the *caller of render* supplied. Left raw, `width: NaN` made
29
+ // `Math.max(1, NaN)` a NaN column count and `new Array` threw `Invalid
30
+ // array length` before a single column was laid out. Absence is preserved
31
+ // rather than parsed: `undefined` selects auto-fit, and `cellCount` would
32
+ // read it as a declared zero.
33
+ this.colWidth = options?.width === undefined ? undefined : cellCount(options.width);
26
34
  this.columnFirst = options?.columnFirst ?? false;
27
35
  this.gutterWidth = 2; // default gutter between columns
28
36
  }
29
- *render(options) {
37
+ *render(rawOptions) {
30
38
  const items = this.renderables;
31
39
  if (items.length === 0)
32
40
  return;
33
- const maxWidth = options.maxWidth;
34
- // Determine column widths
35
- let numCols;
36
- let colWidths;
37
- if (this.colWidth !== undefined) {
38
- numCols = Math.max(1, Math.floor((maxWidth + this.gutterWidth) / (this.colWidth + this.gutterWidth)));
39
- colWidths = new Array(numCols).fill(this.colWidth);
40
- }
41
- else if (this.equal) {
42
- // Measure all items to find the widest
43
- let maxItemWidth = 1;
44
- for (const item of items) {
45
- if (isMeasurable(item)) {
46
- const m = Measurement.get(options, item);
47
- maxItemWidth = Math.max(maxItemWidth, m.maximum);
48
- }
49
- }
50
- numCols = Math.max(1, Math.floor((maxWidth + this.gutterWidth) / (maxItemWidth + this.gutterWidth)));
51
- const equalWidth = Math.floor((maxWidth - this.gutterWidth * (numCols - 1)) / numCols);
52
- colWidths = new Array(numCols).fill(equalWidth);
53
- }
54
- else {
55
- // Auto: fit as many columns as possible
56
- numCols = Math.min(items.length, Math.max(1, Math.floor(maxWidth / 4)));
57
- const colW = Math.floor((maxWidth - this.gutterWidth * (numCols - 1)) / numCols);
58
- colWidths = new Array(numCols).fill(colW);
59
- }
41
+ // The parsed options, not just a parsed local: `_divide` hands them to
42
+ // `Measurement.get`, and a raw NaN reaching it comes back as a NaN item
43
+ // width, then a NaN column count, then `Invalid array length` out of
44
+ // `new Array(numCols)` before a single column is laid out. An unbounded
45
+ // width reaches the same `new Array` by the same route, which is why the
46
+ // parse here is the bounded one.
47
+ const options = withBoundedWidth(rawOptions, this);
48
+ const { numCols, colWidths } = this._divide(options);
60
49
  // Layout items into rows
61
50
  const numRows = Math.ceil(items.length / numCols);
62
51
  // [LAW:types-are-the-program] The element type is Renderable — any number
@@ -78,8 +67,78 @@ export class Columns {
78
67
  yield* Segment.mergeHorizontal(cells, this.gutterWidth);
79
68
  }
80
69
  }
81
- measure(options) {
82
- return { minimum: 1, maximum: options.maxWidth };
70
+ /**
71
+ * The requested width divided into columns, once.
72
+ *
73
+ * [LAW:single-enforcer] The three modes disagree only about how many columns
74
+ * there are and how wide each one is, so they disagree in one place. `render`
75
+ * lays out against this division and `_naturalWidth` is the width at which it
76
+ * comes out as one row of every item.
77
+ */
78
+ _divide(options) {
79
+ const maxWidth = options.maxWidth;
80
+ const gutter = this.gutterWidth;
81
+ if (this.colWidth !== undefined) {
82
+ const numCols = Math.max(1, Math.floor((maxWidth + gutter) / (this.colWidth + gutter)));
83
+ return { numCols, colWidths: new Array(numCols).fill(this.colWidth) };
84
+ }
85
+ if (this.equal) {
86
+ const itemWidth = this._itemWidth(options);
87
+ const numCols = Math.max(1, Math.floor((maxWidth + gutter) / (itemWidth + gutter)));
88
+ const equalWidth = Math.floor((maxWidth - gutter * (numCols - 1)) / numCols);
89
+ return { numCols, colWidths: new Array(numCols).fill(equalWidth) };
90
+ }
91
+ // Auto: as many columns as the widest item fits into, capped at the item
92
+ // count. Sized from the content rather than from a flat four cells per
93
+ // column, because `_naturalWidth` below is the inverse of *this* expression
94
+ // and a constant has no inverse: six two-cell items reported a natural
95
+ // width of 22 and then wrapped into two rows at 22, since `floor(22 / 4)`
96
+ // is five columns no matter how narrow the items are.
97
+ const itemWidth = this._itemWidth(options);
98
+ const numCols = Math.min(this.renderables.length, Math.max(1, Math.floor((maxWidth + gutter) / (itemWidth + gutter))));
99
+ const colW = Math.floor((maxWidth - gutter * (numCols - 1)) / numCols);
100
+ return { numCols, colWidths: new Array(numCols).fill(colW) };
101
+ }
102
+ /**
103
+ * The widest any one item wants to be.
104
+ *
105
+ * An item that cannot measure itself wants the offer, which is what `Panel`,
106
+ * `Padding`, `Layout` and `Tree` all answer for the same case — and under an
107
+ * unbounded offer that is `Infinity`, so `withBoundedWidth` throws and says
108
+ * the request was unanswerable. Counting it as one cell instead reported a
109
+ * natural width of 1, which resolved an unbounded offer to a single column and
110
+ * cropped forty cells of content down to `"x"` with no error at all.
111
+ */
112
+ _itemWidth(options) {
113
+ let widest = 1;
114
+ for (const item of this.renderables) {
115
+ widest = Math.max(widest, isMeasurable(item)
116
+ ? Measurement.get(options, item).maximum
117
+ : options.maxWidth);
118
+ }
119
+ return widest;
120
+ }
121
+ /** The width at which every item sits on one row: n columns and the gutters between them. */
122
+ _naturalWidth(options) {
123
+ const count = this.renderables.length;
124
+ if (count === 0)
125
+ return 0;
126
+ const width = this.colWidth ?? this._itemWidth(options);
127
+ return count * width + this.gutterWidth * (count - 1);
128
+ }
129
+ measure(rawOptions) {
130
+ // A floor of one cell is what Columns asks for; the ceiling is what it was
131
+ // offered, and the ceiling wins. Stated as a bare `minimum: 1`, a Columns
132
+ // measured into no width at all reported the range 1..0 — a floor above
133
+ // its own ceiling, which the parent that asked cannot divide.
134
+ //
135
+ // The ceiling is not the whole answer, though: reported as the offer alone,
136
+ // a Columns claimed every cell it was shown, so `Panel` in fit mode drew a
137
+ // 40-cell frame around five cells of content and an unbounded offer came
138
+ // back unbounded.
139
+ const parsed = withCellWidth(rawOptions);
140
+ const maximum = Math.min(this._naturalWidth(parsed), parsed.maxWidth);
141
+ return { minimum: Math.min(1, maximum), maximum };
83
142
  }
84
143
  }
85
144
  //# sourceMappingURL=columns.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"columns.js","sourceRoot":"","sources":["../../src/renderables/columns.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAO3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAUnD,SAAS,YAAY,CAAC,IAAa;IACjC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QAClE,OAAO,IAAwC,CAAC;IAClD,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,OAAO,OAAO;IAClB,WAAW,CAAuC;IACzC,MAAM,CAAU;IAChB,KAAK,CAAU;IACf,QAAQ,CAAqB;IAC7B,WAAW,CAAU;IACrB,WAAW,CAAS;IAE7B,YAAY,KAAyB,EAAE,OAAwB;QAC7D,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,KAAK,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,KAAK,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,KAAK,CAAC;QACjD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,iCAAiC;IACzD,CAAC;IAED,CAAC,MAAM,CAAC,OAAsB;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE/B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAElC,0BAA0B;QAC1B,IAAI,OAAe,CAAC;QACpB,IAAI,SAAmB,CAAC;QAExB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YACtG,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAa,CAAC;QACjE,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtB,uCAAuC;YACvC,IAAI,YAAY,GAAG,CAAC,CAAC;YACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvB,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;oBACzC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YACD,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YACrG,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;YACvF,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAa,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,wCAAwC;YACxC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACxE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;YACjF,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAa,CAAC;QACxD,CAAC;QAED,yBAAyB;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;QAElD,0EAA0E;QAC1E,6EAA6E;QAC7E,4EAA4E;QAC5E,sEAAsE;QACtE,0EAA0E;QAC1E,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBACzC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,GAAG,GAAG,CAAC;gBACzE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;gBACxB,MAAM,KAAK,GACT,IAAI,KAAK,SAAS;oBAChB,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;wBACjB,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;qBAChD,CAAC,CAAC;gBACT,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,OAAsB;QAC5B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;IACnD,CAAC;CACF"}
1
+ {"version":3,"file":"columns.js","sourceRoot":"","sources":["../../src/renderables/columns.ts"],"names":[],"mappings":"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"}
@@ -12,24 +12,80 @@ export interface LayoutOptions {
12
12
  }
13
13
  export declare class Layout implements Renderable, Measurable {
14
14
  name: string | undefined;
15
- ratio: number;
16
- size: number | undefined;
17
- minimumSize: number;
18
15
  visible: boolean;
16
+ private _ratio;
17
+ private _size;
18
+ private _minimumSize;
19
19
  private _renderable;
20
20
  private _children;
21
21
  private _splitDirection;
22
22
  constructor(renderable?: Renderable | string, options?: LayoutOptions);
23
+ /**
24
+ * The three declared numbers, parsed on assignment rather than at the
25
+ * constructor. All three are public and a caller reaches them long after
26
+ * construction — `layout.getByName("pane")!.ratio = -1` walked straight past a
27
+ * constructor-only parse and put a negative weight back into the division that
28
+ * `_rowBudgetFor` and `_distributeSpace` are written to trust.
29
+ *
30
+ * [LAW:parse-dont-validate] The setter is the border, so the guarantee holds
31
+ * for the object's whole lifetime and nothing downstream re-checks. `size` and
32
+ * `minimumSize` are cell counts; `ratio` is a share weight and keeps its
33
+ * fractions. Absence is preserved rather than parsed: an undefined `size`
34
+ * selects a flex pane, and `cellCount` would read it as a declared zero.
35
+ */
36
+ get ratio(): number;
37
+ set ratio(value: number);
38
+ get size(): number | undefined;
39
+ set size(value: number | undefined);
40
+ get minimumSize(): number;
41
+ set minimumSize(value: number);
23
42
  get children(): Layout[];
43
+ /**
44
+ * Whether this layout draws `_renderable` or its children.
45
+ *
46
+ * [LAW:one-source-of-truth] `render` and `_naturalWidth` must answer this the
47
+ * same way. Asked separately they did not: `_naturalWidth` read it off the
48
+ * *visible* children, so a layout holding content and a single hidden child
49
+ * reported that content's width while `render` emitted nothing at all, and a
50
+ * fit-mode `Panel` framed twelve cells of air.
51
+ */
52
+ private get _isLeaf();
24
53
  splitColumn(...layouts: Layout[]): void;
25
54
  splitRow(...layouts: Layout[]): void;
26
55
  update(renderable: Renderable | string): void;
27
56
  getByName(name: string): Layout | undefined;
28
- render(options: RenderOptions): Iterable<Segment>;
57
+ render(rawOptions: RenderOptions): Iterable<Segment>;
29
58
  private _renderColumn;
30
59
  private _renderRow;
31
60
  private _distributeSpace;
32
- measure(options: RenderOptions): {
61
+ /**
62
+ * The width this layout would take if nothing constrained it: its content's
63
+ * for a leaf, its children's laid out the way the split lays them out.
64
+ *
65
+ * A `size` counts only across a row, which is the one direction in which it
66
+ * is a width — down a column the same field is a height, and reading it as a
67
+ * width there would report a two-line pane as two cells wide.
68
+ */
69
+ private _naturalWidth;
70
+ /**
71
+ * The budget at which `_distributeSpace` gives every child of a row at least
72
+ * the width it wants — the inverse of the ratio rule above, and the reason
73
+ * this is not the sum of those widths.
74
+ *
75
+ * [LAW:one-source-of-truth] A growing child receives `floor(budget * ratio /
76
+ * totalRatio)`, so to receive `want` cells it needs the budget to reach
77
+ * `want * totalRatio / ratio`, and one budget serves them all: the row needs
78
+ * the largest demand, never their total. Summed instead, a 1:1 split of
79
+ * "left" and "right" reported 9 and then rendered "right" into the 4 cells
80
+ * that `floor(9/2)` actually hands it.
81
+ *
82
+ * The panes that do not grow are paid first here for the same reason they
83
+ * are paid first there — and it is the reason this divides by no zero: a
84
+ * `ratio` of 0 never reaches the division, because a pane that does not grow
85
+ * demands nothing of a budget for growing.
86
+ */
87
+ private _rowBudgetFor;
88
+ measure(rawOptions: RenderOptions): {
33
89
  minimum: number;
34
90
  maximum: number;
35
91
  };
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/renderables/layout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,MAAO,YAAW,UAAU,EAAE,UAAU;IACnD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,eAAe,CAA+B;gBAE1C,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAerE,IAAI,QAAQ,IAAI,MAAM,EAAE,CAEvB;IAED,WAAW,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAKvC,QAAQ,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAKpC,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI;IAM7C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAS1C,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IAqBlD,OAAO,CAAE,aAAa;IAmBtB,OAAO,CAAE,UAAU;IAenB,OAAO,CAAC,gBAAgB;IAoCxB,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAGtE"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/renderables/layout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;AAK7B,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAaD,qBAAa,MAAO,YAAW,UAAU,EAAE,UAAU;IACnD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,eAAe,CAA+B;gBAE1C,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa;IAerE;;;;;;;;;;;;OAYG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAEjC;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,MAAM,EAE5B;IAED,IAAI,QAAQ,IAAI,MAAM,EAAE,CAEvB;IAED;;;;;;;;OAQG;IACH,OAAO,KAAK,OAAO,GAElB;IAED,WAAW,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAKvC,QAAQ,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAKpC,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI;IAM7C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAS1C,MAAM,CAAC,UAAU,EAAE,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IA8BrD,OAAO,CAAE,aAAa;IAmBtB,OAAO,CAAE,UAAU;IAiBnB,OAAO,CAAC,gBAAgB;IAuDxB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IA4BrB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,UAAU,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAczE"}
@@ -3,12 +3,25 @@
3
3
  */
4
4
  import { Segment } from "../core/segment.js";
5
5
  import { RichText } from "../core/text.js";
6
+ import { isMeasurable, withBoundedWidth, withCellWidth } from "../core/protocol.js";
7
+ import { Measurement } from "../core/measure.js";
8
+ import { cellCount } from "../core/cells.js";
9
+ /**
10
+ * A share weight, not a cell count: fractions divide space meaningfully, so
11
+ * this parses where `cellCount` would floor. A weight that cannot name a share
12
+ * — negative, NaN, infinite — reads as zero, which already means "this pane
13
+ * does not grow" and is filtered out before any division. That is what makes
14
+ * every ratio reaching `_distributeSpace` and `_rowBudgetFor` positive.
15
+ */
16
+ function growthRatio(ratio) {
17
+ return Number.isFinite(ratio) && ratio > 0 ? ratio : 0;
18
+ }
6
19
  export class Layout {
7
20
  name;
8
- ratio;
9
- size;
10
- minimumSize;
11
21
  visible;
22
+ _ratio;
23
+ _size;
24
+ _minimumSize;
12
25
  _renderable;
13
26
  _children;
14
27
  _splitDirection;
@@ -26,9 +39,52 @@ export class Layout {
26
39
  this._children = [];
27
40
  this._splitDirection = undefined;
28
41
  }
42
+ /**
43
+ * The three declared numbers, parsed on assignment rather than at the
44
+ * constructor. All three are public and a caller reaches them long after
45
+ * construction — `layout.getByName("pane")!.ratio = -1` walked straight past a
46
+ * constructor-only parse and put a negative weight back into the division that
47
+ * `_rowBudgetFor` and `_distributeSpace` are written to trust.
48
+ *
49
+ * [LAW:parse-dont-validate] The setter is the border, so the guarantee holds
50
+ * for the object's whole lifetime and nothing downstream re-checks. `size` and
51
+ * `minimumSize` are cell counts; `ratio` is a share weight and keeps its
52
+ * fractions. Absence is preserved rather than parsed: an undefined `size`
53
+ * selects a flex pane, and `cellCount` would read it as a declared zero.
54
+ */
55
+ get ratio() {
56
+ return this._ratio;
57
+ }
58
+ set ratio(value) {
59
+ this._ratio = growthRatio(value);
60
+ }
61
+ get size() {
62
+ return this._size;
63
+ }
64
+ set size(value) {
65
+ this._size = value === undefined ? undefined : cellCount(value);
66
+ }
67
+ get minimumSize() {
68
+ return this._minimumSize;
69
+ }
70
+ set minimumSize(value) {
71
+ this._minimumSize = cellCount(value);
72
+ }
29
73
  get children() {
30
74
  return this._children;
31
75
  }
76
+ /**
77
+ * Whether this layout draws `_renderable` or its children.
78
+ *
79
+ * [LAW:one-source-of-truth] `render` and `_naturalWidth` must answer this the
80
+ * same way. Asked separately they did not: `_naturalWidth` read it off the
81
+ * *visible* children, so a layout holding content and a single hidden child
82
+ * reported that content's width while `render` emitted nothing at all, and a
83
+ * fit-mode `Panel` framed twelve cells of air.
84
+ */
85
+ get _isLeaf() {
86
+ return this._children.length === 0;
87
+ }
32
88
  splitColumn(...layouts) {
33
89
  this._children = layouts;
34
90
  this._splitDirection = "column";
@@ -52,13 +108,21 @@ export class Layout {
52
108
  }
53
109
  return undefined;
54
110
  }
55
- *render(options) {
111
+ *render(rawOptions) {
56
112
  if (!this.visible)
57
113
  return;
58
- if (this._children.length === 0) {
59
- // Leaf node — render content
114
+ // Parsed once at the top of the layout rather than at the row split below,
115
+ // because a column split forwards the width to its children untouched and
116
+ // would otherwise hand each of them the caller's raw number.
117
+ const options = withBoundedWidth(rawOptions, this);
118
+ if (this._isLeaf) {
119
+ // Cropped rather than forwarded: a leaf hands its content the offer and
120
+ // content is free to ignore it, and a pane wider than the region it was
121
+ // given is the one thing a layout may never emit — in a row split it
122
+ // overwrites the pane beside it. The row path already crops each share,
123
+ // so this is the same rule at the one place that skipped it.
60
124
  if (this._renderable) {
61
- yield* this._renderable.render(options);
125
+ yield* Segment.cropLines(this._renderable.render(options), options.maxWidth);
62
126
  }
63
127
  return;
64
128
  }
@@ -87,7 +151,9 @@ export class Layout {
87
151
  }
88
152
  }
89
153
  *_renderRow(children, options) {
90
- // Horizontal side-by-side: distribute width, then merge child lines.
154
+ // Horizontal side-by-side: divide the requested width once, then merge
155
+ // child lines. The budget arrives parsed from `render` — unparsed, a NaN
156
+ // width made every share NaN and the merge threw `Invalid array length`.
91
157
  const widths = this._distributeSpace(children, options.maxWidth);
92
158
  const cells = children.map((child, i) => ({
93
159
  width: widths[i],
@@ -100,31 +166,137 @@ export class Layout {
100
166
  _distributeSpace(children, totalSpace) {
101
167
  const sizes = new Array(children.length).fill(0);
102
168
  let remaining = totalSpace;
103
- // Fixed-size children first
104
- const flexChildren = [];
169
+ // Children that do not grow are paid first: a declared `size`, and equally
170
+ // a `ratio` of 0, which is the caller saying this pane stays at its
171
+ // `minimumSize`. Left in the ratio pass below, a zero-ratio child divided
172
+ // by its own ratio and drew its minimum out of a budget the shares had
173
+ // already spent — three panes of `zzz`/`aaaaa`/`bbbbb` consumed
174
+ // `3 + 2*floor(T/2)` cells out of `T`, which no `T` satisfies, and the row
175
+ // only came out right at 16 because the `Math.min(remaining, ...)` below
176
+ // happened to clip the last share to the right number.
177
+ const growing = [];
105
178
  for (let i = 0; i < children.length; i++) {
106
179
  const child = children[i];
107
180
  if (child.size !== undefined) {
108
181
  sizes[i] = Math.min(child.size, remaining);
109
- remaining -= sizes[i];
182
+ }
183
+ else if (child.ratio === 0) {
184
+ sizes[i] = Math.min(child.minimumSize, remaining);
110
185
  }
111
186
  else {
112
- flexChildren.push(i);
187
+ growing.push(i);
188
+ continue;
113
189
  }
190
+ remaining -= sizes[i];
114
191
  }
115
- // Distribute remaining by ratio
116
- if (flexChildren.length > 0 && remaining > 0) {
117
- const totalRatio = flexChildren.reduce((s, idx) => s + children[idx].ratio, 0);
118
- for (const idx of flexChildren) {
192
+ // Distribute what is left by ratio. Each child's share comes off one
193
+ // budget and is bounded by what that budget still holds: `minimumSize` is
194
+ // what a child asks for, `remaining` is what there is to give, and the
195
+ // second beats the first. Applied without that bound — as
196
+ // `Math.max(minimumSize, share)` alone — every child claimed its whole
197
+ // minimum out of a budget that could not cover one of them, so two
198
+ // children of a Layout asked to fit one cell merged into a two-cell row.
199
+ if (growing.length > 0 && remaining > 0) {
200
+ const budget = remaining;
201
+ // Every ratio in here is positive — `growthRatio` parses the rest to zero
202
+ // at the constructor and zero is filtered out above — which is what makes
203
+ // the division safe and `_rowBudgetFor`'s inverse of it finite.
204
+ const totalRatio = growing.reduce((s, idx) => s + children[idx].ratio, 0);
205
+ for (const idx of growing) {
119
206
  const child = children[idx];
120
- const allocated = Math.max(child.minimumSize, Math.floor(remaining * child.ratio / totalRatio));
207
+ const share = Math.floor(budget * child.ratio / totalRatio);
208
+ const allocated = Math.min(remaining, Math.max(child.minimumSize, share));
121
209
  sizes[idx] = allocated;
210
+ remaining -= allocated;
122
211
  }
123
212
  }
124
213
  return sizes;
125
214
  }
126
- measure(options) {
127
- return { minimum: this.minimumSize, maximum: options.maxWidth };
215
+ /**
216
+ * The width this layout would take if nothing constrained it: its content's
217
+ * for a leaf, its children's laid out the way the split lays them out.
218
+ *
219
+ * A `size` counts only across a row, which is the one direction in which it
220
+ * is a width — down a column the same field is a height, and reading it as a
221
+ * width there would report a two-line pane as two cells wide.
222
+ */
223
+ _naturalWidth(options) {
224
+ if (!this.visible)
225
+ return 0;
226
+ if (this._isLeaf) {
227
+ if (this._renderable === undefined)
228
+ return 0;
229
+ // A leaf whose content cannot measure itself has no width of its own to
230
+ // report, so it reports the offer — unbounded included, which is where
231
+ // `withBoundedWidth` says so rather than inventing a number.
232
+ return isMeasurable(this._renderable)
233
+ ? Measurement.get(options, this._renderable).maximum
234
+ : options.maxWidth;
235
+ }
236
+ const visible = this._children.filter((c) => c.visible);
237
+ if (visible.length === 0)
238
+ return 0;
239
+ const widths = visible.map((c) => c._naturalWidth(options));
240
+ if (this._splitDirection === "row")
241
+ return this._rowBudgetFor(visible, widths);
242
+ // Accumulated, not spread: a column split holds as many children as a caller
243
+ // made, and `Math.max(...widths)` passes one argument per child, so a
244
+ // generated dashboard deep enough overruns the engine's argument limit and
245
+ // throws out of `measure()`.
246
+ let widest = 0;
247
+ for (const width of widths)
248
+ widest = Math.max(widest, width);
249
+ return widest;
250
+ }
251
+ /**
252
+ * The budget at which `_distributeSpace` gives every child of a row at least
253
+ * the width it wants — the inverse of the ratio rule above, and the reason
254
+ * this is not the sum of those widths.
255
+ *
256
+ * [LAW:one-source-of-truth] A growing child receives `floor(budget * ratio /
257
+ * totalRatio)`, so to receive `want` cells it needs the budget to reach
258
+ * `want * totalRatio / ratio`, and one budget serves them all: the row needs
259
+ * the largest demand, never their total. Summed instead, a 1:1 split of
260
+ * "left" and "right" reported 9 and then rendered "right" into the 4 cells
261
+ * that `floor(9/2)` actually hands it.
262
+ *
263
+ * The panes that do not grow are paid first here for the same reason they
264
+ * are paid first there — and it is the reason this divides by no zero: a
265
+ * `ratio` of 0 never reaches the division, because a pane that does not grow
266
+ * demands nothing of a budget for growing.
267
+ */
268
+ _rowBudgetFor(children, widths) {
269
+ const growing = children.filter((c) => c.size === undefined && c.ratio !== 0);
270
+ const totalRatio = growing.reduce((sum, c) => sum + c.ratio, 0);
271
+ let pinned = 0;
272
+ let budget = 0;
273
+ for (const [i, child] of children.entries()) {
274
+ if (child.size !== undefined) {
275
+ pinned += child.size;
276
+ }
277
+ else if (child.ratio === 0) {
278
+ pinned += child.minimumSize;
279
+ }
280
+ else {
281
+ const want = Math.max(child.minimumSize, widths[i]);
282
+ budget = Math.max(budget, Math.ceil(want * totalRatio / child.ratio));
283
+ }
284
+ }
285
+ return pinned + budget;
286
+ }
287
+ measure(rawOptions) {
288
+ // `minimumSize` is what this layout asks for and the ceiling is what it was
289
+ // offered; the ceiling wins. Unclamped, a layout measured into no width
290
+ // reported the range 1..0 — a floor above its own ceiling, which the parent
291
+ // that asked cannot divide.
292
+ //
293
+ // The ceiling alone was not the answer either: a layout that reported the
294
+ // whole offer as its maximum told every parent it wanted all of it, so
295
+ // `Panel` in fit mode drew its frame at the full console width around a
296
+ // layout of two short panes, and an unbounded offer came back unbounded.
297
+ const parsed = withCellWidth(rawOptions);
298
+ const maximum = Math.min(this._naturalWidth(parsed), parsed.maxWidth);
299
+ return { minimum: Math.min(this.minimumSize, maximum), maximum };
128
300
  }
129
301
  }
130
302
  //# sourceMappingURL=layout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/renderables/layout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/renderables/layout.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,19 @@ import { Segment } from "../core/segment.js";
5
5
  import { Style } from "../core/style.js";
6
6
  import type { Renderable, Measurable, RenderOptions } from "../core/protocol.js";
7
7
  export type PaddingDimensions = number | [number, number] | [number, number, number, number];
8
+ /**
9
+ * Parses the shapes a caller may write padding in — one number, a vertical/
10
+ * horizontal pair, or all four sides — into the four-sided form every
11
+ * renderable indexes by, flooring each side at zero.
12
+ *
13
+ * [LAW:parse-dont-validate] This is the one crossing between the public
14
+ * padding vocabulary and the internal tuple, which is why the floor lives
15
+ * here and nowhere downstream: past this point `" ".repeat(left)` is safe in
16
+ * any renderable without asking what the caller passed. A negative side used
17
+ * to reach the renderers, where `Panel` drew content rows wider than its own
18
+ * border and `Table` threw outright.
19
+ */
20
+ export declare function normalizePadding(padding: PaddingDimensions): [number, number, number, number];
8
21
  export declare class Padding implements Renderable, Measurable {
9
22
  readonly renderable: Renderable;
10
23
  readonly top: number;
@@ -17,8 +30,8 @@ export declare class Padding implements Renderable, Measurable {
17
30
  style?: string | Style;
18
31
  expand?: boolean;
19
32
  });
20
- render(options: RenderOptions): Iterable<Segment>;
21
- measure(options: RenderOptions): {
33
+ render(rawOptions: RenderOptions): Iterable<Segment>;
34
+ measure(rawOptions: RenderOptions): {
22
35
  minimum: number;
23
36
  maximum: number;
24
37
  };
@@ -1 +1 @@
1
- {"version":3,"file":"padding.d.ts","sourceRoot":"","sources":["../../src/renderables/padding.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAc,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;AAG7B,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,CAAC,MAAM,EAAE,MAAM,CAAC,GAChB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAcrC,qBAAa,OAAQ,YAAW,UAAU,EAAE,UAAU;IACpD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAGvB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE;IAYvD,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IA2ClD,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAWtE"}
1
+ {"version":3,"file":"padding.d.ts","sourceRoot":"","sources":["../../src/renderables/padding.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAc,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,qBAAqB,CAAC;AAG7B,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,CAAC,MAAM,EAAE,MAAM,CAAC,GAChB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAErC;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,iBAAiB,GACzB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAqBlC;AA6CD,qBAAa,OAAQ,YAAW,UAAU,EAAE,UAAU;IACpD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAGvB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE;IAYvD,MAAM,CAAC,UAAU,EAAE,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IA6CrD,OAAO,CAAC,UAAU,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAsBzE"}