diff --git a/packages/css-color-parser/CHANGELOG.md b/packages/css-color-parser/CHANGELOG.md index 97403ff98a..f481b993a3 100644 --- a/packages/css-color-parser/CHANGELOG.md +++ b/packages/css-color-parser/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to CSS Color Parser +### Unreleased (patch) + +- Fix handling of out of range percentages from math functions in `color-mix()` (they are clamped, not invalid) +- Fix powerless hue detection for `hwb()` colors with negative whiteness or blackness (these values are not clamped) + ### 4.2.6 _October 2, 2026_ diff --git a/packages/css-color-parser/dist/index.mjs b/packages/css-color-parser/dist/index.mjs index 849f888856..502869414d 100644 --- a/packages/css-color-parser/dist/index.mjs +++ b/packages/css-color-parser/dist/index.mjs @@ -1 +1 @@ -import{TokenType as e,NumberType as n,isTokenIdent as a,isTokenPercentage as o,isTokenNumber as r,isTokenDelim as t,isTokenNumeric as l,isTokenComma as s,isTokenDimension as c,isTokenHash as i}from"@csstools/css-tokenizer";import{XYZ_D65_to_XYZ_D65 as u,XYZ_D50_to_XYZ_D65 as h,OKLCH_to_XYZ_D65 as N,LCH_to_XYZ_D65 as m,OKLab_to_XYZ_D65 as p,Lab_to_XYZ_D65 as b,HWB_to_XYZ_D65 as v,HSL_to_XYZ_D65 as f,ProPhoto_RGB_to_XYZ_D65 as g,a98_RGB_to_XYZ_D65 as d,rec_2020_to_XYZ_D65 as y,lin_P3_to_XYZ_D65 as _,P3_to_XYZ_D65 as C,lin_sRGB_to_XYZ_D65 as T,sRGB_to_XYZ_D65 as w,XYZ_D50_to_XYZ_D50 as x,XYZ_D65_to_OKLab as D,XYZ_D65_to_OKLCH as L,XYZ_D50_to_LCH as H,XYZ_D50_to_Lab as P,XYZ_D65_to_HWB as Z,XYZ_D65_to_HSL as M,XYZ_D65_to_a98_RGB as $,XYZ_D50_to_ProPhoto as F,XYZ_D65_to_rec_2020 as S,XYZ_D65_to_lin_P3 as z,XYZ_D65_to_P3 as R,XYZ_D65_to_lin_sRGB as k,XYZ_D65_to_sRGB as B,XYZ_D65_to_XYZ_D50 as X,OKLCH_to_XYZ_D50 as G,LCH_to_XYZ_D50 as A,OKLab_to_XYZ_D50 as Y,Lab_to_XYZ_D50 as V,HWB_to_XYZ_D50 as K,HSL_to_XYZ_D50 as I,ProPhoto_RGB_to_XYZ_D50 as O,a98_RGB_to_XYZ_D50 as W,rec_2020_to_XYZ_D50 as E,lin_P3_to_XYZ_D50 as U,P3_to_XYZ_D50 as j,lin_sRGB_to_XYZ_D50 as q,sRGB_to_XYZ_D50 as J,namedColors as Q,inGamut as ee,clip as ne,gam_sRGB as ae,mapGamutRayTrace as oe,OKLCH_to_OKLab as re,OKLab_to_XYZ as te,XYZ_to_lin_sRGB as le,lin_sRGB_to_XYZ as se,XYZ_to_OKLab as ce,OKLab_to_OKLCH as ie,contrast_ratio_wcag_2_1 as ue,gam_P3 as he,XYZ_to_lin_P3 as Ne,lin_P3_to_XYZ as me}from"@csstools/color-helpers";import{isWhitespaceNode as pe,isCommentNode as be,isTokenNode as ve,isFunctionNode as fe,TokenNode as ge,isWhiteSpaceOrCommentNode as de,replaceComponentValues as ye,FunctionNode as _e,WhitespaceNode as Ce}from"@csstools/css-parser-algorithms";import{mathFunctionNames as Te,calcFromComponentValues as we}from"@csstools/css-calc";var xe,De;function normalize(e,n,a,o){return Math.min(Math.max(e/n,a),o)}function convertNaNToZero(e){return[Number.isNaN(e[0])?0:e[0],Number.isNaN(e[1])?0:e[1],Number.isNaN(e[2])?0:e[2]]}function colorData_to_XYZ_D50(e){switch(e.colorNotation){case xe.HEX:case xe.RGB:case xe.sRGB:return{...e,colorNotation:xe.XYZ_D50,channels:J(convertNaNToZero(e.channels))};case xe.Linear_sRGB:return{...e,colorNotation:xe.XYZ_D50,channels:q(convertNaNToZero(e.channels))};case xe.Display_P3:return{...e,colorNotation:xe.XYZ_D50,channels:j(convertNaNToZero(e.channels))};case xe.Linear_Display_P3:return{...e,colorNotation:xe.XYZ_D50,channels:U(convertNaNToZero(e.channels))};case xe.Rec2020:return{...e,colorNotation:xe.XYZ_D50,channels:E(convertNaNToZero(e.channels))};case xe.A98_RGB:return{...e,colorNotation:xe.XYZ_D50,channels:W(convertNaNToZero(e.channels))};case xe.ProPhoto_RGB:return{...e,colorNotation:xe.XYZ_D50,channels:O(convertNaNToZero(e.channels))};case xe.HSL:return{...e,colorNotation:xe.XYZ_D50,channels:I(convertNaNToZero(e.channels))};case xe.HWB:return{...e,colorNotation:xe.XYZ_D50,channels:K(convertNaNToZero(e.channels))};case xe.Lab:return{...e,colorNotation:xe.XYZ_D50,channels:V(convertNaNToZero(e.channels))};case xe.OKLab:return{...e,colorNotation:xe.XYZ_D50,channels:Y(convertNaNToZero(e.channels))};case xe.LCH:return{...e,colorNotation:xe.XYZ_D50,channels:A(convertNaNToZero(e.channels))};case xe.OKLCH:return{...e,colorNotation:xe.XYZ_D50,channels:G(convertNaNToZero(e.channels))};case xe.XYZ_D50:return{...e,colorNotation:xe.XYZ_D50,channels:x(convertNaNToZero(e.channels))};case xe.XYZ_D65:return{...e,colorNotation:xe.XYZ_D50,channels:X(convertNaNToZero(e.channels))};default:throw new Error("Unsupported color notation")}}function colorData_to_XYZ_D65(e){switch(e.colorNotation){case xe.HEX:case xe.RGB:case xe.sRGB:return{...e,colorNotation:xe.XYZ_D65,channels:w(convertNaNToZero(e.channels))};case xe.Linear_sRGB:return{...e,colorNotation:xe.XYZ_D65,channels:T(convertNaNToZero(e.channels))};case xe.Display_P3:return{...e,colorNotation:xe.XYZ_D65,channels:C(convertNaNToZero(e.channels))};case xe.Linear_Display_P3:return{...e,colorNotation:xe.XYZ_D65,channels:_(convertNaNToZero(e.channels))};case xe.Rec2020:return{...e,colorNotation:xe.XYZ_D65,channels:y(convertNaNToZero(e.channels))};case xe.A98_RGB:return{...e,colorNotation:xe.XYZ_D65,channels:d(convertNaNToZero(e.channels))};case xe.ProPhoto_RGB:return{...e,colorNotation:xe.XYZ_D65,channels:g(convertNaNToZero(e.channels))};case xe.HSL:return{...e,colorNotation:xe.XYZ_D65,channels:f(convertNaNToZero(e.channels))};case xe.HWB:return{...e,colorNotation:xe.XYZ_D65,channels:v(convertNaNToZero(e.channels))};case xe.Lab:return{...e,colorNotation:xe.XYZ_D65,channels:b(convertNaNToZero(e.channels))};case xe.OKLab:return{...e,colorNotation:xe.XYZ_D65,channels:p(convertNaNToZero(e.channels))};case xe.LCH:return{...e,colorNotation:xe.XYZ_D65,channels:m(convertNaNToZero(e.channels))};case xe.OKLCH:return{...e,colorNotation:xe.XYZ_D65,channels:N(convertNaNToZero(e.channels))};case xe.XYZ_D50:return{...e,colorNotation:xe.XYZ_D65,channels:h(convertNaNToZero(e.channels))};case xe.XYZ_D65:return{...e,colorNotation:xe.XYZ_D65,channels:u(convertNaNToZero(e.channels))};default:throw new Error("Unsupported color notation")}}!function(e){e.A98_RGB="a98-rgb",e.Display_P3="display-p3",e.Linear_Display_P3="display-p3-linear",e.HEX="hex",e.HSL="hsl",e.HWB="hwb",e.LCH="lch",e.Lab="lab",e.Linear_sRGB="srgb-linear",e.OKLCH="oklch",e.OKLab="oklab",e.ProPhoto_RGB="prophoto-rgb",e.RGB="rgb",e.sRGB="srgb",e.Rec2020="rec2020",e.XYZ_D50="xyz-d50",e.XYZ_D65="xyz-d65"}(xe||(xe={})),function(e){e.ColorKeyword="color-keyword",e.HasAlpha="has-alpha",e.HasDimensionValues="has-dimension-values",e.HasNoneKeywords="has-none-keywords",e.HasNumberValues="has-number-values",e.HasPercentageAlpha="has-percentage-alpha",e.HasPercentageValues="has-percentage-values",e.HasVariableAlpha="has-variable-alpha",e.Hex="hex",e.LegacyHSL="legacy-hsl",e.LegacyRGB="legacy-rgb",e.NamedColor="named-color",e.RelativeColorSyntax="relative-color-syntax",e.ColorMix="color-mix",e.ColorMixVariadic="color-mix-variadic",e.ContrastColor="contrast-color",e.RelativeAlphaSyntax="relative-alpha-syntax",e.Experimental="experimental"}(De||(De={}));const Le=new Set([xe.A98_RGB,xe.Display_P3,xe.Linear_Display_P3,xe.HEX,xe.Linear_sRGB,xe.ProPhoto_RGB,xe.RGB,xe.sRGB,xe.Rec2020,xe.XYZ_D50,xe.XYZ_D65]);function colorDataToForInterpolation(e,n){if(e.colorNotation===n)return{...e};const a=[...e.channels];let o={...e};return o.channels=convertPowerlessComponentsToMissingComponents(o.channels,e.colorNotation),o=convertToDestination(o,n),o.channels=carryForwardMissingComponentsForColorAndNotation(o,e.colorNotation,n,a),o}function colorDataToForRelativeColorSyntax(e,n){if(e.colorNotation===n)return{...e};const a=[...e.channels];let o={...e};return o.channels=convertPowerlessComponentsToMissingComponents(o.channels,e.colorNotation),o=convertToDestination(o,n),o.channels=carryForwardMissingComponentsForColorAndNotation(o,e.colorNotation,n,a),o}function convertToDestination(e,n){if(e.colorNotation===n)return e.channels=convertNaNToZero(e.channels),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n),e;switch(n){case xe.HEX:case xe.RGB:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.RGB,e.channels=B(n.channels),e.channels=e.channels.map(e=>reducePrecisionOrNaN(e,8)),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.sRGB:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.sRGB,e.channels=B(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.Linear_sRGB:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.Linear_sRGB,e.channels=k(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.Display_P3:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.Display_P3,e.channels=R(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.Linear_Display_P3:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.Linear_Display_P3,e.channels=z(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.Rec2020:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.Rec2020,e.channels=S(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.ProPhoto_RGB:{const n=colorData_to_XYZ_D50(e);e.colorNotation=xe.ProPhoto_RGB,e.channels=F(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.A98_RGB:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.A98_RGB,e.channels=$(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.HSL:{const a=colorData_to_XYZ_D65(e);e.colorNotation=xe.HSL,e.channels=M(a.channels),e.channels=e.channels.map(e=>reducePrecisionOrNaN(e,8)),e.channels=normalizeAfterColorConversion(e.channels,0),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n);break}case xe.HWB:{const a=colorData_to_XYZ_D65(e);e.colorNotation=xe.HWB,e.channels=Z(a.channels),e.channels=e.channels.map(e=>reducePrecisionOrNaN(e,8)),e.channels=normalizeAfterColorConversion(e.channels,0),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n);break}case xe.Lab:{const n=colorData_to_XYZ_D50(e);e.colorNotation=xe.Lab,e.channels=P(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.LCH:{const a=colorData_to_XYZ_D50(e);e.colorNotation=xe.LCH,e.channels=H(a.channels),e.channels=normalizeAfterColorConversion(e.channels,2),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n);break}case xe.OKLCH:{const a=colorData_to_XYZ_D65(e);e.colorNotation=xe.OKLCH,e.channels=L(a.channels),e.channels=normalizeAfterColorConversion(e.channels,2),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n);break}case xe.OKLab:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.OKLab,e.channels=D(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.XYZ_D50:{const n=colorData_to_XYZ_D50(e);e.colorNotation=xe.XYZ_D50,e.channels=x(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.XYZ_D65:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.XYZ_D65,e.channels=u(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}default:throw new Error("Unsupported color notation")}return e}function carryForwardMissingComponentsForColorAndNotation(e,n,a,o){if(n===a)return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[0,1,2],[]);if(Le.has(a)&&Le.has(n))return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[0,1,2],[]);switch(a){case xe.HSL:switch(n){case xe.HWB:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[0],[1,2]);case xe.Lab:case xe.OKLab:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[2],[0,1]);case xe.LCH:case xe.OKLCH:return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[2,1,0],[]);default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}case xe.HWB:switch(n){case xe.HSL:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[0],[1,2]);case xe.LCH:case xe.OKLCH:return carryForwardMissingComponents(o,[2],[0,1],e.channels,[0],[1,2]);default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}case xe.Lab:case xe.OKLab:switch(n){case xe.HSL:return carryForwardMissingComponents(o,[2],[0,1],e.channels,[0],[1,2]);case xe.Lab:case xe.OKLab:return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[0,1,2],[]);case xe.LCH:case xe.OKLCH:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[0],[1,2]);default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}case xe.LCH:case xe.OKLCH:switch(n){case xe.HSL:return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[2,1,0],[]);case xe.HWB:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[2],[0,1]);case xe.Lab:case xe.OKLab:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[0],[1,2]);case xe.LCH:case xe.OKLCH:return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[0,1,2],[]);default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}}function convertPowerlessComponentsToMissingComponents(e,n){const a=[...e];switch(n){case xe.HSL:(Number.isNaN(a[1])?0:a[1])<=.001&&(a[0]=Number.NaN,!Number.isNaN(a[1])&&a[1]>0&&(a[1]=0));break;case xe.HWB:Math.max(0,Number.isNaN(a[1])?0:a[1])+Math.max(0,Number.isNaN(a[2])?0:a[2])>=99.999&&(a[0]=Number.NaN,Math.max(0,Number.isNaN(a[1])?0:a[1])+Math.max(0,Number.isNaN(a[2])?0:a[2])<100&&(Number.isNaN(a[1])?a[2]=100:Number.isNaN(a[2])?a[1]=100:a[2]=100-a[1]));break;case xe.LCH:(Number.isNaN(a[1])?0:a[1])<=.0015&&(a[2]=Number.NaN,!Number.isNaN(a[1])&&a[1]>0&&(a[1]=0));break;case xe.OKLCH:(Number.isNaN(a[1])?0:a[1])<=4e-6&&(a[2]=Number.NaN,!Number.isNaN(a[1])&&a[1]>0&&(a[1]=0))}return a}function convertPowerlessComponentsToZeroValuesForDisplay(e,n){const a=[...e];switch(n){case xe.HSL:(Number.isNaN(a[1])?0:a[1])<=.001&&(a[0]=Number.NaN),(reducePrecision$1(a[2])<=0||reducePrecision$1(a[2])>=100)&&(a[0]=Number.NaN,a[1]=Number.NaN);break;case xe.HWB:Math.max(0,Number.isNaN(a[1])?0:a[1])+Math.max(0,Number.isNaN(a[2])?0:a[2])>=99.999&&(a[0]=Number.NaN);break;case xe.Lab:(reducePrecision$1(a[0])<=0||reducePrecision$1(a[0])>=100)&&(a[1]=Number.NaN,a[2]=Number.NaN);break;case xe.LCH:(Number.isNaN(a[1])?0:a[1])<=.0015&&(a[2]=Number.NaN),(reducePrecision$1(a[0])<=0||reducePrecision$1(a[0])>=100)&&(a[1]=Number.NaN,a[2]=Number.NaN);break;case xe.OKLab:(reducePrecision$1(a[0])<=0||reducePrecision$1(a[0])>=1)&&(a[1]=Number.NaN,a[2]=Number.NaN);break;case xe.OKLCH:(Number.isNaN(a[1])?0:a[1])<=4e-6&&(a[2]=Number.NaN),(reducePrecision$1(a[0])<=0||reducePrecision$1(a[0])>=1)&&(a[1]=Number.NaN,a[2]=Number.NaN)}return a}function carryForwardMissingComponents(e,n,a,o,r,t){if(n.length<3&&e.every(Number.isNaN))return[Number.NaN,Number.NaN,Number.NaN];const l=[...o];for(let a=0;aNumber.isNaN(e[n])))for(let e=0;ee<-1e-5||e>1.00001)}function colorDataFitsDisplayP3_Gamut(e){const n={...e,channels:[...e.channels]};n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation);return!colorDataToForRelativeColorSyntax(n,xe.Display_P3).channels.find(e=>e<-1e-5||e>1.00001)}const He=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(He,e=>String.fromCharCode(e.charCodeAt(0)+32))}function normalize_Color_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,100,-2147483647,2147483647),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=3===l?normalize(t[4].value,1,0,1):normalize(t[4].value,1,-2147483647,2147483647),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}const Pe=new Set(["srgb","srgb-linear","display-p3","display-p3-linear","a98-rgb","prophoto-rgb","rec2020","xyz","xyz-d50","xyz-d65"]);function color$1(e,n){const o=[],s=[],c=[],i=[];let u,h,N=!1,m=!1;const p={colorNotation:xe.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};let b=o;for(let r=0;r=0){t=i.value[4].value;continue}}return!1}if(!r)return!1;a.push({color:r,percentage:t}),r=!1,t=!1}}return!!r&&(a.push({color:r,percentage:t}),a)}function colorMixRectangular(e,n){if(!n||!n.length)return!1;for(const e of n)if(e.percentage&&(e.percentage<0||e.percentage>100))return!1;const{items:a,leftover:o}=normalizeMixPercentages(n,!0),r=1-o/100;let t;switch(e){case"srgb":t=xe.RGB;break;case"srgb-linear":t=xe.Linear_sRGB;break;case"display-p3":t=xe.Display_P3;break;case"display-p3-linear":t=xe.Linear_Display_P3;break;case"a98-rgb":t=xe.A98_RGB;break;case"prophoto-rgb":t=xe.ProPhoto_RGB;break;case"rec2020":t=xe.Rec2020;break;case"lab":t=xe.Lab;break;case"oklab":t=xe.OKLab;break;case"xyz-d50":t=xe.XYZ_D50;break;case"xyz":case"xyz-d65":t=xe.XYZ_D65;break;default:return!1}if(1===a.length){const e=colorDataToForInterpolation(a[0].color,t);return e.colorNotation=t,e.syntaxFlags.add(De.ColorMixVariadic),e.syntaxFlags.add(De.ColorMix),"number"!=typeof e.alpha?!1:(e.alpha=e.alpha*r,e)}for(a.reverse();a.length>=2;){const e=a.pop(),n=a.pop();if(!e||!n)return!1;const o=e.percentage+n.percentage,r=o>0?n.percentage/o:.5,l=colorMixRectangularPair(t,e.color,n.color,r);if(!l)return!1;a.push({color:l,percentage:o})}const l=a[0]?.color;return!!l&&("number"==typeof l.alpha&&(l.alpha=l.alpha*r,n.some(e=>e.color.syntaxFlags.has(De.Experimental))&&l.syntaxFlags.add(De.Experimental),2!==n.length&&l.syntaxFlags.add(De.ColorMixVariadic),l))}function colorMixRectangularPair(e,n,a,o){let r=n.alpha;if("number"!=typeof r)return!1;let t=a.alpha;if("number"!=typeof t)return!1;r=Number.isNaN(r)?t:r,t=Number.isNaN(t)?r:t;const l=colorDataToForInterpolation(n,e).channels,s=colorDataToForInterpolation(a,e).channels;l[0]=fillInMissingComponent(l[0],s[0]),s[0]=fillInMissingComponent(s[0],l[0]),l[1]=fillInMissingComponent(l[1],s[1]),s[1]=fillInMissingComponent(s[1],l[1]),l[2]=fillInMissingComponent(l[2],s[2]),s[2]=fillInMissingComponent(s[2],l[2]),l[0]=premultiply(l[0],r),l[1]=premultiply(l[1],r),l[2]=premultiply(l[2],r),s[0]=premultiply(s[0],t),s[1]=premultiply(s[1],t),s[2]=premultiply(s[2],t);const c=interpolate(r,t,o);return{colorNotation:e,channels:[un_premultiply(interpolate(l[0],s[0],o),c),un_premultiply(interpolate(l[1],s[1],o),c),un_premultiply(interpolate(l[2],s[2],o),c)],alpha:c,syntaxFlags:new Set([De.ColorMix])}}function colorMixPolar(e,n,a){if(!a||!a.length)return!1;for(const e of a)if(e.percentage&&(e.percentage<0||e.percentage>100))return!1;const{items:o,leftover:r}=normalizeMixPercentages(a,!0),t=1-r/100;let l;switch(e){case"hsl":l=xe.HSL;break;case"hwb":l=xe.HWB;break;case"lch":l=xe.LCH;break;case"oklch":l=xe.OKLCH;break;default:return!1}if(1===o.length){const e=colorDataToForInterpolation(o[0].color,l);return e.colorNotation=l,e.syntaxFlags.add(De.ColorMixVariadic),e.syntaxFlags.add(De.ColorMix),"number"!=typeof e.alpha?!1:(e.alpha=e.alpha*t,e)}for(o.reverse();o.length>=2;){const e=o.pop(),a=o.pop();if(!e||!a)return!1;const r=e.percentage+a.percentage,t=r>0?a.percentage/r:.5,s=colorMixPolarPair(l,n,e.color,a.color,t);if(!s)return!1;o.push({color:s,percentage:r})}const s=o[0]?.color;return!!s&&("number"==typeof s.alpha&&(s.alpha=s.alpha*t,a.some(e=>e.color.syntaxFlags.has(De.Experimental))&&s.syntaxFlags.add(De.Experimental),2!==a.length&&s.syntaxFlags.add(De.ColorMixVariadic),s))}function colorMixPolarPair(e,n,a,o,r){let t=0,l=0,s=0,c=0,i=0,u=0,h=a.alpha;if("number"!=typeof h)return!1;let N=o.alpha;if("number"!=typeof N)return!1;h=Number.isNaN(h)?N:h,N=Number.isNaN(N)?h:N;const m=colorDataToForInterpolation(a,e).channels,p=colorDataToForInterpolation(o,e).channels;switch(e){case xe.HSL:case xe.HWB:t=m[0],l=p[0],s=m[1],c=p[1],i=m[2],u=p[2];break;case xe.LCH:case xe.OKLCH:s=m[0],c=p[0],i=m[1],u=p[1],t=m[2],l=p[2]}if(s=fillInMissingComponent(s,c),c=fillInMissingComponent(c,s),i=fillInMissingComponent(i,u),u=fillInMissingComponent(u,i),t=fillInMissingComponent(t,l),l=fillInMissingComponent(l,t),Number.isNaN(t)&&Number.isNaN(l));else{const e=l-t;switch(n){case"shorter":e>180?t+=360:e<-180&&(l+=360);break;case"longer":-1800?t+=360:l+=360);break;case"increasing":e<0&&(l+=360);break;case"decreasing":e>0&&(t+=360);break;default:throw new Error("Unknown hue interpolation method")}}s=premultiply(s,h),i=premultiply(i,h),c=premultiply(c,N),u=premultiply(u,N);let b=[0,0,0];const v=interpolate(h,N,r);switch(e){case xe.HSL:case xe.HWB:b=[interpolate(t,l,r),un_premultiply(interpolate(s,c,r),v),un_premultiply(interpolate(i,u,r),v)];break;case xe.LCH:case xe.OKLCH:b=[un_premultiply(interpolate(s,c,r),v),un_premultiply(interpolate(i,u,r),v),interpolate(t,l,r)]}return{colorNotation:e,channels:b,alpha:v,syntaxFlags:new Set([De.ColorMix])}}function fillInMissingComponent(e,n){return Number.isNaN(e)?n:e}function interpolate(e,n,a){return e*(1-a)+n*a}function premultiply(e,n){return Number.isNaN(n)?e:Number.isNaN(e)?Number.NaN:e*n}function un_premultiply(e,n){return 0===n||Number.isNaN(n)?e:Number.isNaN(e)?Number.NaN:e/n}function normalizeMixPercentages(e,n=!1){let a=0,o=0;for(const n of e)n.percentage&&(a+=n.percentage),!1===n.percentage&&o++;a=Math.min(100,a);for(const n of e)!1===n.percentage&&(n.percentage=(100-a)/o);const r=e.slice();let t=0;for(const e of r)t+=e.percentage;if(t>100||t>0&&n)for(const e of r)e.percentage=e.percentage*(100/t);let l=0;return t<100&&(l=100-t),{items:r,leftover:l}}function hex(e){const n=toLowerCaseAZ(e[4].value);if(n.match(/[^a-f0-9]/))return!1;const a={colorNotation:xe.HEX,channels:[0,0,0],alpha:1,syntaxFlags:new Set([De.Hex])},o=n.length;if(3===o){const e=n[0],o=n[1],r=n[2];return a.channels=[parseInt(e+e,16)/255,parseInt(o+o,16)/255,parseInt(r+r,16)/255],a}if(6===o){const e=n[0]+n[1],o=n[2]+n[3],r=n[4]+n[5];return a.channels=[parseInt(e,16)/255,parseInt(o,16)/255,parseInt(r,16)/255],a}if(4===o){const e=n[0],o=n[1],r=n[2],t=n[3];return a.channels=[parseInt(e+e,16)/255,parseInt(o+o,16)/255,parseInt(r+r,16)/255],a.alpha=parseInt(t+t,16)/255,a.syntaxFlags.add(De.HasAlpha),a}if(8===o){const e=n[0]+n[1],o=n[2]+n[3],r=n[4]+n[5],t=n[6]+n[7];return a.channels=[parseInt(e,16)/255,parseInt(o,16)/255,parseInt(r,16)/255],a.alpha=parseInt(t,16)/255,a.syntaxFlags.add(De.HasAlpha),a}return!1}function normalizeHue$1(a){if(r(a))return Number.isNaN(a[4].value)||Number.isFinite(a[4].value)||(a[4].value=0),a[4].value=a[4].value%360,a[4].value<0&&(a[4].value+=360),a[1]=a[4].value.toString(),a;if(c(a)){let o=a[4].value;switch(toLowerCaseAZ(a[4].unit)){case"deg":break;case"rad":o=180*a[4].value/Math.PI;break;case"grad":o=.9*a[4].value;break;case"turn":o=360*a[4].value;break;default:return!1}return Number.isNaN(a[4].value)||Number.isFinite(a[4].value)||(a[4].value=0),o%=360,o<0&&(o+=360),[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}return!1}function normalize_legacy_HSL_ChannelValues(a,t,l){if(0===t){const e=normalizeHue$1(a);return!1!==e&&(c(a)&&l.syntaxFlags.add(De.HasDimensionValues),e)}if(o(a)){let o;return 3===t?l.syntaxFlags.add(De.HasPercentageAlpha):l.syntaxFlags.add(De.HasPercentageValues),o=3===t?normalize(a[4].value,100,0,1):normalize(a[4].value,1,0,100),[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}if(r(a)){if(3!==t)return!1;let o;return o=normalize(a[4].value,1,0,3===t?1:100),[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}return!1}function normalize_modern_HSL_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(0===l){const e=normalizeHue$1(t);return!1!==e&&(c(t)&&s.syntaxFlags.add(De.HasDimensionValues),e)}if(o(t)){let a;return 3===l?s.syntaxFlags.add(De.HasPercentageAlpha):s.syntaxFlags.add(De.HasPercentageValues),a=3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,1,1===l?0:-2147483647,2147483647),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=3===l?normalize(t[4].value,1,0,1):normalize(t[4].value,1,1===l?0:-2147483647,2147483647),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function threeChannelLegacySyntax(e,n,a,o){const t=[],c=[],i=[],u=[],h={colorNotation:a,channels:[0,0,0],alpha:1,syntaxFlags:new Set(o)};let N=t;for(let n=0;nve(e)&&s(e.value))){const n=hslCommaSeparated(e);if(!1!==n)return n}{const a=hslSpaceSeparated(e,n);if(!1!==a)return a}return!1}function hslCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_HSL_ChannelValues,xe.HSL,[De.LegacyHSL])}function hslSpaceSeparated(e,n){return threeChannelSpaceSeparated(e,normalize_modern_HSL_ChannelValues,xe.HSL,[],n)}function normalize_HWB_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(0===l){const e=normalizeHue$1(t);return!1!==e&&(c(t)&&s.syntaxFlags.add(De.HasDimensionValues),e)}if(o(t)){let a;return 3===l?s.syntaxFlags.add(De.HasPercentageAlpha):s.syntaxFlags.add(De.HasPercentageValues),a=3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,1,-2147483647,2147483647),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=3===l?normalize(t[4].value,1,0,1):normalize(t[4].value,1,-2147483647,2147483647),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function normalize_Lab_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=1===l||2===l?normalize(t[4].value,.8,-2147483647,2147483647):3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,1,0,100),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=1===l||2===l?normalize(t[4].value,1,-2147483647,2147483647):normalize(t[4].value,1,0,3===l?1:100),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function lab(e,n){return threeChannelSpaceSeparated(e,normalize_Lab_ChannelValues,xe.Lab,[],n)}function normalize_LCH_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(2===l){const e=normalizeHue$1(t);return!1!==e&&(c(t)&&s.syntaxFlags.add(De.HasDimensionValues),e)}if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=1===l?normalize(t[4].value,100/150,0,2147483647):3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,1,0,100),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=normalize(t[4].value,1,0,1===l?2147483647:3===l?1:100),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function lch(e,n){return threeChannelSpaceSeparated(e,normalize_LCH_ChannelValues,xe.LCH,[],n)}const Fe=new Map;for(const[e,n]of Object.entries(Q))Fe.set(e,n);function namedColor(e){const n=Fe.get(toLowerCaseAZ(e));return!!n&&{colorNotation:xe.RGB,channels:[n[0]/255,n[1]/255,n[2]/255],alpha:1,syntaxFlags:new Set([De.ColorKeyword,De.NamedColor])}}function normalize_OKLab_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=1===l||2===l?normalize(t[4].value,250,-2147483647,2147483647):normalize(t[4].value,100,0,1),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=1===l||2===l?normalize(t[4].value,1,-2147483647,2147483647):normalize(t[4].value,1,0,1),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function oklab(e,n){return threeChannelSpaceSeparated(e,normalize_OKLab_ChannelValues,xe.OKLab,[],n)}function normalize_OKLCH_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(2===l){const e=normalizeHue$1(t);return!1!==e&&(c(t)&&s.syntaxFlags.add(De.HasDimensionValues),e)}if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=1===l?normalize(t[4].value,250,0,2147483647):normalize(t[4].value,100,0,1),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=normalize(t[4].value,1,0,1===l?2147483647:1),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function oklch(e,n){return threeChannelSpaceSeparated(e,normalize_OKLCH_ChannelValues,xe.OKLCH,[],n)}function normalize_legacy_sRGB_ChannelValues(a,t,l){if(o(a)){3===t?l.syntaxFlags.add(De.HasPercentageAlpha):l.syntaxFlags.add(De.HasPercentageValues);const o=normalize(a[4].value,100,0,1);return[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}if(r(a)){let o;return 3!==t&&l.syntaxFlags.add(De.HasNumberValues),o=normalize(a[4].value,3===t?1:255,0,1),[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}return!1}function normalize_modern_sRGB_ChannelValues(t,l,s){if(a(t)&&"none"===t[4].value.toLowerCase())return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,100,-2147483647,2147483647),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=3===l?normalize(t[4].value,1,0,1):normalize(t[4].value,255,-2147483647,2147483647),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function rgb(e,n){if(e.value.some(e=>ve(e)&&s(e.value))){const n=rgbCommaSeparated(e);if(!1!==n)return(!n.syntaxFlags.has(De.HasNumberValues)||!n.syntaxFlags.has(De.HasPercentageValues))&&n}else{const a=rgbSpaceSeparated(e,n);if(!1!==a)return a}return!1}function rgbCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_sRGB_ChannelValues,xe.RGB,[De.LegacyRGB])}function rgbSpaceSeparated(e,n){return threeChannelSpaceSeparated(e,normalize_modern_sRGB_ChannelValues,xe.RGB,[],n)}function XYZ_D65_to_sRGB_Gamut(e){const n=B(e);if(ee(n))return ne(n);let a=e;return a=L(a),a[0]<1e-6&&(a=[0,0,0]),a[0]>.999999&&(a=[1,0,0]),ae(oe(a,oklch_to_lin_srgb,lin_srgb_to_oklch))}function oklch_to_lin_srgb(e){return e=re(e),e=te(e),le(e)}function lin_srgb_to_oklch(e){return e=se(e),e=ce(e),ie(e)}function contrastColor(e,n){let a=!1;for(let o=0;ot?[1,1,1]:[0,0,0],o}function alpha(e,n){let o,s,c=!1,i=!1,u=!1;const h={colorNotation:xe.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};for(let N=0;N{if(ve(e)&&a(e.value)&&"alpha"===toLowerCaseAZ(e.value[4].value)&&o&&o.has("alpha"))return new ge(o.get("alpha"))});h.alpha=e[0][0],i=!0;continue}return!1}if(u)return!1;for(;pe(e.value[N+1])||be(e.value[N+1]);)N++;if(N++,m=e.value[N],u=n(m),!1===u)return!1;o=normalizeRelativeColorDataChannels(u),s=noneToZeroInRelativeColorDataChannels(o),h.syntaxFlags=new Set(u.syntaxFlags),h.syntaxFlags.add(De.RelativeAlphaSyntax),h.channels=[...u.channels],h.colorNotation=u.colorNotation,h.alpha=u.alpha}}return!!o&&(!!i&&h)}function XYZ_D65_to_P3_Gamut(e){const n=R(e);if(ee(n))return ne(n);let a=e;return a=L(a),a[0]<1e-6&&(a=[0,0,0]),a[0]>.999999&&(a=[1,0,0]),he(oe(a,oklch_to_lin_p3,lin_p3_to_oklch))}function oklch_to_lin_p3(e){return e=re(e),e=te(e),Ne(e)}function lin_p3_to_oklch(e){return e=me(e),e=ce(e),ie(e)}function toPrecision(e,n=7){e=+e,n=+n;const a=(Math.floor(Math.abs(e))+"").length;if(n>a)return+e.toFixed(n-a);{const o=10**(a-n);return Math.round(e/o)*o}}function serializeWithAlpha(a,o,r,t){const l=[e.CloseParen,")",-1,-1,void 0];if("number"==typeof a.alpha){const s=Math.min(1,Math.max(0,toPrecision(Number.isNaN(a.alpha)?0:a.alpha)));return 1===toPrecision(s,4)?new _e(o,l,t):new _e(o,l,[...t,new Ce([r]),new ge([e.Delim,"/",-1,-1,{value:"/"}]),new Ce([r]),new ge([e.Number,toPrecision(s,4).toString(),-1,-1,{value:a.alpha,type:n.Integer}])])}return new _e(o,l,[...t,new Ce([r]),new ge([e.Delim,"/",-1,-1,{value:"/"}]),new Ce([r]),a.alpha])}function serializeP3(a,o=!0){a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation);let r=a.channels.map(e=>Number.isNaN(e)?0:e);o?r=XYZ_D65_to_P3_Gamut(colorData_to_XYZ_D65(a).channels):a.colorNotation!==xe.Display_P3&&(r=R(colorData_to_XYZ_D65(a).channels));const t=o?Math.min(1,Math.max(0,toPrecision(r[0],6))):toPrecision(r[0],6),l=o?Math.min(1,Math.max(0,toPrecision(r[1],6))):toPrecision(r[1],6),s=o?Math.min(1,Math.max(0,toPrecision(r[2],6))):toPrecision(r[2],6),c=[e.Function,"color(",-1,-1,{value:"color"}],i=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(a,c,i,[new ge([e.Ident,"display-p3",-1,-1,{value:"display-p3"}]),new Ce([i]),new ge([e.Number,t.toString(),-1,-1,{value:r[0],type:n.Number}]),new Ce([i]),new ge([e.Number,l.toString(),-1,-1,{value:r[1],type:n.Number}]),new Ce([i]),new ge([e.Number,s.toString(),-1,-1,{value:r[2],type:n.Number}])])}function serializeRGB(a,o=!0){let r;a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation),r=o?XYZ_D65_to_sRGB_Gamut(colorData_to_XYZ_D65(a).channels):B(colorData_to_XYZ_D65(a).channels);const t=Math.min(255,Math.max(0,Math.round(255*toPrecision(r[0])))),l=Math.min(255,Math.max(0,Math.round(255*toPrecision(r[1])))),s=Math.min(255,Math.max(0,Math.round(255*toPrecision(r[2])))),c=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],u=[e.Comma,",",-1,-1,void 0],h=[new ge([e.Number,t.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,r[0])),type:n.Integer}]),new ge(u),new Ce([i]),new ge([e.Number,l.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,r[1])),type:n.Integer}]),new ge(u),new Ce([i]),new ge([e.Number,s.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,r[2])),type:n.Integer}])];if("number"==typeof a.alpha){const o=Math.min(1,Math.max(0,toPrecision(Number.isNaN(a.alpha)?0:a.alpha)));return 1===toPrecision(o,4)?new _e([e.Function,"rgb(",-1,-1,{value:"rgb"}],c,h):new _e([e.Function,"rgba(",-1,-1,{value:"rgba"}],c,[...h,new ge(u),new Ce([i]),new ge([e.Number,toPrecision(o,4).toString(),-1,-1,{value:a.alpha,type:n.Number}])])}return new _e([e.Function,"rgba(",-1,-1,{value:"rgba"}],c,[...h,new ge(u),new Ce([i]),a.alpha])}function serializeHSL(a,o=!0){let r;a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation),r=M(o?w(XYZ_D65_to_sRGB_Gamut(colorData_to_XYZ_D65(a).channels)):colorData_to_XYZ_D65(a).channels),r=r.map(e=>Number.isNaN(e)?0:e);const t=Math.min(360,Math.max(0,Math.round(toPrecision(r[0]))))%360,l=Math.min(100,Math.max(0,Math.round(toPrecision(r[1])))),s=Math.min(100,Math.max(0,Math.round(toPrecision(r[2])))),c=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],u=[e.Comma,",",-1,-1,void 0],h=[new ge([e.Number,t.toString(),-1,-1,{value:r[0],type:n.Integer}]),new ge(u),new Ce([i]),new ge([e.Percentage,l.toString()+"%",-1,-1,{value:r[1]}]),new ge(u),new Ce([i]),new ge([e.Percentage,s.toString()+"%",-1,-1,{value:r[2]}])];if("number"==typeof a.alpha){const o=Math.min(1,Math.max(0,toPrecision(Number.isNaN(a.alpha)?0:a.alpha)));return 1===toPrecision(o,4)?new _e([e.Function,"hsl(",-1,-1,{value:"hsl"}],c,h):new _e([e.Function,"hsla(",-1,-1,{value:"hsla"}],c,[...h,new ge(u),new Ce([i]),new ge([e.Number,toPrecision(o,4).toString(),-1,-1,{value:a.alpha,type:n.Number}])])}return new _e([e.Function,"hsla(",-1,-1,{value:"hsla"}],c,[...h,new ge(u),new Ce([i]),a.alpha])}function serializeOKLCH(a){a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation);let o=a.channels.map(e=>Number.isNaN(e)?0:e);a.colorNotation!==xe.OKLCH&&(o=L(colorData_to_XYZ_D65(a).channels));const r=toPrecision(o[0],6),t=toPrecision(o[1],6),l=toPrecision(o[2],6),s=[e.Function,"oklch(",-1,-1,{value:"oklch"}],c=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(a,s,c,[new ge([e.Number,r.toString(),-1,-1,{value:o[0],type:n.Number}]),new Ce([c]),new ge([e.Number,t.toString(),-1,-1,{value:o[1],type:n.Number}]),new Ce([c]),new ge([e.Number,l.toString(),-1,-1,{value:o[2],type:n.Number}])])}function computedValue(e,n=!0){const a=e.channels;switch(e.colorNotation){case xe.Lab:return a[0]=nanToNone(a[0]),a[1]=nanToNone(a[1]),a[2]=nanToNone(a[2]),1!==e.alpha?`lab(${a[0]} ${a[1]} ${a[2]} / ${nanToNone(e.alpha)})`:`lab(${a[0]} ${a[1]} ${a[2]})`;case xe.LCH:return a[0]=nanToNone(a[0]),a[1]=nanToNone(a[1]),a[2]=nanToNone(normalizeHue(a[2])),1!==e.alpha?`lch(${a[0]} ${a[1]} ${a[2]} / ${nanToNone(e.alpha)})`:`lch(${a[0]} ${a[1]} ${a[2]})`;case xe.OKLab:return a[0]=nanToNone(a[0]),a[1]=nanToNone(a[1]),a[2]=nanToNone(a[2]),1!==e.alpha?`oklab(${a[0]} ${a[1]} ${a[2]} / ${nanToNone(e.alpha)})`:`oklab(${a[0]} ${a[1]} ${a[2]})`;case xe.OKLCH:return a[0]=nanToNone(a[0]),a[1]=nanToNone(a[1]),a[2]=nanToNone(normalizeHue(a[2])),1!==e.alpha?`oklch(${a[0]} ${a[1]} ${a[2]} / ${nanToNone(e.alpha)})`:`oklch(${a[0]} ${a[1]} ${a[2]})`;case xe.RGB:case xe.HEX:return a.some(Number.isNaN)||Number.isNaN(e.alpha)?1!==e.alpha?`color(srgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(srgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`:e.syntaxFlags.has(De.RelativeColorSyntax)||e.syntaxFlags.has(De.ColorMix)||e.syntaxFlags.has(De.RelativeAlphaSyntax)?computedValue(colorDataToForRelativeColorSyntax(e,xe.sRGB)):1!==e.alpha?`rgba(${nanToNone(Math.round(255*reducePrecision(e.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(e.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(e.channels[2],5)))}, ${nanToNone(e.alpha)})`:`rgb(${nanToNone(Math.round(255*reducePrecision(e.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(e.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(e.channels[2],5)))})`;case xe.HSL:{if(a.some(Number.isNaN)||Number.isNaN(e.alpha)||!1===n)return 1!==e.alpha?`hsl(${nanToNone(normalizeHue(a[0]))} ${nanToNone(a[1],"%")} ${nanToNone(a[2],"%")} / ${nanToNone(e.alpha)})`:`hsl(${nanToNone(normalizeHue(a[0]))} ${nanToNone(a[1],"%")} ${nanToNone(a[2],"%")})`;if(e.syntaxFlags.has(De.RelativeColorSyntax)||e.syntaxFlags.has(De.ColorMix)||e.syntaxFlags.has(De.RelativeAlphaSyntax))return computedValue(colorDataToForRelativeColorSyntax(e,xe.sRGB));const o=colorDataToForRelativeColorSyntax(e,xe.RGB);return 1!==o.alpha?`rgba(${nanToNone(Math.round(255*reducePrecision(o.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[2],5)))}, ${nanToNone(o.alpha)})`:`rgb(${nanToNone(Math.round(255*reducePrecision(o.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[2],5)))})`}case xe.HWB:{if(a.some(Number.isNaN)||Number.isNaN(e.alpha)||!1===n)return 1!==e.alpha?`hwb(${nanToNone(normalizeHue(a[0]))} ${nanToNone(a[1],"%")} ${nanToNone(a[2],"%")} / ${nanToNone(e.alpha)})`:`hwb(${nanToNone(normalizeHue(a[0]))} ${nanToNone(a[1],"%")} ${nanToNone(a[2],"%")})`;if(e.syntaxFlags.has(De.RelativeColorSyntax)||e.syntaxFlags.has(De.ColorMix)||e.syntaxFlags.has(De.RelativeAlphaSyntax))return computedValue(colorDataToForRelativeColorSyntax(e,xe.sRGB));const o=colorDataToForRelativeColorSyntax(e,xe.RGB);return 1!==o.alpha?`rgba(${nanToNone(Math.round(255*reducePrecision(o.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[2],5)))}, ${nanToNone(o.alpha)})`:`rgb(${nanToNone(Math.round(255*reducePrecision(o.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[2],5)))})`}case xe.sRGB:return 1!==e.alpha?`color(srgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(srgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.Linear_sRGB:return 1!==e.alpha?`color(srgb-linear ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(srgb-linear ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.Display_P3:return 1!==e.alpha?`color(display-p3 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(display-p3 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.Linear_Display_P3:return 1!==e.alpha?`color(display-p3-linear ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(display-p3-linear ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.A98_RGB:return 1!==e.alpha?`color(a98-rgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(a98-rgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.ProPhoto_RGB:return 1!==e.alpha?`color(prophoto-rgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(prophoto-rgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.Rec2020:return 1!==e.alpha?`color(rec2020 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(rec2020 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.XYZ_D65:return 1!==e.alpha?`color(xyz-d65 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(xyz-d65 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.XYZ_D50:return 1!==e.alpha?`color(xyz-d50 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(xyz-d50 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`}throw new Error("unsupported color")}function nanToNone(e,n=""){return"string"==typeof e?e:"number"!=typeof e?e.toString():Number.isNaN(e)?"none":n?e.toString()+n:e.toString()}function normalizeHue(e){return"number"!=typeof e||Number.isNaN(e)?e:e%360}function reducePrecision(e,n=8){return Number.isNaN(e)||!Number.isFinite(e)?e:(n=Math.pow(10,n),Math.round(e*n)/n)}function color(e){if(fe(e)){switch(toLowerCaseAZ(e.getName())){case"rgb":case"rgba":return rgb(e,color);case"hsl":case"hsla":return hsl(e,color);case"hwb":return n=color,threeChannelSpaceSeparated(e,normalize_HWB_ChannelValues,xe.HWB,[],n);case"lab":return lab(e,color);case"lch":return lch(e,color);case"oklab":return oklab(e,color);case"oklch":return oklch(e,color);case"color":return color$1(e,color);case"color-mix":return colorMix(e,color);case"contrast-color":return contrastColor(e,color);case"alpha":return alpha(e,color)}}var n;if(ve(e)){if(i(e.value))return hex(e.value);if(a(e.value)){const n=namedColor(e.value[4].value);return!1!==n?n:"transparent"===toLowerCaseAZ(e.value[4].value)&&{colorNotation:xe.RGB,channels:[0,0,0],alpha:0,syntaxFlags:new Set([De.ColorKeyword])}}}return!1}export{xe as ColorNotation,De as SyntaxFlag,color,colorDataFitsDisplayP3_Gamut,colorDataFitsRGB_Gamut,computedValue,serializeHSL,serializeOKLCH,serializeP3,serializeRGB}; +import{TokenType as e,NumberType as n,isTokenIdent as a,isTokenPercentage as o,isTokenNumber as r,isTokenDelim as t,isTokenNumeric as l,isTokenComma as s,isTokenDimension as c,isTokenHash as i}from"@csstools/css-tokenizer";import{XYZ_D65_to_XYZ_D65 as u,XYZ_D50_to_XYZ_D65 as h,OKLCH_to_XYZ_D65 as N,LCH_to_XYZ_D65 as m,OKLab_to_XYZ_D65 as p,Lab_to_XYZ_D65 as b,HWB_to_XYZ_D65 as v,HSL_to_XYZ_D65 as f,ProPhoto_RGB_to_XYZ_D65 as g,a98_RGB_to_XYZ_D65 as d,rec_2020_to_XYZ_D65 as y,lin_P3_to_XYZ_D65 as _,P3_to_XYZ_D65 as C,lin_sRGB_to_XYZ_D65 as T,sRGB_to_XYZ_D65 as w,XYZ_D50_to_XYZ_D50 as x,XYZ_D65_to_OKLab as D,XYZ_D65_to_OKLCH as L,XYZ_D50_to_LCH as H,XYZ_D50_to_Lab as P,XYZ_D65_to_HWB as Z,XYZ_D65_to_HSL as $,XYZ_D65_to_a98_RGB as F,XYZ_D50_to_ProPhoto as M,XYZ_D65_to_rec_2020 as S,XYZ_D65_to_lin_P3 as z,XYZ_D65_to_P3 as R,XYZ_D65_to_lin_sRGB as k,XYZ_D65_to_sRGB as B,XYZ_D65_to_XYZ_D50 as X,OKLCH_to_XYZ_D50 as G,LCH_to_XYZ_D50 as A,OKLab_to_XYZ_D50 as Y,Lab_to_XYZ_D50 as V,HWB_to_XYZ_D50 as K,HSL_to_XYZ_D50 as I,ProPhoto_RGB_to_XYZ_D50 as O,a98_RGB_to_XYZ_D50 as W,rec_2020_to_XYZ_D50 as E,lin_P3_to_XYZ_D50 as U,P3_to_XYZ_D50 as j,lin_sRGB_to_XYZ_D50 as q,sRGB_to_XYZ_D50 as J,namedColors as Q,inGamut as ee,clip as ne,gam_sRGB as ae,mapGamutRayTrace as oe,OKLCH_to_OKLab as re,OKLab_to_XYZ as te,XYZ_to_lin_sRGB as le,lin_sRGB_to_XYZ as se,XYZ_to_OKLab as ce,OKLab_to_OKLCH as ie,contrast_ratio_wcag_2_1 as ue,gam_P3 as he,XYZ_to_lin_P3 as Ne,lin_P3_to_XYZ as me}from"@csstools/color-helpers";import{isWhitespaceNode as pe,isCommentNode as be,isTokenNode as ve,isFunctionNode as fe,TokenNode as ge,isWhiteSpaceOrCommentNode as de,replaceComponentValues as ye,FunctionNode as _e,WhitespaceNode as Ce}from"@csstools/css-parser-algorithms";import{mathFunctionNames as Te,calcFromComponentValues as we}from"@csstools/css-calc";var xe,De;function convertNaNToZero(e){return[Number.isNaN(e[0])?0:e[0],Number.isNaN(e[1])?0:e[1],Number.isNaN(e[2])?0:e[2]]}function colorData_to_XYZ_D50(e){switch(e.colorNotation){case xe.HEX:case xe.RGB:case xe.sRGB:return{...e,colorNotation:xe.XYZ_D50,channels:J(convertNaNToZero(e.channels))};case xe.Linear_sRGB:return{...e,colorNotation:xe.XYZ_D50,channels:q(convertNaNToZero(e.channels))};case xe.Display_P3:return{...e,colorNotation:xe.XYZ_D50,channels:j(convertNaNToZero(e.channels))};case xe.Linear_Display_P3:return{...e,colorNotation:xe.XYZ_D50,channels:U(convertNaNToZero(e.channels))};case xe.Rec2020:return{...e,colorNotation:xe.XYZ_D50,channels:E(convertNaNToZero(e.channels))};case xe.A98_RGB:return{...e,colorNotation:xe.XYZ_D50,channels:W(convertNaNToZero(e.channels))};case xe.ProPhoto_RGB:return{...e,colorNotation:xe.XYZ_D50,channels:O(convertNaNToZero(e.channels))};case xe.HSL:return{...e,colorNotation:xe.XYZ_D50,channels:I(convertNaNToZero(e.channels))};case xe.HWB:return{...e,colorNotation:xe.XYZ_D50,channels:K(convertNaNToZero(e.channels))};case xe.Lab:return{...e,colorNotation:xe.XYZ_D50,channels:V(convertNaNToZero(e.channels))};case xe.OKLab:return{...e,colorNotation:xe.XYZ_D50,channels:Y(convertNaNToZero(e.channels))};case xe.LCH:return{...e,colorNotation:xe.XYZ_D50,channels:A(convertNaNToZero(e.channels))};case xe.OKLCH:return{...e,colorNotation:xe.XYZ_D50,channels:G(convertNaNToZero(e.channels))};case xe.XYZ_D50:return{...e,colorNotation:xe.XYZ_D50,channels:x(convertNaNToZero(e.channels))};case xe.XYZ_D65:return{...e,colorNotation:xe.XYZ_D50,channels:X(convertNaNToZero(e.channels))};default:throw new Error("Unsupported color notation")}}function colorData_to_XYZ_D65(e){switch(e.colorNotation){case xe.HEX:case xe.RGB:case xe.sRGB:return{...e,colorNotation:xe.XYZ_D65,channels:w(convertNaNToZero(e.channels))};case xe.Linear_sRGB:return{...e,colorNotation:xe.XYZ_D65,channels:T(convertNaNToZero(e.channels))};case xe.Display_P3:return{...e,colorNotation:xe.XYZ_D65,channels:C(convertNaNToZero(e.channels))};case xe.Linear_Display_P3:return{...e,colorNotation:xe.XYZ_D65,channels:_(convertNaNToZero(e.channels))};case xe.Rec2020:return{...e,colorNotation:xe.XYZ_D65,channels:y(convertNaNToZero(e.channels))};case xe.A98_RGB:return{...e,colorNotation:xe.XYZ_D65,channels:d(convertNaNToZero(e.channels))};case xe.ProPhoto_RGB:return{...e,colorNotation:xe.XYZ_D65,channels:g(convertNaNToZero(e.channels))};case xe.HSL:return{...e,colorNotation:xe.XYZ_D65,channels:f(convertNaNToZero(e.channels))};case xe.HWB:return{...e,colorNotation:xe.XYZ_D65,channels:v(convertNaNToZero(e.channels))};case xe.Lab:return{...e,colorNotation:xe.XYZ_D65,channels:b(convertNaNToZero(e.channels))};case xe.OKLab:return{...e,colorNotation:xe.XYZ_D65,channels:p(convertNaNToZero(e.channels))};case xe.LCH:return{...e,colorNotation:xe.XYZ_D65,channels:m(convertNaNToZero(e.channels))};case xe.OKLCH:return{...e,colorNotation:xe.XYZ_D65,channels:N(convertNaNToZero(e.channels))};case xe.XYZ_D50:return{...e,colorNotation:xe.XYZ_D65,channels:h(convertNaNToZero(e.channels))};case xe.XYZ_D65:return{...e,colorNotation:xe.XYZ_D65,channels:u(convertNaNToZero(e.channels))};default:throw new Error("Unsupported color notation")}}!function(e){e.A98_RGB="a98-rgb",e.Display_P3="display-p3",e.Linear_Display_P3="display-p3-linear",e.HEX="hex",e.HSL="hsl",e.HWB="hwb",e.LCH="lch",e.Lab="lab",e.Linear_sRGB="srgb-linear",e.OKLCH="oklch",e.OKLab="oklab",e.ProPhoto_RGB="prophoto-rgb",e.RGB="rgb",e.sRGB="srgb",e.Rec2020="rec2020",e.XYZ_D50="xyz-d50",e.XYZ_D65="xyz-d65"}(xe||(xe={})),function(e){e.ColorKeyword="color-keyword",e.HasAlpha="has-alpha",e.HasDimensionValues="has-dimension-values",e.HasNoneKeywords="has-none-keywords",e.HasNumberValues="has-number-values",e.HasPercentageAlpha="has-percentage-alpha",e.HasPercentageValues="has-percentage-values",e.HasVariableAlpha="has-variable-alpha",e.Hex="hex",e.LegacyHSL="legacy-hsl",e.LegacyRGB="legacy-rgb",e.NamedColor="named-color",e.RelativeColorSyntax="relative-color-syntax",e.ColorMix="color-mix",e.ColorMixVariadic="color-mix-variadic",e.ContrastColor="contrast-color",e.RelativeAlphaSyntax="relative-alpha-syntax",e.Experimental="experimental"}(De||(De={}));const Le=new Set([xe.A98_RGB,xe.Display_P3,xe.Linear_Display_P3,xe.HEX,xe.Linear_sRGB,xe.ProPhoto_RGB,xe.RGB,xe.sRGB,xe.Rec2020,xe.XYZ_D50,xe.XYZ_D65]);function colorDataToForInterpolation(e,n){if(e.colorNotation===n)return{...e};const a=[...e.channels];let o={...e};return o.channels=convertPowerlessComponentsToMissingComponents(o.channels,e.colorNotation),o=convertToDestination(o,n),o.channels=carryForwardMissingComponentsForColorAndNotation(o,e.colorNotation,n,a),o}function colorDataToForRelativeColorSyntax(e,n){if(e.colorNotation===n)return{...e};const a=[...e.channels];let o={...e};return o.channels=convertPowerlessComponentsToMissingComponents(o.channels,e.colorNotation),o=convertToDestination(o,n),o.channels=carryForwardMissingComponentsForColorAndNotation(o,e.colorNotation,n,a),o}function convertToDestination(e,n){if(e.colorNotation===n)return e.channels=convertNaNToZero(e.channels),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n),e;switch(n){case xe.HEX:case xe.RGB:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.RGB,e.channels=B(n.channels),e.channels=e.channels.map(e=>reducePrecisionOrNaN(e,8)),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.sRGB:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.sRGB,e.channels=B(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.Linear_sRGB:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.Linear_sRGB,e.channels=k(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.Display_P3:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.Display_P3,e.channels=R(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.Linear_Display_P3:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.Linear_Display_P3,e.channels=z(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.Rec2020:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.Rec2020,e.channels=S(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.ProPhoto_RGB:{const n=colorData_to_XYZ_D50(e);e.colorNotation=xe.ProPhoto_RGB,e.channels=M(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.A98_RGB:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.A98_RGB,e.channels=F(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.HSL:{const a=colorData_to_XYZ_D65(e);e.colorNotation=xe.HSL,e.channels=$(a.channels),e.channels=e.channels.map(e=>reducePrecisionOrNaN(e,8)),e.channels=normalizeAfterColorConversion(e.channels,0),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n);break}case xe.HWB:{const a=colorData_to_XYZ_D65(e);e.colorNotation=xe.HWB,e.channels=Z(a.channels),e.channels=e.channels.map(e=>reducePrecisionOrNaN(e,8)),e.channels=normalizeAfterColorConversion(e.channels,0),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n);break}case xe.Lab:{const n=colorData_to_XYZ_D50(e);e.colorNotation=xe.Lab,e.channels=P(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.LCH:{const a=colorData_to_XYZ_D50(e);e.colorNotation=xe.LCH,e.channels=H(a.channels),e.channels=normalizeAfterColorConversion(e.channels,2),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n);break}case xe.OKLCH:{const a=colorData_to_XYZ_D65(e);e.colorNotation=xe.OKLCH,e.channels=L(a.channels),e.channels=normalizeAfterColorConversion(e.channels,2),e.channels=convertPowerlessComponentsToMissingComponents(e.channels,n);break}case xe.OKLab:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.OKLab,e.channels=D(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.XYZ_D50:{const n=colorData_to_XYZ_D50(e);e.colorNotation=xe.XYZ_D50,e.channels=x(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}case xe.XYZ_D65:{const n=colorData_to_XYZ_D65(e);e.colorNotation=xe.XYZ_D65,e.channels=u(n.channels),e.channels=normalizeAfterColorConversion(e.channels);break}default:throw new Error("Unsupported color notation")}return e}function carryForwardMissingComponentsForColorAndNotation(e,n,a,o){if(n===a)return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[0,1,2],[]);if(Le.has(a)&&Le.has(n))return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[0,1,2],[]);switch(a){case xe.HSL:switch(n){case xe.HWB:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[0],[1,2]);case xe.Lab:case xe.OKLab:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[2],[0,1]);case xe.LCH:case xe.OKLCH:return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[2,1,0],[]);default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}case xe.HWB:switch(n){case xe.HSL:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[0],[1,2]);case xe.LCH:case xe.OKLCH:return carryForwardMissingComponents(o,[2],[0,1],e.channels,[0],[1,2]);default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}case xe.Lab:case xe.OKLab:switch(n){case xe.HSL:return carryForwardMissingComponents(o,[2],[0,1],e.channels,[0],[1,2]);case xe.Lab:case xe.OKLab:return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[0,1,2],[]);case xe.LCH:case xe.OKLCH:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[0],[1,2]);default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}case xe.LCH:case xe.OKLCH:switch(n){case xe.HSL:return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[2,1,0],[]);case xe.HWB:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[2],[0,1]);case xe.Lab:case xe.OKLab:return carryForwardMissingComponents(o,[0],[1,2],e.channels,[0],[1,2]);case xe.LCH:case xe.OKLCH:return carryForwardMissingComponents(o,[0,1,2],[],e.channels,[0,1,2],[]);default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}default:return carryForwardMissingComponents(o,[],[],e.channels,[],[])}}function convertPowerlessComponentsToMissingComponents(e,n){const a=[...e];switch(n){case xe.HSL:(Number.isNaN(a[1])?0:a[1])<=.001&&(a[0]=Number.NaN,!Number.isNaN(a[1])&&a[1]>0&&(a[1]=0));break;case xe.HWB:{const e=Number.isNaN(a[1])?0:a[1],n=Number.isNaN(a[2])?0:a[2];e+n>=99.999&&(a[0]=Number.NaN,e+n<100&&(Number.isNaN(a[1])?a[2]=100:Number.isNaN(a[2])?a[1]=100:a[2]=100-a[1]));break}case xe.LCH:(Number.isNaN(a[1])?0:a[1])<=.0015&&(a[2]=Number.NaN,!Number.isNaN(a[1])&&a[1]>0&&(a[1]=0));break;case xe.OKLCH:(Number.isNaN(a[1])?0:a[1])<=4e-6&&(a[2]=Number.NaN,!Number.isNaN(a[1])&&a[1]>0&&(a[1]=0))}return a}function convertPowerlessComponentsToZeroValuesForDisplay(e,n){const a=[...e];switch(n){case xe.HSL:(Number.isNaN(a[1])?0:a[1])<=.001&&(a[0]=Number.NaN),(reducePrecision$1(a[2])<=0||reducePrecision$1(a[2])>=100)&&(a[0]=Number.NaN,a[1]=Number.NaN);break;case xe.HWB:(Number.isNaN(a[1])?0:a[1])+(Number.isNaN(a[2])?0:a[2])>=99.999&&(a[0]=Number.NaN);break;case xe.Lab:(reducePrecision$1(a[0])<=0||reducePrecision$1(a[0])>=100)&&(a[1]=Number.NaN,a[2]=Number.NaN);break;case xe.LCH:(Number.isNaN(a[1])?0:a[1])<=.0015&&(a[2]=Number.NaN),(reducePrecision$1(a[0])<=0||reducePrecision$1(a[0])>=100)&&(a[1]=Number.NaN,a[2]=Number.NaN);break;case xe.OKLab:(reducePrecision$1(a[0])<=0||reducePrecision$1(a[0])>=1)&&(a[1]=Number.NaN,a[2]=Number.NaN);break;case xe.OKLCH:(Number.isNaN(a[1])?0:a[1])<=4e-6&&(a[2]=Number.NaN),(reducePrecision$1(a[0])<=0||reducePrecision$1(a[0])>=1)&&(a[1]=Number.NaN,a[2]=Number.NaN)}return a}function carryForwardMissingComponents(e,n,a,o,r,t){if(n.length<3&&e.every(Number.isNaN))return[Number.NaN,Number.NaN,Number.NaN];const l=[...o];for(let a=0;aNumber.isNaN(e[n])))for(let e=0;ee<-1e-5||e>1.00001)}function colorDataFitsDisplayP3_Gamut(e){const n={...e,channels:[...e.channels]};n.channels=convertPowerlessComponentsToZeroValuesForDisplay(n.channels,n.colorNotation);return!colorDataToForRelativeColorSyntax(n,xe.Display_P3).channels.find(e=>e<-1e-5||e>1.00001)}function normalize(e,n,a,o){return Math.min(Math.max(e/n,a),o)}const He=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(He,e=>String.fromCharCode(e.charCodeAt(0)+32))}const Pe=-2147483647,Ze=2147483647;function normalize_Color_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,100,Pe,Ze),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=3===l?normalize(t[4].value,1,0,1):normalize(t[4].value,1,Pe,Ze),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}const $e=new Set(["srgb","srgb-linear","display-p3","display-p3-linear","a98-rgb","prophoto-rgb","rec2020","xyz","xyz-d50","xyz-d65"]);function color$1(e,n){const o=[],s=[],c=[],i=[];let u,h,N=!1,m=!1;const p={colorNotation:xe.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};let b=o;for(let r=0;r=0&&i.value[4].value<=100){t=i.value[4].value;continue}}}return!1}if(!r)return!1;a.push({color:r,percentage:t}),r=!1,t=!1}}return!!r&&(a.push({color:r,percentage:t}),a)}function colorMixRectangular(e,n){if(!n||!n.length)return!1;for(const e of n)if(e.percentage&&(e.percentage<0||e.percentage>100))return!1;const{items:a,leftover:o}=normalizeMixPercentages(n,!0),r=1-o/100;let t;switch(e){case"srgb":t=xe.RGB;break;case"srgb-linear":t=xe.Linear_sRGB;break;case"display-p3":t=xe.Display_P3;break;case"display-p3-linear":t=xe.Linear_Display_P3;break;case"a98-rgb":t=xe.A98_RGB;break;case"prophoto-rgb":t=xe.ProPhoto_RGB;break;case"rec2020":t=xe.Rec2020;break;case"lab":t=xe.Lab;break;case"oklab":t=xe.OKLab;break;case"xyz-d50":t=xe.XYZ_D50;break;case"xyz":case"xyz-d65":t=xe.XYZ_D65;break;default:return!1}if(1===a.length){const e=colorDataToForInterpolation(a[0].color,t);return e.colorNotation=t,e.syntaxFlags.add(De.ColorMixVariadic),e.syntaxFlags.add(De.ColorMix),"number"!=typeof e.alpha?!1:(e.alpha=e.alpha*r,e)}for(a.reverse();a.length>=2;){const e=a.pop(),n=a.pop();if(!e||!n)return!1;const o=e.percentage+n.percentage,r=o>0?n.percentage/o:.5,l=colorMixRectangularPair(t,e.color,n.color,r);if(!l)return!1;a.push({color:l,percentage:o})}const l=a[0]?.color;return!!l&&("number"==typeof l.alpha&&(l.alpha=l.alpha*r,n.some(e=>e.color.syntaxFlags.has(De.Experimental))&&l.syntaxFlags.add(De.Experimental),2!==n.length&&l.syntaxFlags.add(De.ColorMixVariadic),l))}function colorMixRectangularPair(e,n,a,o){let r=n.alpha;if("number"!=typeof r)return!1;let t=a.alpha;if("number"!=typeof t)return!1;r=Number.isNaN(r)?t:r,t=Number.isNaN(t)?r:t;const l=colorDataToForInterpolation(n,e).channels,s=colorDataToForInterpolation(a,e).channels;l[0]=fillInMissingComponent(l[0],s[0]),s[0]=fillInMissingComponent(s[0],l[0]),l[1]=fillInMissingComponent(l[1],s[1]),s[1]=fillInMissingComponent(s[1],l[1]),l[2]=fillInMissingComponent(l[2],s[2]),s[2]=fillInMissingComponent(s[2],l[2]),l[0]=premultiply(l[0],r),l[1]=premultiply(l[1],r),l[2]=premultiply(l[2],r),s[0]=premultiply(s[0],t),s[1]=premultiply(s[1],t),s[2]=premultiply(s[2],t);const c=interpolate(r,t,o);return{colorNotation:e,channels:[un_premultiply(interpolate(l[0],s[0],o),c),un_premultiply(interpolate(l[1],s[1],o),c),un_premultiply(interpolate(l[2],s[2],o),c)],alpha:c,syntaxFlags:new Set([De.ColorMix])}}function colorMixPolar(e,n,a){if(!a||!a.length)return!1;for(const e of a)if(e.percentage&&(e.percentage<0||e.percentage>100))return!1;const{items:o,leftover:r}=normalizeMixPercentages(a,!0),t=1-r/100;let l;switch(e){case"hsl":l=xe.HSL;break;case"hwb":l=xe.HWB;break;case"lch":l=xe.LCH;break;case"oklch":l=xe.OKLCH;break;default:return!1}if(1===o.length){const e=colorDataToForInterpolation(o[0].color,l);return e.colorNotation=l,e.syntaxFlags.add(De.ColorMixVariadic),e.syntaxFlags.add(De.ColorMix),"number"!=typeof e.alpha?!1:(e.alpha=e.alpha*t,e)}for(o.reverse();o.length>=2;){const e=o.pop(),a=o.pop();if(!e||!a)return!1;const r=e.percentage+a.percentage,t=r>0?a.percentage/r:.5,s=colorMixPolarPair(l,n,e.color,a.color,t);if(!s)return!1;o.push({color:s,percentage:r})}const s=o[0]?.color;return!!s&&("number"==typeof s.alpha&&(s.alpha=s.alpha*t,a.some(e=>e.color.syntaxFlags.has(De.Experimental))&&s.syntaxFlags.add(De.Experimental),2!==a.length&&s.syntaxFlags.add(De.ColorMixVariadic),s))}function colorMixPolarPair(e,n,a,o,r){let t=0,l=0,s=0,c=0,i=0,u=0,h=a.alpha;if("number"!=typeof h)return!1;let N=o.alpha;if("number"!=typeof N)return!1;h=Number.isNaN(h)?N:h,N=Number.isNaN(N)?h:N;const m=colorDataToForInterpolation(a,e).channels,p=colorDataToForInterpolation(o,e).channels;switch(e){case xe.HSL:case xe.HWB:t=m[0],l=p[0],s=m[1],c=p[1],i=m[2],u=p[2];break;case xe.LCH:case xe.OKLCH:s=m[0],c=p[0],i=m[1],u=p[1],t=m[2],l=p[2]}if(s=fillInMissingComponent(s,c),c=fillInMissingComponent(c,s),i=fillInMissingComponent(i,u),u=fillInMissingComponent(u,i),t=fillInMissingComponent(t,l),l=fillInMissingComponent(l,t),Number.isNaN(t)&&Number.isNaN(l));else{const e=l-t;switch(n){case"shorter":e>180?t+=360:e<-180&&(l+=360);break;case"longer":-1800?t+=360:l+=360);break;case"increasing":e<0&&(l+=360);break;case"decreasing":e>0&&(t+=360);break;default:throw new Error("Unknown hue interpolation method")}}s=premultiply(s,h),i=premultiply(i,h),c=premultiply(c,N),u=premultiply(u,N);let b=[0,0,0];const v=interpolate(h,N,r);switch(e){case xe.HSL:case xe.HWB:b=[interpolate(t,l,r),un_premultiply(interpolate(s,c,r),v),un_premultiply(interpolate(i,u,r),v)];break;case xe.LCH:case xe.OKLCH:b=[un_premultiply(interpolate(s,c,r),v),un_premultiply(interpolate(i,u,r),v),interpolate(t,l,r)]}return{colorNotation:e,channels:b,alpha:v,syntaxFlags:new Set([De.ColorMix])}}function fillInMissingComponent(e,n){return Number.isNaN(e)?n:e}function interpolate(e,n,a){return e*(1-a)+n*a}function premultiply(e,n){return Number.isNaN(n)?e:Number.isNaN(e)?Number.NaN:e*n}function un_premultiply(e,n){return 0===n||Number.isNaN(n)?e:Number.isNaN(e)?Number.NaN:e/n}function normalizeMixPercentages(e,n=!1){let a=0,o=0;for(const n of e)n.percentage&&(a+=n.percentage),!1===n.percentage&&o++;a=Math.min(100,a);for(const n of e)!1===n.percentage&&(n.percentage=(100-a)/o);const r=e.slice();let t=0;for(const e of r)t+=e.percentage;if(t>100||t>0&&n)for(const e of r)e.percentage=e.percentage*(100/t);let l=0;return t<100&&(l=100-t),{items:r,leftover:l}}function hex(e){const n=toLowerCaseAZ(e[4].value);if(n.match(/[^a-f0-9]/))return!1;const a={colorNotation:xe.HEX,channels:[0,0,0],alpha:1,syntaxFlags:new Set([De.Hex])},o=n.length;if(3===o){const e=n[0],o=n[1],r=n[2];return a.channels=[parseInt(e+e,16)/255,parseInt(o+o,16)/255,parseInt(r+r,16)/255],a}if(6===o){const e=n[0]+n[1],o=n[2]+n[3],r=n[4]+n[5];return a.channels=[parseInt(e,16)/255,parseInt(o,16)/255,parseInt(r,16)/255],a}if(4===o){const e=n[0],o=n[1],r=n[2],t=n[3];return a.channels=[parseInt(e+e,16)/255,parseInt(o+o,16)/255,parseInt(r+r,16)/255],a.alpha=parseInt(t+t,16)/255,a.syntaxFlags.add(De.HasAlpha),a}if(8===o){const e=n[0]+n[1],o=n[2]+n[3],r=n[4]+n[5],t=n[6]+n[7];return a.channels=[parseInt(e,16)/255,parseInt(o,16)/255,parseInt(r,16)/255],a.alpha=parseInt(t,16)/255,a.syntaxFlags.add(De.HasAlpha),a}return!1}function normalizeHue$1(a){if(r(a))return Number.isNaN(a[4].value)||Number.isFinite(a[4].value)||(a[4].value=0),a[4].value=a[4].value%360,a[4].value<0&&(a[4].value+=360),a[1]=a[4].value.toString(),a;if(c(a)){let o=a[4].value;switch(toLowerCaseAZ(a[4].unit)){case"deg":break;case"rad":o=180*a[4].value/Math.PI;break;case"grad":o=.9*a[4].value;break;case"turn":o=360*a[4].value;break;default:return!1}return Number.isNaN(a[4].value)||Number.isFinite(a[4].value)||(a[4].value=0),o%=360,o<0&&(o+=360),[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}return!1}function normalize_legacy_HSL_ChannelValues(a,t,l){if(0===t){const e=normalizeHue$1(a);return!1!==e&&(c(a)&&l.syntaxFlags.add(De.HasDimensionValues),e)}if(o(a)){let o;return 3===t?l.syntaxFlags.add(De.HasPercentageAlpha):l.syntaxFlags.add(De.HasPercentageValues),o=3===t?normalize(a[4].value,100,0,1):normalize(a[4].value,1,0,100),[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}if(r(a)){if(3!==t)return!1;let o;return o=normalize(a[4].value,1,0,3===t?1:100),[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}return!1}function normalize_modern_HSL_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(0===l){const e=normalizeHue$1(t);return!1!==e&&(c(t)&&s.syntaxFlags.add(De.HasDimensionValues),e)}if(o(t)){let a;return 3===l?s.syntaxFlags.add(De.HasPercentageAlpha):s.syntaxFlags.add(De.HasPercentageValues),a=3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,1,1===l?0:Pe,Ze),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=3===l?normalize(t[4].value,1,0,1):normalize(t[4].value,1,1===l?0:Pe,Ze),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function threeChannelLegacySyntax(e,n,a,o){const t=[],c=[],i=[],u=[],h={colorNotation:a,channels:[0,0,0],alpha:1,syntaxFlags:new Set(o)};let N=t;for(let n=0;nve(e)&&s(e.value))){const n=hslCommaSeparated(e);if(!1!==n)return n}{const a=hslSpaceSeparated(e,n);if(!1!==a)return a}return!1}function hslCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_HSL_ChannelValues,xe.HSL,[De.LegacyHSL])}function hslSpaceSeparated(e,n){return threeChannelSpaceSeparated(e,normalize_modern_HSL_ChannelValues,xe.HSL,[],n)}function normalize_HWB_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(0===l){const e=normalizeHue$1(t);return!1!==e&&(c(t)&&s.syntaxFlags.add(De.HasDimensionValues),e)}if(o(t)){let a;return 3===l?s.syntaxFlags.add(De.HasPercentageAlpha):s.syntaxFlags.add(De.HasPercentageValues),a=3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,1,Pe,Ze),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=3===l?normalize(t[4].value,1,0,1):normalize(t[4].value,1,Pe,Ze),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function normalize_Lab_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=1===l||2===l?normalize(t[4].value,.8,Pe,Ze):3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,1,0,100),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=1===l||2===l?normalize(t[4].value,1,Pe,Ze):normalize(t[4].value,1,0,3===l?1:100),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function lab(e,n){return threeChannelSpaceSeparated(e,normalize_Lab_ChannelValues,xe.Lab,[],n)}function normalize_LCH_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(2===l){const e=normalizeHue$1(t);return!1!==e&&(c(t)&&s.syntaxFlags.add(De.HasDimensionValues),e)}if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=1===l?normalize(t[4].value,100/150,0,Ze):3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,1,0,100),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=normalize(t[4].value,1,0,1===l?Ze:3===l?1:100),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function lch(e,n){return threeChannelSpaceSeparated(e,normalize_LCH_ChannelValues,xe.LCH,[],n)}const ze=new Map;for(const[e,n]of Object.entries(Q))ze.set(e,n);function namedColor(e){const n=ze.get(toLowerCaseAZ(e));return!!n&&{colorNotation:xe.RGB,channels:[n[0]/255,n[1]/255,n[2]/255],alpha:1,syntaxFlags:new Set([De.ColorKeyword,De.NamedColor])}}function normalize_OKLab_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=1===l||2===l?normalize(t[4].value,250,Pe,Ze):normalize(t[4].value,100,0,1),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=1===l||2===l?normalize(t[4].value,1,Pe,Ze):normalize(t[4].value,1,0,1),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function oklab(e,n){return threeChannelSpaceSeparated(e,normalize_OKLab_ChannelValues,xe.OKLab,[],n)}function normalize_OKLCH_ChannelValues(t,l,s){if(a(t)&&"none"===toLowerCaseAZ(t[4].value))return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(2===l){const e=normalizeHue$1(t);return!1!==e&&(c(t)&&s.syntaxFlags.add(De.HasDimensionValues),e)}if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=1===l?normalize(t[4].value,250,0,Ze):normalize(t[4].value,100,0,1),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=normalize(t[4].value,1,0,1===l?Ze:1),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function oklch(e,n){return threeChannelSpaceSeparated(e,normalize_OKLCH_ChannelValues,xe.OKLCH,[],n)}function normalize_legacy_sRGB_ChannelValues(a,t,l){if(o(a)){3===t?l.syntaxFlags.add(De.HasPercentageAlpha):l.syntaxFlags.add(De.HasPercentageValues);const o=normalize(a[4].value,100,0,1);return[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}if(r(a)){let o;return 3!==t&&l.syntaxFlags.add(De.HasNumberValues),o=normalize(a[4].value,3===t?1:255,0,1),[e.Number,o.toString(),a[2],a[3],{value:o,type:n.Number}]}return!1}function normalize_modern_sRGB_ChannelValues(t,l,s){if(a(t)&&"none"===t[4].value.toLowerCase())return s.syntaxFlags.add(De.HasNoneKeywords),[e.Number,"none",t[2],t[3],{value:Number.NaN,type:n.Number}];if(o(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasPercentageValues),a=3===l?normalize(t[4].value,100,0,1):normalize(t[4].value,100,Pe,Ze),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}if(r(t)){let a;return 3!==l&&s.syntaxFlags.add(De.HasNumberValues),a=3===l?normalize(t[4].value,1,0,1):normalize(t[4].value,255,Pe,Ze),[e.Number,a.toString(),t[2],t[3],{value:a,type:n.Number}]}return!1}function rgb(e,n){if(e.value.some(e=>ve(e)&&s(e.value))){const n=rgbCommaSeparated(e);if(!1!==n)return(!n.syntaxFlags.has(De.HasNumberValues)||!n.syntaxFlags.has(De.HasPercentageValues))&&n}else{const a=rgbSpaceSeparated(e,n);if(!1!==a)return a}return!1}function rgbCommaSeparated(e){return threeChannelLegacySyntax(e,normalize_legacy_sRGB_ChannelValues,xe.RGB,[De.LegacyRGB])}function rgbSpaceSeparated(e,n){return threeChannelSpaceSeparated(e,normalize_modern_sRGB_ChannelValues,xe.RGB,[],n)}function XYZ_D65_to_sRGB_Gamut(e){const n=B(e);if(ee(n))return ne(n);let a=e;return a=L(a),a[0]<1e-6&&(a=[0,0,0]),a[0]>.999999&&(a=[1,0,0]),ae(oe(a,oklch_to_lin_srgb,lin_srgb_to_oklch))}function oklch_to_lin_srgb(e){return e=re(e),e=te(e),le(e)}function lin_srgb_to_oklch(e){return e=se(e),e=ce(e),ie(e)}function contrastColor(e,n){let a=!1;for(let o=0;ot?[1,1,1]:[0,0,0],o}function alpha(e,n){let o,s,c=!1,i=!1,u=!1;const h={colorNotation:xe.sRGB,channels:[0,0,0],alpha:1,syntaxFlags:new Set([])};for(let N=0;N{if(ve(e)&&a(e.value)&&"alpha"===toLowerCaseAZ(e.value[4].value)&&o&&o.has("alpha"))return new ge(o.get("alpha"))});h.alpha=e[0][0],i=!0;continue}return!1}if(u)return!1;for(;pe(e.value[N+1])||be(e.value[N+1]);)N++;if(N++,m=e.value[N],u=n(m),!1===u)return!1;o=normalizeRelativeColorDataChannels(u),s=noneToZeroInRelativeColorDataChannels(o),h.syntaxFlags=new Set(u.syntaxFlags),h.syntaxFlags.add(De.RelativeAlphaSyntax),h.channels=[...u.channels],h.colorNotation=u.colorNotation,h.alpha=u.alpha}}return!!o&&(!!i&&h)}function XYZ_D65_to_P3_Gamut(e){const n=R(e);if(ee(n))return ne(n);let a=e;return a=L(a),a[0]<1e-6&&(a=[0,0,0]),a[0]>.999999&&(a=[1,0,0]),he(oe(a,oklch_to_lin_p3,lin_p3_to_oklch))}function oklch_to_lin_p3(e){return e=re(e),e=te(e),Ne(e)}function lin_p3_to_oklch(e){return e=me(e),e=ce(e),ie(e)}function toPrecision(e,n=7){e=+e,n=+n;const a=(Math.floor(Math.abs(e))+"").length;if(n>a)return+e.toFixed(n-a);{const o=10**(a-n);return Math.round(e/o)*o}}function serializeWithAlpha(a,o,r,t){const l=[e.CloseParen,")",-1,-1,void 0];if("number"==typeof a.alpha){const s=Math.min(1,Math.max(0,toPrecision(Number.isNaN(a.alpha)?0:a.alpha)));return 1===toPrecision(s,4)?new _e(o,l,t):new _e(o,l,[...t,new Ce([r]),new ge([e.Delim,"/",-1,-1,{value:"/"}]),new Ce([r]),new ge([e.Number,toPrecision(s,4).toString(),-1,-1,{value:a.alpha,type:n.Integer}])])}return new _e(o,l,[...t,new Ce([r]),new ge([e.Delim,"/",-1,-1,{value:"/"}]),new Ce([r]),a.alpha])}function serializeP3(a,o=!0){a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation);let r=a.channels.map(e=>Number.isNaN(e)?0:e);o?r=XYZ_D65_to_P3_Gamut(colorData_to_XYZ_D65(a).channels):a.colorNotation!==xe.Display_P3&&(r=R(colorData_to_XYZ_D65(a).channels));const t=o?Math.min(1,Math.max(0,toPrecision(r[0],6))):toPrecision(r[0],6),l=o?Math.min(1,Math.max(0,toPrecision(r[1],6))):toPrecision(r[1],6),s=o?Math.min(1,Math.max(0,toPrecision(r[2],6))):toPrecision(r[2],6),c=[e.Function,"color(",-1,-1,{value:"color"}],i=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(a,c,i,[new ge([e.Ident,"display-p3",-1,-1,{value:"display-p3"}]),new Ce([i]),new ge([e.Number,t.toString(),-1,-1,{value:r[0],type:n.Number}]),new Ce([i]),new ge([e.Number,l.toString(),-1,-1,{value:r[1],type:n.Number}]),new Ce([i]),new ge([e.Number,s.toString(),-1,-1,{value:r[2],type:n.Number}])])}function serializeRGB(a,o=!0){let r;a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation),r=o?XYZ_D65_to_sRGB_Gamut(colorData_to_XYZ_D65(a).channels):B(colorData_to_XYZ_D65(a).channels);const t=Math.min(255,Math.max(0,Math.round(255*toPrecision(r[0])))),l=Math.min(255,Math.max(0,Math.round(255*toPrecision(r[1])))),s=Math.min(255,Math.max(0,Math.round(255*toPrecision(r[2])))),c=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],u=[e.Comma,",",-1,-1,void 0],h=[new ge([e.Number,t.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,r[0])),type:n.Integer}]),new ge(u),new Ce([i]),new ge([e.Number,l.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,r[1])),type:n.Integer}]),new ge(u),new Ce([i]),new ge([e.Number,s.toString(),-1,-1,{value:Math.min(255,255*Math.max(0,r[2])),type:n.Integer}])];if("number"==typeof a.alpha){const o=Math.min(1,Math.max(0,toPrecision(Number.isNaN(a.alpha)?0:a.alpha)));return 1===toPrecision(o,4)?new _e([e.Function,"rgb(",-1,-1,{value:"rgb"}],c,h):new _e([e.Function,"rgba(",-1,-1,{value:"rgba"}],c,[...h,new ge(u),new Ce([i]),new ge([e.Number,toPrecision(o,4).toString(),-1,-1,{value:a.alpha,type:n.Number}])])}return new _e([e.Function,"rgba(",-1,-1,{value:"rgba"}],c,[...h,new ge(u),new Ce([i]),a.alpha])}function serializeHSL(a,o=!0){let r;a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation),r=$(o?w(XYZ_D65_to_sRGB_Gamut(colorData_to_XYZ_D65(a).channels)):colorData_to_XYZ_D65(a).channels),r=r.map(e=>Number.isNaN(e)?0:e);const t=Math.min(360,Math.max(0,Math.round(toPrecision(r[0]))))%360,l=Math.min(100,Math.max(0,Math.round(toPrecision(r[1])))),s=Math.min(100,Math.max(0,Math.round(toPrecision(r[2])))),c=[e.CloseParen,")",-1,-1,void 0],i=[e.Whitespace," ",-1,-1,void 0],u=[e.Comma,",",-1,-1,void 0],h=[new ge([e.Number,t.toString(),-1,-1,{value:r[0],type:n.Integer}]),new ge(u),new Ce([i]),new ge([e.Percentage,l.toString()+"%",-1,-1,{value:r[1]}]),new ge(u),new Ce([i]),new ge([e.Percentage,s.toString()+"%",-1,-1,{value:r[2]}])];if("number"==typeof a.alpha){const o=Math.min(1,Math.max(0,toPrecision(Number.isNaN(a.alpha)?0:a.alpha)));return 1===toPrecision(o,4)?new _e([e.Function,"hsl(",-1,-1,{value:"hsl"}],c,h):new _e([e.Function,"hsla(",-1,-1,{value:"hsla"}],c,[...h,new ge(u),new Ce([i]),new ge([e.Number,toPrecision(o,4).toString(),-1,-1,{value:a.alpha,type:n.Number}])])}return new _e([e.Function,"hsla(",-1,-1,{value:"hsla"}],c,[...h,new ge(u),new Ce([i]),a.alpha])}function serializeOKLCH(a){a.channels=convertPowerlessComponentsToZeroValuesForDisplay(a.channels,a.colorNotation);let o=a.channels.map(e=>Number.isNaN(e)?0:e);a.colorNotation!==xe.OKLCH&&(o=L(colorData_to_XYZ_D65(a).channels));const r=toPrecision(o[0],6),t=toPrecision(o[1],6),l=toPrecision(o[2],6),s=[e.Function,"oklch(",-1,-1,{value:"oklch"}],c=[e.Whitespace," ",-1,-1,void 0];return serializeWithAlpha(a,s,c,[new ge([e.Number,r.toString(),-1,-1,{value:o[0],type:n.Number}]),new Ce([c]),new ge([e.Number,t.toString(),-1,-1,{value:o[1],type:n.Number}]),new Ce([c]),new ge([e.Number,l.toString(),-1,-1,{value:o[2],type:n.Number}])])}function computedValue(e,n=!0){const a=e.channels;switch(e.colorNotation){case xe.Lab:return a[0]=nanToNone(a[0]),a[1]=nanToNone(a[1]),a[2]=nanToNone(a[2]),1!==e.alpha?`lab(${a[0]} ${a[1]} ${a[2]} / ${nanToNone(e.alpha)})`:`lab(${a[0]} ${a[1]} ${a[2]})`;case xe.LCH:return a[0]=nanToNone(a[0]),a[1]=nanToNone(a[1]),a[2]=nanToNone(normalizeHue(a[2])),1!==e.alpha?`lch(${a[0]} ${a[1]} ${a[2]} / ${nanToNone(e.alpha)})`:`lch(${a[0]} ${a[1]} ${a[2]})`;case xe.OKLab:return a[0]=nanToNone(a[0]),a[1]=nanToNone(a[1]),a[2]=nanToNone(a[2]),1!==e.alpha?`oklab(${a[0]} ${a[1]} ${a[2]} / ${nanToNone(e.alpha)})`:`oklab(${a[0]} ${a[1]} ${a[2]})`;case xe.OKLCH:return a[0]=nanToNone(a[0]),a[1]=nanToNone(a[1]),a[2]=nanToNone(normalizeHue(a[2])),1!==e.alpha?`oklch(${a[0]} ${a[1]} ${a[2]} / ${nanToNone(e.alpha)})`:`oklch(${a[0]} ${a[1]} ${a[2]})`;case xe.RGB:case xe.HEX:return a.some(Number.isNaN)||Number.isNaN(e.alpha)?1!==e.alpha?`color(srgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(srgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`:e.syntaxFlags.has(De.RelativeColorSyntax)||e.syntaxFlags.has(De.ColorMix)||e.syntaxFlags.has(De.RelativeAlphaSyntax)?computedValue(colorDataToForRelativeColorSyntax(e,xe.sRGB)):1!==e.alpha?`rgba(${nanToNone(Math.round(255*reducePrecision(e.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(e.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(e.channels[2],5)))}, ${nanToNone(e.alpha)})`:`rgb(${nanToNone(Math.round(255*reducePrecision(e.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(e.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(e.channels[2],5)))})`;case xe.HSL:{if(a.some(Number.isNaN)||Number.isNaN(e.alpha)||!1===n)return 1!==e.alpha?`hsl(${nanToNone(normalizeHue(a[0]))} ${nanToNone(a[1],"%")} ${nanToNone(a[2],"%")} / ${nanToNone(e.alpha)})`:`hsl(${nanToNone(normalizeHue(a[0]))} ${nanToNone(a[1],"%")} ${nanToNone(a[2],"%")})`;if(e.syntaxFlags.has(De.RelativeColorSyntax)||e.syntaxFlags.has(De.ColorMix)||e.syntaxFlags.has(De.RelativeAlphaSyntax))return computedValue(colorDataToForRelativeColorSyntax(e,xe.sRGB));const o=colorDataToForRelativeColorSyntax(e,xe.RGB);return 1!==o.alpha?`rgba(${nanToNone(Math.round(255*reducePrecision(o.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[2],5)))}, ${nanToNone(o.alpha)})`:`rgb(${nanToNone(Math.round(255*reducePrecision(o.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[2],5)))})`}case xe.HWB:{if(a.some(Number.isNaN)||Number.isNaN(e.alpha)||!1===n)return 1!==e.alpha?`hwb(${nanToNone(normalizeHue(a[0]))} ${nanToNone(a[1],"%")} ${nanToNone(a[2],"%")} / ${nanToNone(e.alpha)})`:`hwb(${nanToNone(normalizeHue(a[0]))} ${nanToNone(a[1],"%")} ${nanToNone(a[2],"%")})`;if(e.syntaxFlags.has(De.RelativeColorSyntax)||e.syntaxFlags.has(De.ColorMix)||e.syntaxFlags.has(De.RelativeAlphaSyntax))return computedValue(colorDataToForRelativeColorSyntax(e,xe.sRGB));const o=colorDataToForRelativeColorSyntax(e,xe.RGB);return 1!==o.alpha?`rgba(${nanToNone(Math.round(255*reducePrecision(o.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[2],5)))}, ${nanToNone(o.alpha)})`:`rgb(${nanToNone(Math.round(255*reducePrecision(o.channels[0],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[1],5)))}, ${nanToNone(Math.round(255*reducePrecision(o.channels[2],5)))})`}case xe.sRGB:return 1!==e.alpha?`color(srgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(srgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.Linear_sRGB:return 1!==e.alpha?`color(srgb-linear ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(srgb-linear ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.Display_P3:return 1!==e.alpha?`color(display-p3 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(display-p3 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.Linear_Display_P3:return 1!==e.alpha?`color(display-p3-linear ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(display-p3-linear ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.A98_RGB:return 1!==e.alpha?`color(a98-rgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(a98-rgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.ProPhoto_RGB:return 1!==e.alpha?`color(prophoto-rgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(prophoto-rgb ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.Rec2020:return 1!==e.alpha?`color(rec2020 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(rec2020 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.XYZ_D65:return 1!==e.alpha?`color(xyz-d65 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(xyz-d65 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`;case xe.XYZ_D50:return 1!==e.alpha?`color(xyz-d50 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])} / ${nanToNone(e.alpha)})`:`color(xyz-d50 ${nanToNone(a[0])} ${nanToNone(a[1])} ${nanToNone(a[2])})`}throw new Error("unsupported color")}function nanToNone(e,n=""){return"string"==typeof e?e:"number"!=typeof e?e.toString():Number.isNaN(e)?"none":n?e.toString()+n:e.toString()}function normalizeHue(e){return"number"!=typeof e||Number.isNaN(e)?e:e%360}function reducePrecision(e,n=8){return Number.isNaN(e)||!Number.isFinite(e)?e:(n=Math.pow(10,n),Math.round(e*n)/n)}function color(e){if(fe(e)){switch(toLowerCaseAZ(e.getName())){case"rgb":case"rgba":return rgb(e,color);case"hsl":case"hsla":return hsl(e,color);case"hwb":return n=color,threeChannelSpaceSeparated(e,normalize_HWB_ChannelValues,xe.HWB,[],n);case"lab":return lab(e,color);case"lch":return lch(e,color);case"oklab":return oklab(e,color);case"oklch":return oklch(e,color);case"color":return color$1(e,color);case"color-mix":return colorMix(e,color);case"contrast-color":return contrastColor(e,color);case"alpha":return alpha(e,color)}}var n;if(ve(e)){if(i(e.value))return hex(e.value);if(a(e.value)){const n=namedColor(e.value[4].value);return!1!==n?n:"transparent"===toLowerCaseAZ(e.value[4].value)&&{colorNotation:xe.RGB,channels:[0,0,0],alpha:0,syntaxFlags:new Set([De.ColorKeyword])}}}return!1}export{xe as ColorNotation,De as SyntaxFlag,color,colorDataFitsDisplayP3_Gamut,colorDataFitsRGB_Gamut,computedValue,serializeHSL,serializeOKLCH,serializeP3,serializeRGB}; diff --git a/packages/css-color-parser/src/color-data.ts b/packages/css-color-parser/src/color-data.ts index a040b9c974..7f92c77b85 100644 --- a/packages/css-color-parser/src/color-data.ts +++ b/packages/css-color-parser/src/color-data.ts @@ -4,7 +4,6 @@ import { ColorNotation } from './color-notation'; import type { TokenNumber} from '@csstools/css-tokenizer'; import { NumberType, TokenType } from '@csstools/css-tokenizer'; import { HSL_to_XYZ_D50, HSL_to_XYZ_D65, HWB_to_XYZ_D50, HWB_to_XYZ_D65, LCH_to_XYZ_D50, LCH_to_XYZ_D65, Lab_to_XYZ_D50, Lab_to_XYZ_D65, OKLCH_to_XYZ_D50, OKLCH_to_XYZ_D65, OKLab_to_XYZ_D50, OKLab_to_XYZ_D65, P3_to_XYZ_D50, P3_to_XYZ_D65, ProPhoto_RGB_to_XYZ_D50, ProPhoto_RGB_to_XYZ_D65, XYZ_D50_to_LCH, XYZ_D50_to_Lab, XYZ_D50_to_ProPhoto, XYZ_D50_to_XYZ_D50, XYZ_D50_to_XYZ_D65, XYZ_D65_to_HSL, XYZ_D65_to_HWB, XYZ_D65_to_OKLCH, XYZ_D65_to_OKLab, XYZ_D65_to_P3, XYZ_D65_to_XYZ_D50, XYZ_D65_to_XYZ_D65, XYZ_D65_to_a98_RGB, XYZ_D65_to_lin_P3, XYZ_D65_to_lin_sRGB, XYZ_D65_to_rec_2020, XYZ_D65_to_sRGB, a98_RGB_to_XYZ_D50, a98_RGB_to_XYZ_D65, lin_P3_to_XYZ_D50, lin_P3_to_XYZ_D65, lin_sRGB_to_XYZ_D50, lin_sRGB_to_XYZ_D65, rec_2020_to_XYZ_D50, rec_2020_to_XYZ_D65, sRGB_to_XYZ_D50, sRGB_to_XYZ_D65 } from '@csstools/color-helpers'; -import { normalize } from './functions/normalize'; /** * A color data object. @@ -717,11 +716,14 @@ function convertPowerlessComponentsToMissingComponents(a: Color, colorNotation: } break; - case ColorNotation.HWB: - if ((Math.max(0, (Number.isNaN(out[1]) ? 0 : out[1])) + Math.max(0, (Number.isNaN(out[2]) ? 0 : out[2]))) >= 99.999) { + case ColorNotation.HWB: { + const white = Number.isNaN(out[1]) ? 0 : out[1]; + const black = Number.isNaN(out[2]) ? 0 : out[2]; + + if ((white + black) >= 99.999) { out[0] = Number.NaN; - if ((Math.max(0, (Number.isNaN(out[1]) ? 0 : out[1])) + Math.max(0, (Number.isNaN(out[2]) ? 0 : out[2]))) < 100) { + if ((white + black) < 100) { if (Number.isNaN(out[1])) { out[2] = 100; } else if (Number.isNaN(out[2])) { @@ -733,6 +735,7 @@ function convertPowerlessComponentsToMissingComponents(a: Color, colorNotation: } break; + } case ColorNotation.LCH: if ((Number.isNaN(out[1]) ? 0 : out[1]) <= 0.0015) { out[2] = Number.NaN; @@ -773,11 +776,16 @@ export function convertPowerlessComponentsToZeroValuesForDisplay(a: Color, color } break; - case ColorNotation.HWB: - if ((Math.max(0, (Number.isNaN(out[1]) ? 0 : out[1])) + Math.max(0, (Number.isNaN(out[2]) ? 0 : out[2]))) >= 99.999) { + case ColorNotation.HWB: { + const white = Number.isNaN(out[1]) ? 0 : out[1]; + const black = Number.isNaN(out[2]) ? 0 : out[2]; + + if ((white + black) >= 99.999) { out[0] = Number.NaN; } + break; + } case ColorNotation.Lab: if (reducePrecision(out[0]) <= 0 || reducePrecision(out[0]) >= 100) { out[1] = Number.NaN; @@ -942,11 +950,6 @@ export function noneToZeroInRelativeColorDataChannels(x: Map, colorParser: } } - if ( - !percentage - ) { + if (percentage === false) { + let fromMathFunction = false; + if ( isFunctionNode(node) && mathFunctionNames.has(toLowerCaseAZ(node.getName())) ) { + fromMathFunction = true; + [[node]] = calcFromComponentValues([[node]], { censorIntoStandardRepresentableValues: true, precision: -1, @@ -192,11 +194,22 @@ function colorMixComponents(componentValues: Array, colorParser: if ( isTokenNode(node) && - isTokenPercentage(node.value) && - node.value[4].value >= 0 + isTokenPercentage(node.value) ) { - percentage = node.value[4].value; - continue; + if (fromMathFunction) { + // Math functions with an out of range result do not invalidate the declaration. + // The result is clamped to the allowed range instead. + // https://drafts.csswg.org/css-values-4/#calc-range + percentage = Math.min(100, Math.max(0, node.value[4].value)); + continue; + } + + // A literal percentage outside of the [0,100] range is invalid. + // https://drafts.csswg.org/css-color-5/#color-mix-percent-norm + if (node.value[4].value >= 0 && node.value[4].value <= 100) { + percentage = node.value[4].value; + continue; + } } } diff --git a/packages/css-color-parser/src/functions/color-normalize-channel-values.ts b/packages/css-color-parser/src/functions/color-normalize-channel-values.ts index 97b5bcc3d9..aba324e12e 100644 --- a/packages/css-color-parser/src/functions/color-normalize-channel-values.ts +++ b/packages/css-color-parser/src/functions/color-normalize-channel-values.ts @@ -4,6 +4,7 @@ import { NumberType, TokenType, isTokenIdent, isTokenNumber, isTokenPercentage } import { SyntaxFlag } from '../color-data'; import { normalize } from './normalize'; import { toLowerCaseAZ } from '../util/to-lower-case-a-z'; +import { VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY } from '../util/infinity-constants'; export function normalize_Color_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false { if (isTokenIdent(token) && toLowerCaseAZ(token[4].value) === 'none') { @@ -30,7 +31,7 @@ export function normalize_Color_ChannelValues(token: CSSToken, index: number, co if (index === 3) { value = normalize(token[4].value, 100, 0, 1); } else { - value = normalize(token[4].value, 100, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 100, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } return [ @@ -54,7 +55,7 @@ export function normalize_Color_ChannelValues(token: CSSToken, index: number, co if (index === 3) { value = normalize(token[4].value, 1, 0, 1); } else { - value = normalize(token[4].value, 1, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 1, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } return [ diff --git a/packages/css-color-parser/src/functions/hsl-normalize-channel-values.ts b/packages/css-color-parser/src/functions/hsl-normalize-channel-values.ts index e64fdc5b1a..0f8e527041 100644 --- a/packages/css-color-parser/src/functions/hsl-normalize-channel-values.ts +++ b/packages/css-color-parser/src/functions/hsl-normalize-channel-values.ts @@ -5,6 +5,7 @@ import { SyntaxFlag } from '../color-data'; import { normalize } from './normalize'; import { normalizeHue } from './hue-normalize-channel-value'; import { toLowerCaseAZ } from '../util/to-lower-case-a-z'; +import { VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY } from '../util/infinity-constants'; export function normalize_legacy_HSL_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false { if (index === 0) { @@ -113,9 +114,9 @@ export function normalize_modern_HSL_ChannelValues(token: CSSToken, index: numbe if (index === 3) { value = normalize(token[4].value, 100, 0, 1); } else if (index === 1) { - value = normalize(token[4].value, 1, 0, 2_147_483_647); + value = normalize(token[4].value, 1, 0, VALUE_FOR_POSITIVE_INFINITY); } else { - value = normalize(token[4].value, 1, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 1, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } return [ @@ -139,9 +140,9 @@ export function normalize_modern_HSL_ChannelValues(token: CSSToken, index: numbe if (index === 3) { value = normalize(token[4].value, 1, 0, 1); } else if (index === 1) { - value = normalize(token[4].value, 1, 0, 2_147_483_647); + value = normalize(token[4].value, 1, 0, VALUE_FOR_POSITIVE_INFINITY); } else { - value = normalize(token[4].value, 1, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 1, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } return [ diff --git a/packages/css-color-parser/src/functions/hwb-normalize-channel-values.ts b/packages/css-color-parser/src/functions/hwb-normalize-channel-values.ts index f262356be1..6e83e2ee3d 100644 --- a/packages/css-color-parser/src/functions/hwb-normalize-channel-values.ts +++ b/packages/css-color-parser/src/functions/hwb-normalize-channel-values.ts @@ -5,6 +5,7 @@ import { SyntaxFlag } from '../color-data'; import { normalize } from './normalize'; import { normalizeHue } from './hue-normalize-channel-value'; import { toLowerCaseAZ } from '../util/to-lower-case-a-z'; +import { VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY } from '../util/infinity-constants'; export function normalize_HWB_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false { if (isTokenIdent(token) && toLowerCaseAZ(token[4].value) === 'none') { @@ -46,7 +47,7 @@ export function normalize_HWB_ChannelValues(token: CSSToken, index: number, colo if (index === 3) { value = normalize(token[4].value, 100, 0, 1); } else { - value = normalize(token[4].value, 1, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 1, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } return [ @@ -70,7 +71,7 @@ export function normalize_HWB_ChannelValues(token: CSSToken, index: number, colo if (index === 3) { value = normalize(token[4].value, 1, 0, 1); } else { - value = normalize(token[4].value, 1, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 1, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } return [ diff --git a/packages/css-color-parser/src/functions/lab-normalize-channel-values.ts b/packages/css-color-parser/src/functions/lab-normalize-channel-values.ts index 0fb5577e78..15c27970d4 100644 --- a/packages/css-color-parser/src/functions/lab-normalize-channel-values.ts +++ b/packages/css-color-parser/src/functions/lab-normalize-channel-values.ts @@ -4,6 +4,7 @@ import { NumberType, TokenType, isTokenIdent, isTokenNumber, isTokenPercentage } import { SyntaxFlag } from '../color-data'; import { normalize } from './normalize'; import { toLowerCaseAZ } from '../util/to-lower-case-a-z'; +import { VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY } from '../util/infinity-constants'; export function normalize_Lab_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false { if (isTokenIdent(token) && toLowerCaseAZ(token[4].value) === 'none') { @@ -28,7 +29,7 @@ export function normalize_Lab_ChannelValues(token: CSSToken, index: number, colo let value; if (index === 1 || index === 2) { - value = normalize(token[4].value, 0.8, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 0.8, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } else if (index === 3) { value = normalize(token[4].value, 100, 0, 1); } else { @@ -54,7 +55,7 @@ export function normalize_Lab_ChannelValues(token: CSSToken, index: number, colo let value; if (index === 1 || index === 2) { - value = normalize(token[4].value, 1, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 1, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } else if (index === 3) { value = normalize(token[4].value, 1, 0, 1); } else { diff --git a/packages/css-color-parser/src/functions/lch-normalize-channel-values.ts b/packages/css-color-parser/src/functions/lch-normalize-channel-values.ts index 65567d4df9..1bafbe7479 100644 --- a/packages/css-color-parser/src/functions/lch-normalize-channel-values.ts +++ b/packages/css-color-parser/src/functions/lch-normalize-channel-values.ts @@ -5,6 +5,7 @@ import { SyntaxFlag } from '../color-data'; import { normalize } from './normalize'; import { normalizeHue } from './hue-normalize-channel-value'; import { toLowerCaseAZ } from '../util/to-lower-case-a-z'; +import { VALUE_FOR_POSITIVE_INFINITY } from '../util/infinity-constants'; export function normalize_LCH_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false { if (isTokenIdent(token) && toLowerCaseAZ(token[4].value) === 'none') { @@ -42,7 +43,7 @@ export function normalize_LCH_ChannelValues(token: CSSToken, index: number, colo let value; if (index === 1) { - value = normalize(token[4].value, (100 / 150), 0, 2_147_483_647); + value = normalize(token[4].value, (100 / 150), 0, VALUE_FOR_POSITIVE_INFINITY); } else if (index === 3) { value = normalize(token[4].value, 100, 0, 1); } else { @@ -68,7 +69,7 @@ export function normalize_LCH_ChannelValues(token: CSSToken, index: number, colo let value; if (index === 1) { - value = normalize(token[4].value, 1, 0, 2_147_483_647); + value = normalize(token[4].value, 1, 0, VALUE_FOR_POSITIVE_INFINITY); } else if (index === 3) { value = normalize(token[4].value, 1, 0, 1); } else { diff --git a/packages/css-color-parser/src/functions/oklab-normalize-channel-values.ts b/packages/css-color-parser/src/functions/oklab-normalize-channel-values.ts index 98a9a7445b..05d907e865 100644 --- a/packages/css-color-parser/src/functions/oklab-normalize-channel-values.ts +++ b/packages/css-color-parser/src/functions/oklab-normalize-channel-values.ts @@ -4,6 +4,7 @@ import { NumberType, TokenType, isTokenIdent, isTokenNumber, isTokenPercentage } import { SyntaxFlag } from '../color-data'; import { normalize } from './normalize'; import { toLowerCaseAZ } from '../util/to-lower-case-a-z'; +import { VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY } from '../util/infinity-constants'; export function normalize_OKLab_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false { if (isTokenIdent(token) && toLowerCaseAZ(token[4].value) === 'none') { @@ -28,7 +29,7 @@ export function normalize_OKLab_ChannelValues(token: CSSToken, index: number, co let value; if (index === 1 || index === 2) { - value = normalize(token[4].value, 250, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 250, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } else if (index === 3) { value = normalize(token[4].value, 100, 0, 1); } else { @@ -54,7 +55,7 @@ export function normalize_OKLab_ChannelValues(token: CSSToken, index: number, co let value; if (index === 1 || index === 2) { - value = normalize(token[4].value, 1, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 1, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } else if (index === 3) { value = normalize(token[4].value, 1, 0, 1); } else { diff --git a/packages/css-color-parser/src/functions/oklch-normalize-channel-values.ts b/packages/css-color-parser/src/functions/oklch-normalize-channel-values.ts index 00101149d9..010e411c03 100644 --- a/packages/css-color-parser/src/functions/oklch-normalize-channel-values.ts +++ b/packages/css-color-parser/src/functions/oklch-normalize-channel-values.ts @@ -5,6 +5,7 @@ import { SyntaxFlag } from '../color-data'; import { normalize } from './normalize'; import { normalizeHue } from './hue-normalize-channel-value'; import { toLowerCaseAZ } from '../util/to-lower-case-a-z'; +import { VALUE_FOR_POSITIVE_INFINITY } from '../util/infinity-constants'; export function normalize_OKLCH_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false { if (isTokenIdent(token) && toLowerCaseAZ(token[4].value) === 'none') { @@ -42,7 +43,7 @@ export function normalize_OKLCH_ChannelValues(token: CSSToken, index: number, co let value; if (index === 1) { - value = normalize(token[4].value, 250, 0, 2_147_483_647); + value = normalize(token[4].value, 250, 0, VALUE_FOR_POSITIVE_INFINITY); } else if (index === 3) { value = normalize(token[4].value, 100, 0, 1); } else { @@ -68,7 +69,7 @@ export function normalize_OKLCH_ChannelValues(token: CSSToken, index: number, co let value; if (index === 1) { - value = normalize(token[4].value, 1, 0, 2_147_483_647); + value = normalize(token[4].value, 1, 0, VALUE_FOR_POSITIVE_INFINITY); } else if (index === 3) { value = normalize(token[4].value, 1, 0, 1); } else { diff --git a/packages/css-color-parser/src/functions/rgb-normalize-channel-values.ts b/packages/css-color-parser/src/functions/rgb-normalize-channel-values.ts index c21c54c6f7..3a8d0378b8 100644 --- a/packages/css-color-parser/src/functions/rgb-normalize-channel-values.ts +++ b/packages/css-color-parser/src/functions/rgb-normalize-channel-values.ts @@ -3,6 +3,7 @@ import type { CSSToken} from '@csstools/css-tokenizer'; import { NumberType, TokenType, isTokenIdent, isTokenNumber, isTokenPercentage } from '@csstools/css-tokenizer'; import { SyntaxFlag } from '../color-data'; import { normalize } from './normalize'; +import { VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY } from '../util/infinity-constants'; export function normalize_legacy_sRGB_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false { if (isTokenPercentage(token)) { @@ -78,7 +79,7 @@ export function normalize_modern_sRGB_ChannelValues(token: CSSToken, index: numb if (index === 3) { value = normalize(token[4].value, 100, 0, 1); } else { - value = normalize(token[4].value, 100, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 100, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } return [ @@ -102,7 +103,7 @@ export function normalize_modern_sRGB_ChannelValues(token: CSSToken, index: numb if (index === 3) { value = normalize(token[4].value, 1, 0, 1); } else { - value = normalize(token[4].value, 255, -2_147_483_647, 2_147_483_647); + value = normalize(token[4].value, 255, VALUE_FOR_NEGATIVE_INFINITY, VALUE_FOR_POSITIVE_INFINITY); } return [ diff --git a/packages/css-color-parser/src/serialize/hsl.ts b/packages/css-color-parser/src/serialize/hsl.ts index ccd246c0b7..eab53c30f0 100644 --- a/packages/css-color-parser/src/serialize/hsl.ts +++ b/packages/css-color-parser/src/serialize/hsl.ts @@ -19,7 +19,6 @@ export function serializeHSL(color: ColorData, gamutMapping = true): FunctionNod hsl = XYZ_D65_to_HSL(colorData_to_XYZ_D65(color).channels); } - // Needs to be done twice because `xyz.XYZ_D65_to_HSL` can return `NaN` values. hsl = hsl.map((x) => Number.isNaN(x) ? 0 : x); const h = Math.min(360, Math.max(0, Math.round(toPrecision(hsl[0])))) % 360; diff --git a/packages/css-color-parser/src/util/infinity-constants.ts b/packages/css-color-parser/src/util/infinity-constants.ts new file mode 100644 index 0000000000..f272bf4c3e --- /dev/null +++ b/packages/css-color-parser/src/util/infinity-constants.ts @@ -0,0 +1,2 @@ +export const VALUE_FOR_NEGATIVE_INFINITY = -2_147_483_647; +export const VALUE_FOR_POSITIVE_INFINITY = 2_147_483_647; diff --git a/packages/css-color-parser/test/basic/color-mix-function.mjs b/packages/css-color-parser/test/basic/color-mix-function.mjs index 9f766d37c3..599405fcf6 100644 --- a/packages/css-color-parser/test/basic/color-mix-function.mjs +++ b/packages/css-color-parser/test/basic/color-mix-function.mjs @@ -117,6 +117,12 @@ const tests = [ ['color-mix(in hsl longer hue, hsl(50deg 0% 50%), hsl(50deg 0% 50%))', canonicalize('hsl(230deg 0% 50%)')], ['color-mix(in hsl, color-mix(in hsl longer hue, hsl(50deg 0% 50%), hsl(50deg 0% 50%)), hsl(180deg 100% 50%))', canonicalize('hsl(205deg 50% 50%)')], + // A powerless hue is `missing` after conversion to a different interpolation space, + // so the nested mix resolves to the same result as mixing the original color directly. + // https://github.com/w3c/csswg-drafts/issues/14046 + ['color-mix(in lch, color-mix(in lch longer hue, hsl(50deg 0% 50%), hsl(50deg 0% 50%)), lch(50% 100% 180deg))', canonicalize('lch(51.69448237055716 75 180deg)')], + ['color-mix(in lch, hsl(50deg 0% 50%), lch(50% 100% 180deg))', canonicalize('lch(51.69448237055716 75 180deg)')], + ['color-mix(in hsl, hsl(30deg 40% 80% / 25%) 0%, hsl(90deg none none / none))', canonicalize('hsl(90deg 40% 80% / 25%)')], ['color-mix(in hwb, hwb(30deg 30% 40% / 25%) 0%, hwb(90deg none none / 0.5))', canonicalize('hwb(90deg 30% 40% / 0.5)')], ['color-mix(in hsl, hsl(from hsl(none 50% 50%) h s l), hsl(from hsl(120deg 50% 50%) h s l))', canonicalize('hsl(120deg 50% 50%)')], @@ -135,6 +141,19 @@ const tests = [ // TODO : `none` containing support ['color-mix(in hsl, hsl(calc(none) 30% 40%), hsl(20deg 30% 40%))', ''], + // Percentages outside of the [0,100] range + // https://drafts.csswg.org/css-color-5/#color-mix-percent-norm + ['color-mix(in srgb, red -10%, blue)', ''], // literal percentages are invalid + ['color-mix(in srgb, red 150%, blue)', ''], // literal percentages are invalid + ['color-mix(in srgb, red 0% 20%, blue)', ''], // only one percentage per color + // Math functions with an out of range result are clamped instead of being invalid. + // https://drafts.csswg.org/css-values-4/#calc-range + ['color-mix(in srgb, red calc(-10%), blue)', canonicalize('blue')], // clamped to 0% + ['color-mix(in srgb, red calc(10% - 20%), blue)', canonicalize('blue')], // clamped to 0% + ['color-mix(in srgb, red calc(150%), blue)', canonicalize('red')], // clamped to 100% + ['color-mix(in oklch, red calc(-10%), blue)', canonicalize('blue')], // clamped to 0% + ['color-mix(in oklch, red calc(150%), blue)', canonicalize('red')], // clamped to 100% + // 0 percentage sum ['color-mix(in hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%) 0%)', canonicalize('hsl(75.48deg 20.26% 30% / 0)')], // sum of percentages is 0 ['color-mix(in hwb, hwb(40deg 30% 40%) 0%, hwb(40deg 30% 40%) 0%)', canonicalize('hwb(40.26deg 30.2% 40% / 0%)')], // sum of percentages is 0 diff --git a/packages/css-color-parser/test/basic/hwb.mjs b/packages/css-color-parser/test/basic/hwb.mjs index a44eb4d4f2..43ada86797 100644 --- a/packages/css-color-parser/test/basic/hwb.mjs +++ b/packages/css-color-parser/test/basic/hwb.mjs @@ -1,4 +1,4 @@ -import { color } from '@csstools/css-color-parser'; +import { color, computedValue } from '@csstools/css-color-parser'; import assert from 'node:assert'; import { parse } from '../util/parse.mjs'; import { serialize_P3_data, serialize_sRGB_data } from '../util/serialize.mjs'; @@ -22,3 +22,46 @@ assert.deepStrictEqual( serialize_P3_data(color(parse('hwb(from lab(100 104.3 -50.9) h w b)')), false), 'color(display-p3 1.47874 0.65856 1.37055)', ); + +// `W` and `B` are not clamped, values outside the `[0, 100]` range are not invalid. +assert.deepStrictEqual( + computedValue(color(parse('hwb(0 -10% 50%)')), false), + 'hwb(0 -10% 50%)', +); + +assert.deepStrictEqual( + computedValue(color(parse('hwb(0 50% -10%)')), false), + 'hwb(0 50% -10%)', +); + +// The hue is only powerless when the raw sum of `W` and `B` is `>= 99.999`. +assert.deepStrictEqual( + computedValue(color(parse('color-mix(in hwb, color(srgb -0.1 -0.1 0))')), false), + 'hwb(240 -10% 100%)', +); + +assert.deepStrictEqual( + computedValue(color(parse('color-mix(in hwb, color(srgb -0.1 -0.1 -0.1))')), false), + 'hwb(none -10% 110%)', +); + +// Both `W` and `B` can be negative after conversion from an out-of-gamut color. +assert.deepStrictEqual( + computedValue(color(parse('color-mix(in hwb, color(srgb 2 -1 0.5))')), false), + 'hwb(330 -100% -100%)', +); + +assert.deepStrictEqual( + computedValue(color(parse('color-mix(in hwb, color(display-p3 0 1 0))')), false), + 'hwb(127.88028828 -51.16049826% -1.82656579%)', +); + +assert.deepStrictEqual( + computedValue(color(parse('color(from hwb(30deg 100% -10%) srgb r g b)')), false), + 'color(srgb 1.1 1.05 0.9999999999999999)', +); + +assert.deepStrictEqual( + computedValue(color(parse('color(from hwb(30deg 110% -10%) srgb r g b)')), false), + 'color(srgb 1.1000000000000003 1.0999999999999999 1.1)', +); diff --git a/packages/css-color-parser/test/basic/relative-color.mjs b/packages/css-color-parser/test/basic/relative-color.mjs index 213911e700..97808c233b 100644 --- a/packages/css-color-parser/test/basic/relative-color.mjs +++ b/packages/css-color-parser/test/basic/relative-color.mjs @@ -275,3 +275,23 @@ assert.deepStrictEqual( `${input}: ${expected}`, ); }); + +// Trigonometric functions with component keywords. +// Keywords resolve to s (percentages to their number, angles to degrees) +// and sin() and friends interpret s as radians. +// https://github.com/w3c/csswg-drafts/issues/13938 +[ + ['hsl(from hsl(0 50 50) h s calc((sin(l) + 1) * 50))', 'rgb(141, 47, 47)'], + ['hsl(from hsl(0 50% 50%) h s calc((sin(l) + 1) * 50))', 'rgb(141, 47, 47)'], + ['hsl(from hsl(0 50 50) h s calc((sin((l * pi) / 200) * 100) / 2))', 'rgb(135, 45, 45)'], + ['hsl(from hsl(0 50 50) h s calc(sin(l * 0.005rad * pi) * 50))', 'rgb(135, 45, 45)'], + ['hsl(from hsl(50deg 50 50) h s calc((sin(h * 1deg) + 1) * 50))', 'rgb(240, 235, 210)'], + ['hsl(from hsl(120 50 50) calc(sin(h)) s l)', 'rgb(191, 65, 64)'], + ['hsl(from hsl(120 50 50) calc(sin(h * 1deg)) s l)', 'rgb(191, 66, 64)'], +].forEach(([input, expected]) => { + assert.deepStrictEqual( + serialize_sRGB_data(color(parse(input))), + expected, + `${input}: ${expected}`, + ); +}); diff --git a/packages/css-color-parser/test/fuzzer/001.mjs b/packages/css-color-parser/test/fuzzer/001.mjs index 5afd7f17c4..f72a50468c 100644 --- a/packages/css-color-parser/test/fuzzer/001.mjs +++ b/packages/css-color-parser/test/fuzzer/001.mjs @@ -34,7 +34,7 @@ const tests = [ ['lab( from color( display-p3-linear 0.498631 none 0.881965 ) calc(b - calc(pi)) min(-78.877309, alpha) none )', 'lab(0 -78.877309 none)'], ['hsl( 302.38883 calc(-infinity) 100 )', 'rgb(255, 255, 255)'], ['oklab( 0.101614 0.349302 -0.013596 )', 'oklab(0.101614 0.349302 -0.013596)'], - ['lch( from color( from color( xyz-d50 0.849686 abs(0.23606) calc(-infinity) ) xyz-d65 min(calc(pi), z) clamp(0.403757, x, 0.641031) 0 / z ) 0 h l )', 'lch(0 180.64231331 233 / 0)'], + ['lch( from color( from color( xyz-d50 0.849686 abs(0.23606) calc(-infinity) ) xyz-d65 min(calc(pi), z) clamp(0.403757, x, 0.641031) 0 / z ) 0 h l )', 'lch(0 180.64231331 68.17737579 / 0)'], ['lch( from color( xyz-d65 calc(infinity) 0.824078 none ) h calc(69.179131 - alpha) none )', 'lch(89.99929102 68.179131 none)'], ['color( xyz-d50 calc(-infinity) 0.175398 0 )', 'color(xyz-d50 -2147483647 0.175398 0)'], ['oklch( calc(calc(infinity) * calc(0.023559)) none 0 / 0.659195 )', 'oklch(1 none 0 / 0.659195)'], @@ -907,7 +907,7 @@ const tests = [ ['hsl( calc(nan) 0 clamp(8.151629, calc(pi), calc(pi)) )', 'rgb(21, 21, 21)'], ['lab( 26.673297 -75.013175 calc(calc(calc(-51.981194 * 1.989347) - 211.098857) - -55.650272) )', 'lab(26.673297 -75.013175 -258.85721734)'], ['hsl( 268.505084 41.385756 none )', 'hsl(268.505084 41.385756% none)'], - ['color-mix( in srgb , color( from color( rec2020 calc(0.648646 + exp(30.088095)) none 0.799828 ) xyz-d50 none none alpha ) , color( srgb calc(calc(-infinity)) 0 0.59714 ) )', 'color(srgb -2147483647 414.63465787 0)'], + ['color-mix( in srgb , color( from color( rec2020 calc(0.648646 + exp(30.088095)) none 0.799828 ) xyz-d50 none none alpha ) , color( srgb calc(calc(-infinity)) 0 0.59714 ) )', 'color(srgb -2147483647.0000007 506.91917288 0)'], ['lab( from color( xyz-d50 min(0.630491, calc(e)) 0.5 0.283017 / 0.764744 ) none none a / calc(alpha * 4) )', 'lab(none none 37.11959068)'], ['lch( from color( xyz-d50 0 hypot(0.333333, 0.689882) 0.651966 / 0.515995 ) 55.292901 c calc(h) )', 'lch(55.292901 388.56490088 180.2785414 / 0.515995)'], ['lch( 73.947082 143.372067 none )', 'lch(73.947082 143.372067 none)'], @@ -964,7 +964,7 @@ const tests = [ ['lch( from color( xyz 0.107004 0 0.608241 ) none none sin(abs(calc(-infinity))) )', 'lch(none none 0)'], ['lch( 0 none 300.218561 )', 'lch(0 none 300.218561)'], ['oklab( calc(0.6666666666666666 + 0.049275) -0.17368 none )', 'oklab(0.71594167 -0.17368 none)'], - ['color-mix( in xyz , color( xyz none 0.106347 exp(-1.857346) ) 67.70549%, color( a98-rgb calc(-infinity) none sin(0.1637) ) )', 'color(xyz-d65 -2147483647 0.106347 -693519321.0231007)'], + ['color-mix( in xyz , color( xyz none 0.106347 exp(-1.857346) ) 67.70549%, color( a98-rgb calc(-infinity) none sin(0.1637) ) )', 'color(xyz-d65 -192256827513344500000 0.106347 -2910393768139678000)'], ['hwb( abs(302.694028) calc(-infinity) 80.042088 )', 'rgb(-465, -5476083300, -245878647)'], ['rgb( 246.972492 143.28368 calc(91.337724 + 0) )', 'rgb(247, 143, 91)'], ['hsl( 104.415099 calc(-infinity) max(1.36727, calc(nan)) )', 'rgb(0, 0, 0)'],