color-name-list 13.1.0 → 13.2.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/README.md +48 -2
- package/changes.svg +3 -3
- package/dist/colornames.bestof.csv +6 -2
- package/dist/colornames.bestof.esm.js +1 -1
- package/dist/colornames.bestof.esm.mjs +1 -1
- package/dist/colornames.bestof.html +1 -1
- package/dist/colornames.bestof.json +1 -1
- package/dist/colornames.bestof.min.json +1 -1
- package/dist/colornames.bestof.scss +1 -1
- package/dist/colornames.bestof.umd.js +1 -1
- package/dist/colornames.bestof.xml +18 -2
- package/dist/colornames.bestof.yaml +14 -2
- package/dist/colornames.csv +9 -6
- package/dist/colornames.esm.js +1 -1
- package/dist/colornames.esm.mjs +1 -1
- package/dist/colornames.html +1 -1
- package/dist/colornames.json +1 -1
- package/dist/colornames.min.json +1 -1
- package/dist/colornames.scss +1 -1
- package/dist/colornames.short.csv +4 -2
- package/dist/colornames.short.esm.js +1 -1
- package/dist/colornames.short.esm.mjs +1 -1
- package/dist/colornames.short.html +1 -1
- package/dist/colornames.short.json +1 -1
- package/dist/colornames.short.min.json +1 -1
- package/dist/colornames.short.scss +1 -1
- package/dist/colornames.short.umd.js +1 -1
- package/dist/colornames.short.xml +10 -2
- package/dist/colornames.short.yaml +8 -2
- package/dist/colornames.umd.js +1 -1
- package/dist/colornames.xml +27 -15
- package/dist/colornames.yaml +21 -12
- package/dist/history.json +1 -1
- package/package.json +1 -1
- package/scripts/lib.js +2 -1
- package/src/colornames.csv +9 -6
- package/tests/duplicates.test.js +35 -16
- package/tests/title-case.test.js +82 -18
- package/vitest.config.js +5 -0
- /package/tests/{formats.test.js → formats.ci.test.js} +0 -0
- /package/tests/{imports.test.js → imports.ci.test.js} +0 -0
package/package.json
CHANGED
package/scripts/lib.js
CHANGED
|
@@ -160,7 +160,8 @@ export const findNearDuplicateNameConflicts = (items, options = {}) => {
|
|
|
160
160
|
.normalize('NFD')
|
|
161
161
|
.replace(/[\u0300-\u036f]/g, '');
|
|
162
162
|
const tokens = base.match(/[a-z0-9]+/g) || [];
|
|
163
|
-
const filtered =
|
|
163
|
+
const filtered =
|
|
164
|
+
foldStopwords && stopSet && stopSet.size ? tokens.filter((t) => !stopSet.has(t)) : tokens;
|
|
164
165
|
return filtered.length ? filtered.join('') : normalizeNameForDuplicates(name);
|
|
165
166
|
};
|
|
166
167
|
|
package/src/colornames.csv
CHANGED
|
@@ -215,8 +215,6 @@ Afternoon Stroll,#d9c5a1,
|
|
|
215
215
|
Afternoon Tea,#594e40,
|
|
216
216
|
Agapanthus,#bbc5de,
|
|
217
217
|
Agate Brown,#956a60,
|
|
218
|
-
Agate Green,#52928d,
|
|
219
|
-
Agate Grey,#acaa99,
|
|
220
218
|
Agate Violet,#5a5b74,
|
|
221
219
|
Agave,#879d99,
|
|
222
220
|
Agave Frond,#5a6e6a,
|
|
@@ -1014,7 +1012,7 @@ April Sunshine,#fbe198,
|
|
|
1014
1012
|
April Tears,#b4cbd4,
|
|
1015
1013
|
April Wedding,#c5cfb1,
|
|
1016
1014
|
April Winds,#d5e2e5,
|
|
1017
|
-
Aqua,#
|
|
1015
|
+
Aqua,#0ff0fe,x
|
|
1018
1016
|
Aqua Bay,#b5dfc9,
|
|
1019
1017
|
Aqua Belt,#7acad0,
|
|
1020
1018
|
Aqua Bloom,#96d3d8,
|
|
@@ -1923,6 +1921,7 @@ Barberry Bush,#d2c61f,
|
|
|
1923
1921
|
Barberry Sand,#e1d4bc,
|
|
1924
1922
|
Barberry Yellow,#f3bd32,
|
|
1925
1923
|
Barbie Pink,#fe46a5,
|
|
1924
|
+
Barbiecore,#e15acb,x
|
|
1926
1925
|
Barcelona Beige,#c4b39c,
|
|
1927
1926
|
Barcelona Brown,#926a46,
|
|
1928
1927
|
Barcelona Orange,#ff9500,
|
|
@@ -6975,7 +6974,7 @@ Cuticle Pink,#e3a49a,
|
|
|
6975
6974
|
Cutlery Polish,#f4dda5,
|
|
6976
6975
|
Cuttlefish,#7fbbc2,x
|
|
6977
6976
|
Cutty Sark,#5c8173,
|
|
6978
|
-
Cyan,#
|
|
6977
|
+
Cyan,#00ffff,x
|
|
6979
6978
|
Cyan Azure,#4e82b4,
|
|
6980
6979
|
Cyan Blue,#14a3c7,
|
|
6981
6980
|
Cyan Cobalt Blue,#28589c,
|
|
@@ -7792,6 +7791,7 @@ Dig It,#8e6e57,
|
|
|
7792
7791
|
Digger’s Gold,#a37336,
|
|
7793
7792
|
Digital,#636365,
|
|
7794
7793
|
Digital Garage,#b7b3a4,
|
|
7794
|
+
Digital Lavender,#cac0e1,x
|
|
7795
7795
|
Digital Violets,#aa00ff,
|
|
7796
7796
|
Digital Yellow,#ffeb7e,
|
|
7797
7797
|
Dignified,#3b695f,
|
|
@@ -10683,6 +10683,7 @@ Gemini,#b4d6cb,
|
|
|
10683
10683
|
Gemini Mustard Momento,#fca750,
|
|
10684
10684
|
Gemstone Blue,#004f6d,
|
|
10685
10685
|
Gemstone Green,#4b6331,
|
|
10686
|
+
Gen Z Yellow,#f4e386,
|
|
10686
10687
|
Generic Viridian,#007f66,
|
|
10687
10688
|
Genestealer Purple,#7761ab,
|
|
10688
10689
|
Genetic Code,#18515d,
|
|
@@ -11519,7 +11520,7 @@ Green,#00ff00,x
|
|
|
11519
11520
|
Green 383,#3e3d29,
|
|
11520
11521
|
Green Acres,#53a144,
|
|
11521
11522
|
Green Adirondack,#688878,
|
|
11522
|
-
Green Agate,#
|
|
11523
|
+
Green Agate,#52928d,
|
|
11523
11524
|
Green Alabaster,#c8ccba,
|
|
11524
11525
|
Green Amazons,#98a893,
|
|
11525
11526
|
Green Andara,#afc1a3,
|
|
@@ -11672,6 +11673,7 @@ Green Olive,#8d8b55,x
|
|
|
11672
11673
|
Green Olive Pit,#bdaa89,
|
|
11673
11674
|
Green Onion,#c1e089,
|
|
11674
11675
|
Green Onyx,#989a82,
|
|
11676
|
+
Green Ooze,#e1fe52,x
|
|
11675
11677
|
Green Papaya,#e5ce77,
|
|
11676
11678
|
Green Parakeet,#7bd5bf,
|
|
11677
11679
|
Green Parlor,#cfddb9,
|
|
@@ -15186,7 +15188,6 @@ Lima Green,#b1b787,
|
|
|
15186
15188
|
Lima Sombrio,#7aac21,
|
|
15187
15189
|
Limbert Leather,#988870,
|
|
15188
15190
|
Lime,#aaff32,x
|
|
15189
|
-
Lime Acid,#afff01,
|
|
15190
15191
|
Lime Blossom,#f4f2d3,
|
|
15191
15192
|
Lime Bright,#f1e4b0,
|
|
15192
15193
|
Lime Cake,#dae3d0,
|
|
@@ -16808,6 +16809,7 @@ Milky Yellow,#f8dd74,
|
|
|
16808
16809
|
Mill Creek,#876e59,
|
|
16809
16810
|
Millbrook,#595648,
|
|
16810
16811
|
Mille-Feuille,#efc87d,x
|
|
16812
|
+
Millennial Grey,#7b7b7d,
|
|
16811
16813
|
Millennial Pink,#f6c8c1,x
|
|
16812
16814
|
Millennium Silver,#8c9595,
|
|
16813
16815
|
Million Grey,#999999,x
|
|
@@ -20832,6 +20834,7 @@ Popular Beige,#d4ccc3,
|
|
|
20832
20834
|
Porcelain,#dddcdb,x
|
|
20833
20835
|
Porcelain Basin,#d9d0c4,
|
|
20834
20836
|
Porcelain Blue,#95c0cb,
|
|
20837
|
+
Porcelain Blush,#f0dbd5,x
|
|
20835
20838
|
Porcelain Crab,#e9b7a8,
|
|
20836
20839
|
Porcelain Earth,#eeffbb,
|
|
20837
20840
|
Porcelain Figurines,#a9998c,
|
package/tests/duplicates.test.js
CHANGED
|
@@ -13,20 +13,41 @@ describe('Duplicate-like color names', () => {
|
|
|
13
13
|
|
|
14
14
|
// Shared stopwords for normalization across tests
|
|
15
15
|
const STOPWORDS = [
|
|
16
|
-
'of',
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
16
|
+
'of',
|
|
17
|
+
'the',
|
|
18
|
+
'and',
|
|
19
|
+
'a',
|
|
20
|
+
'an',
|
|
21
|
+
'in',
|
|
22
|
+
'on',
|
|
23
|
+
'at',
|
|
24
|
+
'to',
|
|
25
|
+
'for',
|
|
26
|
+
'by',
|
|
27
|
+
'with',
|
|
28
|
+
'from',
|
|
29
|
+
'as',
|
|
30
|
+
'is',
|
|
31
|
+
'it',
|
|
32
|
+
'this',
|
|
33
|
+
'that',
|
|
34
|
+
'these',
|
|
35
|
+
'those',
|
|
36
|
+
'be',
|
|
37
|
+
'are',
|
|
38
|
+
'was',
|
|
39
|
+
'were',
|
|
40
|
+
'or',
|
|
21
41
|
];
|
|
22
42
|
|
|
23
43
|
// Helper: normalize a phrase similar to scripts/lib normalization but keeping token boundaries
|
|
24
|
-
const normalize = (s) =>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
44
|
+
const normalize = (s) =>
|
|
45
|
+
String(s)
|
|
46
|
+
.toLowerCase()
|
|
47
|
+
.normalize('NFD')
|
|
48
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
49
|
+
.replace(/[^a-z0-9]+/g, ' ')
|
|
50
|
+
.trim();
|
|
30
51
|
|
|
31
52
|
const tokenize = (name) => {
|
|
32
53
|
const base = normalize(name);
|
|
@@ -157,7 +178,8 @@ describe('Duplicate-like color names', () => {
|
|
|
157
178
|
|
|
158
179
|
throw new Error(
|
|
159
180
|
buildFailureMessage({
|
|
160
|
-
title:
|
|
181
|
+
title:
|
|
182
|
+
'Found {n} duplicate-like {items} (case/accents/punctuation/stopwords-insensitive):',
|
|
161
183
|
offenders: [...allOffendingNames],
|
|
162
184
|
offenderLabel: 'name',
|
|
163
185
|
details: [
|
|
@@ -218,10 +240,7 @@ describe('Duplicate-like color names', () => {
|
|
|
218
240
|
});
|
|
219
241
|
|
|
220
242
|
it('should detect names that only differ by stopwords when enabled', () => {
|
|
221
|
-
const items = [
|
|
222
|
-
{ name: 'Heart Gold' },
|
|
223
|
-
{ name: 'Heart of Gold' },
|
|
224
|
-
];
|
|
243
|
+
const items = [{ name: 'Heart Gold' }, { name: 'Heart of Gold' }];
|
|
225
244
|
const conflicts = findNearDuplicateNameConflicts(items, {
|
|
226
245
|
foldStopwords: true,
|
|
227
246
|
stopwords: STOPWORDS,
|
package/tests/title-case.test.js
CHANGED
|
@@ -8,7 +8,7 @@ describe('APA Title Case Validation', () => {
|
|
|
8
8
|
csvTestData.load();
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
12
|
* Determine if a word should be capitalized according to APA title case rules
|
|
13
13
|
* @param {string} word - The word to check
|
|
14
14
|
* @param {boolean} isFirstWordOrAfterPunctuation - True if this is the first word or after punctuation
|
|
@@ -16,7 +16,12 @@ describe('APA Title Case Validation', () => {
|
|
|
16
16
|
* @param {boolean} isLastWord - True if this is the last word in the title
|
|
17
17
|
* @returns {boolean} - True if the word should be capitalized
|
|
18
18
|
*/
|
|
19
|
-
function shouldBeCapitalized(
|
|
19
|
+
function shouldBeCapitalized(
|
|
20
|
+
word,
|
|
21
|
+
isFirstWordOrAfterPunctuation,
|
|
22
|
+
isAfterPunctuation,
|
|
23
|
+
isLastWord = false
|
|
24
|
+
) {
|
|
20
25
|
// Always capitalize first words, words after punctuation, and last words
|
|
21
26
|
if (isFirstWordOrAfterPunctuation || isAfterPunctuation || isLastWord) {
|
|
22
27
|
return true;
|
|
@@ -30,13 +35,44 @@ describe('APA Title Case Validation', () => {
|
|
|
30
35
|
// Short words (3 letters or fewer) that should be lowercase (unless first, after punctuation, or last)
|
|
31
36
|
const minorWords = new Set([
|
|
32
37
|
// Short conjunctions
|
|
33
|
-
'and',
|
|
38
|
+
'and',
|
|
39
|
+
'as',
|
|
40
|
+
'but',
|
|
41
|
+
'for',
|
|
42
|
+
'if',
|
|
43
|
+
'nor',
|
|
44
|
+
'or',
|
|
45
|
+
'so',
|
|
46
|
+
'yet',
|
|
34
47
|
// Articles
|
|
35
|
-
'a',
|
|
48
|
+
'a',
|
|
49
|
+
'an',
|
|
50
|
+
'the',
|
|
36
51
|
// Short prepositions
|
|
37
|
-
'at',
|
|
52
|
+
'at',
|
|
53
|
+
'by',
|
|
54
|
+
'in',
|
|
55
|
+
'of',
|
|
56
|
+
'off',
|
|
57
|
+
'on',
|
|
58
|
+
'per',
|
|
59
|
+
'to',
|
|
60
|
+
'up',
|
|
61
|
+
'via',
|
|
38
62
|
// for short prepositions
|
|
39
|
-
'de',
|
|
63
|
+
'de',
|
|
64
|
+
'la',
|
|
65
|
+
'le',
|
|
66
|
+
'les',
|
|
67
|
+
'un',
|
|
68
|
+
'une',
|
|
69
|
+
'du',
|
|
70
|
+
'des',
|
|
71
|
+
'et',
|
|
72
|
+
'ou',
|
|
73
|
+
'à',
|
|
74
|
+
'au',
|
|
75
|
+
'aux',
|
|
40
76
|
]);
|
|
41
77
|
|
|
42
78
|
return !minorWords.has(word.toLowerCase());
|
|
@@ -147,12 +183,22 @@ describe('APA Title Case Validation', () => {
|
|
|
147
183
|
|
|
148
184
|
// Patterns that suggest Los Angeles context
|
|
149
185
|
const losAngelesIndicators = [
|
|
150
|
-
'vibes',
|
|
151
|
-
'
|
|
186
|
+
'vibes',
|
|
187
|
+
'style',
|
|
188
|
+
'sunset',
|
|
189
|
+
'beach',
|
|
190
|
+
'hollywood',
|
|
191
|
+
'california',
|
|
192
|
+
'west coast',
|
|
193
|
+
'city',
|
|
194
|
+
'metro',
|
|
195
|
+
'downtown',
|
|
196
|
+
'freeway',
|
|
197
|
+
'boulevard',
|
|
152
198
|
];
|
|
153
199
|
|
|
154
200
|
// If the name contains any LA indicators, treat "la" as Los Angeles
|
|
155
|
-
if (losAngelesIndicators.some(indicator => lowerName.includes(indicator))) {
|
|
201
|
+
if (losAngelesIndicators.some((indicator) => lowerName.includes(indicator))) {
|
|
156
202
|
return true;
|
|
157
203
|
}
|
|
158
204
|
|
|
@@ -160,7 +206,7 @@ describe('APA Title Case Validation', () => {
|
|
|
160
206
|
const nextWord = words[wordIndex + 2]; // +2 to skip whitespace
|
|
161
207
|
if (nextWord) {
|
|
162
208
|
const nonFrenchPatterns = ['vibes', 'style', 'sunset', 'beach'];
|
|
163
|
-
if (nonFrenchPatterns.some(pattern => nextWord.toLowerCase().includes(pattern))) {
|
|
209
|
+
if (nonFrenchPatterns.some((pattern) => nextWord.toLowerCase().includes(pattern))) {
|
|
164
210
|
return true;
|
|
165
211
|
}
|
|
166
212
|
}
|
|
@@ -187,8 +233,8 @@ describe('APA Title Case Validation', () => {
|
|
|
187
233
|
|
|
188
234
|
// Check for alphanumeric patterns that should stay uppercase (like model numbers)
|
|
189
235
|
// Exclude ordinal numbers (1st, 2nd, 3rd, 18th, etc.)
|
|
190
|
-
const isAlphanumericPattern =
|
|
191
|
-
!/^\d+(st|nd|rd|th)$/i.test(segment);
|
|
236
|
+
const isAlphanumericPattern =
|
|
237
|
+
/^[0-9]+[A-Z]+$/i.test(segment) && !/^\d+(st|nd|rd|th)$/i.test(segment);
|
|
192
238
|
|
|
193
239
|
// Handle hyphenated words - both parts should follow title case rules
|
|
194
240
|
if (segment.includes('-')) {
|
|
@@ -219,11 +265,20 @@ describe('APA Title Case Validation', () => {
|
|
|
219
265
|
|
|
220
266
|
// Check if this is the last part of the last word in the title
|
|
221
267
|
const isLastPart = partIndex === parts.length - 1;
|
|
222
|
-
const isLastWordInTitle =
|
|
268
|
+
const isLastWordInTitle =
|
|
269
|
+
i === words.length - 1 ||
|
|
270
|
+
(i === words.length - 2 && /^\s+$/.test(words[words.length - 1]));
|
|
223
271
|
const isLastWord = isLastPart && isLastWordInTitle;
|
|
224
272
|
|
|
225
|
-
const shouldCap = shouldBeCapitalized(
|
|
226
|
-
|
|
273
|
+
const shouldCap = shouldBeCapitalized(
|
|
274
|
+
part,
|
|
275
|
+
isFirstWord || partIndex > 0,
|
|
276
|
+
isAfterPunctuation,
|
|
277
|
+
isLastWord
|
|
278
|
+
);
|
|
279
|
+
return shouldCap
|
|
280
|
+
? part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()
|
|
281
|
+
: part.toLowerCase();
|
|
227
282
|
});
|
|
228
283
|
result += capitalizedParts.join('-');
|
|
229
284
|
} else {
|
|
@@ -242,9 +297,18 @@ describe('APA Title Case Validation', () => {
|
|
|
242
297
|
result += 'LA';
|
|
243
298
|
} else {
|
|
244
299
|
// Regular word - check if this is the last non-whitespace word
|
|
245
|
-
const isLastWordInTitle =
|
|
246
|
-
|
|
247
|
-
|
|
300
|
+
const isLastWordInTitle =
|
|
301
|
+
i === words.length - 1 ||
|
|
302
|
+
(i === words.length - 2 && /^\s+$/.test(words[words.length - 1]));
|
|
303
|
+
const shouldCap = shouldBeCapitalized(
|
|
304
|
+
segment,
|
|
305
|
+
isFirstWord,
|
|
306
|
+
isAfterPunctuation,
|
|
307
|
+
isLastWordInTitle
|
|
308
|
+
);
|
|
309
|
+
result += shouldCap
|
|
310
|
+
? segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()
|
|
311
|
+
: segment.toLowerCase();
|
|
248
312
|
}
|
|
249
313
|
}
|
|
250
314
|
|
package/vitest.config.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { defineConfig } from 'vitest/config';
|
|
2
2
|
|
|
3
|
+
// Only run heavy/dist-dependent tests in CI
|
|
4
|
+
const isCI = !!process.env.CI;
|
|
5
|
+
|
|
3
6
|
export default defineConfig({
|
|
4
7
|
test: {
|
|
5
8
|
include: ['tests/**/*.test.js'],
|
|
9
|
+
// Exclude CI-only tests locally. GitHub Actions sets CI=true, so these will run in CI.
|
|
10
|
+
exclude: isCI ? [] : ['tests/*.ci.test.js'],
|
|
6
11
|
environment: 'node',
|
|
7
12
|
},
|
|
8
13
|
});
|
|
File without changes
|
|
File without changes
|