mirror of
https://github.com/NotAShelf/nix-evaluator-stats.git
synced 2026-05-08 08:25:13 +00:00
packages/web: allow sharing analysis and comparison views independently
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I16408e124ebcb36e8452d9c261f6d42f6a6a6964
This commit is contained in:
parent
06b78c6b0e
commit
8d7bd7bb05
5 changed files with 339 additions and 1 deletions
|
|
@ -11,7 +11,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ns/core": "workspace:*",
|
"@ns/core": "workspace:*",
|
||||||
"@ns/ui-utils": "workspace:*"
|
"@ns/ui-utils": "workspace:*",
|
||||||
|
"lzutf8": "^0.6.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^25.5.2",
|
"@types/node": "^25.5.2",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import ArrowRightIcon from 'lucide-solid/icons/arrow-right';
|
||||||
import ArrowDownIcon from 'lucide-solid/icons/arrow-down';
|
import ArrowDownIcon from 'lucide-solid/icons/arrow-down';
|
||||||
import ArrowUpIcon from 'lucide-solid/icons/arrow-up';
|
import ArrowUpIcon from 'lucide-solid/icons/arrow-up';
|
||||||
import XIcon from 'lucide-solid/icons/x';
|
import XIcon from 'lucide-solid/icons/x';
|
||||||
|
import ShareIcon from 'lucide-solid/icons/share';
|
||||||
import FileUpload from './FileUpload';
|
import FileUpload from './FileUpload';
|
||||||
|
|
||||||
interface ComparisonViewProps {
|
interface ComparisonViewProps {
|
||||||
|
|
@ -17,6 +18,10 @@ interface ComparisonViewProps {
|
||||||
onPasteStats: (text: string, name: string) => ComparisonEntry | null;
|
onPasteStats: (text: string, name: string) => ComparisonEntry | null;
|
||||||
onFileLoad: (data: StatsData, raw: Record<string, unknown>) => void;
|
onFileLoad: (data: StatsData, raw: Record<string, unknown>) => void;
|
||||||
onTextLoad: (text: string) => void;
|
onTextLoad: (text: string) => void;
|
||||||
|
onGenerateShareUrl: (left: ComparisonEntry, right: ComparisonEntry) => void;
|
||||||
|
initialLeftId?: number | null;
|
||||||
|
initialRightId?: number | null;
|
||||||
|
onInitialSelectionUsed?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ComparisonView: Component<ComparisonViewProps> = props => {
|
const ComparisonView: Component<ComparisonViewProps> = props => {
|
||||||
|
|
@ -47,6 +52,22 @@ const ComparisonView: Component<ComparisonViewProps> = props => {
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
document.addEventListener('paste', handlePaste);
|
document.addEventListener('paste', handlePaste);
|
||||||
|
|
||||||
|
if (props.initialLeftId !== null && props.initialLeftId !== undefined) {
|
||||||
|
const left = props.entries.find(e => e.id === props.initialLeftId);
|
||||||
|
if (left) {
|
||||||
|
setLeftEntry(left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (props.initialRightId !== null && props.initialRightId !== undefined) {
|
||||||
|
const right = props.entries.find(e => e.id === props.initialRightId);
|
||||||
|
if (right) {
|
||||||
|
setRightEntry(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (props.initialLeftId !== null || props.initialRightId !== null) {
|
||||||
|
props.onInitialSelectionUsed?.();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
|
|
@ -192,6 +213,16 @@ const ComparisonView: Component<ComparisonViewProps> = props => {
|
||||||
Replace
|
Replace
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<Show when={leftEntry() && rightEntry()}>
|
||||||
|
<button
|
||||||
|
class="share-btn"
|
||||||
|
onClick={() => props.onGenerateShareUrl(leftEntry()!, rightEntry()!)}
|
||||||
|
title="Copy share URL to clipboard"
|
||||||
|
>
|
||||||
|
<ShareIcon size={16} />
|
||||||
|
Share
|
||||||
|
</button>
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,59 @@
|
||||||
import { createSignal, Show, For, onMount, createEffect, lazy } from 'solid-js';
|
import { createSignal, Show, For, onMount, createEffect, lazy } from 'solid-js';
|
||||||
import { render } from 'solid-js/web';
|
import { render } from 'solid-js/web';
|
||||||
|
import LZUTF8 from 'lzutf8';
|
||||||
import SaveIcon from 'lucide-solid/icons/save';
|
import SaveIcon from 'lucide-solid/icons/save';
|
||||||
import UploadIcon from 'lucide-solid/icons/upload';
|
import UploadIcon from 'lucide-solid/icons/upload';
|
||||||
import Trash2Icon from 'lucide-solid/icons/trash-2';
|
import Trash2Icon from 'lucide-solid/icons/trash-2';
|
||||||
import XIcon from 'lucide-solid/icons/x';
|
import XIcon from 'lucide-solid/icons/x';
|
||||||
|
import ShareIcon from 'lucide-solid/icons/link-2';
|
||||||
import FileUpload from './components/FileUpload';
|
import FileUpload from './components/FileUpload';
|
||||||
import { StatsData, ComparisonEntry, parseStats } from '@ns/core';
|
import { StatsData, ComparisonEntry, parseStats } from '@ns/core';
|
||||||
import './styles.css';
|
import './styles.css';
|
||||||
|
|
||||||
|
type ShareState =
|
||||||
|
| { type: 'analysis'; data: Record<string, unknown>; name: string }
|
||||||
|
| {
|
||||||
|
type: 'compare';
|
||||||
|
left: Record<string, unknown>;
|
||||||
|
right: Record<string, unknown>;
|
||||||
|
leftName: string;
|
||||||
|
rightName: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
function encodeShareUrl(state: ShareState): string {
|
||||||
|
const json = JSON.stringify(state);
|
||||||
|
const encoded = LZUTF8.compress(json, { outputEncoding: 'Base64' }) as string;
|
||||||
|
return encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function decodeShareUrl(encoded: string): ShareState | null {
|
||||||
|
try {
|
||||||
|
const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');
|
||||||
|
const json = LZUTF8.decompress(base64, {
|
||||||
|
inputEncoding: 'Base64',
|
||||||
|
outputEncoding: 'String',
|
||||||
|
}) as string | null;
|
||||||
|
if (!json) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const state = JSON.parse(json) as ShareState;
|
||||||
|
if (state.type === 'analysis') {
|
||||||
|
if (!state.data || !state.name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (state.type === 'compare') {
|
||||||
|
if (!state.left || !state.right || !state.leftName || !state.rightName) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function debounce<T extends (...args: Parameters<T>) => ReturnType<T>>(
|
function debounce<T extends (...args: Parameters<T>) => ReturnType<T>>(
|
||||||
fn: T,
|
fn: T,
|
||||||
delay: number,
|
delay: number,
|
||||||
|
|
@ -35,6 +81,9 @@ function App() {
|
||||||
const [isLoading, setIsLoading] = createSignal(true);
|
const [isLoading, setIsLoading] = createSignal(true);
|
||||||
const [showOverrideModal, setShowOverrideModal] = createSignal(false);
|
const [showOverrideModal, setShowOverrideModal] = createSignal(false);
|
||||||
const [pendingOverrideText, setPendingOverrideText] = createSignal('');
|
const [pendingOverrideText, setPendingOverrideText] = createSignal('');
|
||||||
|
const [showShareToast, setShowShareToast] = createSignal(false);
|
||||||
|
const [initialLeftId, setInitialLeftId] = createSignal<number | null>(null);
|
||||||
|
const [initialRightId, setInitialRightId] = createSignal<number | null>(null);
|
||||||
|
|
||||||
const STORAGE_KEY = 'ns-data';
|
const STORAGE_KEY = 'ns-data';
|
||||||
|
|
||||||
|
|
@ -71,6 +120,51 @@ function App() {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Failed to load saved data:', e);
|
console.warn('Failed to load saved data:', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const shareParam = params.get('share');
|
||||||
|
if (shareParam) {
|
||||||
|
const shareState = decodeShareUrl(shareParam);
|
||||||
|
if (shareState) {
|
||||||
|
try {
|
||||||
|
if (shareState.type === 'analysis') {
|
||||||
|
const data = parseStats(shareState.data);
|
||||||
|
setCurrentStats(data);
|
||||||
|
setCurrentRaw(shareState.data);
|
||||||
|
setSnapshotName(shareState.name);
|
||||||
|
setView('analysis');
|
||||||
|
window.history.replaceState({}, '', window.location.pathname);
|
||||||
|
} else if (shareState.type === 'compare') {
|
||||||
|
const leftData = parseStats(shareState.left);
|
||||||
|
const rightData = parseStats(shareState.right);
|
||||||
|
const leftId = Date.now();
|
||||||
|
const rightId = Date.now() + 1;
|
||||||
|
const leftEntry: ComparisonEntry = {
|
||||||
|
id: leftId,
|
||||||
|
name: shareState.leftName,
|
||||||
|
data: leftData,
|
||||||
|
raw: shareState.left,
|
||||||
|
timestamp: new Date(),
|
||||||
|
};
|
||||||
|
const rightEntry: ComparisonEntry = {
|
||||||
|
id: rightId,
|
||||||
|
name: shareState.rightName,
|
||||||
|
data: rightData,
|
||||||
|
raw: shareState.right,
|
||||||
|
timestamp: new Date(),
|
||||||
|
};
|
||||||
|
setSnapshots([leftEntry, rightEntry]);
|
||||||
|
setInitialLeftId(leftId);
|
||||||
|
setInitialRightId(rightId);
|
||||||
|
setView('compare');
|
||||||
|
window.history.replaceState({}, '', window.location.pathname);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Failed to load shared data:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
|
|
@ -166,6 +260,20 @@ function App() {
|
||||||
setShowSaveDialog(false);
|
setShowSaveDialog(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const shareAnalysis = () => {
|
||||||
|
const stats = currentStats();
|
||||||
|
const raw = currentRaw();
|
||||||
|
if (!stats || !raw) return;
|
||||||
|
const name = snapshotName().trim() || `Analysis ${Date.now()}`;
|
||||||
|
const state: ShareState = { type: 'analysis', data: raw, name };
|
||||||
|
const encoded = encodeShareUrl(state);
|
||||||
|
const url = `${window.location.origin}${window.location.pathname}?share=${encoded}`;
|
||||||
|
navigator.clipboard.writeText(url).then(() => {
|
||||||
|
setShowShareToast(true);
|
||||||
|
setTimeout(() => setShowShareToast(false), 2000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const deleteSnapshot = (id: number) => {
|
const deleteSnapshot = (id: number) => {
|
||||||
setSnapshots(prev => prev.filter(e => e.id !== id));
|
setSnapshots(prev => prev.filter(e => e.id !== id));
|
||||||
};
|
};
|
||||||
|
|
@ -248,6 +356,22 @@ function App() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleGenerateShareUrl = (left: ComparisonEntry, right: ComparisonEntry) => {
|
||||||
|
const state: ShareState = {
|
||||||
|
type: 'compare',
|
||||||
|
left: left.raw,
|
||||||
|
right: right.raw,
|
||||||
|
leftName: left.name,
|
||||||
|
rightName: right.name,
|
||||||
|
};
|
||||||
|
const encoded = encodeShareUrl(state);
|
||||||
|
const url = `${window.location.origin}${window.location.pathname}?share=${encoded}`;
|
||||||
|
navigator.clipboard.writeText(url).then(() => {
|
||||||
|
setShowShareToast(true);
|
||||||
|
setTimeout(() => setShowShareToast(false), 2000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="app">
|
<div class="app">
|
||||||
<header class="header">
|
<header class="header">
|
||||||
|
|
@ -364,6 +488,13 @@ function App() {
|
||||||
onPasteStats={handlePasteStats}
|
onPasteStats={handlePasteStats}
|
||||||
onFileLoad={handleCompareFileLoad}
|
onFileLoad={handleCompareFileLoad}
|
||||||
onTextLoad={handleCompareTextLoad}
|
onTextLoad={handleCompareTextLoad}
|
||||||
|
onGenerateShareUrl={handleGenerateShareUrl}
|
||||||
|
initialLeftId={initialLeftId()}
|
||||||
|
initialRightId={initialRightId()}
|
||||||
|
onInitialSelectionUsed={() => {
|
||||||
|
setInitialLeftId(null);
|
||||||
|
setInitialRightId(null);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
@ -429,11 +560,18 @@ function App() {
|
||||||
>
|
>
|
||||||
<SaveIcon size={20} />
|
<SaveIcon size={20} />
|
||||||
</button>
|
</button>
|
||||||
|
<button class="action-btn share" onClick={shareAnalysis} title="Share Analysis">
|
||||||
|
<ShareIcon size={20} />
|
||||||
|
</button>
|
||||||
<button class="action-btn clear" onClick={() => setCurrentStats(null)} title="Load New">
|
<button class="action-btn clear" onClick={() => setCurrentStats(null)} title="Load New">
|
||||||
<UploadIcon size={20} />
|
<UploadIcon size={20} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
|
<Show when={showShareToast()}>
|
||||||
|
<div class="toast">Share URL copied to clipboard!</div>
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -444,6 +444,16 @@ body {
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action-btn.share {
|
||||||
|
background: var(--accent);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.share:hover {
|
||||||
|
background: var(--accent-hover);
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
.action-btn.clear {
|
.action-btn.clear {
|
||||||
background: var(--bg-secondary);
|
background: var(--bg-secondary);
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
|
|
@ -1496,6 +1506,26 @@ body {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.share-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
height: calc(0.75rem * 2 + 1rem + 2px);
|
||||||
|
padding: 0 0.875rem;
|
||||||
|
background: var(--accent);
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-btn:hover {
|
||||||
|
background: var(--accent-hover);
|
||||||
|
}
|
||||||
|
|
||||||
.compare-placeholder {
|
.compare-placeholder {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 4rem;
|
padding: 4rem;
|
||||||
|
|
@ -1768,3 +1798,30 @@ body {
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 6rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
padding: 0.875rem 1.5rem;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
z-index: 1000;
|
||||||
|
animation: toast-in 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes toast-in {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50%) translateY(0.5rem);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(-50%) translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
111
pnpm-lock.yaml
generated
111
pnpm-lock.yaml
generated
|
|
@ -77,6 +77,9 @@ importers:
|
||||||
'@ns/ui-utils':
|
'@ns/ui-utils':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../ui-utils
|
version: link:../ui-utils
|
||||||
|
lzutf8:
|
||||||
|
specifier: ^0.6.3
|
||||||
|
version: 0.6.3
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^25.5.2
|
specifier: ^25.5.2
|
||||||
|
|
@ -920,6 +923,13 @@ packages:
|
||||||
}
|
}
|
||||||
engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 }
|
engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 }
|
||||||
|
|
||||||
|
abort-controller@3.0.0:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==,
|
||||||
|
}
|
||||||
|
engines: { node: '>=6.5' }
|
||||||
|
|
||||||
acorn-jsx@5.3.2:
|
acorn-jsx@5.3.2:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -969,6 +979,12 @@ packages:
|
||||||
}
|
}
|
||||||
engines: { node: 18 || 20 || >=22 }
|
engines: { node: 18 || 20 || >=22 }
|
||||||
|
|
||||||
|
base64-js@1.5.1:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==,
|
||||||
|
}
|
||||||
|
|
||||||
baseline-browser-mapping@2.10.16:
|
baseline-browser-mapping@2.10.16:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -992,6 +1008,12 @@ packages:
|
||||||
engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 }
|
engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 }
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
buffer@6.0.3:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==,
|
||||||
|
}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001787:
|
caniuse-lite@1.0.30001787:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -1155,6 +1177,20 @@ packages:
|
||||||
}
|
}
|
||||||
engines: { node: '>=0.10.0' }
|
engines: { node: '>=0.10.0' }
|
||||||
|
|
||||||
|
event-target-shim@5.0.1:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==,
|
||||||
|
}
|
||||||
|
engines: { node: '>=6' }
|
||||||
|
|
||||||
|
events@3.3.0:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==,
|
||||||
|
}
|
||||||
|
engines: { node: '>=0.8.x' }
|
||||||
|
|
||||||
fast-deep-equal@3.1.3:
|
fast-deep-equal@3.1.3:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -1240,6 +1276,12 @@ packages:
|
||||||
integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==,
|
integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ieee754@1.2.1:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==,
|
||||||
|
}
|
||||||
|
|
||||||
ignore@5.3.2:
|
ignore@5.3.2:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -1472,6 +1514,12 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
solid-js: ^1.4.7
|
solid-js: ^1.4.7
|
||||||
|
|
||||||
|
lzutf8@0.6.3:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-CAkF9HKrM+XpB0f3DepQ2to2iUEo0zrbh+XgBqgNBc1+k8HMM3u/YSfHI3Dr4GmoTIez2Pr/If1XFl3rU26AwA==,
|
||||||
|
}
|
||||||
|
|
||||||
merge-anything@5.1.7:
|
merge-anything@5.1.7:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -1588,6 +1636,13 @@ packages:
|
||||||
engines: { node: '>=14' }
|
engines: { node: '>=14' }
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
process@0.11.10:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==,
|
||||||
|
}
|
||||||
|
engines: { node: '>= 0.6.0' }
|
||||||
|
|
||||||
punycode@2.3.1:
|
punycode@2.3.1:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -1595,6 +1650,13 @@ packages:
|
||||||
}
|
}
|
||||||
engines: { node: '>=6' }
|
engines: { node: '>=6' }
|
||||||
|
|
||||||
|
readable-stream@4.7.0:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==,
|
||||||
|
}
|
||||||
|
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
|
||||||
|
|
||||||
rolldown@1.0.0-rc.15:
|
rolldown@1.0.0-rc.15:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -1603,6 +1665,12 @@ packages:
|
||||||
engines: { node: ^20.19.0 || >=22.12.0 }
|
engines: { node: ^20.19.0 || >=22.12.0 }
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
safe-buffer@5.2.1:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==,
|
||||||
|
}
|
||||||
|
|
||||||
semver@6.3.1:
|
semver@6.3.1:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -1669,6 +1737,12 @@ packages:
|
||||||
}
|
}
|
||||||
engines: { node: '>=0.10.0' }
|
engines: { node: '>=0.10.0' }
|
||||||
|
|
||||||
|
string_decoder@1.3.0:
|
||||||
|
resolution:
|
||||||
|
{
|
||||||
|
integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==,
|
||||||
|
}
|
||||||
|
|
||||||
tinyglobby@0.2.16:
|
tinyglobby@0.2.16:
|
||||||
resolution:
|
resolution:
|
||||||
{
|
{
|
||||||
|
|
@ -2288,6 +2362,10 @@ snapshots:
|
||||||
'@typescript-eslint/types': 8.58.1
|
'@typescript-eslint/types': 8.58.1
|
||||||
eslint-visitor-keys: 5.0.1
|
eslint-visitor-keys: 5.0.1
|
||||||
|
|
||||||
|
abort-controller@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
event-target-shim: 5.0.1
|
||||||
|
|
||||||
acorn-jsx@5.3.2(acorn@8.16.0):
|
acorn-jsx@5.3.2(acorn@8.16.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
acorn: 8.16.0
|
acorn: 8.16.0
|
||||||
|
|
@ -2319,6 +2397,8 @@ snapshots:
|
||||||
|
|
||||||
balanced-match@4.0.4: {}
|
balanced-match@4.0.4: {}
|
||||||
|
|
||||||
|
base64-js@1.5.1: {}
|
||||||
|
|
||||||
baseline-browser-mapping@2.10.16: {}
|
baseline-browser-mapping@2.10.16: {}
|
||||||
|
|
||||||
brace-expansion@5.0.5:
|
brace-expansion@5.0.5:
|
||||||
|
|
@ -2333,6 +2413,11 @@ snapshots:
|
||||||
node-releases: 2.0.37
|
node-releases: 2.0.37
|
||||||
update-browserslist-db: 1.2.3(browserslist@4.28.2)
|
update-browserslist-db: 1.2.3(browserslist@4.28.2)
|
||||||
|
|
||||||
|
buffer@6.0.3:
|
||||||
|
dependencies:
|
||||||
|
base64-js: 1.5.1
|
||||||
|
ieee754: 1.2.1
|
||||||
|
|
||||||
caniuse-lite@1.0.30001787: {}
|
caniuse-lite@1.0.30001787: {}
|
||||||
|
|
||||||
convert-source-map@2.0.0: {}
|
convert-source-map@2.0.0: {}
|
||||||
|
|
@ -2459,6 +2544,10 @@ snapshots:
|
||||||
|
|
||||||
esutils@2.0.3: {}
|
esutils@2.0.3: {}
|
||||||
|
|
||||||
|
event-target-shim@5.0.1: {}
|
||||||
|
|
||||||
|
events@3.3.0: {}
|
||||||
|
|
||||||
fast-deep-equal@3.1.3: {}
|
fast-deep-equal@3.1.3: {}
|
||||||
|
|
||||||
fast-json-stable-stringify@2.1.0: {}
|
fast-json-stable-stringify@2.1.0: {}
|
||||||
|
|
@ -2496,6 +2585,8 @@ snapshots:
|
||||||
|
|
||||||
html-entities@2.3.3: {}
|
html-entities@2.3.3: {}
|
||||||
|
|
||||||
|
ieee754@1.2.1: {}
|
||||||
|
|
||||||
ignore@5.3.2: {}
|
ignore@5.3.2: {}
|
||||||
|
|
||||||
ignore@7.0.5: {}
|
ignore@7.0.5: {}
|
||||||
|
|
@ -2594,6 +2685,10 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
solid-js: 1.9.12
|
solid-js: 1.9.12
|
||||||
|
|
||||||
|
lzutf8@0.6.3:
|
||||||
|
dependencies:
|
||||||
|
readable-stream: 4.7.0
|
||||||
|
|
||||||
merge-anything@5.1.7:
|
merge-anything@5.1.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-what: 4.1.16
|
is-what: 4.1.16
|
||||||
|
|
@ -2649,8 +2744,18 @@ snapshots:
|
||||||
|
|
||||||
prettier@3.8.1: {}
|
prettier@3.8.1: {}
|
||||||
|
|
||||||
|
process@0.11.10: {}
|
||||||
|
|
||||||
punycode@2.3.1: {}
|
punycode@2.3.1: {}
|
||||||
|
|
||||||
|
readable-stream@4.7.0:
|
||||||
|
dependencies:
|
||||||
|
abort-controller: 3.0.0
|
||||||
|
buffer: 6.0.3
|
||||||
|
events: 3.3.0
|
||||||
|
process: 0.11.10
|
||||||
|
string_decoder: 1.3.0
|
||||||
|
|
||||||
rolldown@1.0.0-rc.15:
|
rolldown@1.0.0-rc.15:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@oxc-project/types': 0.124.0
|
'@oxc-project/types': 0.124.0
|
||||||
|
|
@ -2672,6 +2777,8 @@ snapshots:
|
||||||
'@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15
|
'@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15
|
||||||
'@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15
|
'@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15
|
||||||
|
|
||||||
|
safe-buffer@5.2.1: {}
|
||||||
|
|
||||||
semver@6.3.1: {}
|
semver@6.3.1: {}
|
||||||
|
|
||||||
semver@7.7.4: {}
|
semver@7.7.4: {}
|
||||||
|
|
@ -2705,6 +2812,10 @@ snapshots:
|
||||||
|
|
||||||
source-map-js@1.2.1: {}
|
source-map-js@1.2.1: {}
|
||||||
|
|
||||||
|
string_decoder@1.3.0:
|
||||||
|
dependencies:
|
||||||
|
safe-buffer: 5.2.1
|
||||||
|
|
||||||
tinyglobby@0.2.16:
|
tinyglobby@0.2.16:
|
||||||
dependencies:
|
dependencies:
|
||||||
fdir: 6.5.0(picomatch@4.0.4)
|
fdir: 6.5.0(picomatch@4.0.4)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue