Coder Social home page Coder Social logo

string-width's Introduction

string-width

Get the visual width of a string - the number of columns required to display it

Some Unicode characters are fullwidth and use double the normal width. ANSI escape codes are stripped and doesn't affect the width.

Useful to be able to measure the actual width of command-line output.

Install

npm install string-width

Usage

import stringWidth from 'string-width';

stringWidth('a');
//=> 1

stringWidth('古');
//=> 2

stringWidth('\u001B[1m古\u001B[22m');
//=> 2

API

stringWidth(string, options?)

string

Type: string

The string to be counted.

options

Type: object

ambiguousIsNarrow

Type: boolean
Default: true

Count ambiguous width characters as having narrow width (count of 1) instead of wide width (count of 2).

Ambiguous characters behave like wide or narrow characters depending on the context (language tag, script identification, associated font, source of data, or explicit markup; all can provide the context). If the context cannot be established reliably, they should be treated as narrow characters by default.

countAnsiEscapeCodes

Type: boolean
Default: false

Whether ANSI escape codes should be counted.

Related

string-width's People

Contributors

adam2k avatar bendingbender avatar coreyfarrell avatar ehmicky avatar fisker avatar gucong3000 avatar h4ad avatar litomore avatar richienb avatar seachicken avatar shinnn avatar sindresorhus avatar tonytonyjan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

string-width's Issues

Update strip-ansi in 4.2 to address CVE

