| 'use strict'; | 
|   | 
| const align = { | 
|     right: alignRight, | 
|     center: alignCenter | 
| }; | 
| const top = 0; | 
| const right = 1; | 
| const bottom = 2; | 
| const left = 3; | 
| class UI { | 
|     constructor(opts) { | 
|         var _a; | 
|         this.width = opts.width; | 
|         this.wrap = (_a = opts.wrap) !== null && _a !== void 0 ? _a : true; | 
|         this.rows = []; | 
|     } | 
|     span(...args) { | 
|         const cols = this.div(...args); | 
|         cols.span = true; | 
|     } | 
|     resetOutput() { | 
|         this.rows = []; | 
|     } | 
|     div(...args) { | 
|         if (args.length === 0) { | 
|             this.div(''); | 
|         } | 
|         if (this.wrap && this.shouldApplyLayoutDSL(...args) && typeof args[0] === 'string') { | 
|             return this.applyLayoutDSL(args[0]); | 
|         } | 
|         const cols = args.map(arg => { | 
|             if (typeof arg === 'string') { | 
|                 return this.colFromString(arg); | 
|             } | 
|             return arg; | 
|         }); | 
|         this.rows.push(cols); | 
|         return cols; | 
|     } | 
|     shouldApplyLayoutDSL(...args) { | 
|         return args.length === 1 && typeof args[0] === 'string' && | 
|             /[\t\n]/.test(args[0]); | 
|     } | 
|     applyLayoutDSL(str) { | 
|         const rows = str.split('\n').map(row => row.split('\t')); | 
|         let leftColumnWidth = 0; | 
|         // simple heuristic for layout, make sure the | 
|         // second column lines up along the left-hand. | 
|         // don't allow the first column to take up more | 
|         // than 50% of the screen. | 
|         rows.forEach(columns => { | 
|             if (columns.length > 1 && mixin.stringWidth(columns[0]) > leftColumnWidth) { | 
|                 leftColumnWidth = Math.min(Math.floor(this.width * 0.5), mixin.stringWidth(columns[0])); | 
|             } | 
|         }); | 
|         // generate a table: | 
|         //  replacing ' ' with padding calculations. | 
|         //  using the algorithmically generated width. | 
|         rows.forEach(columns => { | 
|             this.div(...columns.map((r, i) => { | 
|                 return { | 
|                     text: r.trim(), | 
|                     padding: this.measurePadding(r), | 
|                     width: (i === 0 && columns.length > 1) ? leftColumnWidth : undefined | 
|                 }; | 
|             })); | 
|         }); | 
|         return this.rows[this.rows.length - 1]; | 
|     } | 
|     colFromString(text) { | 
|         return { | 
|             text, | 
|             padding: this.measurePadding(text) | 
|         }; | 
|     } | 
|     measurePadding(str) { | 
|         // measure padding without ansi escape codes | 
|         const noAnsi = mixin.stripAnsi(str); | 
|         return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length]; | 
|     } | 
|     toString() { | 
|         const lines = []; | 
|         this.rows.forEach(row => { | 
|             this.rowToString(row, lines); | 
|         }); | 
|         // don't display any lines with the | 
|         // hidden flag set. | 
|         return lines | 
|             .filter(line => !line.hidden) | 
|             .map(line => line.text) | 
|             .join('\n'); | 
|     } | 
|     rowToString(row, lines) { | 
|         this.rasterize(row).forEach((rrow, r) => { | 
|             let str = ''; | 
|             rrow.forEach((col, c) => { | 
|                 const { width } = row[c]; // the width with padding. | 
|                 const wrapWidth = this.negatePadding(row[c]); // the width without padding. | 
|                 let ts = col; // temporary string used during alignment/padding. | 
|                 if (wrapWidth > mixin.stringWidth(col)) { | 
|                     ts += ' '.repeat(wrapWidth - mixin.stringWidth(col)); | 
|                 } | 
|                 // align the string within its column. | 
|                 if (row[c].align && row[c].align !== 'left' && this.wrap) { | 
|                     const fn = align[row[c].align]; | 
|                     ts = fn(ts, wrapWidth); | 
|                     if (mixin.stringWidth(ts) < wrapWidth) { | 
|                         ts += ' '.repeat((width || 0) - mixin.stringWidth(ts) - 1); | 
|                     } | 
|                 } | 
|                 // apply border and padding to string. | 
|                 const padding = row[c].padding || [0, 0, 0, 0]; | 
|                 if (padding[left]) { | 
|                     str += ' '.repeat(padding[left]); | 
|                 } | 
|                 str += addBorder(row[c], ts, '| '); | 
|                 str += ts; | 
|                 str += addBorder(row[c], ts, ' |'); | 
|                 if (padding[right]) { | 
|                     str += ' '.repeat(padding[right]); | 
|                 } | 
|                 // if prior row is span, try to render the | 
|                 // current row on the prior line. | 
|                 if (r === 0 && lines.length > 0) { | 
|                     str = this.renderInline(str, lines[lines.length - 1]); | 
|                 } | 
|             }); | 
|             // remove trailing whitespace. | 
|             lines.push({ | 
|                 text: str.replace(/ +$/, ''), | 
|                 span: row.span | 
|             }); | 
|         }); | 
|         return lines; | 
|     } | 
|     // if the full 'source' can render in | 
|     // the target line, do so. | 
|     renderInline(source, previousLine) { | 
|         const match = source.match(/^ */); | 
|         const leadingWhitespace = match ? match[0].length : 0; | 
|         const target = previousLine.text; | 
|         const targetTextWidth = mixin.stringWidth(target.trimRight()); | 
|         if (!previousLine.span) { | 
|             return source; | 
|         } | 
|         // if we're not applying wrapping logic, | 
|         // just always append to the span. | 
|         if (!this.wrap) { | 
|             previousLine.hidden = true; | 
|             return target + source; | 
|         } | 
|         if (leadingWhitespace < targetTextWidth) { | 
|             return source; | 
|         } | 
|         previousLine.hidden = true; | 
|         return target.trimRight() + ' '.repeat(leadingWhitespace - targetTextWidth) + source.trimLeft(); | 
|     } | 
|     rasterize(row) { | 
|         const rrows = []; | 
|         const widths = this.columnWidths(row); | 
|         let wrapped; | 
|         // word wrap all columns, and create | 
|         // a data-structure that is easy to rasterize. | 
|         row.forEach((col, c) => { | 
|             // leave room for left and right padding. | 
|             col.width = widths[c]; | 
|             if (this.wrap) { | 
|                 wrapped = mixin.wrap(col.text, this.negatePadding(col), { hard: true }).split('\n'); | 
|             } | 
|             else { | 
|                 wrapped = col.text.split('\n'); | 
|             } | 
|             if (col.border) { | 
|                 wrapped.unshift('.' + '-'.repeat(this.negatePadding(col) + 2) + '.'); | 
|                 wrapped.push("'" + '-'.repeat(this.negatePadding(col) + 2) + "'"); | 
|             } | 
|             // add top and bottom padding. | 
|             if (col.padding) { | 
|                 wrapped.unshift(...new Array(col.padding[top] || 0).fill('')); | 
|                 wrapped.push(...new Array(col.padding[bottom] || 0).fill('')); | 
|             } | 
|             wrapped.forEach((str, r) => { | 
|                 if (!rrows[r]) { | 
|                     rrows.push([]); | 
|                 } | 
|                 const rrow = rrows[r]; | 
|                 for (let i = 0; i < c; i++) { | 
|                     if (rrow[i] === undefined) { | 
|                         rrow.push(''); | 
|                     } | 
|                 } | 
|                 rrow.push(str); | 
|             }); | 
|         }); | 
|         return rrows; | 
|     } | 
|     negatePadding(col) { | 
|         let wrapWidth = col.width || 0; | 
|         if (col.padding) { | 
|             wrapWidth -= (col.padding[left] || 0) + (col.padding[right] || 0); | 
|         } | 
|         if (col.border) { | 
|             wrapWidth -= 4; | 
|         } | 
|         return wrapWidth; | 
|     } | 
|     columnWidths(row) { | 
|         if (!this.wrap) { | 
|             return row.map(col => { | 
|                 return col.width || mixin.stringWidth(col.text); | 
|             }); | 
|         } | 
|         let unset = row.length; | 
|         let remainingWidth = this.width; | 
|         // column widths can be set in config. | 
|         const widths = row.map(col => { | 
|             if (col.width) { | 
|                 unset--; | 
|                 remainingWidth -= col.width; | 
|                 return col.width; | 
|             } | 
|             return undefined; | 
|         }); | 
|         // any unset widths should be calculated. | 
|         const unsetWidth = unset ? Math.floor(remainingWidth / unset) : 0; | 
|         return widths.map((w, i) => { | 
|             if (w === undefined) { | 
|                 return Math.max(unsetWidth, _minWidth(row[i])); | 
|             } | 
|             return w; | 
|         }); | 
|     } | 
| } | 
| function addBorder(col, ts, style) { | 
|     if (col.border) { | 
|         if (/[.']-+[.']/.test(ts)) { | 
|             return ''; | 
|         } | 
|         if (ts.trim().length !== 0) { | 
|             return style; | 
|         } | 
|         return '  '; | 
|     } | 
|     return ''; | 
| } | 
| // calculates the minimum width of | 
| // a column, based on padding preferences. | 
| function _minWidth(col) { | 
|     const padding = col.padding || []; | 
|     const minWidth = 1 + (padding[left] || 0) + (padding[right] || 0); | 
|     if (col.border) { | 
|         return minWidth + 4; | 
|     } | 
|     return minWidth; | 
| } | 
| function getWindowWidth() { | 
|     /* istanbul ignore next: depends on terminal */ | 
|     if (typeof process === 'object' && process.stdout && process.stdout.columns) { | 
|         return process.stdout.columns; | 
|     } | 
|     return 80; | 
| } | 
| function alignRight(str, width) { | 
|     str = str.trim(); | 
|     const strWidth = mixin.stringWidth(str); | 
|     if (strWidth < width) { | 
|         return ' '.repeat(width - strWidth) + str; | 
|     } | 
|     return str; | 
| } | 
| function alignCenter(str, width) { | 
|     str = str.trim(); | 
|     const strWidth = mixin.stringWidth(str); | 
|     /* istanbul ignore next */ | 
|     if (strWidth >= width) { | 
|         return str; | 
|     } | 
|     return ' '.repeat((width - strWidth) >> 1) + str; | 
| } | 
| let mixin; | 
| function cliui(opts, _mixin) { | 
|     mixin = _mixin; | 
|     return new UI({ | 
|         width: (opts === null || opts === void 0 ? void 0 : opts.width) || getWindowWidth(), | 
|         wrap: opts === null || opts === void 0 ? void 0 : opts.wrap | 
|     }); | 
| } | 
|   | 
| // Bootstrap cliui with CommonJS dependencies: | 
| const stringWidth = require('string-width'); | 
| const stripAnsi = require('strip-ansi'); | 
| const wrap = require('wrap-ansi'); | 
| function ui(opts) { | 
|     return cliui(opts, { | 
|         stringWidth, | 
|         stripAnsi, | 
|         wrap | 
|     }); | 
| } | 
|   | 
| module.exports = ui; |