home readme diff tree note docs

0commit 689c6fbd155277103d82d2f4a2a1ce052445d639
1Author: lakefox <mason@lakefox.net>
2Date:   Sun Feb 15 14:48:30 2026 -0700
3
4    Parser complete
5
6diff --git a/Makefile b/Makefile
7index 64a7691..93c0468 100755
8--- a/Makefile
9+++ b/Makefile
10@@ -16,9 +16,28 @@ main: main.c build/grim.o build/parser.o
11 build/grim.o: src/grim.c include/grim.h | build
12 	${CC} ${CCFLAGS} -Iinclude/ -c src/grim.c -o build/grim.o
13 
14-build/parser.o: src/parser.c include/parser.h | build
15+build/parser.o: src/parser.c include/parser.h build/colors.o build/match.o build/functions.o | build
16 	${CC} ${CCFLAGS} -Iinclude/ -c src/parser.c -o build/parser.o
17 
18+# --- Gperf ---
19+build/colors.c: maps/colors.gperf
20+	gperf maps/colors.gperf > build/colors.c
21+
22+build/match.c: maps/match.gperf
23+	gperf maps/match.gperf > build/match.c
24+
25+build/functions.c: maps/functions.gperf
26+	gperf maps/functions.gperf > build/functions.c
27+
28+build/colors.o: build/colors.c include/grim.h | build
29+	${CC} ${CCFLAGS} -Iinclude/ -c build/colors.c -o build/colors.o
30+
31+build/match.o: build/match.c include/grim.h | build
32+	${CC} ${CCFLAGS} -Iinclude/ -c build/match.c -o build/match.o
33+
34+build/functions.o: build/functions.c include/grim.h | build
35+	${CC} ${CCFLAGS} -Iinclude/ -c build/functions.c -o build/functions.o
36+
37 # --- Tests ---
38 
39 TEST_BINARIES = build/html_node_test build/css_selector_test \
40@@ -59,4 +78,4 @@ build/html_parser_playground: playground/html_parser.c build/grim.o build/parser
41 # --- Tools ---
42 
43 clean:
44-	rm -f main build/*.o
45+	rm -f main build/*.o build/*.c
46diff --git a/include/grim.h b/include/grim.h
47index 24481f4..35fc1cf 100755
48--- a/include/grim.h
49+++ b/include/grim.h
50@@ -11,7 +11,6 @@
51 #define MAX_ATTRS 16
52 #define MAX_SYMBOLS 4096
53 
54-/*
55 typedef enum {
56 	// Color
57 		TEST, HEX, 
58@@ -99,7 +98,7 @@ typedef enum {
59 
60 		// Transform Functions
61 		MATRIX, MATRIX3D, PERSPECTIVE, ROTATE, ROTATE3D, ROTATEX, ROTATEY, ROTATEZ, 
62-		SCALE, SCALE3D, SCALEX, SCALEY, SCALEZ, TRANSLATE, TRANSLATE3D, TRANSLATEX,
63+		SCALE, SCALE3D, SCALEX, SCALEY, SCALEZ, TRANSLATE, TRANSLATE3D, TRANSLATEX,
64 		TRANSLATEY, TRANSLATEZ, SKEW, SKEWX, SKEWY,
65 
66 		RGB, RGBA, HSL,
67@@ -109,80 +108,12 @@ typedef enum {
68 	NON_FUNC_PADDING
69 } UnitType;
70 
71-typedef enum {
72-	ACCENT_COLOR, ALIGN_CONTENT, ALIGN_ITEMS, ALIGN_SELF, ALIGNMENT_BASELINE, ALL, ANCHOR_NAME, ANIMATION_COMPOSITION, ANIMATION_DELAY,
73-	ANIMATION_DIRECTION, ANIMATION_DURATION, ANIMATION_FILL_MODE, ANIMATION_ITERATION_COUNT, ANIMATION_NAME, ANIMATION_PLAY_STATE, ANIMATION_RANGE_END,
74-	ANIMATION_RANGE_START, ANIMATION_RANGE, ANIMATION_TIMELINE, ANIMATION_TIMING_FUNCTION, ANIMATION, APPEARANCE, ASPECT_RATIO,
75-	BACKDROP_FILTER, BACKFACE_VISIBILITY, BACKGROUND_ATTACHMENT, BACKGROUND_BLEND_MODE, BACKGROUND_CLIP, BACKGROUND_COLOR, BACKGROUND_IMAGE,
76-	BACKGROUND_ORIGIN, BACKGROUND_POSITION_X, BACKGROUND_POSITION_Y, BACKGROUND_POSITION, BACKGROUND_REPEAT, BACKGROUND_SIZE, BACKGROUND,
77-	BLOCK_SIZE, BORDER_BLOCK_COLOR, BORDER_BLOCK_END_COLOR, BORDER_BLOCK_END_STYLE, BORDER_BLOCK_END_WIDTH, BORDER_BLOCK_END,
78-	BORDER_BLOCK_START_COLOR, BORDER_BLOCK_START_STYLE, BORDER_BLOCK_START_WIDTH, BORDER_BLOCK_START, BORDER_BLOCK_STYLE, BORDER_BLOCK_WIDTH,
79-	BORDER_BLOCK, BORDER_BOTTOM_COLOR, BORDER_BOTTOM_LEFT_RADIUS, BORDER_BOTTOM_RIGHT_RADIUS, BORDER_BOTTOM_STYLE, BORDER_BOTTOM_WIDTH,
80-	BORDER_BOTTOM, BORDER_COLLAPSE, BORDER_COLOR, BORDER_END_END_RADIUS, BORDER_END_START_RADIUS, BORDER_IMAGE_OUTSET, BORDER_IMAGE_REPEAT,
81-	BORDER_IMAGE_SLICE, BORDER_IMAGE_SOURCE, BORDER_IMAGE_WIDTH, BORDER_IMAGE, BORDER_INLINE_COLOR, BORDER_INLINE_END_COLOR, BORDER_INLINE_END_STYLE,
82-	BORDER_INLINE_END_WIDTH, BORDER_INLINE_END, BORDER_INLINE_START_COLOR, BORDER_INLINE_START_STYLE, BORDER_INLINE_START_WIDTH, BORDER_INLINE_START,
83-	BORDER_INLINE_STYLE, BORDER_INLINE_WIDTH, BORDER_INLINE, BORDER_LEFT_COLOR, BORDER_LEFT_STYLE, BORDER_LEFT_WIDTH, BORDER_LEFT, BORDER_RADIUS,
84-	BORDER_RIGHT_COLOR, BORDER_RIGHT_STYLE, BORDER_RIGHT_WIDTH, BORDER_RIGHT, BORDER_SPACING, BORDER_START_END_RADIUS, BORDER_START_START_RADIUS,
85-	BORDER_STYLE, BORDER_TOP_COLOR, BORDER_TOP_LEFT_RADIUS, BORDER_TOP_RIGHT_RADIUS, BORDER_TOP_STYLE, BORDER_TOP_WIDTH, BORDER_TOP, BORDER_WIDTH,
86-	BORDER, BOTTOM, BOX_ALIGN, BOX_DECORATION_BREAK, BOX_DIRECTION, BOX_FLEX_GROUP, BOX_FLEX, BOX_LINES, BOX_ORDINAL_GROUP, BOX_ORIENT, BOX_PACK,
87-	BOX_SHADOW, BOX_SIZING, BREAK_AFTER, BREAK_BEFORE, BREAK_INSIDE,
88-	CAPTION_SIDE, CARET_COLOR, CLEAR, CLIP_PATH, CLIP_RULE, CLIP, COLOR_INTERPOLATION_FILTERS, COLOR_INTERPOLATION, COLOR_SCHEME, COLOR, COLUMN_COUNT,
89-	COLUMN_FILL, COLUMN_GAP, COLUMN_RULE_COLOR, COLUMN_RULE_STYLE, COLUMN_RULE_WIDTH, COLUMN_RULE, COLUMN_SPAN, COLUMN_WIDTH, COLUMNS,
90-	CONTAIN_INTRINSIC_BLOCK_SIZE, CONTAIN_INTRINSIC_HEIGHT, CONTAIN_INTRINSIC_INLINE_SIZE, CONTAIN_INTRINSIC_SIZE, CONTAIN_INTRINSIC_WIDTH,
91-	CONTAIN, CONTAINER_NAME, CONTAINER_TYPE, CONTAINER, CONTENT_VISIBILITY, CONTENT, COUNTER_INCREMENT, COUNTER_RESET, COUNTER_SET, CURSOR,
92-	CX, CY,
93-	D, DIRECTION, DISPLAY, DOMINANT_BASELINE,
94-	EMPTY_CELLS,
95-	FIELD_SIZING, FILL_OPACITY, FILL_RULE, FILL, FILTER, FLEX_BASIS, FLEX_DIRECTION, FLEX_FLOW, FLEX_GROW, FLEX_SHRINK, FLEX_WRAP, FLEX,
96-	FLOAT, FLOOD_COLOR, FLOOD_OPACITY, FONT_FAMILY, FONT_FEATURE_SETTINGS, FONT_KERNING, FONT_LANGUAGE_OVERRIDE, FONT_OPTICAL_SIZING, FONT_PALETTE,
97-	FONT_SIZE_ADJUST, FONT_SIZE, FONT_SMOOTH, FONT_STRETCH, FONT_STYLE, FONT_SYNTHESIS_POSITION, FONT_SYNTHESIS_SMALL_CAPS, FONT_SYNTHESIS_STYLE,
98-	FONT_SYNTHESIS_WEIGHT, FONT_SYNTHESIS, FONT_VARIANT_ALTERNATES, FONT_VARIANT_CAPS, FONT_VARIANT_EAST_ASIAN, FONT_VARIANT_EMOJI, FONT_VARIANT_LIGATURES,
99-	FONT_VARIANT_NUMERIC, FONT_VARIANT_POSITION, FONT_VARIANT, FONT_VARIATION_SETTINGS, FONT_WEIGHT, FONT, FORCED_COLOR_ADJUST,
100-	GAP, GRID_AREA, GRID_AUTO_COLUMNS, GRID_AUTO_FLOW, GRID_AUTO_ROWS, GRID_COLUMN_END, GRID_COLUMN_START, GRID_COLUMN, GRID_ROW_END, GRID_ROW_START,
101-	GRID_ROW, GRID_TEMPLATE_AREAS, GRID_TEMPLATE_COLUMNS, GRID_TEMPLATE_ROWS, GRID_TEMPLATE, GRID,
102-	HANGING_PUNCTUATION, HEIGHT, HYPHENATE_CHARACTER, HYPHENATE_LIMIT_CHARS, HYPHENS,
103-	IMAGE_ORIENTATION, IMAGE_RENDERING, IMAGE_RESOLUTION, INITIAL_LETTER, INLINE_SIZE, INSET_BLOCK_START, INSET_BLOCK_END, INSET_BLOCK, 
104-	INSET_INLINE_END, INSET_INLINE_START, INSET_INLINE, INSET, INTERPOLATE_SIZE, ISOLATION,
105-	JUSTIFY_CONTENT, JUSTIFY_ITEMS, JUSTIFY_SELF,
106-	LEFT, LETTER_SPACING, LIGHTING_COLOR, LINE_BREAK, LINE_CLAMP, LINE_HEIGHT_STEP, LINE_HEIGHT, LIST_STYLE_IMAGE, LIST_STYLE_POSITION, LIST_STYLE_TYPE,
107-	LIST_STYLE,
108-	MARGIN_BLOCK_END, MARGIN_BLOCK_START, MARGIN_BLOCK, MARGIN_BOTTOM, MARGIN_INLINE_END, MARGIN_INLINE_START, MARGIN_INLINE, MARGIN_LEFT, MARGIN_RIGHT,
109-	MARGIN_TOP, MARGIN_TRIM, MARGIN, MARKER_END, MARKER_MID, MARKER_START, MARKER, MASK_BORDER_MODE, MASK_BORDER_OUTSET, MASK_BORDER_REPEAT, MASK_BORDER_SLICE,
110-	MASK_BORDER_SOURCE, MASK_BORDER_WIDTH, MASK_BORDER, MASK_CLIP, MASK_COMPOSITE, MASK_IMAGE, MASK_MODE, MASK_ORIGIN, MASK_POSITION, MASK_REPEAT,
111-	MASK_SIZE, MASK_TYPE, MASK, MATH_DEPTH, MATH_SHIFT, MATH_STYLE, MAX_BLOCK_SIZE, MAX_HEIGHT, MAX_INLINE_SIZE, MAX_WIDTH, MIN_BLOCK_SIZE,
112-	MIN_HEIGHT, MIN_INLINE_SIZE, MIN_WIDTH, MIX_BLEND_MODE,
113-	OBJECT_FIT, OBJECT_POSITION, OFFSET_ANCHOR, OFFSET_DISTANCE, OFFSET_PATH, OFFSET_POSITION, OFFSET_ROTATE, OFFSET, OPACITY, ORDER, ORPHANS,
114-	OUTLINE_COLOR, OUTLINE_OFFSET, OUTLINE_STYLE, OUTLINE_WIDTH, OUTLINE, OVERFLOW_ANCHOR, OVERFLOW_BLOCK, OVERFLOW_CLIP_MARGIN, OVERFLOW_INLINE,
115-	OVERFLOW_WRAP, OVERFLOW_X, OVERFLOW_Y, OVERFLOW, OVERLAY, OVERSCROLL_BEHAVIOR_BLOCK, OVERSCROLL_BEHAVIOR_INLINE, OVERSCROLL_BEHAVIOR_X,
116-	OVERSCROLL_BEHAVIOR_Y, OVERSCROLL_BEHAVIOR,
117-	PADDING_BLOCK_END, PADDING_BLOCK_START, PADDING_BLOCK, PADDING_BOTTOM, PADDING_INLINE_END, PADDING_INLINE_START, PADDING_INLINE, PADDING_LEFT,
118-	PADDING_RIGHT, PADDING_TOP, PADDING, PAGE_BREAK_AFTER, PAGE_BREAK_BEFORE, PAGE_BREAK_INSIDE, PAGE, PAINT_ORDER, PERSPECTIVE_ORIGIN, PERSPECTIVE,
119-	PLACE_CONTENT, PLACE_ITEMS, PLACE_SELF, POINTER_EVENTS, POSITION_ANCHOR, POSITION_AREA, POSITION_TRY_FALLBACKS, POSITION_TRY_ORDER, POSITION_TRY,
120-	POSITION_VISIBILITY, POSITION, PRINT_COLOR_ADJUST,
121-	QUOTES,
122-	R, READING_FLOW, READING_ORDER, RESIZE, RIGHT, ROTATE, ROW_GAP, RUBY_ALIGN, RUBY_POSITION, RX, RY,
123-	SCALE, SCROLL_BEHAVIOR, SCROLL_MARGIN_BLOCK_END, SCROLL_MARGIN_BLOCK_START, SCROLL_MARGIN_BLOCK, SCROLL_MARGIN_BOTTOM, SCROLL_MARGIN_INLINE_END,
124-	SCROLL_MARGIN_INLINE_START, SCROLL_MARGIN_INLINE, SCROLL_MARGIN_LEFT, SCROLL_MARGIN_RIGHT, SCROLL_MARGIN_TOP, SCROLL_MARGIN, SCROLL_MARKER_GROUP,
125-	SCROLL_PADDING_BLOCK_END, SCROLL_PADDING_BLOCK_START, SCROLL_PADDING_BLOCK, SCROLL_PADDING_BOTTOM, SCROLL_PADDING_INLINE_END, SCROLL_PADDING_INLINE_START,
126-	SCROLL_PADDING_INLINE, SCROLL_PADDING_LEFT, SCROLL_PADDING_RIGHT, SCROLL_PADDING_TOP, SCROLL_PADDING, SCROLL_SNAP_ALIGN, SCROLL_SNAP_STOP, SCROLL_SNAP_TYPE,
127-	SCROLL_TIMELINE_AXIS, SCROLL_TIMELINE_NAME, SCROLL_TIMELINE, SCROLLBAR_COLOR, SCROLLBAR_GUTTER, SCROLLBAR_WIDTH, SHAPE_IMAGE_THRESHOLD, SHAPE_MARGIN,
128-	SHAPE_OUTSIDE, SHAPE_RENDERING, SPEAK_AS, STOP_COLOR, STOP_OPACITY, STROKE_DASHARRAY, STROKE_DASHOFFSET, STROKE_LINECAP, STROKE_LINEJOIN, STROKE_MITERLIMIT,
129-	STROKE_OPACITY, STROKE_WIDTH, STROKE,
130-	TAB_SIZE, TABLE_LAYOUT, TEXT_ALIGN_LAST, TEXT_ALIGN, TEXT_ANCHOR, TEXT_BOX_EDGE, TEXT_BOX_TRIM, TEXT_BOX, TEXT_COMBINE_UPRIGHT, TEXT_DECORATION_COLOR,
131-	TEXT_DECORATION_LINE, TEXT_DECORATION_SKIP_INK, TEXT_DECORATION_SKIP, TEXT_DECORATION_STYLE, TEXT_DECORATION_THICKNESS, TEXT_DECORATION, TEXT_EMPHASIS_COLOR,
132-	TEXT_EMPHASIS_POSITION, TEXT_EMPHASIS_STYLE, TEXT_EMPHASIS, TEXT_INDENT, TEXT_JUSTIFY, TEXT_ORIENTATION, TEXT_OVERFLOW, TEXT_RENDERING, TEXT_SHADOW,
133-	TEXT_SIZE_ADJUST, TEXT_SPACING_TRIM, TEXT_TRANSFORM, TEXT_UNDERLINE_OFFSET, TEXT_UNDERLINE_POSITION, TEXT_WRAP_MODE, TEXT_WRAP_STYLE, TEXT_WRAP,
134-	TIMELINE_SCOPE, TOP, TOUCH_ACTION, TRANSFORM_BOX, TRANSFORM_ORIGIN, TRANSFORM_STYLE, TRANSFORM, TRANSITION_BEHAVIOR, TRANSITION_DELAY, TRANSITION_DURATION,
135-	TRANSITION_PROPERTY, TRANSITION_TIMING_FUNCTION, TRANSITION, TRANSLATE,
136-	UNICODE_BIDI, USER_MODIFY, USER_SELECT,
137-	VECTOR_EFFECT, VERTICAL_ALIGN, VIEW_TIMELINE_AXIS, VIEW_TIMELINE_INSET, VIEW_TIMELINE_NAME, VIEW_TIMELINE, VIEW_TRANSITION_CLASS, VIEW_TRANSITION_NAME,
138-	VISIBILITY,
139-	WHITE_SPACE_COLLAPSE, WHITE_SPACE, WIDOWS, WIDTH, WILL_CHANGE, WORD_BREAK, WORD_SPACING, WRITING_MODE,
140-	X,
141-	Y,
142-	Z_INDEX, ZOOM
143-} KeyType;
144+struct Unit {
145+	UnitType type;
146+	float value;
147+};
148 
149+/*
150 typedef enum {
151 	All,
152 	Print,
153@@ -203,12 +134,6 @@ typedef enum {
154 	Slow
155 } Media;
156 
157-// 8 bytes 
158-struct Unit {
159-	UnitType type; // short
160-	float value;
161-};
162-
163 struct Range {
164 	size_t start;
165 	size_t end;
166diff --git a/maps/colors.gperf b/maps/colors.gperf
167new file mode 100644
168index 0000000..3a61a28
169--- /dev/null
170+++ b/maps/colors.gperf
171@@ -0,0 +1,166 @@
172+%{
173+#include <string.h>
174+%}
175+struct ColorMap {
176+    char *name;
177+    unsigned int hex;
178+};
179+%language=ANSI-C
180+%define lookup-function-name find_color
181+%define hash-function-name hash_color
182+%struct-type
183+%readonly-tables
184+%compare-strncmp
185+%ignore-case
186+
187+%%
188+aliceblue, 0xf0f8ff
189+antiquewhite, 0xfaebd7
190+aqua, 0x00ffff
191+aquamarine, 0x7fffd4
192+azure, 0xf0ffff
193+beige, 0xf5f5dc
194+bisque, 0xffe4c4
195+black, 0x000000
196+blanchedalmond, 0xffebcd
197+blue, 0x0000ff
198+blueviolet, 0x8a2be2
199+brown, 0xa52a2a
200+burlywood, 0xdeb887
201+cadetblue, 0x5f9ea0
202+chartreuse, 0x7fff00
203+chocolate, 0xd2691e
204+coral, 0xff7f50
205+cornflowerblue, 0x6495ed
206+cornsilk, 0xfff8dc
207+crimson, 0xdc143c
208+cyan, 0x00ffff
209+darkblue, 0x00008b
210+darkcyan, 0x008b8b
211+darkgoldenrod, 0xb8860b
212+darkgray, 0xa9a9a9
213+darkgreen, 0x006400
214+darkgrey, 0xa9a9a9
215+darkkhaki, 0xbdb76b
216+darkmagenta, 0x8b008b
217+darkolivegreen, 0x556b2f
218+darkorange, 0xff8c00
219+darkorchid, 0x9932cc
220+darkred, 0x8b0000
221+darksalmon, 0xe9967a
222+darkseagreen, 0x8fbc8f
223+darkslateblue, 0x483d8b
224+darkslategray, 0x2f4f4f
225+darkslategrey, 0x2f4f4f
226+darkturquoise, 0x00ced1
227+darkviolet, 0x9400d3
228+deeppink, 0xff1493
229+deepskyblue, 0x00bfff
230+dimgray, 0x696969
231+dimgrey, 0x696969
232+dodgerblue, 0x1e90ff
233+firebrick, 0xb22222
234+floralwhite, 0xfffaf0
235+forestgreen, 0x228b22
236+fuchsia, 0xff00ff
237+gainsboro, 0xdcdcdc
238+ghostwhite, 0xf8f8ff
239+gold, 0xffd700
240+goldenrod, 0xdaa520
241+gray, 0x808080
242+green, 0x008000
243+greenyellow, 0xadff2f
244+grey, 0x808080
245+honeydew, 0xf0fff0
246+hotpink, 0xff69b4
247+indianred, 0xcd5c5c
248+indigo, 0x4b0082
249+ivory, 0xfffff0
250+khaki, 0xf0e68c
251+lavender, 0xe6e6fa
252+lavenderblush, 0xfff0f5
253+lawngreen, 0x7cfc00
254+lemonchiffon, 0xfffacd
255+lightblue, 0xadd8e6
256+lightcoral, 0xf08080
257+lightcyan, 0xe0ffff
258+lightgoldenrodyellow, 0xfafad2
259+lightgray, 0xd3d3d3
260+lightgreen, 0x90ee90
261+lightgrey, 0xd3d3d3
262+lightpink, 0xffb6c1
263+lightsalmon, 0xffa07a
264+lightseagreen, 0x20b2aa
265+lightskyblue, 0x87cefa
266+lightslategray, 0x778899
267+lightslategrey, 0x778899
268+lightsteelblue, 0xb0c4de
269+lightyellow, 0xffffe0
270+lime, 0x00ff00
271+limegreen, 0x32cd32
272+linen, 0xfaf0e6
273+magenta, 0xff00ff
274+maroon, 0x800000
275+mediumaquamarine, 0x66cdaa
276+mediumblue, 0x0000cd
277+mediumorchid, 0xba55d3
278+mediumpurple, 0x9370db
279+mediumseagreen, 0x3cb371
280+mediumslateblue, 0x7b68ee
281+mediumspringgreen, 0x00fa9a
282+mediumturquoise, 0x48d1cc
283+mediumvioletred, 0xc71585
284+midnightblue, 0x191970
285+mintcream, 0xf5fffa
286+mistyrose, 0xffe4e1
287+moccasin, 0xffe4b5
288+navajowhite, 0xffdead
289+navy, 0x000080
290+oldlace, 0xfdf5e6
291+olive, 0x808000
292+olivedrab, 0x6b8e23
293+orange, 0xffa500
294+orangered, 0xff4500
295+orchid, 0xda70d6
296+palegoldenrod, 0xeee8aa
297+palegreen, 0x98fb98
298+paleturquoise, 0xafeeee
299+palevioletred, 0xdb7093
300+papayawhip, 0xffefd5
301+peachpuff, 0xffdab9
302+peru, 0xcd853f
303+pink, 0xffc0cb
304+plum, 0xdda0dd
305+powderblue, 0xb0e0e6
306+purple, 0x800080
307+rebeccapurple, 0x663399
308+red, 0xff0000
309+rosybrown, 0xbc8f8f
310+royalblue, 0x4169e1
311+saddlebrown, 0x8b4513
312+salmon, 0xfa8072
313+sandybrown, 0xf4a460
314+seagreen, 0x2e8b57
315+seashell, 0xfff5ee
316+sienna, 0xa0522d
317+silver, 0xc0c0c0
318+skyblue, 0x87ceeb
319+slateblue, 0x6a5acd
320+slategray, 0x708090
321+slategrey, 0x708090
322+snow, 0xfffafa
323+springgreen, 0x00ff7f
324+steelblue, 0x4682b4
325+tan, 0xd2b48c
326+teal, 0x008080
327+thistle, 0xd8bfd8
328+tomato, 0xff6347
329+transparent, 0x00000000
330+turquoise, 0x40e0d0
331+violet, 0xee82ee
332+wheat, 0xf5deb3
333+white, 0xffffff
334+whitesmoke, 0xf5f5f5
335+yellow, 0xffff00
336+yellowgreen, 0x9acd32
337+%%
338diff --git a/maps/functions.gperf b/maps/functions.gperf
339new file mode 100644
340index 0000000..4fd0710
341--- /dev/null
342+++ b/maps/functions.gperf
343@@ -0,0 +1,96 @@
344+%{
345+#include <string.h>
346+#include "../include/grim.h" 
347+%}
348+struct FuncMap {
349+    char *name;
350+    UnitType type;
351+};
352+%language=ANSI-C
353+%define lookup-function-name find_func
354+%define hash-function-name hash_func
355+%struct-type
356+%readonly-tables
357+%compare-strncmp
358+%ignore-case
359+
360+%%
361+calc, CALC
362+min, MIN
363+max, MAX
364+clamp, CLAMP
365+round, ROUND
366+mod, MOD
367+progress, PROGRESS
368+rem, REMD
369+pow, POW
370+sqrt, SQRT
371+set, SET
372+let, LET
373+hypot, HYPOT
374+log, LOG
375+exp, EXP
376+abs, ABS
377+sin, SIN
378+cos, COS
379+tan, TAN
380+asin, ASIN
381+acos, ACOS
382+atan, ATAN
383+atan2, ATAN2
384+sign, SIGN
385+var, VAR_FUNC
386+rgb, RGB
387+rgba, RGBA
388+hsl, HSL
389+linear, LINEAR_EASING_FUNCTION
390+cubic-bezier, CUBIC_BEZIER_FUNCTION
391+steps, STEPS_FUNCTION
392+blur, BLUR
393+brightness, BRIGHTNESS
394+contrast, CONTRAST
395+drop-shadow, DROP_SHADOW
396+grayscale, GRAYSCALE
397+hue-rotate, HUE_ROTATE
398+invert, INVERT
399+opacity, OPACITY
400+sepia, SEPIA
401+saturate, SATURATE
402+image, IMAGE
403+image-set, IMAGE_SET
404+cross-fade, CROSS_FADE
405+element, ELEMENT
406+gradient, GRADIENT
407+matrix, MATRIX
408+matrix3d, MATRIX3D
409+perspective, PERSPECTIVE
410+rotate, ROTATE
411+rotate3d, ROTATE3D
412+rotateX, ROTATEX
413+rotateY, ROTATEY
414+rotateZ, ROTATEZ
415+scale, SCALE
416+scale3d, SCALE3D
417+scaleX, SCALEX
418+scaleY, SCALEY
419+scaleZ, SCALEZ
420+translate, TRANSLATE
421+translate3d, TRANSLATE3D
422+translateX, TRANSLATEX
423+translateY, TRANSLATEY
424+translateZ, TRANSLATEZ
425+skew, SKEW
426+skewX, SKEWX
427+skewY, SKEWY
428+url, URL
429+attr, ATTR
430+type, TYPE
431+env, ENV
432+if, IF
433+print, PRINT
434+list, LIST
435+at, AT
436+empty, EMPTY
437+insert, INSERT
438+size, SIZE
439+%%
440diff --git a/maps/match.gperf b/maps/match.gperf
441new file mode 100644
442index 0000000..bbb5494
443--- /dev/null
444+++ b/maps/match.gperf
445@@ -0,0 +1,149 @@
446+%{
447+#include <string.h>
448+#include "../include/grim.h"
449+%}
450+struct MatchMap {
451+    char *name;
452+    UnitType type;
453+};
454+%language=ANSI-C
455+%define lookup-function-name find_match
456+%define hash-function-name hash_match
457+%struct-type
458+%readonly-tables
459+%compare-strncmp
460+%ignore-case
461+
462+%%
463+"+", ADD
464+"-", SUB
465+"*", MULT
466+"/", DIV
467+"==", EQ
468+">", GT
469+"<", LT
470+">=", GE
471+"<=", LE
472+and, AND
473+"&&", AND
474+or, OR
475+"||", OR
476+not, NOT
477+"!=", NOT
478+only, ONLY
479+else, ELSE
480+infinity, INF
481+-infinity, NEGINF
482+NaN, NaN
483+e, E
484+pi, PI
485+content-box, CONTENT
486+padding-box, PADDING
487+border-box, BORDER
488+margin-box, MARGIN
489+fill-box, FILL
490+stroke-box, STROKE
491+view-box, VIEW
492+space-between, BETWEEN
493+space-around, AROUND
494+space-evenly, EVENLY
495+stretch, STRETCH
496+normal, NORMAL
497+contents, CONTENTS
498+none, NONE
499+flow, FLOW
500+flow-root, FLOW_ROOT
501+table, TABLE
502+flex, FLEX
503+grid, GRID
504+ruby, RUBY
505+table-row-group, TABLE_ROW_GROUP
506+table-header-group, TABLE_HEADER_GROUP
507+table-footer-group, TABLE_FOOTER_GROUP
508+table-column-group, TABLE_COLUMN_GROUP
509+table-row, TABLE_ROW
510+table-cell, TABLE_CELL
511+table-column, TABLE_COLUMN
512+table-caption, TABLE_CAPTION
513+ruby-base, RUBY_BASE
514+ruby-text, RUBY_TEXT
515+ruby-base-container, RUBY_BASE_CONTAINER
516+ruby-text-container, RUBY_TEXT_CONTAINER
517+inline-block, INLINE_BLOCK
518+inline-table, INLINE_TABLE
519+inline-flex, INLINE_FLEX
520+inline-grid, INLINE_GRID
521+list-item, LISTITEM
522+block, BLOCK
523+inline, INLINE
524+run-in, RUN_IN
525+linear, LINEAR
526+ease, EASE
527+ease-in, EASE_IN
528+ease-out, EASE_OUT
529+ease-in-out, EASE_IN_OUT
530+step-start, STEP_START
531+step-end, STEP_END
532+jump-start, JUMP_START
533+jump-end, JUMP_END
534+jump-none, JUMP_NONE
535+jump-both, JUMP_BOTH
536+serif, SERIF
537+sans-serif, SANS_SERIF
538+monospace, MONOSPACE
539+cursive, CURSIVE
540+fantasy, FANTASY
541+system-ui, SYSTEM_UI
542+ui-serif, UI_SERIF
543+ui-sans-serif, UI_SANS_SERIF
544+ui-monospace, UI_MONOSPACE
545+ui-rounded, UI_ROUNDED
546+math, MATH
547+fangsong, FANGSONG
548+top, TOP
549+left, LEFT
550+bottom, BOTTOM
551+right, RIGHT
552+center, CENTER
553+start, START
554+end, END
555+inline-start, INLINE_START
556+inline-end, INLINE_END
557+block-start, BLOCK_START
558+block-end, BLOCK_END
559+self-start, SELF_START
560+self-end, SELF_END
561+flex-start, FLEX_START
562+flex-end, FLEX_END
563+circle, CIRCLE
564+ellipse, ELLIPSE
565+shorterhue, SHORTER_HUE
566+longerhue, LONGER_HUE
567+increasinghue, INCREASING_HUE
568+decreasinghue, DECREASING_HUE
569+dotted, DOTTED
570+dashed, DASHED
571+solid, SOLID
572+double, DOUBLE
573+groove, GROOVE
574+ridge, RIDGE
575+inset, INSET
576+outset, OUTSET
577+baseline, FIRST_BASELINE
578+firstbaseline, FIRST_BASELINE
579+lastbaseline, LAST_BASELINE
580+safe, SAFE
581+unsafe, UNSAFE
582+visible, VISIBLE
583+clip, CLIP
584+scroll, SCROLL
585+inherit, INHERIT
586+initial, INITIAL
587+revert, REVERT
588+revert-layer, REVERT_LAYER
589+unset, UNSET
590+nearest, NEAREST
591+up, UP
592+down, DOWN
593+to-zero, TO_ZERO
594+%%
595diff --git a/playground/css_parser.c b/playground/css_parser.c
596new file mode 100644
597index 0000000..520740f
598--- /dev/null
599+++ b/playground/css_parser.c
600@@ -0,0 +1,57 @@
601+#define _POSIX_C_SOURCE 199309L
602+#include <stdio.h>
603+#include <stdlib.h>
604+#include <time.h>
605+#include <string.h>
606+
607+#include "../include/grim.h"
608+#include "../include/parser.h"
609+
610+#include <stdbool.h>
611+
612+char* read_file_to_string(const char* filename) {
613+    FILE* file = fopen(filename, "rb");
614+    if (!file) {
615+        perror("Failed to open file");
616+        return NULL;
617+    }
618+
619+    // Seek to the end to find the file size
620+    fseek(file, 0, SEEK_END);
621+    long length = ftell(file);
622+    fseek(file, 0, SEEK_SET);
623+
624+    // Allocate memory (+1 for null terminator)
625+    char* buffer = malloc(length + 1);
626+    if (buffer) {
627+        fread(buffer, 1, length, file);
628+        buffer[length] = '\0'; // Always null-terminate strings in C!
629+    }
630+
631+    fclose(file);
632+    return buffer;
633+}
634+
635+int main() {
636+	SymbolTable* sym = create_symbol_table(4096);
637+	Node* root = CREATE_ELEMENT(sym, "root");
638+
639+	char* file = read_file_to_string("./tests/index.html");
640+
641+	css_parser(sym, root, file, strlen(file));
642+		
643+	size_t size = 10000;
644+	char* html = calloc(size, sizeof(char));
645+
646+	INNER_HTML(sym, root, &html, &size, 0);
647+
648+	printf("%s\n", html);
649+
650+
651+	benchmark_html_parser(sym, file);
652+
653+	free(html);
654+	free(file);
655+	FREE_SYMBOL_TABLE(sym);
656+	FREE_NODE(root);
657+}
658diff --git a/playground/css_parser.cc b/playground/css_parser.cc
659deleted file mode 100644
660index 8adeeec..0000000
661--- a/playground/css_parser.cc
662+++ /dev/null
663@@ -1,22 +0,0 @@
664-#include "../include/grim.h"
665-#include "../include/parser.h"
666-#include <iostream>
667-#include <fstream>
668-#include <sstream>
669-
670-int main() {
671-	std::string cssContent = R"~~~(
672-@media (hover: hover) {
673-  abbr:hover {
674-    color: #001ca8;
675-    transition-duration: 0.5s;
676-  }
677-}
678-)~~~";
679-
680-	std::istringstream inputFile(cssContent);	
681-
682-	Style style = parseCSS(inputFile);
683-
684-	Style s = style.children[0];
685-}
686diff --git a/playground/css_unit.cc b/playground/css_unit.c
687similarity index 83%
688rename from playground/css_unit.cc
689rename to playground/css_unit.c
690index 20d759c..b7ea223 100644
691--- a/playground/css_unit.cc
692+++ b/playground/css_unit.c
693@@ -1,7 +1,5 @@
694 #include "../include/grim.h"
695 #include "../include/parser.h"
696-#include <iostream>
697-#include <fstream>
698 
699 int main() {
700 	Style style{};
701diff --git a/src/parser.c b/src/parser.c
702index c006745..8d3d941 100755
703--- a/src/parser.c
704+++ b/src/parser.c
705@@ -1,960 +1,89 @@
706 #include "grim.h" 
707 #include <string.h>
708 #include <ctype.h>
709-
710-/*
711-
712-static const std::unordered_map<std::string, KeyType> keySearch {
713-	{"accent-color", KeyType::ACCENT_COLOR},
714-	{"align-content", KeyType::ALIGN_CONTENT},
715-	{"align-items", KeyType::ALIGN_ITEMS},
716-	{"align-self", KeyType::ALIGN_SELF},
717-	{"alignment-baseline", KeyType::ALIGNMENT_BASELINE},
718-	{"all", KeyType::ALL},
719-	{"anchor-name", KeyType::ANCHOR_NAME},
720-	{"animation-composition", KeyType::ANIMATION_COMPOSITION},
721-	{"animation-delay", KeyType::ANIMATION_DELAY},
722-	{"animation-direction", KeyType::ANIMATION_DIRECTION},
723-	{"animation-duration", KeyType::ANIMATION_DURATION},
724-	{"animation-fill-mode", KeyType::ANIMATION_FILL_MODE},
725-	{"animation-iteration-count", KeyType::ANIMATION_ITERATION_COUNT},
726-	{"animation-name", KeyType::ANIMATION_NAME},
727-	{"animation-play-state", KeyType::ANIMATION_PLAY_STATE},
728-	{"animation-range-end", KeyType::ANIMATION_RANGE_END},
729-	{"animation-range-start", KeyType::ANIMATION_RANGE_START},
730-	{"animation-range", KeyType::ANIMATION_RANGE},
731-	{"animation-timeline", KeyType::ANIMATION_TIMELINE},
732-	{"animation-timing-function", KeyType::ANIMATION_TIMING_FUNCTION},
733-	{"animation", KeyType::ANIMATION},
734-	{"appearance", KeyType::APPEARANCE},
735-	{"aspect-ratio", KeyType::ASPECT_RATIO},
736-	{"backdrop-filter", KeyType::BACKDROP_FILTER},
737-	{"backface-visibility", KeyType::BACKFACE_VISIBILITY},
738-	{"background-attachment", KeyType::BACKGROUND_ATTACHMENT},
739-	{"background-blend-mode", KeyType::BACKGROUND_BLEND_MODE},
740-	{"background-clip", KeyType::BACKGROUND_CLIP},
741-	{"background-color", KeyType::BACKGROUND_COLOR},
742-	{"background-image", KeyType::BACKGROUND_IMAGE},
743-	{"background-origin", KeyType::BACKGROUND_ORIGIN},
744-	{"background-position-x", KeyType::BACKGROUND_POSITION_X},
745-	{"background-position-y", KeyType::BACKGROUND_POSITION_Y},
746-	{"background-position", KeyType::BACKGROUND_POSITION},
747-	{"background-repeat", KeyType::BACKGROUND_REPEAT},
748-	{"background-size", KeyType::BACKGROUND_SIZE},
749-	{"background", KeyType::BACKGROUND},
750-	{"block-size", KeyType::BLOCK_SIZE},
751-	{"border-block-color", KeyType::BORDER_BLOCK_COLOR},
752-	{"border-block-end-color", KeyType::BORDER_BLOCK_END_COLOR},
753-	{"border-block-end-style", KeyType::BORDER_BLOCK_END_STYLE},
754-	{"border-block-end-width", KeyType::BORDER_BLOCK_END_WIDTH},
755-	{"border-block-end", KeyType::BORDER_BLOCK_END},
756-	{"border-block-start-color", KeyType::BORDER_BLOCK_START_COLOR},
757-	{"border-block-start-style", KeyType::BORDER_BLOCK_START_STYLE},
758-	{"border-block-start-width", KeyType::BORDER_BLOCK_START_WIDTH},
759-	{"border-block-start", KeyType::BORDER_BLOCK_START},
760-	{"border-block-style", KeyType::BORDER_BLOCK_STYLE},
761-	{"border-block-width", KeyType::BORDER_BLOCK_WIDTH},
762-	{"border-block", KeyType::BORDER_BLOCK},
763-	{"border-bottom-color", KeyType::BORDER_BOTTOM_COLOR},
764-	{"border-bottom-left-radius", KeyType::BORDER_BOTTOM_LEFT_RADIUS},
765-	{"border-bottom-right-radius", KeyType::BORDER_BOTTOM_RIGHT_RADIUS},
766-	{"border-bottom-style", KeyType::BORDER_BOTTOM_STYLE},
767-	{"border-bottom-width", KeyType::BORDER_BOTTOM_WIDTH},
768-	{"border-bottom", KeyType::BORDER_BOTTOM},
769-	{"border-collapse", KeyType::BORDER_COLLAPSE},
770-	{"border-color", KeyType::BORDER_COLOR},
771-	{"border-end-end-radius", KeyType::BORDER_END_END_RADIUS},
772-	{"border-end-start-radius", KeyType::BORDER_END_START_RADIUS},
773-	{"border-image-outset", KeyType::BORDER_IMAGE_OUTSET},
774-	{"border-image-repeat", KeyType::BORDER_IMAGE_REPEAT},
775-	{"border-image-slice", KeyType::BORDER_IMAGE_SLICE},
776-	{"border-image-source", KeyType::BORDER_IMAGE_SOURCE},
777-	{"border-image-width", KeyType::BORDER_IMAGE_WIDTH},
778-	{"border-image", KeyType::BORDER_IMAGE},
779-	{"border-inline-color", KeyType::BORDER_INLINE_COLOR},
780-	{"border-inline-end-color", KeyType::BORDER_INLINE_END_COLOR},
781-	{"border-inline-end-style", KeyType::BORDER_INLINE_END_STYLE},
782-	{"border-inline-end-width", KeyType::BORDER_INLINE_END_WIDTH},
783-	{"border-inline-end", KeyType::BORDER_INLINE_END},
784-	{"border-inline-start-color", KeyType::BORDER_INLINE_START_COLOR},
785-	{"border-inline-start-style", KeyType::BORDER_INLINE_START_STYLE},
786-	{"border-inline-start-width", KeyType::BORDER_INLINE_START_WIDTH},
787-	{"border-inline-start", KeyType::BORDER_INLINE_START},
788-	{"border-inline-style", KeyType::BORDER_INLINE_STYLE},
789-	{"border-inline-width", KeyType::BORDER_INLINE_WIDTH},
790-	{"border-inline", KeyType::BORDER_INLINE},
791-	{"border-left-color", KeyType::BORDER_LEFT_COLOR},
792-	{"border-left-style", KeyType::BORDER_LEFT_STYLE},
793-	{"border-left-width", KeyType::BORDER_LEFT_WIDTH},
794-	{"border-left", KeyType::BORDER_LEFT},
795-	{"border-radius", KeyType::BORDER_RADIUS},
796-	{"border-right-color", KeyType::BORDER_RIGHT_COLOR},
797-	{"border-right-style", KeyType::BORDER_RIGHT_STYLE},
798-	{"border-right-width", KeyType::BORDER_RIGHT_WIDTH},
799-	{"border-right", KeyType::BORDER_RIGHT},
800-	{"border-spacing", KeyType::BORDER_SPACING},
801-	{"border-start-end-radius", KeyType::BORDER_START_END_RADIUS},
802-	{"border-start-start-radius", KeyType::BORDER_START_START_RADIUS},
803-	{"border-style", KeyType::BORDER_STYLE},
804-	{"border-top-color", KeyType::BORDER_TOP_COLOR},
805-	{"border-top-left-radius", KeyType::BORDER_TOP_LEFT_RADIUS},
806-	{"border-top-right-radius", KeyType::BORDER_TOP_RIGHT_RADIUS},
807-	{"border-top-style", KeyType::BORDER_TOP_STYLE},
808-	{"border-top-width", KeyType::BORDER_TOP_WIDTH},
809-	{"border-top", KeyType::BORDER_TOP},
810-	{"border-width", KeyType::BORDER_WIDTH},
811-	{"border", KeyType::BORDER},
812-	{"bottom", KeyType::BOTTOM},
813-	{"box-align", KeyType::BOX_ALIGN},
814-	{"box-decoration-break", KeyType::BOX_DECORATION_BREAK},
815-	{"box-direction", KeyType::BOX_DIRECTION},
816-	{"box-flex-group", KeyType::BOX_FLEX_GROUP},
817-	{"box-flex", KeyType::BOX_FLEX},
818-	{"box-lines", KeyType::BOX_LINES},
819-	{"box-ordinal-group", KeyType::BOX_ORDINAL_GROUP},
820-	{"box-orient", KeyType::BOX_ORIENT},
821-	{"box-pack", KeyType::BOX_PACK},
822-	{"box-shadow", KeyType::BOX_SHADOW},
823-	{"box-sizing", KeyType::BOX_SIZING},
824-	{"break-after", KeyType::BREAK_AFTER},
825-	{"break-before", KeyType::BREAK_BEFORE},
826-	{"break-inside", KeyType::BREAK_INSIDE},
827-	{"caption-side", KeyType::CAPTION_SIDE},
828-	{"caret-color", KeyType::CARET_COLOR},
829-	{"clear", KeyType::CLEAR},
830-	{"clip-path", KeyType::CLIP_PATH},
831-	{"clip-rule", KeyType::CLIP_RULE},
832-	{"clip", KeyType::CLIP},
833-	{"color-interpolation-filters", KeyType::COLOR_INTERPOLATION_FILTERS},
834-	{"color-interpolation", KeyType::COLOR_INTERPOLATION},
835-	{"color-scheme", KeyType::COLOR_SCHEME},
836-	{"color", KeyType::COLOR},
837-	{"column-count", KeyType::COLUMN_COUNT},
838-	{"column-fill", KeyType::COLUMN_FILL},
839-	{"column-gap", KeyType::COLUMN_GAP},
840-	{"column-rule-color", KeyType::COLUMN_RULE_COLOR},
841-	{"column-rule-style", KeyType::COLUMN_RULE_STYLE},
842-	{"column-rule-width", KeyType::COLUMN_RULE_WIDTH},
843-	{"column-rule", KeyType::COLUMN_RULE},
844-	{"column-span", KeyType::COLUMN_SPAN},
845-	{"column-width", KeyType::COLUMN_WIDTH},
846-	{"columns", KeyType::COLUMNS},
847-	{"contain-intrinsic-block-size", KeyType::CONTAIN_INTRINSIC_BLOCK_SIZE},
848-	{"contain-intrinsic-height", KeyType::CONTAIN_INTRINSIC_HEIGHT},
849-	{"contain-intrinsic-inline-size", KeyType::CONTAIN_INTRINSIC_INLINE_SIZE},
850-	{"contain-intrinsic-size", KeyType::CONTAIN_INTRINSIC_SIZE},
851-	{"contain-intrinsic-width", KeyType::CONTAIN_INTRINSIC_WIDTH},
852-	{"contain", KeyType::CONTAIN},
853-	{"container-name", KeyType::CONTAINER_NAME},
854-	{"container-type", KeyType::CONTAINER_TYPE},
855-	{"container", KeyType::CONTAINER},
856-	{"content-visibility", KeyType::CONTENT_VISIBILITY},
857-	{"content", KeyType::CONTENT},
858-	{"counter-increment", KeyType::COUNTER_INCREMENT},
859-	{"counter-reset", KeyType::COUNTER_RESET},
860-	{"counter-set", KeyType::COUNTER_SET},
861-	{"cursor", KeyType::CURSOR},
862-	{"cx", KeyType::CX},
863-	{"cy", KeyType::CY},
864-	{"d", KeyType::D},
865-	{"direction", KeyType::DIRECTION},
866-	{"display", KeyType::DISPLAY},
867-	{"dominant-baseline", KeyType::DOMINANT_BASELINE},
868-	{"empty-cells", KeyType::EMPTY_CELLS},
869-	{"field-sizing", KeyType::FIELD_SIZING},
870-	{"fill-opacity", KeyType::FILL_OPACITY},
871-	{"fill-rule", KeyType::FILL_RULE},
872-	{"fill", KeyType::FILL},
873-	{"filter", KeyType::FILTER},
874-	{"flex-basis", KeyType::FLEX_BASIS},
875-	{"flex-direction", KeyType::FLEX_DIRECTION},
876-	{"flex-flow", KeyType::FLEX_FLOW},
877-	{"flex-grow", KeyType::FLEX_GROW},
878-	{"flex-shrink", KeyType::FLEX_SHRINK},
879-	{"flex-wrap", KeyType::FLEX_WRAP},
880-	{"flex", KeyType::FLEX},
881-	{"float", KeyType::FLOAT},
882-	{"flood-color", KeyType::FLOOD_COLOR},
883-	{"flood-opacity", KeyType::FLOOD_OPACITY},
884-	{"font-family", KeyType::FONT_FAMILY},
885-	{"font-feature-settings", KeyType::FONT_FEATURE_SETTINGS},
886-	{"font-kerning", KeyType::FONT_KERNING},
887-	{"font-language-override", KeyType::FONT_LANGUAGE_OVERRIDE},
888-	{"font-optical-sizing", KeyType::FONT_OPTICAL_SIZING},
889-	{"font-palette", KeyType::FONT_PALETTE},
890-	{"font-size-adjust", KeyType::FONT_SIZE_ADJUST},
891-	{"font-size", KeyType::FONT_SIZE},
892-	{"font-smooth", KeyType::FONT_SMOOTH},
893-	{"font-stretch", KeyType::FONT_STRETCH},
894-	{"font-style", KeyType::FONT_STYLE},
895-	{"font-synthesis-position", KeyType::FONT_SYNTHESIS_POSITION},
896-	{"font-synthesis-small-caps", KeyType::FONT_SYNTHESIS_SMALL_CAPS},
897-	{"font-synthesis-style", KeyType::FONT_SYNTHESIS_STYLE},
898-	{"font-synthesis-weight", KeyType::FONT_SYNTHESIS_WEIGHT},
899-	{"font-synthesis", KeyType::FONT_SYNTHESIS},
900-	{"font-variant-alternates", KeyType::FONT_VARIANT_ALTERNATES},
901-	{"font-variant-caps", KeyType::FONT_VARIANT_CAPS},
902-	{"font-variant-east-asian", KeyType::FONT_VARIANT_EAST_ASIAN},
903-	{"font-variant-emoji", KeyType::FONT_VARIANT_EMOJI},
904-	{"font-variant-ligatures", KeyType::FONT_VARIANT_LIGATURES},
905-	{"font-variant-numeric", KeyType::FONT_VARIANT_NUMERIC},
906-	{"font-variant-position", KeyType::FONT_VARIANT_POSITION},
907-	{"font-variant", KeyType::FONT_VARIANT},
908-	{"font-variation-settings", KeyType::FONT_VARIATION_SETTINGS},
909-	{"font-weight", KeyType::FONT_WEIGHT},
910-	{"font", KeyType::FONT},
911-	{"forced-color-adjust", KeyType::FORCED_COLOR_ADJUST},
912-	{"gap", KeyType::GAP},
913-	{"grid-area", KeyType::GRID_AREA},
914-	{"grid-auto-columns", KeyType::GRID_AUTO_COLUMNS},
915-	{"grid-auto-flow", KeyType::GRID_AUTO_FLOW},
916-	{"grid-auto-rows", KeyType::GRID_AUTO_ROWS},
917-	{"grid-column-end", KeyType::GRID_COLUMN_END},
918-	{"grid-column-start", KeyType::GRID_COLUMN_START},
919-	{"grid-column", KeyType::GRID_COLUMN},
920-	{"grid-row-end", KeyType::GRID_ROW_END},
921-	{"grid-row-start", KeyType::GRID_ROW_START},
922-	{"grid-row", KeyType::GRID_ROW},
923-	{"grid-template-areas", KeyType::GRID_TEMPLATE_AREAS},
924-	{"grid-template-columns", KeyType::GRID_TEMPLATE_COLUMNS},
925-	{"grid-template-rows", KeyType::GRID_TEMPLATE_ROWS},
926-	{"grid-template", KeyType::GRID_TEMPLATE},
927-	{"grid", KeyType::GRID},
928-	{"hanging-punctuation", KeyType::HANGING_PUNCTUATION},
929-	{"height", KeyType::HEIGHT},
930-	{"hyphenate-character", KeyType::HYPHENATE_CHARACTER},
931-	{"hyphenate-limit-chars", KeyType::HYPHENATE_LIMIT_CHARS},
932-	{"hyphens", KeyType::HYPHENS},
933-	{"image-orientation", KeyType::IMAGE_ORIENTATION},
934-	{"image-rendering", KeyType::IMAGE_RENDERING},
935-	{"image-resolution", KeyType::IMAGE_RESOLUTION},
936-	{"initial-letter", KeyType::INITIAL_LETTER},
937-	{"inline-size", KeyType::INLINE_SIZE},
938-	{"inset-block-end", KeyType::INSET_BLOCK_END},
939-	{"inset-block-start", KeyType::INSET_BLOCK_START},
940-	{"inset-block", KeyType::INSET_BLOCK},
941-	{"inset-block", KeyType::INSET_BLOCK},
942-	{"inset-inline-end", KeyType::INSET_INLINE_END},
943-	{"inset-inline-start", KeyType::INSET_INLINE_START},
944-	{"inset-inline", KeyType::INSET_INLINE},
945-	{"inset-inline", KeyType::INSET_INLINE},
946-	{"inset", KeyType::INSET},
947-	{"inset", KeyType::INSET},
948-	{"interpolate-size", KeyType::INTERPOLATE_SIZE},
949-	{"isolation", KeyType::ISOLATION},
950-	{"justify-content", KeyType::JUSTIFY_CONTENT},
951-	{"justify-items", KeyType::JUSTIFY_ITEMS},
952-	{"justify-self", KeyType::JUSTIFY_SELF},
953-	{"left", KeyType::LEFT},
954-	{"letter-spacing", KeyType::LETTER_SPACING},
955-	{"lighting-color", KeyType::LIGHTING_COLOR},
956-	{"line-break", KeyType::LINE_BREAK},
957-	{"line-clamp", KeyType::LINE_CLAMP},
958-	{"line-height-step", KeyType::LINE_HEIGHT_STEP},
959-	{"line-height", KeyType::LINE_HEIGHT},
960-	{"list-style-image", KeyType::LIST_STYLE_IMAGE},
961-	{"list-style-position", KeyType::LIST_STYLE_POSITION},
962-	{"list-style-type", KeyType::LIST_STYLE_TYPE},
963-	{"list-style", KeyType::LIST_STYLE},
964-	{"list-style", KeyType::LIST_STYLE},
965-	{"margin-block-end", KeyType::MARGIN_BLOCK_END},
966-	{"margin-block-start", KeyType::MARGIN_BLOCK_START},
967-	{"margin-block", KeyType::MARGIN_BLOCK},
968-	{"margin-bottom", KeyType::MARGIN_BOTTOM},
969-	{"margin-inline-end", KeyType::MARGIN_INLINE_END},
970-	{"margin-inline-start", KeyType::MARGIN_INLINE_START},
971-	{"margin-inline", KeyType::MARGIN_INLINE},
972-	{"margin-left", KeyType::MARGIN_LEFT},
973-	{"margin-right", KeyType::MARGIN_RIGHT},
974-	{"margin-top", KeyType::MARGIN_TOP},
975-	{"margin-trim", KeyType::MARGIN_TRIM},
976-	{"margin", KeyType::MARGIN},
977-	{"marker-end", KeyType::MARKER_END},
978-	{"marker-mid", KeyType::MARKER_MID},
979-	{"marker-start", KeyType::MARKER_START},
980-	{"marker", KeyType::MARKER},
981-	{"mask-border-mode", KeyType::MASK_BORDER_MODE},
982-	{"mask-border-outset", KeyType::MASK_BORDER_OUTSET},
983-	{"mask-border-repeat", KeyType::MASK_BORDER_REPEAT},
984-	{"mask-border-slice", KeyType::MASK_BORDER_SLICE},
985-	{"mask-border-source", KeyType::MASK_BORDER_SOURCE},
986-	{"mask-border-width", KeyType::MASK_BORDER_WIDTH},
987-	{"mask-border", KeyType::MASK_BORDER},
988-	{"mask-clip", KeyType::MASK_CLIP},
989-	{"mask-composite", KeyType::MASK_COMPOSITE},
990-	{"mask-image", KeyType::MASK_IMAGE},
991-	{"mask-mode", KeyType::MASK_MODE},
992-	{"mask-origin", KeyType::MASK_ORIGIN},
993-	{"mask-position", KeyType::MASK_POSITION},
994-	{"mask-repeat", KeyType::MASK_REPEAT},
995-	{"mask-size", KeyType::MASK_SIZE},
996-	{"mask-type", KeyType::MASK_TYPE},
997-	{"mask", KeyType::MASK},
998-	{"math-depth", KeyType::MATH_DEPTH},
999-	{"math-shift", KeyType::MATH_SHIFT},
1000-	{"math-style", KeyType::MATH_STYLE},
1001-	{"max-block-size", KeyType::MAX_BLOCK_SIZE},
1002-	{"max-height", KeyType::MAX_HEIGHT},
1003-	{"max-inline-size", KeyType::MAX_INLINE_SIZE},
1004-	{"max-width", KeyType::MAX_WIDTH},
1005-	{"min-block-size", KeyType::MIN_BLOCK_SIZE},
1006-	{"min-height", KeyType::MIN_HEIGHT},
1007-	{"min-inline-size", KeyType::MIN_INLINE_SIZE},
1008-	{"min-width", KeyType::MIN_WIDTH},
1009-	{"mix-blend-mode", KeyType::MIX_BLEND_MODE},
1010-	{"object-fit", KeyType::OBJECT_FIT},
1011-	{"object-position", KeyType::OBJECT_POSITION},
1012-	{"offset-anchor", KeyType::OFFSET_ANCHOR},
1013-	{"offset-distance", KeyType::OFFSET_DISTANCE},
1014-	{"offset-path", KeyType::OFFSET_PATH},
1015-	{"offset-position", KeyType::OFFSET_POSITION},
1016-	{"offset-rotate", KeyType::OFFSET_ROTATE},
1017-	{"offset", KeyType::OFFSET},
1018-	{"opacity", KeyType::OPACITY},
1019-	{"order", KeyType::ORDER},
1020-	{"orphans", KeyType::ORPHANS},
1021-	{"outline-color", KeyType::OUTLINE_COLOR},
1022-	{"outline-offset", KeyType::OUTLINE_OFFSET},
1023-	{"outline-style", KeyType::OUTLINE_STYLE},
1024-	{"outline-width", KeyType::OUTLINE_WIDTH},
1025-	{"outline", KeyType::OUTLINE},
1026-	{"overflow-anchor", KeyType::OVERFLOW_ANCHOR},
1027-	{"overflow-block", KeyType::OVERFLOW_BLOCK},
1028-	{"overflow-clip-margin", KeyType::OVERFLOW_CLIP_MARGIN},
1029-	{"overflow-inline", KeyType::OVERFLOW_INLINE},
1030-	{"overflow-wrap", KeyType::OVERFLOW_WRAP},
1031-	{"overflow-x", KeyType::OVERFLOW_X},
1032-	{"overflow-y", KeyType::OVERFLOW_Y},
1033-	{"overflow", KeyType::OVERFLOW},
1034-	{"overlay", KeyType::OVERLAY},
1035-	{"overscroll-behavior-block", KeyType::OVERSCROLL_BEHAVIOR_BLOCK},
1036-	{"overscroll-behavior-inline", KeyType::OVERSCROLL_BEHAVIOR_INLINE},
1037-	{"overscroll-behavior-x", KeyType::OVERSCROLL_BEHAVIOR_X},
1038-	{"overscroll-behavior-y", KeyType::OVERSCROLL_BEHAVIOR_Y},
1039-	{"overscroll-behavior", KeyType::OVERSCROLL_BEHAVIOR},
1040-	{"padding-block-end", KeyType::PADDING_BLOCK_END},
1041-	{"padding-block-start", KeyType::PADDING_BLOCK_START},
1042-	{"padding-block", KeyType::PADDING_BLOCK},
1043-	{"padding-bottom", KeyType::PADDING_BOTTOM},
1044-	{"padding-inline-end", KeyType::PADDING_INLINE_END},
1045-	{"padding-inline-start", KeyType::PADDING_INLINE_START},
1046-	{"padding-inline", KeyType::PADDING_INLINE},
1047-	{"padding-left", KeyType::PADDING_LEFT},
1048-	{"padding-right", KeyType::PADDING_RIGHT},
1049-	{"padding-top", KeyType::PADDING_TOP},
1050-	{"padding", KeyType::PADDING},
1051-	{"page-break-after", KeyType::PAGE_BREAK_AFTER},
1052-	{"page-break-before", KeyType::PAGE_BREAK_BEFORE},
1053-	{"page-break-inside", KeyType::PAGE_BREAK_INSIDE},
1054-	{"page", KeyType::PAGE},
1055-	{"paint-order", KeyType::PAINT_ORDER},
1056-	{"perspective-origin", KeyType::PERSPECTIVE_ORIGIN},
1057-	{"perspective", KeyType::PERSPECTIVE},
1058-	{"place-content", KeyType::PLACE_CONTENT},
1059-	{"place-items", KeyType::PLACE_ITEMS},
1060-	{"place-self", KeyType::PLACE_SELF},
1061-	{"pointer-events", KeyType::POINTER_EVENTS},
1062-	{"position-anchor", KeyType::POSITION_ANCHOR},
1063-	{"position-area", KeyType::POSITION_AREA},
1064-	{"position-try-fallbacks", KeyType::POSITION_TRY_FALLBACKS},
1065-	{"position-try-order", KeyType::POSITION_TRY_ORDER},
1066-	{"position-try", KeyType::POSITION_TRY},
1067-	{"position-visibility", KeyType::POSITION_VISIBILITY},
1068-	{"position", KeyType::POSITION},
1069-	{"print-color-adjust", KeyType::PRINT_COLOR_ADJUST},
1070-	{"quotes", KeyType::QUOTES},
1071-	{"r", KeyType::R},
1072-	{"reading-flow", KeyType::READING_FLOW},
1073-	{"reading-order", KeyType::READING_ORDER},
1074-	{"resize", KeyType::RESIZE},
1075-	{"right", KeyType::RIGHT},
1076-	{"rotate", KeyType::ROTATE},
1077-	{"row-gap", KeyType::ROW_GAP},
1078-	{"ruby-align", KeyType::RUBY_ALIGN},
1079-	{"ruby-position", KeyType::RUBY_POSITION},
1080-	{"rx", KeyType::RX},
1081-	{"ry", KeyType::RY},
1082-	{"scale", KeyType::SCALE},
1083-	{"scroll-behavior", KeyType::SCROLL_BEHAVIOR},
1084-	{"scroll-margin-block-end", KeyType::SCROLL_MARGIN_BLOCK_END},
1085-	{"scroll-margin-block-start", KeyType::SCROLL_MARGIN_BLOCK_START},
1086-	{"scroll-margin-block", KeyType::SCROLL_MARGIN_BLOCK},
1087-	{"scroll-margin-bottom", KeyType::SCROLL_MARGIN_BOTTOM},
1088-	{"scroll-margin-inline-end", KeyType::SCROLL_MARGIN_INLINE_END},
1089-	{"scroll-margin-inline-start", KeyType::SCROLL_MARGIN_INLINE_START},
1090-	{"scroll-margin-inline", KeyType::SCROLL_MARGIN_INLINE},
1091-	{"scroll-margin-left", KeyType::SCROLL_MARGIN_LEFT},
1092-	{"scroll-margin-right", KeyType::SCROLL_MARGIN_RIGHT},
1093-	{"scroll-margin-top", KeyType::SCROLL_MARGIN_TOP},
1094-	{"scroll-margin", KeyType::SCROLL_MARGIN},
1095-	{"scroll-marker-group", KeyType::SCROLL_MARKER_GROUP},
1096-	{"scroll-padding-block-end", KeyType::SCROLL_PADDING_BLOCK_END},
1097-	{"scroll-padding-block-start", KeyType::SCROLL_PADDING_BLOCK_START},
1098-	{"scroll-padding-block", KeyType::SCROLL_PADDING_BLOCK},
1099-	{"scroll-padding-bottom", KeyType::SCROLL_PADDING_BOTTOM},
1100-	{"scroll-padding-inline-end", KeyType::SCROLL_PADDING_INLINE_END},
1101-	{"scroll-padding-inline-start", KeyType::SCROLL_PADDING_INLINE_START},
1102-	{"scroll-padding-inline", KeyType::SCROLL_PADDING_INLINE},
1103-	{"scroll-padding-left", KeyType::SCROLL_PADDING_LEFT},
1104-	{"scroll-padding-right", KeyType::SCROLL_PADDING_RIGHT},
1105-	{"scroll-padding-top", KeyType::SCROLL_PADDING_TOP},
1106-	{"scroll-padding", KeyType::SCROLL_PADDING},
1107-	{"scroll-snap-align", KeyType::SCROLL_SNAP_ALIGN},
1108-	{"scroll-snap-stop", KeyType::SCROLL_SNAP_STOP},
1109-	{"scroll-snap-type", KeyType::SCROLL_SNAP_TYPE},
1110-	{"scroll-timeline-axis", KeyType::SCROLL_TIMELINE_AXIS},
1111-	{"scroll-timeline-name", KeyType::SCROLL_TIMELINE_NAME},
1112-	{"scroll-timeline", KeyType::SCROLL_TIMELINE},
1113-	{"scrollbar-color", KeyType::SCROLLBAR_COLOR},
1114-	{"scrollbar-gutter", KeyType::SCROLLBAR_GUTTER},
1115-	{"scrollbar-width", KeyType::SCROLLBAR_WIDTH},
1116-	{"shape-image-threshold", KeyType::SHAPE_IMAGE_THRESHOLD},
1117-	{"shape-margin", KeyType::SHAPE_MARGIN},
1118-	{"shape-outside", KeyType::SHAPE_OUTSIDE},
1119-	{"shape-rendering", KeyType::SHAPE_RENDERING},
1120-	{"speak-as", KeyType::SPEAK_AS},
1121-	{"stop-color", KeyType::STOP_COLOR},
1122-	{"stop-opacity", KeyType::STOP_OPACITY},
1123-	{"stroke-dasharray", KeyType::STROKE_DASHARRAY},
1124-	{"stroke-dashoffset", KeyType::STROKE_DASHOFFSET},
1125-	{"stroke-linecap", KeyType::STROKE_LINECAP},
1126-	{"stroke-linejoin", KeyType::STROKE_LINEJOIN},
1127-	{"stroke-miterlimit", KeyType::STROKE_MITERLIMIT},
1128-	{"stroke-opacity", KeyType::STROKE_OPACITY},
1129-	{"stroke-width", KeyType::STROKE_WIDTH},
1130-	{"stroke", KeyType::STROKE},
1131-	{"tab-size", KeyType::TAB_SIZE},
1132-	{"table-layout", KeyType::TABLE_LAYOUT},
1133-	{"text-align-last", KeyType::TEXT_ALIGN_LAST},
1134-	{"text-align", KeyType::TEXT_ALIGN},
1135-	{"text-anchor", KeyType::TEXT_ANCHOR},
1136-	{"text-box-edge", KeyType::TEXT_BOX_EDGE},
1137-	{"text-box-trim", KeyType::TEXT_BOX_TRIM},
1138-	{"text-box", KeyType::TEXT_BOX},
1139-	{"text-combine-upright", KeyType::TEXT_COMBINE_UPRIGHT},
1140-	{"text-decoration-color", KeyType::TEXT_DECORATION_COLOR},
1141-	{"text-decoration-line", KeyType::TEXT_DECORATION_LINE},
1142-	{"text-decoration-skip-ink", KeyType::TEXT_DECORATION_SKIP_INK},
1143-	{"text-decoration-skip", KeyType::TEXT_DECORATION_SKIP},
1144-	{"text-decoration-style", KeyType::TEXT_DECORATION_STYLE},
1145-	{"text-decoration-thickness", KeyType::TEXT_DECORATION_THICKNESS},
1146-	{"text-decoration", KeyType::TEXT_DECORATION},
1147-	{"text-emphasis-color", KeyType::TEXT_EMPHASIS_COLOR},
1148-	{"text-emphasis-position", KeyType::TEXT_EMPHASIS_POSITION},
1149-	{"text-emphasis-style", KeyType::TEXT_EMPHASIS_STYLE},
1150-	{"text-emphasis", KeyType::TEXT_EMPHASIS},
1151-	{"text-indent", KeyType::TEXT_INDENT},
1152-	{"text-justify", KeyType::TEXT_JUSTIFY},
1153-	{"text-orientation", KeyType::TEXT_ORIENTATION},
1154-	{"text-overflow", KeyType::TEXT_OVERFLOW},
1155-	{"text-rendering", KeyType::TEXT_RENDERING},
1156-	{"text-shadow", KeyType::TEXT_SHADOW},
1157-	{"text-size-adjust", KeyType::TEXT_SIZE_ADJUST},
1158-	{"text-spacing-trim", KeyType::TEXT_SPACING_TRIM},
1159-	{"text-transform", KeyType::TEXT_TRANSFORM},
1160-	{"text-underline-offset", KeyType::TEXT_UNDERLINE_OFFSET},
1161-	{"text-underline-position", KeyType::TEXT_UNDERLINE_POSITION},
1162-	{"text-wrap-mode", KeyType::TEXT_WRAP_MODE},
1163-	{"text-wrap-style", KeyType::TEXT_WRAP_STYLE},
1164-	{"text-wrap", KeyType::TEXT_WRAP},
1165-	{"timeline-scope", KeyType::TIMELINE_SCOPE},
1166-	{"top", KeyType::TOP},
1167-	{"touch-action", KeyType::TOUCH_ACTION},
1168-	{"transform-box", KeyType::TRANSFORM_BOX},
1169-	{"transform-origin", KeyType::TRANSFORM_ORIGIN},
1170-	{"transform-style", KeyType::TRANSFORM_STYLE},
1171-	{"transform", KeyType::TRANSFORM},
1172-	{"transition-behavior", KeyType::TRANSITION_BEHAVIOR},
1173-	{"transition-delay", KeyType::TRANSITION_DELAY},
1174-	{"transition-duration", KeyType::TRANSITION_DURATION},
1175-	{"transition-property", KeyType::TRANSITION_PROPERTY},
1176-	{"transition-timing-function", KeyType::TRANSITION_TIMING_FUNCTION},
1177-	{"transition", KeyType::TRANSITION},
1178-	{"translate", KeyType::TRANSLATE},
1179-	{"unicode-bidi", KeyType::UNICODE_BIDI},
1180-	{"user-modify", KeyType::USER_MODIFY},
1181-	{"user-select", KeyType::USER_SELECT},
1182-	{"vector-effect", KeyType::VECTOR_EFFECT},
1183-	{"vertical-align", KeyType::VERTICAL_ALIGN},
1184-	{"view-timeline-axis", KeyType::VIEW_TIMELINE_AXIS},
1185-	{"view-timeline-inset", KeyType::VIEW_TIMELINE_INSET},
1186-	{"view-timeline-name", KeyType::VIEW_TIMELINE_NAME},
1187-	{"view-timeline", KeyType::VIEW_TIMELINE},
1188-	{"view-transition-class", KeyType::VIEW_TRANSITION_CLASS},
1189-	{"view-transition-name", KeyType::VIEW_TRANSITION_NAME},
1190-	{"visibility", KeyType::VISIBILITY},
1191-	{"white-space-collapse", KeyType::WHITE_SPACE_COLLAPSE},
1192-	{"white-space", KeyType::WHITE_SPACE},
1193-	{"widows", KeyType::WIDOWS},
1194-	{"width", KeyType::WIDTH},
1195-	{"will-change", KeyType::WILL_CHANGE},
1196-	{"word-break", KeyType::WORD_BREAK},
1197-	{"word-spacing", KeyType::WORD_SPACING},
1198-	{"writing-mode", KeyType::WRITING_MODE},
1199-	{"x", KeyType::X},
1200-	{"y", KeyType::Y},
1201-	{"z-index", KeyType::Z_INDEX},
1202-	{"zoom", KeyType::ZOOM}
1203-};
1204-
1205-static const std::unordered_map<std::string_view, unsigned int> kColors {
1206-	{"black", 0x000000},
1207-	{"silver", 0xc0c0c0},
1208-	{"gray", 0x808080},
1209-	{"white", 0xffffff},
1210-	{"maroon", 0x800000},
1211-	{"red", 0xff0000},
1212-	{"purple", 0x800080},
1213-	{"fuchsia", 0xff00ff},
1214-	{"green", 0x008000},
1215-	{"lime", 0x00ff00},
1216-	{"olive", 0x808000},
1217-	{"yellow", 0xffff00},
1218-	{"navy", 0x000080},
1219-	{"blue", 0x0000ff},
1220-	{"teal", 0x008080},
1221-	{"aqua", 0x00ffff},
1222-	{"aliceblue", 0xf0f8ff},
1223-	{"antiquewhite", 0xfaebd7},
1224-	{"aqua", 0x00ffff},
1225-	{"aquamarine", 0x7fffd4},
1226-	{"azure", 0xf0ffff},
1227-	{"beige", 0xf5f5dc},
1228-	{"bisque", 0xffe4c4},
1229-	{"black", 0x000000},
1230-	{"blanchedalmond", 0xffebcd},
1231-	{"blue", 0x0000ff},
1232-	{"blueviolet", 0x8a2be2},
1233-	{"brown", 0xa52a2a},
1234-	{"burlywood", 0xdeb887},
1235-	{"cadetblue", 0x5f9ea0},
1236-	{"chartreuse", 0x7fff00},
1237-	{"chocolate", 0xd2691e},
1238-	{"coral", 0xff7f50},
1239-	{"cornflowerblue", 0x6495ed},
1240-	{"cornsilk", 0xfff8dc},
1241-	{"crimson", 0xdc143c},
1242-	{"cyan", 0x00ffff},
1243-	{"darkblue", 0x00008b},
1244-	{"darkcyan", 0x008b8b},
1245-	{"darkgoldenrod", 0xb8860b},
1246-	{"darkgray", 0xa9a9a9},
1247-	{"darkgreen", 0x006400},
1248-	{"darkgrey", 0xa9a9a9},
1249-	{"darkkhaki", 0xbdb76b},
1250-	{"darkmagenta", 0x8b008b},
1251-	{"darkolivegreen", 0x556b2f},
1252-	{"darkorange", 0xff8c00},
1253-	{"darkorchid", 0x9932cc},
1254-	{"darkred", 0x8b0000},
1255-	{"darksalmon", 0xe9967a},
1256-	{"darkseagreen", 0x8fbc8f},
1257-	{"darkslateblue", 0x483d8b},
1258-	{"darkslategray", 0x2f4f4f},
1259-	{"darkslategrey", 0x2f4f4f},
1260-	{"darkturquoise", 0x00ced1},
1261-	{"darkviolet", 0x9400d3},
1262-	{"deeppink", 0xff1493},
1263-	{"deepskyblue", 0x00bfff},
1264-	{"dimgray", 0x696969},
1265-	{"dimgrey", 0x696969},
1266-	{"dodgerblue", 0x1e90ff},
1267-	{"firebrick", 0xb22222},
1268-	{"floralwhite", 0xfffaf0},
1269-	{"forestgreen", 0x228b22},
1270-	{"fuchsia", 0xff00ff},
1271-	{"gainsboro", 0xdcdcdc},
1272-	{"ghostwhite", 0xf8f8ff},
1273-	{"gold", 0xffd700},
1274-	{"goldenrod", 0xdaa520},
1275-	{"gray", 0x808080},
1276-	{"green", 0x008000},
1277-	{"greenyellow", 0xadff2f},
1278-	{"grey", 0x808080},
1279-	{"honeydew", 0xf0fff0},
1280-	{"hotpink", 0xff69b4},
1281-	{"indianred", 0xcd5c5c},
1282-	{"indigo", 0x4b0082},
1283-	{"ivory", 0xfffff0},
1284-	{"khaki", 0xf0e68c},
1285-	{"lavender", 0xe6e6fa},
1286-	{"lavenderblush", 0xfff0f5},
1287-	{"lawngreen", 0x7cfc00},
1288-	{"lemonchiffon", 0xfffacd},
1289-	{"lightblue", 0xadd8e6},
1290-	{"lightcoral", 0xf08080},
1291-	{"lightcyan", 0xe0ffff},
1292-	{"lightgoldenrodyellow", 0xfafad2},
1293-	{"lightgray", 0xd3d3d3},
1294-	{"lightgreen", 0x90ee90},
1295-	{"lightgrey", 0xd3d3d3},
1296-	{"lightpink", 0xffb6c1},
1297-	{"lightsalmon", 0xffa07a},
1298-	{"lightseagreen", 0x20b2aa},
1299-	{"lightskyblue", 0x87cefa},
1300-	{"lightslategray", 0x778899},
1301-	{"lightslategrey", 0x778899},
1302-	{"lightsteelblue", 0xb0c4de},
1303-	{"lightyellow", 0xffffe0},
1304-	{"lime", 0x00ff00},
1305-	{"limegreen", 0x32cd32},
1306-	{"linen", 0xfaf0e6},
1307-	{"magenta", 0xff00ff},
1308-	{"maroon", 0x800000},
1309-	{"mediumaquamarine", 0x66cdaa},
1310-	{"mediumblue", 0x0000cd},
1311-	{"mediumorchid", 0xba55d3},
1312-	{"mediumpurple", 0x9370db},
1313-	{"mediumseagreen", 0x3cb371},
1314-	{"mediumslateblue", 0x7b68ee},
1315-	{"mediumspringgreen", 0x00fa9a},
1316-	{"mediumturquoise", 0x48d1cc},
1317-	{"mediumvioletred", 0xc71585},
1318-	{"midnightblue", 0x191970},
1319-	{"mintcream", 0xf5fffa},
1320-	{"mistyrose", 0xffe4e1},
1321-	{"moccasin", 0xffe4b5},
1322-	{"navajowhite", 0xffdead},
1323-	{"navy", 0x000080},
1324-	{"oldlace", 0xfdf5e6},
1325-	{"olive", 0x808000},
1326-	{"olivedrab", 0x6b8e23},
1327-	{"orange", 0xffa500},
1328-	{"orangered", 0xff4500},
1329-	{"orchid", 0xda70d6},
1330-	{"palegoldenrod", 0xeee8aa},
1331-	{"palegreen", 0x98fb98},
1332-	{"paleturquoise", 0xafeeee},
1333-	{"palevioletred", 0xdb7093},
1334-	{"papayawhip", 0xffefd5},
1335-	{"peachpuff", 0xffdab9},
1336-	{"peru", 0xcd853f},
1337-	{"pink", 0xffc0cb},
1338-	{"plum", 0xdda0dd},
1339-	{"powderblue", 0xb0e0e6},
1340-	{"purple", 0x800080},
1341-	{"rebeccapurple", 0x663399},
1342-	{"red", 0xff0000},
1343-	{"rosybrown", 0xbc8f8f},
1344-	{"royalblue", 0x4169e1},
1345-	{"saddlebrown", 0x8b4513},
1346-	{"salmon", 0xfa8072},
1347-	{"sandybrown", 0xf4a460},
1348-	{"seagreen", 0x2e8b57},
1349-	{"seashell", 0xfff5ee},
1350-	{"sienna", 0xa0522d},
1351-	{"silver", 0xc0c0c0},
1352-	{"skyblue", 0x87ceeb},
1353-	{"slateblue", 0x6a5acd},
1354-	{"slategray", 0x708090},
1355-	{"slategrey", 0x708090},
1356-	{"snow", 0xfffafa},
1357-	{"springgreen", 0x00ff7f},
1358-	{"steelblue", 0x4682b4},
1359-	{"tan", 0xd2b48c},
1360-	{"teal", 0x008080},
1361-	{"thistle", 0xd8bfd8},
1362-	{"tomato", 0xff6347},
1363-	{"transparent", 0x00000000},
1364-	{"turquoise", 0x40e0d0},
1365-	{"violet", 0xee82ee},
1366-	{"wheat", 0xf5deb3},
1367-	{"white", 0xffffff},
1368-	{"whitesmoke", 0xf5f5f5},
1369-	{"yellow", 0xffff00},
1370-	{"yellowgreen", 0x9acd32},
1371-};
1372+#include <stdlib.h>
1373+#include <stdint.h>
1374+#include "../build/functions.c" 
1375+#include "../build/match.c" 
1376+#include "../build/colors.c" 
1377 
1378 struct SuffixParse {
1379-	std::string_view suffix;
1380+	const char* suffix;
1381 	UnitType type;
1382 	int trim;   // chars to strip from the right
1383 };
1384 
1385-static constexpr SuffixParse sufMatch[] = {
1386-	{"cqmin", UnitType::CQMIN, 5},
1387-	{"cqmax", UnitType::CQMAX, 5},
1388-	{"rcap",  UnitType::RCAP,  4},
1389-	{"vmax",  UnitType::VMAX,  4},
1390-	{"vmin",  UnitType::VMIN,  4},
1391-	{"grad",  UnitType::GRAD,  4},
1392-	{"turn",  UnitType::TURN,  4},
1393-	{"cap",   UnitType::CAP,   3},
1394-	{"rch",   UnitType::RCH,   3},
1395-	{"rem",   UnitType::REM,   3},
1396-	{"rex",   UnitType::REX,   3},
1397-	{"ric",   UnitType::RIC,   3},
1398-	{"rlh",   UnitType::RLH,   3},
1399-	{"cqw",   UnitType::CQW,   3},
1400-	{"cqh",   UnitType::CQH,   3},
1401-	{"cqi",   UnitType::CQI,   3},
1402-	{"cqb",   UnitType::CQB,   3},
1403-	{"deg",   UnitType::DEG,   3},
1404-	{"rad",   UnitType::RAD,   3},
1405-	{"khz",   UnitType::KHZ,   3},
1406-	{"kHz",   UnitType::KHZ,   3},
1407-	{"Khz",   UnitType::KHZ,   3},
1408-	{"KHz",   UnitType::KHZ,   3},
1409-	{"KHZ",   UnitType::KHZ,   3},
1410-	{"px",    UnitType::PX,    2},
1411-	{"hz",    UnitType::HZ,    2},
1412-	{"Hz",    UnitType::HZ,    2},
1413-	{"HZ",    UnitType::HZ,    2},
1414-	{"hZ",    UnitType::HZ,    2},
1415-	{"ms",    UnitType::MS,    2},
1416-	{"em",    UnitType::EM,    2},
1417-	{"cm",    UnitType::CM,    2},
1418-	{"ch",    UnitType::CH,    2},
1419-	{"ex",    UnitType::EX,    2},
1420-	{"ic",    UnitType::IC,    2},
1421-	{"lh",    UnitType::LH,    2},
1422-	{"vh",    UnitType::VH,    2},
1423-	{"vw",    UnitType::VW,    2},
1424-	{"vb",    UnitType::VB,    2},
1425-	{"vi",    UnitType::VI,    2},
1426-	{"mm",    UnitType::MM,    2},
1427-	{"in",    UnitType::IN,    2},
1428-	{"pc",    UnitType::PC,    2},
1429-	{"pt",    UnitType::PT,    2},
1430-	{"fr",    UnitType::FRACTION,2},
1431-	{"%",     UnitType::PERCENT,1},
1432-	{"q",     UnitType::Q,     1},
1433-	{"s",     UnitType::SECOND,1},
1434+static const struct SuffixParse sufMatch[] = {
1435+	{"cqmin", CQMIN, 5},
1436+	{"cqmax", CQMAX, 5},
1437+	{"rcap",  RCAP,  4},
1438+	{"vmax",  VMAX,  4},
1439+	{"vmin",  VMIN,  4},
1440+	{"grad",  GRAD,  4},
1441+	{"turn",  TURN,  4},
1442+	{"cap",   CAP,   3},
1443+	{"rch",   RCH,   3},
1444+	{"rem",   REM,   3},
1445+	{"rex",   REX,   3},
1446+	{"ric",   RIC,   3},
1447+	{"rlh",   RLH,   3},
1448+	{"cqw",   CQW,   3},
1449+	{"cqh",   CQH,   3},
1450+	{"cqi",   CQI,   3},
1451+	{"cqb",   CQB,   3},
1452+	{"deg",   DEG,   3},
1453+	{"rad",   RAD,   3},
1454+	{"khz",   KHZ,   3},
1455+	{"kHz",   KHZ,   3},
1456+	{"Khz",   KHZ,   3},
1457+	{"KHz",   KHZ,   3},
1458+	{"KHZ",   KHZ,   3},
1459+	{"px",    PX,    2},
1460+	{"hz",    HZ,    2},
1461+	{"Hz",    HZ,    2},
1462+	{"HZ",    HZ,    2},
1463+	{"hZ",    HZ,    2},
1464+	{"ms",    MS,    2},
1465+	{"em",    EM,    2},
1466+	{"cm",    CM,    2},
1467+	{"ch",    CH,    2},
1468+	{"ex",    EX,    2},
1469+	{"ic",    IC,    2},
1470+	{"lh",    LH,    2},
1471+	{"vh",    VH,    2},
1472+	{"vw",    VW,    2},
1473+	{"vb",    VB,    2},
1474+	{"vi",    VI,    2},
1475+	{"mm",    MM,    2},
1476+	{"in",    IN,    2},
1477+	{"pc",    PC,    2},
1478+	{"pt",    PT,    2},
1479+	{"fr",    FRACTION,2},
1480+	{"%",     PERCENT,1},
1481+	{"q",     Q,     1},
1482+	{"s",     SECOND,1},
1483 };
1484 
1485-
1486-static const std::unordered_map<std::string_view, UnitType> kMatch{
1487-	{"+", UnitType::ADD},
1488-	{"-", UnitType::SUB},
1489-	{"*", UnitType::MULT},
1490-	{"/", UnitType::DIV},
1491-	{"==", UnitType::EQ},
1492-	{">", UnitType::GT},
1493-	{"<", UnitType::LT},
1494-	{">=", UnitType::GE},
1495-	{"<=", UnitType::LE},
1496-	{"and", UnitType::AND},
1497-	{"&&", UnitType::AND},
1498-	{"or", UnitType::OR},
1499-	{"||", UnitType::OR},
1500-	{"not", UnitType::NOT},
1501-	{"!=", UnitType::NOT},
1502-	{"only", UnitType::ONLY},
1503-	{"else", UnitType::ELSE},
1504-	{"infinity", UnitType::INF},
1505-	{"-infinity", UnitType::NEGINF},
1506-	{"NaN", UnitType::NaN},
1507-	{"e", UnitType::E},
1508-	{"pi", UnitType::PI},
1509-	{"content-box", UnitType::CONTENT},
1510-	{"padding-box", UnitType::PADDING},
1511-	{"border-box", UnitType::BORDER},
1512-	{"margin-box", UnitType::MARGIN},
1513-	{"fill-box", UnitType::FILL},
1514-	{"stroke-box", UnitType::STROKE},
1515-	{"view-box", UnitType::VIEW},
1516-	{"space-between", UnitType::BETWEEN},
1517-	{"space-around", UnitType::AROUND},
1518-	{"space-evenly", UnitType::EVENLY},
1519-	{"stretch", UnitType::STRETCH},
1520-	{"normal", UnitType::NORMAL},
1521-	{"contents", UnitType::CONTENTS},
1522-	{"none", UnitType::NONE},
1523-	{"flow", UnitType::FLOW},
1524-	{"flow-root", UnitType::FLOW_ROOT},
1525-	{"table", UnitType::TABLE},
1526-	{"flex", UnitType::FLEX},
1527-	{"grid", UnitType::GRID},
1528-	{"ruby", UnitType::RUBY},
1529-	{"table-row-group", UnitType::TABLE_ROW_GROUP},
1530-	{"table-header-group", UnitType::TABLE_HEADER_GROUP},
1531-	{"table-footer-group", UnitType::TABLE_FOOTER_GROUP},
1532-	{"table-column-group", UnitType::TABLE_COLUMN_GROUP},
1533-	{"table-row", UnitType::TABLE_ROW},
1534-	{"table-cell", UnitType::TABLE_CELL},
1535-	{"table-column", UnitType::TABLE_COLUMN},
1536-	{"table-caption", UnitType::TABLE_CAPTION},
1537-	{"ruby-base", UnitType::RUBY_BASE},
1538-	{"ruby-text", UnitType::RUBY_TEXT},
1539-	{"ruby-base-container", UnitType::RUBY_BASE_CONTAINER},
1540-	{"ruby-text-container", UnitType::RUBY_TEXT_CONTAINER},
1541-	{"inline-block", UnitType::INLINE_BLOCK},
1542-	{"inline-table", UnitType::INLINE_TABLE},
1543-	{"inline-flex", UnitType::INLINE_FLEX},
1544-	{"inline-grid", UnitType::INLINE_GRID},
1545-	{"list-item", UnitType::LISTITEM},
1546-	{"block", UnitType::BLOCK},
1547-	{"inline", UnitType::INLINE},
1548-	{"run-in", UnitType::RUN_IN},
1549-	{"linear", UnitType::LINEAR},
1550-	{"ease", UnitType::EASE},
1551-	{"ease-in", UnitType::EASE_IN},
1552-	{"ease-out", UnitType::EASE_OUT},
1553-	{"ease-in-out", UnitType::EASE_IN_OUT},
1554-	{"step-start", UnitType::STEP_START},
1555-	{"step-end", UnitType::STEP_END},
1556-	{"jump-start", UnitType::JUMP_START},
1557-	{"jump-end", UnitType::JUMP_END},
1558-	{"jump-none", UnitType::JUMP_NONE},
1559-	{"jump-both", UnitType::JUMP_BOTH},
1560-	{"serif", UnitType::SERIF},
1561-	{"sans-serif", UnitType::SANS_SERIF},
1562-	{"monospace", UnitType::MONOSPACE},
1563-	{"cursive", UnitType::CURSIVE},
1564-	{"fantasy", UnitType::FANTASY},
1565-	{"system-ui", UnitType::SYSTEM_UI},
1566-	{"ui-serif", UnitType::UI_SERIF},
1567-	{"ui-sans-serif", UnitType::UI_SANS_SERIF},
1568-	{"ui-monospace", UnitType::UI_MONOSPACE},
1569-	{"ui-rounded", UnitType::UI_ROUNDED},
1570-	{"math", UnitType::MATH},
1571-	{"fangsong", UnitType::FANGSONG},
1572-	{"top", UnitType::TOP},
1573-	{"left", UnitType::LEFT},
1574-	{"bottom", UnitType::BOTTOM},
1575-	{"right", UnitType::RIGHT},
1576-	{"center", UnitType::CENTER},
1577-	{"start", UnitType::START},
1578-	{"end", UnitType::END},
1579-	{"inline-start", UnitType::INLINE_START},
1580-	{"inline-end", UnitType::INLINE_END},
1581-	{"block-start", UnitType::BLOCK_START},
1582-	{"block-end", UnitType::BLOCK_END},
1583-	{"self-start", UnitType::SELF_START},
1584-	{"self-end", UnitType::SELF_END},
1585-	{"flex-start", UnitType::FLEX_START},
1586-	{"flex-end", UnitType::FLEX_END},
1587-	{"circle", UnitType::CIRCLE},
1588-	{"ellipse", UnitType::ELLIPSE},
1589-	{"shorterhue", UnitType::SHORTER_HUE},
1590-	{"longerhue", UnitType::LONGER_HUE},
1591-	{"increasinghue", UnitType::INCREASING_HUE},
1592-	{"decreasinghue", UnitType::DECREASING_HUE},
1593-	{"dotted", UnitType::DOTTED},
1594-	{"dashed", UnitType::DASHED},
1595-	{"solid", UnitType::SOLID},
1596-	{"double", UnitType::DOUBLE},
1597-	{"groove", UnitType::GROOVE},
1598-	{"ridge", UnitType::RIDGE},
1599-	{"inset", UnitType::INSET},
1600-	{"outset", UnitType::OUTSET},
1601-	{"baseline", UnitType::FIRST_BASELINE},
1602-	{"firstbaseline", UnitType::FIRST_BASELINE},
1603-	{"lastbaseline", UnitType::LAST_BASELINE},
1604-	{"safe", UnitType::SAFE},
1605-	{"unsafe", UnitType::UNSAFE},
1606-	{"visible", UnitType::VISIBLE},
1607-	{"clip", UnitType::CLIP},
1608-	{"scroll", UnitType::SCROLL},
1609-	{"inherit", UnitType::INHERIT},
1610-	{"initial", UnitType::INITIAL},
1611-	{"revert", UnitType::REVERT},
1612-	{"revert-layer", UnitType::REVERT_LAYER},
1613-	{"unset", UnitType::UNSET},
1614-	{"nearest", UnitType::NEAREST},
1615-	{"up", UnitType::UP},
1616-	{"down", UnitType::DOWN},
1617-	{"to-zero", UnitType::TO_ZERO},
1618+struct AbsSize {
1619+	const char* key;
1620+	float value;
1621 };
1622 
1623-static const std::unordered_map<std::string_view, UnitType> kFunc{
1624-	{"calc", UnitType::CALC},
1625-	{"min", UnitType::MIN},
1626-	{"max", UnitType::MAX},
1627-	{"clamp", UnitType::CLAMP},
1628-	{"round", UnitType::ROUND},
1629-	{"mod", UnitType::MOD},
1630-	{"progress", UnitType::PROGRESS},
1631-	{"rem", UnitType::REMD},
1632-	{"pow", UnitType::POW},
1633-	{"sqrt", UnitType::SQRT},
1634-	{"set", UnitType::SET},
1635-	{"let", UnitType::LET},
1636-	{"hypot", UnitType::HYPOT},
1637-	{"log", UnitType::LOG},
1638-	{"exp", UnitType::EXP},
1639-	{"abs", UnitType::ABS},
1640-	{"sin", UnitType::SIN},
1641-	{"cos", UnitType::COS},
1642-	{"tan", UnitType::TAN},
1643-	{"asin", UnitType::ASIN},
1644-	{"acos", UnitType::ACOS},
1645-	{"atan", UnitType::ATAN},
1646-	{"atan2", UnitType::ATAN2},
1647-	{"sign", UnitType::SIGN},
1648-	{"var", UnitType::VAR_FUNC},
1649-	{"rgb", UnitType::RGB},
1650-	{"rgba", UnitType::RGBA},
1651-	{"hsl", UnitType::HSL},
1652-	{"linear", UnitType::LINEAR_EASING_FUNCTION},
1653-	{"cubic-bezier", UnitType::CUBIC_BEZIER_FUNCTION},
1654-	{"steps", UnitType::STEPS_FUNCTION},
1655-	{"blur", UnitType::BLUR},
1656-	{"brightness", UnitType::BRIGHTNESS},
1657-	{"contrast", UnitType::CONTRAST},
1658-	{"drop-shadow", UnitType::DROP_SHADOW},
1659-	{"grayscale", UnitType::GRAYSCALE},
1660-	{"hue-rotate", UnitType::HUE_ROTATE},
1661-	{"invert", UnitType::INVERT},
1662-	{"opacity", UnitType::OPACITY},
1663-	{"sepia", UnitType::SEPIA},
1664-	{"saturate", UnitType::SATURATE},
1665-	{"image", UnitType::IMAGE},
1666-	{"image-set", UnitType::IMAGE_SET},
1667-	{"cross-fade", UnitType::CROSS_FADE},
1668-	{"element", UnitType::ELEMENT},
1669-	{"gradient", UnitType::GRADIENT},
1670-	{"matrix", UnitType::MATRIX},
1671-	{"matrix3d", UnitType::MATRIX3D},
1672-	{"perspective", UnitType::PERSPECTIVE},
1673-	{"rotate", UnitType::ROTATE},
1674-	{"rotate3d", UnitType::ROTATE3D},
1675-	{"rotateX", UnitType::ROTATEX},
1676-	{"rotateY", UnitType::ROTATEY},
1677-	{"rotateZ", UnitType::ROTATEZ},
1678-	{"scale", UnitType::SCALE},
1679-	{"scale3d", UnitType::SCALE3D},
1680-	{"scaleX", UnitType::SCALEX},
1681-	{"scaleY", UnitType::SCALEY},
1682-	{"scaleZ", UnitType::SCALEZ},
1683-	{"translate", UnitType::TRANSLATE},
1684-	{"translate3d", UnitType::TRANSLATE3D},
1685-	{"translateX", UnitType::TRANSLATEX},
1686-	{"translateY", UnitType::TRANSLATEY},
1687-	{"translateZ", UnitType::TRANSLATEZ},
1688-	{"skew", UnitType::SKEW},
1689-	{"skewX", UnitType::SKEWX},
1690-	{"skewY", UnitType::SKEWY},
1691-	{"url", UnitType::URL},
1692-	{"attr", UnitType::ATTR},
1693-	{"type", UnitType::TYPE},
1694-	{"env", UnitType::ENV},
1695-	{"if", UnitType::IF},
1696-	{"var", UnitType::VAR},
1697-	{"print", UnitType::PRINT},
1698-	{"list", UnitType::LIST},
1699-	{"at", UnitType::AT},
1700-	{"empty", UnitType::EMPTY},
1701-	{"insert", UnitType::INSERT},
1702-	{"size", UnitType::SIZE},
1703-	{"", UnitType::GROUP}
1704-};
1705-
1706-static const std::unordered_map<std::string_view, float> kAbsSize{
1707+static const struct AbsSize kAbsSize[] = {
1708 	{"xx-small",0.6f}, {"x-small",0.75f}, {"small",0.89f}, {"medium",1.0f},
1709 	{"large",1.2f}, {"x-large",1.5f}, {"xx-large",2.0f}, {"xxx-large",3.0f}
1710 };
1711 
1712+/*
1713 // Parses a string into Unit's and stores variables & strings into the Style object
1714 
1715-std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullptr) {
1716-	SymbolTable localTable;
1717-	SymbolTable& table = (externalTable != nullptr) ? *externalTable : localTable;
1718+void getUnit(SymbolTable* sym, Unit* units, int* unit_len, char* value, int size) {
1719+	char buffer[1024];
1720+	int buffer_len = 0;
1721+
1722+	char str_buffer[MAX_STR_LEN];
1723+	int str_buffer_len = 0;
1724 
1725-	std::vector<Unit> units;
1726-	
1727-	std::string buffer = "";
1728-	std::string str_buffer = "";
1729 	int parenDepth = 0;
1730 	bool inQuotes = false;
1731 	// Needs to not be empty but can't be a quote
1732@@ -963,24 +92,25 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
1733 	bool inlineComment = false;
1734 	bool multilineComment = false;
1735 
1736-	for (size_t i = 0; i < value.length(); i++) {
1737+	for (size_t i = 0; i < size; i++) {
1738 		char v = value[i];
1739 		if (v == '\\' && !escaped) escaped = true;
1740 		if (!escaped && (v == '"' || v == '\'') && parenDepth == 0) {
1741 			if (inQuotes && v == quoteType) {
1742-				Unit unit{};
1743-				unit.type = UnitType::STRING;
1744-				unit.value = str_buffer.length();
1745-				units.push_back(unit);
1746-
1747-				for (size_t j = 0; j < str_buffer.length(); j++) {
1748-					Unit unit{};
1749-					unit.type = UnitType::CHAR;
1750+				Unit unit;
1751+				unit.type = STRING;
1752+				unit.value = str_buffer_len;
1753+				units[units_len++] = unit;
1754+
1755+				for (size_t j = 0; j < str_buffer_len; j++) {
1756+					Unit unit;
1757+					unit.type = CHAR;
1758 					unit.value = str_buffer[j];
1759-					units.push_back(unit);
1760+					units[units_len++] = unit;
1761 				}
1762 
1763-				str_buffer.clear();	
1764+				str_buffer[0] = '\0';
1765+				str_buffer_len = 0;
1766 				inQuotes = false;
1767 			} else if (!inQuotes) {
1768 				quoteType = v;
1769@@ -989,7 +119,7 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
1770 			continue;
1771 		}
1772 
1773-		if (i+1 < value.length()) {
1774+		if (i+1 < size) {
1775 			if (v == '/' && value[i+1] == '/') {
1776 				inlineComment = true;
1777 				continue;
1778@@ -1007,7 +137,6 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
1779 			}
1780 
1781 			if (multilineComment) {
1782-				std::cout << i << std::endl;
1783 				if (v == '*' && value[i+1] == '/') {
1784 					i++;
1785 					multilineComment = false;
1786@@ -1024,315 +153,194 @@ std::vector<Unit> getUnit(std::string value, SymbolTable* externalTable = nullpt
1787 		}
1788 
1789 		if (parenDepth > 0) {
1790-			buffer.push_back(v);
1791+			buffer[buffer_len++] = v;
1792 			continue;
1793 		} else if (v == ')') {
1794 
1795 			//	Function handling
1796 
1797 			// We are at the end of the parentheseses and we need to pass it for more parsing
1798-			std::string name;
1799+			char name[MAX_STR_LEN];
1800+			int name_len = 0;
1801+
1802 			bool nameset = false;
1803-			std::string value;
1804 
1805-			for (size_t j = 0; j < buffer.size(); j++) {
1806+			char args[MAX_STR_LEN];
1807+			int args_len = 0;
1808+
1809+			for (size_t j = 0; j < buffer_len; j++) {
1810 				if (nameset) {
1811-					value.push_back(buffer[j]);
1812+					args[arg_len++] = buffer[j];
1813 				} else {
1814-					if (buffer[j] == '(') nameset = true;
1815-					else name.push_back(buffer[j]);
1816+					if (buffer[j] == '(') {
1817+						nameset = true;
1818+					} else {
1819+						name[name_len++] = buffer[j];
1820+					}
1821 				}
1822 			}
1823 
1824-			std::vector<Unit> children = getUnit(value, &table);
1825-			
1826+			Unit* children;	
1827+			int children_len = 0;
1828+			getUnit(sym, children, &children_len, &args, args_len);
1829+
1830 			Unit unit;
1831 
1832-			if (auto it = kFunc.find(name); it != kFunc.end()) { 
1833-				unit.type = it->second;
1834+			const struct FuncMap* fm = find_func(name, name_len);
1835+
1836+			if (fm) { 
1837+				unit.type = fm->type;
1838 			} else {
1839-				unit.type = UnitType::FUNC;
1840+				unit.type = FUNC;
1841 			}
1842 
1843 			// The value of the function is the child count
1844-			unit.value = children.size();
1845+			unit.value = children_len;
1846 
1847-			units.push_back(unit);
1848-			units.insert(units.end(), children.begin(), children.end());
1849-			// Add a end value for the function
1850+			units[units_len++] = unit;
1851 
1852-			buffer.clear();
1853-		} else if ((!inQuotes && (v == ',' ||  std::isspace(v))) || i >= value.length()-1) {
1854-			if (v != ',' && !std::isspace(v)) buffer.push_back(v);
1855+			for (int j = 0; j < children_len; j++) {
1856+				units[units_len++] = children[j];
1857+			}
1858+			buffer[0] = '\0';
1859+			buffer_len = 0;
1860+		} else if ((!inQuotes && (v == ',' ||  isspace(v))) || i >= size - 1) {
1861+			if (v != ',' && !isspace(v)) {
1862+				buffer[buffer_len++] = v;
1863+			}
1864 
1865 			Unit unit;
1866 
1867 			// Split by spaces into parts
1868 
1869-			if (auto it = kMatch.find(buffer); it != kMatch.end()) { 
1870-				
1871+			const struct MatchMap* mm = find_match(buffer, buffer_len);
1872+			const struct ColorMap* cm = find_color(buffer, buffer_len);
1873+
1874+			if (mm) { 
1875 				//	Keyword Matching
1876 				
1877-				unit.type = it->second;
1878+				unit.type = mm->type;
1879 				// the value is not used here
1880-			} else if (auto it = kColors.find(buffer); it != kColors.end()) { 
1881-				
1882+				buffer[0] = '\0';
1883+				buffer_len = 0;
1884+			} else if (cm) { 
1885 				//	Color Matching
1886 				
1887 				unit.type = UnitType::HEX;
1888-				unit.value = it->second;
1889+				unit.value = cm->hex;
1890+				buffer[0] = '\0';
1891+				buffer_len = 0;
1892+
1893 			} else {
1894 				bool found = false;
1895-				for (const auto& [suffix, type, trim] : sufMatch) {
1896-					if (buffer.ends_with(suffix)) {
1897+				size_t suf_match_length = sizeof(sufMatch) / sizeof(sufMatch[0]);
1898+
1899+				for (int j = 0; j < suf_match_length; j++) {
1900+					if (strcmp(buffer + (buffer_len-sufMatch[j].trim), sufMatch[j].suffix)) {
1901 						found = true;
1902 						try {
1903-							unit.value = std::stof(std::string(buffer.substr(0, buffer.size() - trim)));
1904+							buffer[buffer_len-sufMatch[j].trim] = '\0';
1905+							unit.value = (float)atof(buffer);
1906 						} catch (...) {
1907 							unit.value = 0.0f;
1908 						}
1909 
1910-						unit.type = type;
1911+						unit.type = sufMatch[j].type;
1912+						buffer[0] = '\0';
1913+						buffer_len = 0;
1914 						break;
1915 					}
1916 				}
1917 
1918 				if (!found) {
1919-					if (buffer.starts_with("#") && buffer.length() > 1) {
1920-						
1921+					if (buffer[0] == '#' && buffer_len > 1) {
1922 						//	# Prefix for HEX codes
1923 						
1924-						unit.type = UnitType::HEX;
1925-						unit.value = std::bit_cast<float>(static_cast<uint32_t>(std::stoul(buffer.substr(1), nullptr, 16)));
1926-					} else if (auto it = kAbsSize.find(buffer); it != kAbsSize.end()) { 
1927-						
1928-						//	Absolute size matching
1929-						
1930-						unit.type = UnitType::EM;
1931-						unit.value = it->second;
1932-					} else if (buffer == "true") {
1933-						unit.type = UnitType::BOOL;
1934-						unit.value = true;
1935-					} else if (buffer == "false") {
1936-						unit.type = UnitType::BOOL;
1937-						unit.value = false;
1938+						unit.type = HEX;
1939+						uint32_t u32 = (uint32_t)strtoul(buffer+1, NULL, 16);
1940+						float f;
1941+						memcpy(&f, &u32, sizeof(f));
1942+						unit.value = f;
1943 					} else {
1944-						// Maybe its a number?
1945-						try {
1946-							unit.value = std::stof(buffer);
1947-							unit.type = UnitType::NUMBER;
1948-						} catch (...) {
1949-							// If we are here it is not a known parsable word, this could be a typo 
1950-							// or a keyword like with the attr(size px) function. Here px would be
1951-							// parsed but not size.
1952-							if (!buffer.empty() && buffer.find_first_not_of(' ') != std::string::npos) {
1953-								if (buffer[0] == ':') {
1954-									unit.type = UnitType::TAG;
1955-									unit.value = table.get(buffer);
1956+						int abs_length = sizeof(kAbsSize) / sizeof(kAbsSize[0]);
1957 
1958-								} else {
1959-									unit.type = UnitType::VAR;
1960-									unit.value = table.get(buffer);
1961-								}
1962+						//	Absolute size matching
1963+						for (int j = 0; j < abs_length; j++) {
1964+							if (strmp(buffer, kAbsSize[j].key)) {
1965+								unit.type = EM;
1966+								unit.value = kAbsSize[j].value;
1967+								found = true;
1968+								break;
1969+							}
1970+						}
1971+
1972+						if (!found) { 
1973+							if (strcmp(buffer, "true")) {
1974+								unit.type = BOOL;
1975+								unit.value = true;
1976+							} else if (strcmp(buffer, "false")) {
1977+								unit.type = BOOL;
1978+								unit.value = false;
1979 							} else {
1980-								continue;
1981+								// Maybe its a number?
1982+								try {
1983+									unit.value = (float)atof(buffer);
1984+									unit.type = UnitType::NUMBER;
1985+								} catch (...) {
1986+									// If we are here it is not a known parsable word, this could be a typo 
1987+									// or a keyword like with the attr(size px) function. Here px would be
1988+									// parsed but not size.
1989+									if (buffer_len > 0) {
1990+										if (buffer[0] == ':') {
1991+											unit.type = TAG;
1992+											unit.value = intern_string(sym, buffer);
1993+
1994+										} else {
1995+											unit.type = VAR;
1996+											unit.value = intern_string(sym, buffer);
1997+										}
1998+									} else {
1999+										continue;
2000+									}
2001+								}
2002 							}
2003 						}
2004 					}
2005 				}
2006 			}
2007 
2008-			units.push_back(unit);
2009-			buffer.clear();
2010+			units[units_len++] = unit;
2011+			buffer[0] = '\0';
2012+			buffer_len = 0;
2013 		} else if (inQuotes) {
2014-			str_buffer.push_back(v);
2015+			str_buffer[str_buffer_len++] = v;
2016 		} else {
2017-			buffer.push_back(v);
2018+			buffer[buffer_len++] = v;
2019 		}
2020 
2021 		escaped = false;
2022 		if (v == '\\') escaped = true;
2023 	}
2024-
2025-	return units;
2026 }
2027 */
2028-/*
2029-void css_parser(std::istream& inputStream) {
2030-	// nowhitespace: value(can have whitespace); = property
2031-	// a selector name is anything before a { up to a ; or a }
2032-	std::vector<Style*> stack;
2033-	Style root{};
2034-	Style* current = &root;
2035-
2036-	// how to handle @import
2037-
2038-	std::string buffer;
2039-
2040-	bool incomment = false;
2041-
2042-
2043-	SymbolTable table;
2044-
2045-	char ch;
2046-	while (inputStream.get(ch)) {
2047-		if (ch == '*' && inputStream.peek() == '/') {
2048-			incomment = false;
2049-			// Skip ahead to the next letter so we don't capture the trailing /
2050-			inputStream.get(ch);
2051-			continue;
2052-		}
2053-		if (ch == '/' && inputStream.peek() == '*') {
2054-			incomment = true;
2055-		}
2056-		
2057-		if (incomment) {
2058-			continue;
2059-		}
2060-
2061-		if (ch == '{') {
2062-			for (size_t i = buffer.length()-1; i >= 0; i--) {
2063-				if (std::isspace(buffer[i])) {
2064-					buffer.pop_back();
2065-				} else {
2066-					break;
2067-				}
2068-			}
2069-
2070-			// Parse the selector into its parts
2071-			std::vector<std::vector<std::string>> parts = parseSelectorParts(buffer);
2072-
2073-			if (current->selector.size() > 0) {
2074-				// To be able to handle a substitution with a parent that has h1, h2
2075-				// we need to rebuild the selector so we can add new copies
2076-				std::vector<std::vector<std::string>> subd;
2077-
2078-				// Look for any & if its a style and replace it with the parsed parent selector
2079-				for (size_t i = 0; i < parts.size(); i++) {
2080-					bool hasAmp = false;
2081-					for (size_t e = 0; e < parts[i].size(); e++) {
2082-						if (parts[i][e] == "&") {
2083-							hasAmp = true;
2084-							break;
2085-						}
2086-					}
2087-
2088-					if (hasAmp) {
2089-						// If it contains a amp then we need replace the amp with each parent selector
2090-						// Inject each part of the parent
2091-						// Parent [[h1],[h2]]
2092-						// Child: [[& .class, &, &]]
2093-						// Result: [[h1 .class, h1, h1]]
2094-						// 	   [[h2 .class, h2, h2]]
2095-						for (size_t e = 0; e < current->selector.size(); e++) {
2096-							std::vector<std::string> temp;
2097-							for (size_t f = 0; f < parts[i].size(); f++) {
2098-								if (parts[i][f] == "&") {
2099-									for (auto p : current->selector[e]) {
2100-										temp.push_back(p);
2101-									}
2102-								} else {
2103-									temp.push_back(parts[i][f]);
2104-								}
2105-							}
2106-							subd.push_back(temp);
2107-						}
2108-					} else {
2109-						// If there's nothing to replace just add to back
2110-						subd.push_back(parts[i]);
2111-					}
2112-				}
2113 
2114-				parts = subd;
2115-			}
2116-
2117-			stack.push_back(current);
2118-
2119-			Style newSheet{};
2120-			newSheet.selector = parts;
2121-			current->addChild(newSheet);
2122+// Basemap maps sym tokens to arrays of indexes to the selector list
2123+// @container (width > 200px)			| getUnit
2124+// @import "url"				| Resolve at compile
2125+// @keyframes					| Seperate thing
2126+// @import "theme.css" layer(utilities);	| Changes specificity 
2127+// @layer module, state;			| -
2128+// @media not all and (hover: hover)  		| getUnit
2129+// !important
2130 
2131-			current = &current->children.back();
2132-
2133-			buffer.clear();
2134-		} else if (ch == '}') {
2135-				
2136-			if (!stack.empty()) {
2137-				current = stack.back();
2138-				stack.pop_back();
2139-			}
2140+// specificity will be calculated during style computing
2141 
2142-                        buffer.clear();
2143-		} else if (ch == ';') {
2144-			if (buffer[0] == '@') {
2145-				// Single line at-rule
2146-				Style inlineRule;
2147-				std::vector<std::vector<std::string>> parts = parseSelectorParts(buffer);
2148-				inlineRule.selector = parts;
2149-				
2150-				if (parts[0][0] == "@import") {
2151-					inlineRule.selector = parts;
2152-
2153-					if (parts[0].size() > 3) {
2154-						// See if the last word ends in )
2155-						// if not then its the name of the layer
2156-						if (parts[0].back().back() != ')') {
2157-							inlineRule.name = parts[0].back();
2158-						}
2159-					}
2160-
2161-				} else if (parts[0][0] == "@layer") {
2162-					// ISSUE: need to add specificity
2163-
2164-				}
2165-
2166-				current->addChild(inlineRule);
2167-
2168-			} else {
2169-				// end of a style property
2170-				std::string key;
2171-				std::string value;
2172-				bool keyFound = false;
2173-				bool firstValue = false;
2174-				for (size_t i = 0; i < buffer.length(); i++) {
2175-					char c = buffer[i];
2176-					if (!keyFound && c == ':') {
2177-						keyFound = true;
2178-					} else if (!std::isspace(c) && !keyFound) {
2179-						key += c;
2180-					} else if (!firstValue && keyFound && !std::isspace(c)) {
2181-						firstValue = true;
2182-						value += c;
2183-					} else if (keyFound && firstValue && !(std::isspace(c) && i < buffer.length()-1 && std::isspace(buffer[i+1]))) {
2184-						// if the key is found and the character isn't a ':'
2185-						// 	also (if c is a space and the next c will be a space)
2186-						// 	this is to auto trim duplicate spaces from the value
2187-						value += c;
2188-					}
2189-				}
2190-
2191-				if (key.length() > 2 && key[0] == '-' && key[1] == '-') {
2192-					current->variables.set(key, getUnit(value, &table));
2193-				} else {
2194-					KeyType keyENUM;
2195-
2196-					if (auto it = keySearch.find(key); it != keySearch.end()) {
2197-						keyENUM = it->second;
2198-					} else {
2199-						std::cout << "Invalid property name: " << key << std::endl;
2200-					}
2201-					current->properties[keyENUM] = getUnit(value, &table);
2202-				}
2203-			}
2204-			buffer.clear();
2205-		} else {
2206-			buffer.push_back(ch);
2207-		}
2208-	}
2209-
2210-	return root;
2211-}*/
2212+// media queries [[selector_index, index_to_media_query_in_selectors]]
2213+/*
2214+void css_parser(SymbolTable* sym, char* input, int size, int** basemap, Unit** selectors, Style* styles, Query* queries) {
2215 
2216+}
2217+*/
2218 /*
2219 std::string get_working_path() {
2220     char temp [ PATH_MAX ];