Now that strip-ansi has version 6.0.1 that addresses the CVE in its dependency of ansi-regex (chalk/strip-ansi#40; thank you!), would it be possible to update the strip-ansi dependency in version 4.2 of string-width. This is required for upstream packages that can't update to version 5 due to it being pure ESM.

Can't require package (v5.0.1)

I'm trying to analyze a react app build files source-map-explorer 'build/static/js/*.js' , but I'm getting this error:

> [email protected] analyze
> source-map-explorer 'build/static/js/*.js'

\my-project\node_modules\wrap-ansi\node_modules\string-width\index.js:3
const isFullwidthCodePoint = require('is-fullwidth-code-point');
                             ^

Error [ERR_REQUIRE_ESM]: require() of ES Module \my-project\node_modules\is-fullwidth-code-point\index.js from \my-project\node_modules\wrap-ansi\node_modules\string-width\index.js not supported.
Instead change the require of \my-project\node_modules\is-fullwidth-code-point\index.js in \my-project\node_modules\wrap-ansi\node_modules\string-width\index.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (\my-project\node_modules\wrap-ansi\node_modules\string-width\index.js:3:30)
    at Object.<anonymous> (\my-project\node_modules\wrap-ansi\index.js:2:21)
    at Object.<anonymous> (\my-project\node_modules\source-map-explorer\node_modules\cliui\build\index.cjs:293:14)
    at Object.<anonymous> (\my-project\node_modules\source-map-explorer\node_modules\yargs\build\index.cjs:2861:12)
    at Object.<anonymous> (\my-project\node_modules\source-map-explorer\node_modules\yargs\index.cjs:5:30)
    at Object.<anonymous> (\my-project\node_modules\source-map-explorer\bin\cli.js:10:33) {
  code: 'ERR_REQUIRE_ESM'
}

might be related to this issue #33

Some full-width characters are not included

According to the Punctuation marks in Chinese in Requirements for Chinese Text Layout (https://www.w3.org/International/clreq/#positioning_of_headings_notes_illustrations_and_tables), I think there are some full-width characters that are not included.
They are:

—	2014	EM DASH	  
‘	2018	LEFT SINGLE QUOTATION MARK	// Full-width in Chinese Font  
’	2019	RIGHT SINGLE QUOTATION MARK	// Full-width in Chinese Font  
“	201C	LEFT DOUBLE QUOTATION MARK	// Full-width in Chinese Font  
”	201D	RIGHT DOUBLE QUOTATION MARK	// Full-width in Chinese Font  
…	2026	HORIZONTAL ELLIPSIS  
‼	203C	DOUBLE EXCLAMATION MARK  
⁇	2047	DOUBLE QUESTION MARK  
⋯	22EF	MIDLINE HORIZONTAL ELLIPSIS  
●	25CF	BLACK CIRCLE  
⸺	2E3A	TWO-EM DASH	// The character width is twice that of a Full-width character 

Can't require package in Node v14

I'm trying to require this package in my project, but I'm getting this error:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /project/node_modules/string-width/index.js
require() of ES modules is not supported.
require() of /project/node_modules/string-width/index.js from /project/lib/printer.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /project/node_modules/string-width/package.json

It seems like my only option is to convert my entire project into ES modules, which is not possible given my current situation. How can I use this package from a standard Node project?

Incomplete support for XTerm escape codes

Many Unix terminals follow "XTerm escape codes". I refer to the "rxvt_reference" manpage, available on Debian Jessie as man 7 urxvt when the rxvt-unicode package is installed:

   XTerm Operating System Commands
       "ESC ] Ps;Pt ST"
           Set XTerm Parameters. 8-bit ST: 0x9c, 7-bit ST sequence: ESC \
           (0x1b, 0x5c), backwards compatible terminator BEL (0x07) is also
           accepted. any octet can be escaped by prefixing it with SYN (0x16,
           ^V).

           Ps = 0     Change Icon Name and Window Title to Pt
           Ps = 1     Change Icon Name to Pt
           Ps = 2     Change Window Title to Pt
...

So, for example, the sequence \033]2;example\007 will change the terminal's title to "example" and not use any of the character cells in the terminal itself.

This could be represented as a (non-passing) test:

t.is(m('\033]2;example\007'), 0)

and similar for the ST sequences '\033\' and '\x9c' though to be honest I'm not sure whether the 8-bit '\x9c' even makes sense in UTF-8 world or can be expressed in javascript unicode strings.since it is only valid as a continuation byte in the UTF-8 encoding; it can probably be ignored.

Combining characters not supported

For instance, the unicode sequence "x\u0300" renders in a standard Unicode terminal using a single character cell, but string-width counts it as 2. (tested in xfce4-terminal and rxvt-unicode on Debian Jessie)

This could be represented as a (non-passing) test:

t.is(m('x\u0300'), 1);

Exploring upstreaming "fast-string-width"

Hey 👋 Following bun's announcement of a supposedly 100_000x faster built-in "stringWidth" function I tried to rewrite this function in JS with performance in mind, and I think I got some good results.

I would be interested in trying to upstream the optimizations, so that they can actually reach people, would this be something that you could be interested in also?

If so, I think there are currently the following differences between the implementations that would need to be handled one way or the other:

  1. Intl.Segmenter is borderline buggy in V8, in the sense that it's way slower than the JSC equivalent, and it gets massively slower and slower the longer the input string is, so I'm not using that and instead I'm stripping out all the combining marks with a regex, assuming that's what \p{M} actually matches, this stuff seems poorly documented. There may be other subtle differences here, I don't understand exactly what Intl.Segmenter does. Also Intl.Segmenter seems unavailable in Firefox at the moment, and by default I prefer if my code could run ~everywhere, so that's another reason for temporarily dropping Intl.Segmenter I guess.
  2. I'm using a slightly simplified regex for matching ANSI escapes. Potentially the regex from ansi-regex could be used instead, but in my tests it slowed things down a bit in some cases, even though in my benchmarks there was no additional ANSI escape to match that this more robust regex was accounting for, so maybe that could be tweaked somehow to be just as fast as the simplified regex, or potentially we could just switch to ansi-regex anyway, the difference in performance wasn't huge.
  3. I'm using a simpler regex for matching emojis, mostly out of convenience, but I haven't checked what the difference in performance would be like with the one from emoji-regex. The regex I'm using is potentially slightly problematic because it can consider emojis joined by a ZWJ as a single emoji even if they are not supposed to collapse into a single emoji like some family emojis are.
  4. I'm using a different options object, one that can be used to set the width of full-width, wide, emoji, and other classes of characters, mainly because how much space a string occupies depends on the context really, so if these numbers are not customizable there are scenarios where this function just can't give us the expected result.
  5. I'm inlining some of the lookup functions from get-east-asian-width, since those don't seem to be exported from a standalone package. I could have potentially called getEastAsianWidth directly, but mainly it just doesn't expose the options that I want.
  6. My implementation is measurably slower on CJK inputs for example, it would be nice to remove that regression somehow.
  7. I haven't implemented it yet, but since I've only seen this function being used for CLIs for the purpose of truncating and padding I think there's actually a better algorithm for that, so I'd like to also expose a function that somehow tells people where to truncate the string, ignoring the width of whatever follows the truncation point since we most probably don't actually care about that, in some cases.

Basically my reimplementation is not immediately mergable, but maybe it could be merged after some changes?

Either way pretty much the entire speedup comes from not using Intl.Segmenter and from trying to do as little as possible for common latin/ansi characters, by just matching them with some simple regexes, so maybe it's more practical to just port those two changes.

can not import in node environment

Thank you for your nice work.

When I use
import stringWidth from 'string-width';
I got an Error [ERR_REQUIRE_ESM]: Must use import to load ES Module.

Hope to support this way to import at the same time:
const stringWidth = require('string-width');

zwj codepoints, skin tones, families, and kisses

Consider these various glyphs:

  1. 👶
  2. 👶🏽
  3. 👩‍👩‍👦‍👦
  4. 👨‍❤️‍💋‍👨

The first is a generic "simpsons-colored" baby. This module correctly interprets it as a single column. (One might argue it really ought to be considered full-width, or 2 columns, since most terminals render emoji as extra wide, but one would be wrong to make that argument, because most terminals also "incorrectly" overlap the next character on top of the emoji, so it actually only "takes up" one column.)

The second is a baby with a specific skin tone. This module doesn't handle the zero-width-joiner (or "zwj", pronounced "zwidge") properly, so it reads as 2 columns.

The third is a "woman [zwj] woman [zwj] boy [zwj] boy". It's a full 25 bytes of familial goodness, and this module treats it as 7 columns.

The fourth is "man [zwj] heart [zwj] kiss [zwj] man", and comes in at 8 columns.

Is this problem even solvable? Conceivably, something like "fireman [zwj] cat" could be turned into "fire cat" by Apple or Google or Microsoft tomorrow, and a current 2 column set of code points could become 1.

If not, it seems like maybe it should be called out in the readme as just an impossible thing we can never hope to account for? Another way would be to optimistically treat anything with zero width joiners as single chars, but that might be too optimistic?

Default value for the `ambiguousIsNarrow` option

The default value for the ambiguousIsNarrow option introduced in 5.1.0 might surprise some users. It might also be a breaking change for a few of them. For example, some characters used fairly commonly in terminal outputs like ± now have a width of 2 instead of 1 by default (since ambiguousIsNarrow defaults to false). In my case, this broke the line wrapping logic of my CLI application.

The best value for this option seems to depend on whether the user is using an East Asian legacy character encoding. Are those legacy character encodings more common among East Asian languages users than non-legacy ones? If not, should the default value be switched to true?

Another solution would be to make the default value depend on the machine's locale? os-locale could be used for that purpose, providing it is memoized (since it spawns processes, which can be slow).

If the default value does remain false, since this might be unexpected for developers of other languages, it might make sense to document that users of this library should tweak this option based on whether they expect to use an East Asian legacy character encoding.

xo has given up support for Node v4

The following code will make CI environment inconsistent:

"devDependencies": {
"ava": "*",
"xo": "*"
}

For instance, xo has dropped support for Node v4 a few months ago (xojs/xo@d1eb47c), and it broke PR #17.

Some suggestions:

  • Give up node v4, and add package-locks or yarn.lock to make dependency tree consistent.
  • Define xo version in package.json explicitly, for example, use "0.20.0", instead of using "*".

Not support emoji

Is there any plan to support width of emoji ?

const stringWidth = require('string-width');

stringWidth('👨‍👩‍👦');
// expect: 1
// actual: 5

tabulation returns with zero

Tabs have a display width in many outputs, but they return zeros, which is not intuitive.
stringWidth('\t') // -> 0
Incidentally, a function slightly similar to this library is Excel's LENB function, which counts tabs as 1.

there's zwnj too

Related to #2, there is also zero-width non-joiners (ZWNJ).

I'm in the process of packaging string-width in Debian, and as a low-cost, acceptable solution to all these problems I propose to replace the dependency on is-fullwidth-code-point with wcwidth.js. This patch does the trick:
https://anonscm.debian.org/git/pkg-javascript/node-string-width.git/tree/debian/patches/01-wcwidth.diff

We've created a minimal test suite of strings with zwj and zwnj, you can find it here:
https://anonscm.debian.org/git/pkg-javascript/node-string-width.git/tree/debian/patches/02-test_zwj_zwnj.diff
[sorry we also switched from ava to mocha since ava is not available yet in Debian ...; run them with mocha -u tdd]

As pointed out in #2, the right number of columns required to display an emoji zwj sequence is debatable, so the tests are only there to guarantee we're at least reproducible.

Breaking change in v2.1

v2.0 of this package depends on strip-ansi v3, which supports node v0.10, which works fine with string-width's support of >= 4.

however, v2.1 of this package depends on strip-ansi v4, which requires >= 8, which means it's a breaking change in a minor version of this package. This breaks https://npmjs.com/salita, and every other package that depends on yargs 10.

Please release a v2 version of string-width that restores node 4 compatibility. The easiest is probably to revert strip-ansi to v3. (The most reliable would be a change in policy in ensuring that every dep supports as far back as is possible, but i realize that's not likely to happen)

v5 breaks `yarn install` when it is used indirectly by `lerna`

I already posted a bug in wide-align, but maybe you can add a backwards compatibility too:

Your library is used by wide-align, which is used by gauge, which is used by npmlog <- @npmcli/arborist <- lerna.
And a simple yarn upgrade on my project now fails to do yarn install with:

[5/5] 🔨  Building fresh packages...
.../node_modules/wide-align/align.js:2
var stringWidth = require('string-width')
                  ^

Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/string-width/index.js from .../node_modules/wide-align/align.js not supported.
Instead change the require of index.js in .../node_modules/wide-align/align.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (.../node_modules/wide-align/align.js:2:19)
    at Object.<anonymous> (.../node_modules/gauge/lib/render-template.js:2:13)
    at Object.<anonymous> (.../node_modules/gauge/lib/plumbing.js:3:22)
    at Object.<anonymous> (.../node_modules/gauge/lib/index.js:2:16)
    at Object.<anonymous> (.../node_modules/npmlog/lib/log.js:3:13)
    at libs/core/src/lib/collect-uncommitted.ts (.../node_modules/lerna/dist/cli.js:48:29)
    at __init (.../node_modules/lerna/dist/cli.js:11:56)
    at libs/core/src/lib/check-working-tree.ts (.../node_modules/lerna/dist/cli.js:163:5)
    at __init (.../node_modules/lerna/dist/cli.js:11:56)
    at libs/core/src/index.ts (.../node_modules/lerna/dist/cli.js:4516:5)
    at __init (.../node_modules/lerna/dist/cli.js:11:56)
    at packages/lerna/src/index.ts (.../node_modules/lerna/dist/cli.js:9511:5)
    at __require (.../node_modules/lerna/dist/cli.js:14:50)
    at Object.<anonymous> (.../node_modules/lerna/dist/cli.js:9545:3) {
  code: 'ERR_REQUIRE_ESM'

Handling text variation selector

Hello,

I realized that some unicode characters output a width of 2 instead of 1 when they have the text variation modifier applied (\ufe0e), e.g.:

> '\u21a9\ufe0e'
'↩︎' // text
> '\u21a9\ufe0f'
'↩️' // I cannot paste the emoji for some reason
> stringWidth('\u21a9\ufe0f')
2 // Ok
> stringWidth('\u21a9\ufe0e')
2 // should be 1

I took a look at the list of unicode characters that accept a variation here and it doesn't seem there is a simple rule to follow, some are full-width some are normal so I'm not sure if this can be handled correctly across platforms.

This is a display test I used to visually check some of the characters:

console.log(`\u0023\uFE0E  ; text style;  # (1.1) NUMBER SIGN`)
console.log(`\u0023\uFE0F  ; emoji style; # (1.1) NUMBER SIGN`)
console.log(`\u002A\uFE0E  ; text style;  # (1.1) ASTERISK`)
console.log(`\u002A\uFE0F  ; emoji style; # (1.1) ASTERISK`)
console.log(`\u0030\uFE0E  ; text style;  # (1.1) DIGIT ZERO`)
console.log(`\u0030\uFE0F  ; emoji style; # (1.1) DIGIT ZERO`)
console.log(`\u0031\uFE0E  ; text style;  # (1.1) DIGIT ONE`)
console.log(`\u0031\uFE0F  ; emoji style; # (1.1) DIGIT ONE`)
console.log(`\u0032\uFE0E  ; text style;  # (1.1) DIGIT TWO`)
console.log(`\u0032\uFE0F  ; emoji style; # (1.1) DIGIT TWO`)
console.log(`\u0033\uFE0E  ; text style;  # (1.1) DIGIT THREE`)
console.log(`\u0033\uFE0F  ; emoji style; # (1.1) DIGIT THREE`)
console.log(`\u0034\uFE0E  ; text style;  # (1.1) DIGIT FOUR`)
console.log(`\u0034\uFE0F  ; emoji style; # (1.1) DIGIT FOUR`)
console.log(`\u0035\uFE0E  ; text style;  # (1.1) DIGIT FIVE`)
console.log(`\u0035\uFE0F  ; emoji style; # (1.1) DIGIT FIVE`)
console.log(`\u0036\uFE0E  ; text style;  # (1.1) DIGIT SIX`)
console.log(`\u0036\uFE0F  ; emoji style; # (1.1) DIGIT SIX`)
console.log(`\u0037\uFE0E  ; text style;  # (1.1) DIGIT SEVEN`)
console.log(`\u0037\uFE0F  ; emoji style; # (1.1) DIGIT SEVEN`)
console.log(`\u0038\uFE0E  ; text style;  # (1.1) DIGIT EIGHT`)
console.log(`\u0038\uFE0F  ; emoji style; # (1.1) DIGIT EIGHT`)
console.log(`\u0039\uFE0E  ; text style;  # (1.1) DIGIT NINE`)
console.log(`\u0039\uFE0F  ; emoji style; # (1.1) DIGIT NINE`)
console.log(`\u00A9\uFE0E  ; text style;  # (1.1) COPYRIGHT SIGN`)
console.log(`\u00A9\uFE0F  ; emoji style; # (1.1) COPYRIGHT SIGN`)
console.log(`\u00AE\uFE0E  ; text style;  # (1.1) REGISTERED SIGN`)
console.log(`\u00AE\uFE0F  ; emoji style; # (1.1) REGISTERED SIGN`)
console.log(`\u203C\uFE0E  ; text style;  # (1.1) DOUBLE EXCLAMATION MARK`)
console.log(`\u203C\uFE0F  ; emoji style; # (1.1) DOUBLE EXCLAMATION MARK`)
console.log(`\u2049\uFE0E  ; text style;  # (3.0) EXCLAMATION QUESTION MARK`)
console.log(`\u2049\uFE0F  ; emoji style; # (3.0) EXCLAMATION QUESTION MARK`)
console.log(`\u2122\uFE0E  ; text style;  # (1.1) TRADE MARK SIGN`)
console.log(`\u2122\uFE0F  ; emoji style; # (1.1) TRADE MARK SIGN`)
console.log(`\u2139\uFE0E  ; text style;  # (3.0) INFORMATION SOURCE`)
console.log(`\u2139\uFE0F  ; emoji style; # (3.0) INFORMATION SOURCE`)
console.log(`\u2194\uFE0E  ; text style;  # (1.1) LEFT RIGHT ARROW`)
console.log(`\u2194\uFE0F  ; emoji style; # (1.1) LEFT RIGHT ARROW`)
console.log(`\u2195\uFE0E  ; text style;  # (1.1) UP DOWN ARROW`)
console.log(`\u2195\uFE0F  ; emoji style; # (1.1) UP DOWN ARROW`)
console.log(`\u2196\uFE0E  ; text style;  # (1.1) NORTH WEST ARROW`)
console.log(`\u2196\uFE0F  ; emoji style; # (1.1) NORTH WEST ARROW`)
console.log(`\u2197\uFE0E  ; text style;  # (1.1) NORTH EAST ARROW`)
console.log(`\u2197\uFE0F  ; emoji style; # (1.1) NORTH EAST ARROW`)
console.log(`\u2198\uFE0E  ; text style;  # (1.1) SOUTH EAST ARROW`)
console.log(`\u2198\uFE0F  ; emoji style; # (1.1) SOUTH EAST ARROW`)
console.log(`\u2199\uFE0E  ; text style;  # (1.1) SOUTH WEST ARROW`)
console.log(`\u2199\uFE0F  ; emoji style; # (1.1) SOUTH WEST ARROW`)
console.log(`\u21A9\uFE0E  ; text style;  # (1.1) LEFTWARDS ARROW WITH HOOK`)
console.log(`\u21A9\uFE0F  ; emoji style; # (1.1) LEFTWARDS ARROW WITH HOOK`)
console.log(`\u21AA\uFE0E  ; text style;  # (1.1) RIGHTWARDS ARROW WITH HOOK`)
console.log(`\u21AA\uFE0F  ; emoji style; # (1.1) RIGHTWARDS ARROW WITH HOOK`)
console.log(`\u231A\uFE0E  ; text style;  # (1.1) WATCH`)
console.log(`\u231A\uFE0F  ; emoji style; # (1.1) WATCH`)
console.log(`\u231B\uFE0E  ; text style;  # (1.1) HOURGLASS`)
console.log(`\u231B\uFE0F  ; emoji style; # (1.1) HOURGLASS`)
console.log(`\u2328\uFE0E  ; text style;  # (1.1) KEYBOARD`)
console.log(`\u2328\uFE0F  ; emoji style; # (1.1) KEYBOARD`)
console.log(`\u23CF\uFE0E  ; text style;  # (4.0) EJECT SYMBOL`)
console.log(`\u23CF\uFE0F  ; emoji style; # (4.0) EJECT SYMBOL`)
console.log(
  `\u23E9\uFE0E  ; text style;  # (6.0) BLACK RIGHT-POINTING DOUBLE TRIANGLE`
)
console.log(
  `\u23E9\uFE0F  ; emoji style; # (6.0) BLACK RIGHT-POINTING DOUBLE TRIANGLE`
)
console.log(
  `\u23EA\uFE0E  ; text style;  # (6.0) BLACK LEFT-POINTING DOUBLE TRIANGLE`
)
console.log(
  `\u23EA\uFE0F  ; emoji style; # (6.0) BLACK LEFT-POINTING DOUBLE TRIANGLE`
)
console.log(
  `\u23ED\uFE0E  ; text style;  # (6.0) BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH `
)
console.log(
  `\u23ED\uFE0F  ; emoji style; # (6.0) BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH `
)
console.log(
  `\u23EE\uFE0E  ; text style;  # (6.0) BLACK LEFT-POINTING DOUBLE TRIANGLE WITH `
)
console.log(
  `\u23EE\uFE0F  ; emoji style; # (6.0) BLACK LEFT-POINTING DOUBLE TRIANGLE WITH `
)
console.log(
  `\u23EF\uFE0E  ; text style;  # (6.0) BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE `
)
console.log(
  `\u23EF\uFE0F  ; emoji style; # (6.0) BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE `
)
console.log(`\u23F1\uFE0E  ; text style;  # (6.0) STOPWATCH`)
console.log(`\u23F1\uFE0F  ; emoji style; # (6.0) STOPWATCH`)
console.log(`\u23F2\uFE0E  ; text style;  # (6.0) TIMER CLOCK`)
console.log(`\u23F2\uFE0F  ; emoji style; # (6.0) TIMER CLOCK`)
console.log(`\u23F3\uFE0E  ; text style;  # (6.0) HOURGLASS WITH FLOWING SAND`)
console.log(`\u23F3\uFE0F  ; emoji style; # (6.0) HOURGLASS WITH FLOWING SAND`)
console.log(`\u23F8\uFE0E  ; text style;  # (7.0) DOUBLE VERTICAL BAR`)
console.log(`\u23F8\uFE0F  ; emoji style; # (7.0) DOUBLE VERTICAL BAR`)
console.log(`\u23F9\uFE0E  ; text style;  # (7.0) BLACK SQUARE FOR STOP`)
console.log(`\u23F9\uFE0F  ; emoji style; # (7.0) BLACK SQUARE FOR STOP`)
console.log(`\u23FA\uFE0E  ; text style;  # (7.0) BLACK CIRCLE FOR RECORD`)
console.log(`\u23FA\uFE0F  ; emoji style; # (7.0) BLACK CIRCLE FOR RECORD`)
console.log(
  `\u24C2\uFE0E  ; text style;  # (1.1) CIRCLED LATIN CAPITAL LETTER M`
)
console.log(
  `\u24C2\uFE0F  ; emoji style; # (1.1) CIRCLED LATIN CAPITAL LETTER M`
)
console.log(`\u25AA\uFE0E  ; text style;  # (1.1) BLACK SMALL SQUARE`)
console.log(`\u25AA\uFE0F  ; emoji style; # (1.1) BLACK SMALL SQUARE`)
console.log(`\u25AB\uFE0E  ; text style;  # (1.1) WHITE SMALL SQUARE`)
console.log(`\u25AB\uFE0F  ; emoji style; # (1.1) WHITE SMALL SQUARE`)
console.log(
  `\u25B6\uFE0E  ; text style;  # (1.1) BLACK RIGHT-POINTING TRIANGLE`
)
console.log(
  `\u25B6\uFE0F  ; emoji style; # (1.1) BLACK RIGHT-POINTING TRIANGLE`
)
console.log(`\u25C0\uFE0E  ; text style;  # (1.1) BLACK LEFT-POINTING TRIANGLE`)
console.log(`\u25C0\uFE0F  ; emoji style; # (1.1) BLACK LEFT-POINTING TRIANGLE`)
console.log(`\u25FB\uFE0E  ; text style;  # (3.2) WHITE MEDIUM SQUARE`)
console.log(`\u25FB\uFE0F  ; emoji style; # (3.2) WHITE MEDIUM SQUARE`)
console.log(`\u25FC\uFE0E  ; text style;  # (3.2) BLACK MEDIUM SQUARE`)
console.log(`\u25FC\uFE0F  ; emoji style; # (3.2) BLACK MEDIUM SQUARE`)
console.log(`\u25FD\uFE0E  ; text style;  # (3.2) WHITE MEDIUM SMALL SQUARE`)
console.log(`\u25FD\uFE0F  ; emoji style; # (3.2) WHITE MEDIUM SMALL SQUARE`)
console.log(`\u25FE\uFE0E  ; text style;  # (3.2) BLACK MEDIUM SMALL SQUARE`)
console.log(`\u25FE\uFE0F  ; emoji style; # (3.2) BLACK MEDIUM SMALL SQUARE`)
console.log(`\u2600\uFE0E  ; text style;  # (1.1) BLACK SUN WITH RAYS`)
console.log(`\u2600\uFE0F  ; emoji style; # (1.1) BLACK SUN WITH RAYS`)
console.log(`\u2601\uFE0E  ; text style;  # (1.1) CLOUD`)
console.log(`\u2601\uFE0F  ; emoji style; # (1.1) CLOUD`)
console.log(`\u2602\uFE0E  ; text style;  # (1.1) UMBRELLA`)
console.log(`\u2602\uFE0F  ; emoji style; # (1.1) UMBRELLA`)
console.log(`\u2603\uFE0E  ; text style;  # (1.1) SNOWMAN`)
console.log(`\u2603\uFE0F  ; emoji style; # (1.1) SNOWMAN`)
console.log(`\u2604\uFE0E  ; text style;  # (1.1) COMET`)
console.log(`\u2604\uFE0F  ; emoji style; # (1.1) COMET`)
console.log(`\u260E\uFE0E  ; text style;  # (1.1) BLACK TELEPHONE`)
console.log(`\u260E\uFE0F  ; emoji style; # (1.1) BLACK TELEPHONE`)
console.log(`\u2611\uFE0E  ; text style;  # (1.1) BALLOT BOX WITH CHECK`)
console.log(`\u2611\uFE0F  ; emoji style; # (1.1) BALLOT BOX WITH CHECK`)
console.log(`\u2614\uFE0E  ; text style;  # (4.0) UMBRELLA WITH RAIN DROPS`)
console.log(`\u2614\uFE0F  ; emoji style; # (4.0) UMBRELLA WITH RAIN DROPS`)
console.log(`\u2615\uFE0E  ; text style;  # (4.0) HOT BEVERAGE`)
console.log(`\u2615\uFE0F  ; emoji style; # (4.0) HOT BEVERAGE`)
console.log(`\u2618\uFE0E  ; text style;  # (4.1) SHAMROCK`)
console.log(`\u2618\uFE0F  ; emoji style; # (4.1) SHAMROCK`)
console.log(`\u261D\uFE0E  ; text style;  # (1.1) WHITE UP POINTING INDEX`)
console.log(`\u261D\uFE0F  ; emoji style; # (1.1) WHITE UP POINTING INDEX`)
console.log(`\u2620\uFE0E  ; text style;  # (1.1) SKULL AND CROSSBONES`)
console.log(`\u2620\uFE0F  ; emoji style; # (1.1) SKULL AND CROSSBONES`)
console.log(`\u2622\uFE0E  ; text style;  # (1.1) RADIOACTIVE SIGN`)
console.log(`\u2622\uFE0F  ; emoji style; # (1.1) RADIOACTIVE SIGN`)
console.log(`\u2623\uFE0E  ; text style;  # (1.1) BIOHAZARD SIGN`)
console.log(`\u2623\uFE0F  ; emoji style; # (1.1) BIOHAZARD SIGN`)
console.log(`\u2626\uFE0E  ; text style;  # (1.1) ORTHODOX CROSS`)
console.log(`\u2626\uFE0F  ; emoji style; # (1.1) ORTHODOX CROSS`)
console.log(`\u262A\uFE0E  ; text style;  # (1.1) STAR AND CRESCENT`)
console.log(`\u262A\uFE0F  ; emoji style; # (1.1) STAR AND CRESCENT`)
console.log(`\u262E\uFE0E  ; text style;  # (1.1) PEACE SYMBOL`)
console.log(`\u262E\uFE0F  ; emoji style; # (1.1) PEACE SYMBOL`)
console.log(`\u262F\uFE0E  ; text style;  # (1.1) YIN YANG`)
console.log(`\u262F\uFE0F  ; emoji style; # (1.1) YIN YANG`)
console.log(`\u2638\uFE0E  ; text style;  # (1.1) WHEEL OF DHARMA`)
console.log(`\u2638\uFE0F  ; emoji style; # (1.1) WHEEL OF DHARMA`)
console.log(`\u2639\uFE0E  ; text style;  # (1.1) WHITE FROWNING FACE`)
console.log(`\u2639\uFE0F  ; emoji style; # (1.1) WHITE FROWNING FACE`)
console.log(`\u263A\uFE0E  ; text style;  # (1.1) WHITE SMILING FACE`)
console.log(`\u263A\uFE0F  ; emoji style; # (1.1) WHITE SMILING FACE`)
console.log(`\u2640\uFE0E  ; text style;  # (1.1) FEMALE SIGN`)
console.log(`\u2640\uFE0F  ; emoji style; # (1.1) FEMALE SIGN`)
console.log(`\u2642\uFE0E  ; text style;  # (1.1) MALE SIGN`)
console.log(`\u2642\uFE0F  ; emoji style; # (1.1) MALE SIGN`)
console.log(`\u2648\uFE0E  ; text style;  # (1.1) ARIES`)
console.log(`\u2648\uFE0F  ; emoji style; # (1.1) ARIES`)
console.log(`\u2649\uFE0E  ; text style;  # (1.1) TAURUS`)
console.log(`\u2649\uFE0F  ; emoji style; # (1.1) TAURUS`)
console.log(`\u264A\uFE0E  ; text style;  # (1.1) GEMINI`)
console.log(`\u264A\uFE0F  ; emoji style; # (1.1) GEMINI`)
console.log(`\u264B\uFE0E  ; text style;  # (1.1) CANCER`)
console.log(`\u264B\uFE0F  ; emoji style; # (1.1) CANCER`)
console.log(`\u264C\uFE0E  ; text style;  # (1.1) LEO`)
console.log(`\u264C\uFE0F  ; emoji style; # (1.1) LEO`)
console.log(`\u264D\uFE0E  ; text style;  # (1.1) VIRGO`)
console.log(`\u264D\uFE0F  ; emoji style; # (1.1) VIRGO`)
console.log(`\u264E\uFE0E  ; text style;  # (1.1) LIBRA`)
console.log(`\u264E\uFE0F  ; emoji style; # (1.1) LIBRA`)
console.log(`\u264F\uFE0E  ; text style;  # (1.1) SCORPIUS`)
console.log(`\u264F\uFE0F  ; emoji style; # (1.1) SCORPIUS`)
console.log(`\u2650\uFE0E  ; text style;  # (1.1) SAGITTARIUS`)
console.log(`\u2650\uFE0F  ; emoji style; # (1.1) SAGITTARIUS`)
console.log(`\u2651\uFE0E  ; text style;  # (1.1) CAPRICORN`)
console.log(`\u2651\uFE0F  ; emoji style; # (1.1) CAPRICORN`)
console.log(`\u2652\uFE0E  ; text style;  # (1.1) AQUARIUS`)
console.log(`\u2652\uFE0F  ; emoji style; # (1.1) AQUARIUS`)
console.log(`\u2653\uFE0E  ; text style;  # (1.1) PISCES`)
console.log(`\u2653\uFE0F  ; emoji style; # (1.1) PISCES`)
console.log(`\u265F\uFE0E  ; text style;  # (1.1) BLACK CHESS PAWN`)
console.log(`\u265F\uFE0F  ; emoji style; # (1.1) BLACK CHESS PAWN`)
console.log(`\u2660\uFE0E  ; text style;  # (1.1) BLACK SPADE SUIT`)
console.log(`\u2660\uFE0F  ; emoji style; # (1.1) BLACK SPADE SUIT`)
console.log(`\u2663\uFE0E  ; text style;  # (1.1) BLACK CLUB SUIT`)
console.log(`\u2663\uFE0F  ; emoji style; # (1.1) BLACK CLUB SUIT`)
console.log(`\u2665\uFE0E  ; text style;  # (1.1) BLACK HEART SUIT`)
console.log(`\u2665\uFE0F  ; emoji style; # (1.1) BLACK HEART SUIT`)
console.log(`\u2666\uFE0E  ; text style;  # (1.1) BLACK DIAMOND SUIT`)
console.log(`\u2666\uFE0F  ; emoji style; # (1.1) BLACK DIAMOND SUIT`)
console.log(`\u2668\uFE0E  ; text style;  # (1.1) HOT SPRINGS`)
console.log(`\u2668\uFE0F  ; emoji style; # (1.1) HOT SPRINGS`)
console.log(
  `\u267B\uFE0E  ; text style;  # (3.2) BLACK UNIVERSAL RECYCLING SYMBOL`
)
console.log(
  `\u267B\uFE0F  ; emoji style; # (3.2) BLACK UNIVERSAL RECYCLING SYMBOL`
)
console.log(`\u267E\uFE0E  ; text style;  # (4.1) PERMANENT PAPER SIGN`)
console.log(`\u267E\uFE0F  ; emoji style; # (4.1) PERMANENT PAPER SIGN`)
console.log(`\u267F\uFE0E  ; text style;  # (4.1) WHEELCHAIR SYMBOL`)
console.log(`\u267F\uFE0F  ; emoji style; # (4.1) WHEELCHAIR SYMBOL`)
console.log(`\u2692\uFE0E  ; text style;  # (4.1) HAMMER AND PICK`)
console.log(`\u2692\uFE0F  ; emoji style; # (4.1) HAMMER AND PICK`)
console.log(`\u2693\uFE0E  ; text style;  # (4.1) ANCHOR`)
console.log(`\u2693\uFE0F  ; emoji style; # (4.1) ANCHOR`)
console.log(`\u2694\uFE0E  ; text style;  # (4.1) CROSSED SWORDS`)
console.log(`\u2694\uFE0F  ; emoji style; # (4.1) CROSSED SWORDS`)
console.log(`\u2695\uFE0E  ; text style;  # (4.1) STAFF OF AESCULAPIUS`)
console.log(`\u2695\uFE0F  ; emoji style; # (4.1) STAFF OF AESCULAPIUS`)
console.log(`\u2696\uFE0E  ; text style;  # (4.1) SCALES`)
console.log(`\u2696\uFE0F  ; emoji style; # (4.1) SCALES`)
console.log(`\u2697\uFE0E  ; text style;  # (4.1) ALEMBIC`)
console.log(`\u2697\uFE0F  ; emoji style; # (4.1) ALEMBIC`)
console.log(`\u2699\uFE0E  ; text style;  # (4.1) GEAR`)
console.log(`\u2699\uFE0F  ; emoji style; # (4.1) GEAR`)
console.log(`\u269B\uFE0E  ; text style;  # (4.1) ATOM SYMBOL`)
console.log(`\u269B\uFE0F  ; emoji style; # (4.1) ATOM SYMBOL`)
console.log(`\u269C\uFE0E  ; text style;  # (4.1) FLEUR-DE-LIS`)
console.log(`\u269C\uFE0F  ; emoji style; # (4.1) FLEUR-DE-LIS`)
console.log(`\u26A0\uFE0E  ; text style;  # (4.0) WARNING SIGN`)
console.log(`\u26A0\uFE0F  ; emoji style; # (4.0) WARNING SIGN`)
console.log(`\u26A1\uFE0E  ; text style;  # (4.0) HIGH VOLTAGE SIGN`)
console.log(`\u26A1\uFE0F  ; emoji style; # (4.0) HIGH VOLTAGE SIGN`)
console.log(`\u26AA\uFE0E  ; text style;  # (4.1) MEDIUM WHITE CIRCLE`)
console.log(`\u26AA\uFE0F  ; emoji style; # (4.1) MEDIUM WHITE CIRCLE`)
console.log(`\u26AB\uFE0E  ; text style;  # (4.1) MEDIUM BLACK CIRCLE`)
console.log(`\u26AB\uFE0F  ; emoji style; # (4.1) MEDIUM BLACK CIRCLE`)
console.log(`\u26B0\uFE0E  ; text style;  # (4.1) COFFIN`)
console.log(`\u26B0\uFE0F  ; emoji style; # (4.1) COFFIN`)
console.log(`\u26B1\uFE0E  ; text style;  # (4.1) FUNERAL URN`)
console.log(`\u26B1\uFE0F  ; emoji style; # (4.1) FUNERAL URN`)
console.log(`\u26BD\uFE0E  ; text style;  # (5.2) SOCCER BALL`)
console.log(`\u26BD\uFE0F  ; emoji style; # (5.2) SOCCER BALL`)
console.log(`\u26BE\uFE0E  ; text style;  # (5.2) BASEBALL`)
console.log(`\u26BE\uFE0F  ; emoji style; # (5.2) BASEBALL`)
console.log(`\u26C4\uFE0E  ; text style;  # (5.2) SNOWMAN WITHOUT SNOW`)
console.log(`\u26C4\uFE0F  ; emoji style; # (5.2) SNOWMAN WITHOUT SNOW`)
console.log(`\u26C5\uFE0E  ; text style;  # (5.2) SUN BEHIND CLOUD`)
console.log(`\u26C5\uFE0F  ; emoji style; # (5.2) SUN BEHIND CLOUD`)
console.log(`\u26C8\uFE0E  ; text style;  # (5.2) THUNDER CLOUD AND RAIN`)
console.log(`\u26C8\uFE0F  ; emoji style; # (5.2) THUNDER CLOUD AND RAIN`)
console.log(`\u26CF\uFE0E  ; text style;  # (5.2) PICK`)
console.log(`\u26CF\uFE0F  ; emoji style; # (5.2) PICK`)
console.log(`\u26D1\uFE0E  ; text style;  # (5.2) HELMET WITH WHITE CROSS`)
console.log(`\u26D1\uFE0F  ; emoji style; # (5.2) HELMET WITH WHITE CROSS`)
console.log(`\u26D3\uFE0E  ; text style;  # (5.2) CHAINS`)
console.log(`\u26D3\uFE0F  ; emoji style; # (5.2) CHAINS`)
console.log(`\u26D4\uFE0E  ; text style;  # (5.2) NO ENTRY`)
console.log(`\u26D4\uFE0F  ; emoji style; # (5.2) NO ENTRY`)
console.log(`\u26E9\uFE0E  ; text style;  # (5.2) SHINTO SHRINE`)
console.log(`\u26E9\uFE0F  ; emoji style; # (5.2) SHINTO SHRINE`)
console.log(`\u26EA\uFE0E  ; text style;  # (5.2) CHURCH`)
console.log(`\u26EA\uFE0F  ; emoji style; # (5.2) CHURCH`)
console.log(`\u26F0\uFE0E  ; text style;  # (5.2) MOUNTAIN`)
console.log(`\u26F0\uFE0F  ; emoji style; # (5.2) MOUNTAIN`)
console.log(`\u26F1\uFE0E  ; text style;  # (5.2) UMBRELLA ON GROUND`)
console.log(`\u26F1\uFE0F  ; emoji style; # (5.2) UMBRELLA ON GROUND`)
console.log(`\u26F2\uFE0E  ; text style;  # (5.2) FOUNTAIN`)
console.log(`\u26F2\uFE0F  ; emoji style; # (5.2) FOUNTAIN`)
console.log(`\u26F3\uFE0E  ; text style;  # (5.2) FLAG IN HOLE`)
console.log(`\u26F3\uFE0F  ; emoji style; # (5.2) FLAG IN HOLE`)
console.log(`\u26F4\uFE0E  ; text style;  # (5.2) FERRY`)
console.log(`\u26F4\uFE0F  ; emoji style; # (5.2) FERRY`)
console.log(`\u26F5\uFE0E  ; text style;  # (5.2) SAILBOAT`)
console.log(`\u26F5\uFE0F  ; emoji style; # (5.2) SAILBOAT`)
console.log(`\u26F7\uFE0E  ; text style;  # (5.2) SKIER`)
console.log(`\u26F7\uFE0F  ; emoji style; # (5.2) SKIER`)
console.log(`\u26F8\uFE0E  ; text style;  # (5.2) ICE SKATE`)
console.log(`\u26F8\uFE0F  ; emoji style; # (5.2) ICE SKATE`)
console.log(`\u26F9\uFE0E  ; text style;  # (5.2) PERSON WITH BALL`)
console.log(`\u26F9\uFE0F  ; emoji style; # (5.2) PERSON WITH BALL`)
console.log(`\u26FA\uFE0E  ; text style;  # (5.2) TENT`)
console.log(`\u26FA\uFE0F  ; emoji style; # (5.2) TENT`)
console.log(`\u26FD\uFE0E  ; text style;  # (5.2) FUEL PUMP`)
console.log(`\u26FD\uFE0F  ; emoji style; # (5.2) FUEL PUMP`)
console.log(`\u2702\uFE0E  ; text style;  # (1.1) BLACK SCISSORS`)
console.log(`\u2702\uFE0F  ; emoji style; # (1.1) BLACK SCISSORS`)
console.log(`\u2708\uFE0E  ; text style;  # (1.1) AIRPLANE`)
console.log(`\u2708\uFE0F  ; emoji style; # (1.1) AIRPLANE`)
console.log(`\u2709\uFE0E  ; text style;  # (1.1) ENVELOPE`)
console.log(`\u2709\uFE0F  ; emoji style; # (1.1) ENVELOPE`)
console.log(`\u270C\uFE0E  ; text style;  # (1.1) VICTORY HAND`)
console.log(`\u270C\uFE0F  ; emoji style; # (1.1) VICTORY HAND`)
console.log(`\u270D\uFE0E  ; text style;  # (1.1) WRITING HAND`)
console.log(`\u270D\uFE0F  ; emoji style; # (1.1) WRITING HAND`)
console.log(`\u270F\uFE0E  ; text style;  # (1.1) PENCIL`)
console.log(`\u270F\uFE0F  ; emoji style; # (1.1) PENCIL`)
console.log(`\u2712\uFE0E  ; text style;  # (1.1) BLACK NIB`)
console.log(`\u2712\uFE0F  ; emoji style; # (1.1) BLACK NIB`)
console.log(`\u2714\uFE0E  ; text style;  # (1.1) HEAVY CHECK MARK`)
console.log(`\u2714\uFE0F  ; emoji style; # (1.1) HEAVY CHECK MARK`)
console.log(`\u2716\uFE0E  ; text style;  # (1.1) HEAVY MULTIPLICATION X`)
console.log(`\u2716\uFE0F  ; emoji style; # (1.1) HEAVY MULTIPLICATION X`)
console.log(`\u271D\uFE0E  ; text style;  # (1.1) LATIN CROSS`)
console.log(`\u271D\uFE0F  ; emoji style; # (1.1) LATIN CROSS`)
console.log(`\u2721\uFE0E  ; text style;  # (1.1) STAR OF DAVID`)
console.log(`\u2721\uFE0F  ; emoji style; # (1.1) STAR OF DAVID`)
console.log(`\u2733\uFE0E  ; text style;  # (1.1) EIGHT SPOKED ASTERISK`)
console.log(`\u2733\uFE0F  ; emoji style; # (1.1) EIGHT SPOKED ASTERISK`)
console.log(`\u2734\uFE0E  ; text style;  # (1.1) EIGHT POINTED BLACK STAR`)
console.log(`\u2734\uFE0F  ; emoji style; # (1.1) EIGHT POINTED BLACK STAR`)
console.log(`\u2744\uFE0E  ; text style;  # (1.1) SNOWFLAKE`)
console.log(`\u2744\uFE0F  ; emoji style; # (1.1) SNOWFLAKE`)
console.log(`\u2747\uFE0E  ; text style;  # (1.1) SPARKLE`)
console.log(`\u2747\uFE0F  ; emoji style; # (1.1) SPARKLE`)
console.log(`\u2753\uFE0E  ; text style;  # (6.0) BLACK QUESTION MARK ORNAMENT`)
console.log(`\u2753\uFE0F  ; emoji style; # (6.0) BLACK QUESTION MARK ORNAMENT`)
console.log(
  `\u2757\uFE0E  ; text style;  # (5.2) HEAVY EXCLAMATION MARK SYMBOL`
)
console.log(
  `\u2757\uFE0F  ; emoji style; # (5.2) HEAVY EXCLAMATION MARK SYMBOL`
)
console.log(
  `\u2763\uFE0E  ; text style;  # (1.1) HEAVY HEART EXCLAMATION MARK ORNAMENT`
)
console.log(
  `\u2763\uFE0F  ; emoji style; # (1.1) HEAVY HEART EXCLAMATION MARK ORNAMENT`
)
console.log(`\u2764\uFE0E  ; text style;  # (1.1) HEAVY BLACK HEART`)
console.log(`\u2764\uFE0F  ; emoji style; # (1.1) HEAVY BLACK HEART`)
console.log(`\u27A1\uFE0E  ; text style;  # (1.1) BLACK RIGHTWARDS ARROW`)
console.log(`\u27A1\uFE0F  ; emoji style; # (1.1) BLACK RIGHTWARDS ARROW`)
console.log(
  `\u2934\uFE0E  ; text style;  # (3.2) ARROW POINTING RIGHTWARDS THEN CURVING `
)
console.log(
  `\u2934\uFE0F  ; emoji style; # (3.2) ARROW POINTING RIGHTWARDS THEN CURVING `
)
console.log(
  `\u2935\uFE0E  ; text style;  # (3.2) ARROW POINTING RIGHTWARDS THEN CURVING `
)
console.log(
  `\u2935\uFE0F  ; emoji style; # (3.2) ARROW POINTING RIGHTWARDS THEN CURVING `
)
console.log(`\u2B05\uFE0E  ; text style;  # (4.0) LEFTWARDS BLACK ARROW`)
console.log(`\u2B05\uFE0F  ; emoji style; # (4.0) LEFTWARDS BLACK ARROW`)
console.log(`\u2B06\uFE0E  ; text style;  # (4.0) UPWARDS BLACK ARROW`)
console.log(`\u2B06\uFE0F  ; emoji style; # (4.0) UPWARDS BLACK ARROW`)
console.log(`\u2B07\uFE0E  ; text style;  # (4.0) DOWNWARDS BLACK ARROW`)
console.log(`\u2B07\uFE0F  ; emoji style; # (4.0) DOWNWARDS BLACK ARROW`)
console.log(`\u2B1B\uFE0E  ; text style;  # (5.1) BLACK LARGE SQUARE`)
console.log(`\u2B1B\uFE0F  ; emoji style; # (5.1) BLACK LARGE SQUARE`)
console.log(`\u2B1C\uFE0E  ; text style;  # (5.1) WHITE LARGE SQUARE`)
console.log(`\u2B1C\uFE0F  ; emoji style; # (5.1) WHITE LARGE SQUARE`)
console.log(`\u2B50\uFE0E  ; text style;  # (5.1) WHITE MEDIUM STAR`)
console.log(`\u2B50\uFE0F  ; emoji style; # (5.1) WHITE MEDIUM STAR`)
console.log(`\u2B55\uFE0E  ; text style;  # (5.2) HEAVY LARGE CIRCLE`)
console.log(`\u2B55\uFE0F  ; emoji style; # (5.2) HEAVY LARGE CIRCLE`)
console.log(`\u3030\uFE0E  ; text style;  # (1.1) WAVY DASH`)
console.log(`\u3030\uFE0F  ; emoji style; # (1.1) WAVY DASH`)
console.log(`\u303D\uFE0E  ; text style;  # (3.2) PART ALTERNATION MARK`)
console.log(`\u303D\uFE0F  ; emoji style; # (3.2) PART ALTERNATION MARK`)
console.log(
  `\u3297\uFE0E  ; text style;  # (1.1) CIRCLED IDEOGRAPH CONGRATULATION`
)
console.log(
  `\u3297\uFE0F  ; emoji style; # (1.1) CIRCLED IDEOGRAPH CONGRATULATION`
)
console.log(`\u3299\uFE0E  ; text style;  # (1.1) CIRCLED IDEOGRAPH SECRET`)
console.log(`\u3299\uFE0F  ; emoji style; # (1.1) CIRCLED IDEOGRAPH SECRET`)

Only being able to use in nestjs with peerDependencies

Problems

I and @yukinoda work on a nestjs project but when I import string-width it return Error [ERR_REQUIRE_ESM]: require() of ES Module

How to reproduce

I create a simple project for demo of the problem here.

import stringWidth from 'string-width';
console.log(stringWidth('a'));

When running nestjs I got this error

$ yarn start
yarn run v1.22.17
$ nest start

/home/bach/Workspace/tmp/demo-nest/dist/main.js:5
const string_width_1 = require("string-width");
                       ^
Error [ERR_REQUIRE_ESM]: require() of ES Module /home/bach/Workspace/tmp/demo-nest/node_modules/string-width/index.js from /home/bach/Workspace/tmp/demo-nest/dist/main.js not supported.
Instead change the require of index.js in /home/bach/Workspace/tmp/demo-nest/dist/main.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/home/bach/Workspace/tmp/demo-nest/dist/main.js:5:24)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Workaround

The problem will be solved if I use peerDependencies instead of dependencies for adding string-width

...
  },
  "peerDependencies": {
    "string-width": "^5.1.2"
  },
  "devDependencies": {
...

Question

Is there anyways to add string-width to dependencies in this case? Because I want to avoid peerDependencies

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.