diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3491fa4..382adb2 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,6 +18,9 @@ "ghcr.io/helpers4/devcontainer/vite-plus:1": {}, "ghcr.io/helpers4/devcontainer/package-auto-install:1": {} }, + "containerEnv": { + "NPM_TOKEN_WEB_AWESOME": "${localEnv:NPM_TOKEN_WEB_AWESOME}" + }, "forwardPorts": [ 3000, 3001, diff --git a/assets/logo/Helpers4 Logo.png b/assets/logo/Helpers4 Logo.png new file mode 100644 index 0000000..9d6f123 Binary files /dev/null and b/assets/logo/Helpers4 Logo.png differ diff --git a/landing/index.html b/landing/index.html index 35d2ca0..c3c1580 100644 --- a/landing/index.html +++ b/landing/index.html @@ -1,38 +1,23 @@ - + helpers4 - Open Source Utilities + + + + -
+
diff --git a/landing/package.json b/landing/package.json index 744b843..a2f2c25 100644 --- a/landing/package.json +++ b/landing/package.json @@ -6,17 +6,18 @@ "type": "module", "scripts": { "build": "vite build", - "dev": "vite --port 3000", + "dev": "vite --host 0.0.0.0 --port 3000", "preview": "vite preview", "clean": "rm -rf dist .vite" }, "dependencies": { "@awesome.me/webawesome-pro": "^3.2.1", - "@builder.io/qwik": "^1.19.0", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "react": "^18.3.1", + "react-dom": "^18.3.1" }, "devDependencies": { + "@types/react": "^18.3.28", + "@types/react-dom": "^18.3.5", "typescript": "^5.3.0", "vite": "^7.3.1" } diff --git a/landing/public/helpers4-logo.png b/landing/public/helpers4-logo.png new file mode 100644 index 0000000..9d6f123 Binary files /dev/null and b/landing/public/helpers4-logo.png differ diff --git a/landing/qwik.config.ts b/landing/qwik.config.ts deleted file mode 100644 index 8cbc12b..0000000 --- a/landing/qwik.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from '@builder.io/qwik/optimizer'; - -export default defineConfig({ - mdx: { - jsxImportSource: '@builder.io/qwik', - }, -}); diff --git a/landing/src/components/CardItem.tsx b/landing/src/components/CardItem.tsx new file mode 100644 index 0000000..00d07be --- /dev/null +++ b/landing/src/components/CardItem.tsx @@ -0,0 +1,36 @@ +/** + * @license AGPL-3.0-or-later + */ + +import { type ProjectCard } from '../types'; +import { formatStars } from '../utils/github'; + +interface CardItemProps { + card: ProjectCard; + stars: number | null; +} + +export function CardItem({ card, stars }: CardItemProps) { + return ( + + {/* Header */} +

{card.title}

+ + + {formatStars(stars)} + + + {/* Body */} + {card.description} + + {/* Footer */} + +
+ Open {card.label} docs + + GitHub + +
+
+ ); +} diff --git a/landing/src/components/CardsList.tsx b/landing/src/components/CardsList.tsx new file mode 100644 index 0000000..4a5487a --- /dev/null +++ b/landing/src/components/CardsList.tsx @@ -0,0 +1,48 @@ +/** + * @license AGPL-3.0-or-later + */ + +import { useEffect, useMemo, useState } from 'react'; +import { type ProjectCard, type RepoStars } from '../types'; +import { fetchAllStars } from '../utils/github'; +import { CardItem } from './CardItem'; + +interface CardsListProps { + projects: ProjectCard[]; +} + +export function CardsList({ projects }: CardsListProps) { + const [starsByRepo, setStarsByRepo] = useState(() => { + // Initialize with hardcoded stars to avoid GitHub API rate limit + return Object.fromEntries(projects.map((p) => [p.repoPath, p.stars ?? null])); + }); + + useEffect(() => { + let active = true; + + // Try to fetch live stars, but fallback to hardcoded values on rate limit + void fetchAllStars(projects.map((p) => p.repoPath)).then((stars) => { + if (active) { + setStarsByRepo(stars); + } + }); + + return () => { + active = false; + }; + }, [projects]); + + const cards = useMemo( + () => + projects.map((project) => ( + + )), + [projects, starsByRepo], + ); + + return ( +
+ {cards} +
+ ); +} diff --git a/landing/src/components/Header.tsx b/landing/src/components/Header.tsx new file mode 100644 index 0000000..fb69742 --- /dev/null +++ b/landing/src/components/Header.tsx @@ -0,0 +1,12 @@ +/** + * @license AGPL-3.0-or-later + */ + +export function Header() { + return ( +
+ helpers4 logo +

helpers4

+
+ ); +} diff --git a/landing/src/components/footer.module.css b/landing/src/components/footer.module.css deleted file mode 100644 index d1e627c..0000000 --- a/landing/src/components/footer.module.css +++ /dev/null @@ -1,66 +0,0 @@ -.footer { - background: var(--wa-color-surface-highest); - color: var(--wa-color-text-primary); - padding: 3rem 0 1rem 0; - margin-top: 4rem; - border-top: 1px solid var(--wa-color-stroke-default); -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 var(--wa-space-m); -} - -.grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 2rem; - margin-bottom: 2rem; -} - -.section h4 { - font-size: 0.95rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - margin: 0 0 1rem 0; - color: var(--wa-color-text-primary); -} - -.section ul { - list-style: none; - padding: 0; - margin: 0; -} - -.section li { - margin-bottom: 0.5rem; -} - -.section a { - color: var(--wa-color-text-secondary); - text-decoration: none; - transition: color 0.2s ease; - font-size: 0.9rem; -} - -.section a:hover { - color: var(--wa-color-brand-500); -} - -.bottom { - padding-top: 2rem; - text-align: center; -} - -.bottom p { - margin: 0.5rem 0; - font-size: 0.9rem; - color: var(--wa-color-text-secondary); -} - -.license { - font-size: 0.8rem; - color: var(--wa-color-text-tertiary); -} diff --git a/landing/src/components/footer.tsx b/landing/src/components/footer.tsx deleted file mode 100644 index 96856d1..0000000 --- a/landing/src/components/footer.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { component$ } from '@builder.io/qwik'; -import styles from './footer.module.css'; - -export const Footer = component$(() => { - return ( -
-
-
-
-

Organization

-
    -
  • - - - GitHub Organization - -
  • -
  • - - - All Repositories - -
  • -
-
- -
-

Libraries

-
    -
  • - - - TypeScript - -
  • -
  • - - - DevContainer - -
  • -
  • - - - GitHub Actions - -
  • -
-
- -
-

Links

-
    -
  • - - - npm Organization - -
  • -
  • - - - GitHub Marketplace - -
  • -
-
-
- - - -
-

- Built with ❤️ by the helpers4 community -

-

- AGPL-3.0 License - See individual repositories for details -

-
-
-
- ); -}); diff --git a/landing/src/components/hero.module.css b/landing/src/components/hero.module.css deleted file mode 100644 index dcbca15..0000000 --- a/landing/src/components/hero.module.css +++ /dev/null @@ -1,91 +0,0 @@ -.hero { - background: linear-gradient( - 135deg, - var(--wa-color-brand-900) 0%, - var(--wa-color-brand-700) 100% - ); - color: var(--wa-color-text-inverse-primary); - padding: 5rem var(--wa-space-m); - text-align: center; - min-height: 600px; - display: flex; - align-items: center; - justify-content: center; -} - -.content { - max-width: 800px; - margin: 0 auto; -} - -.title { - font-size: 3.5rem; - font-weight: 800; - line-height: 1.1; - margin: 0 0 1.5rem 0; - letter-spacing: -0.02em; -} - -.subtitle { - font-size: 1.25rem; - line-height: 1.8; - color: rgba(255, 255, 255, 0.9); - margin: 0 0 2rem 0; - max-width: 600px; - margin-left: auto; - margin-right: auto; -} - -.stats { - display: flex; - justify-content: center; - gap: var(--wa-space-l); - flex-wrap: wrap; - margin: 2rem 0; -} - -.stat { - min-width: 150px; - text-align: center; -} - -.stat::part(base) { - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(10px); - border-color: rgba(255, 255, 255, 0.2); -} - -.statValue { - font-size: 2.5rem; - font-weight: 700; - margin: 0 0 0.5rem 0; -} - -.statLabel { - font-size: 0.95rem; - color: rgba(255, 255, 255, 0.8); - text-transform: uppercase; - letter-spacing: 0.05em; - font-weight: 500; -} - -.cta { - display: flex; - gap: var(--wa-space-m); - justify-content: center; - flex-wrap: wrap; -} - -@media (max-width: 768px) { - .title { - font-size: 2.5rem; - } - - .subtitle { - font-size: 1.05rem; - } - - .cta { - flex-direction: column; - } -} diff --git a/landing/src/components/hero.tsx b/landing/src/components/hero.tsx deleted file mode 100644 index 72fc639..0000000 --- a/landing/src/components/hero.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { component$ } from '@builder.io/qwik'; -import styles from './hero.module.css'; - -export const Hero = component$(() => { - return ( -
-
-

helpers4

-

- Modern open-source utilities for TypeScript, DevContainers, and GitHub Actions.
- Tree-shakable • Zero dependencies • Modular -

- -
- -
3
-
Libraries
-
- -
12+
-
Categories
-
- -
-
Tree-shakable
-
-
- -
- - - Explore Libraries - - - - View on GitHub - -
-
-
- ); -}); diff --git a/landing/src/components/index.ts b/landing/src/components/index.ts new file mode 100644 index 0000000..2a1d76b --- /dev/null +++ b/landing/src/components/index.ts @@ -0,0 +1,7 @@ +/** + * @license AGPL-3.0-or-later + */ + +export { CardItem } from './CardItem'; +export { CardsList } from './CardsList'; +export { Header } from './Header'; diff --git a/landing/src/components/libraries.module.css b/landing/src/components/libraries.module.css deleted file mode 100644 index e6e0357..0000000 --- a/landing/src/components/libraries.module.css +++ /dev/null @@ -1,63 +0,0 @@ -.section { - padding: 4rem 0; - background: linear-gradient(180deg, #ffffff 0%, #f3f4f6 100%); -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 var(--wa-space-m); -} - -.title { - font-size: 2.5rem; - font-weight: 700; - text-align: center; - margin: 0 0 0.5rem 0; - color: var(--wa-color-text-primary); -} - -.subtitle { - font-size: 1.125rem; - text-align: center; - color: var(--wa-color-text-secondary); - margin: 0 0 2rem 0; - max-width: 600px; - margin-left: auto; - margin-right: auto; -} - -.grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); - gap: 2rem; - margin-top: 2rem; -} - -.card { - display: flex; - flex-direction: column; - height: 100%; -} - -.description { - color: var(--wa-color-text-secondary); - line-height: 1.6; - margin: 0 0 1.25rem 0; - flex: 1; - font-size: 0.95rem; -} - -.badges { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; - margin: 1rem 0; -} - -.loading, -.error { - text-align: center; - padding: var(--wa-space-l); - color: var(--wa-color-text-secondary); -} diff --git a/landing/src/components/libraries.tsx b/landing/src/components/libraries.tsx deleted file mode 100644 index 0bdba10..0000000 --- a/landing/src/components/libraries.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { component$, Resource } from '@builder.io/qwik'; -import { GithubCard, useGithubStats } from '../lib/github-stats'; -import styles from './libraries.module.css'; - -export const Libraries = component$(() => { - const githubStats = useGithubStats(); - - return ( -
-
-

Libraries

-

- Essential tools for modern development -

- -
- ( -
- - Loading stats... -
- )} - onRejected={() => ( - - - Failed to load stats - - )} - onResolved={(stats) => ( - <> - -
-

TypeScript Helpers

- -
-

- Tree-shakable utility functions: arrays, dates, numbers, objects, promises, strings, URLs, versions, and more. -

-
- TypeScript - ESM - Versioned -
-
- - - Learn more - -
-
- - -
-

DevContainer Features

- -
-

- Pre-configured dev container features for modern web development. Vite, TypeScript, Git tools, and more. -

-
- Docker - 7 Features - Dev -
-
- - - Learn more - -
-
- - -
-

GitHub Actions

- -
-

- Reusable actions for CI/CD workflows. Commit validation, releases, and automation. -

-
- CI/CD - GitHub - Automation -
-
- - - Learn more - -
-
- - )} - /> -
-
-
- ); -}); diff --git a/landing/src/components/navbar.module.css b/landing/src/components/navbar.module.css deleted file mode 100644 index 76ee9ca..0000000 --- a/landing/src/components/navbar.module.css +++ /dev/null @@ -1,57 +0,0 @@ -.navbar { - background: var(--wa-color-surface-high); - border-bottom: 1px solid var(--wa-color-stroke-default); - position: sticky; - top: 0; - z-index: 1000; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 var(--wa-space-m); - display: flex; - justify-content: space-between; - align-items: center; - height: 70px; -} - -.logo { - display: flex; - align-items: center; - gap: 0.75rem; - text-decoration: none; - font-weight: 700; - font-size: 1.25rem; - color: var(--wa-color-text-primary); -} - -.icon { - background: linear-gradient(135deg, var(--wa-color-brand-400), var(--wa-color-brand-600)); - color: white; - width: 32px; - height: 32px; - border-radius: 0.5rem; - display: flex; - align-items: center; - justify-content: center; - font-weight: 800; - font-size: 0.85rem; -} - -.links { - display: flex; - gap: var(--wa-space-l); - align-items: center; -} - -.link { - color: var(--wa-color-text-secondary); - text-decoration: none; - font-weight: 500; - transition: color 0.2s ease; -} - -.link:hover { - color: var(--wa-color-brand-500); -} diff --git a/landing/src/components/navbar.tsx b/landing/src/components/navbar.tsx deleted file mode 100644 index 6eaa419..0000000 --- a/landing/src/components/navbar.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { component$ } from '@builder.io/qwik'; -import styles from './navbar.module.css'; - -export const NavBar = component$(() => { - return ( -
-
- - h4 - helpers4 - -
- - Libraries - - - - GitHub - - - - Docs - -
-
-
- ); -}); diff --git a/landing/src/const.ts b/landing/src/const.ts new file mode 100644 index 0000000..48fcca1 --- /dev/null +++ b/landing/src/const.ts @@ -0,0 +1,32 @@ +/** + * @license AGPL-3.0-or-later + */ + +import { type ProjectCard } from './types'; + +export const PROJECTS: ProjectCard[] = [ + { + title: 'For JS and TypeScript', + label: 'TypeScript', + description: 'Tree-shakable utility functions with strict typing.', + docsHref: '/ts/', + repoPath: 'helpers4/typescript', + stars: 0, + }, + { + title: 'For Dev Container', + label: 'Dev Container', + description: 'Reusable development container features for consistent environments.', + docsHref: '/dev-container/', + repoPath: 'helpers4/devcontainer', + stars: 0, + }, + { + title: 'For GitHub Action', + label: 'GitHub Action', + description: 'Automation workflows and publishing support for repositories.', + docsHref: '/action/', + repoPath: 'helpers4/action', + stars: 0, + }, +]; diff --git a/landing/src/index.tsx b/landing/src/index.tsx deleted file mode 100644 index 90534b5..0000000 --- a/landing/src/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { component$ } from '@builder.io/qwik'; -import { NavBar } from './components/navbar'; -import { Hero } from './components/hero'; -import { Libraries } from './components/libraries'; -import { Footer } from './components/footer'; - -export default component$(() => { - return ( - -
- -
- - -
-
-
-
- ); -}); diff --git a/landing/src/lib/github-stats.tsx b/landing/src/lib/github-stats.tsx deleted file mode 100644 index 8fcc406..0000000 --- a/landing/src/lib/github-stats.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { component$, useResource$, Resource } from '@builder.io/qwik'; - -interface GithubRepo { - name: string; - url: string; - stars: number; - issues: number; - description: string; -} - -interface GithubStats { - typescript: GithubRepo; - devcontainer: GithubRepo; - action: GithubRepo; -} - -export const useGithubStats = () => { - return useResource$(async () => { - const repos = ['typescript', 'devcontainer', 'action']; - const stats: any = {}; - - try { - for (const repo of repos) { - const response = await fetch(`https://api.github.com/repos/helpers4/${repo}`); - if (response.ok) { - const data = await response.json(); - stats[repo] = { - name: data.name, - url: data.html_url, - stars: data.stargazers_count || 0, - issues: data.open_issues_count || 0, - description: data.description || '', - }; - } - } - } catch (error) { - console.error('Failed to fetch GitHub stats:', error); - } - - return stats as GithubStats; - }); -}; - -export const GithubCard = component$<{ repo: GithubRepo| undefined }>( - ({ repo }) => { - if (!repo) { - return
Loading...
; - } - - return ( - - ); - } -); diff --git a/landing/src/main.tsx b/landing/src/main.tsx index e3a4f8e..05b09f6 100644 --- a/landing/src/main.tsx +++ b/landing/src/main.tsx @@ -1,13 +1,39 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later +/** + * @license AGPL-3.0-or-later + */ +import { createRoot } from 'react-dom/client'; import '@awesome.me/webawesome-pro/dist/styles/webawesome.css'; import '@awesome.me/webawesome-pro/dist/styles/themes/tailspin.css'; -import '@awesome.me/webawesome-pro'; +import '@awesome.me/webawesome-pro/dist/components/card/card.js'; +import '@awesome.me/webawesome-pro/dist/components/button/button.js'; +import '@awesome.me/webawesome-pro/dist/components/icon/icon.js'; +import { Header, CardsList } from './components'; +import { PROJECTS } from './const'; -import { render } from '@builder.io/qwik'; -import App from './index'; +function App() { + return ( +
+
-const root = document.getElementById('root'); -if (root) { - render(root, ); +
+

+ Open-source libraries for developers. +

+

+ Free to use under the AGPL-3.0 license, including commercial use. + Modifications must be shared under the same license. + If you use this code to provide a network service, you must make the source code available to users. +

+
+ + +
+ ); +} + +const rootElement = document.getElementById('root'); + +if (rootElement) { + createRoot(rootElement).render(); } diff --git a/landing/src/types.ts b/landing/src/types.ts new file mode 100644 index 0000000..226f8a3 --- /dev/null +++ b/landing/src/types.ts @@ -0,0 +1,14 @@ +/** + * @license AGPL-3.0-or-later + */ + +export type ProjectCard = { + title: string; + label: string; + description: string; + docsHref: string; + repoPath: string; + stars?: number; +}; + +export type RepoStars = Record; diff --git a/landing/src/utils/github.ts b/landing/src/utils/github.ts new file mode 100644 index 0000000..c360591 --- /dev/null +++ b/landing/src/utils/github.ts @@ -0,0 +1,40 @@ +/** + * @license AGPL-3.0-or-later + */ + +export function formatStars(value: number | null): string { + if (value === null) { + return 'N/A'; + } + + if (value >= 1000) { + return `${(value / 1000).toFixed(1)}k`; + } + + return String(value); +} + +export async function fetchRepoStars(repoPath: string): Promise { + try { + const response = await fetch(`https://api.github.com/repos/${repoPath}`); + if (!response.ok) { + return null; + } + + const data = (await response.json()) as { stargazers_count?: number }; + return typeof data.stargazers_count === 'number' ? data.stargazers_count : null; + } catch { + return null; + } +} + +export async function fetchAllStars(repoPaths: string[]): Promise> { + const entries = await Promise.all( + repoPaths.map(async (repoPath) => { + const stars = await fetchRepoStars(repoPath); + return [repoPath, stars] as const; + }), + ); + + return Object.fromEntries(entries); +} diff --git a/landing/src/vite-env.d.ts b/landing/src/vite-env.d.ts index bc4bbf1..7927712 100644 --- a/landing/src/vite-env.d.ts +++ b/landing/src/vite-env.d.ts @@ -1,6 +1,36 @@ /// +/// -declare module '*.module.css' { - const classes: { [key: string]: string }; - export default classes; +import type React from 'react'; + +declare module '*.css'; +declare module '@awesome.me/webawesome-pro/dist/styles/webawesome.css'; +declare module '@awesome.me/webawesome-pro/dist/styles/themes/tailspin.css'; +declare module '@awesome.me/webawesome-pro/dist/components/page/page.js'; +declare module '@awesome.me/webawesome-pro/dist/components/card/card.js'; +declare module '@awesome.me/webawesome-pro/dist/components/button/button.js'; +declare module '@awesome.me/webawesome-pro/dist/components/icon/icon.js'; + +declare module 'react' { + namespace JSX { + interface IntrinsicElements { + 'wa-page': React.DetailedHTMLProps, HTMLElement>; + 'wa-card': React.DetailedHTMLProps, HTMLElement> & { + appearance?: string; + }; + 'wa-button': React.DetailedHTMLProps, HTMLElement> & { + appearance?: string; + variant?: string; + href?: string; + target?: string; + rel?: string; + slot?: string; + }; + 'wa-icon': React.DetailedHTMLProps, HTMLElement> & { + name?: string; + variant?: string; + label?: string; + }; + } + } } diff --git a/landing/tsconfig.json b/landing/tsconfig.json index fa07a7c..742a625 100644 --- a/landing/tsconfig.json +++ b/landing/tsconfig.json @@ -4,7 +4,6 @@ "module": "ES2022", "lib": ["ES2022", "DOM", "DOM.Iterable"], "jsx": "react-jsx", - "jsxImportSource": "@builder.io/qwik", "declaration": true, "declarationMap": true, "sourceMap": true, @@ -12,7 +11,7 @@ "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "resolveJsonModule": true, "allowSyntheticDefaultImports": true }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db2ae0c..f681d18 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -118,17 +118,20 @@ importers: dependencies: '@awesome.me/webawesome-pro': specifier: ^3.2.1 - version: 3.2.1(@floating-ui/utils@0.2.10)(@types/react@18.3.28) - '@builder.io/qwik': - specifier: ^1.19.0 - version: 1.19.0(vite@7.3.1(@types/node@25.2.3)(jiti@1.21.7)(terser@5.46.0)) + version: 3.3.1(@floating-ui/utils@0.2.11)(@types/react@18.3.28) react: - specifier: ^18.2.0 + specifier: ^18.3.1 version: 18.3.1 react-dom: - specifier: ^18.2.0 + specifier: ^18.3.1 version: 18.3.1(react@18.3.1) devDependencies: + '@types/react': + specifier: ^18.3.28 + version: 18.3.28 + '@types/react-dom': + specifier: ^18.3.5 + version: 18.3.7(@types/react@18.3.28) typescript: specifier: ^5.3.0 version: 5.9.3 @@ -211,8 +214,8 @@ packages: resolution: {integrity: sha512-rprr8yA/tcoNoqoKFRm/6hBRsosMfcUSHVDGsi//hjo3g5BLwLtlzBxmhb47/7YjwfEQHtIDvu7L7qkY3kmC/g==} engines: {node: '>= 14.0.0'} - '@awesome.me/webawesome-pro@3.2.1': - resolution: {integrity: sha512-6rDqIpkHDozUL3pcrzvsN/3pjAKCD3JPVg2igb/RRHp+6CwU+GgPkEuRVaTfoj3Jq5/Sj+raWpcA3jvQUViaog==} + '@awesome.me/webawesome-pro@3.3.1': + resolution: {integrity: sha512-MeDDXApCmMboDNBVeRiCf2HWEmu0hFLz81etmPuP+VQkxe9cdGKlUmiBpxLjv5C1ma6UaVQ1izcx5Zffeh0zGA==} engines: {node: '>=14.17.0'} '@babel/code-frame@7.29.0': @@ -785,13 +788,6 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@builder.io/qwik@1.19.0': - resolution: {integrity: sha512-KT3auaIo52cGiw4xrNK91LTiJQ45o5ikUQ4RSoHOQYhioOjUa+WLdrUBVwHVW5KMzpmnhehWHra8p/8/6Xf4Ng==} - engines: {node: '>=16.8.0 <18.0.0 || >=18.11'} - hasBin: true - peerDependencies: - vite: '>=5 <8' - '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -1461,14 +1457,14 @@ packages: cpu: [x64] os: [win32] - '@floating-ui/core@1.7.4': - resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} - '@floating-ui/dom@1.7.5': - resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} - '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -1623,6 +1619,9 @@ packages: peerDependencies: tslib: '2' + '@kurkle/color@0.3.4': + resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} @@ -2479,6 +2478,10 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chart.js@4.5.1: + resolution: {integrity: sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==} + engines: {pnpm: '>=8'} + cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -5151,6 +5154,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + style-observer@0.1.2: + resolution: {integrity: sha512-VdGkVx7dGqEzosau63CI33vRJsAGKPJCXyS9f5ze7gFbgsXm0wt5liXUNB9+YjyfhMyD+iTwNa7sM4cvpP3N9Q==} + style-to-js@1.1.21: resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} @@ -5697,17 +5703,19 @@ snapshots: dependencies: '@algolia/client-common': 5.48.2 - '@awesome.me/webawesome-pro@3.2.1(@floating-ui/utils@0.2.10)(@types/react@18.3.28)': + '@awesome.me/webawesome-pro@3.3.1(@floating-ui/utils@0.2.11)(@types/react@18.3.28)': dependencies: '@ctrl/tinycolor': 4.1.0 - '@floating-ui/dom': 1.7.5 + '@floating-ui/dom': 1.7.6 '@lit/react': 1.0.8(@types/react@18.3.28) '@shoelace-style/animations': 1.2.0 '@shoelace-style/localize': 3.2.1 - composed-offset-position: 0.0.6(@floating-ui/utils@0.2.10) + chart.js: 4.5.1 + composed-offset-position: 0.0.6(@floating-ui/utils@0.2.11) lit: 3.3.2 nanoid: 5.1.6 qr-creator: 1.0.0 + style-observer: 0.1.2 transitivePeerDependencies: - '@floating-ui/utils' - '@types/react' @@ -6465,13 +6473,6 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@builder.io/qwik@1.19.0(vite@7.3.1(@types/node@25.2.3)(jiti@1.21.7)(terser@5.46.0))': - dependencies: - csstype: 3.2.3 - launch-editor: 2.12.0 - rollup: 4.57.1 - vite: 7.3.1(@types/node@25.2.3)(jiti@1.21.7)(terser@5.46.0) - '@colors/colors@1.5.0': optional: true @@ -7812,16 +7813,16 @@ snapshots: '@esbuild/win32-x64@0.27.3': optional: true - '@floating-ui/core@1.7.4': + '@floating-ui/core@1.7.5': dependencies: - '@floating-ui/utils': 0.2.10 + '@floating-ui/utils': 0.2.11 - '@floating-ui/dom@1.7.5': + '@floating-ui/dom@1.7.6': dependencies: - '@floating-ui/core': 1.7.4 - '@floating-ui/utils': 0.2.10 + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 - '@floating-ui/utils@0.2.10': {} + '@floating-ui/utils@0.2.11': {} '@hapi/hoek@9.3.0': {} @@ -7993,6 +7994,8 @@ snapshots: '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) tslib: 2.8.1 + '@kurkle/color@0.3.4': {} + '@leichtgewicht/ip-codec@2.0.5': {} '@lit-labs/ssr-dom-shim@1.5.1': {} @@ -8964,6 +8967,10 @@ snapshots: character-reference-invalid@2.0.1: {} + chart.js@4.5.1: + dependencies: + '@kurkle/color': 0.3.4 + cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -9049,9 +9056,9 @@ snapshots: common-path-prefix@3.0.0: {} - composed-offset-position@0.0.6(@floating-ui/utils@0.2.10): + composed-offset-position@0.0.6(@floating-ui/utils@0.2.11): dependencies: - '@floating-ui/utils': 0.2.10 + '@floating-ui/utils': 0.2.11 compressible@2.0.18: dependencies: @@ -12206,6 +12213,8 @@ snapshots: strip-json-comments@3.1.1: {} + style-observer@0.1.2: {} + style-to-js@1.1.21: dependencies: style-to-object: 1.0.14