|  | 'use strict'; | 
|  | const stripAnsi = require('strip-ansi'); | 
|  | const isFullwidthCodePoint = require('is-fullwidth-code-point'); | 
|  |  | 
|  | module.exports = str => { | 
|  | if (typeof str !== 'string' || str.length === 0) { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | str = stripAnsi(str); | 
|  |  | 
|  | let width = 0; | 
|  |  | 
|  | for (let i = 0; i < str.length; i++) { | 
|  | const code = str.codePointAt(i); | 
|  |  | 
|  | // Ignore control characters | 
|  | if (code <= 0x1F || (code >= 0x7F && code <= 0x9F)) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | // Ignore combining characters | 
|  | if (code >= 0x300 && code <= 0x36F) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | // Surrogates | 
|  | if (code > 0xFFFF) { | 
|  | i++; | 
|  | } | 
|  |  | 
|  | width += isFullwidthCodePoint(code) ? 2 : 1; | 
|  | } | 
|  |  | 
|  | return width; | 
|  | }; |