aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-02 22:31:34 -0800
committerFuwn <[email protected]>2026-02-02 22:33:29 -0800
commitdc31efafe99e8759eb1c06d3b2f5d6489d1825c4 (patch)
tree04696e70ccf1765a4336b8506ed6c350e2ca5cb7
parentGenerate README from JSON (diff)
downloadxp-test-dc31efafe99e8759eb1c06d3b2f5d6489d1825c4.tar.xz
xp-test-dc31efafe99e8759eb1c06d3b2f5d6489d1825c4.zip
Add pages filesHEADmaster
-rw-r--r--index.html155
1 files changed, 155 insertions, 0 deletions
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..e5e1af4
--- /dev/null
+++ b/index.html
@@ -0,0 +1,155 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+ <title>💻 Windows XP All Editions Universal Product Keys Collection</title>
+
+ <style>
+ body {
+ font-family:
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial,
+ sans-serif;
+ line-height: 1.6;
+ max-width: 900px;
+ margin: 0 auto;
+ padding: 2rem;
+ color: #24292e;
+ }
+
+ img {
+ max-width: 100%;
+ height: auto;
+ }
+
+ h1 {
+ border-bottom: 1px solid #eaecef;
+ padding-bottom: 0.3em;
+ }
+
+ h2 {
+ border-bottom: 1px solid #eaecef;
+ padding-bottom: 0.3em;
+ }
+
+ ul {
+ padding-left: 2em;
+ }
+
+ li {
+ font-family: monospace;
+ }
+
+ p {
+ margin: 1em 0;
+ }
+
+ #search {
+ width: 100%;
+ padding: 0.75rem;
+ font-size: 1rem;
+ border: 1px solid #ddd;
+ border-radius: 6px;
+ margin-bottom: 1.5rem;
+ box-sizing: border-box;
+ }
+
+ #search:focus {
+ outline: none;
+ border-color: #0366d6;
+ box-shadow: 0 0 0 3px rgba(3, 102, 214, 0.1);
+ }
+
+ .no-results {
+ color: #666;
+ font-style: italic;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div id="content"></div>
+
+ <script type="module">
+ const markdownBoldToHtml = (text) =>
+ text.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
+
+ const keysData = await fetch("./keys.json").then((response) =>
+ response.json(),
+ );
+ const { header, footer } = keysData.content;
+
+ const render = (searchQuery = "") => {
+ const normalizedQuery = searchQuery.toLowerCase().trim();
+
+ const textContainsQuery = (text) =>
+ normalizedQuery === "" ||
+ text.toLowerCase().includes(normalizedQuery);
+
+ const editionsMarkup = Object.values(keysData.editions)
+ .map((edition) => {
+ const editionNameMatchesQuery = textContainsQuery(edition.name);
+
+ const categoriesMarkup = Object.values(edition.categories)
+ .map((category) => {
+ const categoryNameMatchesQuery = textContainsQuery(
+ category.name,
+ );
+ const matchingKeys = category.keys.filter(
+ (key) =>
+ textContainsQuery(key) ||
+ categoryNameMatchesQuery ||
+ editionNameMatchesQuery,
+ );
+
+ if (!matchingKeys.length) return "";
+
+ const categoryHeading =
+ category.name !== "Default"
+ ? `<h2>${category.name}</h2>`
+ : "";
+ const keysListMarkup = `<ul>${matchingKeys.map((key) => `<li>${key}</li>`).join("")}</ul>`;
+
+ return categoryHeading + keysListMarkup;
+ })
+ .join("");
+
+ return categoriesMarkup
+ ? `<h1>${edition.name}</h1>${categoriesMarkup}`
+ : "";
+ })
+ .join("");
+
+ const noResultsMessage =
+ normalizedQuery && !editionsMarkup
+ ? `<p class="no-results">No keys found matching "${searchQuery}"</p>`
+ : "";
+
+ document.getElementById("content").innerHTML = `
+ <p><img src="${header.logo}" alt="Windows XP Logo"></p>
+ <p>${header.intro}</p>
+ <p>${header.description}</p>
+ <p><img src="${header.setup_image}" alt="Windows XP Setup"></p>
+ <input type="text" id="search" placeholder="Search keys or sections ..." value="${searchQuery}">
+ ${editionsMarkup}
+ ${noResultsMessage}
+ <h1>${footer.title}</h1>
+ <p>${markdownBoldToHtml(footer.vol_explanation)}</p>
+ <p>${markdownBoldToHtml(footer.vlk_explanation)}</p>
+ <p>${footer.license_info}</p>
+ `;
+
+ const searchInput = document.getElementById("search");
+
+ searchInput.addEventListener("input", (event) =>
+ render(event.target.value),
+ );
+ searchInput.focus();
+ searchInput.setSelectionRange(searchQuery.length, searchQuery.length);
+ };
+
+ render();
+ </script>
+ </body>
+</html>