diff --git a/LICENSE b/LICENSE
index 24ed56b..c709af1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2023 Government Digital Services, Singapore
+Copyright (c) 2023 greyguy21
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 132c397..58a6dd9 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1 @@
-# purple-ai
-GPT responses for Accessibility
+# purple-ai-test
\ No newline at end of file
diff --git a/catalog.json b/catalog.json
index 3652078..5cfce86 100644
--- a/catalog.json
+++ b/catalog.json
@@ -1,3 +1,55 @@
-{  
-  "lastUpdated": "01/09/2023, 12:00:00 AM"
+{
+  "lastUpdated": "9/29/2023, 8:07:04 AM",
+  "label": [
+    "input_tabindex_value",
+    "input_type_value",
+    "input_type",
+    "input_name_style"
+  ],
+  "aria-required-parent": ["a_role=\"tab\""],
+  "aria-required-children": ["ul_role=\"tablist\""],
+  "landmark-unique": [
+    "nav",
+    "nav_aria-label",
+    "footer_onclick",
+    "div_aria-label_role",
+    "header",
+    "nav_style",
+    "main",
+    "nav_role",
+    "iframe_aria-label_name_role_style_tabindex_title"
+  ],
+  "aria-allowed-role": [
+    "button_role=\"presentation\"",
+    "form_role=\"form\"",
+    "input_role=\"button\"",
+    "a_role=\"tooltip\"",
+    "button_role=\"heading\"",
+    "iframe_role=\"region\"",
+    "section_role=\"tablist\"",
+    "textarea_role=\"combobox\"",
+    "label_role=\"radio\"",
+    "section_role=\"list\"",
+    "li_role=\"button\"",
+    "input_role=\"link\""
+  ],
+  "presentation-role-conflict": ["button_role_type_i"],
+  "scrollable-region-focusable": ["div"],
+  "aria-allowed-attr": ["div_aria-expanded"],
+  "select-name": ["select_name"],
+  "aria-hidden-focus": [
+    "div_aria-hidden_style",
+    "li_aria-controls_aria-hidden_aria-selected_role_button_role_tabindex_type"
+  ],
+  "aria-input-field-name": ["div_role_style", "div_role"],
+  "aria-toggle-field-name": [
+    "div_aria-describedby_aria-hidden_role_style_tabindex"
+  ],
+  "aria-valid-attr": ["a_aria-controls_aria-disabled_aria-role_tabindex"],
+  "aria-roles": [
+    "section_role=\"main-content\"",
+    "aside_role=\"right-content\"",
+    "fieldset_role=\"radio-group\"",
+    "div_role=\"pagination\""
+  ]
 }
diff --git a/catalog_test.json b/catalog_test.json
new file mode 100644
index 0000000..04c5778
--- /dev/null
+++ b/catalog_test.json
@@ -0,0 +1,13 @@
+{
+	"aria-hidden-focus": ["div_aria-hidden", "div_aria-hidden_data-slice-index_style_tabindex_div"],
+	"aria-input-field-name": ["div_class_role"],
+	"aria-roles": [],
+	"aria-toggle-field-name": [],
+	"aria-valid-attr-value": ["li_aria-controls_aria-selected_data-analytics-click-id_data-analytics-section_data-analytics-text_role","div_aria-labelledby_data-guide-parent-id_role"],
+	"aria-valid-attr": [],
+	"marquee": [],
+	"nested-interactive": ["div_role","li_aria-controls_aria-selected_class_role_data-analytics-click-id_data-analytics-text_data-analytics-section"],
+	"avoid-inline-spacing": [],
+	"aria-allowed-role": [],
+	"tabindex": []
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..e412ed5
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,749 @@
+{
+    "name": "purple-ai-test",
+    "lockfileVersion": 3,
+    "requires": true,
+    "packages": {
+        "": {
+            "dependencies": {
+                "dotenv": "^16.3.1",
+                "github-api": "^3.4.0",
+                "google-auth-library": "^8.9.0",
+                "google-spreadsheet": "^4.0.2",
+                "openai": "^3.3.0",
+                "prettier": "^2.8.8",
+                "winston": "^3.9.0"
+            }
+        },
+        "node_modules/@colors/colors": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+            "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+            "engines": {
+                "node": ">=0.1.90"
+            }
+        },
+        "node_modules/@dabh/diagnostics": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
+            "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+            "dependencies": {
+                "colorspace": "1.1.x",
+                "enabled": "2.0.x",
+                "kuler": "^2.0.0"
+            }
+        },
+        "node_modules/@types/triple-beam": {
+            "version": "1.3.2",
+            "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz",
+            "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g=="
+        },
+        "node_modules/agent-base": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+            "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+            "dependencies": {
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/agent-base/node_modules/debug": {
+            "version": "4.3.4",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+            "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+            "dependencies": {
+                "ms": "2.1.2"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/agent-base/node_modules/ms": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+        },
+        "node_modules/arrify": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+            "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/async": {
+            "version": "3.2.4",
+            "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+            "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
+        },
+        "node_modules/asynckit": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+            "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+        },
+        "node_modules/axios": {
+            "version": "0.21.4",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+            "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+            "dependencies": {
+                "follow-redirects": "^1.14.0"
+            }
+        },
+        "node_modules/base64-js": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+            "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/bignumber.js": {
+            "version": "9.1.1",
+            "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz",
+            "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/buffer-equal-constant-time": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+            "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+        },
+        "node_modules/color": {
+            "version": "3.2.1",
+            "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+            "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+            "dependencies": {
+                "color-convert": "^1.9.3",
+                "color-string": "^1.6.0"
+            }
+        },
+        "node_modules/color-convert": {
+            "version": "1.9.3",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+            "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+            "dependencies": {
+                "color-name": "1.1.3"
+            }
+        },
+        "node_modules/color-name": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+            "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+        },
+        "node_modules/color-string": {
+            "version": "1.9.1",
+            "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+            "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+            "dependencies": {
+                "color-name": "^1.0.0",
+                "simple-swizzle": "^0.2.2"
+            }
+        },
+        "node_modules/colorspace": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
+            "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
+            "dependencies": {
+                "color": "^3.1.3",
+                "text-hex": "1.0.x"
+            }
+        },
+        "node_modules/combined-stream": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+            "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+            "dependencies": {
+                "delayed-stream": "~1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/delayed-stream": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+            "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/dotenv": {
+            "version": "16.3.1",
+            "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
+            "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/motdotla/dotenv?sponsor=1"
+            }
+        },
+        "node_modules/ecdsa-sig-formatter": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+            "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/enabled": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
+            "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
+        },
+        "node_modules/extend": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+            "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+        },
+        "node_modules/fast-text-encoding": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz",
+            "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w=="
+        },
+        "node_modules/fecha": {
+            "version": "4.2.3",
+            "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
+            "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
+        },
+        "node_modules/fn.name": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
+            "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
+        },
+        "node_modules/follow-redirects": {
+            "version": "1.15.2",
+            "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+            "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+            "funding": [
+                {
+                    "type": "individual",
+                    "url": "https://github.com/sponsors/RubenVerborgh"
+                }
+            ],
+            "engines": {
+                "node": ">=4.0"
+            },
+            "peerDependenciesMeta": {
+                "debug": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/form-data": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+            "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+            "dependencies": {
+                "asynckit": "^0.4.0",
+                "combined-stream": "^1.0.8",
+                "mime-types": "^2.1.12"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/gaxios": {
+            "version": "5.1.3",
+            "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz",
+            "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==",
+            "dependencies": {
+                "extend": "^3.0.2",
+                "https-proxy-agent": "^5.0.0",
+                "is-stream": "^2.0.0",
+                "node-fetch": "^2.6.9"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/gcp-metadata": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz",
+            "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==",
+            "dependencies": {
+                "gaxios": "^5.0.0",
+                "json-bigint": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/github-api": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/github-api/-/github-api-3.4.0.tgz",
+            "integrity": "sha512-2yYqYS6Uy4br1nw0D3VrlYWxtGTkUhIZrumBrcBwKdBOzMT8roAe8IvI6kjIOkxqxapKR5GkEsHtz3Du/voOpA==",
+            "dependencies": {
+                "axios": "^0.21.1",
+                "debug": "^2.2.0",
+                "js-base64": "^2.1.9",
+                "utf8": "^2.1.1"
+            }
+        },
+        "node_modules/google-auth-library": {
+            "version": "8.9.0",
+            "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.9.0.tgz",
+            "integrity": "sha512-f7aQCJODJFmYWN6PeNKzgvy9LI2tYmXnzpNDHEjG5sDNPgGb2FXQyTBnXeSH+PAtpKESFD+LmHw3Ox3mN7e1Fg==",
+            "dependencies": {
+                "arrify": "^2.0.0",
+                "base64-js": "^1.3.0",
+                "ecdsa-sig-formatter": "^1.0.11",
+                "fast-text-encoding": "^1.0.0",
+                "gaxios": "^5.0.0",
+                "gcp-metadata": "^5.3.0",
+                "gtoken": "^6.1.0",
+                "jws": "^4.0.0",
+                "lru-cache": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/google-p12-pem": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.1.tgz",
+            "integrity": "sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==",
+            "dependencies": {
+                "node-forge": "^1.3.1"
+            },
+            "bin": {
+                "gp12-pem": "build/src/bin/gp12-pem.js"
+            },
+            "engines": {
+                "node": ">=12.0.0"
+            }
+        },
+        "node_modules/google-spreadsheet": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/google-spreadsheet/-/google-spreadsheet-4.0.2.tgz",
+            "integrity": "sha512-A5Y3HdgQhwnc16cwfwIdMS1FR2rAVRBa+4RLO8jbuUPYWOGMTPWqhl1mkIB5XOT+w69znoXMHeNgaNbKZp0J2g==",
+            "dependencies": {
+                "axios": "^1.4.0",
+                "lodash": "^4.17.21"
+            },
+            "peerDependencies": {
+                "google-auth-library": "^8.8.0"
+            },
+            "peerDependenciesMeta": {
+                "google-auth-library": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/google-spreadsheet/node_modules/axios": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
+            "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+            "dependencies": {
+                "follow-redirects": "^1.15.0",
+                "form-data": "^4.0.0",
+                "proxy-from-env": "^1.1.0"
+            }
+        },
+        "node_modules/gtoken": {
+            "version": "6.1.2",
+            "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-6.1.2.tgz",
+            "integrity": "sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==",
+            "dependencies": {
+                "gaxios": "^5.0.1",
+                "google-p12-pem": "^4.0.0",
+                "jws": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=12.0.0"
+            }
+        },
+        "node_modules/https-proxy-agent": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+            "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+            "dependencies": {
+                "agent-base": "6",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/https-proxy-agent/node_modules/debug": {
+            "version": "4.3.4",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+            "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+            "dependencies": {
+                "ms": "2.1.2"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/https-proxy-agent/node_modules/ms": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+        },
+        "node_modules/inherits": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+        },
+        "node_modules/is-arrayish": {
+            "version": "0.3.2",
+            "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+            "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+        },
+        "node_modules/is-stream": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+            "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/js-base64": {
+            "version": "2.6.4",
+            "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
+            "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ=="
+        },
+        "node_modules/json-bigint": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
+            "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+            "dependencies": {
+                "bignumber.js": "^9.0.0"
+            }
+        },
+        "node_modules/jwa": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
+            "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
+            "dependencies": {
+                "buffer-equal-constant-time": "1.0.1",
+                "ecdsa-sig-formatter": "1.0.11",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/jws": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
+            "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
+            "dependencies": {
+                "jwa": "^2.0.0",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/kuler": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
+            "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
+        },
+        "node_modules/lodash": {
+            "version": "4.17.21",
+            "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+            "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+        },
+        "node_modules/logform": {
+            "version": "2.5.1",
+            "resolved": "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz",
+            "integrity": "sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==",
+            "dependencies": {
+                "@colors/colors": "1.5.0",
+                "@types/triple-beam": "^1.3.2",
+                "fecha": "^4.2.0",
+                "ms": "^2.1.1",
+                "safe-stable-stringify": "^2.3.1",
+                "triple-beam": "^1.3.0"
+            }
+        },
+        "node_modules/logform/node_modules/ms": {
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+            "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+        },
+        "node_modules/lru-cache": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+            "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/mime-db": {
+            "version": "1.52.0",
+            "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+            "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/mime-types": {
+            "version": "2.1.35",
+            "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+            "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+            "dependencies": {
+                "mime-db": "1.52.0"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+        },
+        "node_modules/node-fetch": {
+            "version": "2.6.12",
+            "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
+            "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
+            "dependencies": {
+                "whatwg-url": "^5.0.0"
+            },
+            "engines": {
+                "node": "4.x || >=6.0.0"
+            },
+            "peerDependencies": {
+                "encoding": "^0.1.0"
+            },
+            "peerDependenciesMeta": {
+                "encoding": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/node-forge": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
+            "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
+            "engines": {
+                "node": ">= 6.13.0"
+            }
+        },
+        "node_modules/one-time": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
+            "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
+            "dependencies": {
+                "fn.name": "1.x.x"
+            }
+        },
+        "node_modules/openai": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/openai/-/openai-3.3.0.tgz",
+            "integrity": "sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ==",
+            "dependencies": {
+                "axios": "^0.26.0",
+                "form-data": "^4.0.0"
+            }
+        },
+        "node_modules/openai/node_modules/axios": {
+            "version": "0.26.1",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
+            "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
+            "dependencies": {
+                "follow-redirects": "^1.14.8"
+            }
+        },
+        "node_modules/prettier": {
+            "version": "2.8.8",
+            "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+            "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+            "bin": {
+                "prettier": "bin-prettier.js"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            },
+            "funding": {
+                "url": "https://github.com/prettier/prettier?sponsor=1"
+            }
+        },
+        "node_modules/proxy-from-env": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+            "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+        },
+        "node_modules/readable-stream": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/safe-buffer": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+            "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/safe-stable-stringify": {
+            "version": "2.4.3",
+            "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
+            "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==",
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/simple-swizzle": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+            "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+            "dependencies": {
+                "is-arrayish": "^0.3.1"
+            }
+        },
+        "node_modules/stack-trace": {
+            "version": "0.0.10",
+            "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+            "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/string_decoder": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+            "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+            "dependencies": {
+                "safe-buffer": "~5.2.0"
+            }
+        },
+        "node_modules/text-hex": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
+            "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
+        },
+        "node_modules/tr46": {
+            "version": "0.0.3",
+            "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+            "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+        },
+        "node_modules/triple-beam": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
+            "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
+            "engines": {
+                "node": ">= 14.0.0"
+            }
+        },
+        "node_modules/utf8": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz",
+            "integrity": "sha512-QXo+O/QkLP/x1nyi54uQiG0XrODxdysuQvE5dtVqv7F5K2Qb6FsN+qbr6KhF5wQ20tfcV3VQp0/2x1e1MRSPWg=="
+        },
+        "node_modules/util-deprecate": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+            "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+        },
+        "node_modules/webidl-conversions": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+            "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+        },
+        "node_modules/whatwg-url": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+            "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+            "dependencies": {
+                "tr46": "~0.0.3",
+                "webidl-conversions": "^3.0.0"
+            }
+        },
+        "node_modules/winston": {
+            "version": "3.10.0",
+            "resolved": "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz",
+            "integrity": "sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g==",
+            "dependencies": {
+                "@colors/colors": "1.5.0",
+                "@dabh/diagnostics": "^2.0.2",
+                "async": "^3.2.3",
+                "is-stream": "^2.0.0",
+                "logform": "^2.4.0",
+                "one-time": "^1.0.0",
+                "readable-stream": "^3.4.0",
+                "safe-stable-stringify": "^2.3.1",
+                "stack-trace": "0.0.x",
+                "triple-beam": "^1.3.0",
+                "winston-transport": "^4.5.0"
+            },
+            "engines": {
+                "node": ">= 12.0.0"
+            }
+        },
+        "node_modules/winston-transport": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz",
+            "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==",
+            "dependencies": {
+                "logform": "^2.3.2",
+                "readable-stream": "^3.6.0",
+                "triple-beam": "^1.3.0"
+            },
+            "engines": {
+                "node": ">= 6.4.0"
+            }
+        },
+        "node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+        }
+    }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..9704157
--- /dev/null
+++ b/package.json
@@ -0,0 +1,12 @@
+{
+    "dependencies": {
+      "dotenv": "^16.3.1",
+      "github-api": "^3.4.0",
+      "google-auth-library": "^8.9.0",
+      "google-spreadsheet": "^4.0.2",
+      "openai": "^3.3.0",
+      "prettier": "^2.8.8",
+      "winston": "^3.9.0"
+    }
+  }
+  
\ No newline at end of file
diff --git a/purpleAIPrompts.json b/purpleAIPrompts.json
new file mode 100644
index 0000000..74a2a25
--- /dev/null
+++ b/purpleAIPrompts.json
@@ -0,0 +1,24 @@
+{
+  "aria-allowed-attr": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains ARIA attributes that are not allowed for the element's role. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-hidden-focus": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains aria-hidden elements that are focusable or contains focusable elements. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-input-field-name": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains ARIA input fields with inaccessible names. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-required-attr": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains elements with ARIA roles that do not have all required ARIA attributes . Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-required-children": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains ARIA roles that do not contain their required child roles. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-required-parent": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains ARIA roles that are not contained by their required parent roles. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-roles": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains elements with a role attribute that do not use a valid value. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-toggle-field-name": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains ARIA toggle fields that have inaccessible names. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-valid-attr": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains elements with attributes that begin with aria- that are invalid ARIA attributes. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-allowed-role": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains elements with inappropriate value for role attribute. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "form-field-multiple-labels": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains form fields with multiple label elements. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "label": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains form elements that do not have label. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "scrollable-region-focusable": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains elements with scrollable content that are not accessible by keyboard. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "select-name": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that select elements that do not have accessible names. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "landmark-unique": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains landmarks that do not have a unique role or role/label/title. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "presentation-role-conflict": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains elements marked as presentational that have global ARIA or tabindex. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "aria-treeitem-name": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains treeitem nodes that do not have accessible names. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "server-side-image-map": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains uses server-side image maps. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "svg-img-alt": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains has <svg> elements with an img, graphics-document or graphics-symbol-role that do not have an accessible text. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "autocomplete-valid": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains elements with autocomplete attribute that is incorrect and not suitable for form field. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  " aria-valid-attr-value": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains ARIA attributes that have invalid values. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}",
+  "meta-viewport-large": "A frontend software engineer working in a product team has been tasked to fix an accessibility issues. They are given a code snippet that contains <meta name=\"viewport\"> cannot scale a significant amount. Help to highlight the issue in a concise manner and provide the correct version of the code snippet. The code snippet is: ${htmlSnippet}"
+}
\ No newline at end of file
diff --git a/range.json b/range.json
new file mode 100644
index 0000000..dbd5750
--- /dev/null
+++ b/range.json
@@ -0,0 +1 @@
+{"offset":484,"limit":500}
\ No newline at end of file
diff --git a/results/aria-allowed-attr.json b/results/aria-allowed-attr.json
new file mode 100644
index 0000000..66efc7c
--- /dev/null
+++ b/results/aria-allowed-attr.json
@@ -0,0 +1,3 @@
+{
+  "div_aria-expanded": "The issue in the given code snippet is that the `aria-expanded` attribute is not allowed on a `div` element.\n\nTo fix the issue, you can use a button element instead of a div, as the `aria-expanded` attribute is allowed on button elements. Here's the corrected version of the code snippet:\n\n```\n<button aria-expanded=\"false\"></button>\n```"
+}
diff --git a/results/aria-allowed-role.json b/results/aria-allowed-role.json
new file mode 100644
index 0000000..efd552e
--- /dev/null
+++ b/results/aria-allowed-role.json
@@ -0,0 +1,14 @@
+{
+  "button_role=\"presentation\"": "The issue in the given code snippet is that the button element has an inappropriate role attribute value \"presentation\". The \"presentation\" role is used to remove the semantic meaning of an element, which is not suitable for a button. The correct version of the code snippet should not include the role attribute for a button element.\n\nCorrect version:\n\n<button type=\"button\"><i></i></button>",
+  "form_role=\"form\"": "The issue in the given code snippet is that the role attribute has an inappropriate value. The `form` element already has a default role of \"form\", so it is unnecessary to add a role attribute with the same value. To fix this, simply remove the role attribute from the `form` element.\n\nCorrected code snippet:\n\n```\n<form>\n```",
+  "input_role=\"button\"": "The issue in the given code snippet is that the `role` attribute has an inappropriate value. The element is an `input` with a `type` of \"checkbox\", but the `role` is set to \"button\". The correct role for a checkbox input should be \"checkbox\".\n\nHere's the corrected version of the code snippet:\n\n```html\n<input aria-expanded=\"false\" aria-label=\"...\" role=\"checkbox\" type=\"checkbox\">\n```",
+  "a_role=\"tooltip\"": "The issue in the given code snippet is that the `role` attribute has an inappropriate value \"tooltip\" for an anchor (`<a>`) element. The correct role for an anchor element is \"link\". Here is the corrected version of the code snippet:\n\n```html\n<a aria-describedby=\"tooltip-overview-5\" href=\"...\" role=\"link\"><i></i></a>\n```",
+  "button_role=\"heading\"": "The issue in this code snippet is that the `role` attribute has an inappropriate value \"heading\" for a button element. The correct value should be \"button\". Here's the corrected code snippet:\n\n```html\n<button aria-expanded=\"true\" role=\"button\" type=\"button\">\n```",
+  "iframe_role=\"region\"": "The issue in the given code snippet is that the `role` attribute is set to \"region\" for an `iframe` element. The \"region\" role is not appropriate for an `iframe`. Instead, you should use the \"document\" or \"application\" role for an `iframe` depending on its content.\n\nHere's the corrected version of the code snippet:\n\n```\n<iframe aria-label=\"...\" name=\"...\" role=\"document\" style=\"border: 0px; vertical-align: bottom;\" tabindex=\"0\" title=\"...\"></iframe>\n```\n\nIn this corrected version, the `role` attribute is set to \"document\". If the content of the `iframe` is more like an application, you can use `role=\"application\"` instead.",
+  "section_role=\"tablist\"": "The issue in the given code snippet is that the `role` attribute has an inappropriate value \"tablist\" for the `section` element. A `section` element should not have a \"tablist\" role as it is not semantically correct. The \"tablist\" role should be used with a `div` or similar container element that holds a group of tabs.\n\nHere's the corrected version of the code snippet:\n\n```\n<div role=\"tablist\">\n  <section>\n    <!-- Your content here -->\n  </section>\n</div>\n```\n\nIn this corrected version, I have wrapped the `section` element inside a `div` element and assigned the \"tablist\" role to the `div` element. Now, the `section` element can be used to represent a tab panel, while the `div` element with the \"tablist\" role will act as a container for the group of tabs.",
+  "textarea_role=\"combobox\"": "The issue in the code snippet is that the `role` attribute is set to \"combobox\" on a `textarea` element. A combobox role should be associated with an input element, not a textarea element. Also, the `type` attribute is not valid for a textarea element. Here's the corrected version of the code snippet:\n\n```html\n<div role=\"combobox\" aria-haspopup=\"both\" aria-owns=\"Alh6id\" aria-expanded=\"false\">\n  <input\n    aria-activedescendant=\"\"\n    aria-autocomplete=\"both\"\n    aria-controls=\"Alh6id\"\n    aria-label=\"...\"\n    name=\"...\"\n    title=\"...\"\n    type=\"search\"\n    value=\"...\"\n  />\n  <textarea aria-label=\"...\" name=\"...\" title=\"...\"></textarea>\n</div>\n```\n\nIn this corrected version, I've wrapped the input and textarea elements inside a div with the role of \"combobox\". The input element now has the appropriate attributes, and the textarea element no longer has the invalid attributes.",
+  "label_role=\"radio\"": "The issue in the code snippet is that the `role` attribute is set to \"radio\" for a `label` element, which is inappropriate. The `role` attribute should be set on the actual input element instead.\n\nHere's the correct version of the code snippet:\n\n```html\n<label for=\"radioInput\" aria-label=\"...\" title=\"...\">\n  <input\n    type=\"radio\"\n    id=\"radioInput\"\n    name=\"...\"\n    aria-checked=\"false\"\n    aria-required=\"true\"\n    tabindex=\"0\"\n    role=\"radio\"\n  >\n</label>\n```\n\nI moved the `role`, `aria-checked`, `aria-required`, `name`, and `tabindex` attributes to the correct `input` element and added a `for` attribute to the `label` element to associate it with the input.",
+  "section_role=\"list\"": "The issue in the code snippet is that the `role` attribute has an inappropriate value \"list\" for the `section` element. The correct version of the code snippet should use an appropriate element for the \"list\" role, such as an unordered list `<ul>` or an ordered list `<ol>`.\n\nCorrected code snippet:\n\n```html\n<ul role=\"list\">\n  <!-- List items go here -->\n</ul>\n```\n\nOr, if you want to use an ordered list:\n\n```html\n<ol role=\"list\">\n  <!-- List items go here -->\n</ol>\n```",
+  "li_role=\"button\"": "The issue in the code snippet is that the `role` attribute is set to \"button\" for a list item (`<li>`), which is inappropriate. List items should have a role of \"listitem\". Here's the corrected version of the code snippet:\n\n```\n<li role=\"listitem\" tabindex=\"0\">\n```",
+  "input_role=\"link\"": "The issue in the given code snippet is that the `input` element with `type=\"submit\"` has an inappropriate value for the `role` attribute. The `role` attribute is set to \"link\", which is incorrect for a submit button. The correct value for the `role` attribute for a submit button should be \"button\".\n\nHere's the correct version of the code snippet:\n\n```html\n<input name=\"...\" onclick=\"if(document.getElementById('loginForm').checkValidity()){this.onclick = function () { return false; }};\" role=\"button\" type=\"submit\" value=\"...\">\n```"
+}
diff --git a/results/aria-hidden-focus.json b/results/aria-hidden-focus.json
new file mode 100644
index 0000000..5b1db37
--- /dev/null
+++ b/results/aria-hidden-focus.json
@@ -0,0 +1,4 @@
+{
+  "div_aria-hidden_style": "The issue in the code snippet is that the `aria-hidden` attribute is set to \"true\" on an element that contains focusable elements or is focusable itself. This can cause confusion for screen reader users, as the focusable elements inside the hidden content will still be reachable and announced, even though they are not visible on the screen.\n\nTo fix the issue, you should either remove the focusable elements from the hidden content or make them non-focusable by adding `tabindex=\"-1\"` to each focusable element. Alternatively, you can remove the `aria-hidden` attribute if the content should be accessible.\n\nHere's the corrected version of the code snippet:\n\n```html\n<div aria-hidden=\"true\" style=\"width: 394px;\">\n  <!-- Non-focusable content goes here -->\n  <button tabindex=\"-1\">Sample Button</button>\n  <a href=\"#\" tabindex=\"-1\">Sample Link</a>\n</div>\n```\n\nIn this corrected version, I've added `tabindex=\"-1\"` to the focusable elements (button and link) inside the hidden content, making them non-focusable.",
+  "li_aria-controls_aria-hidden_aria-selected_role_button_role_tabindex_type": "The issue in the code snippet is that the element with `aria-hidden=\"true\"` contains a focusable element (the button). This means that screen readers will skip the content, but keyboard users can still focus on it, causing confusion.\n\nHere's the corrected version of the code snippet:\n\n```\n<li aria-controls=\"navigation00\" role=\"presentation\">\n  <button role=\"button\" type=\"button\"></button>\n</li>\n```\n\nIn this corrected version, I removed the `aria-hidden=\"true\"` and `aria-selected=\"true\"` attributes from the `li` element, as they are not necessary in this context. The button remains focusable, and screen reader users will now be able to access it as well."
+}
diff --git a/results/aria-input-field-name.json b/results/aria-input-field-name.json
new file mode 100644
index 0000000..50833bc
--- /dev/null
+++ b/results/aria-input-field-name.json
@@ -0,0 +1,4 @@
+{
+  "div_role_style": "The issue in the given code snippet is that the ARIA input fields do not have accessible names. To fix this issue, you should add the `aria-label` attribute to provide an accessible name for the input fields.\n\nHere's the corrected version of the code snippet:\n\n```html\n<div role=\"listbox\" aria-label=\"Your accessible name here\" style=\"opacity: 1; width: 7200px; transform: translate3d(-3600px, 0px, 0px);\">\n```\n\nMake sure to replace \"Your accessible name here\" with an appropriate name that describes the purpose of the input field.",
+  "div_role": "The issue in the given code snippet is that the ARIA input fields do not have accessible names. To fix this, you need to add the `aria-label` attribute to the input fields.\n\nHere is the corrected version of the code snippet:\n\n```html\n<div role=\"listbox\">\n  <input type=\"text\" aria-label=\"Name\" />\n  <input type=\"email\" aria-label=\"Email\" />\n  <input type=\"password\" aria-label=\"Password\" />\n</div>\n```\n\nIn this example, I've added `aria-label` attributes to each input field with appropriate labels (\"Name\", \"Email\", and \"Password\"). This ensures that the input fields have accessible names for screen readers and other assistive technologies."
+}
diff --git a/results/aria-required-children.json b/results/aria-required-children.json
new file mode 100644
index 0000000..9b003f1
--- /dev/null
+++ b/results/aria-required-children.json
@@ -0,0 +1,3 @@
+{
+  "ul_role=\"tablist\"": "The issue in the given code snippet is that the `ul` element with the `role` of \"tablist\" is missing the required child elements with the `role` of \"tab\". To fix this issue, you should add the required child elements with the appropriate ARIA roles. Here's the corrected version of the code snippet:\n\n```html\n<ul role=\"tablist\">\n  <li role=\"tab\">Tab 1</li>\n  <li role=\"tab\">Tab 2</li>\n  <li role=\"tab\">Tab 3</li>\n</ul>\n```\n\nIn this corrected version, the `li` elements have been given the required `role` of \"tab\" as children of the `ul` element with the `role` of \"tablist\"."
+}
diff --git a/results/aria-required-parent.json b/results/aria-required-parent.json
new file mode 100644
index 0000000..34648ff
--- /dev/null
+++ b/results/aria-required-parent.json
@@ -0,0 +1,3 @@
+{
+  "a_role=\"tab\"": "The issue in the code snippet is that the `role=\"tab\"` is not contained within an element with `role=\"tablist\"`. To fix this issue, you should wrap the anchor tag with a parent element that has the required role \"tablist\". Here's the corrected version of the code snippet:\n\n```\n<div role=\"tablist\">\n  <a aria-controls=\"full-fsbb-today\" aria-selected=\"true\" href=\"...\" role=\"tab\"></a>\n</div>\n```"
+}
diff --git a/results/aria-roles.json b/results/aria-roles.json
new file mode 100644
index 0000000..0b1c161
--- /dev/null
+++ b/results/aria-roles.json
@@ -0,0 +1,6 @@
+{
+  "section_role=\"main-content\"": "The issue in the code snippet is that the value of the role attribute is not valid. The correct value should be \"main\". Here's the corrected code snippet:\n\n```html\n<section role=\"main\">\n```",
+  "aside_role=\"right-content\"": "The issue in this code snippet is that the role attribute has an invalid value \"right-content\". To fix this, you should use a valid ARIA role. Assuming the aside element is meant to be complementary content, you can use the \"complementary\" role.\n\nHere's the corrected version of the code snippet:\n\n```html\n<aside role=\"complementary\">\n```",
+  "fieldset_role=\"radio-group\"": "The issue in the provided code snippet is that the `role` attribute has an invalid value \"radio-group\". The correct value should be \"radiogroup\". Here's the corrected version of the code snippet:\n\n```\n<fieldset name=\"...\" role=\"radiogroup\">\n```",
+  "div_role=\"pagination\"": "The issue in the given code snippet is that the `role` attribute has an invalid value \"pagination\". The correct value should be \"navigation\". Here is the corrected version of the code snippet:\n\n```\n<div aria-label=\"...\" role=\"navigation\">\n```"
+}
diff --git a/results/aria-toggle-field-name.json b/results/aria-toggle-field-name.json
new file mode 100644
index 0000000..65e67fe
--- /dev/null
+++ b/results/aria-toggle-field-name.json
@@ -0,0 +1,3 @@
+{
+  "div_aria-describedby_aria-hidden_role_style_tabindex": "The issue in the given code snippet is that the ARIA toggle fields do not have accessible names. To fix this, you can add an `aria-label` attribute that provides a descriptive name for the toggle fields.\n\nHere's the corrected version of the code snippet:\n\n```html\n<div aria-describedby=\"...\" aria-hidden=\"false\" role=\"option\" style=\"width: 900px;\" tabindex=\"-1\" aria-label=\"Descriptive name for the toggle field\">\n```\n\nMake sure to replace \"Descriptive name for the toggle field\" with an appropriate name that describes the purpose of the toggle field."
+}
diff --git a/results/aria-valid-attr.json b/results/aria-valid-attr.json
new file mode 100644
index 0000000..564b52c
--- /dev/null
+++ b/results/aria-valid-attr.json
@@ -0,0 +1,3 @@
+{
+  "a_aria-controls_aria-disabled_aria-role_tabindex": "The issue in this code snippet is the use of an invalid ARIA attribute `aria-role`. The correct attribute is `role`. Here's the corrected code snippet:\n\n```\n<a aria-controls=\"tblwykazy\" aria-disabled=\"true\" role=\"link\" tabindex=\"0\"></a>\n```"
+}
diff --git a/results/label.json b/results/label.json
new file mode 100644
index 0000000..e145564
--- /dev/null
+++ b/results/label.json
@@ -0,0 +1,6 @@
+{
+  "input_tabindex_value": "The issue with the code snippet is that the input element does not have an associated label. To fix this, you should add a label element with a \"for\" attribute that matches the input element's \"id\" attribute. Here's the correct version of the code snippet:\n\n```html\n<label for=\"inputId\">Label text:</label>\n<input id=\"inputId\" tabindex=\"0\" value=\"...\">\n```\n\nMake sure to replace \"Label text\" with the appropriate label for the input field, and \"inputId\" with a unique identifier for the input element.",
+  "input_type_value": "Issue: The form element (input) does not have an associated label, which is an accessibility issue.\n\nCorrected code snippet:\n\n```html\n<label for=\"input-text\">Label Text:</label>\n<input type=\"text\" id=\"input-text\" value=\"...\">\n```\n\nIn the corrected code snippet, we've added a `<label>` element with a \"for\" attribute that matches the \"id\" attribute of the `<input>` element. This associates the label with the input, improving accessibility.",
+  "input_type": "The issue in the given code snippet is that the input element does not have an associated label, which is important for accessibility. To fix this issue, you can add a label element with a \"for\" attribute that matches the input element's \"id\" attribute. Here's the corrected version of the code snippet:\n\n```\n<label for=\"number-input\">Number:</label>\n<input type=\"number\" id=\"number-input\">\n```\n\nIn this corrected version, a label element is added with the text \"Number:\". The \"for\" attribute in the label element is set to \"number-input\", which matches the \"id\" attribute of the input element. This way, screen readers and other assistive technologies can properly associate the label with the input field.",
+  "input_name_style": "Issue: The input element in the code snippet does not have an associated label, which is essential for accessibility.\n\nCorrected code snippet:\n\n```html\n<label for=\"inputId\">Label Text</label>\n<input id=\"inputId\" name=\"...\" style=\"width: 54px;\">\n```\n\nIn the corrected code snippet, a label element is added with a \"for\" attribute that matches the \"id\" attribute of the input element. This associates the label with the input and improves accessibility."
+}
diff --git a/results/landmark-unique.json b/results/landmark-unique.json
new file mode 100644
index 0000000..8a0f064
--- /dev/null
+++ b/results/landmark-unique.json
@@ -0,0 +1,11 @@
+{
+  "nav": "The issue in the given code snippet is that the `<nav>` element does not have a unique role or role/label/title, which is necessary for accessibility.\n\nHere's the corrected version of the code snippet:\n\n```html\n<nav role=\"navigation\" aria-label=\"Main navigation\">\n  <!-- Navigation content goes here -->\n</nav>\n```\n\nIn this corrected version, we've added a `role` attribute with the value \"navigation\" and an `aria-label` attribute with the value \"Main navigation\" to provide a unique role and label for the landmark. This will make it more accessible for screen reader users and improve overall accessibility.",
+  "nav_aria-label": "The issue with the code snippet is that the `nav` element has an `aria-label` attribute with an empty value. To fix the accessibility issue, you should provide a unique and descriptive label for the `nav` element.\n\nHere is the corrected version of the code snippet:\n\n```html\n<nav aria-label=\"Main navigation\">\n  <!-- Navigation content goes here -->\n</nav>\n```\n\nIn this example, I've added a descriptive label \"Main navigation\" to the `aria-label` attribute. This will help screen reader users understand the purpose of the navigation landmark.",
+  "footer_onclick": "The issue with the given code snippet is that the `footer` landmark does not have a unique role or role/label/title, which makes it less accessible for screen reader users.\n\nHere's the correct version of the code snippet:\n\n```html\n<footer onclick=\"\" role=\"contentinfo\" aria-label=\"Footer\">\n  <!-- Footer content goes here -->\n</footer>\n```\n\nIn the corrected version, we added the `role` attribute with the value \"contentinfo\" and the `aria-label` attribute with the value \"Footer\" to make the `footer` landmark more accessible.",
+  "div_aria-label_role": "The issue with the given code snippet is that the landmark has a generic \"region\" role without a unique label or title. To fix this, we can change the role to a more specific one or add a unique label/title.\n\nCorrect version of the code snippet:\n\n```html\n<div aria-label=\"Unique label for the region\" role=\"region\"></div>\n```\n\nor\n\n```html\n<div aria-labelledby=\"uniqueLabelId\" role=\"region\">\n  <h2 id=\"uniqueLabelId\">Unique label for the region</h2>\n  <!-- other content -->\n</div>\n```\n\nIn the first example, we added a unique label using `aria-label`. In the second example, we used `aria-labelledby` to reference a unique label from an inner element.",
+  "header": "The issue in the given code snippet is that the header landmark does not have a unique role or role/label/title. To fix this issue, we can add the role attribute and an appropriate label using aria-label. Here's the correct version of the code snippet:\n\n```html\n<header role=\"banner\" aria-label=\"Main header\">\n```\n\nIn this updated snippet, we've added the role \"banner\" and an aria-label \"Main header\" to make it more accessible.",
+  "nav_style": "The issue in the given code snippet is that the `nav` element does not have a unique role or role/label/title, which makes it difficult for screen readers and other assistive technologies to identify the purpose of the landmark.\n\nTo fix this issue, you can add an `aria-label` attribute to the `nav` element with a descriptive label. Here's the corrected version of the code snippet:\n\n```html\n<nav style=\"background: #0a6160;\" aria-label=\"Main Navigation\">\n  <!-- navigation items go here -->\n</nav>\n```\n\nBy adding the `aria-label` attribute, you provide a unique label that helps assistive technologies understand the purpose of the navigation landmark, improving accessibility for users.",
+  "main": "The issue in the given code snippet is that the `<main>` landmark does not have a unique role or role/label/title. To fix this, we can add the `role` attribute with a value of \"main\" and an `aria-label` attribute with a unique label.\n\nHere's the corrected version of the code snippet:\n\n```html\n<main role=\"main\" aria-label=\"Unique Label\">\n  <!-- Content goes here -->\n</main>\n```\n\nReplace \"Unique Label\" with a descriptive label that represents the main content of the page.",
+  "nav_role": "The issue in the given code snippet is that the landmark (nav element) does not have a unique label or title. To fix this, you can add an `aria-label` attribute to provide a unique and descriptive label for the navigation landmark.\n\nHere's the corrected version of the code snippet:\n\n```html\n<nav role=\"navigation\" aria-label=\"Main Navigation\">\n```",
+  "iframe_aria-label_name_role_style_tabindex_title": "The issue in the code snippet is that the `iframe` element has a `role=\"region\"` attribute, which is not necessary as `iframe` has an inherent role of its own. Additionally, it is important to provide a unique and descriptive `aria-label` and `title` attribute for better accessibility.\n\nHere's the corrected version of the code snippet:\n\n```html\n<iframe aria-label=\"Descriptive label for iframe content\" name=\"...\" style=\"border: 0px; vertical-align: bottom;\" tabindex=\"0\" title=\"Descriptive title for iframe content\"></iframe>\n```\n\nIn this corrected version, the `role=\"region\"` attribute has been removed, and the `aria-label` and `title` attributes have been updated with a placeholder for a unique and descriptive label/title. Make sure to replace the placeholder with an appropriate label and title specific to your content."
+}
diff --git a/results/presentation-role-conflict.json b/results/presentation-role-conflict.json
new file mode 100644
index 0000000..cc3bc01
--- /dev/null
+++ b/results/presentation-role-conflict.json
@@ -0,0 +1,3 @@
+{
+  "button_role_type_i": "The issue in the code snippet is that the button has a \"presentation\" role, which means it should not have any semantic meaning or interactivity. However, it has a \"button\" type and it may also contain global ARIA or tabindex attributes, which contradicts the \"presentation\" role.\n\nA correct version of the code snippet should remove the \"presentation\" role and allow the button to have its default semantic meaning:\n\n```html\n<button type=\"button\"><i></i></button>\n```\n\nIf the intention was to have a presentational element without interactivity, you should use a different element, like a `div` or a `span`, and remove any global ARIA or tabindex attributes:\n\n```html\n<span role=\"presentation\"><i></i></span>\n```"
+}
diff --git a/results/scrollable-region-focusable.json b/results/scrollable-region-focusable.json
new file mode 100644
index 0000000..f29b2a2
--- /dev/null
+++ b/results/scrollable-region-focusable.json
@@ -0,0 +1,3 @@
+{
+  "div": "The issue in the code snippet is that the scrollable content is not accessible by keyboard. To fix this, we can add the `tabindex=\"0\"` attribute to the scrollable `div` element. This will make the scrollable content accessible by keyboard.\n\nIncorrect code snippet:\n```\n<div>\n```\n\nCorrected code snippet:\n```\n<div tabindex=\"0\">\n```"
+}
diff --git a/results/select-name.json b/results/select-name.json
new file mode 100644
index 0000000..ef7fa4e
--- /dev/null
+++ b/results/select-name.json
@@ -0,0 +1,3 @@
+{
+  "select_name": "The issue with the given code snippet is that it lacks a proper label for the select element, which is important for accessibility. Screen readers rely on labels to provide context and information to users about the purpose of form elements.\n\nHere's the corrected version of the code snippet with a proper label:\n\n```html\n<label for=\"exampleSelect\">Example Label:</label>\n<select name=\"exampleSelect\" id=\"exampleSelect\">\n  <!-- Add your option elements here -->\n</select>\n```\n\nIn this example, we've added a `<label>` element with a `for` attribute that matches the `id` attribute of the `<select>` element. This ensures that the label is associated with the select element, improving accessibility for users relying on screen readers."
+}
diff --git a/updater/constants.js b/updater/constants.js
new file mode 100644
index 0000000..6f95da1
--- /dev/null
+++ b/updater/constants.js
@@ -0,0 +1,73 @@
+const purpleAiRules = [
+    'aria-allowed-attr',
+    'aria-hidden-focus',
+    'aria-input-field-name',
+    'aria-required-attr',
+    'aria-required-children',
+    'aria-required-parent',
+    'aria-roles',
+    'aria-toggle-field-name',
+    'aria-valid-attr',
+    'aria-allowed-role',
+    'form-field-multiple-labels',
+    'label',
+    'scrollable-region-focusable',
+    'select-name',
+    'landmark-unique',
+    'meta-viewport-large',
+    'presentation-role-conflict',
+    'aria-treeitem-name',
+    'server-side-image-map',
+    'svg-img-alt',
+    'autocomplete-valid',
+];
+
+const rulesUsingRoles = [
+    'aria-allowed-attr', 
+    'aria-required-attr', 
+    'aria-required-children', 
+    'aria-required-parent', 
+    'aria-roles', 
+    'aria-allowed-role', 
+    'aria-valid-attr-value'
+]; 
+
+const omittedRules = [
+    'html-xml-lang-mismatch', 
+    'frame-tested', 
+    'color-contrast', 
+    'link-in-text-block', 
+    'page-has-heading-one',
+    'duplicate-id-aria', 
+    'frame-title-unique', 
+    'frame-title', 
+    'html-has-lang', 
+    'html-lang-valid', 
+    'input-image-alt', 
+    'link-in-text-block', 
+    'list', 
+    'listitem', 
+    'marquee', 
+    'valid-lang', 
+    'video-caption', 
+    'accesskeys', 
+    'empty-heading', 
+    'empty-table-header', 
+    'label-title-only'
+];
+
+const deprecatedRules = ['aria-roledescription', 'audio-caption', 'duplicate-id-active', 'duplicate-id'];
+
+const catalogPath = './catalog.json'; 
+const resultsFolderPath = './results';
+const rangePath = './range.json'
+const purpleAIPromptsPath = './purpleAIPrompts.json';
+
+module.exports = {
+    purpleAiRules, 
+    rulesUsingRoles,
+    catalogPath,
+    resultsFolderPath,
+    rangePath,
+    purpleAIPromptsPath
+}
\ No newline at end of file
diff --git a/updater/logs.js b/updater/logs.js
new file mode 100644
index 0000000..478a269
--- /dev/null
+++ b/updater/logs.js
@@ -0,0 +1,39 @@
+/* eslint-disable no-shadow */
+const{ createLogger, format, transports } = require('winston');
+const { combine, timestamp, printf } = format;
+
+// Sample output
+// {"timestamp":"2020-11-25 17:29:07","level":"error","message":"hello world"}
+const logFormat = printf(({ timestamp, level, message }) => {
+  const log = {
+    timestamp: `${timestamp}`,
+    level: `${level}`,
+    message: `${message}`,
+  };
+
+  return JSON.stringify(log);
+});
+
+// transport: storage device for logs
+// Enabled for console and storing into files; Files are overwritten each time
+// All logs in combined.txt, error in errors.txt
+
+const consoleLogger = createLogger({
+  format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat),
+  transports: [new transports.Console()],
+});
+
+// No display in consoles, this will mostly be used within the interactive script to avoid disrupting the flow
+// Also used in common functions to not link internal information
+const silentLogger = createLogger({
+  format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat),
+  transports: [
+    new transports.File({ filename: 'errors.txt', level: 'warn', handleExceptions: true }),
+  ],
+});
+
+module.exports = {
+  logFormat,
+  consoleLogger,
+  silentLogger,
+};
diff --git a/updater/purpleAIUpdater.js b/updater/purpleAIUpdater.js
new file mode 100644
index 0000000..2244cc6
--- /dev/null
+++ b/updater/purpleAIUpdater.js
@@ -0,0 +1,164 @@
+const { GoogleSpreadsheet } = require('google-spreadsheet');
+const { JWT } = require('google-auth-library');
+const { config } = require("dotenv");
+const fs = require('fs');
+const axios = require('axios');
+const utils = require('./utils');
+const { execSync } = require('child_process');
+const { silentLogger } = require('./logs'); 
+
+const { purpleAiRules, rangePath, purpleAIPromptsPath, resultsFolderPath } = require('./constants');
+
+config(); 
+
+const serviceAccountAuth = new JWT({
+    email: process.env.GOOGLE_CLIENT_EMAIL,
+    key: process.env.GOOGLE_PRIVATE_KEY, 
+    scopes: [
+        'https://www.googleapis.com/auth/spreadsheets'
+    ]
+})
+
+const HEADERS = {
+    "Content-Type": "application/json",
+    "Authorization": process.env.OPENAI_API_KEY
+}
+
+const query = async (payload) => {
+    try {
+      const response = await axios.post(process.env.OPENAI_API_ENDPOINT, payload, { headers: HEADERS });
+      return { status: response.status, answer: response.data.data[0].llm_response.content };
+    } catch (error) {
+      const errorMessage = `${error}: ${error.response.config.data}`
+      silentLogger.error(errorMessage);
+      return { status: error.response.status }
+    }
+}
+
+const getDataFromGoogleSheets = async () => {
+    const sheet = new GoogleSpreadsheet(process.env.GOOGLE_SHEET_ID, serviceAccountAuth);
+    await sheet.loadInfo();
+
+    const formReponses = sheet.sheetsByIndex[0];
+    const range = utils.getRange();
+    const rows = await formReponses.getRows({offset: range.offset, limit: range.limit}); // can set offset and limit
+    return rows; 
+}
+
+const generateIssuesToQuery = (data) => {
+    var issues = [];
+    for (const d of data) {
+        try {
+            const results = JSON.parse(d.get('Accessibility Scan Results'));
+
+            for (const ruleID of Object.keys(results)) {
+                if (purpleAiRules.includes(ruleID)) {
+                    const snippets = results[ruleID].snippets; 
+                    for (const snippet of snippets) {  
+                        const basicHTMLLabel = utils.createBasicHTMLLabel(ruleID, snippet);
+                        const promptHTMLSnippet = utils.processHTMLSnippet(snippet);
+                        issues.push({
+                            ruleID: ruleID, 
+                            htmlSnippet: snippet,
+                            basicHTMLLabel: basicHTMLLabel,
+                            promptHTMLSnippet: promptHTMLSnippet
+                        })
+                    }
+                }
+            } 
+        } catch (e) {
+        const errorMessage = `${e}: ${d['_rawData']}`
+        silentLogger.error(errorMessage);
+       }
+    }
+    utils.updateRowRange(data);
+    return issues; 
+}
+
+const getAIResponse = async (promptHTMLSnippet, ruleID) => {
+    const prompts = JSON.parse(fs.readFileSync(purpleAIPromptsPath));
+    const htmlSnippet = promptHTMLSnippet;
+    const prompt = eval('`' + prompts[ruleID] + '`');
+
+    console.log(prompt);
+
+    const result = await query({
+        "flow_id": process.env.OPENAI_FLOW_ID, 
+        "inputs": [{
+            "prompt": prompt
+        }]
+    })
+
+    console.log(result)
+    return result.status === 200 ? result.answer : null;
+}
+
+const generateAIResponses = async (issues) => {
+    const updatedIssues = new Set();
+    const catalog = utils.getCatalog();
+    for (const i of issues) {
+        const { ruleID, htmlSnippet, basicHTMLLabel, promptHTMLSnippet } = i;
+        const needsQuery = utils.needsQuery(ruleID, htmlSnippet, basicHTMLLabel, catalog); 
+        if (needsQuery) {
+            const response = await getAIResponse(promptHTMLSnippet, ruleID); 
+            if (response) {
+                utils.writeAIResponse(ruleID, basicHTMLLabel, response); 
+                // update catalog
+                catalog[ruleID] = catalog[ruleID] ? catalog[ruleID] : [];
+                catalog[ruleID].push(basicHTMLLabel);
+
+                updatedIssues.add(ruleID)
+            }
+        }
+    }
+    catalog["lastUpdated"] = new Date().toLocaleString();
+    utils.writeCatalog(catalog);
+    return updatedIssues;
+}
+
+const writeResultsToGithub = async (updatedIssues) => {
+    if (updatedIssues.size > 0) {
+        let commitMessage = 'Add '; 
+        for (const issue of updatedIssues) {
+            commitMessage += `${issue}.json `; 
+        }
+        execSync(`git pull && git add results && git commit -m "${commitMessage}"`)  
+    }
+    execSync(`git pull && git add catalog.json && git commit -m "Update catalog.json"`) 
+    execSync(`git pull && git add range.json && git commit -m "Update range.json"`)
+    execSync(`git push`)
+ }
+
+const writeCatalogLastUpdatedToGithub = () => {
+    const catalog = utils.getCatalog();
+    catalog["lastUpdated"] = new Date().toLocaleString();
+    utils.writeCatalog(catalog);
+    execSync(`git pull && git add catalog.json && git commit -m "Update catalog.json"`) 
+}
+
+const run = async () => {
+    if (!fs.existsSync('./results')) {
+        fs.mkdirSync('./results');
+    }
+    
+    // for testing
+    // const prompt = "How to ensure accessible tab order:  <button tabindex=\"10000\"><span></span></button>";
+    // const result = await query({
+    //     "flow_id": process.env.OPENAI_FLOW_ID, 
+    //     "inputs": [{
+    //         "prompt": prompt
+    //     }]
+    // })
+    // console.log(result.answer);
+
+    const data = await getDataFromGoogleSheets();
+    if (data.length > 0) {
+        const issues = generateIssuesToQuery(data);
+        const updatedIssues = await generateAIResponses(issues);
+        await writeResultsToGithub(updatedIssues);
+    } else {
+        writeCatalogLastUpdatedToGithub();
+    }
+}
+
+run();
diff --git a/updater/utils.js b/updater/utils.js
new file mode 100644
index 0000000..9789c3c
--- /dev/null
+++ b/updater/utils.js
@@ -0,0 +1,102 @@
+const fs = require('fs');
+const prettier = require('prettier');
+const { execSync } = require('child_process');
+const { rulesUsingRoles, resultsFolderPath, rangePath, catalogPath } = require('./constants');
+
+const htmlTagAndAttributeRegex = new RegExp(/((?<=[<])\s*([a-zA-Z][^\s>/]*)\b)|([\w-]+)\s*(?==\s*["']([^"']*)["'])/g);
+const createBasicHTMLLabel = (ruleID, html) => {
+    if (rulesUsingRoles.includes(ruleID) && html.includes('role')) {
+        return createLabelForRuleWithRole(html);
+    }
+    const label = html.match(htmlTagAndAttributeRegex).toString().replaceAll(",", "_");
+    return label;
+}; 
+
+const createLabelForRuleWithRole = (html) => {
+    const htmlRoleAttributeRegex = new RegExp(/role="([^"]*)"/g); 
+    const outermostHTMLTag = html.match(htmlTagAndAttributeRegex)[0]; 
+    const outermostRoleAttribute = html.match(htmlRoleAttributeRegex)[0];
+    const htmlLabel = `${outermostHTMLTag}_${outermostRoleAttribute}`;
+    return htmlLabel || "";
+}
+
+const processHTMLSnippet = (html) => {
+    const processed = html.replace(htmlTagAndAttributeRegex, `\`$&\``);
+    return processed;
+};
+
+const getRange = () => {
+    return JSON.parse(fs.readFileSync(rangePath));
+}
+const updateRowRange = async (rows) => {
+    const range = getRange();
+    if (rows.length <= range.limit && rows.length > 0) {
+        range.offset += rows.length;
+       fs.writeFileSync('./range.json', JSON.stringify(range));
+    }
+};
+
+const needsQuery = (ruleID, html, label, catalog) => {
+    // no information for current rule 
+    if (!catalog[ruleID] || catalog[ruleID].length === 0) {
+        return true; 
+    }
+
+    // response exists for exact label 
+    if (catalog[ruleID].includes(label)) {
+        return false; 
+    }
+
+    // rule requires role 
+    if (rulesUsingRoles.includes(ruleID) && html.includes('role')) {
+        return !catalog[ruleID].includes(label);
+    }
+
+    // count the number of elements in keyArr that
+    // have matching elements at the same index in currentLabelList
+    // return match if >= 3 elements matching
+    const currentLabelList = html.match(htmlTagAndAttributeRegex);
+    const currentLabelSet = new Set(currentLabelList);
+    const hasMatches = catalog[ruleID].some(label => {
+        const keyArr = label.split('_');
+        const attrMatch = keyArr.filter(key => currentLabelSet.has(key));
+
+        return attrMatch.length >= 3;
+    })
+    return !hasMatches;
+}
+
+const writeAIResponse = (ruleID, basicHTMLLabel, response) => {
+     const resultPath = `${resultsFolderPath}/${ruleID}.json`; 
+     var data = {}; 
+     if (fs.existsSync(resultPath)) {
+         data = JSON.parse(fs.readFileSync(resultPath));
+     }
+     data[basicHTMLLabel] = response;
+     fs.writeFileSync(resultPath, prettier.format(JSON.stringify(data), {parser: "json"}));
+}
+
+const getCatalog = () => {
+    var catalog; 
+    if (fs.existsSync(catalogPath)) {
+        catalog = JSON.parse(fs.readFileSync(catalogPath));
+    } else {
+        catalog = {};
+    }
+    return catalog;
+}
+
+const writeCatalog = (catalog) => {
+    fs.writeFileSync(catalogPath, prettier.format(JSON.stringify(catalog), {parser: 'json'}));
+}
+
+module.exports = {
+    createBasicHTMLLabel, 
+    processHTMLSnippet, 
+    getRange,
+    updateRowRange,
+    needsQuery,
+    writeAIResponse,
+    getCatalog,
+    writeCatalog
+}
\ No newline at end of file