2 const isFullwidthCodePoint = require('is-fullwidth-code-point');
10 const ASTRAL_REGEX = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
12 const ESCAPE_CODES = new Map([
40 const wrapAnsi = code => `${ESCAPES[0]}[${code}m`;
42 module.exports = (str, begin, end) => {
43 const arr = Array.from(str.normalize());
45 end = typeof end === 'number' ? end : arr.length;
47 let insideEscape = false;
52 for (const item of arr.entries()) {
56 let leftEscape = false;
58 if (ESCAPES.indexOf(x) !== -1) {
60 const code = /\d[^m]*/.exec(str.slice(i, i + 4));
61 escapeCode = code === END_CODE ? null : code;
62 } else if (insideEscape && x === 'm') {
67 if (!insideEscape && !leftEscape) {
71 if (!ASTRAL_REGEX.test(x) && isFullwidthCodePoint(x.codePointAt())) {
75 if (visible > begin && visible <= end) {
77 } else if (visible === begin && !insideEscape && escapeCode !== undefined && escapeCode !== END_CODE) {
78 output += wrapAnsi(escapeCode);
79 } else if (visible >= end) {
80 if (escapeCode !== undefined) {
81 output += wrapAnsi(ESCAPE_CODES.get(parseInt(escapeCode, 10)) || END_CODE);