1// Copyright (c) 2019, David Kitchen <david@buro9.com>
   2//
   3// All rights reserved.
   4//
   5// Redistribution and use in source and binary forms, with or without
   6// modification, are permitted provided that the following conditions are met:
   7//
   8// * Redistributions of source code must retain the above copyright notice, this
   9//   list of conditions and the following disclaimer.
  10//
  11// * Redistributions in binary form must reproduce the above copyright notice,
  12//   this list of conditions and the following disclaimer in the documentation
  13//   and/or other materials provided with the distribution.
  14//
  15// * Neither the name of the organisation (Microcosm) nor the names of its
  16//   contributors may be used to endorse or promote products derived from
  17//   this software without specific prior written permission.
  18//
  19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  23// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  25// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  26// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  27// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29
  30package css
  31
  32import (
  33	"regexp"
  34	"strings"
  35)
  36
  37var (
  38	defaultStyleHandlers = map[string]func(string) bool{
  39		"align-content":              AlignContentHandler,
  40		"align-items":                AlignItemsHandler,
  41		"align-self":                 AlignSelfHandler,
  42		"all":                        AllHandler,
  43		"animation":                  AnimationHandler,
  44		"animation-delay":            AnimationDelayHandler,
  45		"animation-direction":        AnimationDirectionHandler,
  46		"animation-duration":         AnimationDurationHandler,
  47		"animation-fill-mode":        AnimationFillModeHandler,
  48		"animation-iteration-count":  AnimationIterationCountHandler,
  49		"animation-name":             AnimationNameHandler,
  50		"animation-play-state":       AnimationPlayStateHandler,
  51		"animation-timing-function":  TimingFunctionHandler,
  52		"backface-visibility":        BackfaceVisibilityHandler,
  53		"background":                 BackgroundHandler,
  54		"background-attachment":      BackgroundAttachmentHandler,
  55		"background-blend-mode":      BackgroundBlendModeHandler,
  56		"background-clip":            BackgroundClipHandler,
  57		"background-color":           ColorHandler,
  58		"background-image":           ImageHandler,
  59		"background-origin":          BackgroundOriginHandler,
  60		"background-position":        BackgroundPositionHandler,
  61		"background-repeat":          BackgroundRepeatHandler,
  62		"background-size":            BackgroundSizeHandler,
  63		"border":                     BorderHandler,
  64		"border-bottom":              BorderSideHandler,
  65		"border-bottom-color":        ColorHandler,
  66		"border-bottom-left-radius":  BorderSideRadiusHandler,
  67		"border-bottom-right-radius": BorderSideRadiusHandler,
  68		"border-bottom-style":        BorderSideStyleHandler,
  69		"border-bottom-width":        BorderSideWidthHandler,
  70		"border-collapse":            BorderCollapseHandler,
  71		"border-color":               ColorHandler,
  72		"border-image":               BorderImageHandler,
  73		"border-image-outset":        BorderImageOutsetHandler,
  74		"border-image-repeat":        BorderImageRepeatHandler,
  75		"border-image-slice":         BorderImageSliceHandler,
  76		"border-image-source":        ImageHandler,
  77		"border-image-width":         BorderImageWidthHandler,
  78		"border-left":                BorderSideHandler,
  79		"border-left-color":          ColorHandler,
  80		"border-left-style":          BorderSideStyleHandler,
  81		"border-left-width":          BorderSideWidthHandler,
  82		"border-radius":              BorderRadiusHandler,
  83		"border-right":               BorderSideHandler,
  84		"border-right-color":         ColorHandler,
  85		"border-right-style":         BorderSideStyleHandler,
  86		"border-right-width":         BorderSideWidthHandler,
  87		"border-spacing":             BorderSpacingHandler,
  88		"border-style":               BorderStyleHandler,
  89		"border-top":                 BorderSideHandler,
  90		"border-top-color":           ColorHandler,
  91		"border-top-left-radius":     BorderSideRadiusHandler,
  92		"border-top-right-radius":    BorderSideRadiusHandler,
  93		"border-top-style":           BorderSideStyleHandler,
  94		"border-top-width":           BorderSideWidthHandler,
  95		"border-width":               BorderWidthHandler,
  96		"bottom":                     SideHandler,
  97		"box-decoration-break":       BoxDecorationBreakHandler,
  98		"box-shadow":                 BoxShadowHandler,
  99		"box-sizing":                 BoxSizingHandler,
 100		"break-after":                BreakBeforeAfterHandler,
 101		"break-before":               BreakBeforeAfterHandler,
 102		"break-inside":               BreakInsideHandler,
 103		"caption-side":               CaptionSideHandler,
 104		"caret-color":                CaretColorHandler,
 105		"clear":                      ClearHandler,
 106		"clip":                       ClipHandler,
 107		"color":                      ColorHandler,
 108		"column-count":               ColumnCountHandler,
 109		"column-fill":                ColumnFillHandler,
 110		"column-gap":                 ColumnGapHandler,
 111		"column-rule":                ColumnRuleHandler,
 112		"column-rule-color":          ColorHandler,
 113		"column-rule-style":          BorderSideStyleHandler,
 114		"column-rule-width":          ColumnRuleWidthHandler,
 115		"column-span":                ColumnSpanHandler,
 116		"column-width":               ColumnWidthHandler,
 117		"columns":                    ColumnsHandler,
 118		"cursor":                     CursorHandler,
 119		"direction":                  DirectionHandler,
 120		"display":                    DisplayHandler,
 121		"empty-cells":                EmptyCellsHandler,
 122		"filter":                     FilterHandler,
 123		"flex":                       FlexHandler,
 124		"flex-basis":                 FlexBasisHandler,
 125		"flex-direction":             FlexDirectionHandler,
 126		"flex-flow":                  FlexFlowHandler,
 127		"flex-grow":                  FlexGrowHandler,
 128		"flex-shrink":                FlexGrowHandler,
 129		"flex-wrap":                  FlexWrapHandler,
 130		"float":                      FloatHandler,
 131		"font":                       FontHandler,
 132		"font-family":                FontFamilyHandler,
 133		"font-kerning":               FontKerningHandler,
 134		"font-language-override":     FontLanguageOverrideHandler,
 135		"font-size":                  FontSizeHandler,
 136		"font-size-adjust":           FontSizeAdjustHandler,
 137		"font-stretch":               FontStretchHandler,
 138		"font-style":                 FontStyleHandler,
 139		"font-synthesis":             FontSynthesisHandler,
 140		"font-variant":               FontVariantHandler,
 141		"font-variant-caps":          FontVariantCapsHandler,
 142		"font-variant-position":      FontVariantPositionHandler,
 143		"font-weight":                FontWeightHandler,
 144		"grid":                       GridHandler,
 145		"grid-area":                  GridAreaHandler,
 146		"grid-auto-columns":          GridAutoColumnsHandler,
 147		"grid-auto-flow":             GridAutoFlowHandler,
 148		"grid-auto-rows":             GridAutoColumnsHandler,
 149		"grid-column":                GridColumnHandler,
 150		"grid-column-end":            GridAxisStartEndHandler,
 151		"grid-column-gap":            LengthHandler,
 152		"grid-column-start":          GridAxisStartEndHandler,
 153		"grid-gap":                   GridGapHandler,
 154		"grid-row":                   GridRowHandler,
 155		"grid-row-end":               GridAxisStartEndHandler,
 156		"grid-row-gap":               LengthHandler,
 157		"grid-row-start":             GridAxisStartEndHandler,
 158		"grid-template":              GridTemplateHandler,
 159		"grid-template-areas":        GridTemplateAreasHandler,
 160		"grid-template-columns":      GridTemplateColumnsHandler,
 161		"grid-template-rows":         GridTemplateRowsHandler,
 162		"hanging-punctuation":        HangingPunctuationHandler,
 163		"height":                     HeightHandler,
 164		"hyphens":                    HyphensHandler,
 165		"image-rendering":            ImageRenderingHandler,
 166		"isolation":                  IsolationHandler,
 167		"justify-content":            JustifyContentHandler,
 168		"left":                       SideHandler,
 169		"letter-spacing":             LetterSpacingHandler,
 170		"line-break":                 LineBreakHandler,
 171		"line-height":                LineHeightHandler,
 172		"list-style":                 ListStyleHandler,
 173		"list-style-image":           ImageHandler,
 174		"list-style-position":        ListStylePositionHandler,
 175		"list-style-type":            ListStyleTypeHandler,
 176		"margin":                     MarginHandler,
 177		"margin-bottom":              MarginSideHandler,
 178		"margin-left":                MarginSideHandler,
 179		"margin-right":               MarginSideHandler,
 180		"margin-top":                 MarginSideHandler,
 181		"max-height":                 MaxHeightWidthHandler,
 182		"max-width":                  MaxHeightWidthHandler,
 183		"min-height":                 MinHeightWidthHandler,
 184		"min-width":                  MinHeightWidthHandler,
 185		"mix-blend-mode":             MixBlendModeHandler,
 186		"object-fit":                 ObjectFitHandler,
 187		"object-position":            ObjectPositionHandler,
 188		"opacity":                    OpacityHandler,
 189		"order":                      OrderHandler,
 190		"orphans":                    OrphansHandler,
 191		"outline":                    OutlineHandler,
 192		"outline-color":              ColorHandler,
 193		"outline-offset":             OutlineOffsetHandler,
 194		"outline-style":              OutlineStyleHandler,
 195		"outline-width":              OutlineWidthHandler,
 196		"overflow":                   OverflowHandler,
 197		"overflow-wrap":              OverflowWrapHandler,
 198		"overflow-x":                 OverflowXYHandler,
 199		"overflow-y":                 OverflowXYHandler,
 200		"padding":                    PaddingHandler,
 201		"padding-bottom":             PaddingSideHandler,
 202		"padding-left":               PaddingSideHandler,
 203		"padding-right":              PaddingSideHandler,
 204		"padding-top":                PaddingSideHandler,
 205		"page-break-after":           PageBreakBeforeAfterHandler,
 206		"page-break-before":          PageBreakBeforeAfterHandler,
 207		"page-break-inside":          PageBreakInsideHandler,
 208		"perspective":                PerspectiveHandler,
 209		"perspective-origin":         PerspectiveOriginHandler,
 210		"pointer-events":             PointerEventsHandler,
 211		"position":                   PositionHandler,
 212		"quotes":                     QuotesHandler,
 213		"resize":                     ResizeHandler,
 214		"right":                      SideHandler,
 215		"scroll-behavior":            ScrollBehaviorHandler,
 216		"tab-size":                   TabSizeHandler,
 217		"table-layout":               TableLayoutHandler,
 218		"text-align":                 TextAlignHandler,
 219		"text-align-last":            TextAlignLastHandler,
 220		"text-combine-upright":       TextCombineUprightHandler,
 221		"text-decoration":            TextDecorationHandler,
 222		"text-decoration-color":      ColorHandler,
 223		"text-decoration-line":       TextDecorationLineHandler,
 224		"text-decoration-style":      TextDecorationStyleHandler,
 225		"text-indent":                TextIndentHandler,
 226		"text-justify":               TextJustifyHandler,
 227		"text-orientation":           TextOrientationHandler,
 228		"text-overflow":              TextOverflowHandler,
 229		"text-shadow":                TextShadowHandler,
 230		"text-transform":             TextTransformHandler,
 231		"top":                        SideHandler,
 232		"transform":                  TransformHandler,
 233		"transform-origin":           TransformOriginHandler,
 234		"transform-style":            TransformStyleHandler,
 235		"transition":                 TransitionHandler,
 236		"transition-delay":           TransitionDelayHandler,
 237		"transition-duration":        TransitionDurationHandler,
 238		"transition-property":        TransitionPropertyHandler,
 239		"transition-timing-function": TimingFunctionHandler,
 240		"unicode-bidi":               UnicodeBidiHandler,
 241		"user-select":                UserSelectHandler,
 242		"vertical-align":             VerticalAlignHandler,
 243		"visibility":                 VisiblityHandler,
 244		"white-space":                WhiteSpaceHandler,
 245		"widows":                     OrphansHandler,
 246		"width":                      WidthHandler,
 247		"word-break":                 WordBreakHandler,
 248		"word-spacing":               WordSpacingHandler,
 249		"word-wrap":                  WordWrapHandler,
 250		"writing-mode":               WritingModeHandler,
 251		"z-index":                    ZIndexHandler,
 252	}
 253	colorValues = []string{"initial", "inherit", "aliceblue", "antiquewhite",
 254		"aqua", "aquamarine", "azure", "beige", "bisque", "black",
 255		"blanchedalmond", "blue", "blueviolet", "brown", "burlywood",
 256		"cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
 257		"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
 258		"darkgray", "darkgrey", "darkgreen", "darkkhaki", "darkmagenta",
 259		"darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon",
 260		"darkseagreen", "darkslateblue", "darkslategrey", "darkslategray",
 261		"darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray",
 262		"dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen",
 263		"fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray",
 264		"grey", "green", "greenyellow", "honeydew", "hotpink", "indianred",
 265		"indigo", "ivory", "khaki", "lavender", "lavenderblush",
 266		"lemonchiffon", "lightblue", "lightcoral", "lightcyan",
 267		"lightgoldenrodyellow", "lightgray", "lightgrey", "lightgreen",
 268		"lightpink", "lightsalmon", "lightseagreen", "lightskyblue",
 269		"lightslategray", "lightslategrey", "lightsteeelblue", "lightyellow",
 270		"lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine",
 271		"mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
 272		"mediumslateblue", "mediumspringgreen", "mediumturquoise",
 273		"mediumvioletred", "midnightblue", "mintcream", "mistyrose",
 274		"moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab",
 275		"orange", "orangered", "orchid", "palegoldenrod", "palegreen",
 276		"paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru",
 277		"pink", "plum", "powderblue", "purple", "rebeccapurple", "red",
 278		"rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown",
 279		"seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue",
 280		"slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
 281		"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
 282		"whitesmoke", "yellow", "yellowgreen"}
 283
 284	Alpha             = regexp.MustCompile(`^[a-z]+$`)
 285	Blur              = regexp.MustCompile(`^blur\([0-9]+px\)$`)
 286	BrightnessCont    = regexp.MustCompile(`^(brightness|contrast)\([0-9]+\%\)$`)
 287	Count             = regexp.MustCompile(`^[0-9]+[\.]?[0-9]*$`)
 288	CubicBezier       = regexp.MustCompile(`^cubic-bezier\(([ ]*(0(.[0-9]+)?|1(.0)?),){3}[ ]*(0(.[0-9]+)?|1)\)$`)
 289	Digits            = regexp.MustCompile(`^digits [2-4]$`)
 290	DropShadow        = regexp.MustCompile(`drop-shadow\(([-]?[0-9]+px) ([-]?[0-9]+px)( [-]?[0-9]+px)?( ([-]?[0-9]+px))?`)
 291	Font              = regexp.MustCompile(`^('[a-z \-]+'|[a-z \-]+)$`)
 292	Grayscale         = regexp.MustCompile(`^grayscale\(([0-9]{1,2}|100)%\)$`)
 293	GridTemplateAreas = regexp.MustCompile(`^['"]?[a-z ]+['"]?$`)
 294	HexRGB            = regexp.MustCompile(`^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$`)
 295	HSL               = regexp.MustCompile(`^hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)$`)
 296	HSLA              = regexp.MustCompile(`^hsla\(([ ]*[012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%,[ ]*(1|1\.0|0|(0\.[0-9]+))\)$`)
 297	HueRotate         = regexp.MustCompile(`^hue-rotate\(([12]?[0-9]{1,2}|3[0-5][0-9]|360)?\)$`)
 298	Invert            = regexp.MustCompile(`^invert\(([0-9]{1,2}|100)%\)$`)
 299	Length            = regexp.MustCompile(`^[\-]?([0-9]+|[0-9]*[\.][0-9]+)(%|cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|deg|rad|turn)?$`)
 300	Matrix            = regexp.MustCompile(`^matrix\(([ ]*[0-9]+[\.]?[0-9]*,){5}([ ]*[0-9]+[\.]?[0-9]*)\)$`)
 301	Matrix3D          = regexp.MustCompile(`^matrix3d\(([ ]*[0-9]+[\.]?[0-9]*,){15}([ ]*[0-9]+[\.]?[0-9]*)\)$`)
 302	NegTime           = regexp.MustCompile(`^[\-]?[0-9]+[\.]?[0-9]*(s|ms)?$`)
 303	Numeric           = regexp.MustCompile(`^[0-9]+$`)
 304	NumericDecimal    = regexp.MustCompile(`^[0-9\.]+$`)
 305	Opactiy           = regexp.MustCompile(`^opacity\(([0-9]{1,2}|100)%\)$`)
 306	Perspective       = regexp.MustCompile(`perspective\(`)
 307	Position          = regexp.MustCompile(`^[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]* [[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]*]*$`)
 308	Opacity           = regexp.MustCompile(`^(0[.]?[0-9]*)|(1.0)$`)
 309	QuotedAlpha       = regexp.MustCompile(`^["'][a-z]+["']$`)
 310	Quotes            = regexp.MustCompile(`^([ ]*["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'] ["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'])+$`)
 311	Rect              = regexp.MustCompile(`^rect\([0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px\)$`)
 312	RGB               = regexp.MustCompile(`^rgb\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){2}([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))))\)$`)
 313	RGBA              = regexp.MustCompile(`^rgba\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){3}[ ]*(1(\.0)?|0|(0\.[0-9]+))\)$`)
 314	Rotate            = regexp.MustCompile(`^rotate(x|y|z)?\(([12]?|3[0-5][0-9]|360)\)$`)
 315	Rotate3D          = regexp.MustCompile(`^rotate3d\(([ ]?(1(\.0)?|0\.[0-9]+),){3}([12]?|3[0-5][0-9]|360)\)$`)
 316	Saturate          = regexp.MustCompile(`^saturate\([0-9]+%\)$`)
 317	Sepia             = regexp.MustCompile(`^sepia\(([0-9]{1,2}|100)%\)$`)
 318	Skew              = regexp.MustCompile(`skew(x|y)?\(`)
 319	Span              = regexp.MustCompile(`^span [0-9]+$`)
 320	Steps             = regexp.MustCompile(`^steps\([ ]*[0-9]+([ ]*,[ ]*(start|end)?)\)$`)
 321	Time              = regexp.MustCompile(`^[0-9]+[\.]?[0-9]*(s|ms)?$`)
 322	TransitionProp    = regexp.MustCompile(`^([a-zA-Z]+,[ ]?)*[a-zA-Z]+$`)
 323	TranslateScale    = regexp.MustCompile(`(translate|translate3d|translatex|translatey|translatez|scale|scale3d|scalex|scaley|scalez)\(`)
 324	URL               = regexp.MustCompile(`^url\([\"\']?((https|http)[a-z0-9\.\\/_:]+[\"\']?)\)$`)
 325	ZIndex            = regexp.MustCompile(`^[\-]?[0-9]+$`)
 326)
 327
 328func multiSplit(value string, seps ...string) []string {
 329	curArray := []string{value}
 330	for _, i := range seps {
 331		newArray := []string{}
 332		for _, j := range curArray {
 333			newArray = append(newArray, strings.Split(j, i)...)
 334		}
 335		curArray = newArray
 336	}
 337	return curArray
 338}
 339
 340func recursiveCheck(value []string, funcs []func(string) bool) bool {
 341	for i := 0; i < len(value); i++ {
 342		tempVal := strings.Join(value[:i+1], " ")
 343		for _, j := range funcs {
 344			if j(tempVal) && (len(value[i+1:]) == 0 || recursiveCheck(value[i+1:], funcs)) {
 345				return true
 346			}
 347		}
 348	}
 349	return false
 350}
 351
 352func in(value []string, arr []string) bool {
 353	for _, i := range value {
 354		foundString := false
 355		for _, j := range arr {
 356			if j == i {
 357				foundString = true
 358			}
 359		}
 360		if !foundString {
 361			return false
 362		}
 363	}
 364	return true
 365}
 366
 367func splitValues(value string) []string {
 368	values := strings.Split(value, ",")
 369	for _, strippedValue := range values {
 370		strippedValue = strings.ToLower(strings.TrimSpace(strippedValue))
 371	}
 372	return values
 373}
 374
 375func GetDefaultHandler(attr string) func(string) bool {
 376
 377	if defaultStyleHandlers[attr] != nil {
 378		return defaultStyleHandlers[attr]
 379	}
 380	return BaseHandler
 381}
 382
 383func BaseHandler(value string) bool {
 384	return false
 385}
 386
 387func AlignContentHandler(value string) bool {
 388	values := []string{"stretch", "center", "flex-start",
 389		"flex-end", "space-between", "space-around", "initial", "inherit"}
 390	splitVals := splitValues(value)
 391	return in(splitVals, values)
 392}
 393
 394func AlignItemsHandler(value string) bool {
 395	values := []string{"stretch", "center", "flex-start",
 396		"flex-end", "baseline", "initial", "inherit"}
 397	splitVals := splitValues(value)
 398	return in(splitVals, values)
 399}
 400
 401func AlignSelfHandler(value string) bool {
 402	values := []string{"auto", "stretch", "center", "flex-start",
 403		"flex-end", "baseline", "initial", "inherit"}
 404	splitVals := splitValues(value)
 405	return in(splitVals, values)
 406}
 407
 408func AllHandler(value string) bool {
 409	values := []string{"initial", "inherit", "unset"}
 410	splitVals := splitValues(value)
 411	return in(splitVals, values)
 412}
 413
 414func AnimationHandler(value string) bool {
 415	values := []string{"initial", "inherit"}
 416	if in([]string{value}, values) {
 417		return true
 418	}
 419	splitVals := strings.Split(value, " ")
 420	usedFunctions := []func(string) bool{
 421		AnimationNameHandler,
 422		AnimationDurationHandler,
 423		TimingFunctionHandler,
 424		AnimationDelayHandler,
 425		AnimationIterationCountHandler,
 426		AnimationDirectionHandler,
 427		AnimationFillModeHandler,
 428		AnimationPlayStateHandler,
 429	}
 430	return recursiveCheck(splitVals, usedFunctions)
 431}
 432
 433func AnimationDelayHandler(value string) bool {
 434	if NegTime.MatchString(value) {
 435		return true
 436	}
 437	values := []string{"initial", "inherit"}
 438	splitVals := splitValues(value)
 439	return in(splitVals, values)
 440}
 441
 442func AnimationDirectionHandler(value string) bool {
 443	values := []string{"normal", "reverse", "alternate", "alternate-reverse", "initial", "inherit"}
 444	splitVals := splitValues(value)
 445	return in(splitVals, values)
 446}
 447
 448func AnimationDurationHandler(value string) bool {
 449	if Time.MatchString(value) {
 450		return true
 451	}
 452	values := []string{"initial", "inherit"}
 453	splitVals := splitValues(value)
 454	return in(splitVals, values)
 455}
 456
 457func AnimationFillModeHandler(value string) bool {
 458	values := []string{"none", "forwards", "backwards", "both", "initial", "inherit"}
 459	splitVals := splitValues(value)
 460	return in(splitVals, values)
 461}
 462
 463func AnimationIterationCountHandler(value string) bool {
 464	if Count.MatchString(value) {
 465		return true
 466	}
 467	values := []string{"infinite", "initial", "inherit"}
 468	splitVals := splitValues(value)
 469	return in(splitVals, values)
 470}
 471
 472func AnimationNameHandler(value string) bool {
 473	return Alpha.MatchString(value)
 474}
 475
 476func AnimationPlayStateHandler(value string) bool {
 477	values := []string{"paused", "running", "initial", "inherit"}
 478	splitVals := splitValues(value)
 479	return in(splitVals, values)
 480}
 481
 482func TimingFunctionHandler(value string) bool {
 483	values := []string{"linear", "ease", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "initial", "inherit"}
 484	splitVals := splitValues(value)
 485	if in(splitVals, values) {
 486		return true
 487	}
 488	if CubicBezier.MatchString(value) {
 489		return true
 490	}
 491	return Steps.MatchString(value)
 492}
 493
 494func BackfaceVisibilityHandler(value string) bool {
 495	values := []string{"visible", "hidden", "initial", "inherit"}
 496	splitVals := splitValues(value)
 497	return in(splitVals, values)
 498}
 499
 500func BackgroundHandler(value string) bool {
 501	values := []string{"initial", "inherit"}
 502	if in([]string{value}, values) {
 503		return true
 504	}
 505	splitVals := strings.Split(value, " ")
 506	newSplitVals := []string{}
 507	for _, i := range splitVals {
 508		if len(strings.Split(i, "/")) == 2 {
 509			newSplitVals = append(newSplitVals, strings.Split(i, "/")...)
 510		} else {
 511			newSplitVals = append(newSplitVals, i)
 512		}
 513	}
 514	usedFunctions := []func(string) bool{
 515		ColorHandler,
 516		ImageHandler,
 517		BackgroundPositionHandler,
 518		BackgroundSizeHandler,
 519		BackgroundRepeatHandler,
 520		BackgroundOriginHandler,
 521		BackgroundClipHandler,
 522		BackgroundAttachmentHandler,
 523	}
 524	return recursiveCheck(newSplitVals, usedFunctions)
 525}
 526
 527func BackgroundAttachmentHandler(value string) bool {
 528	values := []string{"scroll", "fixed", "local", "initial", "inherit"}
 529	splitVals := splitValues(value)
 530	return in(splitVals, values)
 531}
 532
 533func BackgroundClipHandler(value string) bool {
 534	values := []string{"border-box", "padding-box", "content-box", "initial", "inherit"}
 535	splitVals := splitValues(value)
 536	return in(splitVals, values)
 537}
 538
 539func BackgroundBlendModeHandler(value string) bool {
 540	values := []string{"normal", "multiply", "screen", "overlay", "darken",
 541		"lighten", "color-dodge", "saturation", "color", "luminosity"}
 542	splitVals := splitValues(value)
 543	return in(splitVals, values)
 544}
 545
 546func ImageHandler(value string) bool {
 547	values := []string{"none", "initial", "inherit"}
 548	splitVals := splitValues(value)
 549	if in(splitVals, values) {
 550		return true
 551	}
 552	return URL.MatchString(value)
 553}
 554
 555func BackgroundOriginHandler(value string) bool {
 556	values := []string{"padding-box", "border-box", "content-box", "initial", "inherit"}
 557	splitVals := splitValues(value)
 558	return in(splitVals, values)
 559}
 560
 561func BackgroundPositionHandler(value string) bool {
 562	splitVals := strings.Split(value, ";")
 563	values := []string{"left", "left top", "left bottom", "right", "right top", "right bottom", "right center", "center top", "center center", "center bottom", "center", "top", "bottom", "initial", "inherit"}
 564	if in(splitVals, values) {
 565		return true
 566	}
 567	return Position.MatchString(value)
 568}
 569
 570func BackgroundRepeatHandler(value string) bool {
 571	values := []string{"repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round", "initial", "inherit"}
 572	splitVals := splitValues(value)
 573	return in(splitVals, values)
 574}
 575
 576func BackgroundSizeHandler(value string) bool {
 577	splitVals := strings.Split(value, " ")
 578	values := []string{"auto", "cover", "contain", "initial", "inherit"}
 579	if in(splitVals, values) {
 580		return true
 581	}
 582	if len(splitVals) > 0 && LengthHandler(splitVals[0]) {
 583		if len(splitVals) < 2 || (len(splitVals) == 2 && LengthHandler(splitVals[1])) {
 584			return true
 585		}
 586	}
 587	return false
 588}
 589
 590func BorderHandler(value string) bool {
 591	values := []string{"initial", "inherit"}
 592	if in([]string{value}, values) {
 593		return true
 594	}
 595	splitVals := multiSplit(value, " ", "/")
 596	usedFunctions := []func(string) bool{
 597		BorderWidthHandler,
 598		BorderStyleHandler,
 599		ColorHandler,
 600	}
 601	return recursiveCheck(splitVals, usedFunctions)
 602}
 603
 604func BorderSideHandler(value string) bool {
 605	values := []string{"initial", "inherit"}
 606	if in([]string{value}, values) {
 607		return true
 608	}
 609	splitVals := strings.Split(value, " ")
 610	usedFunctions := []func(string) bool{
 611		BorderSideWidthHandler,
 612		BorderSideStyleHandler,
 613		ColorHandler,
 614	}
 615	return recursiveCheck(splitVals, usedFunctions)
 616}
 617
 618func BorderSideRadiusHandler(value string) bool {
 619	splitVals := strings.Split(value, " ")
 620	valid := true
 621	for _, i := range splitVals {
 622		if !LengthHandler(i) {
 623			valid = false
 624			break
 625		}
 626	}
 627	if valid {
 628		return true
 629	}
 630	splitVals = splitValues(value)
 631	values := []string{"initial", "inherit"}
 632	return in(splitVals, values)
 633}
 634
 635func BorderSideStyleHandler(value string) bool {
 636	values := []string{"none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "initial", "inherit"}
 637	splitVals := splitValues(value)
 638	return in(splitVals, values)
 639}
 640
 641func BorderSideWidthHandler(value string) bool {
 642	if LengthHandler(value) {
 643		return true
 644	}
 645	splitVals := strings.Split(value, ";")
 646	values := []string{"medium", "thin", "thick", "initial", "inherit"}
 647	return in(splitVals, values)
 648}
 649
 650func BorderCollapseHandler(value string) bool {
 651	values := []string{"separate", "collapse", "initial", "inherit"}
 652	splitVals := splitValues(value)
 653	return in(splitVals, values)
 654}
 655
 656func BorderImageHandler(value string) bool {
 657	values := []string{"initial", "inherit"}
 658	if in([]string{value}, values) {
 659		return true
 660	}
 661	splitVals := multiSplit(value, " ", " / ")
 662	usedFunctions := []func(string) bool{
 663		ImageHandler,
 664		BorderImageSliceHandler,
 665		BorderImageWidthHandler,
 666		BorderImageOutsetHandler,
 667		BorderImageRepeatHandler,
 668	}
 669	return recursiveCheck(splitVals, usedFunctions)
 670}
 671
 672func BorderImageOutsetHandler(value string) bool {
 673	if LengthHandler(value) {
 674		return true
 675	}
 676	values := []string{"initial", "inherit"}
 677	splitVals := splitValues(value)
 678	return in(splitVals, values)
 679}
 680
 681func BorderImageRepeatHandler(value string) bool {
 682	values := []string{"stretch", "repeat", "round", "space", "initial", "inherit"}
 683	splitVals := splitValues(value)
 684	return in(splitVals, values)
 685}
 686
 687func BorderImageSliceHandler(value string) bool {
 688	values := []string{"fill", "initial", "inherit"}
 689	if in([]string{value}, values) {
 690		return true
 691	}
 692	splitVals := strings.Split(value, " ")
 693	if len(splitVals) > 4 {
 694		return false
 695	}
 696	usedFunctions := []func(string) bool{
 697		LengthHandler,
 698	}
 699	return recursiveCheck(splitVals, usedFunctions)
 700}
 701
 702func BorderImageWidthHandler(value string) bool {
 703	if LengthHandler(value) {
 704		return true
 705	}
 706	values := []string{"auto", "initial", "inherit"}
 707	splitVals := splitValues(value)
 708	return in(splitVals, values)
 709}
 710
 711func BorderRadiusHandler(value string) bool {
 712	values := []string{"initial", "inherit"}
 713	if in([]string{value}, values) {
 714		return true
 715	}
 716	splitVals := strings.Split(value, " ")
 717	if len(splitVals) > 4 {
 718		return false
 719	}
 720	usedFunctions := []func(string) bool{
 721		LengthHandler,
 722	}
 723	return recursiveCheck(splitVals, usedFunctions)
 724}
 725
 726func BorderSpacingHandler(value string) bool {
 727	values := []string{"initial", "inherit"}
 728	if in([]string{value}, values) {
 729		return true
 730	}
 731	splitVals := strings.Split(value, " ")
 732	if len(splitVals) > 2 {
 733		return false
 734	}
 735	usedFunctions := []func(string) bool{
 736		LengthHandler,
 737	}
 738	return recursiveCheck(splitVals, usedFunctions)
 739}
 740
 741func BorderStyleHandler(value string) bool {
 742	values := []string{"initial", "inherit"}
 743	if in([]string{value}, values) {
 744		return true
 745	}
 746	splitVals := strings.Split(value, " ")
 747	if len(splitVals) > 4 {
 748		return false
 749	}
 750	usedFunctions := []func(string) bool{
 751		BorderSideStyleHandler,
 752	}
 753	return recursiveCheck(splitVals, usedFunctions)
 754}
 755
 756func BorderWidthHandler(value string) bool {
 757	values := []string{"initial", "inherit"}
 758	if in([]string{value}, values) {
 759		return true
 760	}
 761	splitVals := strings.Split(value, " ")
 762	if len(splitVals) > 4 {
 763		return false
 764	}
 765	usedFunctions := []func(string) bool{
 766		BorderSideWidthHandler,
 767	}
 768	return recursiveCheck(splitVals, usedFunctions)
 769}
 770
 771func SideHandler(value string) bool {
 772	if LengthHandler(value) {
 773		return true
 774	}
 775	values := []string{"auto", "inherit", "unset"}
 776	splitVals := splitValues(value)
 777	return in(splitVals, values)
 778}
 779
 780func BoxDecorationBreakHandler(value string) bool {
 781	values := []string{"slice", "clone", "initial", "initial", "inherit", "unset"}
 782	splitVals := splitValues(value)
 783	return in(splitVals, values)
 784}
 785
 786func BoxShadowHandler(value string) bool {
 787	values := []string{"none", "initial", "inherit"}
 788	if in([]string{value}, values) {
 789		return true
 790	}
 791	commaSplitVals := strings.Split(value, ",")
 792	for _, val := range commaSplitVals {
 793		splitVals := strings.Split(val, " ")
 794		if len(splitVals) > 6 || len(splitVals) < 2 {
 795			return false
 796		}
 797		if !LengthHandler(splitVals[0]) {
 798			return false
 799		}
 800		if !LengthHandler(splitVals[1]) {
 801			return false
 802		}
 803		usedFunctions := []func(string) bool{
 804			LengthHandler,
 805			ColorHandler,
 806		}
 807		if len(splitVals) > 2 && !recursiveCheck(splitVals[2:], usedFunctions) {
 808			return false
 809		}
 810	}
 811	return true
 812}
 813
 814func BoxSizingHandler(value string) bool {
 815	values := []string{"slicontent-box", "border-box", "initial", "inherit"}
 816	splitVals := splitValues(value)
 817	return in(splitVals, values)
 818}
 819
 820func BreakBeforeAfterHandler(value string) bool {
 821	values := []string{"auto", "avoid", "always", "all", "avoid-page", "page", "left", "right", "recto", "verso", "avoid-column", "column", "avoid-region", "region"}
 822	splitVals := splitValues(value)
 823	return in(splitVals, values)
 824}
 825
 826func BreakInsideHandler(value string) bool {
 827	values := []string{"auto", "avoid", "avoid-page", "avoid-column", "avoid-region"}
 828	splitVals := splitValues(value)
 829	return in(splitVals, values)
 830}
 831
 832func CaptionSideHandler(value string) bool {
 833	values := []string{"top", "bottom", "initial", "inherit"}
 834	splitVals := splitValues(value)
 835	return in(splitVals, values)
 836}
 837
 838func CaretColorHandler(value string) bool {
 839	splitVals := splitValues(value)
 840	if in(splitVals, colorValues) {
 841		return true
 842	}
 843	if HexRGB.MatchString(value) {
 844		return true
 845	}
 846	if RGB.MatchString(value) {
 847		return true
 848	}
 849	if RGBA.MatchString(value) {
 850		return true
 851	}
 852	if HSL.MatchString(value) {
 853		return true
 854	}
 855	return HSLA.MatchString(value)
 856}
 857
 858func ClearHandler(value string) bool {
 859	values := []string{"none", "left", "right", "both", "initial", "inherit"}
 860	splitVals := splitValues(value)
 861	return in(splitVals, values)
 862}
 863
 864func ClipHandler(value string) bool {
 865	if Rect.MatchString(value) {
 866		return true
 867	}
 868	values := []string{"auto", "initial", "inherit"}
 869	splitVals := splitValues(value)
 870	return in(splitVals, values)
 871}
 872
 873func ColorHandler(value string) bool {
 874	splitVals := splitValues(value)
 875	if in(splitVals, colorValues) {
 876		return true
 877	}
 878	if HexRGB.MatchString(value) {
 879		return true
 880	}
 881	if RGB.MatchString(value) {
 882		return true
 883	}
 884	if RGBA.MatchString(value) {
 885		return true
 886	}
 887	if HSL.MatchString(value) {
 888		return true
 889	}
 890	return HSLA.MatchString(value)
 891}
 892
 893func ColumnCountHandler(value string) bool {
 894	if Numeric.MatchString(value) {
 895		return true
 896	}
 897	values := []string{"auto", "initial", "inherit"}
 898	splitVals := splitValues(value)
 899	return in(splitVals, values)
 900}
 901
 902func ColumnFillHandler(value string) bool {
 903	values := []string{"balance", "auto", "initial", "inherit"}
 904	splitVals := splitValues(value)
 905	return in(splitVals, values)
 906}
 907
 908func ColumnGapHandler(value string) bool {
 909	if LengthHandler(value) {
 910		return true
 911	}
 912	values := []string{"normal", "initial", "inherit"}
 913	splitVals := splitValues(value)
 914	return in(splitVals, values)
 915}
 916
 917func ColumnRuleHandler(value string) bool {
 918	values := []string{"initial", "inherit"}
 919	if in([]string{value}, values) {
 920		return true
 921	}
 922	splitVals := strings.Split(value, " ")
 923	usedFunctions := []func(string) bool{
 924		ColumnRuleWidthHandler,
 925		BorderSideStyleHandler,
 926		ColorHandler,
 927	}
 928	return recursiveCheck(splitVals, usedFunctions)
 929}
 930
 931func ColumnRuleWidthHandler(value string) bool {
 932	if LengthHandler(value) {
 933		return true
 934	}
 935	splitVals := strings.Split(value, ";")
 936	values := []string{"medium", "thin", "thick", "initial", "inherit"}
 937	return in(splitVals, values)
 938}
 939
 940func ColumnSpanHandler(value string) bool {
 941	values := []string{"none", "all", "initial", "inherit"}
 942	splitVals := splitValues(value)
 943	return in(splitVals, values)
 944}
 945
 946func ColumnWidthHandler(value string) bool {
 947	if LengthHandler(value) {
 948		return true
 949	}
 950	splitVals := strings.Split(value, ";")
 951	values := []string{"auto", "initial", "inherit"}
 952	return in(splitVals, values)
 953}
 954
 955func ColumnsHandler(value string) bool {
 956	values := []string{"auto", "initial", "inherit"}
 957	if in([]string{value}, values) {
 958		return true
 959	}
 960	splitVals := strings.Split(value, " ")
 961	usedFunctions := []func(string) bool{
 962		ColumnWidthHandler,
 963		ColumnCountHandler,
 964	}
 965	return recursiveCheck(splitVals, usedFunctions)
 966}
 967
 968func CursorHandler(value string) bool {
 969	values := []string{"alias", "all-scroll", "auto", "cell", "context-menu", "col-resize", "copy", "crosshair", "default", "e-resize", "ew-resize", "grab", "grabbing", "help", "move", "n-resize", "ne-resize", "nesw-resize", "ns-resize", "nw-resize", "nwse-resize", "no-drop", "none", "not-allowed", "pointer", "progress", "row-resize", "s-resize", "se-resize", "sw-resize", "text", "vertical-text", "w-resize", "wait", "zoom-in", "zoom-out", "initial", "inherit"}
 970	splitVals := splitValues(value)
 971	return in(splitVals, values)
 972}
 973
 974func DirectionHandler(value string) bool {
 975	values := []string{"ltr", "rtl", "initial", "inherit"}
 976	splitVals := splitValues(value)
 977	return in(splitVals, values)
 978}
 979
 980func DisplayHandler(value string) bool {
 981	values := []string{"inline", "block", "contents", "flex", "grid", "inline-block", "inline-flex", "inline-grid", "inline-table", "list-item", "run-in", "table", "table-caption", "table-column-group", "table-header-group", "table-footer-group", "table-row-group", "table-cell", "table-column", "table-row", "none", "initial", "inherit"}
 982	splitVals := splitValues(value)
 983	return in(splitVals, values)
 984}
 985
 986func EmptyCellsHandler(value string) bool {
 987	values := []string{"show", "hide", "initial", "inherit"}
 988	splitVals := splitValues(value)
 989	return in(splitVals, values)
 990}
 991
 992func FilterHandler(value string) bool {
 993	values := []string{"none", "initial", "inherit"}
 994	splitVals := splitValues(value)
 995	if in(splitVals, values) {
 996		return true
 997	}
 998	if Blur.MatchString(value) {
 999		return true
1000	}
1001	if BrightnessCont.MatchString(value) {
1002		return true
1003	}
1004	if DropShadow.MatchString(value) {
1005		return true
1006	}
1007	colorValue := strings.TrimSuffix(string(DropShadow.ReplaceAll([]byte(value), []byte{})), ")")
1008	if ColorHandler(colorValue) {
1009		return true
1010	}
1011	if Grayscale.MatchString(value) {
1012		return true
1013	}
1014	if HueRotate.MatchString(value) {
1015		return true
1016	}
1017	if Invert.MatchString(value) {
1018		return true
1019	}
1020	if Opacity.MatchString(value) {
1021		return true
1022	}
1023	if Saturate.MatchString(value) {
1024		return true
1025	}
1026	return Sepia.MatchString(value)
1027}
1028
1029func FlexHandler(value string) bool {
1030	values := []string{"auto", "initial", "initial", "inherit"}
1031	if in([]string{value}, values) {
1032		return true
1033	}
1034	splitVals := strings.Split(value, " ")
1035	usedFunctions := []func(string) bool{
1036		FlexGrowHandler,
1037		FlexBasisHandler,
1038	}
1039	return recursiveCheck(splitVals, usedFunctions)
1040}
1041
1042func FlexBasisHandler(value string) bool {
1043	if LengthHandler(value) {
1044		return true
1045	}
1046	splitVals := strings.Split(value, ";")
1047	values := []string{"auto", "initial", "inherit"}
1048	return in(splitVals, values)
1049}
1050
1051func FlexDirectionHandler(value string) bool {
1052	values := []string{"row", "row-reverse", "column", "column-reverse", "initial", "inherit"}
1053	splitVals := splitValues(value)
1054	return in(splitVals, values)
1055}
1056
1057func FlexFlowHandler(value string) bool {
1058	values := []string{"initial", "inherit"}
1059	if in([]string{value}, values) {
1060		return true
1061	}
1062	splitVals := strings.Split(value, " ")
1063	usedFunctions := []func(string) bool{
1064		FlexDirectionHandler,
1065		FlexWrapHandler,
1066	}
1067	return recursiveCheck(splitVals, usedFunctions)
1068}
1069
1070func FlexGrowHandler(value string) bool {
1071	if NumericDecimal.MatchString(value) {
1072		return true
1073	}
1074	splitVals := strings.Split(value, ";")
1075	values := []string{"initial", "inherit"}
1076	return in(splitVals, values)
1077}
1078
1079func FlexWrapHandler(value string) bool {
1080	values := []string{"nowrap", "wrap", "wrap-reverse", "initial", "inherit"}
1081	splitVals := splitValues(value)
1082	return in(splitVals, values)
1083}
1084
1085func FloatHandler(value string) bool {
1086	values := []string{"none", "left", "right", "initial", "inherit"}
1087	splitVals := splitValues(value)
1088	return in(splitVals, values)
1089}
1090
1091func FontHandler(value string) bool {
1092	values := []string{"caption", "icon", "menu", "message-box", "small-caption", "status-bar", "initial", "inherit"}
1093	if in([]string{value}, values) {
1094		return true
1095	}
1096	splitVals := strings.Split(value, " ")
1097	newSplitVals := []string{}
1098	for _, i := range splitVals {
1099		if len(strings.Split(i, "/")) == 2 {
1100			newSplitVals = append(newSplitVals, strings.Split(i, "/")...)
1101		} else {
1102			newSplitVals = append(newSplitVals, i)
1103		}
1104	}
1105	usedFunctions := []func(string) bool{
1106		FontStyleHandler,
1107		FontVariantHandler,
1108		FontWeightHandler,
1109		FontSizeHandler,
1110		FontFamilyHandler,
1111	}
1112	return recursiveCheck(newSplitVals, usedFunctions)
1113}
1114
1115func FontFamilyHandler(value string) bool {
1116	values := []string{"initial", "inherit"}
1117	splitVals := splitValues(value)
1118	if in(splitVals, values) {
1119		return true
1120	}
1121	for _, i := range splitVals {
1122		i = strings.TrimSpace(i)
1123		if Font.FindString(i) != i {
1124			return false
1125		}
1126	}
1127	return true
1128}
1129
1130func FontKerningHandler(value string) bool {
1131	values := []string{"auto", "normal", "none"}
1132	splitVals := splitValues(value)
1133	return in(splitVals, values)
1134}
1135
1136func FontLanguageOverrideHandler(value string) bool {
1137	return Alpha.MatchString(value)
1138}
1139
1140func FontSizeHandler(value string) bool {
1141	if LengthHandler(value) {
1142		return true
1143	}
1144	values := []string{"medium", "xx-small", "x-small", "small", "large", "x-large", "xx-large", "smaller", "larger", "initial", "inherit"}
1145	splitVals := splitValues(value)
1146	return in(splitVals, values)
1147}
1148
1149func FontSizeAdjustHandler(value string) bool {
1150	if Count.MatchString(value) {
1151		return true
1152	}
1153	values := []string{"auto", "initial", "inherit"}
1154	splitVals := splitValues(value)
1155	return in(splitVals, values)
1156}
1157
1158func FontStretchHandler(value string) bool {
1159	values := []string{"ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", "initial", "inherit"}
1160	splitVals := splitValues(value)
1161	return in(splitVals, values)
1162}
1163
1164func FontStyleHandler(value string) bool {
1165	values := []string{"normal", "italic", "oblique", "initial", "inherit"}
1166	splitVals := splitValues(value)
1167	return in(splitVals, values)
1168}
1169
1170func FontSynthesisHandler(value string) bool {
1171	values := []string{"none", "style", "weight"}
1172	splitVals := splitValues(value)
1173	return in(splitVals, values)
1174}
1175
1176func FontVariantCapsHandler(value string) bool {
1177	values := []string{"normal", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps"}
1178	splitVals := splitValues(value)
1179	return in(splitVals, values)
1180}
1181
1182func FontVariantHandler(value string) bool {
1183	values := []string{"normal", "small-caps", "initial", "inherit"}
1184	splitVals := splitValues(value)
1185	return in(splitVals, values)
1186}
1187
1188func FontVariantPositionHandler(value string) bool {
1189	values := []string{"normal", "sub", "super"}
1190	splitVals := splitValues(value)
1191	return in(splitVals, values)
1192}
1193
1194func FontWeightHandler(value string) bool {
1195	values := []string{"normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "initial", "inherit"}
1196	splitVals := splitValues(value)
1197	return in(splitVals, values)
1198}
1199
1200func GridHandler(value string) bool {
1201	values := []string{"none", "initial", "inherit"}
1202	if in([]string{value}, values) {
1203		return true
1204	}
1205	splitVals := strings.Split(value, " ")
1206	newSplitVals := []string{}
1207	for _, i := range splitVals {
1208		if i != "/" {
1209			newSplitVals = append(newSplitVals, i)
1210		}
1211	}
1212	usedFunctions := []func(string) bool{
1213		GridTemplateRowsHandler,
1214		GridTemplateColumnsHandler,
1215		GridTemplateAreasHandler,
1216		GridAutoColumnsHandler,
1217		GridAutoFlowHandler,
1218	}
1219	return recursiveCheck(newSplitVals, usedFunctions)
1220}
1221
1222func GridAreaHandler(value string) bool {
1223	values := []string{"none", "initial", "inherit"}
1224	if in([]string{value}, values) {
1225		return true
1226	}
1227	splitVals := strings.Split(value, " / ")
1228	usedFunctions := []func(string) bool{
1229		GridAxisStartEndHandler,
1230	}
1231	return recursiveCheck(splitVals, usedFunctions)
1232}
1233
1234func GridAutoColumnsHandler(value string) bool {
1235	if LengthHandler(value) {
1236		return true
1237	}
1238	values := []string{"auto", "max-content", "min-content", "initial", "inherit"}
1239	splitVals := splitValues(value)
1240	return in(splitVals, values)
1241}
1242
1243func GridAutoFlowHandler(value string) bool {
1244	values := []string{"row", "column", "dense", "row dense", "column dense"}
1245	splitVals := splitValues(value)
1246	return in(splitVals, values)
1247}
1248
1249func GridColumnHandler(value string) bool {
1250	values := []string{"none", "initial", "inherit"}
1251	if in([]string{value}, values) {
1252		return true
1253	}
1254	splitVals := strings.Split(value, " / ")
1255	if len(splitVals) > 2 {
1256		return false
1257	}
1258	usedFunctions := []func(string) bool{
1259		GridAxisStartEndHandler,
1260	}
1261	return recursiveCheck(splitVals, usedFunctions)
1262}
1263
1264func GridColumnGapHandler(value string) bool {
1265	return LengthHandler(value)
1266}
1267
1268func LengthHandler(value string) bool {
1269	return Length.MatchString(value)
1270}
1271
1272func LineBreakHandler(value string) bool {
1273	values := []string{"auto", "loose", "normal", "strict"}
1274	splitVals := splitValues(value)
1275	return in(splitVals, values)
1276}
1277
1278func GridAxisStartEndHandler(value string) bool {
1279	if Numeric.MatchString(value) {
1280		return true
1281	}
1282	if Span.MatchString(value) {
1283		return true
1284	}
1285	values := []string{"auto"}
1286	splitVals := splitValues(value)
1287	return in(splitVals, values)
1288}
1289
1290func GridGapHandler(value string) bool {
1291	splitVals := strings.Split(value, " ")
1292	if len(splitVals) > 2 {
1293		return false
1294	}
1295	usedFunctions := []func(string) bool{
1296		GridColumnGapHandler,
1297	}
1298	return recursiveCheck(splitVals, usedFunctions)
1299}
1300
1301func GridRowHandler(value string) bool {
1302	splitVals := strings.Split(value, " / ")
1303	if len(splitVals) > 2 {
1304		return false
1305	}
1306	usedFunctions := []func(string) bool{
1307		GridAxisStartEndHandler,
1308	}
1309	return recursiveCheck(splitVals, usedFunctions)
1310}
1311
1312func GridTemplateHandler(value string) bool {
1313	values := []string{"none", "initial", "inherit"}
1314	if in([]string{value}, values) {
1315		return true
1316	}
1317	splitVals := strings.Split(value, " / ")
1318	if len(splitVals) > 2 {
1319		return false
1320	}
1321	usedFunctions := []func(string) bool{
1322		GridTemplateColumnsHandler,
1323		GridTemplateRowsHandler,
1324	}
1325	return recursiveCheck(splitVals, usedFunctions)
1326}
1327
1328func GridTemplateAreasHandler(value string) bool {
1329	values := []string{"none"}
1330	if in([]string{value}, values) {
1331		return true
1332	}
1333	return GridTemplateAreas.MatchString(value)
1334}
1335
1336func GridTemplateColumnsHandler(value string) bool {
1337	splitVals := strings.Split(value, " ")
1338	values := []string{"none", "auto", "max-content", "min-content", "initial", "inherit"}
1339	for _, val := range splitVals {
1340		if LengthHandler(val) {
1341			continue
1342		}
1343		valArr := []string{val}
1344		if !in(valArr, values) {
1345			return false
1346		}
1347	}
1348	return true
1349}
1350
1351func GridTemplateRowsHandler(value string) bool {
1352	splitVals := strings.Split(value, " ")
1353	values := []string{"none", "auto", "max-content", "min-content"}
1354	for _, val := range splitVals {
1355		if LengthHandler(val) {
1356			continue
1357		}
1358		valArr := []string{val}
1359		if !in(valArr, values) {
1360			return false
1361		}
1362	}
1363	return true
1364}
1365
1366func HangingPunctuationHandler(value string) bool {
1367	values := []string{"none", "first", "last", "allow-end", "force-end", "initial", "inherit"}
1368	splitVals := splitValues(value)
1369	return in(splitVals, values)
1370}
1371
1372func HeightHandler(value string) bool {
1373	if LengthHandler(value) {
1374		return true
1375	}
1376	values := []string{"auto", "initial", "inherit"}
1377	splitVals := splitValues(value)
1378	return in(splitVals, values)
1379}
1380
1381func HyphensHandler(value string) bool {
1382	values := []string{"none", "manual", "auto", "initial", "inherit"}
1383	splitVals := splitValues(value)
1384	return in(splitVals, values)
1385}
1386
1387func ImageRenderingHandler(value string) bool {
1388	values := []string{"auto", "smooth", "high-quality", "crisp-edges", "pixelated"}
1389	splitVals := splitValues(value)
1390	return in(splitVals, values)
1391}
1392
1393func IsolationHandler(value string) bool {
1394	values := []string{"auto", "isolate", "initial", "inherit"}
1395	splitVals := splitValues(value)
1396	return in(splitVals, values)
1397}
1398
1399func JustifyContentHandler(value string) bool {
1400	values := []string{"flex-start", "flex-end", "center", "space-between", "space-around", "initial", "inherit"}
1401	splitVals := splitValues(value)
1402	return in(splitVals, values)
1403}
1404
1405func LetterSpacingHandler(value string) bool {
1406	if LengthHandler(value) {
1407		return true
1408	}
1409	values := []string{"normal", "initial", "inherit"}
1410	splitVals := splitValues(value)
1411	return in(splitVals, values)
1412}
1413
1414func LineHeightHandler(value string) bool {
1415	if LengthHandler(value) {
1416		return true
1417	}
1418	values := []string{"normal", "initial", "inherit"}
1419	splitVals := splitValues(value)
1420	return in(splitVals, values)
1421}
1422
1423func ListStyleHandler(value string) bool {
1424	values := []string{"initial", "inherit"}
1425	if in([]string{value}, values) {
1426		return true
1427	}
1428	splitVals := strings.Split(value, " ")
1429	usedFunctions := []func(string) bool{
1430		ListStyleTypeHandler,
1431		ListStylePositionHandler,
1432		ImageHandler,
1433	}
1434	return recursiveCheck(splitVals, usedFunctions)
1435}
1436
1437func ListStylePositionHandler(value string) bool {
1438	values := []string{"inside", "outside", "initial", "inherit"}
1439	splitVals := splitValues(value)
1440	return in(splitVals, values)
1441}
1442
1443func ListStyleTypeHandler(value string) bool {
1444	values := []string{"disc", "armenian", "circle", "cjk-ideographic", "decimal", "decimal-leading-zero", "georgian", "hebrew", "hiragana", "hiragana-iroha", "katakana", "katakana-iroha", "lower-alpha", "lower-greek", "lower-latin", "lower-roman", "none", "square", "upper-alpha", "upper-greek", "upper-latin", "upper-roman", "initial", "inherit"}
1445	splitVals := splitValues(value)
1446	return in(splitVals, values)
1447}
1448
1449func MarginHandler(value string) bool {
1450	values := []string{"auto", "initial", "inherit"}
1451	if in([]string{value}, values) {
1452		return true
1453	}
1454	splitVals := strings.Split(value, " ")
1455	usedFunctions := []func(string) bool{
1456		MarginSideHandler,
1457	}
1458	return recursiveCheck(splitVals, usedFunctions)
1459}
1460
1461func MarginSideHandler(value string) bool {
1462	if LengthHandler(value) {
1463		return true
1464	}
1465	values := []string{"auto", "initial", "inherit"}
1466	splitVals := splitValues(value)
1467	return in(splitVals, values)
1468}
1469
1470func MaxHeightWidthHandler(value string) bool {
1471	if LengthHandler(value) {
1472		return true
1473	}
1474	values := []string{"none", "initial", "inherit"}
1475	splitVals := splitValues(value)
1476	return in(splitVals, values)
1477}
1478
1479func MinHeightWidthHandler(value string) bool {
1480	if LengthHandler(value) {
1481		return true
1482	}
1483	values := []string{"initial", "inherit"}
1484	splitVals := splitValues(value)
1485	return in(splitVals, values)
1486}
1487
1488func MixBlendModeHandler(value string) bool {
1489	values := []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}
1490	splitVals := splitValues(value)
1491	return in(splitVals, values)
1492}
1493
1494func ObjectFitHandler(value string) bool {
1495	values := []string{"fill", "contain", "cover", "none", "scale-down", "initial", "inherit"}
1496	splitVals := splitValues(value)
1497	return in(splitVals, values)
1498}
1499
1500func ObjectPositionHandler(value string) bool {
1501	values := []string{"initial", "inherit"}
1502	if in([]string{value}, values) {
1503		return true
1504	}
1505	splitVals := strings.Split(value, " ")
1506	if len(splitVals) > 2 {
1507		return false
1508	}
1509	usedFunctions := []func(string) bool{
1510		LengthHandler,
1511	}
1512	return recursiveCheck(splitVals, usedFunctions)
1513}
1514
1515func OpacityHandler(value string) bool {
1516	if Opacity.MatchString(value) {
1517		return true
1518	}
1519	values := []string{"initial", "inherit"}
1520	splitVals := splitValues(value)
1521	return in(splitVals, values)
1522}
1523
1524func OrderHandler(value string) bool {
1525	if Numeric.MatchString(value) {
1526		return true
1527	}
1528	values := []string{"initial", "inherit"}
1529	splitVals := splitValues(value)
1530	return in(splitVals, values)
1531}
1532
1533func OutlineHandler(value string) bool {
1534	values := []string{"initial", "inherit"}
1535	if in([]string{value}, values) {
1536		return true
1537	}
1538	splitVals := strings.Split(value, " ")
1539	usedFunctions := []func(string) bool{
1540		ColorHandler,
1541		OutlineWidthHandler,
1542		OutlineStyleHandler,
1543	}
1544	return recursiveCheck(splitVals, usedFunctions)
1545}
1546
1547func OutlineOffsetHandler(value string) bool {
1548	if LengthHandler(value) {
1549		return true
1550	}
1551	values := []string{"initial", "inherit"}
1552	splitVals := splitValues(value)
1553	return in(splitVals, values)
1554}
1555
1556func OutlineStyleHandler(value string) bool {
1557	values := []string{"none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "initial", "inherit"}
1558	splitVals := splitValues(value)
1559	return in(splitVals, values)
1560}
1561
1562func OutlineWidthHandler(value string) bool {
1563	if LengthHandler(value) {
1564		return true
1565	}
1566	values := []string{"medium", "thin", "thick", "initial", "inherit"}
1567	splitVals := splitValues(value)
1568	return in(splitVals, values)
1569}
1570
1571func OverflowHandler(value string) bool {
1572	values := []string{"visible", "hidden", "scroll", "auto", "initial", "inherit"}
1573	splitVals := splitValues(value)
1574	return in(splitVals, values)
1575}
1576
1577func OverflowXYHandler(value string) bool {
1578	values := []string{"visible", "hidden", "scroll", "auto", "initial", "inherit"}
1579	splitVals := splitValues(value)
1580	return in(splitVals, values)
1581}
1582
1583func OverflowWrapHandler(value string) bool {
1584	values := []string{"normal", "break-word", "anywhere"}
1585	splitVals := splitValues(value)
1586	return in(splitVals, values)
1587}
1588
1589func OrphansHandler(value string) bool {
1590	return Numeric.MatchString(value)
1591}
1592
1593func PaddingHandler(value string) bool {
1594	values := []string{"initial", "inherit"}
1595	if in([]string{value}, values) {
1596		return true
1597	}
1598	splitVals := strings.Split(value, " ")
1599	if len(splitVals) > 4 {
1600		return false
1601	}
1602	usedFunctions := []func(string) bool{
1603		PaddingSideHandler,
1604	}
1605	return recursiveCheck(splitVals, usedFunctions)
1606}
1607
1608func PaddingSideHandler(value string) bool {
1609	if LengthHandler(value) {
1610		return true
1611	}
1612	values := []string{"initial", "inherit"}
1613	splitVals := splitValues(value)
1614	return in(splitVals, values)
1615}
1616
1617func PageBreakBeforeAfterHandler(value string) bool {
1618	values := []string{"auto", "always", "avoid", "left", "right", "initial", "inherit"}
1619	splitVals := splitValues(value)
1620	return in(splitVals, values)
1621}
1622
1623func PageBreakInsideHandler(value string) bool {
1624	values := []string{"auto", "avoid", "initial", "inherit"}
1625	splitVals := splitValues(value)
1626	return in(splitVals, values)
1627}
1628
1629func PerspectiveHandler(value string) bool {
1630	if LengthHandler(value) {
1631		return true
1632	}
1633	values := []string{"none", "initial", "inherit"}
1634	splitVals := splitValues(value)
1635	return in(splitVals, values)
1636}
1637
1638func PerspectiveOriginHandler(value string) bool {
1639	values := []string{"initial", "inherit"}
1640	if in([]string{value}, values) {
1641		return true
1642	}
1643	splitVals := strings.Split(value, " ")
1644	xValues := []string{"left", "center", "right"}
1645	yValues := []string{"top", "center", "bottom"}
1646	if len(splitVals) > 1 {
1647		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
1648			return false
1649		}
1650		return in([]string{splitVals[1]}, yValues) || LengthHandler(splitVals[1])
1651	} else if len(splitVals) == 1 {
1652		return in(splitVals, xValues) || in(splitVals, yValues) || LengthHandler(splitVals[0])
1653	}
1654	return false
1655}
1656
1657func PointerEventsHandler(value string) bool {
1658	values := []string{"auto", "none", "initial", "inherit"}
1659	splitVals := splitValues(value)
1660	return in(splitVals, values)
1661}
1662
1663func PositionHandler(value string) bool {
1664	values := []string{"static", "absolute", "fixed", "relative", "sticky", "initial", "inherit"}
1665	splitVals := splitValues(value)
1666	return in(splitVals, values)
1667}
1668
1669func QuotesHandler(value string) bool {
1670	values := []string{"none", "initial", "inherit"}
1671	splitVals := splitValues(value)
1672	if in(splitVals, values) {
1673		return true
1674	}
1675	return Quotes.MatchString(value)
1676}
1677
1678func ResizeHandler(value string) bool {
1679	values := []string{"none", "both", "horizontal", "vertical", "initial", "inherit"}
1680	splitVals := splitValues(value)
1681	return in(splitVals, values)
1682}
1683
1684func ScrollBehaviorHandler(value string) bool {
1685	values := []string{"auto", "smooth", "initial", "inherit"}
1686	splitVals := splitValues(value)
1687	return in(splitVals, values)
1688}
1689
1690func TabSizeHandler(value string) bool {
1691	if LengthHandler(value) {
1692		return true
1693	}
1694	values := []string{"initial", "inherit"}
1695	splitVals := splitValues(value)
1696	return in(splitVals, values)
1697}
1698
1699func TableLayoutHandler(value string) bool {
1700	values := []string{"auto", "fixed", "initial", "inherit"}
1701	splitVals := splitValues(value)
1702	return in(splitVals, values)
1703}
1704
1705func TextAlignHandler(value string) bool {
1706	values := []string{"left", "right", "center", "justify", "initial", "inherit"}
1707	splitVals := splitValues(value)
1708	return in(splitVals, values)
1709}
1710
1711func TextAlignLastHandler(value string) bool {
1712	values := []string{"auto", "left", "right", "center", "justify", "start", "end", "initial", "inherit"}
1713	splitVals := splitValues(value)
1714	return in(splitVals, values)
1715}
1716
1717func TextCombineUprightHandler(value string) bool {
1718	values := []string{"none", "all"}
1719	splitVals := splitValues(value)
1720	if in(splitVals, values) {
1721		return true
1722	}
1723	return Digits.MatchString(value)
1724}
1725
1726func TextDecorationHandler(value string) bool {
1727	values := []string{"initial", "inherit"}
1728	if in([]string{value}, values) {
1729		return true
1730	}
1731	splitVals := strings.Split(value, " ")
1732	usedFunctions := []func(string) bool{
1733		TextDecorationStyleHandler,
1734		ColorHandler,
1735		TextDecorationLineHandler,
1736	}
1737	return recursiveCheck(splitVals, usedFunctions)
1738}
1739
1740func TextDecorationLineHandler(value string) bool {
1741	values := []string{"none", "underline", "overline", "line-through", "initial", "inherit"}
1742	splitVals := strings.Split(value, " ")
1743	return in(splitVals, values)
1744}
1745
1746func TextDecorationStyleHandler(value string) bool {
1747	values := []string{"solid", "double", "dotted", "dashed", "wavy", "initial", "inherit"}
1748	splitVals := splitValues(value)
1749	return in(splitVals, values)
1750}
1751
1752func TextIndentHandler(value string) bool {
1753	if LengthHandler(value) {
1754		return true
1755	}
1756	values := []string{"initial", "inherit"}
1757	splitVals := splitValues(value)
1758	return in(splitVals, values)
1759}
1760
1761func TextJustifyHandler(value string) bool {
1762	values := []string{"auto", "inter-word", "inter-character", "none", "initial", "inherit"}
1763	splitVals := splitValues(value)
1764	return in(splitVals, values)
1765}
1766
1767func TextOverflowHandler(value string) bool {
1768	if QuotedAlpha.MatchString(value) {
1769		return true
1770	}
1771	values := []string{"clip", "ellipsis", "initial", "inherit"}
1772	splitVals := splitValues(value)
1773	return in(splitVals, values)
1774}
1775
1776func TextOrientationHandler(value string) bool {
1777	values := []string{"mixed", "upright", "sideways", "sideways-right"}
1778	splitVals := splitValues(value)
1779	return in(splitVals, values)
1780}
1781
1782func TextShadowHandler(value string) bool {
1783	values := []string{"none", "initial", "inherit"}
1784	if in([]string{value}, values) {
1785		return true
1786	}
1787	commaSplitVals := strings.Split(value, ",")
1788	for _, val := range commaSplitVals {
1789		splitVals := strings.Split(val, " ")
1790		if len(splitVals) > 6 || len(splitVals) < 2 {
1791			return false
1792		}
1793		if !LengthHandler(splitVals[0]) {
1794			return false
1795		}
1796		if !LengthHandler(splitVals[1]) {
1797			return false
1798		}
1799		usedFunctions := []func(string) bool{
1800			LengthHandler,
1801			ColorHandler,
1802		}
1803		if len(splitVals) > 2 && !recursiveCheck(splitVals[2:], usedFunctions) {
1804			return false
1805		}
1806	}
1807	return true
1808}
1809
1810func TextTransformHandler(value string) bool {
1811	values := []string{"none", "capitalize", "uppercase", "lowercase", "initial", "inherit"}
1812	splitVals := splitValues(value)
1813	return in(splitVals, values)
1814}
1815
1816func TransformHandler(value string) bool {
1817	values := []string{"none", "initial", "inherit"}
1818	if in([]string{value}, values) {
1819		return true
1820	}
1821	if Matrix.MatchString(value) {
1822		return true
1823	}
1824	if Matrix3D.MatchString(value) {
1825		return true
1826	}
1827	subValue := string(TranslateScale.ReplaceAll([]byte(value), []byte{}))
1828	trimValue := strings.Split(strings.TrimSuffix(subValue, ")"), ",")
1829	valid := true
1830	for _, i := range trimValue {
1831		if !LengthHandler(strings.TrimSpace(i)) {
1832			valid = false
1833			break
1834		}
1835	}
1836	if valid && trimValue != nil {
1837		return true
1838	}
1839	if Rotate.MatchString(value) {
1840		return true
1841	}
1842	if Rotate3D.MatchString(value) {
1843		return true
1844	}
1845	subValue = string(Skew.ReplaceAll([]byte(value), []byte{}))
1846	subValue = strings.TrimSuffix(subValue, ")")
1847	trimValue = strings.Split(subValue, ",")
1848	valid = true
1849	for _, i := range trimValue {
1850		if !LengthHandler(strings.TrimSpace(i)) {
1851			valid = false
1852			break
1853		}
1854	}
1855	if valid {
1856		return true
1857	}
1858	subValue = string(Perspective.ReplaceAll([]byte(value), []byte{}))
1859	subValue = strings.TrimSuffix(subValue, ")")
1860	return LengthHandler(subValue)
1861}
1862
1863func TransformOriginHandler(value string) bool {
1864	values := []string{"initial", "inherit"}
1865	if in([]string{value}, values) {
1866		return true
1867	}
1868	splitVals := strings.Split(value, " ")
1869	xValues := []string{"left", "center", "right"}
1870	yValues := []string{"top", "center", "bottom"}
1871	if len(splitVals) > 2 {
1872		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
1873			return false
1874		}
1875		if !in([]string{splitVals[1]}, yValues) && !LengthHandler(splitVals[1]) {
1876			return false
1877		}
1878		return LengthHandler(splitVals[2])
1879	} else if len(splitVals) > 1 {
1880		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
1881			return false
1882		}
1883		return in([]string{splitVals[1]}, yValues) || LengthHandler(splitVals[1])
1884	} else if len(splitVals) == 1 {
1885		return in(splitVals, xValues) || in(splitVals, yValues) || LengthHandler(splitVals[0])
1886	}
1887	return false
1888}
1889
1890func TransformStyleHandler(value string) bool {
1891	values := []string{"flat", "preserve-3d", "initial", "inherit"}
1892	splitVals := splitValues(value)
1893	return in(splitVals, values)
1894}
1895
1896func TransitionHandler(value string) bool {
1897	values := []string{"initial", "inherit"}
1898	if in([]string{value}, values) {
1899		return true
1900	}
1901	splitVals := strings.Split(value, " ")
1902	usedFunctions := []func(string) bool{
1903		TransitionPropertyHandler,
1904		TransitionDurationHandler,
1905		TimingFunctionHandler,
1906		TransitionDelayHandler,
1907		ColorHandler,
1908	}
1909	return recursiveCheck(splitVals, usedFunctions)
1910}
1911
1912func TransitionDelayHandler(value string) bool {
1913	if Time.MatchString(value) {
1914		return true
1915	}
1916	values := []string{"initial", "inherit"}
1917	splitVals := splitValues(value)
1918	return in(splitVals, values)
1919}
1920
1921func TransitionDurationHandler(value string) bool {
1922	if Time.MatchString(value) {
1923		return true
1924	}
1925	values := []string{"initial", "inherit"}
1926	splitVals := splitValues(value)
1927	return in(splitVals, values)
1928}
1929
1930func TransitionPropertyHandler(value string) bool {
1931	if TransitionProp.MatchString(value) {
1932		return true
1933	}
1934	values := []string{"none", "all", "initial", "inherit"}
1935	splitVals := splitValues(value)
1936	return in(splitVals, values)
1937}
1938
1939func UnicodeBidiHandler(value string) bool {
1940	values := []string{"normal", "embed", "bidi-override", "isolate", "isolate-override", "plaintext", "initial", "inherit"}
1941	splitVals := splitValues(value)
1942	return in(splitVals, values)
1943}
1944
1945func UserSelectHandler(value string) bool {
1946	values := []string{"auto", "none", "text", "all"}
1947	splitVals := splitValues(value)
1948	return in(splitVals, values)
1949}
1950
1951func VerticalAlignHandler(value string) bool {
1952	if LengthHandler(value) {
1953		return true
1954	}
1955	values := []string{"baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "initial", "inherit"}
1956	splitVals := splitValues(value)
1957	return in(splitVals, values)
1958}
1959
1960func VisiblityHandler(value string) bool {
1961	values := []string{"visible", "hidden", "collapse", "initial", "inherit"}
1962	splitVals := splitValues(value)
1963	return in(splitVals, values)
1964}
1965
1966func WhiteSpaceHandler(value string) bool {
1967	values := []string{"normal", "nowrap", "pre", "pre-line", "pre-wrap", "initial", "inherit"}
1968	splitVals := splitValues(value)
1969	return in(splitVals, values)
1970}
1971
1972func WidthHandler(value string) bool {
1973	if LengthHandler(value) {
1974		return true
1975	}
1976	values := []string{"auto", "initial", "inherit"}
1977	splitVals := splitValues(value)
1978	return in(splitVals, values)
1979}
1980
1981func WordSpacingHandler(value string) bool {
1982	if LengthHandler(value) {
1983		return true
1984	}
1985	values := []string{"normal", "initial", "inherit"}
1986	splitVals := splitValues(value)
1987	return in(splitVals, values)
1988}
1989
1990func WordBreakHandler(value string) bool {
1991	values := []string{"normal", "break-all", "keep-all", "break-word", "initial", "inherit"}
1992	splitVals := splitValues(value)
1993	return in(splitVals, values)
1994}
1995
1996func WordWrapHandler(value string) bool {
1997	values := []string{"normal", "break-word", "initial", "inherit"}
1998	splitVals := splitValues(value)
1999	return in(splitVals, values)
2000}
2001
2002func WritingModeHandler(value string) bool {
2003	values := []string{"horizontal-tb", "vertical-rl", "vertical-lr"}
2004	splitVals := splitValues(value)
2005	return in(splitVals, values)
2006}
2007
2008func ZIndexHandler(value string) bool {
2009	if ZIndex.MatchString(value) {
2010		return true
2011	}
2012	values := []string{"auto", "initial", "inherit"}
2013	splitVals := splitValues(value)
2014	return in(splitVals, values)
2015}