@xivdyetools/core 1.3.7
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 +37 -0
- package/README.md +400 -0
- package/dist/constants/index.d.ts +56 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +103 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/data/colors_xiv.json +3130 -0
- package/dist/data/locales/de.json +231 -0
- package/dist/data/locales/en.json +231 -0
- package/dist/data/locales/fr.json +231 -0
- package/dist/data/locales/ja.json +231 -0
- package/dist/data/locales/ko.json +233 -0
- package/dist/data/locales/zh.json +233 -0
- package/dist/data/presets.json +390 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/services/APIService.d.ts +246 -0
- package/dist/services/APIService.d.ts.map +1 -0
- package/dist/services/APIService.js +499 -0
- package/dist/services/APIService.js.map +1 -0
- package/dist/services/ColorService.d.ts +146 -0
- package/dist/services/ColorService.d.ts.map +1 -0
- package/dist/services/ColorService.js +209 -0
- package/dist/services/ColorService.js.map +1 -0
- package/dist/services/DyeService.d.ts +230 -0
- package/dist/services/DyeService.d.ts.map +1 -0
- package/dist/services/DyeService.js +326 -0
- package/dist/services/DyeService.js.map +1 -0
- package/dist/services/LocalizationService.d.ts +338 -0
- package/dist/services/LocalizationService.d.ts.map +1 -0
- package/dist/services/LocalizationService.js +449 -0
- package/dist/services/LocalizationService.js.map +1 -0
- package/dist/services/PaletteService.d.ts +137 -0
- package/dist/services/PaletteService.d.ts.map +1 -0
- package/dist/services/PaletteService.js +349 -0
- package/dist/services/PaletteService.js.map +1 -0
- package/dist/services/PresetService.d.ts +196 -0
- package/dist/services/PresetService.d.ts.map +1 -0
- package/dist/services/PresetService.js +261 -0
- package/dist/services/PresetService.js.map +1 -0
- package/dist/services/color/ColorAccessibility.d.ts +39 -0
- package/dist/services/color/ColorAccessibility.d.ts.map +1 -0
- package/dist/services/color/ColorAccessibility.js +71 -0
- package/dist/services/color/ColorAccessibility.js.map +1 -0
- package/dist/services/color/ColorConverter.d.ts +146 -0
- package/dist/services/color/ColorConverter.d.ts.map +1 -0
- package/dist/services/color/ColorConverter.js +393 -0
- package/dist/services/color/ColorConverter.js.map +1 -0
- package/dist/services/color/ColorManipulator.d.ts +36 -0
- package/dist/services/color/ColorManipulator.d.ts.map +1 -0
- package/dist/services/color/ColorManipulator.js +56 -0
- package/dist/services/color/ColorManipulator.js.map +1 -0
- package/dist/services/color/ColorblindnessSimulator.d.ts +35 -0
- package/dist/services/color/ColorblindnessSimulator.d.ts.map +1 -0
- package/dist/services/color/ColorblindnessSimulator.js +110 -0
- package/dist/services/color/ColorblindnessSimulator.js.map +1 -0
- package/dist/services/dye/DyeDatabase.d.ts +131 -0
- package/dist/services/dye/DyeDatabase.d.ts.map +1 -0
- package/dist/services/dye/DyeDatabase.js +367 -0
- package/dist/services/dye/DyeDatabase.js.map +1 -0
- package/dist/services/dye/DyeSearch.d.ts +55 -0
- package/dist/services/dye/DyeSearch.d.ts.map +1 -0
- package/dist/services/dye/DyeSearch.js +196 -0
- package/dist/services/dye/DyeSearch.js.map +1 -0
- package/dist/services/dye/HarmonyGenerator.d.ts +110 -0
- package/dist/services/dye/HarmonyGenerator.d.ts.map +1 -0
- package/dist/services/dye/HarmonyGenerator.js +221 -0
- package/dist/services/dye/HarmonyGenerator.js.map +1 -0
- package/dist/services/localization/LocaleLoader.d.ts +38 -0
- package/dist/services/localization/LocaleLoader.d.ts.map +1 -0
- package/dist/services/localization/LocaleLoader.js +83 -0
- package/dist/services/localization/LocaleLoader.js.map +1 -0
- package/dist/services/localization/LocaleRegistry.d.ts +73 -0
- package/dist/services/localization/LocaleRegistry.d.ts.map +1 -0
- package/dist/services/localization/LocaleRegistry.js +84 -0
- package/dist/services/localization/LocaleRegistry.js.map +1 -0
- package/dist/services/localization/TranslationProvider.d.ts +157 -0
- package/dist/services/localization/TranslationProvider.d.ts.map +1 -0
- package/dist/services/localization/TranslationProvider.js +289 -0
- package/dist/services/localization/TranslationProvider.js.map +1 -0
- package/dist/types/index.d.ts +409 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +87 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/logger.d.ts +84 -0
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/logger.js +54 -0
- package/dist/types/logger.js.map +1 -0
- package/dist/utils/index.d.ts +441 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +577 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/kd-tree.d.ts +76 -0
- package/dist/utils/kd-tree.d.ts.map +1 -0
- package/dist/utils/kd-tree.js +195 -0
- package/dist/utils/kd-tree.js.map +1 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @xivdyetools/core - Preset Service
|
|
3
|
+
*
|
|
4
|
+
* Manages preset color palettes for FFXIV glamours.
|
|
5
|
+
* Provides themed color combinations for jobs, seasons, events, and aesthetics.
|
|
6
|
+
*
|
|
7
|
+
* @module services/PresetService
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { PresetService, presetData, DyeService, dyeDatabase } from '@xivdyetools/core';
|
|
11
|
+
*
|
|
12
|
+
* const presetService = new PresetService(presetData);
|
|
13
|
+
* const dyeService = new DyeService(dyeDatabase);
|
|
14
|
+
*
|
|
15
|
+
* // Get all job presets
|
|
16
|
+
* const jobPresets = presetService.getPresetsByCategory('jobs');
|
|
17
|
+
*
|
|
18
|
+
* // Get a preset with resolved dye objects
|
|
19
|
+
* const rdmPreset = presetService.getPresetWithDyes('job-rdm', dyeService);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Service for managing preset color palettes
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const presetService = new PresetService(presetData);
|
|
28
|
+
*
|
|
29
|
+
* // List categories
|
|
30
|
+
* const categories = presetService.getCategories();
|
|
31
|
+
*
|
|
32
|
+
* // Get presets by category
|
|
33
|
+
* const jobPresets = presetService.getPresetsByCategory('jobs');
|
|
34
|
+
*
|
|
35
|
+
* // Search presets
|
|
36
|
+
* const results = presetService.searchPresets('red');
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class PresetService {
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the preset service with preset data
|
|
42
|
+
* @param presetData - Preset data object (import from presets.json)
|
|
43
|
+
*/
|
|
44
|
+
constructor(presetData) {
|
|
45
|
+
this.data = presetData;
|
|
46
|
+
// Build lookup map for O(1) access by ID
|
|
47
|
+
this.presetById = new Map(this.data.palettes.map((p) => [p.id, p]));
|
|
48
|
+
}
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Category Operations
|
|
51
|
+
// ============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Get all preset categories with metadata
|
|
54
|
+
* @returns Array of category metadata with IDs
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const categories = presetService.getCategories();
|
|
59
|
+
* // [{ id: 'jobs', name: 'FFXIV Jobs', description: '...', icon: '⚔️' }, ...]
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
getCategories() {
|
|
63
|
+
return Object.entries(this.data.categories).map(([id, meta]) => ({
|
|
64
|
+
id,
|
|
65
|
+
...meta,
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get metadata for a specific category
|
|
70
|
+
* @param category - Category identifier
|
|
71
|
+
* @returns Category metadata or undefined if not found
|
|
72
|
+
*/
|
|
73
|
+
getCategoryMeta(category) {
|
|
74
|
+
return this.data.categories[category];
|
|
75
|
+
}
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// Preset Retrieval
|
|
78
|
+
// ============================================================================
|
|
79
|
+
/**
|
|
80
|
+
* Get all presets
|
|
81
|
+
* @returns Array of all preset palettes
|
|
82
|
+
*/
|
|
83
|
+
getAllPresets() {
|
|
84
|
+
return [...this.data.palettes];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get all presets in a specific category
|
|
88
|
+
* @param category - Category to filter by
|
|
89
|
+
* @returns Array of presets in that category
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const jobPresets = presetService.getPresetsByCategory('jobs');
|
|
94
|
+
* // Returns all job-themed presets (RDM, BLM, WHM, etc.)
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
getPresetsByCategory(category) {
|
|
98
|
+
return this.data.palettes.filter((p) => p.category === category);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get a specific preset by ID
|
|
102
|
+
* @param id - Preset identifier (e.g., "job-rdm")
|
|
103
|
+
* @returns Preset or undefined if not found
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const rdm = presetService.getPreset('job-rdm');
|
|
108
|
+
* if (rdm) {
|
|
109
|
+
* console.log(rdm.name); // "Red Mage"
|
|
110
|
+
* console.log(rdm.dyes); // [5738, 13115, 13117, 5729]
|
|
111
|
+
* }
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
getPreset(id) {
|
|
115
|
+
return this.presetById.get(id);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get preset count by category
|
|
119
|
+
* @returns Map of category to preset count
|
|
120
|
+
*/
|
|
121
|
+
getPresetCountByCategory() {
|
|
122
|
+
const counts = new Map();
|
|
123
|
+
for (const preset of this.data.palettes) {
|
|
124
|
+
counts.set(preset.category, (counts.get(preset.category) ?? 0) + 1);
|
|
125
|
+
}
|
|
126
|
+
return counts;
|
|
127
|
+
}
|
|
128
|
+
// ============================================================================
|
|
129
|
+
// Search Operations
|
|
130
|
+
// ============================================================================
|
|
131
|
+
/**
|
|
132
|
+
* Search presets by name or tags
|
|
133
|
+
* @param query - Search query (case-insensitive)
|
|
134
|
+
* @returns Array of matching presets
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* // Search by name
|
|
139
|
+
* const results = presetService.searchPresets('red');
|
|
140
|
+
* // Returns: Red Mage, Blood Red themed presets, etc.
|
|
141
|
+
*
|
|
142
|
+
* // Search by tag
|
|
143
|
+
* const tankResults = presetService.searchPresets('tank');
|
|
144
|
+
* // Returns: Paladin, Warrior, Dark Knight, Gunbreaker
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
searchPresets(query) {
|
|
148
|
+
const lowerQuery = query.toLowerCase().trim();
|
|
149
|
+
if (!lowerQuery) {
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
152
|
+
return this.data.palettes.filter((p) => p.name.toLowerCase().includes(lowerQuery) ||
|
|
153
|
+
p.description.toLowerCase().includes(lowerQuery) ||
|
|
154
|
+
p.tags.some((tag) => tag.toLowerCase().includes(lowerQuery)));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Search presets by tag (exact match)
|
|
158
|
+
* @param tag - Tag to search for (case-insensitive)
|
|
159
|
+
* @returns Array of presets with that tag
|
|
160
|
+
*/
|
|
161
|
+
getPresetsByTag(tag) {
|
|
162
|
+
const lowerTag = tag.toLowerCase().trim();
|
|
163
|
+
return this.data.palettes.filter((p) => p.tags.some((t) => t.toLowerCase() === lowerTag));
|
|
164
|
+
}
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// Random Selection
|
|
167
|
+
// ============================================================================
|
|
168
|
+
/**
|
|
169
|
+
* Get a random preset, optionally filtered by category
|
|
170
|
+
* @param category - Optional category to filter by
|
|
171
|
+
* @returns Random preset, or undefined if no presets exist
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* // Random from all presets
|
|
176
|
+
* const random = presetService.getRandomPreset();
|
|
177
|
+
*
|
|
178
|
+
* // Random job preset
|
|
179
|
+
* const randomJob = presetService.getRandomPreset('jobs');
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
getRandomPreset(category) {
|
|
183
|
+
const pool = category ? this.getPresetsByCategory(category) : this.data.palettes;
|
|
184
|
+
if (pool.length === 0) {
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
return pool[Math.floor(Math.random() * pool.length)];
|
|
188
|
+
}
|
|
189
|
+
// ============================================================================
|
|
190
|
+
// Dye Resolution (requires DyeService)
|
|
191
|
+
// ============================================================================
|
|
192
|
+
/**
|
|
193
|
+
* Get preset with resolved Dye objects
|
|
194
|
+
* Requires a DyeService instance to resolve dye IDs to full Dye objects
|
|
195
|
+
*
|
|
196
|
+
* @param id - Preset identifier
|
|
197
|
+
* @param dyeService - DyeService instance for resolving dye IDs
|
|
198
|
+
* @returns Resolved preset with full Dye objects, or undefined if preset not found
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```typescript
|
|
202
|
+
* const dyeService = new DyeService(dyeDatabase);
|
|
203
|
+
* const resolved = presetService.getPresetWithDyes('job-rdm', dyeService);
|
|
204
|
+
*
|
|
205
|
+
* if (resolved) {
|
|
206
|
+
* resolved.resolvedDyes.forEach(dye => {
|
|
207
|
+
* if (dye) {
|
|
208
|
+
* console.log(`${dye.name}: ${dye.hex}`);
|
|
209
|
+
* }
|
|
210
|
+
* });
|
|
211
|
+
* }
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
getPresetWithDyes(id, dyeService) {
|
|
215
|
+
const preset = this.getPreset(id);
|
|
216
|
+
if (!preset) {
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
...preset,
|
|
221
|
+
resolvedDyes: preset.dyes.map((dyeId) => dyeService.getDyeById(dyeId)),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Resolve multiple presets with their Dye objects
|
|
226
|
+
* @param presets - Array of presets to resolve
|
|
227
|
+
* @param dyeService - DyeService instance for resolving dye IDs
|
|
228
|
+
* @returns Array of resolved presets
|
|
229
|
+
*/
|
|
230
|
+
resolvePresets(presets, dyeService) {
|
|
231
|
+
return presets.map((preset) => ({
|
|
232
|
+
...preset,
|
|
233
|
+
resolvedDyes: preset.dyes.map((dyeId) => dyeService.getDyeById(dyeId)),
|
|
234
|
+
}));
|
|
235
|
+
}
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// Metadata
|
|
238
|
+
// ============================================================================
|
|
239
|
+
/**
|
|
240
|
+
* Get data version
|
|
241
|
+
* @returns Version string from preset data
|
|
242
|
+
*/
|
|
243
|
+
getVersion() {
|
|
244
|
+
return this.data.version;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get last update timestamp
|
|
248
|
+
* @returns ISO date string of last update
|
|
249
|
+
*/
|
|
250
|
+
getLastUpdated() {
|
|
251
|
+
return this.data.lastUpdated;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get total number of presets
|
|
255
|
+
* @returns Total preset count
|
|
256
|
+
*/
|
|
257
|
+
getPresetCount() {
|
|
258
|
+
return this.data.palettes.length;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=PresetService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PresetService.js","sourceRoot":"","sources":["../../src/services/PresetService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color Accessibility
|
|
3
|
+
* Per R-4: Focused class for accessibility-related color operations
|
|
4
|
+
* Handles WCAG contrast, luminance, and text color optimization
|
|
5
|
+
*/
|
|
6
|
+
import type { HexColor } from '../../types/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Color accessibility utilities
|
|
9
|
+
* Per R-4: Single Responsibility - accessibility operations only
|
|
10
|
+
*/
|
|
11
|
+
export declare class ColorAccessibility {
|
|
12
|
+
/**
|
|
13
|
+
* Calculate perceived luminance of a color (0-1)
|
|
14
|
+
* Uses relative luminance formula from WCAG
|
|
15
|
+
*/
|
|
16
|
+
static getPerceivedLuminance(hex: string): number;
|
|
17
|
+
/**
|
|
18
|
+
* Calculate contrast ratio between two colors
|
|
19
|
+
* Returns 1 (no contrast) to 21 (maximum contrast)
|
|
20
|
+
*/
|
|
21
|
+
static getContrastRatio(hex1: string, hex2: string): number;
|
|
22
|
+
/**
|
|
23
|
+
* Check if two colors meet WCAG AA contrast ratio (4.5:1 for small text, 3:1 for large)
|
|
24
|
+
*/
|
|
25
|
+
static meetsWCAGAA(hex1: string, hex2: string, largeText?: boolean): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Check if two colors meet WCAG AAA contrast ratio (7:1 for small text, 4.5:1 for large)
|
|
28
|
+
*/
|
|
29
|
+
static meetsWCAGAAA(hex1: string, hex2: string, largeText?: boolean): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Check if a color is light (for determining text color on background)
|
|
32
|
+
*/
|
|
33
|
+
static isLightColor(hex: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Get optimal text color for a background color
|
|
36
|
+
*/
|
|
37
|
+
static getOptimalTextColor(backgroundColor: string): HexColor;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=ColorAccessibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorAccessibility.d.ts","sourceRoot":"","sources":["../../../src/services/color/ColorAccessibility.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B;;;OAGG;IACH,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAiBjD;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAU3D;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,OAAe,GAAG,OAAO;IAKnF;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,OAAe,GAAG,OAAO;IAKpF;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAKzC;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ;CAK9D"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color Accessibility
|
|
3
|
+
* Per R-4: Focused class for accessibility-related color operations
|
|
4
|
+
* Handles WCAG contrast, luminance, and text color optimization
|
|
5
|
+
*/
|
|
6
|
+
import { createHexColor } from '../../types/index.js';
|
|
7
|
+
import { ColorConverter } from './ColorConverter.js';
|
|
8
|
+
/**
|
|
9
|
+
* Color accessibility utilities
|
|
10
|
+
* Per R-4: Single Responsibility - accessibility operations only
|
|
11
|
+
*/
|
|
12
|
+
export class ColorAccessibility {
|
|
13
|
+
/**
|
|
14
|
+
* Calculate perceived luminance of a color (0-1)
|
|
15
|
+
* Uses relative luminance formula from WCAG
|
|
16
|
+
*/
|
|
17
|
+
static getPerceivedLuminance(hex) {
|
|
18
|
+
const rgb = ColorConverter.hexToRgb(hex);
|
|
19
|
+
// Convert to sRGB (linear RGB)
|
|
20
|
+
const toLinear = (c) => {
|
|
21
|
+
const cNorm = c / 255;
|
|
22
|
+
return cNorm <= 0.03928 ? cNorm / 12.92 : Math.pow((cNorm + 0.055) / 1.055, 2.4);
|
|
23
|
+
};
|
|
24
|
+
const r = toLinear(rgb.r);
|
|
25
|
+
const g = toLinear(rgb.g);
|
|
26
|
+
const b = toLinear(rgb.b);
|
|
27
|
+
// WCAG relative luminance formula
|
|
28
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Calculate contrast ratio between two colors
|
|
32
|
+
* Returns 1 (no contrast) to 21 (maximum contrast)
|
|
33
|
+
*/
|
|
34
|
+
static getContrastRatio(hex1, hex2) {
|
|
35
|
+
const lum1 = this.getPerceivedLuminance(hex1);
|
|
36
|
+
const lum2 = this.getPerceivedLuminance(hex2);
|
|
37
|
+
const lighter = Math.max(lum1, lum2);
|
|
38
|
+
const darker = Math.min(lum1, lum2);
|
|
39
|
+
return (lighter + 0.05) / (darker + 0.05);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if two colors meet WCAG AA contrast ratio (4.5:1 for small text, 3:1 for large)
|
|
43
|
+
*/
|
|
44
|
+
static meetsWCAGAA(hex1, hex2, largeText = false) {
|
|
45
|
+
const ratio = this.getContrastRatio(hex1, hex2);
|
|
46
|
+
return ratio >= (largeText ? 3 : 4.5);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if two colors meet WCAG AAA contrast ratio (7:1 for small text, 4.5:1 for large)
|
|
50
|
+
*/
|
|
51
|
+
static meetsWCAGAAA(hex1, hex2, largeText = false) {
|
|
52
|
+
const ratio = this.getContrastRatio(hex1, hex2);
|
|
53
|
+
return ratio >= (largeText ? 4.5 : 7);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if a color is light (for determining text color on background)
|
|
57
|
+
*/
|
|
58
|
+
static isLightColor(hex) {
|
|
59
|
+
const luminance = this.getPerceivedLuminance(hex);
|
|
60
|
+
return luminance > 0.5;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get optimal text color for a background color
|
|
64
|
+
*/
|
|
65
|
+
static getOptimalTextColor(backgroundColor) {
|
|
66
|
+
return this.isLightColor(backgroundColor)
|
|
67
|
+
? createHexColor('#000000')
|
|
68
|
+
: createHexColor('#FFFFFF');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=ColorAccessibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorAccessibility.js","sourceRoot":"","sources":["../../../src/services/color/ColorAccessibility.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IAC7B;;;OAGG;IACH,MAAM,CAAC,qBAAqB,CAAC,GAAW;QACtC,MAAM,GAAG,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAEzC,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAU,EAAE;YACrC,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC;YACtB,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC;QACnF,CAAC,CAAC;QAEF,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAE1B,kCAAkC;QAClC,OAAO,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAY,EAAE,IAAY;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAE9C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEpC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAY,EAAE,IAAY,EAAE,YAAqB,KAAK;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAY,EAAE,IAAY,EAAE,YAAqB,KAAK;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,GAAW;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAClD,OAAO,SAAS,GAAG,GAAG,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,eAAuB;QAChD,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC;YACvC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC;YAC3B,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color Converter
|
|
3
|
+
* Per R-4: Focused class for color format conversions
|
|
4
|
+
* Handles conversions between hex, RGB, and HSV color formats
|
|
5
|
+
*/
|
|
6
|
+
import type { RGB, HSV, HexColor } from '../../types/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for ColorConverter caches
|
|
9
|
+
*/
|
|
10
|
+
export interface ColorConverterConfig {
|
|
11
|
+
cacheSize?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Color format converter with LRU caching
|
|
15
|
+
* Per R-4: Single Responsibility - format conversions only
|
|
16
|
+
*
|
|
17
|
+
* Refactored for testability: Supports dependency injection of cache configuration
|
|
18
|
+
*/
|
|
19
|
+
export declare class ColorConverter {
|
|
20
|
+
private readonly hexToRgbCache;
|
|
21
|
+
private readonly rgbToHexCache;
|
|
22
|
+
private readonly rgbToHsvCache;
|
|
23
|
+
private readonly hsvToRgbCache;
|
|
24
|
+
private readonly hexToHsvCache;
|
|
25
|
+
private static defaultInstance;
|
|
26
|
+
/**
|
|
27
|
+
* Constructor with optional cache configuration
|
|
28
|
+
* @param config Configuration for cache sizes (default: 1000 entries per cache)
|
|
29
|
+
*/
|
|
30
|
+
constructor(config?: ColorConverterConfig);
|
|
31
|
+
/**
|
|
32
|
+
* Get the default singleton instance
|
|
33
|
+
* Per Issue #6: Returns eagerly-initialized instance to avoid race conditions
|
|
34
|
+
*/
|
|
35
|
+
private static getDefault;
|
|
36
|
+
/**
|
|
37
|
+
* Clear all caches (useful for testing or memory management)
|
|
38
|
+
*/
|
|
39
|
+
clearCaches(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Static method: Clear all caches of the default instance
|
|
42
|
+
*/
|
|
43
|
+
static clearCaches(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get cache statistics (for monitoring)
|
|
46
|
+
*/
|
|
47
|
+
getCacheStats(): {
|
|
48
|
+
hexToRgb: number;
|
|
49
|
+
rgbToHex: number;
|
|
50
|
+
rgbToHsv: number;
|
|
51
|
+
hsvToRgb: number;
|
|
52
|
+
hexToHsv: number;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Static method: Get cache statistics from default instance
|
|
56
|
+
*/
|
|
57
|
+
static getCacheStats(): {
|
|
58
|
+
hexToRgb: number;
|
|
59
|
+
rgbToHex: number;
|
|
60
|
+
rgbToHsv: number;
|
|
61
|
+
hsvToRgb: number;
|
|
62
|
+
hexToHsv: number;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Convert hexadecimal color to RGB
|
|
66
|
+
* Per P-1: Cached for performance
|
|
67
|
+
* @example hexToRgb("#FF0000") -> { r: 255, g: 0, b: 0 }
|
|
68
|
+
*/
|
|
69
|
+
hexToRgb(hex: string): RGB;
|
|
70
|
+
/**
|
|
71
|
+
* Static method: Convert hex to RGB using default instance
|
|
72
|
+
*/
|
|
73
|
+
static hexToRgb(hex: string): RGB;
|
|
74
|
+
/**
|
|
75
|
+
* Convert RGB to hexadecimal color
|
|
76
|
+
* Per P-1: Cached for performance
|
|
77
|
+
* @example rgbToHex(255, 0, 0) -> "#FF0000"
|
|
78
|
+
*/
|
|
79
|
+
rgbToHex(r: number, g: number, b: number): HexColor;
|
|
80
|
+
/**
|
|
81
|
+
* Static method: Convert RGB to hex using default instance
|
|
82
|
+
*/
|
|
83
|
+
static rgbToHex(r: number, g: number, b: number): HexColor;
|
|
84
|
+
/**
|
|
85
|
+
* Convert RGB to HSV
|
|
86
|
+
* Per P-1: Cached for performance, optimized single-pass min/max
|
|
87
|
+
* @example rgbToHsv(255, 0, 0) -> { h: 0, s: 100, v: 100 }
|
|
88
|
+
*/
|
|
89
|
+
rgbToHsv(r: number, g: number, b: number): HSV;
|
|
90
|
+
/**
|
|
91
|
+
* Static method: Convert RGB to HSV using default instance
|
|
92
|
+
*/
|
|
93
|
+
static rgbToHsv(r: number, g: number, b: number): HSV;
|
|
94
|
+
/**
|
|
95
|
+
* Normalize hue to [0, 360) range.
|
|
96
|
+
* CORE-BUG-001: Ensures consistent cache keys for equivalent hue values
|
|
97
|
+
* (e.g., h=359.9999 and h=0.0001 both produce similar cache keys after rounding)
|
|
98
|
+
* Also handles negative values and values >= 360.
|
|
99
|
+
*/
|
|
100
|
+
private normalizeHue;
|
|
101
|
+
/**
|
|
102
|
+
* Convert HSV to RGB
|
|
103
|
+
* Per P-1: Cached for performance
|
|
104
|
+
* @example hsvToRgb(0, 100, 100) -> { r: 255, g: 0, b: 0 }
|
|
105
|
+
*/
|
|
106
|
+
hsvToRgb(h: number, s: number, v: number): RGB;
|
|
107
|
+
/**
|
|
108
|
+
* Static method: Convert HSV to RGB using default instance
|
|
109
|
+
*/
|
|
110
|
+
static hsvToRgb(h: number, s: number, v: number): RGB;
|
|
111
|
+
/**
|
|
112
|
+
* Convert hex to HSV
|
|
113
|
+
* Per P-1: Cached for performance
|
|
114
|
+
*/
|
|
115
|
+
hexToHsv(hex: string): HSV;
|
|
116
|
+
/**
|
|
117
|
+
* Static method: Convert hex to HSV using default instance
|
|
118
|
+
*/
|
|
119
|
+
static hexToHsv(hex: string): HSV;
|
|
120
|
+
/**
|
|
121
|
+
* Convert HSV to hex
|
|
122
|
+
*/
|
|
123
|
+
hsvToHex(h: number, s: number, v: number): HexColor;
|
|
124
|
+
/**
|
|
125
|
+
* Static method: Convert HSV to hex using default instance
|
|
126
|
+
*/
|
|
127
|
+
static hsvToHex(h: number, s: number, v: number): HexColor;
|
|
128
|
+
/**
|
|
129
|
+
* Normalize a hex color to #RRGGBB format
|
|
130
|
+
*/
|
|
131
|
+
normalizeHex(hex: string): HexColor;
|
|
132
|
+
/**
|
|
133
|
+
* Static method: Normalize hex using default instance
|
|
134
|
+
*/
|
|
135
|
+
static normalizeHex(hex: string): HexColor;
|
|
136
|
+
/**
|
|
137
|
+
* Calculate Euclidean distance between two RGB colors
|
|
138
|
+
* Returns 0 for identical colors, ~441.67 for white vs black
|
|
139
|
+
*/
|
|
140
|
+
getColorDistance(hex1: string, hex2: string): number;
|
|
141
|
+
/**
|
|
142
|
+
* Static method: Calculate color distance using default instance
|
|
143
|
+
*/
|
|
144
|
+
static getColorDistance(hex1: string, hex2: string): number;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=ColorConverter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColorConverter.d.ts","sourceRoot":"","sources":["../../../src/services/color/ColorConverter.ts"],"names":[],"mappings":"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"}
|