lognal 0.1.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.
- package/LICENSE +21 -0
- package/README.md +99 -0
- package/dist/core/filter.d.ts +29 -0
- package/dist/core/filter.js +82 -0
- package/dist/core/layout/entry-lines.d.ts +16 -0
- package/dist/core/layout/entry-lines.js +120 -0
- package/dist/core/layout/layout.d.ts +152 -0
- package/dist/core/layout/layout.js +784 -0
- package/dist/core/layout/row-index.d.ts +33 -0
- package/dist/core/layout/row-index.js +99 -0
- package/dist/core/layout/types.d.ts +128 -0
- package/dist/core/layout/types.js +8 -0
- package/dist/core/store.d.ts +96 -0
- package/dist/core/store.js +204 -0
- package/dist/core/text/ansi.d.ts +20 -0
- package/dist/core/text/ansi.js +187 -0
- package/dist/core/text/graphemes.d.ts +17 -0
- package/dist/core/text/graphemes.js +70 -0
- package/dist/core/text/line-splitter.d.ts +18 -0
- package/dist/core/text/line-splitter.js +56 -0
- package/dist/core/text/measure.d.ts +10 -0
- package/dist/core/text/measure.js +38 -0
- package/dist/core/text/shape.d.ts +24 -0
- package/dist/core/text/shape.js +220 -0
- package/dist/core/text/unicode-width-data.d.ts +54 -0
- package/dist/core/text/unicode-width-data.js +227 -0
- package/dist/core/text/width.d.ts +20 -0
- package/dist/core/text/width.js +157 -0
- package/dist/core/text/wrap.d.ts +14 -0
- package/dist/core/text/wrap.js +94 -0
- package/dist/core/time.d.ts +10 -0
- package/dist/core/time.js +24 -0
- package/dist/core/types.d.ts +131 -0
- package/dist/core/types.js +9 -0
- package/dist/core/value/preview.d.ts +16 -0
- package/dist/core/value/preview.js +207 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +24 -0
- package/dist/lognal.css +589 -0
- package/dist/react/LogViewer.d.ts +32 -0
- package/dist/react/LogViewer.js +183 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +2 -0
- package/dist/renderer/canvas/canvas-renderer.d.ts +45 -0
- package/dist/renderer/canvas/canvas-renderer.js +464 -0
- package/dist/renderer/canvas/palette.d.ts +6 -0
- package/dist/renderer/canvas/palette.js +25 -0
- package/dist/renderer/theme.d.ts +3 -0
- package/dist/renderer/theme.js +52 -0
- package/dist/renderer/types.d.ts +82 -0
- package/dist/renderer/types.js +1 -0
- package/dist/sources/console/format.d.ts +32 -0
- package/dist/sources/console/format.js +189 -0
- package/dist/sources/console/hook.d.ts +27 -0
- package/dist/sources/console/hook.js +94 -0
- package/dist/sources/console/recorder.d.ts +41 -0
- package/dist/sources/console/recorder.js +239 -0
- package/dist/sources/console/snapshot.d.ts +22 -0
- package/dist/sources/console/snapshot.js +547 -0
- package/dist/sources/console/table.d.ts +9 -0
- package/dist/sources/console/table.js +87 -0
- package/dist/sources/text/encoding.d.ts +11 -0
- package/dist/sources/text/encoding.js +59 -0
- package/dist/sources/text/follow-file.d.ts +49 -0
- package/dist/sources/text/follow-file.js +109 -0
- package/dist/sources/text/read-file.d.ts +63 -0
- package/dist/sources/text/read-file.js +82 -0
- package/dist/viewer/icons.d.ts +14 -0
- package/dist/viewer/icons.js +30 -0
- package/dist/viewer/input-line.d.ts +46 -0
- package/dist/viewer/input-line.js +144 -0
- package/dist/viewer/labels.d.ts +35 -0
- package/dist/viewer/labels.js +61 -0
- package/dist/viewer/scrollbar.d.ts +27 -0
- package/dist/viewer/scrollbar.js +143 -0
- package/dist/viewer/theme.d.ts +15 -0
- package/dist/viewer/theme.js +105 -0
- package/dist/viewer/viewer.d.ts +217 -0
- package/dist/viewer/viewer.js +1201 -0
- package/package.json +92 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Character width data generated from the Unicode Character Database 17.0.0
|
|
3
|
+
* (EastAsianWidth.txt and DerivedGeneralCategory.txt) by
|
|
4
|
+
* `scripts/generate-unicode-width.mjs`. Do not edit this file by hand.
|
|
5
|
+
*
|
|
6
|
+
* Every list holds inclusive `[start, end]` pairs, flattened and sorted.
|
|
7
|
+
*
|
|
8
|
+
* UNICODE LICENSE V3
|
|
9
|
+
*
|
|
10
|
+
* COPYRIGHT AND PERMISSION NOTICE
|
|
11
|
+
*
|
|
12
|
+
* Copyright © 1991-2026 Unicode, Inc.
|
|
13
|
+
*
|
|
14
|
+
* NOTICE TO USER: Carefully read the following legal agreement. BY
|
|
15
|
+
* DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
|
|
16
|
+
* SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
|
17
|
+
* TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
|
|
18
|
+
* DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
|
|
19
|
+
*
|
|
20
|
+
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
21
|
+
* copy of data files and any associated documentation (the "Data Files") or
|
|
22
|
+
* software and any associated documentation (the "Software") to deal in the
|
|
23
|
+
* Data Files or Software without restriction, including without limitation
|
|
24
|
+
* the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
|
25
|
+
* copies of the Data Files or Software, and to permit persons to whom the
|
|
26
|
+
* Data Files or Software are furnished to do so, provided that either (a)
|
|
27
|
+
* this copyright and permission notice appear with all copies of the Data
|
|
28
|
+
* Files or Software, or (b) this copyright and permission notice appear in
|
|
29
|
+
* associated Documentation.
|
|
30
|
+
*
|
|
31
|
+
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
32
|
+
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
33
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
34
|
+
* THIRD PARTY RIGHTS.
|
|
35
|
+
*
|
|
36
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
|
|
37
|
+
* BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
|
|
38
|
+
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
39
|
+
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
40
|
+
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
|
|
41
|
+
* FILES OR SOFTWARE.
|
|
42
|
+
*
|
|
43
|
+
* Except as contained in this notice, the name of a copyright holder shall
|
|
44
|
+
* not be used in advertising or otherwise to promote the sale, use or other
|
|
45
|
+
* dealings in these Data Files or Software without prior written
|
|
46
|
+
* authorization of the copyright holder.
|
|
47
|
+
*/
|
|
48
|
+
export declare const UNICODE_VERSION = "17.0.0";
|
|
49
|
+
/** East Asian Wide and Fullwidth code points, drawn two cells wide. */
|
|
50
|
+
export declare const WIDE_RANGES: readonly number[];
|
|
51
|
+
/** East Asian Ambiguous code points, one or two cells wide depending on the option. */
|
|
52
|
+
export declare const AMBIGUOUS_RANGES: readonly number[];
|
|
53
|
+
/** Combining marks, format characters and Hangul jamo that attach to the previous character. */
|
|
54
|
+
export declare const ZERO_WIDTH_RANGES: readonly number[];
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Character width data generated from the Unicode Character Database 17.0.0
|
|
3
|
+
* (EastAsianWidth.txt and DerivedGeneralCategory.txt) by
|
|
4
|
+
* `scripts/generate-unicode-width.mjs`. Do not edit this file by hand.
|
|
5
|
+
*
|
|
6
|
+
* Every list holds inclusive `[start, end]` pairs, flattened and sorted.
|
|
7
|
+
*
|
|
8
|
+
* UNICODE LICENSE V3
|
|
9
|
+
*
|
|
10
|
+
* COPYRIGHT AND PERMISSION NOTICE
|
|
11
|
+
*
|
|
12
|
+
* Copyright © 1991-2026 Unicode, Inc.
|
|
13
|
+
*
|
|
14
|
+
* NOTICE TO USER: Carefully read the following legal agreement. BY
|
|
15
|
+
* DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
|
|
16
|
+
* SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
|
17
|
+
* TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
|
|
18
|
+
* DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
|
|
19
|
+
*
|
|
20
|
+
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
21
|
+
* copy of data files and any associated documentation (the "Data Files") or
|
|
22
|
+
* software and any associated documentation (the "Software") to deal in the
|
|
23
|
+
* Data Files or Software without restriction, including without limitation
|
|
24
|
+
* the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
|
25
|
+
* copies of the Data Files or Software, and to permit persons to whom the
|
|
26
|
+
* Data Files or Software are furnished to do so, provided that either (a)
|
|
27
|
+
* this copyright and permission notice appear with all copies of the Data
|
|
28
|
+
* Files or Software, or (b) this copyright and permission notice appear in
|
|
29
|
+
* associated Documentation.
|
|
30
|
+
*
|
|
31
|
+
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
32
|
+
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
33
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
34
|
+
* THIRD PARTY RIGHTS.
|
|
35
|
+
*
|
|
36
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
|
|
37
|
+
* BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
|
|
38
|
+
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
39
|
+
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
40
|
+
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
|
|
41
|
+
* FILES OR SOFTWARE.
|
|
42
|
+
*
|
|
43
|
+
* Except as contained in this notice, the name of a copyright holder shall
|
|
44
|
+
* not be used in advertising or otherwise to promote the sale, use or other
|
|
45
|
+
* dealings in these Data Files or Software without prior written
|
|
46
|
+
* authorization of the copyright holder.
|
|
47
|
+
*/
|
|
48
|
+
export const UNICODE_VERSION = '17.0.0';
|
|
49
|
+
/** East Asian Wide and Fullwidth code points, drawn two cells wide. */
|
|
50
|
+
export const WIDE_RANGES = [
|
|
51
|
+
0x1100, 0x115f, 0x231a, 0x231b, 0x2329, 0x232a, 0x23e9, 0x23ec,
|
|
52
|
+
0x23f0, 0x23f0, 0x23f3, 0x23f3, 0x25fd, 0x25fe, 0x2614, 0x2615,
|
|
53
|
+
0x2630, 0x2637, 0x2648, 0x2653, 0x267f, 0x267f, 0x268a, 0x268f,
|
|
54
|
+
0x2693, 0x2693, 0x26a1, 0x26a1, 0x26aa, 0x26ab, 0x26bd, 0x26be,
|
|
55
|
+
0x26c4, 0x26c5, 0x26ce, 0x26ce, 0x26d4, 0x26d4, 0x26ea, 0x26ea,
|
|
56
|
+
0x26f2, 0x26f3, 0x26f5, 0x26f5, 0x26fa, 0x26fa, 0x26fd, 0x26fd,
|
|
57
|
+
0x2705, 0x2705, 0x270a, 0x270b, 0x2728, 0x2728, 0x274c, 0x274c,
|
|
58
|
+
0x274e, 0x274e, 0x2753, 0x2755, 0x2757, 0x2757, 0x2795, 0x2797,
|
|
59
|
+
0x27b0, 0x27b0, 0x27bf, 0x27bf, 0x2b1b, 0x2b1c, 0x2b50, 0x2b50,
|
|
60
|
+
0x2b55, 0x2b55, 0x2e80, 0x2e99, 0x2e9b, 0x2ef3, 0x2f00, 0x2fd5,
|
|
61
|
+
0x2ff0, 0x3029, 0x302e, 0x303e, 0x3041, 0x3096, 0x309b, 0x30ff,
|
|
62
|
+
0x3105, 0x312f, 0x3131, 0x318e, 0x3190, 0x31e5, 0x31ef, 0x321e,
|
|
63
|
+
0x3220, 0x3247, 0x3250, 0xa48c, 0xa490, 0xa4c6, 0xa960, 0xa97c,
|
|
64
|
+
0xac00, 0xd7a3, 0xf900, 0xfaff, 0xfe10, 0xfe19, 0xfe30, 0xfe52,
|
|
65
|
+
0xfe54, 0xfe66, 0xfe68, 0xfe6b, 0xff01, 0xff60, 0xffe0, 0xffe6,
|
|
66
|
+
0x16fe0, 0x16fe3, 0x16ff0, 0x16ff6, 0x17000, 0x18cd5, 0x18cff, 0x18d1e,
|
|
67
|
+
0x18d80, 0x18df2, 0x1aff0, 0x1aff3, 0x1aff5, 0x1affb, 0x1affd, 0x1affe,
|
|
68
|
+
0x1b000, 0x1b122, 0x1b132, 0x1b132, 0x1b150, 0x1b152, 0x1b155, 0x1b155,
|
|
69
|
+
0x1b164, 0x1b167, 0x1b170, 0x1b2fb, 0x1d300, 0x1d356, 0x1d360, 0x1d376,
|
|
70
|
+
0x1f004, 0x1f004, 0x1f0cf, 0x1f0cf, 0x1f18e, 0x1f18e, 0x1f191, 0x1f19a,
|
|
71
|
+
0x1f200, 0x1f202, 0x1f210, 0x1f23b, 0x1f240, 0x1f248, 0x1f250, 0x1f251,
|
|
72
|
+
0x1f260, 0x1f265, 0x1f300, 0x1f320, 0x1f32d, 0x1f335, 0x1f337, 0x1f37c,
|
|
73
|
+
0x1f37e, 0x1f393, 0x1f3a0, 0x1f3ca, 0x1f3cf, 0x1f3d3, 0x1f3e0, 0x1f3f0,
|
|
74
|
+
0x1f3f4, 0x1f3f4, 0x1f3f8, 0x1f43e, 0x1f440, 0x1f440, 0x1f442, 0x1f4fc,
|
|
75
|
+
0x1f4ff, 0x1f53d, 0x1f54b, 0x1f54e, 0x1f550, 0x1f567, 0x1f57a, 0x1f57a,
|
|
76
|
+
0x1f595, 0x1f596, 0x1f5a4, 0x1f5a4, 0x1f5fb, 0x1f64f, 0x1f680, 0x1f6c5,
|
|
77
|
+
0x1f6cc, 0x1f6cc, 0x1f6d0, 0x1f6d2, 0x1f6d5, 0x1f6d8, 0x1f6dc, 0x1f6df,
|
|
78
|
+
0x1f6eb, 0x1f6ec, 0x1f6f4, 0x1f6fc, 0x1f7e0, 0x1f7eb, 0x1f7f0, 0x1f7f0,
|
|
79
|
+
0x1f90c, 0x1f93a, 0x1f93c, 0x1f945, 0x1f947, 0x1f9ff, 0x1fa70, 0x1fa7c,
|
|
80
|
+
0x1fa80, 0x1fa8a, 0x1fa8e, 0x1fac6, 0x1fac8, 0x1fac8, 0x1facd, 0x1fadc,
|
|
81
|
+
0x1fadf, 0x1faea, 0x1faef, 0x1faf8, 0x20000, 0x2fffd, 0x30000, 0x3fffd
|
|
82
|
+
];
|
|
83
|
+
/** East Asian Ambiguous code points, one or two cells wide depending on the option. */
|
|
84
|
+
export const AMBIGUOUS_RANGES = [
|
|
85
|
+
0xa1, 0xa1, 0xa4, 0xa4, 0xa7, 0xa8, 0xaa, 0xaa,
|
|
86
|
+
0xae, 0xae, 0xb0, 0xb4, 0xb6, 0xba, 0xbc, 0xbf,
|
|
87
|
+
0xc6, 0xc6, 0xd0, 0xd0, 0xd7, 0xd8, 0xde, 0xe1,
|
|
88
|
+
0xe6, 0xe6, 0xe8, 0xea, 0xec, 0xed, 0xf0, 0xf0,
|
|
89
|
+
0xf2, 0xf3, 0xf7, 0xfa, 0xfc, 0xfc, 0xfe, 0xfe,
|
|
90
|
+
0x101, 0x101, 0x111, 0x111, 0x113, 0x113, 0x11b, 0x11b,
|
|
91
|
+
0x126, 0x127, 0x12b, 0x12b, 0x131, 0x133, 0x138, 0x138,
|
|
92
|
+
0x13f, 0x142, 0x144, 0x144, 0x148, 0x14b, 0x14d, 0x14d,
|
|
93
|
+
0x152, 0x153, 0x166, 0x167, 0x16b, 0x16b, 0x1ce, 0x1ce,
|
|
94
|
+
0x1d0, 0x1d0, 0x1d2, 0x1d2, 0x1d4, 0x1d4, 0x1d6, 0x1d6,
|
|
95
|
+
0x1d8, 0x1d8, 0x1da, 0x1da, 0x1dc, 0x1dc, 0x251, 0x251,
|
|
96
|
+
0x261, 0x261, 0x2c4, 0x2c4, 0x2c7, 0x2c7, 0x2c9, 0x2cb,
|
|
97
|
+
0x2cd, 0x2cd, 0x2d0, 0x2d0, 0x2d8, 0x2db, 0x2dd, 0x2dd,
|
|
98
|
+
0x2df, 0x2df, 0x391, 0x3a1, 0x3a3, 0x3a9, 0x3b1, 0x3c1,
|
|
99
|
+
0x3c3, 0x3c9, 0x401, 0x401, 0x410, 0x44f, 0x451, 0x451,
|
|
100
|
+
0x2010, 0x2010, 0x2013, 0x2016, 0x2018, 0x2019, 0x201c, 0x201d,
|
|
101
|
+
0x2020, 0x2022, 0x2024, 0x2027, 0x2030, 0x2030, 0x2032, 0x2033,
|
|
102
|
+
0x2035, 0x2035, 0x203b, 0x203b, 0x203e, 0x203e, 0x2074, 0x2074,
|
|
103
|
+
0x207f, 0x207f, 0x2081, 0x2084, 0x20ac, 0x20ac, 0x2103, 0x2103,
|
|
104
|
+
0x2105, 0x2105, 0x2109, 0x2109, 0x2113, 0x2113, 0x2116, 0x2116,
|
|
105
|
+
0x2121, 0x2122, 0x2126, 0x2126, 0x212b, 0x212b, 0x2153, 0x2154,
|
|
106
|
+
0x215b, 0x215e, 0x2160, 0x216b, 0x2170, 0x2179, 0x2189, 0x2189,
|
|
107
|
+
0x2190, 0x2199, 0x21b8, 0x21b9, 0x21d2, 0x21d2, 0x21d4, 0x21d4,
|
|
108
|
+
0x21e7, 0x21e7, 0x2200, 0x2200, 0x2202, 0x2203, 0x2207, 0x2208,
|
|
109
|
+
0x220b, 0x220b, 0x220f, 0x220f, 0x2211, 0x2211, 0x2215, 0x2215,
|
|
110
|
+
0x221a, 0x221a, 0x221d, 0x2220, 0x2223, 0x2223, 0x2225, 0x2225,
|
|
111
|
+
0x2227, 0x222c, 0x222e, 0x222e, 0x2234, 0x2237, 0x223c, 0x223d,
|
|
112
|
+
0x2248, 0x2248, 0x224c, 0x224c, 0x2252, 0x2252, 0x2260, 0x2261,
|
|
113
|
+
0x2264, 0x2267, 0x226a, 0x226b, 0x226e, 0x226f, 0x2282, 0x2283,
|
|
114
|
+
0x2286, 0x2287, 0x2295, 0x2295, 0x2299, 0x2299, 0x22a5, 0x22a5,
|
|
115
|
+
0x22bf, 0x22bf, 0x2312, 0x2312, 0x2460, 0x24e9, 0x24eb, 0x254b,
|
|
116
|
+
0x2550, 0x2573, 0x2580, 0x258f, 0x2592, 0x2595, 0x25a0, 0x25a1,
|
|
117
|
+
0x25a3, 0x25a9, 0x25b2, 0x25b3, 0x25b6, 0x25b7, 0x25bc, 0x25bd,
|
|
118
|
+
0x25c0, 0x25c1, 0x25c6, 0x25c8, 0x25cb, 0x25cb, 0x25ce, 0x25d1,
|
|
119
|
+
0x25e2, 0x25e5, 0x25ef, 0x25ef, 0x2605, 0x2606, 0x2609, 0x2609,
|
|
120
|
+
0x260e, 0x260f, 0x261c, 0x261c, 0x261e, 0x261e, 0x2640, 0x2640,
|
|
121
|
+
0x2642, 0x2642, 0x2660, 0x2661, 0x2663, 0x2665, 0x2667, 0x266a,
|
|
122
|
+
0x266c, 0x266d, 0x266f, 0x266f, 0x269e, 0x269f, 0x26bf, 0x26bf,
|
|
123
|
+
0x26c6, 0x26cd, 0x26cf, 0x26d3, 0x26d5, 0x26e1, 0x26e3, 0x26e3,
|
|
124
|
+
0x26e8, 0x26e9, 0x26eb, 0x26f1, 0x26f4, 0x26f4, 0x26f6, 0x26f9,
|
|
125
|
+
0x26fb, 0x26fc, 0x26fe, 0x26ff, 0x273d, 0x273d, 0x2776, 0x277f,
|
|
126
|
+
0x2b56, 0x2b59, 0x3248, 0x324f, 0xe000, 0xf8ff, 0xfffd, 0xfffd,
|
|
127
|
+
0x1f100, 0x1f10a, 0x1f110, 0x1f12d, 0x1f130, 0x1f169, 0x1f170, 0x1f18d,
|
|
128
|
+
0x1f18f, 0x1f190, 0x1f19b, 0x1f1ac, 0xf0000, 0xffffd, 0x100000, 0x10fffd
|
|
129
|
+
];
|
|
130
|
+
/** Combining marks, format characters and Hangul jamo that attach to the previous character. */
|
|
131
|
+
export const ZERO_WIDTH_RANGES = [
|
|
132
|
+
0xad, 0xad, 0x300, 0x36f, 0x483, 0x489, 0x591, 0x5bd,
|
|
133
|
+
0x5bf, 0x5bf, 0x5c1, 0x5c2, 0x5c4, 0x5c5, 0x5c7, 0x5c7,
|
|
134
|
+
0x600, 0x605, 0x610, 0x61a, 0x61c, 0x61c, 0x64b, 0x65f,
|
|
135
|
+
0x670, 0x670, 0x6d6, 0x6dd, 0x6df, 0x6e4, 0x6e7, 0x6e8,
|
|
136
|
+
0x6ea, 0x6ed, 0x70f, 0x70f, 0x711, 0x711, 0x730, 0x74a,
|
|
137
|
+
0x7a6, 0x7b0, 0x7eb, 0x7f3, 0x7fd, 0x7fd, 0x816, 0x819,
|
|
138
|
+
0x81b, 0x823, 0x825, 0x827, 0x829, 0x82d, 0x859, 0x85b,
|
|
139
|
+
0x890, 0x891, 0x897, 0x89f, 0x8ca, 0x902, 0x93a, 0x93a,
|
|
140
|
+
0x93c, 0x93c, 0x941, 0x948, 0x94d, 0x94d, 0x951, 0x957,
|
|
141
|
+
0x962, 0x963, 0x981, 0x981, 0x9bc, 0x9bc, 0x9c1, 0x9c4,
|
|
142
|
+
0x9cd, 0x9cd, 0x9e2, 0x9e3, 0x9fe, 0x9fe, 0xa01, 0xa02,
|
|
143
|
+
0xa3c, 0xa3c, 0xa41, 0xa42, 0xa47, 0xa48, 0xa4b, 0xa4d,
|
|
144
|
+
0xa51, 0xa51, 0xa70, 0xa71, 0xa75, 0xa75, 0xa81, 0xa82,
|
|
145
|
+
0xabc, 0xabc, 0xac1, 0xac5, 0xac7, 0xac8, 0xacd, 0xacd,
|
|
146
|
+
0xae2, 0xae3, 0xafa, 0xaff, 0xb01, 0xb01, 0xb3c, 0xb3c,
|
|
147
|
+
0xb3f, 0xb3f, 0xb41, 0xb44, 0xb4d, 0xb4d, 0xb55, 0xb56,
|
|
148
|
+
0xb62, 0xb63, 0xb82, 0xb82, 0xbc0, 0xbc0, 0xbcd, 0xbcd,
|
|
149
|
+
0xc00, 0xc00, 0xc04, 0xc04, 0xc3c, 0xc3c, 0xc3e, 0xc40,
|
|
150
|
+
0xc46, 0xc48, 0xc4a, 0xc4d, 0xc55, 0xc56, 0xc62, 0xc63,
|
|
151
|
+
0xc81, 0xc81, 0xcbc, 0xcbc, 0xcbf, 0xcbf, 0xcc6, 0xcc6,
|
|
152
|
+
0xccc, 0xccd, 0xce2, 0xce3, 0xd00, 0xd01, 0xd3b, 0xd3c,
|
|
153
|
+
0xd41, 0xd44, 0xd4d, 0xd4d, 0xd62, 0xd63, 0xd81, 0xd81,
|
|
154
|
+
0xdca, 0xdca, 0xdd2, 0xdd4, 0xdd6, 0xdd6, 0xe31, 0xe31,
|
|
155
|
+
0xe34, 0xe3a, 0xe47, 0xe4e, 0xeb1, 0xeb1, 0xeb4, 0xebc,
|
|
156
|
+
0xec8, 0xece, 0xf18, 0xf19, 0xf35, 0xf35, 0xf37, 0xf37,
|
|
157
|
+
0xf39, 0xf39, 0xf71, 0xf7e, 0xf80, 0xf84, 0xf86, 0xf87,
|
|
158
|
+
0xf8d, 0xf97, 0xf99, 0xfbc, 0xfc6, 0xfc6, 0x102d, 0x1030,
|
|
159
|
+
0x1032, 0x1037, 0x1039, 0x103a, 0x103d, 0x103e, 0x1058, 0x1059,
|
|
160
|
+
0x105e, 0x1060, 0x1071, 0x1074, 0x1082, 0x1082, 0x1085, 0x1086,
|
|
161
|
+
0x108d, 0x108d, 0x109d, 0x109d, 0x1160, 0x11ff, 0x135d, 0x135f,
|
|
162
|
+
0x1712, 0x1714, 0x1732, 0x1733, 0x1752, 0x1753, 0x1772, 0x1773,
|
|
163
|
+
0x17b4, 0x17b5, 0x17b7, 0x17bd, 0x17c6, 0x17c6, 0x17c9, 0x17d3,
|
|
164
|
+
0x17dd, 0x17dd, 0x180b, 0x180f, 0x1885, 0x1886, 0x18a9, 0x18a9,
|
|
165
|
+
0x1920, 0x1922, 0x1927, 0x1928, 0x1932, 0x1932, 0x1939, 0x193b,
|
|
166
|
+
0x1a17, 0x1a18, 0x1a1b, 0x1a1b, 0x1a56, 0x1a56, 0x1a58, 0x1a5e,
|
|
167
|
+
0x1a60, 0x1a60, 0x1a62, 0x1a62, 0x1a65, 0x1a6c, 0x1a73, 0x1a7c,
|
|
168
|
+
0x1a7f, 0x1a7f, 0x1ab0, 0x1add, 0x1ae0, 0x1aeb, 0x1b00, 0x1b03,
|
|
169
|
+
0x1b34, 0x1b34, 0x1b36, 0x1b3a, 0x1b3c, 0x1b3c, 0x1b42, 0x1b42,
|
|
170
|
+
0x1b6b, 0x1b73, 0x1b80, 0x1b81, 0x1ba2, 0x1ba5, 0x1ba8, 0x1ba9,
|
|
171
|
+
0x1bab, 0x1bad, 0x1be6, 0x1be6, 0x1be8, 0x1be9, 0x1bed, 0x1bed,
|
|
172
|
+
0x1bef, 0x1bf1, 0x1c2c, 0x1c33, 0x1c36, 0x1c37, 0x1cd0, 0x1cd2,
|
|
173
|
+
0x1cd4, 0x1ce0, 0x1ce2, 0x1ce8, 0x1ced, 0x1ced, 0x1cf4, 0x1cf4,
|
|
174
|
+
0x1cf8, 0x1cf9, 0x1dc0, 0x1dff, 0x200b, 0x200f, 0x202a, 0x202e,
|
|
175
|
+
0x2060, 0x2064, 0x2066, 0x206f, 0x20d0, 0x20f0, 0x2cef, 0x2cf1,
|
|
176
|
+
0x2d7f, 0x2d7f, 0x2de0, 0x2dff, 0x302a, 0x302d, 0x3099, 0x309a,
|
|
177
|
+
0xa66f, 0xa672, 0xa674, 0xa67d, 0xa69e, 0xa69f, 0xa6f0, 0xa6f1,
|
|
178
|
+
0xa802, 0xa802, 0xa806, 0xa806, 0xa80b, 0xa80b, 0xa825, 0xa826,
|
|
179
|
+
0xa82c, 0xa82c, 0xa8c4, 0xa8c5, 0xa8e0, 0xa8f1, 0xa8ff, 0xa8ff,
|
|
180
|
+
0xa926, 0xa92d, 0xa947, 0xa951, 0xa980, 0xa982, 0xa9b3, 0xa9b3,
|
|
181
|
+
0xa9b6, 0xa9b9, 0xa9bc, 0xa9bd, 0xa9e5, 0xa9e5, 0xaa29, 0xaa2e,
|
|
182
|
+
0xaa31, 0xaa32, 0xaa35, 0xaa36, 0xaa43, 0xaa43, 0xaa4c, 0xaa4c,
|
|
183
|
+
0xaa7c, 0xaa7c, 0xaab0, 0xaab0, 0xaab2, 0xaab4, 0xaab7, 0xaab8,
|
|
184
|
+
0xaabe, 0xaabf, 0xaac1, 0xaac1, 0xaaec, 0xaaed, 0xaaf6, 0xaaf6,
|
|
185
|
+
0xabe5, 0xabe5, 0xabe8, 0xabe8, 0xabed, 0xabed, 0xd7b0, 0xd7ff,
|
|
186
|
+
0xfb1e, 0xfb1e, 0xfe00, 0xfe0f, 0xfe20, 0xfe2f, 0xfeff, 0xfeff,
|
|
187
|
+
0xfff9, 0xfffb, 0x101fd, 0x101fd, 0x102e0, 0x102e0, 0x10376, 0x1037a,
|
|
188
|
+
0x10a01, 0x10a03, 0x10a05, 0x10a06, 0x10a0c, 0x10a0f, 0x10a38, 0x10a3a,
|
|
189
|
+
0x10a3f, 0x10a3f, 0x10ae5, 0x10ae6, 0x10d24, 0x10d27, 0x10d69, 0x10d6d,
|
|
190
|
+
0x10eab, 0x10eac, 0x10efa, 0x10eff, 0x10f46, 0x10f50, 0x10f82, 0x10f85,
|
|
191
|
+
0x11001, 0x11001, 0x11038, 0x11046, 0x11070, 0x11070, 0x11073, 0x11074,
|
|
192
|
+
0x1107f, 0x11081, 0x110b3, 0x110b6, 0x110b9, 0x110ba, 0x110bd, 0x110bd,
|
|
193
|
+
0x110c2, 0x110c2, 0x110cd, 0x110cd, 0x11100, 0x11102, 0x11127, 0x1112b,
|
|
194
|
+
0x1112d, 0x11134, 0x11173, 0x11173, 0x11180, 0x11181, 0x111b6, 0x111be,
|
|
195
|
+
0x111c9, 0x111cc, 0x111cf, 0x111cf, 0x1122f, 0x11231, 0x11234, 0x11234,
|
|
196
|
+
0x11236, 0x11237, 0x1123e, 0x1123e, 0x11241, 0x11241, 0x112df, 0x112df,
|
|
197
|
+
0x112e3, 0x112ea, 0x11300, 0x11301, 0x1133b, 0x1133c, 0x11340, 0x11340,
|
|
198
|
+
0x11366, 0x1136c, 0x11370, 0x11374, 0x113bb, 0x113c0, 0x113ce, 0x113ce,
|
|
199
|
+
0x113d0, 0x113d0, 0x113d2, 0x113d2, 0x113e1, 0x113e2, 0x11438, 0x1143f,
|
|
200
|
+
0x11442, 0x11444, 0x11446, 0x11446, 0x1145e, 0x1145e, 0x114b3, 0x114b8,
|
|
201
|
+
0x114ba, 0x114ba, 0x114bf, 0x114c0, 0x114c2, 0x114c3, 0x115b2, 0x115b5,
|
|
202
|
+
0x115bc, 0x115bd, 0x115bf, 0x115c0, 0x115dc, 0x115dd, 0x11633, 0x1163a,
|
|
203
|
+
0x1163d, 0x1163d, 0x1163f, 0x11640, 0x116ab, 0x116ab, 0x116ad, 0x116ad,
|
|
204
|
+
0x116b0, 0x116b5, 0x116b7, 0x116b7, 0x1171d, 0x1171d, 0x1171f, 0x1171f,
|
|
205
|
+
0x11722, 0x11725, 0x11727, 0x1172b, 0x1182f, 0x11837, 0x11839, 0x1183a,
|
|
206
|
+
0x1193b, 0x1193c, 0x1193e, 0x1193e, 0x11943, 0x11943, 0x119d4, 0x119d7,
|
|
207
|
+
0x119da, 0x119db, 0x119e0, 0x119e0, 0x11a01, 0x11a0a, 0x11a33, 0x11a38,
|
|
208
|
+
0x11a3b, 0x11a3e, 0x11a47, 0x11a47, 0x11a51, 0x11a56, 0x11a59, 0x11a5b,
|
|
209
|
+
0x11a8a, 0x11a96, 0x11a98, 0x11a99, 0x11b60, 0x11b60, 0x11b62, 0x11b64,
|
|
210
|
+
0x11b66, 0x11b66, 0x11c30, 0x11c36, 0x11c38, 0x11c3d, 0x11c3f, 0x11c3f,
|
|
211
|
+
0x11c92, 0x11ca7, 0x11caa, 0x11cb0, 0x11cb2, 0x11cb3, 0x11cb5, 0x11cb6,
|
|
212
|
+
0x11d31, 0x11d36, 0x11d3a, 0x11d3a, 0x11d3c, 0x11d3d, 0x11d3f, 0x11d45,
|
|
213
|
+
0x11d47, 0x11d47, 0x11d90, 0x11d91, 0x11d95, 0x11d95, 0x11d97, 0x11d97,
|
|
214
|
+
0x11ef3, 0x11ef4, 0x11f00, 0x11f01, 0x11f36, 0x11f3a, 0x11f40, 0x11f40,
|
|
215
|
+
0x11f42, 0x11f42, 0x11f5a, 0x11f5a, 0x13430, 0x13440, 0x13447, 0x13455,
|
|
216
|
+
0x1611e, 0x16129, 0x1612d, 0x1612f, 0x16af0, 0x16af4, 0x16b30, 0x16b36,
|
|
217
|
+
0x16f4f, 0x16f4f, 0x16f8f, 0x16f92, 0x16fe4, 0x16fe4, 0x1bc9d, 0x1bc9e,
|
|
218
|
+
0x1bca0, 0x1bca3, 0x1cf00, 0x1cf2d, 0x1cf30, 0x1cf46, 0x1d167, 0x1d169,
|
|
219
|
+
0x1d173, 0x1d182, 0x1d185, 0x1d18b, 0x1d1aa, 0x1d1ad, 0x1d242, 0x1d244,
|
|
220
|
+
0x1da00, 0x1da36, 0x1da3b, 0x1da6c, 0x1da75, 0x1da75, 0x1da84, 0x1da84,
|
|
221
|
+
0x1da9b, 0x1da9f, 0x1daa1, 0x1daaf, 0x1e000, 0x1e006, 0x1e008, 0x1e018,
|
|
222
|
+
0x1e01b, 0x1e021, 0x1e023, 0x1e024, 0x1e026, 0x1e02a, 0x1e08f, 0x1e08f,
|
|
223
|
+
0x1e130, 0x1e136, 0x1e2ae, 0x1e2ae, 0x1e2ec, 0x1e2ef, 0x1e4ec, 0x1e4ef,
|
|
224
|
+
0x1e5ee, 0x1e5ef, 0x1e6e3, 0x1e6e3, 0x1e6e6, 0x1e6e6, 0x1e6ee, 0x1e6ef,
|
|
225
|
+
0x1e6f5, 0x1e6f5, 0x1e8d0, 0x1e8d6, 0x1e944, 0x1e94a, 0xe0001, 0xe0001,
|
|
226
|
+
0xe0020, 0xe007f, 0xe0100, 0xe01ef
|
|
227
|
+
];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** How many cells an East Asian Ambiguous character takes. */
|
|
2
|
+
export type AmbiguousWidth = 1 | 2;
|
|
3
|
+
/**
|
|
4
|
+
* Returns how many cells a single code point takes: 0 for combining marks and format
|
|
5
|
+
* characters, 2 for wide characters, and 1 otherwise.
|
|
6
|
+
*
|
|
7
|
+
* Control characters return 1. Callers are expected to replace them with a visible notation
|
|
8
|
+
* before measuring.
|
|
9
|
+
*/
|
|
10
|
+
export declare const codePointWidth: (codePoint: number, ambiguousWidth?: AmbiguousWidth) => number;
|
|
11
|
+
/** Returns whether a code point is a Hangul syllable or jamo, where words break at spaces only. */
|
|
12
|
+
export declare const isHangul: (codePoint: number) => boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Returns how many cells a grapheme cluster takes.
|
|
15
|
+
*
|
|
16
|
+
* The widest code point decides, with the rules emoji add on top: a cluster with the emoji
|
|
17
|
+
* variation selector or a pair of regional indicators (a flag) is two cells, and one with the
|
|
18
|
+
* text variation selector is one cell.
|
|
19
|
+
*/
|
|
20
|
+
export declare const clusterWidth: (cluster: string, ambiguousWidth?: AmbiguousWidth) => number;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { AMBIGUOUS_RANGES, WIDE_RANGES, ZERO_WIDTH_RANGES } from './unicode-width-data.js';
|
|
2
|
+
const BMP_SIZE = 0x10000;
|
|
3
|
+
// Values stored in `bmpCache`. Zero means the code point has not been looked up yet.
|
|
4
|
+
const CACHE_ZERO = 1;
|
|
5
|
+
const CACHE_NARROW = 2;
|
|
6
|
+
const CACHE_WIDE = 3;
|
|
7
|
+
const CACHE_AMBIGUOUS = 4;
|
|
8
|
+
const REGIONAL_INDICATOR_FIRST = 0x1f1e6;
|
|
9
|
+
const REGIONAL_INDICATOR_LAST = 0x1f1ff;
|
|
10
|
+
const VARIATION_SELECTOR_TEXT = 0xfe0e;
|
|
11
|
+
const VARIATION_SELECTOR_EMOJI = 0xfe0f;
|
|
12
|
+
const bmpCache = new Uint8Array(BMP_SIZE);
|
|
13
|
+
const isInRanges = (ranges, codePoint) => {
|
|
14
|
+
let low = 0;
|
|
15
|
+
let high = ranges.length / 2 - 1;
|
|
16
|
+
if (high < 0 || codePoint < ranges[0] || codePoint > ranges[ranges.length - 1]) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
while (low <= high) {
|
|
20
|
+
const middle = (low + high) >> 1;
|
|
21
|
+
const start = ranges[middle * 2];
|
|
22
|
+
const end = ranges[middle * 2 + 1];
|
|
23
|
+
if (codePoint < start) {
|
|
24
|
+
high = middle - 1;
|
|
25
|
+
}
|
|
26
|
+
else if (codePoint > end) {
|
|
27
|
+
low = middle + 1;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
35
|
+
const classify = (codePoint) => {
|
|
36
|
+
// Box drawing and block elements are ambiguous in the data, but monospace fonts draw them
|
|
37
|
+
// one cell wide, and tables drawn with them only line up that way.
|
|
38
|
+
if (codePoint >= 0x2500 && codePoint <= 0x259f) {
|
|
39
|
+
return CACHE_NARROW;
|
|
40
|
+
}
|
|
41
|
+
if (isInRanges(ZERO_WIDTH_RANGES, codePoint)) {
|
|
42
|
+
return CACHE_ZERO;
|
|
43
|
+
}
|
|
44
|
+
if (isInRanges(WIDE_RANGES, codePoint)) {
|
|
45
|
+
return CACHE_WIDE;
|
|
46
|
+
}
|
|
47
|
+
if (isInRanges(AMBIGUOUS_RANGES, codePoint)) {
|
|
48
|
+
return CACHE_AMBIGUOUS;
|
|
49
|
+
}
|
|
50
|
+
return CACHE_NARROW;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Returns how many cells a single code point takes: 0 for combining marks and format
|
|
54
|
+
* characters, 2 for wide characters, and 1 otherwise.
|
|
55
|
+
*
|
|
56
|
+
* Control characters return 1. Callers are expected to replace them with a visible notation
|
|
57
|
+
* before measuring.
|
|
58
|
+
*/
|
|
59
|
+
export const codePointWidth = (codePoint, ambiguousWidth = 1) => {
|
|
60
|
+
// Printable ASCII and the Latin-1 range before the first ambiguous character.
|
|
61
|
+
if (codePoint < 0xa1) {
|
|
62
|
+
return 1;
|
|
63
|
+
}
|
|
64
|
+
let kind;
|
|
65
|
+
if (codePoint < BMP_SIZE) {
|
|
66
|
+
kind = bmpCache[codePoint];
|
|
67
|
+
if (kind === 0) {
|
|
68
|
+
kind = classify(codePoint);
|
|
69
|
+
bmpCache[codePoint] = kind;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
kind = classify(codePoint);
|
|
74
|
+
}
|
|
75
|
+
if (kind === CACHE_ZERO) {
|
|
76
|
+
return 0;
|
|
77
|
+
}
|
|
78
|
+
if (kind === CACHE_WIDE) {
|
|
79
|
+
return 2;
|
|
80
|
+
}
|
|
81
|
+
if (kind === CACHE_AMBIGUOUS) {
|
|
82
|
+
return ambiguousWidth;
|
|
83
|
+
}
|
|
84
|
+
return 1;
|
|
85
|
+
};
|
|
86
|
+
/** Returns whether a code point is a Hangul syllable or jamo, where words break at spaces only. */
|
|
87
|
+
export const isHangul = (codePoint) => {
|
|
88
|
+
return ((codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
|
|
89
|
+
(codePoint >= 0x1100 && codePoint <= 0x11ff) ||
|
|
90
|
+
(codePoint >= 0x3130 && codePoint <= 0x318f) ||
|
|
91
|
+
(codePoint >= 0xa960 && codePoint <= 0xa97f) ||
|
|
92
|
+
(codePoint >= 0xd7b0 && codePoint <= 0xd7ff));
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Returns how many cells a grapheme cluster takes.
|
|
96
|
+
*
|
|
97
|
+
* The widest code point decides, with the rules emoji add on top: a cluster with the emoji
|
|
98
|
+
* variation selector or a pair of regional indicators (a flag) is two cells, and one with the
|
|
99
|
+
* text variation selector is one cell.
|
|
100
|
+
*/
|
|
101
|
+
export const clusterWidth = (cluster, ambiguousWidth = 1) => {
|
|
102
|
+
if (cluster.length === 1) {
|
|
103
|
+
const code = cluster.charCodeAt(0);
|
|
104
|
+
if (code < 0xa1) {
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
return Math.max(codePointWidth(code, ambiguousWidth), isZeroOnly(code) ? 0 : 1);
|
|
108
|
+
}
|
|
109
|
+
let width = 0;
|
|
110
|
+
let hasEmojiSelector = false;
|
|
111
|
+
let hasTextSelector = false;
|
|
112
|
+
let hasRegionalIndicator = false;
|
|
113
|
+
let hasVisible = false;
|
|
114
|
+
for (const character of cluster) {
|
|
115
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
116
|
+
if (codePoint === VARIATION_SELECTOR_EMOJI) {
|
|
117
|
+
hasEmojiSelector = true;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (codePoint === VARIATION_SELECTOR_TEXT) {
|
|
121
|
+
hasTextSelector = true;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (codePoint >= REGIONAL_INDICATOR_FIRST && codePoint <= REGIONAL_INDICATOR_LAST) {
|
|
125
|
+
hasRegionalIndicator = true;
|
|
126
|
+
}
|
|
127
|
+
const codeWidth = codePointWidth(codePoint, ambiguousWidth);
|
|
128
|
+
if (codeWidth > 0 || !isZeroOnly(codePoint)) {
|
|
129
|
+
hasVisible = true;
|
|
130
|
+
}
|
|
131
|
+
if (codeWidth > width) {
|
|
132
|
+
width = codeWidth;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (hasEmojiSelector || hasRegionalIndicator) {
|
|
136
|
+
return 2;
|
|
137
|
+
}
|
|
138
|
+
if (hasTextSelector) {
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
141
|
+
if (width === 0) {
|
|
142
|
+
return hasVisible ? 1 : 0;
|
|
143
|
+
}
|
|
144
|
+
return width;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Invisible format characters, such as the zero width space, that take no cell even when they
|
|
148
|
+
* stand alone. A combining mark on its own still takes one cell so it stays visible.
|
|
149
|
+
*/
|
|
150
|
+
const isZeroOnly = (codePoint) => {
|
|
151
|
+
return (codePoint === 0x200b ||
|
|
152
|
+
codePoint === 0x200c ||
|
|
153
|
+
codePoint === 0x200d ||
|
|
154
|
+
codePoint === 0x2060 ||
|
|
155
|
+
codePoint === 0xfeff ||
|
|
156
|
+
codePoint === 0x00ad);
|
|
157
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ShapedLine, type WrapMode } from '../layout/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the index of the first cluster of every row a line wraps into.
|
|
4
|
+
*
|
|
5
|
+
* - `none` keeps the line on one row.
|
|
6
|
+
* - `char` fills every row and breaks between any two clusters.
|
|
7
|
+
* - `word` breaks after a space, or on either side of a wide character such as a Han
|
|
8
|
+
* ideograph. Hangul syllables keep words together, so Korean text breaks at spaces. A word
|
|
9
|
+
* longer than the row is broken between characters.
|
|
10
|
+
*
|
|
11
|
+
* A space that does not fit at the end of a row hangs past the edge, so a row never starts
|
|
12
|
+
* with the space that ended the word before it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const wrapLine: (line: ShapedLine, columns: number, mode: WrapMode) => number[];
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { BREAK_SPACE, BREAK_WIDE } from '../layout/types.js';
|
|
2
|
+
import { breakAt, widthAt } from './shape.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the index of the first cluster of every row a line wraps into.
|
|
5
|
+
*
|
|
6
|
+
* - `none` keeps the line on one row.
|
|
7
|
+
* - `char` fills every row and breaks between any two clusters.
|
|
8
|
+
* - `word` breaks after a space, or on either side of a wide character such as a Han
|
|
9
|
+
* ideograph. Hangul syllables keep words together, so Korean text breaks at spaces. A word
|
|
10
|
+
* longer than the row is broken between characters.
|
|
11
|
+
*
|
|
12
|
+
* A space that does not fit at the end of a row hangs past the edge, so a row never starts
|
|
13
|
+
* with the space that ended the word before it.
|
|
14
|
+
*/
|
|
15
|
+
export const wrapLine = (line, columns, mode) => {
|
|
16
|
+
const count = line.length;
|
|
17
|
+
if (mode === 'none' || count === 0 || line.cells <= columns) {
|
|
18
|
+
return [0];
|
|
19
|
+
}
|
|
20
|
+
const width = Math.max(1, columns);
|
|
21
|
+
const isWord = mode === 'word';
|
|
22
|
+
if (line.simple) {
|
|
23
|
+
return wrapAscii(line.text, width, isWord);
|
|
24
|
+
}
|
|
25
|
+
const rows = [0];
|
|
26
|
+
let rowStart = 0;
|
|
27
|
+
let rowCells = 0;
|
|
28
|
+
let breakIndex = -1;
|
|
29
|
+
for (let index = 0; index < count; index++) {
|
|
30
|
+
const clusterCells = widthAt(line, index);
|
|
31
|
+
const breakClass = breakAt(line, index);
|
|
32
|
+
if (isWord && index > rowStart) {
|
|
33
|
+
const previous = breakAt(line, index - 1);
|
|
34
|
+
if ((previous === BREAK_SPACE && breakClass !== BREAK_SPACE) ||
|
|
35
|
+
previous === BREAK_WIDE ||
|
|
36
|
+
breakClass === BREAK_WIDE) {
|
|
37
|
+
breakIndex = index;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (rowCells > 0 && rowCells + clusterCells > width) {
|
|
41
|
+
if (breakClass === BREAK_SPACE) {
|
|
42
|
+
rowCells += clusterCells;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const start = isWord && breakIndex > rowStart ? breakIndex : index;
|
|
46
|
+
rows.push(start);
|
|
47
|
+
rowStart = start;
|
|
48
|
+
rowCells = 0;
|
|
49
|
+
breakIndex = -1;
|
|
50
|
+
for (let cluster = start; cluster < index; cluster++) {
|
|
51
|
+
rowCells += widthAt(line, cluster);
|
|
52
|
+
}
|
|
53
|
+
// The carried-over part of a word can still leave no room for a wide character.
|
|
54
|
+
if (rowCells > 0 && rowCells + clusterCells > width) {
|
|
55
|
+
rows.push(index);
|
|
56
|
+
rowStart = index;
|
|
57
|
+
rowCells = 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
rowCells += clusterCells;
|
|
61
|
+
}
|
|
62
|
+
return rows;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* `wrapLine` for a line where every character is one cell and only spaces allow a break. It
|
|
66
|
+
* follows the same rules without looking up widths and break classes, which makes laying out
|
|
67
|
+
* a large plain-text log several times faster.
|
|
68
|
+
*/
|
|
69
|
+
const wrapAscii = (text, width, isWord) => {
|
|
70
|
+
const rows = [0];
|
|
71
|
+
const count = text.length;
|
|
72
|
+
let rowStart = 0;
|
|
73
|
+
let rowCells = 0;
|
|
74
|
+
let breakIndex = -1;
|
|
75
|
+
for (let index = 0; index < count; index++) {
|
|
76
|
+
const isSpace = text.charCodeAt(index) === 0x20;
|
|
77
|
+
if (isWord && index > rowStart && !isSpace && text.charCodeAt(index - 1) === 0x20) {
|
|
78
|
+
breakIndex = index;
|
|
79
|
+
}
|
|
80
|
+
if (rowCells > 0 && rowCells + 1 > width) {
|
|
81
|
+
if (isSpace) {
|
|
82
|
+
rowCells++;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const start = isWord && breakIndex > rowStart ? breakIndex : index;
|
|
86
|
+
rows.push(start);
|
|
87
|
+
rowStart = start;
|
|
88
|
+
rowCells = index - start;
|
|
89
|
+
breakIndex = -1;
|
|
90
|
+
}
|
|
91
|
+
rowCells++;
|
|
92
|
+
}
|
|
93
|
+
return rows;
|
|
94
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** How the timestamp of an entry is written. */
|
|
2
|
+
export type TimestampFormat = 'time' | 'datetime' | 'iso' | ((time: number) => string);
|
|
3
|
+
/**
|
|
4
|
+
* Formats an epoch time in local time.
|
|
5
|
+
*
|
|
6
|
+
* - `time`: `14:03:09.120`
|
|
7
|
+
* - `datetime`: `2026-09-13 14:03:09.120`
|
|
8
|
+
* - `iso`: `2026-09-13T05:03:09.120Z`, in UTC
|
|
9
|
+
*/
|
|
10
|
+
export declare const formatTimestamp: (time: number, format?: TimestampFormat) => string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const pad = (value, length = 2) => {
|
|
2
|
+
return String(value).padStart(length, '0');
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* Formats an epoch time in local time.
|
|
6
|
+
*
|
|
7
|
+
* - `time`: `14:03:09.120`
|
|
8
|
+
* - `datetime`: `2026-09-13 14:03:09.120`
|
|
9
|
+
* - `iso`: `2026-09-13T05:03:09.120Z`, in UTC
|
|
10
|
+
*/
|
|
11
|
+
export const formatTimestamp = (time, format = 'time') => {
|
|
12
|
+
if (typeof format === 'function') {
|
|
13
|
+
return format(time);
|
|
14
|
+
}
|
|
15
|
+
const date = new Date(time);
|
|
16
|
+
if (format === 'iso') {
|
|
17
|
+
return date.toISOString();
|
|
18
|
+
}
|
|
19
|
+
const clock = `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}.${pad(date.getMilliseconds(), 3)}`;
|
|
20
|
+
if (format === 'datetime') {
|
|
21
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${clock}`;
|
|
22
|
+
}
|
|
23
|
+
return clock;
|
|
24
|
+
};
|