/
vls0885
/
html
Обзор
Документация
Войти
/
vls0885
/
html
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
ake_json.html
2 499 строк
134 KB
vls0885
create: ake_json.html
28 апр 2026, 10:00
Верифицирован
28 апр 2026, 10:00
afc91c8
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>PANTONE LCH Pro AI</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', system-ui, sans-serif; background: #050508; color: #fff; height: 100vh; overflow: hidden; display: flex; flex-direction: column; } .header { background: linear-gradient(90deg, #1a1a2e, #16213e); padding: 8px 15px; border-bottom: 1px solid #333; display: flex; justify-content: space-between; align-items: center; } h1 { font-size: 1.1rem; font-weight: 600; background: linear-gradient(90deg, #667eea, #764ba2); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .file-btns { display: flex; gap: 10px; } input[type="file"] { display: none; } .btn-file { padding: 6px 12px; background: #2a2a3a; border: 1px solid #444; border-radius: 6px; color: #fff; font-size: 0.75rem; cursor: pointer; } .btn-file:hover { background: #3a3a4a; } .color-count { font-size: 0.75rem; color: #4ade80; margin-left: 10px; } .main { flex: 1; display: flex; padding: 10px; gap: 10px; min-height: 0; } .panel { background: #151520; border-radius: 10px; border: 1px solid #2a2a3a; display: flex; flex-direction: column; overflow: hidden; } .left-panel, .right-panel { width: 300px; padding: 12px; overflow-y: auto; } .center-panel { flex: 1; display: flex; flex-direction: column; padding: 10px; } .panel-header { font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 10px; } .ref-header { color: #4ade80; } .sample-header { color: #fbbf24; } .color-preview { height: 80px; border-radius: 8px; margin-bottom: 10px; border: 3px solid #3a3a4a; display: flex; align-items: center; justify-content: center; position: relative; box-shadow: inset 0 2px 10px rgba(0,0,0,0.3); } .pantone-number { font-size: 1.3rem; font-weight: 700; text-shadow: 0 2px 4px rgba(0,0,0,0.9); background: rgba(0,0,0,0.7); padding: 6px 14px; border-radius: 20px; border: 1px solid rgba(255,255,255,0.2); } .values-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; } .val-box { background: #1a1a25; padding: 10px 4px; border-radius: 6px; text-align: center; } .val-label { font-size: 0.65rem; color: #666; text-transform: uppercase; margin-bottom: 4px; } .val-num { font-size: 1rem; font-weight: 700; font-family: monospace; } .slider-group { margin-bottom: 12px; } .slider-label { display: flex; justify-content: space-between; font-size: 0.75rem; color: #888; margin-bottom: 5px; } .slider-label span:last-child { color: #fff; font-weight: 700; font-family: monospace; font-size: 0.9rem; } input[type="range"] { width: 100%; height: 8px; -webkit-appearance: none; background: #2a2a3a; border-radius: 4px; outline: none; } input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%; background: #667eea; cursor: pointer; border: 2px solid #fff; } .ref-sliders input[type="range"]::-webkit-slider-thumb { background: #4ade80; } .sample-sliders input[type="range"]::-webkit-slider-thumb { background: #fbbf24; } .recipe-section { background: #1a1a25; border-radius: 8px; padding: 10px; margin-top: 12px; max-height: 150px; overflow-y: auto; } .recipe-title { font-size: 0.7rem; color: #888; margin-bottom: 8px; text-transform: uppercase; font-weight: 600; } .recipe-item { display: flex; align-items: center; gap: 8px; padding: 6px; background: #252530; border-radius: 4px; margin-bottom: 4px; font-size: 0.75rem; } .recipe-color { width: 20px; height: 20px; border-radius: 4px; flex-shrink: 0; border: 1px solid #444; } .recipe-name { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .recipe-percent { font-weight: 700; color: #4ade80; font-family: monospace; font-size: 0.85rem; } .blend-control { background: #1a1a25; padding: 12px; border-radius: 8px; margin-top: 12px; } .blend-title { font-size: 0.7rem; color: #888; margin-bottom: 10px; text-align: center; text-transform: uppercase; font-weight: 600; } .blend-slider-container { display: flex; align-items: center; gap: 10px; } .blend-slider-container input[type="range"] { flex: 1; background: linear-gradient(to right, #4ade80, #fbbf24); } .blend-value { font-size: 1.3rem; font-weight: 700; min-width: 50px; text-align: center; font-family: monospace; color: #fff; } .base-colors-title { font-size: 0.7rem; color: #888; margin: 12px 0 8px 0; text-transform: uppercase; text-align: center; font-weight: 600; } .base-colors-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; } .base-color-btn { padding: 10px 4px; border: 2px solid transparent; border-radius: 6px; cursor: pointer; font-size: 0.65rem; font-weight: 700; text-align: center; transition: all 0.2s; position: relative; } .base-color-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.4); border-color: rgba(255,255,255,0.5); } .base-color-btn.ai-suggested { border-color: #fbbf24; box-shadow: 0 0 10px rgba(251, 191, 36, 0.5); animation: pulse 1.5s infinite; } @keyframes pulse { 0%, 100% { box-shadow: 0 0 5px rgba(251, 191, 36, 0.5); } 50% { box-shadow: 0 0 15px rgba(251, 191, 36, 0.8); } } .search-box { margin-top: 12px; } .search-box input { width: 100%; padding: 10px; background: #1a1a25; border: 1px solid #3a3a4a; border-radius: 6px; color: #fff; font-size: 0.8rem; } .results-list { margin-top: 8px; max-height: 120px; overflow-y: auto; } .result-item { display: flex; align-items: center; gap: 8px; padding: 8px; background: #1a1a25; border-radius: 6px; margin-bottom: 4px; cursor: pointer; font-size: 0.75rem; transition: all 0.2s; border: 1px solid transparent; } .result-item:hover { background: #2a2a3a; border-color: #444; } .result-color { width: 24px; height: 24px; border-radius: 4px; flex-shrink: 0; border: 1px solid #444; } .canvas-container { flex: 1; position: relative; display: flex; align-items: center; justify-content: center; background: #0a0a0f; border-radius: 10px; margin-bottom: 10px; } canvas { cursor: crosshair; } .axis-label { position: absolute; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; } .axis-0 { right: 15px; top: 50%; transform: translateY(-50%); color: #f44336; } .axis-90 { top: 15px; left: 50%; transform: translateX(-50%); color: #ffeb3b; } .axis-180 { left: 15px; top: 50%; transform: translateY(-50%); color: #4caf50; } .axis-270 { bottom: 15px; left: 50%; transform: translateX(-50%); color: #2196f3; } .controls { display: flex; gap: 10px; justify-content: center; padding: 10px; background: #151520; border-radius: 8px; } .btn { padding: 10px 20px; border: none; border-radius: 6px; font-size: 0.8rem; font-weight: 600; cursor: pointer; background: #2a2a3a; color: #fff; } .btn:hover { background: #3a3a4a; } .btn-primary { background: linear-gradient(90deg, #667eea, #764ba2); } .view-options { display: flex; gap: 15px; align-items: center; } .view-options label { font-size: 0.75rem; color: #888; display: flex; align-items: center; gap: 5px; cursor: pointer; } .loading { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.8); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s; } .loading.show { opacity: 1; pointer-events: all; } .loading-text { font-size: 1.2rem; color: #667eea; } #aiAnalysis { background: linear-gradient(135deg, #1a1a25, #252535); padding: 12px; border-radius: 8px; margin-top: 10px; font-size: 0.8rem; border: 1px solid #3a3a4a; } #aiAnalysisTitle { color: #fbbf24; margin-bottom: 8px; font-weight: 600; display: flex; align-items: center; gap: 6px; } #aiText { color: #fff; line-height: 1.4; } #aiDE { color: #4ade80; font-family: monospace; margin-top: 8px; font-size: 0.9rem; font-weight: 700; } #aiLCHPreview { margin-top: 6px; font-size: 0.75rem; color: #a5b4fc; font-family: monospace; background: rgba(102, 126, 234, 0.1); padding: 6px; border-radius: 4px; } #aiSuggestion { margin-top: 8px; padding-top: 8px; border-top: 1px solid #3a3a4a; font-size: 0.75rem; color: #888; } #aiSuggestion strong { color: #fbbf24; } .transwhite-control { background: linear-gradient(135deg, #2a2a3a, #3a3a4a); padding: 12px; border-radius: 8px; margin-top: 12px; border: 1px solid #4a4a5a; } .transwhite-title { font-size: 0.7rem; color: #a5b4fc; margin-bottom: 8px; text-align: center; text-transform: uppercase; font-weight: 600; } .transwhite-slider-container { display: flex; align-items: center; gap: 10px; } .transwhite-slider-container input[type="range"] { flex: 1; background: linear-gradient(to right, #ffffff, #e0e0e0); } .transwhite-slider-container input[type="range"]::-webkit-slider-thumb { background: #ffffff; border-color: #667eea; } .transwhite-value { font-size: 1.3rem; font-weight: 700; min-width: 50px; text-align: center; font-family: monospace; color: #fff; } .transwhite-btn { width: 100%; margin-top: 8px; padding: 8px; background: #4a5568; border: 1px solid #718096; border-radius: 6px; color: #fff; font-size: 0.75rem; cursor: pointer; transition: all 0.2s; } .transwhite-btn:hover { background: #556575; } .transwhite-btn.active { background: #667eea; border-color: #764ba2; } .transwhite-info { font-size: 0.65rem; color: #a5b4fc; margin-top: 6px; text-align: center; } #canvasTooltip { position: absolute; background: rgba(0,0,0,0.95); border: 2px solid #667eea; border-radius: 8px; padding: 12px; pointer-events: none; display: none; z-index: 100; font-size: 0.8rem; box-shadow: 0 4px 20px rgba(0,0,0,0.5); } #canvasTooltip .tooltip-pantone { font-weight: 700; color: #fbbf24; margin-bottom: 6px; font-size: 0.9rem; } #canvasTooltip .tooltip-de { color: #4ade80; font-family: monospace; font-size: 0.85rem; } #canvasTooltip .tooltip-values { color: #888; font-size: 0.75rem; margin-top: 6px; padding-top: 6px; border-top: 1px solid #333; } .ai-strategy { background: linear-gradient(135deg, #1e1b4b, #312e81); padding: 10px; border-radius: 6px; margin-top: 8px; border-left: 3px solid #fbbf24; } .ai-strategy-title { color: #fbbf24; font-size: 0.7rem; font-weight: 600; margin-bottom: 4px; text-transform: uppercase; } .ai-strategy-text { color: #c7d2fe; font-size: 0.75rem; line-height: 1.4; } .ai-multi-step { background: rgba(102, 126, 234, 0.1); padding: 8px; border-radius: 4px; margin-top: 6px; font-size: 0.7rem; color: #a5b4fc; } .ai-confidence { display: inline-block; padding: 2px 6px; border-radius: 4px; font-size: 0.65rem; font-weight: 600; margin-left: 6px; } .ai-confidence.high { background: #4ade80; color: #000; } .ai-confidence.medium { background: #fbbf24; color: #000; } .ai-confidence.low { background: #f87171; color: #fff; } /* Индикатор точности цвета */ .color-accuracy { position: absolute; bottom: 4px; right: 8px; font-size: 0.6rem; padding: 2px 6px; border-radius: 4px; background: rgba(0,0,0,0.7); } .color-accuracy.exact { color: #4ade80; } .color-accuracy.approx { color: #fbbf24; } .color-accuracy.calc { color: #a5b4fc; } </style> </head> <body> <div class="header"> <h1>PANTONE LCH Pro AI</h1> <div class="file-btns"> <label class="btn-file"><input type="file" id="colorsFile" accept=".xlsx,.csv" onchange="loadColors(event)">📊 Цвета</label> <span class="color-count" id="colorsCount"></span> <label class="btn-file"><input type="file" id="recipesFile" accept=".xlsx,.csv" onchange="loadRecipes(event)">📋 Рецепты</label> <span class="color-count" id="recipesCount"></span> </div> </div> <div class="main"> <div class="panel left-panel"> <div class="panel-header ref-header"><span>●</span> ЭТАЛОН</div> <div class="color-preview" id="refPreview"> <span class="pantone-number" id="refNumber">116 C</span> <span class="color-accuracy exact" id="refAccuracy">Pantone</span> </div> <div class="values-grid"> <div class="val-box"><div class="val-label">L*</div><div class="val-num" id="refL">85.5</div></div> <div class="val-box"><div class="val-label">C*</div><div class="val-num" id="refC">88.4</div></div> <div class="val-box"><div class="val-label">H°</div><div class="val-num" id="refH">84.6</div></div> </div> <div class="ref-sliders"> <div class="slider-group"> <div class="slider-label"><span>L* Светлота</span><span id="refLval">85.5</span></div> <input type="range" id="refLslider" min="0" max="100" value="85.5" step="0.1"> </div> <div class="slider-group"> <div class="slider-label"><span>C* Насыщенность</span><span id="refCval">88.4</span></div> <input type="range" id="refCslider" min="0" max="150" value="88.4" step="0.1"> </div> <div class="slider-group"> <div class="slider-label"><span>H° Тон</span><span id="refHval">84.6°</span></div> <input type="range" id="refHslider" min="0" max="360" value="84.6" step="0.1"> </div> </div> <div class="recipe-section" id="refRecipeSection" style="display: none;"> <div class="recipe-title">Рецепт смешивания</div> <div id="refRecipes"></div> </div> <div class="blend-control"> <div class="blend-title">Сила смешивания</div> <div class="blend-slider-container"> <span style="font-size: 0.7rem; color: #888;">1%</span> <input type="range" id="blendAmount" min="1" max="40" value="10" oninput="updateBlendPreview(this.value)"> <span style="font-size: 0.7rem; color: #888;">40%</span> </div> <div class="blend-value" id="blendValue">10%</div> </div> <div class="base-colors-title">Базовые цвета</div> <div class="base-colors-grid" id="refBaseColors"></div> <div class="search-box"> <input type="text" id="refSearch" placeholder="Поиск: 'яркий красный' или 116..." onkeyup="smartSearch(this.value,'ref')"> </div> <div class="results-list" id="refResults"></div> </div> <div class="panel center-panel"> <div class="canvas-container"> <canvas id="lchCanvas" width="600" height="450"></canvas> <div id="canvasTooltip"> <div class="tooltip-pantone" id="tooltipPantone">PANTONE 300 C</div> <div class="tooltip-de" id="tooltipDE">ΔE: 0.00</div> <div class="tooltip-values" id="tooltipValues">L: 40.0 C: 55.0 H: 283°</div> </div> <div class="axis-label axis-0">0° Red</div> <div class="axis-label axis-90">90° Yellow</div> <div class="axis-label axis-180">180° Green</div> <div class="axis-label axis-270">270° Blue</div> </div> <div class="controls"> <div class="view-options"> <label><input type="checkbox" id="showAllColors" checked onchange="drawCanvas()"> Все цвета</label> <label><input type="checkbox" id="showGrid" checked onchange="drawCanvas()"> Сетка</label> </div> <button class="btn" onclick="findNearest()">🔍 Ближайшие</button> <button class="btn btn-primary" onclick="swapColors()">⇄ Обмен</button> </div> <div id="aiAnalysis"> <div id="aiAnalysisTitle">🤖 AI Анализ различий</div> <div id="aiText">Загрузите цвета или измените образец для анализа</div> <div id="aiDE">ΔE = --</div> <div id="aiLCHPreview"></div> <div id="aiSuggestion"></div> <div id="aiStrategy" class="ai-strategy" style="display: none;"> <div class="ai-strategy-title">Стратегия коррекции</div> <div class="ai-strategy-text" id="aiStrategyText"></div> <div class="ai-multi-step" id="aiMultiStep"></div> </div> </div> </div> <div class="panel right-panel"> <div class="panel-header sample-header"><span>●</span> ОБРАЗЕЦ</div> <div class="color-preview" id="samplePreview"> <span class="pantone-number" id="sampleNumber">109 C</span> <span class="color-accuracy exact" id="sampleAccuracy">Pantone</span> </div> <div class="values-grid"> <div class="val-box"><div class="val-label">L*</div><div class="val-num" id="sampleL">86.3</div></div> <div class="val-box"><div class="val-label">C*</div><div class="val-num" id="sampleC">97.9</div></div> <div class="val-box"><div class="val-label">H°</div><div class="val-num" id="sampleH">86.3</div></div> </div> <div class="sample-sliders"> <div class="slider-group"> <div class="slider-label"><span>L* Светлота</span><span id="sampleLval">86.3</span></div> <input type="range" id="sampleLslider" min="0" max="100" value="86.3" step="0.1"> </div> <div class="slider-group"> <div class="slider-label"><span>C* Насыщенность</span><span id="sampleCval">97.9</span></div> <input type="range" id="sampleCslider" min="0" max="150" value="97.9" step="0.1"> </div> <div class="slider-group"> <div class="slider-label"><span>H° Тон</span><span id="sampleHval">86.3°</span></div> <input type="range" id="sampleHslider" min="0" max="360" value="86.3" step="0.1"> </div> </div> <div class="recipe-section" id="sampleRecipeSection" style="display: none;"> <div class="recipe-title">Рецепт смешивания</div> <div id="sampleRecipes"></div> </div> <div class="transwhite-control"> <div class="transwhite-title">⚪ Trans White (Лак)</div> <div class="transwhite-slider-container"> <span style="font-size: 0.7rem; color: #888;">0%</span> <input type="range" id="transWhiteAmount" min="0" max="100" value="0" step="1" oninput="updateTransWhite(this.value)"> <span style="font-size: 0.7rem; color: #888;">100%</span> </div> <div class="transwhite-value" id="transWhiteValue">0%</div> <button class="transwhite-btn" id="transWhiteBtn" onclick="applyTransWhite()">Применить к образцу</button> <div class="transwhite-info" id="transWhiteInfo">Добавьте лак для осветления образца</div> </div> <div class="base-colors-title">Базовые цвета <span style="color:#fbbf24">← AI рекомендует</span></div> <div class="base-colors-grid" id="sampleBaseColors"></div> <div class="search-box"> <input type="text" id="sampleSearch" placeholder="Поиск: 'пастельный синий' или 109..." onkeyup="smartSearch(this.value,'sample')"> </div> <div class="results-list" id="sampleResults"></div> </div> </div> <div class="loading" id="loading"><div class="loading-text">Загрузка...</div></div> <script> // ===== КОРРЕКЦИЯ ЦВЕТОВ: База стандартных Pantone RGB ===== const pantoneRGBDatabase = { // Yellows "PANTONE 100 C": { r: 244, g: 237, b: 124 }, "PANTONE 101 C": { r: 244, g: 237, b: 71 }, "PANTONE 102 C": { r: 245, g: 236, b: 0 }, "PANTONE 103 C": { r: 209, g: 195, b: 0 }, "PANTONE 104 C": { r: 176, g: 165, b: 0 }, "PANTONE 105 C": { r: 133, g: 123, b: 28 }, "PANTONE 106 C": { r: 247, g: 232, b: 89 }, "PANTONE 107 C": { r: 249, g: 229, b: 0 }, "PANTONE 108 C": { r: 255, g: 221, b: 0 }, "PANTONE 109 C": { r: 255, g: 209, b: 0 }, "PANTONE 110 C": { r: 218, g: 179, b: 0 }, "PANTONE 111 C": { r: 170, g: 138, b: 0 }, "PANTONE 112 C": { r: 153, g: 120, b: 0 }, "PANTONE 113 C": { r: 251, g: 225, b: 82 }, "PANTONE 114 C": { r: 253, g: 219, b: 51 }, "PANTONE 115 C": { r: 253, g: 218, b: 36 }, "PANTONE 116 C": { r: 255, g: 206, b: 0 }, "PANTONE 117 C": { r: 201, g: 151, b: 0 }, "PANTONE 118 C": { r: 172, g: 120, b: 0 }, "PANTONE 119 C": { r: 137, g: 98, b: 29 }, "PANTONE 120 C": { r: 251, g: 222, b: 114 }, "PANTONE 121 C": { r: 253, g: 218, b: 83 }, "PANTONE 122 C": { r: 255, g: 209, b: 66 }, "PANTONE 123 C": { r: 255, g: 199, b: 38 }, "PANTONE 124 C": { r: 234, g: 170, b: 0 }, "PANTONE 125 C": { r: 181, g: 133, b: 0 }, "PANTONE 126 C": { r: 162, g: 112, b: 0 }, "PANTONE 127 C": { r: 243, g: 221, b: 109 }, "PANTONE 128 C": { r: 243, g: 214, b: 83 }, "PANTONE 129 C": { r: 242, g: 205, b: 65 }, "PANTONE 130 C": { r: 242, g: 189, b: 40 }, "PANTONE 131 C": { r: 203, g: 144, b: 0 }, "PANTONE 132 C": { r: 160, g: 112, b: 0 }, "PANTONE 133 C": { r: 121, g: 85, b: 0 }, "PANTONE 134 C": { r: 255, g: 205, b: 119 }, "PANTONE 135 C": { r: 255, g: 192, b: 85 }, "PANTONE 136 C": { r: 255, g: 179, b: 58 }, "PANTONE 137 C": { r: 255, g: 158, b: 27 }, "PANTONE 138 C": { r: 220, g: 121, b: 0 }, "PANTONE 139 C": { r: 175, g: 95, b: 0 }, "PANTONE 140 C": { r: 130, g: 72, b: 0 }, "PANTONE 141 C": { r: 242, g: 189, b: 89 }, "PANTONE 142 C": { r: 242, g: 175, b: 61 }, "PANTONE 143 C": { r: 241, g: 159, b: 40 }, "PANTONE 144 C": { r: 236, g: 134, b: 16 }, "PANTONE 145 C": { r: 197, g: 105, b: 0 }, "PANTONE 146 C": { r: 155, g: 84, b: 0 }, "PANTONE 147 C": { r: 114, g: 64, b: 19 }, "PANTONE 148 C": { r: 255, g: 191, b: 128 }, "PANTONE 149 C": { r: 255, g: 179, b: 107 }, "PANTONE 150 C": { r: 255, g: 158, b: 74 }, "PANTONE 151 C": { r: 255, g: 127, b: 33 }, "PANTONE 152 C": { r: 232, g: 96, b: 0 }, "PANTONE 153 C": { r: 190, g: 80, b: 0 }, "PANTONE 154 C": { r: 149, g: 63, b: 0 }, "PANTONE 155 C": { r: 242, g: 186, b: 124 }, "PANTONE 156 C": { r: 242, g: 168, b: 97 }, "PANTONE 157 C": { r: 241, g: 142, b: 60 }, "PANTONE 158 C": { r: 236, g: 111, b: 29 }, "PANTONE 159 C": { r: 200, g: 78, b: 0 }, "PANTONE 160 C": { r: 160, g: 66, b: 0 }, "PANTONE 161 C": { r: 112, g: 47, b: 9 }, "PANTONE 162 C": { r: 255, g: 176, b: 138 }, "PANTONE 163 C": { r: 255, g: 147, b: 99 }, "PANTONE 164 C": { r: 255, g: 120, b: 66 }, "PANTONE 165 C": { r: 255, g: 85, b: 27 }, "PANTONE 166 C": { r: 230, g: 64, b: 0 }, "PANTONE 167 C": { r: 190, g: 55, b: 0 }, "PANTONE 168 C": { r: 138, g: 41, b: 0 }, "PANTONE 169 C": { r: 255, g: 163, b: 139 }, "PANTONE 170 C": { r: 255, g: 134, b: 106 }, "PANTONE 171 C": { r: 255, g: 103, b: 71 }, "PANTONE 172 C": { r: 255, g: 67, b: 27 }, "PANTONE 173 C": { r: 219, g: 52, b: 0 }, "PANTONE 174 C": { r: 179, g: 44, b: 0 }, "PANTONE 175 C": { r: 130, g: 33, b: 0 }, "PANTONE 176 C": { r: 255, g: 156, b: 158 }, "PANTONE 177 C": { r: 255, g: 122, b: 127 }, "PANTONE 178 C": { r: 255, g: 88, b: 93 }, "PANTONE 179 C": { r: 255, g: 50, b: 46 }, "PANTONE 180 C": { r: 227, g: 19, b: 0 }, "PANTONE 181 C": { r: 179, g: 16, b: 0 }, "PANTONE 182 C": { r: 133, g: 12, b: 0 }, "PANTONE 183 C": { r: 255, g: 155, b: 170 }, "PANTONE 184 C": { r: 255, g: 119, b: 140 }, "PANTONE 185 C": { r: 255, g: 78, b: 97 }, "PANTONE 186 C": { r: 255, g: 28, b: 46 }, "PANTONE 187 C": { r: 207, g: 0, b: 22 }, "PANTONE 188 C": { r: 166, g: 0, b: 18 }, "PANTONE 189 C": { r: 124, g: 0, b: 14 }, "PANTONE 190 C": { r: 255, g: 145, b: 170 }, "PANTONE 191 C": { r: 255, g: 107, b: 140 }, "PANTONE 192 C": { r: 255, g: 62, b: 100 }, "PANTONE 193 C": { r: 255, g: 0, b: 56 }, "PANTONE 194 C": { r: 204, g: 0, b: 45 }, "PANTONE 195 C": { r: 162, g: 0, b: 36 }, "PANTONE 196 C": { r: 120, g: 0, b: 27 }, "PANTONE 197 C": { r: 255, g: 137, b: 172 }, "PANTONE 198 C": { r: 255, g: 97, b: 136 }, "PANTONE 199 C": { r: 255, g: 0, b: 85 }, "PANTONE 200 C": { r: 223, g: 0, b: 57 }, "PANTONE 201 C": { r: 186, g: 0, b: 47 }, "PANTONE 202 C": { r: 155, g: 0, b: 39 }, "PANTONE 203 C": { r: 122, g: 0, b: 31 }, "PANTONE 204 C": { r: 255, g: 130, b: 175 }, "PANTONE 205 C": { r: 255, g: 85, b: 140 }, "PANTONE 206 C": { r: 255, g: 0, b: 85 }, "PANTONE 207 C": { r: 215, g: 0, b: 55 }, "PANTONE 208 C": { r: 176, g: 0, b: 45 }, "PANTONE 209 C": { r: 147, g: 0, b: 38 }, "PANTONE 210 C": { r: 255, g: 109, b: 166 }, "PANTONE 211 C": { r: 255, g: 64, b: 130 }, "PANTONE 212 C": { r: 255, g: 0, b: 85 }, "PANTONE 213 C": { r: 230, g: 0, b: 65 }, "PANTONE 214 C": { r: 196, g: 0, b: 55 }, "PANTONE 215 C": { r: 166, g: 0, b: 47 }, "PANTONE 216 C": { r: 130, g: 0, b: 37 }, "PANTONE 217 C": { r: 255, g: 150, b: 200 }, "PANTONE 218 C": { r: 255, g: 90, b: 160 }, "PANTONE 219 C": { r: 255, g: 0, b: 100 }, "PANTONE 220 C": { r: 200, g: 0, b: 65 }, "PANTONE 221 C": { r: 165, g: 0, b: 54 }, "PANTONE 222 C": { r: 128, g: 0, b: 42 }, "PANTONE 223 C": { r: 255, g: 140, b: 205 }, "PANTONE 224 C": { r: 255, g: 85, b: 175 }, "PANTONE 225 C": { r: 255, g: 0, b: 120 }, "PANTONE 226 C": { r: 215, g: 0, b: 85 }, "PANTONE 227 C": { r: 175, g: 0, b: 70 }, "PANTONE 228 C": { r: 135, g: 0, b: 54 }, "PANTONE 229 C": { r: 255, g: 120, b: 210 }, "PANTONE 230 C": { r: 255, g: 70, b: 185 }, "PANTONE 231 C": { r: 255, g: 0, b: 140 }, "PANTONE 232 C": { r: 220, g: 0, b: 100 }, "PANTONE 233 C": { r: 180, g: 0, b: 82 }, "PANTONE 234 C": { r: 140, g: 0, b: 64 }, "PANTONE 235 C": { r: 255, g: 105, b: 220 }, "PANTONE 236 C": { r: 255, g: 55, b: 200 }, "PANTONE 237 C": { r: 255, g: 0, b: 165 }, "PANTONE 238 C": { r: 225, g: 0, b: 120 }, "PANTONE 239 C": { r: 185, g: 0, b: 95 }, "PANTONE 240 C": { r: 145, g: 0, b: 75 }, "PANTONE 241 C": { r: 255, g: 90, b: 230 }, "PANTONE 242 C": { r: 255, g: 40, b: 210 }, "PANTONE 243 C": { r: 255, g: 0, b: 175 }, "PANTONE 244 C": { r: 230, g: 0, b: 135 }, "PANTONE 245 C": { r: 190, g: 0, b: 110 }, "PANTONE 246 C": { r: 150, g: 0, b: 87 }, "PANTONE 247 C": { r: 255, g: 75, b: 240 }, "PANTONE 248 C": { r: 255, g: 25, b: 220 }, "PANTONE 249 C": { r: 255, g: 0, b: 185 }, "PANTONE 250 C": { r: 230, g: 0, b: 140 }, "PANTONE 251 C": { r: 195, g: 0, b: 115 }, "PANTONE 252 C": { r: 155, g: 0, b: 92 }, "PANTONE 253 C": { r: 255, g: 60, b: 250 }, "PANTONE 254 C": { r: 255, g: 10, b: 230 }, "PANTONE 255 C": { r: 255, g: 0, b: 195 }, "PANTONE 256 C": { r: 230, g: 0, b: 145 }, "PANTONE 257 C": { r: 190, g: 0, b: 115 }, "PANTONE 258 C": { r: 150, g: 0, b: 90 }, "PANTONE 259 C": { r: 145, g: 0, b: 90 }, "PANTONE 260 C": { r: 120, g: 0, b: 75 }, "PANTONE 261 C": { r: 100, g: 0, b: 65 }, "PANTONE 262 C": { r: 80, g: 0, b: 52 }, "PANTONE 263 C": { r: 230, g: 190, b: 255 }, "PANTONE 264 C": { r: 205, g: 140, b: 255 }, "PANTONE 265 C": { r: 170, g: 80, b: 255 }, "PANTONE 266 C": { r: 140, g: 30, b: 255 }, "PANTONE 267 C": { r: 120, g: 0, b: 230 }, "PANTONE 268 C": { r: 100, g: 0, b: 190 }, "PANTONE 269 C": { r: 85, g: 0, b: 150 }, "PANTONE 270 C": { r: 200, g: 180, b: 255 }, "PANTONE 271 C": { r: 175, g: 145, b: 255 }, "PANTONE 272 C": { r: 145, g: 105, b: 255 }, "PANTONE 273 C": { r: 100, g: 30, b: 255 }, "PANTONE 274 C": { r: 75, g: 0, b: 200 }, "PANTONE 275 C": { r: 60, g: 0, b: 160 }, "PANTONE 276 C": { r: 50, g: 0, b: 125 }, "PANTONE 277 C": { r: 180, g: 210, b: 255 }, "PANTONE 278 C": { r: 145, g: 185, b: 255 }, "PANTONE 279 C": { r: 100, g: 150, b: 255 }, "PANTONE 280 C": { r: 0, g: 50, b: 200 }, "PANTONE 281 C": { r: 0, g: 35, b: 160 }, "PANTONE 282 C": { r: 0, g: 25, b: 120 }, "PANTONE 283 C": { r: 155, g: 210, b: 255 }, "PANTONE 284 C": { r: 110, g: 185, b: 255 }, "PANTONE 285 C": { r: 50, g: 150, b: 255 }, "PANTONE 286 C": { r: 0, g: 80, b: 220 }, "PANTONE 287 C": { r: 0, g: 60, b: 180 }, "PANTONE 288 C": { r: 0, g: 45, b: 140 }, "PANTONE 289 C": { r: 0, g: 30, b: 100 }, "PANTONE 290 C": { r: 195, g: 230, b: 255 }, "PANTONE 291 C": { r: 145, g: 210, b: 255 }, "PANTONE 292 C": { r: 85, g: 185, b: 255 }, "PANTONE 293 C": { r: 0, g: 100, b: 255 }, "PANTONE 294 C": { r: 0, g: 75, b: 200 }, "PANTONE 295 C": { r: 0, g: 55, b: 155 }, "PANTONE 296 C": { r: 0, g: 40, b: 110 }, "PANTONE 297 C": { r: 130, g: 220, b: 255 }, "PANTONE 298 C": { r: 65, g: 200, b: 255 }, "PANTONE 299 C": { r: 0, g: 160, b: 255 }, "PANTONE 300 C": { r: 0, g: 115, b: 230 }, "PANTONE 301 C": { r: 0, g: 85, b: 180 }, "PANTONE 302 C": { r: 0, g: 60, b: 130 }, "PANTONE 303 C": { r: 0, g: 45, b: 95 }, "PANTONE 304 C": { r: 165, g: 240, b: 255 }, "PANTONE 305 C": { r: 95, g: 225, b: 255 }, "PANTONE 306 C": { r: 0, g: 190, b: 255 }, "PANTONE 307 C": { r: 0, g: 130, b: 195 }, "PANTONE 308 C": { r: 0, g: 95, b: 145 }, "PANTONE 309 C": { r: 0, g: 65, b: 100 }, "PANTONE 310 C": { r: 110, g: 235, b: 255 }, "PANTONE 311 C": { r: 40, g: 215, b: 255 }, "PANTONE 312 C": { r: 0, g: 175, b: 220 }, "PANTONE 313 C": { r: 0, g: 140, b: 180 }, "PANTONE 314 C": { r: 0, g: 110, b: 140 }, "PANTONE 315 C": { r: 0, g: 85, b: 110 }, "PANTONE 316 C": { r: 0, g: 60, b: 75 }, "PANTONE 317 C": { r: 200, g: 250, b: 240 }, "PANTONE 318 C": { r: 140, g: 245, b: 230 }, "PANTONE 319 C": { r: 75, g: 235, b: 215 }, "PANTONE 320 C": { r: 0, g: 175, b: 155 }, "PANTONE 321 C": { r: 0, g: 140, b: 125 }, "PANTONE 322 C": { r: 0, g: 110, b: 100 }, "PANTONE 323 C": { r: 0, g: 85, b: 75 }, "PANTONE 324 C": { r: 165, g: 245, b: 225 }, "PANTONE 325 C": { r: 100, g: 235, b: 205 }, "PANTONE 326 C": { r: 0, g: 195, b: 165 }, "PANTONE 327 C": { r: 0, g: 155, b: 130 }, "PANTONE 328 C": { r: 0, g: 125, b: 105 }, "PANTONE 329 C": { r: 0, g: 100, b: 85 }, "PANTONE 330 C": { r: 0, g: 75, b: 65 }, "PANTONE 331 C": { r: 195, g: 250, b: 220 }, "PANTONE 332 C": { r: 150, g: 245, b: 200 }, "PANTONE 333 C": { r: 75, g: 235, b: 175 }, "PANTONE 334 C": { r: 0, g: 175, b: 125 }, "PANTONE 335 C": { r: 0, g: 135, b: 95 }, "PANTONE 336 C": { r: 0, g: 110, b: 80 }, "PANTONE 337 C": { r: 0, g: 85, b: 60 }, "PANTONE 338 C": { r: 180, g: 245, b: 195 }, "PANTONE 339 C": { r: 110, g: 235, b: 160 }, "PANTONE 340 C": { r: 0, g: 180, b: 110 }, "PANTONE 341 C": { r: 0, g: 140, b: 85 }, "PANTONE 342 C": { r: 0, g: 115, b: 70 }, "PANTONE 343 C": { r: 0, g: 90, b: 55 }, "PANTONE 344 C": { r: 185, g: 240, b: 175 }, "PANTONE 345 C": { r: 130, g: 230, b: 140 }, "PANTONE 346 C": { r: 65, g: 215, b: 105 }, "PANTONE 347 C": { r: 0, g: 160, b: 75 }, "PANTONE 348 C": { r: 0, g: 125, b: 60 }, "PANTONE 349 C": { r: 0, g: 100, b: 48 }, "PANTONE 350 C": { r: 0, g: 75, b: 35 }, "PANTONE 351 C": { r: 175, g: 235, b: 155 }, "PANTONE 352 C": { r: 130, g: 225, b: 120 }, "PANTONE 353 C": { r: 80, g: 210, b: 85 }, "PANTONE 354 C": { r: 0, g: 165, b: 60 }, "PANTONE 355 C": { r: 0, g: 130, b: 45 }, "PANTONE 356 C": { r: 0, g: 105, b: 35 }, "PANTONE 357 C": { r: 0, g: 80, b: 25 }, "PANTONE 358 C": { r: 175, g: 230, b: 130 }, "PANTONE 359 C": { r: 140, g: 220, b: 100 }, "PANTONE 360 C": { r: 85, g: 200, b: 60 }, "PANTONE 361 C": { r: 30, g: 170, b: 35 }, "PANTONE 362 C": { r: 25, g: 140, b: 30 }, "PANTONE 363 C": { r: 20, g: 115, b: 25 }, "PANTONE 364 C": { r: 15, g: 90, b: 20 }, "PANTONE 365 C": { r: 200, g: 235, b: 120 }, "PANTONE 366 C": { r: 170, g: 225, b: 90 }, "PANTONE 367 C": { r: 130, g: 210, b: 55 }, "PANTONE 368 C": { r: 85, g: 185, b: 30 }, "PANTONE 369 C": { r: 65, g: 155, b: 20 }, "PANTONE 370 C": { r: 55, g: 130, b: 15 }, "PANTONE 371 C": { r: 45, g: 105, b: 10 }, "PANTONE 372 C": { r: 220, g: 240, b: 120 }, "PANTONE 373 C": { r: 200, g: 235, b: 90 }, "PANTONE 374 C": { r: 175, g: 225, b: 55 }, "PANTONE 375 C": { r: 140, g: 205, b: 20 }, "PANTONE 376 C": { r: 115, g: 175, b: 10 }, "PANTONE 377 C": { r: 95, g: 145, b: 5 }, "PANTONE 378 C": { r: 75, g: 115, b: 0 }, "PANTONE 379 C": { r: 225, g: 240, b: 85 }, "PANTONE 380 C": { r: 210, g: 235, b: 55 }, "PANTONE 381 C": { r: 190, g: 225, b: 20 }, "PANTONE 382 C": { r: 160, g: 205, b: 0 }, "PANTONE 383 C": { r: 135, g: 175, b: 0 }, "PANTONE 384 C": { r: 110, g: 145, b: 0 }, "PANTONE 385 C": { r: 90, g: 115, b: 0 }, "PANTONE 386 C": { r: 230, g: 240, b: 75 }, "PANTONE 387 C": { r: 220, g: 237, b: 40 }, "PANTONE 388 C": { r: 205, g: 230, b: 0 }, "PANTONE 389 C": { r: 180, g: 210, b: 0 }, "PANTONE 390 C": { r: 155, g: 180, b: 0 }, "PANTONE 391 C": { r: 130, g: 150, b: 0 }, "PANTONE 392 C": { r: 105, g: 120, b: 0 }, "PANTONE 393 C": { r: 240, g: 245, b: 85 }, "PANTONE 394 C": { r: 235, g: 242, b: 45 }, "PANTONE 395 C": { r: 225, g: 235, b: 0 }, "PANTONE 396 C": { r: 205, g: 220, b: 0 }, "PANTONE 397 C": { r: 175, g: 190, b: 0 }, "PANTONE 398 C": { r: 150, g: 165, b: 0 }, "PANTONE 399 C": { r: 125, g: 140, b: 0 }, "PANTONE 400 C": { r: 206, g: 194, b: 178 }, "PANTONE 401 C": { r: 191, g: 178, b: 161 }, "PANTONE 402 C": { r: 175, g: 161, b: 142 }, "PANTONE 403 C": { r: 155, g: 141, b: 121 }, "PANTONE 404 C": { r: 130, g: 115, b: 95 }, "PANTONE 405 C": { r: 105, g: 91, b: 72 }, "PANTONE 406 C": { r: 203, g: 189, b: 173 }, "PANTONE 407 C": { r: 183, g: 167, b: 149 }, "PANTONE 408 C": { r: 163, g: 146, b: 127 }, "PANTONE 409 C": { r: 143, g: 125, b: 106 }, "PANTONE 410 C": { r: 118, g: 101, b: 83 }, "PANTONE 411 C": { r: 93, g: 77, b: 60 }, "PANTONE 412 C": { r: 63, g: 48, b: 33 }, "PANTONE 413 C": { r: 197, g: 192, b: 179 }, "PANTONE 414 C": { r: 177, g: 172, b: 157 }, "PANTONE 415 C": { r: 157, g: 151, b: 135 }, "PANTONE 416 C": { r: 137, g: 131, b: 114 }, "PANTONE 417 C": { r: 112, g: 106, b: 90 }, "PANTONE 418 C": { r: 87, g: 81, b: 66 }, "PANTONE 419 C": { r: 54, g: 49, b: 36 }, "PANTONE 420 C": { r: 194, g: 189, b: 177 }, "PANTONE 421 C": { r: 174, g: 169, b: 157 }, "PANTONE 422 C": { r: 154, g: 149, b: 137 }, "PANTONE 423 C": { r: 134, g: 129, b: 117 }, "PANTONE 424 C": { r: 109, g: 104, b: 92 }, "PANTONE 425 C": { r: 84, g: 79, b: 68 }, "PANTONE 426 C": { r: 38, g: 34, b: 25 }, "PANTONE 427 C": { r: 218, g: 216, b: 209 }, "PANTONE 428 C": { r: 198, g: 196, b: 189 }, "PANTONE 429 C": { r: 173, g: 171, b: 164 }, "PANTONE 430 C": { r: 148, g: 146, b: 139 }, "PANTONE 431 C": { r: 118, g: 116, b: 109 }, "PANTONE 432 C": { r: 88, g: 86, b: 80 }, "PANTONE 433 C": { r: 48, g: 46, b: 41 }, "PANTONE 434 C": { r: 216, g: 209, b: 201 }, "PANTONE 435 C": { r: 201, g: 191, b: 181 }, "PANTONE 436 C": { r: 181, g: 168, b: 156 }, "PANTONE 437 C": { r: 156, g: 141, b: 128 }, "PANTONE 438 C": { r: 116, g: 100, b: 87 }, "PANTONE 439 C": { r: 91, g: 76, b: 64 }, "PANTONE 440 C": { r: 61, g: 48, b: 37 }, "PANTONE 441 C": { r: 203, g: 208, b: 204 }, "PANTONE 442 C": { r: 178, g: 184, b: 180 }, "PANTONE 443 C": { r: 153, g: 160, b: 156 }, "PANTONE 444 C": { r: 123, g: 130, b: 126 }, "PANTONE 445 C": { r: 93, g: 100, b: 96 }, "PANTONE 446 C": { r: 68, g: 75, b: 71 }, "PANTONE 447 C": { r: 48, g: 54, b: 51 }, "PANTONE 448 C": { r: 74, g: 65, b: 42 }, "PANTONE 449 C": { r: 89, g: 80, b: 52 }, "PANTONE 450 C": { r: 109, g: 98, b: 67 }, "PANTONE 451 C": { r: 149, g: 140, b: 109 }, "PANTONE 452 C": { r: 179, g: 171, b: 142 }, "PANTONE 453 C": { r: 199, g: 192, b: 165 }, "PANTONE 454 C": { r: 214, g: 208, b: 184 }, "PANTONE 455 C": { r: 106, g: 91, b: 42 }, "PANTONE 456 C": { r: 131, g: 115, b: 55 }, "PANTONE 457 C": { r: 161, g: 144, b: 72 }, "PANTONE 458 C": { r: 196, g: 181, b: 112 }, "PANTONE 459 C": { r: 211, g: 198, b: 135 }, "PANTONE 460 C": { r: 221, g: 210, b: 155 }, "PANTONE 461 C": { r: 229, g: 220, b: 172 }, "PANTONE 462 C": { r: 95, g: 74, b: 46 }, "PANTONE 463 C": { r: 120, g: 91, b: 55 }, "PANTONE 464 C": { r: 145, g: 108, b: 64 }, "PANTONE 465 C": { r: 180, g: 146, b: 100 }, "PANTONE 466 C": { r: 200, g: 170, b: 127 }, "PANTONE 467 C": { r: 215, g: 190, b: 150 }, "PANTONE 468 C": { r: 225, g: 205, b: 170 }, "PANTONE 469 C": { r: 105, g: 60, b: 37 }, "PANTONE 470 C": { r: 135, g: 75, b: 46 }, "PANTONE 471 C": { r: 170, g: 95, b: 57 }, "PANTONE 472 C": { r: 210, g: 130, b: 85 }, "PANTONE 473 C": { r: 230, g: 160, b: 115 }, "PANTONE 474 C": { r: 240, g: 185, b: 145 }, "PANTONE 475 C": { r: 245, g: 200, b: 165 }, "PANTONE 476 C": { r: 78, g: 54, b: 43 }, "PANTONE 477 C": { r: 95, g: 63, b: 49 }, "PANTONE 478 C": { r: 115, g: 75, b: 57 }, "PANTONE 479 C": { r: 155, g: 110, b: 87 }, "PANTONE 480 C": { r: 190, g: 150, b: 125 }, "PANTONE 481 C": { r: 210, g: 175, b: 150 }, "PANTONE 482 C": { r: 225, g: 195, b: 172 }, "PANTONE 483 C": { r: 95, g: 46, b: 36 }, "PANTONE 484 C": { r: 120, g: 50, b: 38 }, "PANTONE 485 C": { r: 155, g: 55, b: 41 }, "PANTONE 486 C": { r: 205, g: 105, b: 85 }, "PANTONE 487 C": { r: 220, g: 140, b: 120 }, "PANTONE 488 C": { r: 230, g: 170, b: 150 }, "PANTONE 489 C": { r: 240, g: 195, b: 178 }, "PANTONE 490 C": { r: 92, g: 46, b: 46 }, "PANTONE 491 C": { r: 115, g: 52, b: 52 }, "PANTONE 492 C": { r: 140, g: 58, b: 58 }, "PANTONE 493 C": { r: 190, g: 100, b: 100 }, "PANTONE 494 C": { r: 215, g: 140, b: 140 }, "PANTONE 495 C": { r: 230, g: 170, b: 170 }, "PANTONE 496 C": { r: 242, g: 195, b: 195 }, "PANTONE 497 C": { r: 82, g: 43, b: 43 }, "PANTONE 498 C": { r: 102, g: 48, b: 48 }, "PANTONE 499 C": { r: 127, g: 54, b: 54 }, "PANTONE 500 C": { r: 177, g: 97, b: 97 }, "PANTONE 501 C": { r: 210, g: 150, b: 150 }, "PANTONE 502 C": { r: 227, g: 185, b: 185 }, "PANTONE 503 C": { r: 242, g: 210, b: 210 }, "PANTONE 504 C": { r: 92, g: 38, b: 48 }, "PANTONE 505 C": { r: 115, g: 41, b: 56 }, "PANTONE 506 C": { r: 140, g: 46, b: 66 }, "PANTONE 507 C": { r: 190, g: 95, b: 115 }, "PANTONE 508 C": { r: 215, g: 140, b: 155 }, "PANTONE 509 C": { r: 230, g: 170, b: 180 }, "PANTONE 510 C": { r: 242, g: 200, b: 205 }, "PANTONE 511 C": { r: 92, g: 33, b: 56 }, "PANTONE 512 C": { r: 115, g: 36, b: 71 }, "PANTONE 513 C": { r: 145, g: 41, b: 92 }, "PANTONE 514 C": { r: 195, g: 95, b: 140 }, "PANTONE 515 C": { r: 220, g: 145, b: 175 }, "PANTONE 516 C": { r: 235, g: 180, b: 200 }, "PANTONE 517 C": { r: 245, g: 210, b: 220 }, "PANTONE 518 C": { r: 87, g: 33, b: 64 }, "PANTONE 519 C": { r: 107, g: 36, b: 79 }, "PANTONE 520 C": { r: 133, g: 41, b: 102 }, "PANTONE 521 C": { r: 179, g: 95, b: 150 }, "PANTONE 522 C": { r: 207, g: 145, b: 185 }, "PANTONE 523 C": { r: 225, g: 180, b: 205 }, "PANTONE 524 C": { r: 235, g: 205, b: 220 }, "PANTONE 525 C": { r: 87, g: 31, b: 74 }, "PANTONE 526 C": { r: 107, g: 33, b: 92 }, "PANTONE 527 C": { r: 133, g: 38, b: 117 }, "PANTONE 528 C": { r: 179, g: 95, b: 170 }, "PANTONE 529 C": { r: 207, g: 150, b: 200 }, "PANTONE 530 C": { r: 225, g: 185, b: 215 }, "PANTONE 531 C": { r: 235, g: 210, b: 230 }, "PANTONE 532 C": { r: 38, g: 41, b: 54 }, "PANTONE 533 C": { r: 41, g: 48, b: 69 }, "PANTONE 534 C": { r: 46, g: 56, b: 87 }, "PANTONE 535 C": { r: 102, g: 115, b: 153 }, "PANTONE 536 C": { r: 145, g: 155, b: 185 }, "PANTONE 537 C": { r: 180, g: 187, b: 207 }, "PANTONE 538 C": { r: 205, g: 210, b: 222 }, "PANTONE 539 C": { r: 0, g: 38, b: 61 }, "PANTONE 540 C": { r: 0, g: 48, b: 79 }, "PANTONE 541 C": { r: 0, g: 56, b: 99 }, "PANTONE 542 C": { r: 112, g: 155, b: 194 }, "PANTONE 543 C": { r: 155, g: 187, b: 215 }, "PANTONE 544 C": { r: 190, g: 210, b: 227 }, "PANTONE 545 C": { r: 210, g: 225, b: 237 }, "PANTONE 546 C": { r: 0, g: 43, b: 56 }, "PANTONE 547 C": { r: 0, g: 56, b: 74 }, "PANTONE 548 C": { r: 0, g: 66, b: 89 }, "PANTONE 549 C": { r: 97, g: 150, b: 175 }, "PANTONE 550 C": { r: 140, g: 182, b: 200 }, "PANTONE 551 C": { r: 175, g: 205, b: 217 }, "PANTONE 552 C": { r: 200, g: 220, b: 230 }, "PANTONE 553 C": { r: 38, g: 56, b: 48 }, "PANTONE 554 C": { r: 43, g: 71, b: 59 }, "PANTONE 555 C": { r: 48, g: 87, b: 71 }, "PANTONE 556 C": { r: 115, g: 160, b: 140 }, "PANTONE 557 C": { r: 155, g: 190, b: 175 }, "PANTONE 558 C": { r: 185, g: 210, b: 197 }, "PANTONE 559 C": { r: 207, g: 225, b: 215 }, "PANTONE 560 C": { r: 38, g: 61, b: 54 }, "PANTONE 561 C": { r: 41, g: 77, b: 69 }, "PANTONE 562 C": { r: 46, g: 97, b: 87 }, "PANTONE 563 C": { r: 107, g: 175, b: 165 }, "PANTONE 564 C": { r: 150, g: 205, b: 195 }, "PANTONE 565 C": { r: 185, g: 220, b: 215 }, "PANTONE 566 C": { r: 210, g: 232, b: 227 }, "PANTONE 567 C": { r: 38, g: 69, b: 61 }, "PANTONE 568 C": { r: 0, g: 87, b: 79 }, "PANTONE 569 C": { r: 0, g: 115, b: 107 }, "PANTONE 570 C": { r: 92, g: 185, b: 175 }, "PANTONE 571 C": { r: 140, g: 210, b: 200 }, "PANTONE 572 C": { r: 175, g: 225, b: 217 }, "PANTONE 573 C": { r: 205, g: 237, b: 232 }, "PANTONE 574 C": { r: 74, g: 79, b: 46 }, "PANTONE 575 C": { r: 89, g: 97, b: 56 }, "PANTONE 576 C": { r: 107, g: 117, b: 69 }, "PANTONE 577 C": { r: 155, g: 166, b: 115 }, "PANTONE 578 C": { r: 180, g: 189, b: 140 }, "PANTONE 579 C": { r: 200, g: 207, b: 165 }, "PANTONE 580 C": { r: 215, g: 220, b: 185 }, "PANTONE 581 C": { r: 89, g: 87, b: 38 }, "PANTONE 582 C": { r: 115, g: 112, b: 46 }, "PANTONE 583 C": { r: 145, g: 140, b: 56 }, "PANTONE 584 C": { r: 195, g: 190, b: 107 }, "PANTONE 585 C": { r: 217, g: 212, b: 140 }, "PANTONE 586 C": { r: 227, g: 222, b: 165 }, "PANTONE 587 C": { r: 235, g: 230, b: 185 }, "PANTONE 600 C": { r: 241, g: 233, b: 165 }, "PANTONE 601 C": { r: 240, g: 230, b: 140 }, "PANTONE 602 C": { r: 240, g: 228, b: 115 }, "PANTONE 603 C": { r: 238, g: 222, b: 82 }, "PANTONE 604 C": { r: 235, g: 215, b: 46 }, "PANTONE 605 C": { r: 230, g: 205, b: 10 }, "PANTONE 606 C": { r: 225, g: 195, b: 0 }, "PANTONE 607 C": { r: 236, g: 230, b: 165 }, "PANTONE 608 C": { r: 234, g: 227, b: 140 }, "PANTONE 609 C": { r: 232, g: 224, b: 115 }, "PANTONE 610 C": { r: 228, g: 217, b: 82 }, "PANTONE 611 C": { r: 223, g: 210, b: 46 }, "PANTONE 612 C": { r: 217, g: 200, b: 10 }, "PANTONE 613 C": { r: 210, g: 190, b: 0 }, "PANTONE 614 C": { r: 220, g: 212, b: 165 }, "PANTONE 615 C": { r: 215, g: 207, b: 140 }, "PANTONE 616 C": { r: 210, g: 200, b: 115 }, "PANTONE 617 C": { r: 200, g: 187, b: 82 }, "PANTONE 618 C": { r: 187, g: 172, b: 46 }, "PANTONE 619 C": { r: 172, g: 155, b: 10 }, "PANTONE 620 C": { r: 155, g: 138, b: 0 }, "PANTONE 621 C": { r: 205, g: 217, b: 210 }, "PANTONE 622 C": { r: 175, g: 200, b: 190 }, "PANTONE 623 C": { r: 145, g: 182, b: 170 }, "PANTONE 624 C": { r: 115, g: 165, b: 150 }, "PANTONE 625 C": { r: 82, g: 145, b: 130 }, "PANTONE 626 C": { r: 46, g: 115, b: 100 }, "PANTONE 627 C": { r: 15, g: 82, b: 71 }, "PANTONE 628 C": { r: 200, g: 227, b: 230 }, "PANTONE 629 C": { r: 165, g: 210, b: 220 }, "PANTONE 630 C": { r: 130, g: 195, b: 210 }, "PANTONE 631 C": { r: 90, g: 175, b: 195 }, "PANTONE 632 C": { r: 46, g: 150, b: 175 }, "PANTONE 633 C": { r: 0, g: 120, b: 150 }, "PANTONE 634 C": { r: 0, g: 95, b: 120 }, "PANTONE 635 C": { r: 185, g: 220, b: 230 }, "PANTONE 636 C": { r: 145, g: 205, b: 225 }, "PANTONE 637 C": { r: 100, g: 187, b: 215 }, "PANTONE 638 C": { r: 46, g: 165, b: 205 }, "PANTONE 639 C": { r: 0, g: 140, b: 185 }, "PANTONE 640 C": { r: 0, g: 115, b: 160 }, "PANTONE 641 C": { r: 0, g: 95, b: 135 }, "PANTONE 642 C": { r: 210, g: 215, b: 220 }, "PANTONE 643 C": { r: 195, g: 200, b: 210 }, "PANTONE 644 C": { r: 165, g: 175, b: 195 }, "PANTONE 645 C": { r: 135, g: 150, b: 175 }, "PANTONE 646 C": { r: 110, g: 125, b: 155 }, "PANTONE 647 C": { r: 82, g: 97, b: 130 }, "PANTONE 648 C": { r: 56, g: 71, b: 107 }, "PANTONE 649 C": { r: 220, g: 215, b: 220 }, "PANTONE 650 C": { r: 205, g: 195, b: 210 }, "PANTONE 651 C": { r: 180, g: 165, b: 195 }, "PANTONE 652 C": { r: 150, g: 130, b: 175 }, "PANTONE 653 C": { r: 120, g: 95, b: 155 }, "PANTONE 654 C": { r: 95, g: 66, b: 130 }, "PANTONE 655 C": { r: 74, g: 43, b: 107 }, "PANTONE 656 C": { r: 225, g: 220, b: 230 }, "PANTONE 657 C": { r: 210, g: 200, b: 225 }, "PANTONE 658 C": { r: 190, g: 175, b: 215 }, "PANTONE 659 C": { r: 165, g: 140, b: 200 }, "PANTONE 660 C": { r: 135, g: 100, b: 180 }, "PANTONE 661 C": { r: 105, g: 64, b: 155 }, "PANTONE 662 C": { r: 82, g: 38, b: 135 }, "PANTONE 663 C": { r: 235, g: 225, b: 230 }, "PANTONE 664 C": { r: 225, g: 210, b: 220 }, "PANTONE 665 C": { r: 210, g: 187, b: 205 }, "PANTONE 666 C": { r: 185, g: 155, b: 185 }, "PANTONE 667 C": { r: 155, g: 115, b: 160 }, "PANTONE 668 C": { r: 130, g: 85, b: 135 }, "PANTONE 669 C": { r: 107, g: 59, b: 115 }, "PANTONE 670 C": { r: 245, g: 220, b: 230 }, "PANTONE 671 C": { r: 240, g: 205, b: 220 }, "PANTONE 672 C": { r: 235, g: 185, b: 205 }, "PANTONE 673 C": { r: 225, g: 155, b: 185 }, "PANTONE 674 C": { r: 210, g: 115, b: 160 }, "PANTONE 675 C": { r: 195, g: 74, b: 135 }, "PANTONE 676 C": { r: 179, g: 33, b: 107 }, "PANTONE 677 C": { r: 242, g: 215, b: 220 }, "PANTONE 678 C": { r: 237, g: 200, b: 210 }, "PANTONE 679 C": { r: 232, g: 180, b: 195 }, "PANTONE 680 C": { r: 220, g: 145, b: 170 }, "PANTONE 681 C": { r: 205, g: 107, b: 145 }, "PANTONE 682 C": { r: 187, g: 66, b: 120 }, "PANTONE 683 C": { r: 166, g: 25, b: 95 }, "PANTONE 684 C": { r: 240, g: 210, b: 215 }, "PANTONE 685 C": { r: 235, g: 190, b: 200 }, "PANTONE 686 C": { r: 227, g: 165, b: 180 }, "PANTONE 687 C": { r: 212, g: 130, b: 155 }, "PANTONE 688 C": { r: 195, g: 92, b: 130 }, "PANTONE 689 C": { r: 176, g: 51, b: 105 }, "PANTONE 690 C": { r: 153, g: 10, b: 79 }, "PANTONE 691 C": { r: 242, g: 205, b: 205 }, "PANTONE 692 C": { r: 235, g: 180, b: 185 }, "PANTONE 693 C": { r: 225, g: 150, b: 160 }, "PANTONE 694 C": { r: 210, g: 115, b: 130 }, "PANTONE 695 C": { r: 192, g: 77, b: 102 }, "PANTONE 696 C": { r: 171, g: 36, b: 74 }, "PANTONE 697 C": { r: 148, g: 0, b: 46 }, "PANTONE 698 C": { r: 242, g: 200, b: 200 }, "PANTONE 699 C": { r: 237, g: 172, b: 175 }, "PANTONE 700 C": { r: 230, g: 140, b: 150 }, "PANTONE 701 C": { r: 220, g: 105, b: 120 }, "PANTONE 702 C": { r: 205, g: 66, b: 92 }, "PANTONE 703 C": { r: 187, g: 25, b: 64 }, "PANTONE 704 C": { r: 166, g: 0, b: 36 }, "PANTONE 705 C": { r: 245, g: 215, b: 215 }, "PANTONE 706 C": { r: 242, g: 190, b: 195 }, "PANTONE 707 C": { r: 237, g: 160, b: 170 }, "PANTONE 708 C": { r: 230, g: 125, b: 140 }, "PANTONE 709 C": { r: 220, g: 87, b: 110 }, "PANTONE 710 C": { r: 207, g: 46, b: 82 }, "PANTONE 711 C": { r: 192, r: 5, b: 56 }, "PANTONE 712 C": { r: 255, g: 220, b: 190 }, "PANTONE 713 C": { r: 255, g: 205, b: 165 }, "PANTONE 714 C": { r: 255, g: 187, b: 130 }, "PANTONE 715 C": { r: 255, g: 165, b: 87 }, "PANTONE 716 C": { r: 255, g: 140, b: 46 }, "PANTONE 717 C": { r: 250, g: 112, b: 0 }, "PANTONE 718 C": { r: 240, g: 95, b: 0 }, "PANTONE 719 C": { r: 245, g: 210, b: 180 }, "PANTONE 720 C": { r: 242, g: 195, b: 155 }, "PANTONE 721 C": { r: 237, g: 175, b: 125 }, "PANTONE 722 C": { r: 230, g: 150, b: 92 }, "PANTONE 723 C": { r: 220, g: 122, b: 56 }, "PANTONE 724 C": { r: 207, g: 92, b: 20 }, "PANTONE 725 C": { r: 192, g: 71, b: 0 }, "PANTONE 726 C": { r: 230, g: 205, b: 175 }, "PANTONE 727 C": { r: 222, g: 187, b: 150 }, "PANTONE 728 C": { r: 212, g: 165, b: 120 }, "PANTONE 729 C": { r: 200, g: 140, b: 87 }, "PANTONE 730 C": { r: 185, g: 112, b: 56 }, "PANTONE 731 C": { r: 166, g: 84, b: 28 }, "PANTONE 732 C": { r: 145, g: 61, b: 10 }, "PANTONE 7401 C": { r: 242, g: 227, b: 187 }, "PANTONE 7402 C": { r: 237, g: 222, b: 170 }, "PANTONE 7403 C": { r: 232, g: 217, b: 150 }, "PANTONE 7404 C": { r: 230, g: 212, b: 115 }, "PANTONE 7405 C": { r: 225, g: 205, b: 77 }, "PANTONE 7406 C": { r: 220, g: 195, b: 36 }, "PANTONE 7407 C": { r: 195, g: 170, b: 61 }, "PANTONE 7408 C": { r: 255, g: 200, b: 69 }, "PANTONE 7409 C": { r: 255, g: 190, b: 46 }, "PANTONE 7410 C": { r: 255, g: 175, b: 87 }, "PANTONE 7411 C": { r: 242, g: 160, b: 61 }, "PANTONE 7412 C": { r: 230, g: 135, b: 36 }, "PANTONE 7413 C": { r: 220, g: 115, b: 25 }, "PANTONE 7414 C": { r: 200, g: 95, b: 15 }, "PANTONE 7415 C": { r: 235, g: 200, b: 195 }, "PANTONE 7416 C": { r: 255, g: 145, b: 130 }, "PANTONE 7417 C": { r: 255, g: 105, b: 87 }, "PANTONE 7418 C": { r: 250, g: 77, b: 87 }, "PANTONE 7419 C": { r: 230, g: 56, b: 87 }, "PANTONE 7420 C": { r: 207, g: 36, b: 79 }, "PANTONE 7421 C": { r: 153, g: 10, b: 56 }, "PANTONE 7422 C": { r: 245, g: 210, b: 220 }, "PANTONE 7423 C": { r: 245, g: 145, b: 170 }, "PANTONE 7424 C": { r: 242, g: 105, b: 145 }, "PANTONE 7425 C": { r: 230, g: 66, b: 120 }, "PANTONE 7426 C": { r: 212, g: 36, b: 95 }, "PANTONE 7427 C": { r: 192, g: 15, b: 74 }, "PANTONE 7428 C": { r: 140, g: 0, b: 56 }, "PANTONE 7429 C": { r: 232, g: 195, b: 215 }, "PANTONE 7430 C": { r: 225, g: 170, b: 200 }, "PANTONE 7431 C": { r: 215, g: 140, b: 180 }, "PANTONE 7432 C": { r: 200, g: 105, b: 155 }, "PANTONE 7433 C": { r: 185, g: 71, b: 135 }, "PANTONE 7434 C": { r: 166, g: 41, b: 115 }, "PANTONE 7435 C": { r: 140, g: 10, b: 87 }, "PANTONE 7436 C": { r: 230, g: 210, b: 230 }, "PANTONE 7437 C": { r: 215, g: 175, b: 215 }, "PANTONE 7438 C": { r: 200, g: 140, b: 200 }, "PANTONE 7439 C": { r: 180, g: 105, b: 180 }, "PANTONE 7440 C": { r: 160, g: 74, b: 160 }, "PANTONE 7441 C": { r: 140, g: 46, b: 145 }, "PANTONE 7442 C": { r: 115, g: 15, b: 125 }, "PANTONE 7443 C": { r: 230, g: 220, b: 235 }, "PANTONE 7444 C": { r: 210, g: 195, b: 230 }, "PANTONE 7445 C": { r: 185, g: 165, b: 215 }, "PANTONE 7446 C": { r: 155, g: 130, b: 195 }, "PANTONE 7447 C": { r: 120, g: 92, b: 166 }, "PANTONE 7448 C": { r: 92, g: 66, b: 130 }, "PANTONE 7449 C": { r: 66, g: 41, b: 97 }, "PANTONE 7450 C": { r: 190, g: 205, b: 230 }, "PANTONE 7451 C": { r: 150, g: 180, b: 230 }, "PANTONE 7452 C": { r: 115, g: 155, b: 225 }, "PANTONE 7453 C": { r: 82, g: 135, b: 215 }, "PANTONE 7454 C": { r: 56, g: 115, b: 195 }, "PANTONE 7455 C": { r: 33, g: 95, b: 175 }, "PANTONE 7456 C": { r: 15, g: 77, b: 155 }, "PANTONE 7457 C": { r: 195, g: 225, b: 240 }, "PANTONE 7458 C": { r: 145, g: 205, b: 230 }, "PANTONE 7459 C": { r: 100, g: 185, b: 220 }, "PANTONE 7460 C": { r: 46, g: 160, b: 210 }, "PANTONE 7461 C": { r: 0, g: 130, b: 190 }, "PANTONE 7462 C": { r: 0, g: 105, b: 165 }, "PANTONE 7463 C": { r: 0, g: 82, b: 140 }, "PANTONE 7464 C": { r: 175, g: 230, b: 230 }, "PANTONE 7465 C": { r: 115, g: 220, b: 220 }, "PANTONE 7466 C": { r: 56, g: 205, b: 215 }, "PANTONE 7467 C": { r: 0, g: 185, b: 205 }, "PANTONE 7468 C": { r: 0, g: 145, b: 175 }, "PANTONE 7469 C": { r: 0, g: 115, b: 150 }, "PANTONE 7470 C": { r: 0, g: 92, b: 125 }, "PANTONE 7471 C": { r: 135, g: 230, b: 215 }, "PANTONE 7472 C": { r: 87, g: 215, b: 195 }, "PANTONE 7473 C": { r: 46, g: 200, b: 175 }, "PANTONE 7474 C": { r: 0, g: 170, b: 155 }, "PANTONE 7475 C": { r: 0, g: 135, b: 130 }, "PANTONE 7476 C": { r: 0, g: 105, b: 110 }, "PANTONE 7477 C": { r: 0, g: 77, b: 87 }, "PANTONE 7478 C": { r: 175, g: 235, b: 195 }, "PANTONE 7479 C": { r: 105, g: 225, b: 150 }, "PANTONE 7480 C": { r: 46, g: 215, b: 115 }, "PANTONE 7481 C": { r: 0, g: 195, b: 87 }, "PANTONE 7482 C": { r: 0, g: 170, b: 69 }, "PANTONE 7483 C": { r: 0, g: 130, b: 56 }, "PANTONE 7484 C": { r: 0, g: 97, b: 46 }, "PANTONE 7485 C": { r: 215, g: 240, b: 195 }, "PANTONE 7486 C": { r: 170, g: 235, b: 155 }, "PANTONE 7487 C": { r: 120, g: 225, b: 115 }, "PANTONE 7488 C": { r: 69, g: 215, b: 77 }, "PANTONE 7489 C": { r: 28, g: 195, b: 56 }, "PANTONE 7490 C": { r: 0, g: 166, b: 46 }, "PANTONE 7491 C": { r: 0, g: 138, b: 41 }, "PANTONE 7492 C": { r: 200, g: 230, b: 155 }, "PANTONE 7493 C": { r: 180, g: 220, b: 145 }, "PANTONE 7494 C": { r: 155, g: 205, b: 130 }, "PANTONE 7495 C": { r: 120, g: 185, b: 95 }, "PANTONE 7496 C": { r: 87, g: 160, b: 66 }, "PANTONE 7497 C": { r: 130, g: 130, b: 92 }, "PANTONE 7498 C": { r: 92, g: 97, b: 61 }, "PANTONE 7499 C": { r: 242, g: 230, b: 195 }, "PANTONE 7500 C": { r: 235, g: 220, b: 177 }, "PANTONE 7501 C": { r: 227, g: 210, b: 160 }, "PANTONE 7502 C": { r: 220, g: 200, b: 140 }, "PANTONE 7503 C": { r: 205, g: 182, b: 115 }, "PANTONE 7504 C": { r: 185, g: 155, b: 87 }, "PANTONE 7505 C": { r: 166, g: 130, b: 61 }, "PANTONE 7506 C": { r: 245, g: 225, b: 200 }, "PANTONE 7507 C": { r: 242, g: 210, b: 170 }, "PANTONE 7508 C": { r: 235, g: 195, b: 140 }, "PANTONE 7509 C": { r: 227, g: 180, b: 115 }, "PANTONE 7510 C": { r: 215, g: 160, b: 87 }, "PANTONE 7511 C": { r: 200, g: 140, b: 61 }, "PANTONE 7512 C": { r: 182, g: 120, b: 41 }, "PANTONE 7513 C": { r: 230, g: 195, b: 175 }, "PANTONE 7514 C": { r: 220, g: 175, b: 145 }, "PANTONE 7515 C": { r: 210, g: 155, b: 120 }, "PANTONE 7516 C": { r: 195, g: 130, b: 87 }, "PANTONE 7517 C": { r: 175, g: 105, b: 61 }, "PANTONE 7518 C": { r: 150, g: 82, b: 41 }, "PANTONE 7519 C": { r: 125, g: 61, b: 28 }, "PANTONE 7520 C": { r: 230, g: 195, b: 185 }, "PANTONE 7521 C": { r: 215, g: 170, b: 155 }, "PANTONE 7522 C": { r: 200, g: 145, b: 125 }, "PANTONE 7523 C": { r: 185, g: 122, b: 105 }, "PANTONE 7524 C": { r: 170, g: 100, b: 82 }, "PANTONE 7525 C": { r: 150, g: 79, b: 64 }, "PANTONE 7526 C": { r: 130, g: 59, b: 46 }, "PANTONE 7527 C": { r: 220, g: 215, b: 195 }, "PANTONE 7528 C": { r: 205, g: 197, b: 175 }, "PANTONE 7529 C": { r: 190, g: 180, b: 155 }, "PANTONE 7530 C": { r: 170, g: 160, b: 135 }, "PANTONE 7531 C": { r: 145, g: 135, b: 110 }, "PANTONE 7532 C": { r: 120, g: 110, b: 87 }, "PANTONE 7533 C": { r: 97, g: 87, b: 66 }, "PANTONE 7534 C": { r: 210, g: 205, b: 180 }, "PANTONE 7535 C": { r: 190, g: 185, b: 160 }, "PANTONE 7536 C": { r: 170, g: 165, b: 140 }, "PANTONE 7537 C": { r: 195, g: 200, b: 185 }, "PANTONE 7538 C": { r: 175, g: 182, b: 170 }, "PANTONE 7539 C": { r: 155, g: 162, b: 150 }, "PANTONE 7540 C": { r: 125, g: 135, b: 125 }, "PANTONE 7541 C": { r: 225, g: 235, b: 242 }, "PANTONE 7542 C": { r: 195, g: 220, b: 230 }, "PANTONE 7543 C": { r: 175, g: 200, b: 215 }, "PANTONE 7544 C": { r: 145, g: 175, b: 195 }, "PANTONE 7545 C": { r: 115, g: 150, b: 175 }, "PANTONE 7546 C": { r: 82, g: 122, b: 150 }, "PANTONE 7547 C": { r: 56, g: 97, b: 125 }, "PANTONE 7548 C": { r: 255, g: 230, b: 115 }, "PANTONE 7549 C": { r: 255, g: 215, b: 56 }, "PANTONE 7550 C": { r: 230, g: 190, b: 41 }, "PANTONE 7551 C": { r: 215, g: 170, b: 33 }, "PANTONE 7552 C": { r: 195, g: 145, b: 25 }, "PANTONE 7553 C": { r: 170, g: 120, b: 18 }, "PANTONE 7554 C": { r: 140, g: 95, b: 13 }, "PANTONE 7555 C": { r: 235, g: 200, b: 100 }, "PANTONE 7556 C": { r: 220, g: 175, b: 74 }, "PANTONE 7557 C": { r: 200, g: 150, b: 51 }, "PANTONE 7558 C": { r: 182, g: 130, b: 36 }, "PANTONE 7559 C": { r: 165, g: 112, b: 25 }, "PANTONE 7560 C": { r: 150, g: 97, b: 18 }, "PANTONE 7561 C": { r: 135, g: 82, b: 10 }, "PANTONE 7562 C": { r: 205, g: 185, b: 140 }, "PANTONE 7563 C": { r: 195, g: 170, b: 105 }, "PANTONE 7564 C": { r: 185, g: 155, b: 74 }, "PANTONE 7565 C": { r: 175, g: 140, b: 46 }, "PANTONE 7566 C": { r: 160, g: 120, b: 25 }, "PANTONE 7567 C": { r: 145, g: 105, b: 15 }, "PANTONE 7568 C": { r: 130, g: 90, b: 8 }, "PANTONE 7569 C": { r: 230, g: 160, b: 61 }, "PANTONE 7570 C": { r: 220, g: 140, b: 46 }, "PANTONE 7571 C": { r: 205, g: 122, b: 36 }, "PANTONE 7572 C": { r: 190, g: 105, b: 28 }, "PANTONE 7573 C": { r: 175, g: 90, b: 20 }, "PANTONE 7574 C": { r: 160, g: 77, b: 15 }, "PANTONE 7575 C": { r: 140, g: 64, b: 10 }, "PANTONE 7576 C": { r: 230, g: 130, b: 71 }, "PANTONE 7577 C": { r: 220, g: 115, b: 56 }, "PANTONE 7578 C": { r: 210, g: 100, b: 41 }, "PANTONE 7579 C": { r: 200, g: 87, b: 30 }, "PANTONE 7580 C": { r: 185, g: 74, b: 20 }, "PANTONE 7581 C": { r: 170, g: 64, b: 15 }, "PANTONE 7582 C": { r: 150, g: 54, b: 10 }, "PANTONE 7583 C": { r: 220, g: 105, b: 56 }, "PANTONE 7584 C": { r: 210, g: 90, b: 46 }, "PANTONE 7585 C": { r: 195, g: 79, b: 38 }, "PANTONE 7586 C": { r: 182, g: 69, b: 30 }, "PANTONE 7587 C": { r: 170, g: 61, b: 23 }, "PANTONE 7588 C": { r: 155, g: 54, b: 18 }, "PANTONE 7589 C": { r: 140, g: 46, b: 13 }, "PANTONE 7590 C": { r: 205, g: 160, b: 130 }, "PANTONE 7591 C": { r: 195, g: 140, b: 105 }, "PANTONE 7592 C": { r: 185, g: 122, b: 87 }, "PANTONE 7593 C": { r: 175, g: 105, b: 71 }, "PANTONE 7594 C": { r: 160, g: 90, b: 59 }, "PANTONE 7595 C": { r: 145, g: 77, b: 48 }, "PANTONE 7596 C": { r: 130, g: 64, b: 38 }, "PANTONE 7597 C": { r: 200, g: 87, b: 56 }, "PANTONE 7598 C": { r: 190, g: 77, b: 48 }, "PANTONE 7599 C": { r: 180, g: 69, b: 41 }, "PANTONE 7600 C": { r: 170, g: 61, b: 36 }, "PANTONE 7601 C": { r: 160, g: 54, b: 30 }, "PANTONE 7602 C": { r: 150, g: 48, b: 25 }, "PANTONE 7603 C": { r: 135, g: 41, b: 20 }, "PANTONE 7604 C": { r: 215, g: 180, b: 175 }, "PANTONE 7605 C": { r: 205, g: 160, b: 155 }, "PANTONE 7606 C": { r: 195, g: 140, b: 135 }, "PANTONE 7607 C": { r: 185, g: 122, b: 115 }, "PANTONE 7608 C": { r: 175, g: 105, b: 97 }, "PANTONE 7609 C": { r: 160, g: 87, b: 79 }, "PANTONE 7610 C": { r: 145, g: 71, b: 64 }, "PANTONE 7611 C": { r: 200, g: 160, b: 150 }, "PANTONE 7612 C": { r: 187, g: 145, b: 135 }, "PANTONE 7613 C": { r: 175, g: 130, b: 120 }, "PANTONE 7614 C": { r: 160, g: 115, b: 105 }, "PANTONE 7615 C": { r: 145, g: 100, b: 90 }, "PANTONE 7616 C": { r: 130, g: 85, b: 77 }, "PANTONE 7617 C": { r: 115, g: 71, b: 64 }, "PANTONE 7618 C": { r: 200, g: 130, b: 105 }, "PANTONE 7619 C": { r: 190, g: 110, b: 82 }, "PANTONE 7620 C": { r: 180, g: 92, b: 61 }, "PANTONE 7621 C": { r: 170, g: 77, b: 46 }, "PANTONE 7622 C": { r: 160, g: 64, b: 33 }, "PANTONE 7623 C": { r: 150, g: 54, b: 23 }, "PANTONE 7624 C": { r: 140, g: 46, b: 15 }, "PANTONE 7625 C": { r: 210, g: 100, b: 64 }, "PANTONE 7626 C": { r: 200, g: 82, b: 48 }, "PANTONE 7627 C": { r: 190, g: 69, b: 36 }, "PANTONE 7628 C": { r: 180, g: 59, b: 28 }, "PANTONE 7629 C": { r: 170, g: 51, b: 20 }, "PANTONE 7630 C": { r: 160, g: 43, b: 15 }, "PANTONE 7631 C": { r: 150, g: 36, b: 10 }, "PANTONE 7632 C": { r: 210, g: 205, b: 200 }, "PANTONE 7633 C": { r: 195, g: 187, b: 182 }, "PANTONE 7634 C": { r: 180, g: 170, b: 165 }, "PANTONE 7635 C": { r: 165, g: 154, b: 148 }, "PANTONE 7636 C": { r: 150, g: 138, b: 132 }, "PANTONE 7637 C": { r: 135, g: 122, b: 115 }, "PANTONE 7638 C": { r: 120, g: 107, b: 100 }, "PANTONE 7639 C": { r: 195, g: 180, b: 170 }, "PANTONE 7640 C": { r: 180, g: 160, b: 148 }, "PANTONE 7641 C": { r: 165, g: 140, b: 128 }, "PANTONE 7642 C": { r: 150, g: 122, b: 110 }, "PANTONE 7643 C": { r: 135, g: 105, b: 95 }, "PANTONE 7644 C": { r: 120, g: 90, b: 80 }, "PANTONE 7645 C": { r: 105, g: 77, b: 66 }, "PANTONE 7646 C": { r: 185, g: 145, b: 130 }, "PANTONE 7647 C": { r: 170, g: 122, b: 105 }, "PANTONE 7648 C": { r: 155, g: 100, b: 82 }, "PANTONE 7649 C": { r: 140, g: 82, b: 64 }, "PANTONE 7650 C": { r: 125, g: 66, b: 51 }, "PANTONE 7651 C": { r: 110, g: 54, b: 41 }, "PANTONE 7652 C": { r: 97, g: 43, b: 33 }, "PANTONE 7653 C": { r: 190, g: 180, b: 170 }, "PANTONE 7654 C": { r: 180, g: 165, b: 155 }, "PANTONE 7655 C": { r: 170, g: 150, b: 140 }, "PANTONE 7656 C": { r: 160, g: 135, b: 125 }, "PANTONE 7657 C": { r: 150, g: 122, b: 110 }, "PANTONE 7658 C": { r: 140, g: 110, b: 97 }, "PANTONE 7659 C": { r: 130, g: 97, b: 87 }, "PANTONE 7660 C": { r: 185, g: 170, b: 160 }, "PANTONE 7661 C": { r: 175, g: 155, b: 145 }, "PANTONE 7662 C": { r: 165, g: 140, b: 130 }, "PANTONE 7663 C": { r: 155, g: 128, b: 115 }, "PANTONE 7664 C": { r: 145, g: 115, b: 105 }, "PANTONE 7665 C": { r: 135, g: 105, b: 92 }, "PANTONE 7666 C": { r: 125, g: 95, b: 82 }, "PANTONE 7667 C": { r: 175, g: 150, b: 140 }, "PANTONE 7668 C": { r: 165, g: 135, b: 125 }, "PANTONE 7669 C": { r: 155, g: 122, b: 110 }, "PANTONE 7670 C": { r: 145, g: 110, b: 97 }, "PANTONE 7671 C": { r: 135, g: 97, b: 87 }, "PANTONE 7672 C": { r: 125, g: 87, b: 77 }, "PANTONE 7673 C": { r: 115, g: 77, b: 66 }, "PANTONE 7674 C": { r: 165, g: 140, b: 145 }, "PANTONE 7675 C": { r: 155, g: 128, b: 135 }, "PANTONE 7676 C": { r: 145, g: 115, b: 122 }, "PANTONE 7677 C": { r: 135, g: 105, b: 110 }, "PANTONE 7678 C": { r: 125, g: 95, b: 100 }, "PANTONE 7679 C": { r: 115, g: 85, b: 90 }, "PANTONE 7680 C": { r: 105, g: 74, b: 79 }, "PANTONE 7681 C": { r: 155, g: 135, b: 150 }, "PANTONE 7682 C": { r: 145, g: 122, b: 140 }, "PANTONE 7683 C": { r: 135, g: 110, b: 130 }, "PANTONE 7684 C": { r: 125, g: 97, b: 120 }, "PANTONE 7685 C": { r: 115, g: 87, b: 110 }, "PANTONE 7686 C": { r: 105, g: 77, b: 100 }, "PANTONE 7687 C": { r: 95, g: 66, b: 90 }, "PANTONE 7688 C": { r: 145, g: 122, b: 155 }, "PANTONE 7689 C": { r: 135, g: 110, b: 145 }, "PANTONE 7690 C": { r: 125, g: 97, b: 135 }, "PANTONE 7691 C": { r: 115, g: 87, b: 125 }, "PANTONE 7692 C": { r: 105, g: 77, b: 115 }, "PANTONE 7693 C": { r: 95, g: 66, b: 105 }, "PANTONE 7694 C": { r: 85, g: 59, b: 95 }, "PANTONE 7695 C": { r: 140, g: 130, b: 160 }, "PANTONE 7696 C": { r: 130, g: 120, b: 150 }, "PANTONE 7697 C": { r: 120, g: 110, b: 140 }, "PANTONE 7698 C": { r: 110, g: 100, b: 130 }, "PANTONE 7699 C": { r: 100, g: 90, b: 120 }, "PANTONE 7700 C": { r: 90, g: 80, b: 110 }, "PANTONE 7701 C": { r: 80, g: 71, b: 100 }, "PANTONE 7702 C": { r: 135, g: 115, b: 77 }, "PANTONE 7703 C": { r: 125, g: 105, b: 64 }, "PANTONE 7704 C": { r: 115, g: 95, b: 54 }, "PANTONE 7705 C": { r: 105, g: 85, b: 46 }, "PANTONE 7706 C": { r: 95, g: 77, b: 38 }, "PANTONE 7707 C": { r: 87, g: 69, b: 31 }, "PANTONE 7708 C": { r: 77, g: 61, b: 25 }, "PANTONE 7709 C": { r: 140, g: 125, b: 100 }, "PANTONE 7710 C": { r: 125, g: 110, b: 87 }, "PANTONE 7711 C": { r: 115, g: 100, b: 77 }, "PANTONE 7712 C": { r: 105, g: 90, b: 69 }, "PANTONE 7713 C": { r: 95, g: 82, b: 61 }, "PANTONE 7714 C": { r: 87, g: 74, b: 56 }, "PANTONE 7715 C": { r: 77, g: 66, b: 48 }, "PANTONE 7716 C": { r: 140, g: 130, b: 115 }, "PANTONE 7717 C": { r: 128, g: 117, b: 102 }, "PANTONE 7718 C": { r: 117, g: 107, b: 92 }, "PANTONE 7719 C": { r: 107, g: 97, b: 84 }, "PANTONE 7720 C": { r: 97, g: 87, b: 74 }, "PANTONE 7721 C": { r: 87, g: 79, b: 66 }, "PANTONE 7722 C": { r: 77, g: 69, b: 59 }, "PANTONE 7723 C": { r: 135, g: 130, b: 120 }, "PANTONE 7724 C": { r: 125, g: 120, b: 110 }, "PANTONE 7725 C": { r: 115, g: 110, b: 102 }, "PANTONE 7726 C": { r: 105, g: 100, b: 92 }, "PANTONE 7727 C": { r: 95, g: 90, b: 84 }, "PANTONE 7728 C": { r: 87, g: 82, b: 77 }, "PANTONE 7729 C": { r: 77, g: 74, b: 69 }, "PANTONE 7730 C": { r: 130, g: 135, b: 125 }, "PANTONE 7731 C": { r: 120, g: 125, b: 115 }, "PANTONE 7732 C": { r: 110, g: 115, b: 105 }, "PANTONE 7733 C": { r: 102, g: 107, b: 97 }, "PANTONE 7734 C": { r: 92, g: 97, b: 89 }, "PANTONE 7735 C": { r: 84, g: 89, b: 82 }, "PANTONE 7736 C": { r: 77, g: 82, b: 74 }, "PANTONE 7737 C": { r: 125, g: 135, b: 130 }, "PANTONE 7738 C": { r: 115, g: 125, b: 120 }, "PANTONE 7739 C": { r: 107, g: 117, b: 112 }, "PANTONE 7740 C": { r: 97, g: 107, b: 102 }, "PANTONE 7741 C": { r: 89, g: 99, b: 94 }, "PANTONE 7742 C": { r: 82, g: 92, b: 87 }, "PANTONE 7743 C": { r: 74, g: 84, b: 79 }, "PANTONE 7744 C": { r: 120, g: 135, b: 135 }, "PANTONE 7745 C": { r: 110, g: 125, b: 125 }, "PANTONE 7746 C": { r: 102, g: 117, b: 117 }, "PANTONE 7747 C": { r: 94, g: 109, b: 109 }, "PANTONE 7748 C": { r: 87, g: 102, b: 102 }, "PANTONE 7749 C": { r: 79, g: 94, b: 94 }, "PANTONE 7750 C": { r: 74, g: 89, b: 89 }, "PANTONE 7751 C": { r: 115, g: 130, b: 135 }, "PANTONE 7752 C": { r: 105, g: 120, b: 125 }, "PANTONE 7753 C": { r: 97, g: 112, b: 117 }, "PANTONE 7754 C": { r: 89, g: 104, b: 109 }, "PANTONE 7755 C": { r: 82, g: 97, b: 102 }, "PANTONE 7756 C": { r: 74, g: 89, b: 94 }, "PANTONE 7757 C": { r: 69, g: 84, b: 89 }, "PANTONE 7758 C": { r: 110, g: 120, b: 135 }, "PANTONE 7759 C": { r: 100, g: 110, b: 125 }, "PANTONE 7760 C": { r: 92, g: 102, b: 117 }, "PANTONE 7761 C": { r: 84, g: 94, b: 109 }, "PANTONE 7762 C": { r: 77, g: 87, b: 102 }, "PANTONE 7763 C": { r: 71, g: 81, b: 97 }, "PANTONE 7764 C": { r: 64, g: 74, b: 89 }, "PANTONE 7765 C": { r: 105, g: 110, b: 130 }, "PANTONE 7766 C": { r: 97, g: 102, b: 122 }, "PANTONE 7767 C": { r: 89, g: 94, b: 115 }, "PANTONE 7768 C": { r: 82, g: 87, b: 107 }, "PANTONE 7769 C": { r: 74, g: 79, b: 100 }, "PANTONE 7770 C": { r: 69, g: 74, b: 94 }, "PANTONE 7771 C": { r: 61, g: 66, b: 87 } }; // Глобальные переменные let allColors = []; let allRecipes = {}; let ref = { name: "PANTONE 116 C", r: 255, g: 206, b: 0, l: 85.48, c: 88.37, h: 84.58 }; let sample = { name: "PANTONE 109 C", r: 255, g: 209, b: 0, l: 86.31, c: 97.86, h: 86.35 }; let dragging = null; let transWhitePercent = 0; // Trans White характеристики (прозрачный лак) const transWhite = { name: "Trans White", r: 255, g: 255, b: 255, l: 100, c: 0, h: 0 }; // Базовые цвета (Rhodamine убран, добавлен Orange 021 C) const baseColors = [ { name: "Yellow", r: 254, g: 222, b: 0, l: 89.09, c: 110.90, h: 90.80, bg: "#FEDE00", fg: "#000" }, { name: "Orange 021", r: 254, g: 81, b: 0, l: 60.91, c: 106.5, h: 48.5, bg: "#FE5100", fg: "#fff" }, { name: "Warm Red", r: 250, g: 67, b: 64, l: 58.89, c: 85.01, h: 34.50, bg: "#FA4340", fg: "#fff" }, { name: "Red 032", r: 239, g: 51, b: 68, l: 55.28, c: 83.17, h: 29.70, bg: "#EF3344", fg: "#fff" }, { name: "Rubine", r: 206, g: 0, b: 93, l: 43.92, c: 79.98, h: 7.33, bg: "#CE005D", fg: "#fff" }, { name: "Purple", r: 188, g: 38, b: 194, l: 47.80, c: 84.30, h: 326.71, bg: "#BC26C2", fg: "#fff" }, { name: "Violet", r: 69, g: 0, b: 159, l: 18.82, c: 93.17, h: 308.23, bg: "#45009F", fg: "#fff" }, { name: "Blue 072", r: 17, g: 3, b: 161, l: 17.50, c: 88.32, h: 299.73, bg: "#1103A1", fg: "#fff" }, { name: "Reflex Blue", r: 0, g: 18, b: 141, l: 15.29, c: 76.78, h: 296.02, bg: "#00128D", fg: "#fff" }, { name: "Process Blue", r: 0, g: 132, b: 205, l: 47.62, c: 63.72, h: 238.80, bg: "#0084CD", fg: "#fff" }, { name: "Green", r: 0, g: 171, b: 132, l: 57.69, c: 77.27, h: 180.00, bg: "#00AB84", fg: "#fff" }, { name: "Black", r: 45, g: 42, b: 40, l: 17.27, c: 2.44, h: 56.31, bg: "#2D2A28", fg: "#fff" } ]; // Словарь ключевых слов для умного поиска const colorKeywords = { 'красный': { hMin: 330, hMax: 30, cMin: 40 }, 'красная': { hMin: 330, hMax: 30, cMin: 40 }, 'оранжевый': { hMin: 30, hMax: 60, cMin: 40 }, 'оранжевая': { hMin: 30, hMax: 60, cMin: 40 }, 'желтый': { hMin: 60, hMax: 90, cMin: 40 }, 'желтая': { hMin: 60, hMax: 90, cMin: 40 }, 'зеленый': { hMin: 90, hMax: 150, cMin: 30 }, 'зеленая': { hMin: 90, hMax: 150, cMin: 30 }, 'голубой': { hMin: 150, hMax: 200, cMin: 30 }, 'голубая': { hMin: 150, hMax: 200, cMin: 30 }, 'синий': { hMin: 200, hMax: 260, cMin: 40 }, 'синяя': { hMin: 200, hMax: 260, cMin: 40 }, 'фиолетовый': { hMin: 260, hMax: 330, cMin: 40 }, 'фиолетовая': { hMin: 260, hMax: 330, cMin: 40 }, 'розовый': { hMin: 300, hMax: 360, cMin: 30, lMin: 60 }, 'розовая': { hMin: 300, hMax: 360, cMin: 30, lMin: 60 }, 'коричневый': { hMin: 20, hMax: 60, cMax: 40, lMax: 50 }, 'коричневая': { hMin: 20, hMax: 60, cMax: 40, lMax: 50 }, 'серый': { cMax: 15 }, 'серая': { cMax: 15 }, 'черный': { lMax: 20 }, 'черная': { lMax: 20 }, 'белый': { lMin: 85 }, 'белая': { lMin: 85 }, 'яркий': { cMin: 60 }, 'яркая': { cMin: 60 }, 'темный': { lMax: 40 }, 'темная': { lMax: 40 }, 'светлый': { lMin: 70 }, 'светлая': { lMin: 70 }, 'пастельный': { cMax: 35, lMin: 70 }, 'пастельная': { cMax: 35, lMin: 70 }, 'насыщенный': { cMin: 70 }, 'насыщенная': { cMin: 70 } }; // ===== ИСПРАВЛЕНИЕ ЦВЕТА: Получение точного Pantone RGB ===== function getExactPantoneRGB(colorName) { // Прямое совпадение в базе if (pantoneRGBDatabase[colorName]) { return { ...pantoneRGBDatabase[colorName], source: 'database' }; } // Поиск по номеру (например, "116 C" -> "PANTONE 116 C") const match = colorName.match(/(\d+)\s*C/i); if (match) { const fullName = `PANTONE ${match[1]} C`; if (pantoneRGBDatabase[fullName]) { return { ...pantoneRGBDatabase[fullName], source: 'database' }; } } // Если нет в базе, пересчитываем из LCH с коррекцией return null; } // ===== ИСПРАВЛЕНИЕ ЦВЕТА: LCH в RGB с коррекцией ===== function lchToRGBCorrected(l, c, h) { // Преобразование LCH -> Lab const hRad = h * Math.PI / 180; const a = c * Math.cos(hRad); const b = c * Math.sin(hRad); // Lab -> XYZ (D65) const y = (l + 16) / 116; const x = a / 500 + y; const z = y - b / 200; const xyz = [ x > 0.206893034 ? x * x * x : (x - 16/116) / 7.787, y > 0.206893034 ? y * y * y : (y - 16/116) / 7.787, z > 0.206893034 ? z * z * z : (z - 16/116) / 7.787 ]; // XYZ -> RGB (sRGB) const xyzMatrix = [ [3.2404542, -1.5371385, -0.4985314], [-0.9692660, 1.8760108, 0.0415560], [0.0556434, -0.2040259, 1.0572252] ]; let rgb = [ xyzMatrix[0][0] * xyz[0] + xyzMatrix[0][1] * xyz[1] + xyzMatrix[0][2] * xyz[2], xyzMatrix[1][0] * xyz[0] + xyzMatrix[1][1] * xyz[1] + xyzMatrix[1][2] * xyz[2], xyzMatrix[2][0] * xyz[0] + xyzMatrix[2][1] * xyz[1] + xyzMatrix[2][2] * xyz[2] ]; // Гамма-коррекция rgb = rgb.map(v => { v = v > 0.0031308 ? 1.055 * Math.pow(v, 1/2.4) - 0.055 : 12.92 * v; return Math.max(0, Math.min(255, Math.round(v * 255))); }); return { r: rgb[0], g: rgb[1], b: rgb[2], source: 'calculated' }; } // ===== ИСПРАВЛЕНИЕ ЦВЕТА: Получение отображаемого цвета ===== function getDisplayColor(colorObj) { // Сначала пробуем найти в базе Pantone const exact = getExactPantoneRGB(colorObj.name); if (exact) { return { r: exact.r, g: exact.g, b: exact.b, source: 'pantone', css: `rgb(${exact.r}, ${exact.g}, ${exact.b})` }; } // Если это базовый цвет или смесь, пересчитываем из LCH const calculated = lchToRGBCorrected(colorObj.l, colorObj.c, colorObj.h); return { ...calculated, css: `rgb(${calculated.r}, ${calculated.g}, ${calculated.b})` }; } // Инициализация function init() { createBaseButtons(); setupSliders(); setupCanvasEvents(); updateDisplay(); } function createBaseButtons() { ['ref', 'sample'].forEach(target => { const container = document.getElementById(target + 'BaseColors'); container.innerHTML = baseColors.map((bc, idx) => `<button class="base-color-btn" id="${target}Base${idx}" style="background: ${bc.bg}; color: ${bc.fg};" onclick="applyBaseColor('${target}', ${idx})">${bc.name}</button>` ).join(''); }); } function setupSliders() { ['ref', 'sample'].forEach(target => { ['L', 'C', 'H'].forEach(param => { const slider = document.getElementById(target + param + 'slider'); slider.addEventListener('input', function() { const color = target === 'ref' ? ref : sample; const val = parseFloat(this.value); if (param === 'L') color.l = val; if (param === 'C') color.c = val; if (param === 'H') color.h = val; color.a = color.c * Math.cos(color.h * Math.PI / 180); color.b = color.c * Math.sin(color.h * Math.PI / 180); document.getElementById(target + param + 'val').textContent = param === 'H' ? val.toFixed(1) + '°' : val.toFixed(1); drawCanvas(); if (target === 'sample') updateAIAnalysis(); }); }); }); } function setupCanvasEvents() { const canvas = document.getElementById('lchCanvas'); const tooltip = document.getElementById('canvasTooltip'); canvas.addEventListener('mousemove', (e) => { const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const cx = canvas.width/2, cy = canvas.height/2; const dx = x - cx, dy = y - cy; let h = -Math.atan2(dy, dx) * 180 / Math.PI; if (h < 0) h += 360; const c = Math.sqrt(dx*dx + dy*dy) / 1.2; const nearest = findNearestPantone({ l: 50, c: c, h: h }); if (nearest && nearest.dE < 25) { tooltip.style.display = 'block'; tooltip.style.left = (x + 15) + 'px'; tooltip.style.top = (y + 15) + 'px'; document.getElementById('tooltipPantone').textContent = nearest.name; document.getElementById('tooltipDE').textContent = `ΔE: ${nearest.dE.toFixed(2)}`; document.getElementById('tooltipValues').textContent = `L*: ${nearest.l.toFixed(1)} C*: ${nearest.c.toFixed(1)} h°: ${nearest.h.toFixed(1)}`; } else { tooltip.style.display = 'none'; } }); canvas.addEventListener('mouseleave', () => { tooltip.style.display = 'none'; }); } function updateTransWhite(value) { transWhitePercent = parseInt(value); document.getElementById('transWhiteValue').textContent = transWhitePercent + '%'; const blend = transWhitePercent / 100; const previewL = sample.l + (transWhite.l - sample.l) * blend; const previewC = sample.c * (1 - blend * 0.8); const previewH = sample.h; const nearest = findNearestPantone({ l: previewL, c: previewC, h: previewH }); const infoText = transWhitePercent === 0 ? 'Добавьте лак для осветления образца' : `Будет: L*${previewL.toFixed(1)} C*${previewC.toFixed(1)} → ${nearest.name} (ΔE ${nearest.dE.toFixed(2)})`; document.getElementById('transWhiteInfo').innerHTML = infoText; const btn = document.getElementById('transWhiteBtn'); if (transWhitePercent > 0) { btn.classList.add('active'); btn.textContent = `Применить ${transWhitePercent}% лака`; } else { btn.classList.remove('active'); btn.textContent = 'Применить к образцу'; } } function applyTransWhite() { if (transWhitePercent === 0) return; const blend = transWhitePercent / 100; sample.l = sample.l + (transWhite.l - sample.l) * blend; sample.c = sample.c * (1 - blend * 0.8); sample.r = Math.round(sample.r + (transWhite.r - sample.r) * blend); sample.g = Math.round(sample.g + (transWhite.g - sample.g) * blend); sample.b = Math.round(sample.b + (transWhite.b - sample.b) * blend); sample.a = sample.c * Math.cos(sample.h * Math.PI / 180); sample.b = sample.c * Math.sin(sample.h * Math.PI / 180); transWhitePercent = 0; document.getElementById('transWhiteAmount').value = 0; document.getElementById('transWhiteValue').textContent = '0%'; document.getElementById('transWhiteInfo').textContent = 'Добавьте лак для осветления образца'; document.getElementById('transWhiteBtn').classList.remove('active'); document.getElementById('transWhiteBtn').textContent = 'Применить к образцу'; updateDisplay(); } function updateBlendPreview(value) { document.getElementById('blendValue').textContent = value + '%'; updateAIAnalysis(); } function applyBaseColor(target, idx) { const blend = parseInt(document.getElementById('blendAmount').value) / 100; const base = baseColors[idx]; const color = target === 'ref' ? ref : sample; color.l = color.l + (base.l - color.l) * blend; color.c = color.c + (base.c - color.c) * blend; let hDiff = base.h - color.h; if (hDiff > 180) hDiff -= 360; if (hDiff < -180) hDiff += 360; color.h = color.h + hDiff * blend; if (color.h < 0) color.h += 360; if (color.h >= 360) color.h -= 360; color.a = color.c * Math.cos(color.h * Math.PI / 180); color.b = color.c * Math.sin(color.h * Math.PI / 180); color.r = Math.round(color.r + (base.r - color.r) * blend); color.g = Math.round(color.g + (base.g - color.g) * blend); color.b = Math.round(color.b + (base.b - color.b) * blend); updateDisplay(); } function findNearestPantone(lch) { if (allColors.length === 0) return { name: 'Нет данных', dE: 999, l: 0, c: 0, h: 0 }; let nearest = null; let minDE = Infinity; allColors.forEach(c => { const dL = c.l - lch.l; const dC = c.c - lch.c; let dH = c.h - lch.h; if (dH > 180) dH -= 360; if (dH < -180) dH += 360; const dE = Math.sqrt(dL*dL + dC*dC + dH*dH); if (dE < minDE) { minDE = dE; nearest = { ...c, dE: dE }; } }); return nearest; } function loadColors(e) { const file = e.target.files[0]; if (!file) return; document.getElementById('loading').classList.add('show'); const reader = new FileReader(); reader.onload = function(e) { try { const data = new Uint8Array(e.target.result); const workbook = XLSX.read(data, { type: 'array' }); const sheet = workbook.Sheets[workbook.SheetNames[0]]; const json = XLSX.utils.sheet_to_json(sheet); allColors = json.map(row => { const name = row['Name'] || row['PANTONE'] || row['name'] || ''; const r = parseFloat(row['ns1:R'] || row['R'] || row['r'] || 0); const g = parseFloat(row['ns1:G'] || row['G'] || row['g'] || 0); const b = parseFloat(row['ns1:B'] || row['B'] || row['b'] || 0); const l = parseFloat(row['ns1:L'] || row['L'] || row['l'] || 0); const a = parseFloat(row['ns1:A'] || row['A'] || row['a'] || 0); const b5 = parseFloat(row['ns1:B5'] || row['B5'] || row['b5'] || row['b'] || 0); const c = Math.sqrt(a*a + b5*b5); let h = Math.atan2(b5, a) * 180 / Math.PI; if (h < 0) h += 360; return { name, r, g, b, l, a, b: b5, c, h }; }).filter(c => c.name && !isNaN(c.l)); document.getElementById('colorsCount').textContent = allColors.length + ' цветов'; updateDisplay(); } catch(err) { alert('Ошибка загрузки цветов: ' + err.message); console.error(err); } document.getElementById('loading').classList.remove('show'); }; reader.readAsArrayBuffer(file); } function loadRecipes(e) { const file = e.target.files[0]; if (!file) return; document.getElementById('loading').classList.add('show'); const reader = new FileReader(); reader.onload = function(e) { try { const data = new Uint8Array(e.target.result); const workbook = XLSX.read(data, { type: 'array' }); const sheet = workbook.Sheets[workbook.SheetNames[0]]; const json = XLSX.utils.sheet_to_json(sheet); allRecipes = {}; json.forEach(row => { const pantone = row['PANTONE'] || row['Name'] || row['pantone'] || row['name'] || ''; const component = row['Component'] || row['component'] || row['Base'] || row['base'] || ''; const percent = parseFloat(row['Percent'] || row['percent'] || row['Ratio'] || row['ratio'] || 0); if (pantone && component && !isNaN(percent)) { if (!allRecipes[pantone]) allRecipes[pantone] = []; allRecipes[pantone].push({ name: component, percent: percent }); } }); document.getElementById('recipesCount').textContent = Object.keys(allRecipes).length + ' рецептов'; updateRecipes(); } catch(err) { alert('Ошибка загрузки рецептов: ' + err.message); console.error(err); } document.getElementById('loading').classList.remove('show'); }; reader.readAsArrayBuffer(file); } // ===== ИСПРАВЛЕНИЕ ЦВЕТА: Обновленная функция отображения ===== function updateDisplay() { ['ref', 'sample'].forEach(target => { const color = target === 'ref' ? ref : sample; document.getElementById(target + 'Lslider').value = color.l; document.getElementById(target + 'Cslider').value = color.c; document.getElementById(target + 'Hslider').value = color.h; document.getElementById(target + 'Lval').textContent = color.l.toFixed(1); document.getElementById(target + 'Cval').textContent = color.c.toFixed(1); document.getElementById(target + 'Hval').textContent = color.h.toFixed(1) + '°'; document.getElementById(target + 'L').textContent = color.l.toFixed(1); document.getElementById(target + 'C').textContent = color.c.toFixed(1); document.getElementById(target + 'H').textContent = color.h.toFixed(1); // ===== ИСПРАВЛЕНИЕ: Используем точный Pantone RGB ===== const displayColor = getDisplayColor(color); const preview = document.getElementById(target + 'Preview'); preview.style.background = displayColor.css; // Индикатор источника цвета const accuracyEl = document.getElementById(target + 'Accuracy'); if (displayColor.source === 'pantone') { accuracyEl.textContent = 'Pantone®'; accuracyEl.className = 'color-accuracy exact'; } else { accuracyEl.textContent = 'Calculated'; accuracyEl.className = 'color-accuracy calc'; } const match = color.name.match(/(d+s*C?)/); document.getElementById(target + 'Number').textContent = match ? match[1] : (target === 'ref' ? 'REF' : 'SMP'); }); updateRecipes(); drawCanvas(); updateAIAnalysis(); } function updateRecipes() { ['ref', 'sample'].forEach(target => { const color = target === 'ref' ? ref : sample; const section = document.getElementById(target + 'RecipeSection'); const container = document.getElementById(target + 'Recipes'); const recipe = allRecipes[color.name]; if (recipe && recipe.length > 0) { section.style.display = 'block'; container.innerHTML = recipe.map(r => { const compColor = allColors.find(c => c.name.includes(r.name)) || { r: 200, g: 200, b: 200 }; // Используем точный цвет для компонентов рецепта тоже const compDisplay = getDisplayColor(compColor); return ` <div class="recipe-item"> <div class="recipe-color" style="background: ${compDisplay.css};"></div> <div class="recipe-name">${r.name}</div> <div class="recipe-percent">${(r.percent * 100).toFixed(1)}%</div> </div> `; }).join(''); } else { section.style.display = 'none'; } }); } function drawCanvas() { const canvas = document.getElementById('lchCanvas'); const ctx = canvas.getContext('2d'); const w = canvas.width, h = canvas.height; const cx = w / 2, cy = h / 2, maxR = 160; ctx.clearRect(0, 0, w, h); for (let angle = 0; angle < 360; angle += 3) { const a1 = -angle * Math.PI / 180; const a2 = -(angle + 3) * Math.PI / 180; ctx.beginPath(); ctx.moveTo(cx, cy); ctx.arc(cx, cy, maxR, a1, a2, true); ctx.closePath(); ctx.fillStyle = `hsl(${angle}, 100%, 50%)`; ctx.fill(); } const g = ctx.createRadialGradient(cx, cy, 0, cx, cy, maxR); g.addColorStop(0, 'rgba(128,128,128,1)'); g.addColorStop(0.15, 'rgba(128,128,128,0.6)'); g.addColorStop(1, 'rgba(128,128,128,0)'); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(cx, cy, maxR, 0, Math.PI * 2); ctx.fill(); if (document.getElementById('showGrid').checked) { ctx.strokeStyle = 'rgba(255,255,255,0.2)'; ctx.lineWidth = 1; [40, 80, 120].forEach(r => { ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI * 2); ctx.stroke(); }); ctx.strokeStyle = 'rgba(255,255,255,0.4)'; ctx.lineWidth = 2; [0, 90, 180, 270].forEach(hue => { const a = -hue * Math.PI / 180; ctx.beginPath(); ctx.moveTo(cx, cy); ctx.lineTo(cx + Math.cos(a) * maxR, cy + Math.sin(a) * maxR); ctx.stroke(); }); } if (document.getElementById('showAllColors').checked && allColors.length > 0) { allColors.forEach(c => { if (c.c < 5) return; const a = -c.h * Math.PI / 180; const r = Math.min(maxR, c.c * 1.2); // Используем точный цвет для точек на canvas const display = getDisplayColor(c); ctx.fillStyle = display.css.replace('rgb', 'rgba').replace(')', ', 0.5)'); ctx.beginPath(); ctx.arc(cx + Math.cos(a) * r, cy + Math.sin(a) * r, 2, 0, Math.PI * 2); ctx.fill(); }); } function drawPoint(color, isRef) { const a = -color.h * Math.PI / 180; const r = Math.min(maxR, color.c * 1.2); const x = cx + Math.cos(a) * r; const y = cy + Math.sin(a) * r; ctx.shadowColor = 'rgba(0,0,0,0.5)'; ctx.shadowBlur = 10; ctx.beginPath(); ctx.arc(x, y, isRef ? 16 : 14, 0, Math.PI * 2); // Используем точный цвет для точки const display = getDisplayColor(color); ctx.fillStyle = display.css; ctx.fill(); ctx.shadowBlur = 0; ctx.strokeStyle = isRef ? '#4ade80' : '#fbbf24'; ctx.lineWidth = 4; ctx.stroke(); const match = color.name.match(/(d+s*C?)/); const label = match ? match[1] : (isRef ? 'REF' : 'SMP'); ctx.fillStyle = '#fff'; ctx.font = 'bold 12px sans-serif'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(label, x, y - 22); ctx.strokeStyle = isRef ? 'rgba(74,222,128,0.4)' : 'rgba(251,191,36,0.4)'; ctx.lineWidth = 1; ctx.setLineDash([3, 3]); ctx.beginPath(); ctx.moveTo(cx, cy); ctx.lineTo(x, y); ctx.stroke(); ctx.setLineDash([]); return { x, y, r: isRef ? 16 : 14 }; } window.refPos = drawPoint(ref, true); window.samplePos = drawPoint(sample, false); ctx.strokeStyle = 'rgba(255,255,255,0.6)'; ctx.lineWidth = 2; ctx.setLineDash([5, 5]); ctx.beginPath(); ctx.moveTo(window.refPos.x, window.refPos.y); ctx.lineTo(window.samplePos.x, window.samplePos.y); ctx.stroke(); ctx.setLineDash([]); ctx.beginPath(); ctx.arc(cx, cy, 5, 0, Math.PI * 2); ctx.fillStyle = '#444'; ctx.fill(); } const canvas = document.getElementById('lchCanvas'); function getPos(e) { const rect = canvas.getBoundingClientRect(); return { x: e.clientX - rect.left, y: e.clientY - rect.top }; } canvas.addEventListener('mousedown', (e) => { const p = getPos(e); const check = (pos) => { const dx = p.x - pos.x, dy = p.y - pos.y; return Math.sqrt(dx*dx + dy*dy) < pos.r + 5; }; if (check(window.refPos)) dragging = 'ref'; else if (check(window.samplePos)) dragging = 'sample'; }); canvas.addEventListener('mousemove', (e) => { if (!dragging) return; const p = getPos(e); const cx = canvas.width/2, cy = canvas.height/2; const dx = p.x - cx, dy = p.y - cy; let h = -Math.atan2(dy, dx) * 180 / Math.PI; if (h < 0) h += 360; const c = Math.min(150, Math.sqrt(dx*dx + dy*dy) / 1.2); const color = dragging === 'ref' ? ref : sample; color.h = h; color.c = c; color.a = c * Math.cos(h * Math.PI / 180); color.b = c * Math.sin(h * Math.PI / 180); document.getElementById(dragging + 'Hslider').value = h; document.getElementById(dragging + 'Cslider').value = c; document.getElementById(dragging + 'Hval').textContent = h.toFixed(1) + '°'; document.getElementById(dragging + 'Cval').textContent = c.toFixed(1); document.getElementById(dragging + 'H').textContent = h.toFixed(1); document.getElementById(dragging + 'C').textContent = c.toFixed(1); drawCanvas(); if (dragging === 'sample') updateAIAnalysis(); }); canvas.addEventListener('mouseup', () => dragging = null); canvas.addEventListener('mouseleave', () => dragging = null); function findNearest() { if (allColors.length === 0) { alert('Сначала загрузите файл с цветами'); return; } ['ref', 'sample'].forEach(target => { const color = target === 'ref' ? ref : sample; const dists = allColors.map(c => { const dL = c.l - color.l, dC = c.c - color.c; let dH = c.h - color.h; if (dH > 180) dH -= 360; if (dH < -180) dH += 360; return { ...c, dE: Math.sqrt(dL*dL + dC*dC + dH*dH) }; }); dists.sort((a, b) => a.dE - b.dE); document.getElementById(target + 'Results').innerHTML = dists.slice(0, 5).map(c => { const display = getDisplayColor(c); return ` <div class="result-item" onclick="setColor('${target}', '${c.name.replace(/'/g, "\'")}')"> <div class="result-color" style="background: ${display.css};"></div> <div style="flex: 1; min-width: 0;"> <div style="font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${c.name}</div> <div style="font-size: 0.65rem; color: #888;">ΔE: ${c.dE.toFixed(2)} | L:${c.l.toFixed(0)} C:${c.c.toFixed(0)} H:${c.h.toFixed(0)}°</div> </div> </div> `}).join(''); }); } function setColor(target, name) { const c = allColors.find(x => x.name === name); if (c) { if (target === 'ref') ref = { ...c }; else sample = { ...c }; updateDisplay(); } } function searchColor(target) { const q = document.getElementById(target + 'Search').value.toLowerCase(); if (q.length < 2) return; if (allColors.length === 0) return; const matches = allColors.filter(c => c.name.toLowerCase().includes(q)).slice(0, 5); document.getElementById(target + 'Results').innerHTML = matches.map(c => { const display = getDisplayColor(c); return ` <div class="result-item" onclick="setColor('${target}', '${c.name.replace(/'/g, "\'")}')"> <div class="result-color" style="background: ${display.css};"></div> <div style="flex: 1; min-width: 0;"> <div style="font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${c.name}</div> <div style="font-size: 0.65rem; color: #888;">L:${c.l.toFixed(0)} C:${c.c.toFixed(0)} H:${c.h.toFixed(0)}°</div> </div> </div> `}).join(''); } function swapColors() { const t = { ...ref }; ref = { ...sample }; sample = t; updateDisplay(); } function smartSearch(query, target) { if (!query || query.length < 2) return; if (allColors.length === 0) { if (query.length > 2) searchColor(target); return; } const q = query.toLowerCase(); const words = q.split(/\s+/); let hasKeywords = false; words.forEach(word => { if (colorKeywords[word]) hasKeywords = true; }); if (!hasKeywords) { if (query.length > 2) searchColor(target); return; } const scored = allColors.map(c => { let score = 0; let matches = 0; words.forEach(word => { const kw = colorKeywords[word]; if (!kw) return; let matched = true; if (kw.hMin !== undefined && kw.hMax !== undefined) { if (kw.hMin > kw.hMax) { matched = (c.h >= kw.hMin || c.h <= kw.hMax); } else { matched = (c.h >= kw.hMin && c.h <= kw.hMax); } } if (kw.cMin !== undefined && c.c < kw.cMin) matched = false; if (kw.cMax !== undefined && c.c > kw.cMax) matched = false; if (kw.lMin !== undefined && c.l < kw.lMin) matched = false; if (kw.lMax !== undefined && c.l > kw.lMax) matched = false; if (matched) { matches++; if (kw.cMin !== undefined) score += Math.min(c.c / kw.cMin, 2); if (kw.lMin !== undefined) score += Math.min(c.l / kw.lMin, 2); if (kw.cMax !== undefined) score += Math.min(kw.cMax / (c.c + 1), 2); if (kw.lMax !== undefined) score += Math.min(kw.lMax / (c.l + 1), 2); } }); return { ...c, score: matches > 0 ? score / words.length : 0, matches }; }); const filtered = scored.filter(c => c.matches > 0).sort((a, b) => b.score - a.score); if (filtered.length === 0) { document.getElementById(target + 'Results').innerHTML = '<div style="color:#888;font-size:0.75rem;padding:8px;">Нет совпадений</div>'; return; } document.getElementById(target + 'Results').innerHTML = filtered.slice(0, 6).map(c => { const display = getDisplayColor(c); return ` <div class="result-item" onclick="setColor('${target}', '${c.name.replace(/'/g, "\\'")}')"> <div class="result-color" style="background: ${display.css};"></div> <div style="flex: 1; min-width: 0;"> <div style="font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${c.name}</div> <div style="font-size: 0.65rem; color: #888;">L:${c.l.toFixed(0)} C:${c.c.toFixed(0)} H:${c.h.toFixed(0)}° | Совпадение: ${(c.score*50).toFixed(0)}%</div> </div> </div> `}).join(''); } function describeDifference() { const dL = sample.l - ref.l; const dC = sample.c - ref.c; let dH = sample.h - ref.h; if (dH > 180) dH -= 360; if (dH < -180) dH += 360; const parts = []; if (Math.abs(dL) > 1) { if (dL > 0) parts.push(`светлее на ${dL.toFixed(1)}`); else parts.push(`темнее на ${Math.abs(dL).toFixed(1)}`); } if (Math.abs(dC) > 2) { if (dC > 0) parts.push(`насыщеннее на ${dC.toFixed(1)}`); else parts.push(`бледнее на ${Math.abs(dC).toFixed(1)}`); } if (Math.abs(dH) > 3) { const directions = [ { name: 'красный', range: [330, 30] }, { name: 'оранжевый', range: [30, 60] }, { name: 'желтый', range: [60, 90] }, { name: 'желто-зеленый', range: [90, 120] }, { name: 'зеленый', range: [120, 180] }, { name: 'бирюзовый', range: [180, 210] }, { name: 'синий', range: [210, 270] }, { name: 'фиолетовый', range: [270, 330] } ]; const getDirection = (h) => { const found = directions.find(d => { if (d.range[0] > d.range[1]) return h >= d.range[0] || h <= d.range[1]; return h >= d.range[0] && h < d.range[1]; }); return found ? found.name : 'нейтральный'; }; const sampleDir = getDirection(sample.h); const refDir = getDirection(ref.h); if (sampleDir !== refDir) { parts.push(`смещение от ${refDir} к ${sampleDir}`); } else { parts.push(`тон в зоне ${sampleDir}`); } } const dE = Math.sqrt(dL*dL + dC*dC + dH*dH); let quality = ''; let color = ''; if (dE < 1) { quality = '✓ Идеальное совпадение'; color = '#4ade80'; } else if (dE < 3) { quality = '~ Хорошее совпадение (допустимо)'; color = '#fbbf24'; } else if (dE < 5) { quality = '⚠ Заметное отклонение'; color = '#fb923c'; } else { quality = '✗ Критическое отклонение'; color = '#f87171'; } return { text: parts.length > 0 ? parts.join(', ') : 'Цвета практически идентичны', dE: dE.toFixed(2), quality: quality, qualityColor: color, dL, dC, dH }; } function calculateColorVector(color1, color2) { const dL = color2.l - color1.l; const dC = color2.c - color1.c; let dH = color2.h - color1.h; if (dH > 180) dH -= 360; if (dH < -180) dH += 360; return { dL: dL, dC: dC * 0.5, dH: dH * (color1.c / 100), magnitude: Math.sqrt(dL*dL + dC*dC + dH*dH), direction: Math.atan2(dH, dL) * 180 / Math.PI }; } function predictMixResult(baseColor, additive, ratio, mixType = 'linear') { const r = ratio / 100; if (mixType === 'transwhite') { const newL = baseColor.l + (100 - baseColor.l) * r * 0.9; const newC = baseColor.c * Math.pow(1 - r, 1.5); return { l: newL, c: newC, h: baseColor.h, a: newC * Math.cos(baseColor.h * Math.PI / 180), b: newC * Math.sin(baseColor.h * Math.PI / 180) }; } let newL = baseColor.l + (additive.l - baseColor.l) * r; let newC = baseColor.c + (additive.c - baseColor.c) * r; let hDiff = additive.h - baseColor.h; if (hDiff > 180) hDiff -= 360; if (hDiff < -180) hDiff += 360; let newH = baseColor.h + hDiff * r; if (newH < 0) newH += 360; if (newH >= 360) newH -= 360; if (r > 0.3) { newL = newL * 0.95 + additive.l * 0.05 * (r - 0.3); } return { l: newL, c: newC, h: newH, a: newC * Math.cos(newH * Math.PI / 180), b: newC * Math.sin(newH * Math.PI / 180) }; } function evaluateCorrection(current, target, predicted, weight = 1) { const currentDE = Math.sqrt( Math.pow(current.l - target.l, 2) + Math.pow(current.c - target.c, 2) + Math.pow(current.h - target.h, 2) ); const predictedDE = Math.sqrt( Math.pow(predicted.l - target.l, 2) + Math.pow(predicted.c - target.c, 2) + Math.pow(predicted.h - target.h, 2) ); const improvement = currentDE - predictedDE; const efficiency = improvement / (currentDE + 0.1); return { currentDE, predictedDE, improvement, efficiency: efficiency * weight, score: improvement * weight + (efficiency > 0.5 ? 2 : 0) }; } function generateMultiStepStrategy(analysis) { const { dL, dC, dH, dE } = analysis; const steps = []; let remainingDE = parseFloat(dE); const priorities = []; if (Math.abs(dL) > 3) priorities.push({ param: 'L', delta: dL, weight: 1.2 }); if (Math.abs(dH) > 5) priorities.push({ param: 'H', delta: dH, weight: 1.0 }); if (Math.abs(dC) > 4) priorities.push({ param: 'C', delta: dC, weight: 0.8 }); priorities.sort((a, b) => Math.abs(b.delta) * b.weight - Math.abs(a.delta) * a.weight); priorities.forEach((p, idx) => { if (remainingDE < 1.5) return; if (p.param === 'L') { if (p.delta < 0) { steps.push({ action: 'transwhite', amount: Math.min(100, Math.abs(p.delta) * 8), reason: 'Осветление', expectedImprovement: Math.abs(p.delta) * 0.7 }); } else { steps.push({ action: 'black', amount: Math.min(40, p.delta * 3), reason: 'Затемнение', expectedImprovement: Math.abs(p.delta) * 0.6 }); } } else if (p.param === 'C') { const direction = p.delta > 0 ? 'увеличение насыщенности' : 'уменьшение насыщенности'; steps.push({ action: 'chromatic', direction: p.delta > 0 ? 'up' : 'down', reason: direction, expectedImprovement: Math.abs(p.delta) * 0.5 }); } else if (p.param === 'H') { steps.push({ action: 'hue_shift', direction: p.delta > 0 ? 'cw' : 'ccw', amount: Math.abs(p.delta), reason: `Сдвиг оттенка ${p.delta > 0 ? 'по часовой' : 'против часовой'}`, expectedImprovement: Math.abs(p.delta) * 0.4 }); } remainingDE -= steps[steps.length - 1].expectedImprovement; }); return steps; } function suggestCorrection() { const analysis = describeDifference(); const { dL, dC, dH, dE } = analysis; const currentDE = parseFloat(dE); if (currentDE < 1.2) return null; const blendPercent = parseInt(document.getElementById('blendAmount').value); const candidates = []; if (dL < -2) { for (let pct = 5; pct <= 100; pct += 5) { const predicted = predictMixResult(sample, transWhite, pct, 'transwhite'); const eval = evaluateCorrection(sample, ref, predicted, 1.3); if (eval.improvement > 0.5) { candidates.push({ type: 'transwhite', percent: pct, ...eval, predicted, confidence: Math.min(95, 60 + eval.efficiency * 30) }); } } } baseColors.forEach((base, idx) => { const vector = calculateColorVector(sample, base); const targetVector = calculateColorVector(sample, ref); const dotProduct = (vector.dL * targetVector.dL + vector.dC * targetVector.dC) / (vector.magnitude * targetVector.magnitude + 0.001); if (dotProduct < -0.3) return; for (let pct = 5; pct <= Math.min(40, blendPercent * 2); pct += 5) { const predicted = predictMixResult(sample, base, pct, 'linear'); const eval = evaluateCorrection(sample, ref, predicted, 1.0); const directionBonus = dotProduct > 0.7 ? 1.3 : (dotProduct > 0.3 ? 1.1 : 1.0); eval.score *= directionBonus; if (eval.improvement > 0.3) { candidates.push({ type: 'base', base: base, idx: idx, percent: pct, ...eval, predicted, dotProduct, confidence: Math.min(95, 50 + eval.efficiency * 25 + dotProduct * 20) }); } } }); if (currentDE > 8 && candidates.length > 0) { const bestWhite = candidates.find(c => c.type === 'transwhite' && c.percent <= 50); const bestBase = candidates.filter(c => c.type === 'base').sort((a, b) => b.score - a.score)[0]; if (bestWhite && bestBase) { const step1 = predictMixResult(sample, transWhite, bestWhite.percent, 'transwhite'); const step2 = predictMixResult(step1, bestBase.base, bestBase.percent, 'linear'); const combinedEval = evaluateCorrection(sample, ref, step2, 1.5); candidates.push({ type: 'combined', steps: [ { type: 'transwhite', percent: bestWhite.percent }, { type: 'base', base: bestBase.base, percent: bestBase.percent, idx: bestBase.idx } ], ...combinedEval, predicted: step2, confidence: Math.min(90, bestWhite.confidence * 0.8 + bestBase.confidence * 0.8) }); } } if (candidates.length === 0) return null; candidates.sort((a, b) => { const scoreA = a.score * 0.6 + (a.confidence / 100) * 0.4; const scoreB = b.score * 0.6 + (b.confidence / 100) * 0.4; return scoreB - scoreA; }); const best = candidates[0]; const nearest = findNearestPantone(best.predicted); let strategy = null; if (currentDE > 6) { strategy = generateMultiStepStrategy(analysis); } return { ...best, nearestPantone: nearest, strategy: strategy, alternatives: candidates.slice(1, 3) }; } function updateAIAnalysis() { const analysis = describeDifference(); const suggestion = suggestCorrection(); document.getElementById('aiText').textContent = analysis.text; const deEl = document.getElementById('aiDE'); deEl.innerHTML = `ΔE = ${analysis.dE} <span style="color:${analysis.qualityColor}">${analysis.quality}</span>`; const lchPreview = document.getElementById('aiLCHPreview'); const sugEl = document.getElementById('aiSuggestion'); const strategyEl = document.getElementById('aiStrategy'); const strategyText = document.getElementById('aiStrategyText'); const multiStepEl = document.getElementById('aiMultiStep'); document.querySelectorAll('.base-color-btn').forEach(btn => { btn.classList.remove('ai-suggested'); }); document.getElementById('transWhiteBtn').classList.remove('active'); strategyEl.style.display = 'none'; if (suggestion) { const confClass = suggestion.confidence > 80 ? 'high' : (suggestion.confidence > 60 ? 'medium' : 'low'); const confText = suggestion.confidence > 80 ? 'Высокая уверенность' : (suggestion.confidence > 60 ? 'Средняя уверенность' : 'Низкая уверенность'); if (suggestion.type === 'transwhite') { const pl = suggestion.predicted; const np = suggestion.nearestPantone; lchPreview.innerHTML = ` <strong>Предсказание (Лак ${suggestion.percent}%):</strong><br> Получите: L*${pl.l.toFixed(1)} C*${pl.c.toFixed(1)} h°${pl.h.toFixed(1)}<br> Будет близко к: <strong>${np.name}</strong> (ΔE ${np.dE.toFixed(2)})<br> <span style="color:#4ade80">Улучшение: -${suggestion.improvement.toFixed(1)} ΔE</span> `; sugEl.innerHTML = ` <strong>💡 Рекомендация:</strong> Добавьте <strong>Trans White ${suggestion.percent}%</strong> <span class="ai-confidence ${confClass}">${confText}</span><br> <span style="color:#888;font-size:0.7rem;">Точность предсказания: ${suggestion.predictedDE.toFixed(2)} ΔE</span> `; document.getElementById('transWhiteBtn').classList.add('active'); document.getElementById('transWhiteAmount').value = suggestion.percent; updateTransWhite(suggestion.percent); } else if (suggestion.type === 'base') { const pl = suggestion.predicted; const np = suggestion.nearestPantone; lchPreview.innerHTML = ` <strong>Предсказание (${suggestion.base.name} ${suggestion.percent}%):</strong><br> Получите: L*${pl.l.toFixed(1)} C*${pl.c.toFixed(1)} h°${pl.h.toFixed(1)}<br> Будет близко к: <strong>${np.name}</strong> (ΔE ${np.dE.toFixed(2)})<br> <span style="color:#4ade80">Улучшение: -${suggestion.improvement.toFixed(1)} ΔE</span> `; const directionMatch = suggestion.dotProduct > 0.7 ? ' (отличное направление)' : ''; sugEl.innerHTML = ` <strong>💡 Рекомендация:</strong> Добавьте <strong>${suggestion.base.name}</strong> ${suggestion.percent}% <span class="ai-confidence ${confClass}">${confText}</span>${directionMatch}<br> <span style="color:#888;font-size:0.7rem;">Эффективность: ${(suggestion.efficiency * 100).toFixed(0)}%</span> `; const btn = document.getElementById('sampleBase' + suggestion.idx); if (btn) btn.classList.add('ai-suggested'); } else if (suggestion.type === 'combined') { const pl = suggestion.predicted; const np = suggestion.nearestPantone; const steps = suggestion.steps; lchPreview.innerHTML = ` <strong>Предсказание (Комбинированное):</strong><br> Получите: L*${pl.l.toFixed(1)} C*${pl.c.toFixed(1)} h°${pl.h.toFixed(1)}<br> Будет близко к: <strong>${np.name}</strong> (ΔE ${np.dE.toFixed(2)})<br> <span style="color:#4ade80">Общее улучшение: -${suggestion.improvement.toFixed(1)} ΔE</span> `; sugEl.innerHTML = ` <strong>💡 Комплексная коррекция:</strong> <span class="ai-confidence ${confClass}">${confText}</span><br> 1. Trans White ${steps[0].percent}% → 2. ${steps[1].base.name} ${steps[1].percent}% `; strategyEl.style.display = 'block'; strategyText.innerHTML = 'Двухшаговая коррекция для сложного отклонения'; multiStepEl.innerHTML = ` Шаг 1: Осветление на ${(100 - steps[0].percent * 0.9).toFixed(1)}% L*<br> Шаг 2: Коррекция оттенка ${steps[1].base.name} `; } if (suggestion.strategy && suggestion.strategy.length > 0) { strategyEl.style.display = 'block'; strategyText.textContent = 'Многошаговая стратегия коррекции:'; multiStepEl.innerHTML = suggestion.strategy.map((step, i) => `${i + 1}. ${step.reason}: ${step.action === 'transwhite' ? step.amount + '%' : step.action}${step.amount ? ' ' + step.amount + '%' : ''}` ).join('<br>'); } if (suggestion.alternatives && suggestion.alternatives.length > 0) { const alt = suggestion.alternatives[0]; const altText = alt.type === 'transwhite' ? `Trans White ${alt.percent}%` : `${alt.base.name} ${alt.percent}%`; sugEl.innerHTML += `<br><span style="color:#666;font-size:0.7rem;">Альтернатива: ${altText} (ΔE ${alt.predictedDE.toFixed(1)})</span>`; } } else { lchPreview.style.display = 'none'; sugEl.innerHTML = parseFloat(analysis.dE) < 2 ? '<span style="color:#4ade80">✓ Коррекция не требуется</span>' : '<span style="color:#f87171">Требуется ручной подбор или измените силу смешивания</span>'; } } init(); </script> </body> </html>