kappa mirror: ui + q closures (2357 objects, blake3-addressed) - U3 (part 5)
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +1 -0
- b/7c94194f6ae258e7962b9038fde33f9ea83436fef34a9b6f2bd0aeb9a71832f9 +59 -0
- b/7ca9db9c9f90d8c0cc7be6325ed12b23f192567a6a3609415468afa325191614 +27 -0
- b/7cab59a17fdca534668351692972c446e784840ac6a3ada4c4c2bc98b90def21 +20 -0
- b/7d0acc4f5ee3f54576205bf024c578ed0ffacddf5ffd9d0e0e74e0c06504f61f +1 -0
- b/7d11b7cbbef379fee1f2beaca2cec83b7580f4cad7c622d792fed27f98f433fb +0 -0
- b/7d2373b0423832c322df6e168c8f24f3d11b543644f9a348fc3bce587be41132 +20 -0
- b/7d36638ce776a6d44cea84846d1d498e7ae257f789ae7d542f3922f540a3ec27 +94 -0
- b/7d465442a594e690fcadfee764aba9e1c5e4d75f83a1e9166d08c71aeeae16c7 +20 -0
- b/7d75cd08318bc3da6ef6e01d223d2aa5e9bd402960c894937cb908939978ddf1 +64 -0
- b/7d7e23cb1a98743e844e2c81ff60f53a0722fbc729a5771eb1941d47464867b3 +7 -0
- b/7d9f323cce0ac6bfd8632416fa50954d5ffb775b9e6f177989b26a15513cac07 +7 -0
- b/7dc50be3dfe0ebc2d723c2776efe39b4aec0b229ca831504e7a51a8f0f8fa545 +67 -0
- b/7de0257cdb542f26c13df7d2618952a0eceee269bb39112913cd9e119e81e9aa +38 -0
- b/7dec6f767bc56b6ca4d8a9b1466668b610487ddadbffd8af1ad3e207ec69de75 +138 -0
- b/7df3f984b8b390d4f7bd37919880eb578b768135c6e28febc7cf0c7e12db34c0 +1 -0
- b/7df7b2aed777965801d0c53ccc30aebe168222d4dc7f9655cfab4c0f42304cd7 +7 -0
- b/7e15964d1bb887e39bb9edebbdcdee192d9b938a8782a8183d07c373034b150b +27 -0
- b/7e162b2333a13ef1e22b36859b603ed1bea97583111d54f8ec369b06d3ca912c +5 -0
- b/7e432d6657c8cfc407353bc200cd6e6f83e64941f4ba7d2a35a6ab5c7399cb2e +88 -0
- b/7e438a060057b1fe1e317554a97135e7733066c0f3f59ab8dad43a2f8c8437fc +60 -0
- b/7e502c71cf1bc0c41721f5c03dddc4992da176836b898283c983368a161b7068 +864 -0
- b/7e530ec32c30fd622814756a82a99606dc963865c7bddfe075bfa8adc003d8bb +51 -0
- b/7e64e42a03aae2b794cc12945866d47f2832b7d36aa68f5b824feb07b99f7c9d +20 -0
- b/7e8619577045f8535dcbcf93bd8be3c72a4e657de3605709f364a17ccd9d22d9 +168 -0
- b/7eb1c553d98e3051cc249c3cca0f88e6f569becfdf9674316f138f3d10a1dbda +20 -0
- b/7ebcefa0db306029a6037f2cf631157bc1d6fc18dc9f7275800b8485aaf87af5 +84 -0
- b/7ee16de3c3d73e5301f3c8f8f4eff9e5a934a95962ac68cb6a46bd10d38e7102 +1 -0
- b/7ef7c27c5e1302f62fb0d4dca0988546bc6600abb18d7313c2076fb9b1bdcb5e +87 -0
- b/7f0e7ae2d260d288634152afa17778c566dd011c50242aca93db24da4990e45a +1 -0
- b/7f156a842f39b67c777393add8fcb4e4d6f4a48f60dad200886f201f51abe68c +35 -0
- b/7f3399686bd8522e467759a93261b3c3b19332caf6a242eedc333ce9a5ce1889 +56 -0
- b/7f5f9102ebee5f45184b8d79389490682cdf2a1c38b33a771c924f9444f28ae3 +227 -0
- b/7f942a10f50e561c4bba8d3c124cb9f5c79bf7cfeca73df5c5034c86f1f5bf66 +1 -0
- b/7fd646dca67a8e4acba92ac322d190ea76a34c9b194e32f228154171fc60d20e +27 -0
- b/7fe9c4fd23bd6f219d5f21107168cd3ac4f6d9e88b40ebe3525c104780bc89db +17 -0
- b/7ff6489df10ee40d906b0322fbb2e6030e96a60f24399b11ea520f09702bbbfb +32 -0
- b/80165c49198f10b2f3aad4c627e2cf3dc707ab863d779a6131d6645f8a861cd1 +7 -0
- b/80235b3abcba833ae912ef0c682f2ffa3162aac12dc2e61691495bdb852e3ff5 +19 -0
- b/807d9cb5d6bc7dcfc02da6704130597c68309e997dd7d5d1ff1ffff5960d5e85 +20 -0
- b/807fd730926d5b732ad87b35cb4eb6c725151ebf8f6a18a75cefcc2f1cb8f7c9 +27 -0
- b/80ecd8805b348cda9c3140fa857c11a9279643e4d418d7aae84fa4985891a269 +158 -0
- b/80fad96c6271e3e14f74a4ca503bef27df355f99b5a920bd7753fc98066e140f +43 -0
- b/80fdc692e539bffcc25e337d147a9eb104da31201c311b6a5625f086a3d39eca +53 -0
- b/8106443153817133945aa49cdf1377054560d97974e6ca62fd142e324dff39a2 +61 -0
- b/81397eb59910f084716618642f5f50bd9c5790dd44ddaf735a341cb5f2165419 +0 -0
- b/81663f74ed767954e39c49f77b49a2a1989544a53fb5d9a45a7d58b00054feaf +71 -0
- b/816d69918ec74ddbfee25527da0b25148f41abac0fe0c4183811a8c3d4659b3a +56 -0
- b/817514b0589eb6db36a802fe5cfeb2bc3786035885ffd023fb504d00c6a292eb +61 -0
- b/818d57be07161f271298770ffe37855d76d52efc0525fe1f56371cc35cc4474d +63 -0
.gitattributes
CHANGED
|
@@ -104,3 +104,4 @@ b/4ad638420430db1bdd3051864a434b18e6fbc40cd6feb91ec48c873b6c23e82c filter=lfs di
|
|
| 104 |
b/50cc95e131bb26b0837a6bfa44a62aff84fefcc21fb94118b099be12846fb87a filter=lfs diff=lfs merge=lfs -text
|
| 105 |
b/6f89df7ac143f7be87409587aa86fdf9640c28f743871f15954544dda360c16c filter=lfs diff=lfs merge=lfs -text
|
| 106 |
b/765a9f4b7f4975d323b6d2b03fc85c6240e533f89188b5c9c3712c774efd3a29 filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 104 |
b/50cc95e131bb26b0837a6bfa44a62aff84fefcc21fb94118b099be12846fb87a filter=lfs diff=lfs merge=lfs -text
|
| 105 |
b/6f89df7ac143f7be87409587aa86fdf9640c28f743871f15954544dda360c16c filter=lfs diff=lfs merge=lfs -text
|
| 106 |
b/765a9f4b7f4975d323b6d2b03fc85c6240e533f89188b5c9c3712c774efd3a29 filter=lfs diff=lfs merge=lfs -text
|
| 107 |
+
b/8c43519c6f672c286fcde80cb884165030ce3a62171181416642e24ca4462ab6 filter=lfs diff=lfs merge=lfs -text
|
b/7c94194f6ae258e7962b9038fde33f9ea83436fef34a9b6f2bd0aeb9a71832f9
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// holo-lora.mjs — a LoRA adapter as a κ-object + a deterministic test adapter shared by the GPU runtime
|
| 2 |
+
// and the CPU witness. An adapter is the learned delta y += scale·B·(A·x) on top of a base linear; it is
|
| 3 |
+
// content (per-layer A,B matrices) → content-addressed (its κ), shareable as a link, applied on-device.
|
| 4 |
+
// genTestAdapter produces a small reproducible adapter (seeded LCG, identical in Node + browser) so the
|
| 5 |
+
// GPU forward and the CPU oracle apply the SAME delta — proving adapter-inference parity.
|
| 6 |
+
|
| 7 |
+
import { readHolo, writeHoloArchive } from "../holo-archive.mjs";
|
| 8 |
+
|
| 9 |
+
const lcg = (seed) => { let s = (seed >>> 0) || 1; return () => { s = (Math.imul(s, 1103515245) + 12345) >>> 0; return (s / 4294967296 - 0.5) * 2; }; };
|
| 10 |
+
|
| 11 |
+
// Open a LoRA adapter sealed as a .holo (writeHoloArchive): per-layer A/B loaded BY κ with per-body L5 +
|
| 12 |
+
// footer L5 (a tampered body is REFUSED). Same rails as a model (readHolo store). Returns {meta, layers, footer}.
|
| 13 |
+
export function openAdapterHolo(bytes) {
|
| 14 |
+
const h = readHolo(bytes); // footer L5 + per-body L5 store + meta
|
| 15 |
+
const m = h.meta, byName = new Map(m.order.map((o) => [o.name, o.kappa]));
|
| 16 |
+
const f32 = (name) => { const c = h.store.get(byName.get(name)).slice(); return new Float32Array(c.buffer, c.byteOffset, c.byteLength / 4); }; // each body re-derives its κ (L5) on get
|
| 17 |
+
const layers = [];
|
| 18 |
+
for (let L = 0; L < m.nLayer; L++) layers.push({ A: f32("blk." + L + ".A"), B: f32("blk." + L + ".B") });
|
| 19 |
+
return { meta: m, target: m.target, scale: m.scale, r: m.r, inn: m.inn, out: m.out, nLayer: m.nLayer, layers, footer: h.footer };
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
// adapter for ONE target module (e.g. attn_q) across all layers: layers[L] = {A:[r×inn], B:[out×r]}.
|
| 23 |
+
export function genTestAdapter({ seed = 1, inn, out, r, nLayer, scale = 1.0, amp = 0.05 }) {
|
| 24 |
+
const layers = [];
|
| 25 |
+
for (let L = 0; L < nLayer; L++) {
|
| 26 |
+
const ra = lcg(seed * 100003 + L * 2 + 1), rb = lcg(seed * 100003 + L * 2 + 2);
|
| 27 |
+
const A = new Float32Array(r * inn); for (let i = 0; i < A.length; i++) A[i] = ra() * amp;
|
| 28 |
+
const B = new Float32Array(out * r); for (let i = 0; i < B.length; i++) B[i] = rb() * amp;
|
| 29 |
+
layers.push({ A, B });
|
| 30 |
+
}
|
| 31 |
+
return { target: "attn_q", scale, inn, out, r, nLayer, layers };
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// Seal an adapter (genTestAdapter / a trained checkpoint) as a .holo that openAdapterHolo reads back byte-for-byte:
|
| 35 |
+
// each per-layer A/B is a content body keyed by sha256(bytes) (L5 on get), meta carries {target,scale,r,inn,out,
|
| 36 |
+
// nLayer,order}. Footer = sha256(everything) = the adapter's shareable did:holo (a tampered body is REFUSED on open).
|
| 37 |
+
// sha256hex is injected (Node: holo-uor; browser: a hex-sha) so this stays DOM-free + dependency-free like the rest.
|
| 38 |
+
export function sealAdapterHolo(ad, sha256hex) {
|
| 39 |
+
if (!ad || !ad.layers || !ad.nLayer) throw new Error("sealAdapterHolo: not an adapter");
|
| 40 |
+
const order = [], bodies = [];
|
| 41 |
+
const push = (name, f32) => {
|
| 42 |
+
const u8 = new Uint8Array(f32.buffer, f32.byteOffset, f32.byteLength);
|
| 43 |
+
const hex = sha256hex(u8); order.push({ name, kappa: hex }); bodies.push({ kappa: hex, bytes: u8 });
|
| 44 |
+
};
|
| 45 |
+
for (let L = 0; L < ad.nLayer; L++) { push("blk." + L + ".A", ad.layers[L].A); push("blk." + L + ".B", ad.layers[L].B); }
|
| 46 |
+
const meta = { format: "holo-lora/1", target: ad.target, scale: ad.scale, r: ad.r, inn: ad.inn, out: ad.out, nLayer: ad.nLayer, order };
|
| 47 |
+
return writeHoloArchive({ meta, bodies, extKey: "holo.lora" }); // { holo, footer, bytes }
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
// raw f32 footprint of an adapter's deltas (the lower bound the seal rounds up from). Pure arithmetic, no alloc.
|
| 51 |
+
export function adapterBytes(ad) { let n = 0; for (const L of ad.layers) n += L.A.byteLength + L.B.byteLength; return n; }
|
| 52 |
+
|
| 53 |
+
// content identity of an adapter: sha256 over its bytes (the shareable κ). sha256hex injected (Node/browser).
|
| 54 |
+
export async function adapterKappa(ad, sha256hex) {
|
| 55 |
+
const parts = [];
|
| 56 |
+
for (const L of ad.layers) { parts.push(new Uint8Array(L.A.buffer, L.A.byteOffset, L.A.byteLength), new Uint8Array(L.B.buffer, L.B.byteOffset, L.B.byteLength)); }
|
| 57 |
+
let n = 0; for (const p of parts) n += p.length; const all = new Uint8Array(n); let o = 0; for (const p of parts) { all.set(p, o); o += p.length; }
|
| 58 |
+
return "sha256:" + (await sha256hex(all));
|
| 59 |
+
}
|
b/7ca9db9c9f90d8c0cc7be6325ed12b23f192567a6a3609415468afa325191614
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.daisyui.toast",
|
| 3 |
+
"name": "daisyui-toast",
|
| 4 |
+
"tier": "component",
|
| 5 |
+
"library": "daisyui",
|
| 6 |
+
"category": "Feedback",
|
| 7 |
+
"upstream": "https://cdn.jsdelivr.net/npm/daisyui@5.5.23/components/toast.css",
|
| 8 |
+
"docs": "https://daisyui.com/components/toast/",
|
| 9 |
+
"did": "did:holo:sha256:ed44bab433cc3e19210a3fa442774c23b5c9e8fb1c6a0795ee834a33f1d982a4",
|
| 10 |
+
"import": "holo://sha256:ed44bab433cc3e19210a3fa442774c23b5c9e8fb1c6a0795ee834a33f1d982a4",
|
| 11 |
+
"integrity": "sha256-7US6tDPMPhkhCj+kQndMI7XJ6PscageV7oNKM/HZgqQ=",
|
| 12 |
+
"kappa": "sha256:ed44bab433cc3e19210a3fa442774c23b5c9e8fb1c6a0795ee834a33f1d982a4",
|
| 13 |
+
"moduleKappa": "sha256:ed44bab433cc3e19210a3fa442774c23b5c9e8fb1c6a0795ee834a33f1d982a4",
|
| 14 |
+
"renderExport": null,
|
| 15 |
+
"format": "css",
|
| 16 |
+
"source": "components/toast.css",
|
| 17 |
+
"module": "vendor/daisyui/components/toast.css",
|
| 18 |
+
"exports": [],
|
| 19 |
+
"bytes": 5002,
|
| 20 |
+
"provenance": {
|
| 21 |
+
"package": "daisyui",
|
| 22 |
+
"version": "5.5.23",
|
| 23 |
+
"integrity": "sha512-xuheNUSL4T6ZVtWXoioqcNkjoyGX85QTDz4HTw2aBPfqk4fuMjax5HDo8qCmpV6M1YN8bGvfx5BpYCoDeRlt+A==",
|
| 24 |
+
"file": "components/toast.css"
|
| 25 |
+
},
|
| 26 |
+
"license": "MIT"
|
| 27 |
+
}
|
b/7cab59a17fdca534668351692972c446e784840ac6a3ada4c4c2bc98b90def21
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.example.form-tanstack-demo",
|
| 3 |
+
"name": "form-tanstack-demo",
|
| 4 |
+
"tier": "example",
|
| 5 |
+
"library": "shadcn",
|
| 6 |
+
"category": "Examples",
|
| 7 |
+
"upstream": "https://ui.shadcn.com/r/styles/new-york-v4/form-tanstack-demo.json",
|
| 8 |
+
"did": "did:holo:sha256:b0a54c0c1b1be29ea699c32f5b35c6fcbac60048a13cf452493ae3288bcf4c1a",
|
| 9 |
+
"import": "holo://sha256:1d653969206b17e1278428e9d49698ec0b2b52663c75fb0c671a48775a0ae870",
|
| 10 |
+
"integrity": "sha256-HWU5aSBrF+EnhCjp1JaY7AsrUmY8dfsMZxpId1oK6HA=",
|
| 11 |
+
"kappa": "sha256:b0a54c0c1b1be29ea699c32f5b35c6fcbac60048a13cf452493ae3288bcf4c1a",
|
| 12 |
+
"moduleKappa": "sha256:1d653969206b17e1278428e9d49698ec0b2b52663c75fb0c671a48775a0ae870",
|
| 13 |
+
"renderExport": "default",
|
| 14 |
+
"source": "registry/new-york-v4/examples/form-tanstack-demo.tsx",
|
| 15 |
+
"module": "vendor/components/form-tanstack-demo.js",
|
| 16 |
+
"exports": [
|
| 17 |
+
"default"
|
| 18 |
+
],
|
| 19 |
+
"license": "MIT"
|
| 20 |
+
}
|
b/7d0acc4f5ee3f54576205bf024c578ed0ffacddf5ffd9d0e0e74e0c06504f61f
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default {".badge":{"@layer daisyui.l1.l2.l3":{"display":"inline-flex","align-items":"center","justify-content":"center","gap":"calc(0.25rem * 2)","border-radius":"var(--radius-selector)","vertical-align":"middle","color":"var(--badge-fg)","border":"var(--border) solid var(--badge-color, var(--color-base-200))","font-size":"0.875rem","width":"fit-content","background-size":"auto, calc(var(--noise) * 100%)","background-image":"none, var(--fx-noise)","background-color":"var(--badge-bg)","--badge-bg":"var(--badge-color, var(--color-base-100))","--badge-fg":"var(--color-base-content)","--size":"calc(var(--size-selector, 0.25rem) * 6)","height":"var(--size)","padding-inline":"calc(var(--size) / 2 - var(--border))"}},".badge-outline":{"@layer daisyui.l1.l2":{"color":"var(--badge-color)","--badge-bg":"#0000","background-image":"none","border-color":"currentColor"}},".badge-dash":{"@layer daisyui.l1.l2":{"color":"var(--badge-color)","--badge-bg":"#0000","background-image":"none","border-color":"currentColor","border-style":"dashed"}},".badge-soft":{"@layer daisyui.l1.l2":{"color":"var(--badge-color, var(--color-base-content))","background-color":"color-mix( in oklab, var(--badge-color, var(--color-base-content)) 8%, var(--color-base-100) )","border-color":"color-mix( in oklab, var(--badge-color, var(--color-base-content)) 10%, var(--color-base-100) )","background-image":"none"}},".badge-primary":{"@layer daisyui.l1.l2":{"--badge-color":"var(--color-primary)","--badge-fg":"var(--color-primary-content)"}},".badge-secondary":{"@layer daisyui.l1.l2":{"--badge-color":"var(--color-secondary)","--badge-fg":"var(--color-secondary-content)"}},".badge-accent":{"@layer daisyui.l1.l2":{"--badge-color":"var(--color-accent)","--badge-fg":"var(--color-accent-content)"}},".badge-neutral":{"@layer daisyui.l1.l2":{"--badge-color":"var(--color-neutral)","--badge-fg":"var(--color-neutral-content)"}},".badge-info":{"@layer daisyui.l1.l2":{"--badge-color":"var(--color-info)","--badge-fg":"var(--color-info-content)"}},".badge-success":{"@layer daisyui.l1.l2":{"--badge-color":"var(--color-success)","--badge-fg":"var(--color-success-content)"}},".badge-warning":{"@layer daisyui.l1.l2":{"--badge-color":"var(--color-warning)","--badge-fg":"var(--color-warning-content)"}},".badge-error":{"@layer daisyui.l1.l2":{"--badge-color":"var(--color-error)","--badge-fg":"var(--color-error-content)"}},".badge-ghost":{"@layer daisyui.l1.l2":{"border-color":"var(--color-base-200)","background-color":"var(--color-base-200)","color":"var(--color-base-content)","background-image":"none"}},".badge-xs":{"@layer daisyui.l1.l2":{"--size":"calc(var(--size-selector, 0.25rem) * 4)","font-size":"0.625rem"}},".badge-sm":{"@layer daisyui.l1.l2":{"--size":"calc(var(--size-selector, 0.25rem) * 5)","font-size":"0.75rem"}},".badge-md":{"@layer daisyui.l1.l2":{"--size":"calc(var(--size-selector, 0.25rem) * 6)","font-size":"0.875rem"}},".badge-lg":{"@layer daisyui.l1.l2":{"--size":"calc(var(--size-selector, 0.25rem) * 7)","font-size":"1rem"}},".badge-xl":{"@layer daisyui.l1.l2":{"--size":"calc(var(--size-selector, 0.25rem) * 8)","font-size":"1.125rem"}}};
|
b/7d11b7cbbef379fee1f2beaca2cec83b7580f4cad7c622d792fed27f98f433fb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
b/7d2373b0423832c322df6e168c8f24f3d11b543644f9a348fc3bce587be41132
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.example.button-size",
|
| 3 |
+
"name": "button-size",
|
| 4 |
+
"tier": "example",
|
| 5 |
+
"library": "shadcn",
|
| 6 |
+
"category": "Examples",
|
| 7 |
+
"upstream": "https://ui.shadcn.com/r/styles/new-york-v4/button-size.json",
|
| 8 |
+
"did": "did:holo:sha256:bab639686b0e35b601d5a9917383a8a6c12bdc20ceed1a1ffd131d269b0d12c7",
|
| 9 |
+
"import": "holo://sha256:de054f7449af17466a7c252eaa8b8bdbbb88ef836b69e566eefd5e51528a0e9a",
|
| 10 |
+
"integrity": "sha256-3gVPdEmvF0ZqfCUuqouL27uI74NraeVm7v1eUVKKDpo=",
|
| 11 |
+
"kappa": "sha256:bab639686b0e35b601d5a9917383a8a6c12bdc20ceed1a1ffd131d269b0d12c7",
|
| 12 |
+
"moduleKappa": "sha256:de054f7449af17466a7c252eaa8b8bdbbb88ef836b69e566eefd5e51528a0e9a",
|
| 13 |
+
"renderExport": "default",
|
| 14 |
+
"source": "registry/new-york-v4/examples/button-size.tsx",
|
| 15 |
+
"module": "vendor/components/button-size.js",
|
| 16 |
+
"exports": [
|
| 17 |
+
"default"
|
| 18 |
+
],
|
| 19 |
+
"license": "MIT"
|
| 20 |
+
}
|
b/7d36638ce776a6d44cea84846d1d498e7ae257f789ae7d542f3922f540a3ec27
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client"
|
| 2 |
+
|
| 3 |
+
import { Bar, BarChart, XAxis } from "recharts"
|
| 4 |
+
|
| 5 |
+
import {
|
| 6 |
+
Card,
|
| 7 |
+
CardContent,
|
| 8 |
+
CardDescription,
|
| 9 |
+
CardHeader,
|
| 10 |
+
CardTitle,
|
| 11 |
+
} from "@/registry/new-york-v4/ui/card"
|
| 12 |
+
import {
|
| 13 |
+
ChartContainer,
|
| 14 |
+
ChartTooltip,
|
| 15 |
+
ChartTooltipContent,
|
| 16 |
+
type ChartConfig,
|
| 17 |
+
} from "@/registry/new-york-v4/ui/chart"
|
| 18 |
+
|
| 19 |
+
export const description = "A stacked bar chart with a legend"
|
| 20 |
+
|
| 21 |
+
const chartData = [
|
| 22 |
+
{ date: "2024-07-15", running: 450, swimming: 300 },
|
| 23 |
+
{ date: "2024-07-16", running: 380, swimming: 420 },
|
| 24 |
+
{ date: "2024-07-17", running: 520, swimming: 120 },
|
| 25 |
+
{ date: "2024-07-18", running: 140, swimming: 550 },
|
| 26 |
+
{ date: "2024-07-19", running: 600, swimming: 350 },
|
| 27 |
+
{ date: "2024-07-20", running: 480, swimming: 400 },
|
| 28 |
+
]
|
| 29 |
+
|
| 30 |
+
const chartConfig = {
|
| 31 |
+
running: {
|
| 32 |
+
label: "Running",
|
| 33 |
+
color: "var(--chart-1)",
|
| 34 |
+
},
|
| 35 |
+
swimming: {
|
| 36 |
+
label: "Swimming",
|
| 37 |
+
color: "var(--chart-2)",
|
| 38 |
+
},
|
| 39 |
+
} satisfies ChartConfig
|
| 40 |
+
|
| 41 |
+
export function ChartTooltipLabelFormatter() {
|
| 42 |
+
return (
|
| 43 |
+
<Card>
|
| 44 |
+
<CardHeader>
|
| 45 |
+
<CardTitle>Tooltip - Label Formatter</CardTitle>
|
| 46 |
+
<CardDescription>Tooltip with label formatter.</CardDescription>
|
| 47 |
+
</CardHeader>
|
| 48 |
+
<CardContent>
|
| 49 |
+
<ChartContainer config={chartConfig}>
|
| 50 |
+
<BarChart accessibilityLayer data={chartData}>
|
| 51 |
+
<XAxis
|
| 52 |
+
dataKey="date"
|
| 53 |
+
tickLine={false}
|
| 54 |
+
tickMargin={10}
|
| 55 |
+
axisLine={false}
|
| 56 |
+
tickFormatter={(value) => {
|
| 57 |
+
return new Date(value).toLocaleDateString("en-US", {
|
| 58 |
+
weekday: "short",
|
| 59 |
+
})
|
| 60 |
+
}}
|
| 61 |
+
/>
|
| 62 |
+
<Bar
|
| 63 |
+
dataKey="running"
|
| 64 |
+
stackId="a"
|
| 65 |
+
fill="var(--color-running)"
|
| 66 |
+
radius={[0, 0, 4, 4]}
|
| 67 |
+
/>
|
| 68 |
+
<Bar
|
| 69 |
+
dataKey="swimming"
|
| 70 |
+
stackId="a"
|
| 71 |
+
fill="var(--color-swimming)"
|
| 72 |
+
radius={[4, 4, 0, 0]}
|
| 73 |
+
/>
|
| 74 |
+
<ChartTooltip
|
| 75 |
+
content={
|
| 76 |
+
<ChartTooltipContent
|
| 77 |
+
labelFormatter={(value) => {
|
| 78 |
+
return new Date(value).toLocaleDateString("en-US", {
|
| 79 |
+
day: "numeric",
|
| 80 |
+
month: "long",
|
| 81 |
+
year: "numeric",
|
| 82 |
+
})
|
| 83 |
+
}}
|
| 84 |
+
/>
|
| 85 |
+
}
|
| 86 |
+
cursor={false}
|
| 87 |
+
defaultIndex={1}
|
| 88 |
+
/>
|
| 89 |
+
</BarChart>
|
| 90 |
+
</ChartContainer>
|
| 91 |
+
</CardContent>
|
| 92 |
+
</Card>
|
| 93 |
+
)
|
| 94 |
+
}
|
b/7d465442a594e690fcadfee764aba9e1c5e4d75f83a1e9166d08c71aeeae16c7
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.example.toggle-group-single",
|
| 3 |
+
"name": "toggle-group-single",
|
| 4 |
+
"tier": "example",
|
| 5 |
+
"library": "shadcn",
|
| 6 |
+
"category": "Examples",
|
| 7 |
+
"upstream": "https://ui.shadcn.com/r/styles/new-york-v4/toggle-group-single.json",
|
| 8 |
+
"did": "did:holo:sha256:38866c073dd15ceab478c25fcb9c0686840e60643356ff073328cc731858d1fc",
|
| 9 |
+
"import": "holo://sha256:7f2fe19b817da06e49bef5df3e04f6ce1f045923e495fd9b44925216b0fd0a0e",
|
| 10 |
+
"integrity": "sha256-fy/hm4F9oG5JvvXfPgT2zh8EWSPklf2bRJJSFrD9Cg4=",
|
| 11 |
+
"kappa": "sha256:38866c073dd15ceab478c25fcb9c0686840e60643356ff073328cc731858d1fc",
|
| 12 |
+
"moduleKappa": "sha256:7f2fe19b817da06e49bef5df3e04f6ce1f045923e495fd9b44925216b0fd0a0e",
|
| 13 |
+
"renderExport": "default",
|
| 14 |
+
"source": "registry/new-york-v4/examples/toggle-group-single.tsx",
|
| 15 |
+
"module": "vendor/components/toggle-group-single.js",
|
| 16 |
+
"exports": [
|
| 17 |
+
"default"
|
| 18 |
+
],
|
| 19 |
+
"license": "MIT"
|
| 20 |
+
}
|
b/7d75cd08318bc3da6ef6e01d223d2aa5e9bd402960c894937cb908939978ddf1
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from "react"
|
| 2 |
+
import { cva, type VariantProps } from "class-variance-authority"
|
| 3 |
+
import { Slot } from "radix-ui"
|
| 4 |
+
|
| 5 |
+
import { cn } from "@/lib/utils"
|
| 6 |
+
|
| 7 |
+
const buttonVariants = cva(
|
| 8 |
+
"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
| 9 |
+
{
|
| 10 |
+
variants: {
|
| 11 |
+
variant: {
|
| 12 |
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
| 13 |
+
destructive:
|
| 14 |
+
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
|
| 15 |
+
outline:
|
| 16 |
+
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
| 17 |
+
secondary:
|
| 18 |
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
| 19 |
+
ghost:
|
| 20 |
+
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
| 21 |
+
link: "text-primary underline-offset-4 hover:underline",
|
| 22 |
+
},
|
| 23 |
+
size: {
|
| 24 |
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
| 25 |
+
xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
|
| 26 |
+
sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
|
| 27 |
+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
| 28 |
+
icon: "size-9",
|
| 29 |
+
"icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
|
| 30 |
+
"icon-sm": "size-8",
|
| 31 |
+
"icon-lg": "size-10",
|
| 32 |
+
},
|
| 33 |
+
},
|
| 34 |
+
defaultVariants: {
|
| 35 |
+
variant: "default",
|
| 36 |
+
size: "default",
|
| 37 |
+
},
|
| 38 |
+
}
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
function Button({
|
| 42 |
+
className,
|
| 43 |
+
variant = "default",
|
| 44 |
+
size = "default",
|
| 45 |
+
asChild = false,
|
| 46 |
+
...props
|
| 47 |
+
}: React.ComponentProps<"button"> &
|
| 48 |
+
VariantProps<typeof buttonVariants> & {
|
| 49 |
+
asChild?: boolean
|
| 50 |
+
}) {
|
| 51 |
+
const Comp = asChild ? Slot.Root : "button"
|
| 52 |
+
|
| 53 |
+
return (
|
| 54 |
+
<Comp
|
| 55 |
+
data-slot="button"
|
| 56 |
+
data-variant={variant}
|
| 57 |
+
data-size={size}
|
| 58 |
+
className={cn(buttonVariants({ variant, size, className }))}
|
| 59 |
+
{...props}
|
| 60 |
+
/>
|
| 61 |
+
)
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
export { Button, buttonVariants }
|
b/7d7e23cb1a98743e844e2c81ff60f53a0722fbc729a5771eb1941d47464867b3
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import table from './object.js';
|
| 2 |
+
import { addPrefix } from '../../functions/addPrefix.js';
|
| 3 |
+
|
| 4 |
+
export default ({ addComponents, prefix = '' }) => {
|
| 5 |
+
const prefixedtable = addPrefix(table, prefix);
|
| 6 |
+
addComponents({ ...prefixedtable });
|
| 7 |
+
};
|
b/7d9f323cce0ac6bfd8632416fa50954d5ffb775b9e6f177989b26a15513cac07
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import loading from './object.js';
|
| 2 |
+
import { addPrefix } from '../../functions/addPrefix.js';
|
| 3 |
+
|
| 4 |
+
export default ({ addComponents, prefix = '' }) => {
|
| 5 |
+
const prefixedloading = addPrefix(loading, prefix);
|
| 6 |
+
addComponents({ ...prefixedloading });
|
| 7 |
+
};
|
b/7dc50be3dfe0ebc2d723c2776efe39b4aec0b229ca831504e7a51a8f0f8fa545
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
var ut=Object.defineProperty;var st=(e,t)=>{for(var a in t)ut(e,a,{get:t[a],enumerable:!0})};import{forwardRef as ft,createElement as it}from"react";var la=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),we=(...e)=>e.filter((t,a,o)=>!!t&&t.trim()!==""&&o.indexOf(t)===a).join(" ").trim();import{forwardRef as dt,createElement as sa}from"react";var ua={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var da=dt(({color:e="currentColor",size:t=24,strokeWidth:a=2,absoluteStrokeWidth:o,className:r="",children:l,iconNode:u,...s},n)=>sa("svg",{ref:n,...ua,width:t,height:t,stroke:e,strokeWidth:o?Number(a)*24/Number(t):a,className:we("lucide",r),...s},[...u.map(([d,p])=>sa(d,p)),...Array.isArray(l)?l:[l]]));var re=(e,t)=>{let a=ft(({className:o,...r},l)=>it(da,{ref:l,iconNode:t,className:we(`lucide-${la(e)}`,o),...r}));return a.displayName=`${e}`,a};var fe=re("Bold",[["path",{d:"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8",key:"mg9rjx"}]]);var ie=re("Italic",[["line",{x1:"19",x2:"10",y1:"4",y2:"4",key:"15jd3p"}],["line",{x1:"14",x2:"5",y1:"20",y2:"20",key:"bu0au3"}],["line",{x1:"15",x2:"9",y1:"4",y2:"20",key:"uljnxc"}]]);var ne=re("Underline",[["path",{d:"M6 4v6a6 6 0 0 0 12 0V4",key:"9kb039"}],["line",{x1:"4",x2:"20",y1:"20",y2:"20",key:"nun2al"}]]);import*as Oe from"react";import*as ca from"react";import*as St from"react-dom";import*as M from"react";import*as ia from"react";function fa(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function nt(...e){return t=>{let a=!1,o=e.map(r=>{let l=fa(r,t);return!a&&typeof l=="function"&&(a=!0),l});if(a)return()=>{for(let r=0;r<o.length;r++){let l=o[r];typeof l=="function"?l():fa(e[r],null)}}}}function $(...e){return ia.useCallback(nt(...e),e)}function ce(e){let t=M.forwardRef((a,o)=>{let{children:r,...l}=a,u=null,s=!1,n=[];na(r)&&typeof ke=="function"&&(r=ke(r._payload)),M.Children.forEach(r,g=>{if(It(g)){s=!0;let h=g,k="child"in h.props?h.props.child:h.props.children;na(k)&&typeof ke=="function"&&(k=ke(k._payload)),u=pt(h,k),n.push(u?.props?.children)}else n.push(g)}),u?u=M.cloneElement(u,void 0,n):!s&&M.Children.count(r)===1&&M.isValidElement(r)&&(u=r);let d=u?Lt(u):void 0,p=$(o,d);if(!u){if(r||r===0)throw new Error(s?ht(e):Ct(e));return r}let m=mt(l,u.props??{});return u.type!==M.Fragment&&(m.ref=o?p:d),M.cloneElement(u,m)});return t.displayName=`${e}.Slot`,t}var ct=Symbol.for("radix.slottable");var pt=(e,t)=>{if("child"in e.props){let a=e.props.child;return M.isValidElement(a)?M.cloneElement(a,void 0,e.props.children(a.props.children)):null}return M.isValidElement(t)?t:null};function mt(e,t){let a={...t};for(let o in t){let r=e[o],l=t[o];/^on[A-Z]/.test(o)?r&&l?a[o]=(...s)=>{let n=l(...s);return r(...s),n}:r&&(a[o]=r):o==="style"?a[o]={...r,...l}:o==="className"&&(a[o]=[r,l].filter(Boolean).join(" "))}return{...e,...a}}function Lt(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,a=t&&"isReactWarning"in t&&t.isReactWarning;return a?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,a=t&&"isReactWarning"in t&&t.isReactWarning,a?e.props.ref:e.props.ref||e.ref)}function It(e){return M.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===ct}var xt=Symbol.for("react.lazy");function na(e){return e!=null&&typeof e=="object"&&"$$typeof"in e&&e.$$typeof===xt&&"_payload"in e&>(e._payload)}function gt(e){return typeof e=="object"&&e!==null&&"then"in e}var Ct=e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,ht=e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,ke=M[" use ".trim().toString()];import{jsx as wt}from"react/jsx-runtime";var kt=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],_=kt.reduce((e,t)=>{let a=ce(`Primitive.${t}`),o=ca.forwardRef((r,l)=>{let{asChild:u,...s}=r,n=u?a:t;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),wt(n,{...s,ref:l})});return o.displayName=`Primitive.${t}`,{...e,[t]:o}},{});import*as V from"react";import{jsx as bt}from"react/jsx-runtime";function le(e,t=[]){let a=[];function o(l,u){let s=V.createContext(u);s.displayName=l+"Context";let n=a.length;a=[...a,u];let d=m=>{let{scope:g,children:h,...k}=m,C=g?.[e]?.[n]||s,I=V.useMemo(()=>k,Object.values(k));return bt(C.Provider,{value:I,children:h})};d.displayName=l+"Provider";function p(m,g){let h=g?.[e]?.[n]||s,k=V.useContext(h);if(k)return k;if(u!==void 0)return u;throw new Error(`\`${m}\` must be used within \`${l}\``)}return[d,p]}let r=()=>{let l=a.map(u=>V.createContext(u));return function(s){let n=s?.[e]||l;return V.useMemo(()=>({[`__scope${e}`]:{...s,[e]:n}}),[s,n])}};return r.scopeName=e,[o,Pt(r,...t)]}function Pt(...e){let t=e[0];if(e.length===1)return t;let a=()=>{let o=e.map(r=>({useScope:r(),scopeName:r.scopeName}));return function(l){let u=o.reduce((s,{useScope:n,scopeName:d})=>{let m=n(l)[`__scope${d}`];return{...s,...m}},{});return V.useMemo(()=>({[`__scope${t.scopeName}`]:u}),[u])}};return a.scopeName=t.scopeName,a}import*as E from"react";import{jsx as Ve}from"react/jsx-runtime";import*as be from"react";import{jsx as br}from"react/jsx-runtime";function pa(e){let t=e+"CollectionProvider",[a,o]=le(t),[r,l]=a(t,{collectionRef:{current:null},itemMap:new Map}),u=C=>{let{scope:I,children:b}=C,S=E.useRef(null),w=E.useRef(new Map).current;return Ve(r,{scope:I,itemMap:w,collectionRef:S,children:b})};u.displayName=t;let s=e+"CollectionSlot",n=ce(s),d=E.forwardRef((C,I)=>{let{scope:b,children:S}=C,w=l(s,b),P=$(I,w.collectionRef);return Ve(n,{ref:P,children:S})});d.displayName=s;let p=e+"CollectionItemSlot",m="data-radix-collection-item",g=ce(p),h=E.forwardRef((C,I)=>{let{scope:b,children:S,...w}=C,P=E.useRef(null),U=$(I,P),H=l(p,b);return E.useEffect(()=>(H.itemMap.set(P,{ref:P,...w}),()=>void H.itemMap.delete(P))),Ve(g,{[m]:"",ref:U,children:S})});h.displayName=p;function k(C){let I=l(e+"CollectionConsumer",C);return E.useCallback(()=>{let S=I.collectionRef.current;if(!S)return[];let w=Array.from(S.querySelectorAll(`[${m}]`));return Array.from(I.itemMap.values()).sort((H,q)=>w.indexOf(H.ref.current)-w.indexOf(q.ref.current))},[I.collectionRef,I.itemMap])}return[{Provider:u,Slot:d,ItemSlot:h},k,o]}var Rr=!!(typeof window<"u"&&window.document&&window.document.createElement);function W(e,t,{checkForDefaultPrevented:a=!0}={}){return function(r){if(e?.(r),a===!1||!r.defaultPrevented)return t?.(r)}}import*as G from"react";import*as ma from"react";var Pe=globalThis?.document?ma.useLayoutEffect:()=>{};import*as Re from"react";var Rt=G[" useInsertionEffect ".trim().toString()]||Pe;function Q({prop:e,defaultProp:t,onChange:a=()=>{},caller:o}){let[r,l,u]=At({defaultProp:t,onChange:a}),s=e!==void 0,n=s?e:r;{let p=G.useRef(e!==void 0);G.useEffect(()=>{let m=p.current;m!==s&&console.warn(`${o} is changing from ${m?"controlled":"uncontrolled"} to ${s?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),p.current=s},[s,o])}let d=G.useCallback(p=>{if(s){let m=yt(p)?p(e):p;m!==e&&u.current?.(m)}else l(p)},[s,e,l,u]);return[n,d]}function At({defaultProp:e,onChange:t}){let[a,o]=G.useState(e),r=G.useRef(a),l=G.useRef(t);return Rt(()=>{l.current=t},[t]),G.useEffect(()=>{r.current!==a&&(l.current?.(a),r.current=a)},[a,r]),[a,o,l]}function yt(e){return typeof e=="function"}var Mr=Symbol("RADIX:SYNC_STATE");import*as We from"react";var vt=We[" useId ".trim().toString()]||(()=>{}),Mt=0;function La(e){let[t,a]=We.useState(vt());return Pe(()=>{e||a(o=>o??String(Mt++))},[e]),e||(t?`radix-${t}`:"")}import*as Ae from"react";import{jsx as qr}from"react/jsx-runtime";var Ft=Ae.createContext(void 0);function ye(e){let t=Ae.useContext(Ft);return e||t||"ltr"}import*as ue from"react";function Ia(e){let t=ue.useRef(e);return ue.useEffect(()=>{t.current=e}),ue.useMemo(()=>(...a)=>t.current?.(...a),[])}import*as v from"react";import{jsx as Y}from"react/jsx-runtime";var Ne="rovingFocusGroup.onEntryFocus",Bt={bubbles:!1,cancelable:!0},pe="RovingFocusGroup",[Xe,xa,Dt]=pa(pe),[Tt,_e]=le(pe,[Dt]),[qt,Ot]=Tt(pe),ga=v.forwardRef((e,t)=>Y(Xe.Provider,{scope:e.__scopeRovingFocusGroup,children:Y(Xe.Slot,{scope:e.__scopeRovingFocusGroup,children:Y(Ut,{...e,ref:t})})}));ga.displayName=pe;var Ut=v.forwardRef((e,t)=>{let{__scopeRovingFocusGroup:a,orientation:o,loop:r=!1,dir:l,currentTabStopId:u,defaultCurrentTabStopId:s,onCurrentTabStopIdChange:n,onEntryFocus:d,preventScrollOnEntryFocus:p=!1,...m}=e,g=v.useRef(null),h=$(t,g),k=ye(l),[C,I]=Q({prop:u,defaultProp:s??null,onChange:n,caller:pe}),[b,S]=v.useState(!1),w=Ia(d),P=xa(a),U=v.useRef(!1),[H,q]=v.useState(0);return v.useEffect(()=>{let f=g.current;if(f)return f.addEventListener(Ne,w),()=>f.removeEventListener(Ne,w)},[w]),Y(qt,{scope:a,orientation:o,dir:k,loop:r,currentTabStopId:C,onItemFocus:v.useCallback(f=>I(f),[I]),onItemShiftTab:v.useCallback(()=>S(!0),[]),onFocusableItemAdd:v.useCallback(()=>q(f=>f+1),[]),onFocusableItemRemove:v.useCallback(()=>q(f=>f-1),[]),children:Y(_.div,{tabIndex:b||H===0?-1:0,"data-orientation":o,...m,ref:h,style:{outline:"none",...e.style},onMouseDown:W(e.onMouseDown,()=>{U.current=!0}),onFocus:W(e.onFocus,f=>{let F=!U.current;if(f.target===f.currentTarget&&F&&!b){let de=new CustomEvent(Ne,Bt);if(f.currentTarget.dispatchEvent(de),!de.defaultPrevented){let te=P().filter(R=>R.focusable),oe=te.find(R=>R.active),Ie=te.find(R=>R.id===C),X=[oe,Ie,...te].filter(Boolean).map(R=>R.ref.current);Sa(X,p)}}U.current=!1}),onBlur:W(e.onBlur,()=>S(!1))})})}),Ca="RovingFocusGroupItem",ha=v.forwardRef((e,t)=>{let{__scopeRovingFocusGroup:a,focusable:o=!0,active:r=!1,tabStopId:l,children:u,...s}=e,n=La(),d=l||n,p=Ot(Ca,a),m=p.currentTabStopId===d,g=xa(a),{onFocusableItemAdd:h,onFocusableItemRemove:k,currentTabStopId:C}=p;return v.useEffect(()=>{if(o)return h(),()=>k()},[o,h,k]),Y(Xe.ItemSlot,{scope:a,id:d,focusable:o,active:r,children:Y(_.span,{tabIndex:m?0:-1,"data-orientation":p.orientation,...s,ref:t,onMouseDown:W(e.onMouseDown,I=>{o?p.onItemFocus(d):I.preventDefault()}),onFocus:W(e.onFocus,()=>p.onItemFocus(d)),onKeyDown:W(e.onKeyDown,I=>{if(I.key==="Tab"&&I.shiftKey){p.onItemShiftTab();return}if(I.target!==I.currentTarget)return;let b=Et(I,p.orientation,p.dir);if(b!==void 0){if(I.metaKey||I.ctrlKey||I.altKey||I.shiftKey)return;I.preventDefault();let w=g().filter(P=>P.focusable).map(P=>P.ref.current);if(b==="last")w.reverse();else if(b==="prev"||b==="next"){b==="prev"&&w.reverse();let P=w.indexOf(I.currentTarget);w=p.loop?zt(w,P+1):w.slice(P+1)}setTimeout(()=>Sa(w))}}),children:typeof u=="function"?u({isCurrentTabStop:m,hasTabStop:C!=null}):u})})});ha.displayName=Ca;var Ht={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function Gt(e,t){return t!=="rtl"?e:e==="ArrowLeft"?"ArrowRight":e==="ArrowRight"?"ArrowLeft":e}function Et(e,t,a){let o=Gt(e.key,a);if(!(t==="vertical"&&["ArrowLeft","ArrowRight"].includes(o))&&!(t==="horizontal"&&["ArrowUp","ArrowDown"].includes(o)))return Ht[o]}function Sa(e,t=!1){let a=document.activeElement;for(let o of e)if(o===a||(o.focus({preventScroll:t}),document.activeElement!==a))return}function zt(e,t){return e.map((a,o)=>e[(t+o)%e.length])}var wa=ga,ka=ha;import*as ba from"react";import{jsx as Wt}from"react/jsx-runtime";var Pa="Toggle",Ke=ba.forwardRef((e,t)=>{let{pressed:a,defaultPressed:o,onPressedChange:r,...l}=e,[u,s]=Q({prop:a,onChange:r,defaultProp:o??!1,caller:Pa});return Wt(_.button,{type:"button","aria-pressed":u,"data-state":u?"on":"off","data-disabled":e.disabled?"":void 0,...l,ref:t,onClick:W(e.onClick,()=>{e.disabled||s(!u)})})});Ke.displayName=Pa;var me={};st(me,{Item:()=>Jt,Root:()=>Zt,ToggleGroup:()=>Me,ToggleGroupItem:()=>je,createToggleGroupScope:()=>Nt});import*as T from"react";import{jsx as O}from"react/jsx-runtime";var K="ToggleGroup",[Aa,Nt]=le(K,[_e]),ya=_e(),Me=T.forwardRef((e,t)=>{let{type:a,...o}=e;if(a==="single")return O(Xt,{...o,ref:t});if(a==="multiple")return O(_t,{...o,ref:t});throw new Error(`Missing prop \`type\` expected on \`${K}\``)});Me.displayName=K;var[va,Ma]=Aa(K),Xt=T.forwardRef((e,t)=>{let{value:a,defaultValue:o,onValueChange:r=()=>{},...l}=e,[u,s]=Q({prop:a,defaultProp:o??"",onChange:r,caller:K});return O(va,{scope:e.__scopeToggleGroup,type:"single",value:T.useMemo(()=>u?[u]:[],[u]),onItemActivate:s,onItemDeactivate:T.useCallback(()=>s(""),[s]),children:O(Fa,{...l,ref:t})})}),_t=T.forwardRef((e,t)=>{let{value:a,defaultValue:o,onValueChange:r=()=>{},...l}=e,[u,s]=Q({prop:a,defaultProp:o??[],onChange:r,caller:K}),n=T.useCallback(p=>s((m=[])=>[...m,p]),[s]),d=T.useCallback(p=>s((m=[])=>m.filter(g=>g!==p)),[s]);return O(va,{scope:e.__scopeToggleGroup,type:"multiple",value:u,onItemActivate:n,onItemDeactivate:d,children:O(Fa,{...l,ref:t})})});Me.displayName=K;var[Kt,jt]=Aa(K),Fa=T.forwardRef((e,t)=>{let{__scopeToggleGroup:a,disabled:o=!1,rovingFocus:r=!0,orientation:l,dir:u,loop:s=!0,...n}=e,d=ya(a),p=ye(u),m={role:"group",dir:p,...n};return O(Kt,{scope:a,rovingFocus:r,disabled:o,children:r?O(wa,{asChild:!0,...d,orientation:l,dir:p,loop:s,children:O(_.div,{...m,ref:t})}):O(_.div,{...m,ref:t})})}),ve="ToggleGroupItem",je=T.forwardRef((e,t)=>{let a=Ma(ve,e.__scopeToggleGroup),o=jt(ve,e.__scopeToggleGroup),r=ya(e.__scopeToggleGroup),l=a.value.includes(e.value),u=o.disabled||e.disabled,s={...e,pressed:l,disabled:u},n=T.useRef(null);return o.rovingFocus?O(ka,{asChild:!0,...r,focusable:!u,active:l,ref:n,children:O(Ra,{...s,ref:t})}):O(Ra,{...s,ref:t})});je.displayName=ve;var Ra=T.forwardRef((e,t)=>{let{__scopeToggleGroup:a,value:o,...r}=e,l=Ma(ve,a),u={role:"radio","aria-checked":e.pressed,"aria-pressed":void 0},s=l.type==="single"?u:void 0;return O(Ke,{...s,...r,ref:t,onPressedChange:n=>{n?l.onItemActivate(o):l.onItemDeactivate(o)}})}),Zt=Me,Jt=je;function Ba(e){var t,a,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var r=e.length;for(t=0;t<r;t++)e[t]&&(a=Ba(e[t]))&&(o&&(o+=" "),o+=a)}else for(a in e)e[a]&&(o&&(o+=" "),o+=a);return o}function Fe(){for(var e,t,a=0,o="",r=arguments.length;a<r;a++)(e=arguments[a])&&(t=Ba(e))&&(o&&(o+=" "),o+=t);return o}var $t=(e,t)=>{let a=new Array(e.length+t.length);for(let o=0;o<e.length;o++)a[o]=e[o];for(let o=0;o<t.length;o++)a[e.length+o]=t[o];return a},Qt=(e,t)=>({classGroupId:e,validator:t}),Ga=(e=new Map,t=null,a)=>({nextPart:e,validators:t,classGroupId:a}),Te="-",Da=[],Yt="arbitrary..",eo=e=>{let t=to(e),{conflictingClassGroups:a,conflictingClassGroupModifiers:o}=e;return{getClassGroupId:u=>{if(u.startsWith("[")&&u.endsWith("]"))return ao(u);let s=u.split(Te),n=s[0]===""&&s.length>1?1:0;return Ea(s,n,t)},getConflictingClassGroupIds:(u,s)=>{if(s){let n=o[u],d=a[u];return n?d?$t(d,n):n:d||Da}return a[u]||Da}}},Ea=(e,t,a)=>{if(e.length-t===0)return a.classGroupId;let r=e[t],l=a.nextPart.get(r);if(l){let d=Ea(e,t+1,l);if(d)return d}let u=a.validators;if(u===null)return;let s=t===0?e.join(Te):e.slice(t).join(Te),n=u.length;for(let d=0;d<n;d++){let p=u[d];if(p.validator(s))return p.classGroupId}},ao=e=>e.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let t=e.slice(1,-1),a=t.indexOf(":"),o=t.slice(0,a);return o?Yt+o:void 0})(),to=e=>{let{theme:t,classGroups:a}=e;return oo(a,t)},oo=(e,t)=>{let a=Ga();for(let o in e){let r=e[o];$e(r,a,o,t)}return a},$e=(e,t,a,o)=>{let r=e.length;for(let l=0;l<r;l++){let u=e[l];ro(u,t,a,o)}},ro=(e,t,a,o)=>{if(typeof e=="string"){lo(e,t,a);return}if(typeof e=="function"){uo(e,t,a,o);return}so(e,t,a,o)},lo=(e,t,a)=>{let o=e===""?t:za(t,e);o.classGroupId=a},uo=(e,t,a,o)=>{if(fo(e)){$e(e(o),t,a,o);return}t.validators===null&&(t.validators=[]),t.validators.push(Qt(a,e))},so=(e,t,a,o)=>{let r=Object.entries(e),l=r.length;for(let u=0;u<l;u++){let[s,n]=r[u];$e(n,za(t,s),a,o)}},za=(e,t)=>{let a=e,o=t.split(Te),r=o.length;for(let l=0;l<r;l++){let u=o[l],s=a.nextPart.get(u);s||(s=Ga(),a.nextPart.set(u,s)),a=s}return a},fo=e=>"isThemeGetter"in e&&e.isThemeGetter===!0,io=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,a=Object.create(null),o=Object.create(null),r=(l,u)=>{a[l]=u,t++,t>e&&(t=0,o=a,a=Object.create(null))};return{get(l){let u=a[l];if(u!==void 0)return u;if((u=o[l])!==void 0)return r(l,u),u},set(l,u){l in a?a[l]=u:r(l,u)}}},Je="!",Ta=":",no=[],qa=(e,t,a,o,r)=>({modifiers:e,hasImportantModifier:t,baseClassName:a,maybePostfixModifierPosition:o,isExternal:r}),co=e=>{let{prefix:t,experimentalParseClassName:a}=e,o=r=>{let l=[],u=0,s=0,n=0,d,p=r.length;for(let C=0;C<p;C++){let I=r[C];if(u===0&&s===0){if(I===Ta){l.push(r.slice(n,C)),n=C+1;continue}if(I==="/"){d=C;continue}}I==="["?u++:I==="]"?u--:I==="("?s++:I===")"&&s--}let m=l.length===0?r:r.slice(n),g=m,h=!1;m.endsWith(Je)?(g=m.slice(0,-1),h=!0):m.startsWith(Je)&&(g=m.slice(1),h=!0);let k=d&&d>n?d-n:void 0;return qa(l,h,g,k)};if(t){let r=t+Ta,l=o;o=u=>u.startsWith(r)?l(u.slice(r.length)):qa(no,!1,u,void 0,!0)}if(a){let r=o;o=l=>a({className:l,parseClassName:r})}return o},po=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((a,o)=>{t.set(a,1e6+o)}),a=>{let o=[],r=[];for(let l=0;l<a.length;l++){let u=a[l],s=u[0]==="[",n=t.has(u);s||n?(r.length>0&&(r.sort(),o.push(...r),r=[]),o.push(u)):r.push(u)}return r.length>0&&(r.sort(),o.push(...r)),o}},mo=e=>({cache:io(e.cacheSize),parseClassName:co(e),sortModifiers:po(e),postfixLookupClassGroupIds:Lo(e),...eo(e)}),Lo=e=>{let t=Object.create(null),a=e.postfixLookupClassGroups;if(a)for(let o=0;o<a.length;o++)t[a[o]]=!0;return t},Io=/\s+/,xo=(e,t)=>{let{parseClassName:a,getClassGroupId:o,getConflictingClassGroupIds:r,sortModifiers:l,postfixLookupClassGroupIds:u}=t,s=[],n=e.trim().split(Io),d="";for(let p=n.length-1;p>=0;p-=1){let m=n[p],{isExternal:g,modifiers:h,hasImportantModifier:k,baseClassName:C,maybePostfixModifierPosition:I}=a(m);if(g){d=m+(d.length>0?" "+d:d);continue}let b=!!I,S;if(b){let q=C.substring(0,I);S=o(q);let f=S&&u[S]?o(C):void 0;f&&f!==S&&(S=f,b=!1)}else S=o(C);if(!S){if(!b){d=m+(d.length>0?" "+d:d);continue}if(S=o(C),!S){d=m+(d.length>0?" "+d:d);continue}b=!1}let w=h.length===0?"":h.length===1?h[0]:l(h).join(":"),P=k?w+Je:w,U=P+S;if(s.indexOf(U)>-1)continue;s.push(U);let H=r(S,b);for(let q=0;q<H.length;++q){let f=H[q];s.push(P+f)}d=m+(d.length>0?" "+d:d)}return d},go=(...e)=>{let t=0,a,o,r="";for(;t<e.length;)(a=e[t++])&&(o=Va(a))&&(r&&(r+=" "),r+=o);return r},Va=e=>{if(typeof e=="string")return e;let t,a="";for(let o=0;o<e.length;o++)e[o]&&(t=Va(e[o]))&&(a&&(a+=" "),a+=t);return a},Co=(e,...t)=>{let a,o,r,l,u=n=>{let d=t.reduce((p,m)=>m(p),e());return a=mo(d),o=a.cache.get,r=a.cache.set,l=s,s(n)},s=n=>{let d=o(n);if(d)return d;let p=xo(n,a);return r(n,p),p};return l=u,(...n)=>l(go(...n))},ho=[],A=e=>{let t=a=>a[e]||ho;return t.isThemeGetter=!0,t},Wa=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Na=/^\((?:(\w[\w-]*):)?(.+)\)$/i,So=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,wo=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,ko=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,bo=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Po=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Ro=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,j=e=>So.test(e),x=e=>!!e&&!Number.isNaN(Number(e)),z=e=>!!e&&Number.isInteger(Number(e)),Ze=e=>e.endsWith("%")&&x(e.slice(0,-1)),N=e=>wo.test(e),Xa=()=>!0,Ao=e=>ko.test(e)&&!bo.test(e),Qe=()=>!1,yo=e=>Po.test(e),vo=e=>Ro.test(e),Mo=e=>!i(e)&&!c(e),Fo=e=>e.startsWith("@container")&&(e[10]==="/"&&e[11]!==void 0||e[11]==="s"&&e[16]!==void 0&&e.startsWith("-size/",10)||e[11]==="n"&&e[18]!==void 0&&e.startsWith("-normal/",10)),Bo=e=>Z(e,ja,Qe),i=e=>Wa.test(e),ee=e=>Z(e,Za,Ao),Oa=e=>Z(e,Eo,x),Do=e=>Z(e,$a,Xa),To=e=>Z(e,Ja,Qe),Ua=e=>Z(e,_a,Qe),qo=e=>Z(e,Ka,vo),Be=e=>Z(e,Qa,yo),c=e=>Na.test(e),Le=e=>ae(e,Za),Oo=e=>ae(e,Ja),Ha=e=>ae(e,_a),Uo=e=>ae(e,ja),Ho=e=>ae(e,Ka),De=e=>ae(e,Qa,!0),Go=e=>ae(e,$a,!0),Z=(e,t,a)=>{let o=Wa.exec(e);return o?o[1]?t(o[1]):a(o[2]):!1},ae=(e,t,a=!1)=>{let o=Na.exec(e);return o?o[1]?t(o[1]):a:!1},_a=e=>e==="position"||e==="percentage",Ka=e=>e==="image"||e==="url",ja=e=>e==="length"||e==="size"||e==="bg-size",Za=e=>e==="length",Eo=e=>e==="number",Ja=e=>e==="family-name",$a=e=>e==="number"||e==="weight",Qa=e=>e==="shadow";var zo=()=>{let e=A("color"),t=A("font"),a=A("text"),o=A("font-weight"),r=A("tracking"),l=A("leading"),u=A("breakpoint"),s=A("container"),n=A("spacing"),d=A("radius"),p=A("shadow"),m=A("inset-shadow"),g=A("text-shadow"),h=A("drop-shadow"),k=A("blur"),C=A("perspective"),I=A("aspect"),b=A("ease"),S=A("animate"),w=()=>["auto","avoid","all","avoid-page","page","left","right","column"],P=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],U=()=>[...P(),c,i],H=()=>["auto","hidden","clip","visible","scroll"],q=()=>["auto","contain","none"],f=()=>[c,i,n],F=()=>[j,"full","auto",...f()],de=()=>[z,"none","subgrid",c,i],te=()=>["auto",{span:["full",z,c,i]},z,c,i],oe=()=>[z,"auto",c,i],Ie=()=>["auto","min","max","fr",c,i],xe=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],X=()=>["start","end","center","stretch","center-safe","end-safe"],R=()=>["auto",...f()],J=()=>[j,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...f()],He=()=>[j,"screen","full","dvw","lvw","svw","min","max","fit",...f()],Ge=()=>[j,"screen","full","lh","dvh","lvh","svh","min","max","fit",...f()],L=()=>[e,c,i],ea=()=>[...P(),Ha,Ua,{position:[c,i]}],aa=()=>["no-repeat",{repeat:["","x","y","space","round"]}],ta=()=>["auto","cover","contain",Uo,Bo,{size:[c,i]}],Ee=()=>[Ze,Le,ee],B=()=>["","none","full",d,c,i],D=()=>["",x,Le,ee],ge=()=>["solid","dashed","dotted","double"],oa=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],y=()=>[x,Ze,Ha,Ua],ra=()=>["","none",k,c,i],Ce=()=>["none",x,c,i],he=()=>["none",x,c,i],ze=()=>[x,c,i],Se=()=>[j,"full",...f()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[N],breakpoint:[N],color:[Xa],container:[N],"drop-shadow":[N],ease:["in","out","in-out"],font:[Mo],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[N],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[N],shadow:[N],spacing:["px",x],text:[N],"text-shadow":[N],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",j,i,c,I]}],container:["container"],"container-type":[{"@container":["","normal","size",c,i]}],"container-named":[Fo],columns:[{columns:[x,i,c,s]}],"break-after":[{"break-after":w()}],"break-before":[{"break-before":w()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:U()}],overflow:[{overflow:H()}],"overflow-x":[{"overflow-x":H()}],"overflow-y":[{"overflow-y":H()}],overscroll:[{overscroll:q()}],"overscroll-x":[{"overscroll-x":q()}],"overscroll-y":[{"overscroll-y":q()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:F()}],"inset-x":[{"inset-x":F()}],"inset-y":[{"inset-y":F()}],start:[{"inset-s":F(),start:F()}],end:[{"inset-e":F(),end:F()}],"inset-bs":[{"inset-bs":F()}],"inset-be":[{"inset-be":F()}],top:[{top:F()}],right:[{right:F()}],bottom:[{bottom:F()}],left:[{left:F()}],visibility:["visible","invisible","collapse"],z:[{z:[z,"auto",c,i]}],basis:[{basis:[j,"full","auto",s,...f()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[x,j,"auto","initial","none",i]}],grow:[{grow:["",x,c,i]}],shrink:[{shrink:["",x,c,i]}],order:[{order:[z,"first","last","none",c,i]}],"grid-cols":[{"grid-cols":de()}],"col-start-end":[{col:te()}],"col-start":[{"col-start":oe()}],"col-end":[{"col-end":oe()}],"grid-rows":[{"grid-rows":de()}],"row-start-end":[{row:te()}],"row-start":[{"row-start":oe()}],"row-end":[{"row-end":oe()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":Ie()}],"auto-rows":[{"auto-rows":Ie()}],gap:[{gap:f()}],"gap-x":[{"gap-x":f()}],"gap-y":[{"gap-y":f()}],"justify-content":[{justify:[...xe(),"normal"]}],"justify-items":[{"justify-items":[...X(),"normal"]}],"justify-self":[{"justify-self":["auto",...X()]}],"align-content":[{content:["normal",...xe()]}],"align-items":[{items:[...X(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...X(),{baseline:["","last"]}]}],"place-content":[{"place-content":xe()}],"place-items":[{"place-items":[...X(),"baseline"]}],"place-self":[{"place-self":["auto",...X()]}],p:[{p:f()}],px:[{px:f()}],py:[{py:f()}],ps:[{ps:f()}],pe:[{pe:f()}],pbs:[{pbs:f()}],pbe:[{pbe:f()}],pt:[{pt:f()}],pr:[{pr:f()}],pb:[{pb:f()}],pl:[{pl:f()}],m:[{m:R()}],mx:[{mx:R()}],my:[{my:R()}],ms:[{ms:R()}],me:[{me:R()}],mbs:[{mbs:R()}],mbe:[{mbe:R()}],mt:[{mt:R()}],mr:[{mr:R()}],mb:[{mb:R()}],ml:[{ml:R()}],"space-x":[{"space-x":f()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":f()}],"space-y-reverse":["space-y-reverse"],size:[{size:J()}],"inline-size":[{inline:["auto",...He()]}],"min-inline-size":[{"min-inline":["auto",...He()]}],"max-inline-size":[{"max-inline":["none",...He()]}],"block-size":[{block:["auto",...Ge()]}],"min-block-size":[{"min-block":["auto",...Ge()]}],"max-block-size":[{"max-block":["none",...Ge()]}],w:[{w:[s,"screen",...J()]}],"min-w":[{"min-w":[s,"screen","none",...J()]}],"max-w":[{"max-w":[s,"screen","none","prose",{screen:[u]},...J()]}],h:[{h:["screen","lh",...J()]}],"min-h":[{"min-h":["screen","lh","none",...J()]}],"max-h":[{"max-h":["screen","lh",...J()]}],"font-size":[{text:["base",a,Le,ee]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[o,Go,Do]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",Ze,i]}],"font-family":[{font:[Oo,To,t]}],"font-features":[{"font-features":[i]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[r,c,i]}],"line-clamp":[{"line-clamp":[x,"none",c,Oa]}],leading:[{leading:[l,...f()]}],"list-image":[{"list-image":["none",c,i]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",c,i]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:L()}],"text-color":[{text:L()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...ge(),"wavy"]}],"text-decoration-thickness":[{decoration:[x,"from-font","auto",c,ee]}],"text-decoration-color":[{decoration:L()}],"underline-offset":[{"underline-offset":[x,"auto",c,i]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:f()}],"tab-size":[{tab:[z,c,i]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",c,i]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",c,i]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:ea()}],"bg-repeat":[{bg:aa()}],"bg-size":[{bg:ta()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},z,c,i],radial:["",c,i],conic:[z,c,i]},Ho,qo]}],"bg-color":[{bg:L()}],"gradient-from-pos":[{from:Ee()}],"gradient-via-pos":[{via:Ee()}],"gradient-to-pos":[{to:Ee()}],"gradient-from":[{from:L()}],"gradient-via":[{via:L()}],"gradient-to":[{to:L()}],rounded:[{rounded:B()}],"rounded-s":[{"rounded-s":B()}],"rounded-e":[{"rounded-e":B()}],"rounded-t":[{"rounded-t":B()}],"rounded-r":[{"rounded-r":B()}],"rounded-b":[{"rounded-b":B()}],"rounded-l":[{"rounded-l":B()}],"rounded-ss":[{"rounded-ss":B()}],"rounded-se":[{"rounded-se":B()}],"rounded-ee":[{"rounded-ee":B()}],"rounded-es":[{"rounded-es":B()}],"rounded-tl":[{"rounded-tl":B()}],"rounded-tr":[{"rounded-tr":B()}],"rounded-br":[{"rounded-br":B()}],"rounded-bl":[{"rounded-bl":B()}],"border-w":[{border:D()}],"border-w-x":[{"border-x":D()}],"border-w-y":[{"border-y":D()}],"border-w-s":[{"border-s":D()}],"border-w-e":[{"border-e":D()}],"border-w-bs":[{"border-bs":D()}],"border-w-be":[{"border-be":D()}],"border-w-t":[{"border-t":D()}],"border-w-r":[{"border-r":D()}],"border-w-b":[{"border-b":D()}],"border-w-l":[{"border-l":D()}],"divide-x":[{"divide-x":D()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":D()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...ge(),"hidden","none"]}],"divide-style":[{divide:[...ge(),"hidden","none"]}],"border-color":[{border:L()}],"border-color-x":[{"border-x":L()}],"border-color-y":[{"border-y":L()}],"border-color-s":[{"border-s":L()}],"border-color-e":[{"border-e":L()}],"border-color-bs":[{"border-bs":L()}],"border-color-be":[{"border-be":L()}],"border-color-t":[{"border-t":L()}],"border-color-r":[{"border-r":L()}],"border-color-b":[{"border-b":L()}],"border-color-l":[{"border-l":L()}],"divide-color":[{divide:L()}],"outline-style":[{outline:[...ge(),"none","hidden"]}],"outline-offset":[{"outline-offset":[x,c,i]}],"outline-w":[{outline:["",x,Le,ee]}],"outline-color":[{outline:L()}],shadow:[{shadow:["","none",p,De,Be]}],"shadow-color":[{shadow:L()}],"inset-shadow":[{"inset-shadow":["none",m,De,Be]}],"inset-shadow-color":[{"inset-shadow":L()}],"ring-w":[{ring:D()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:L()}],"ring-offset-w":[{"ring-offset":[x,ee]}],"ring-offset-color":[{"ring-offset":L()}],"inset-ring-w":[{"inset-ring":D()}],"inset-ring-color":[{"inset-ring":L()}],"text-shadow":[{"text-shadow":["none",g,De,Be]}],"text-shadow-color":[{"text-shadow":L()}],opacity:[{opacity:[x,c,i]}],"mix-blend":[{"mix-blend":[...oa(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":oa()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[x]}],"mask-image-linear-from-pos":[{"mask-linear-from":y()}],"mask-image-linear-to-pos":[{"mask-linear-to":y()}],"mask-image-linear-from-color":[{"mask-linear-from":L()}],"mask-image-linear-to-color":[{"mask-linear-to":L()}],"mask-image-t-from-pos":[{"mask-t-from":y()}],"mask-image-t-to-pos":[{"mask-t-to":y()}],"mask-image-t-from-color":[{"mask-t-from":L()}],"mask-image-t-to-color":[{"mask-t-to":L()}],"mask-image-r-from-pos":[{"mask-r-from":y()}],"mask-image-r-to-pos":[{"mask-r-to":y()}],"mask-image-r-from-color":[{"mask-r-from":L()}],"mask-image-r-to-color":[{"mask-r-to":L()}],"mask-image-b-from-pos":[{"mask-b-from":y()}],"mask-image-b-to-pos":[{"mask-b-to":y()}],"mask-image-b-from-color":[{"mask-b-from":L()}],"mask-image-b-to-color":[{"mask-b-to":L()}],"mask-image-l-from-pos":[{"mask-l-from":y()}],"mask-image-l-to-pos":[{"mask-l-to":y()}],"mask-image-l-from-color":[{"mask-l-from":L()}],"mask-image-l-to-color":[{"mask-l-to":L()}],"mask-image-x-from-pos":[{"mask-x-from":y()}],"mask-image-x-to-pos":[{"mask-x-to":y()}],"mask-image-x-from-color":[{"mask-x-from":L()}],"mask-image-x-to-color":[{"mask-x-to":L()}],"mask-image-y-from-pos":[{"mask-y-from":y()}],"mask-image-y-to-pos":[{"mask-y-to":y()}],"mask-image-y-from-color":[{"mask-y-from":L()}],"mask-image-y-to-color":[{"mask-y-to":L()}],"mask-image-radial":[{"mask-radial":[c,i]}],"mask-image-radial-from-pos":[{"mask-radial-from":y()}],"mask-image-radial-to-pos":[{"mask-radial-to":y()}],"mask-image-radial-from-color":[{"mask-radial-from":L()}],"mask-image-radial-to-color":[{"mask-radial-to":L()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":P()}],"mask-image-conic-pos":[{"mask-conic":[x]}],"mask-image-conic-from-pos":[{"mask-conic-from":y()}],"mask-image-conic-to-pos":[{"mask-conic-to":y()}],"mask-image-conic-from-color":[{"mask-conic-from":L()}],"mask-image-conic-to-color":[{"mask-conic-to":L()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:ea()}],"mask-repeat":[{mask:aa()}],"mask-size":[{mask:ta()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",c,i]}],filter:[{filter:["","none",c,i]}],blur:[{blur:ra()}],brightness:[{brightness:[x,c,i]}],contrast:[{contrast:[x,c,i]}],"drop-shadow":[{"drop-shadow":["","none",h,De,Be]}],"drop-shadow-color":[{"drop-shadow":L()}],grayscale:[{grayscale:["",x,c,i]}],"hue-rotate":[{"hue-rotate":[x,c,i]}],invert:[{invert:["",x,c,i]}],saturate:[{saturate:[x,c,i]}],sepia:[{sepia:["",x,c,i]}],"backdrop-filter":[{"backdrop-filter":["","none",c,i]}],"backdrop-blur":[{"backdrop-blur":ra()}],"backdrop-brightness":[{"backdrop-brightness":[x,c,i]}],"backdrop-contrast":[{"backdrop-contrast":[x,c,i]}],"backdrop-grayscale":[{"backdrop-grayscale":["",x,c,i]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[x,c,i]}],"backdrop-invert":[{"backdrop-invert":["",x,c,i]}],"backdrop-opacity":[{"backdrop-opacity":[x,c,i]}],"backdrop-saturate":[{"backdrop-saturate":[x,c,i]}],"backdrop-sepia":[{"backdrop-sepia":["",x,c,i]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":f()}],"border-spacing-x":[{"border-spacing-x":f()}],"border-spacing-y":[{"border-spacing-y":f()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",c,i]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[x,"initial",c,i]}],ease:[{ease:["linear","initial",b,c,i]}],delay:[{delay:[x,c,i]}],animate:[{animate:["none",S,c,i]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[C,c,i]}],"perspective-origin":[{"perspective-origin":U()}],rotate:[{rotate:Ce()}],"rotate-x":[{"rotate-x":Ce()}],"rotate-y":[{"rotate-y":Ce()}],"rotate-z":[{"rotate-z":Ce()}],scale:[{scale:he()}],"scale-x":[{"scale-x":he()}],"scale-y":[{"scale-y":he()}],"scale-z":[{"scale-z":he()}],"scale-3d":["scale-3d"],skew:[{skew:ze()}],"skew-x":[{"skew-x":ze()}],"skew-y":[{"skew-y":ze()}],transform:[{transform:[c,i,"","none","gpu","cpu"]}],"transform-origin":[{origin:U()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:Se()}],"translate-x":[{"translate-x":Se()}],"translate-y":[{"translate-y":Se()}],"translate-z":[{"translate-z":Se()}],"translate-none":["translate-none"],zoom:[{zoom:[z,c,i]}],accent:[{accent:L()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:L()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",c,i]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scrollbar-thumb-color":[{"scrollbar-thumb":L()}],"scrollbar-track-color":[{"scrollbar-track":L()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":f()}],"scroll-mx":[{"scroll-mx":f()}],"scroll-my":[{"scroll-my":f()}],"scroll-ms":[{"scroll-ms":f()}],"scroll-me":[{"scroll-me":f()}],"scroll-mbs":[{"scroll-mbs":f()}],"scroll-mbe":[{"scroll-mbe":f()}],"scroll-mt":[{"scroll-mt":f()}],"scroll-mr":[{"scroll-mr":f()}],"scroll-mb":[{"scroll-mb":f()}],"scroll-ml":[{"scroll-ml":f()}],"scroll-p":[{"scroll-p":f()}],"scroll-px":[{"scroll-px":f()}],"scroll-py":[{"scroll-py":f()}],"scroll-ps":[{"scroll-ps":f()}],"scroll-pe":[{"scroll-pe":f()}],"scroll-pbs":[{"scroll-pbs":f()}],"scroll-pbe":[{"scroll-pbe":f()}],"scroll-pt":[{"scroll-pt":f()}],"scroll-pr":[{"scroll-pr":f()}],"scroll-pb":[{"scroll-pb":f()}],"scroll-pl":[{"scroll-pl":f()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",c,i]}],fill:[{fill:["none",...L()]}],"stroke-w":[{stroke:[x,Le,ee,Oa]}],stroke:[{stroke:["none",...L()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{"container-named":["container-type"],overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","inset-bs","inset-be","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pbs","pbe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mbs","mbe","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-bs","border-w-be","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-bs","border-color-be","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mbs","scroll-mbe","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pbs","scroll-pbe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},postfixLookupClassGroups:["container-type"],orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}};var Ya=Co(zo);function qe(...e){return Ya(Fe(e))}var et=e=>typeof e=="boolean"?`${e}`:e===0?"0":e,at=Fe,tt=(e,t)=>a=>{var o;if(t?.variants==null)return at(e,a?.class,a?.className);let{variants:r,defaultVariants:l}=t,u=Object.keys(r).map(d=>{let p=a?.[d],m=l?.[d];if(p===null)return null;let g=et(p)||et(m);return r[d][g]}),s=a&&Object.entries(a).reduce((d,p)=>{let[m,g]=p;return g===void 0||(d[m]=g),d},{}),n=t==null||(o=t.compoundVariants)===null||o===void 0?void 0:o.reduce((d,p)=>{let{class:m,className:g,...h}=p;return Object.entries(h).every(k=>{let[C,I]=k;return Array.isArray(I)?I.includes({...l,...s}[C]):{...l,...s}[C]===I})?[...d,m,g]:d},[]);return at(e,u,n,a?.class,a?.className)};import{jsx as xl}from"react/jsx-runtime";var ot=tt("inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",{variants:{variant:{default:"bg-transparent",outline:"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"},size:{default:"h-9 min-w-9 px-2",sm:"h-8 min-w-8 px-1.5",lg:"h-10 min-w-10 px-2.5"}},defaultVariants:{variant:"default",size:"default"}});import{jsx as Ye}from"react/jsx-runtime";var rt=Oe.createContext({size:"default",variant:"default",spacing:0});function lt({className:e,variant:t,size:a,spacing:o=0,children:r,...l}){return Ye(me.Root,{"data-slot":"toggle-group","data-variant":t,"data-size":a,"data-spacing":o,style:{"--gap":o},className:qe("group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs",e),...l,children:Ye(rt.Provider,{value:{variant:t,size:a,spacing:o},children:r})})}function Ue({className:e,children:t,variant:a,size:o,...r}){let l=Oe.useContext(rt);return Ye(me.Item,{"data-slot":"toggle-group-item","data-variant":l.variant||a,"data-size":l.size||o,"data-spacing":l.spacing,className:qe(ot({variant:l.variant||a,size:l.size||o}),"w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10","data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",e),...r,children:t})}import{jsx as se,jsxs as Wo}from"react/jsx-runtime";function Vo(){return Wo(lt,{type:"single",size:"sm",children:[se(Ue,{value:"bold","aria-label":"Toggle bold",children:se(fe,{className:"h-4 w-4"})}),se(Ue,{value:"italic","aria-label":"Toggle italic",children:se(ie,{className:"h-4 w-4"})}),se(Ue,{value:"strikethrough","aria-label":"Toggle strikethrough",children:se(ne,{className:"h-4 w-4"})})]})}export{Vo as default};
|
| 2 |
+
/*! Bundled license information:
|
| 3 |
+
|
| 4 |
+
lucide-react/dist/esm/shared/src/utils.js:
|
| 5 |
+
(**
|
| 6 |
+
* @license lucide-react v0.456.0 - ISC
|
| 7 |
+
*
|
| 8 |
+
* This source code is licensed under the ISC license.
|
| 9 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 10 |
+
*)
|
| 11 |
+
|
| 12 |
+
lucide-react/dist/esm/defaultAttributes.js:
|
| 13 |
+
(**
|
| 14 |
+
* @license lucide-react v0.456.0 - ISC
|
| 15 |
+
*
|
| 16 |
+
* This source code is licensed under the ISC license.
|
| 17 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 18 |
+
*)
|
| 19 |
+
|
| 20 |
+
lucide-react/dist/esm/Icon.js:
|
| 21 |
+
(**
|
| 22 |
+
* @license lucide-react v0.456.0 - ISC
|
| 23 |
+
*
|
| 24 |
+
* This source code is licensed under the ISC license.
|
| 25 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 26 |
+
*)
|
| 27 |
+
|
| 28 |
+
lucide-react/dist/esm/createLucideIcon.js:
|
| 29 |
+
(**
|
| 30 |
+
* @license lucide-react v0.456.0 - ISC
|
| 31 |
+
*
|
| 32 |
+
* This source code is licensed under the ISC license.
|
| 33 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 34 |
+
*)
|
| 35 |
+
|
| 36 |
+
lucide-react/dist/esm/icons/bold.js:
|
| 37 |
+
(**
|
| 38 |
+
* @license lucide-react v0.456.0 - ISC
|
| 39 |
+
*
|
| 40 |
+
* This source code is licensed under the ISC license.
|
| 41 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 42 |
+
*)
|
| 43 |
+
|
| 44 |
+
lucide-react/dist/esm/icons/italic.js:
|
| 45 |
+
(**
|
| 46 |
+
* @license lucide-react v0.456.0 - ISC
|
| 47 |
+
*
|
| 48 |
+
* This source code is licensed under the ISC license.
|
| 49 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 50 |
+
*)
|
| 51 |
+
|
| 52 |
+
lucide-react/dist/esm/icons/underline.js:
|
| 53 |
+
(**
|
| 54 |
+
* @license lucide-react v0.456.0 - ISC
|
| 55 |
+
*
|
| 56 |
+
* This source code is licensed under the ISC license.
|
| 57 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 58 |
+
*)
|
| 59 |
+
|
| 60 |
+
lucide-react/dist/esm/lucide-react.js:
|
| 61 |
+
(**
|
| 62 |
+
* @license lucide-react v0.456.0 - ISC
|
| 63 |
+
*
|
| 64 |
+
* This source code is licensed under the ISC license.
|
| 65 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 66 |
+
*)
|
| 67 |
+
*/
|
b/7de0257cdb542f26c13df7d2618952a0eceee269bb39112913cd9e119e81e9aa
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import {
|
| 2 |
+
NativeSelect,
|
| 3 |
+
NativeSelectOptGroup,
|
| 4 |
+
NativeSelectOption,
|
| 5 |
+
} from "@/registry/new-york-v4/ui/native-select"
|
| 6 |
+
|
| 7 |
+
export default function NativeSelectGroups() {
|
| 8 |
+
return (
|
| 9 |
+
<NativeSelect>
|
| 10 |
+
<NativeSelectOption value="">Select department</NativeSelectOption>
|
| 11 |
+
<NativeSelectOptGroup label="Engineering">
|
| 12 |
+
<NativeSelectOption value="frontend">Frontend</NativeSelectOption>
|
| 13 |
+
<NativeSelectOption value="backend">Backend</NativeSelectOption>
|
| 14 |
+
<NativeSelectOption value="devops">DevOps</NativeSelectOption>
|
| 15 |
+
</NativeSelectOptGroup>
|
| 16 |
+
<NativeSelectOptGroup label="Sales">
|
| 17 |
+
<NativeSelectOption value="sales-rep">Sales Rep</NativeSelectOption>
|
| 18 |
+
<NativeSelectOption value="account-manager">
|
| 19 |
+
Account Manager
|
| 20 |
+
</NativeSelectOption>
|
| 21 |
+
<NativeSelectOption value="sales-director">
|
| 22 |
+
Sales Director
|
| 23 |
+
</NativeSelectOption>
|
| 24 |
+
</NativeSelectOptGroup>
|
| 25 |
+
<NativeSelectOptGroup label="Operations">
|
| 26 |
+
<NativeSelectOption value="support">
|
| 27 |
+
Customer Support
|
| 28 |
+
</NativeSelectOption>
|
| 29 |
+
<NativeSelectOption value="product-manager">
|
| 30 |
+
Product Manager
|
| 31 |
+
</NativeSelectOption>
|
| 32 |
+
<NativeSelectOption value="ops-manager">
|
| 33 |
+
Operations Manager
|
| 34 |
+
</NativeSelectOption>
|
| 35 |
+
</NativeSelectOptGroup>
|
| 36 |
+
</NativeSelect>
|
| 37 |
+
)
|
| 38 |
+
}
|
b/7dec6f767bc56b6ca4d8a9b1466668b610487ddadbffd8af1ad3e207ec69de75
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Warm residency + multi-source witness (S4 of sparse expert streaming).
|
| 2 |
+
// Using the per-expert κ directory + a resident multi-source store, prove the three
|
| 3 |
+
// honest regimes: COLD (first forward fetches routed experts from a source, verified),
|
| 4 |
+
// WARM (a second forward of the same prompt fetches ZERO blocks — served from L3
|
| 5 |
+
// residency), and HOT-SET (an overlapping prompt fetches ONLY the newly-routed experts,
|
| 6 |
+
// strictly fewer than a cold load). Plus multi-source: a corrupt source is refused by
|
| 7 |
+
// re-derivation and the next source serves the block; if every source is corrupt the
|
| 8 |
+
// load fails closed. Logits are identical across every regime (residency is memoization).
|
| 9 |
+
|
| 10 |
+
import assert from "node:assert";
|
| 11 |
+
import { forgeGguf, mapStore, loadByKappa } from "./gguf-forge.mjs";
|
| 12 |
+
import { synthesizeGraph } from "./gguf-forge-graph.mjs";
|
| 13 |
+
import { forward } from "./gguf-forge-exec.mjs";
|
| 14 |
+
import { GGML } from "./gguf-forge-dequant.mjs";
|
| 15 |
+
import { buildExpertDirectory, expertKappa } from "./gguf-forge-expert-dir.mjs";
|
| 16 |
+
import { makeResidentStore, asSource } from "./gguf-forge-kstore.mjs";
|
| 17 |
+
import { sha256hex } from "../../../../holo-os/system/os/usr/lib/holo/holo-uor.mjs";
|
| 18 |
+
|
| 19 |
+
let pass = 0, fail = 0;
|
| 20 |
+
const t = (name, fn) => { try { fn(); pass++; console.log(" ok " + name); } catch (e) { fail++; console.log("FAIL " + name + "\n " + e.message); } };
|
| 21 |
+
|
| 22 |
+
const D = 8, NH = 2, NHKV = 1, HD = 4, FF = 6, VOCAB = 5, E = 4, USED = 2, EPS = 1e-6, FREQ = 10000;
|
| 23 |
+
const QD = NH * HD, KV = NHKV * HD;
|
| 24 |
+
const hexOf = (k) => String(k).split(":").pop();
|
| 25 |
+
function prng(seed) { let s = seed >>> 0; return () => { s = (s * 1664525 + 1013904223) >>> 0; return (s / 4294967296) * 2 - 1; }; }
|
| 26 |
+
const randF = (r, n, scale = 0.3) => { const a = new Float32Array(n); for (let i = 0; i < n; i++) a[i] = r() * scale; return a; };
|
| 27 |
+
const f32bytes = (arr) => new Uint8Array(arr.buffer.slice(arr.byteOffset, arr.byteOffset + arr.byteLength));
|
| 28 |
+
|
| 29 |
+
function buildGguf(meta, tensors) {
|
| 30 |
+
const ALIGN = 32; let off = 0;
|
| 31 |
+
const infos = tensors.map((tn) => { const o = off; off = Math.ceil((o + tn.bytes.length) / ALIGN) * ALIGN; return { ...tn, offset: o }; });
|
| 32 |
+
let parts = [], len = 0; const push = (b) => { parts.push(b); len += b.length; };
|
| 33 |
+
const u32 = (v) => { const b = new Uint8Array(4); new DataView(b.buffer).setUint32(0, v >>> 0, true); push(b); };
|
| 34 |
+
const f32 = (v) => { const b = new Uint8Array(4); new DataView(b.buffer).setFloat32(0, v, true); push(b); };
|
| 35 |
+
const u64 = (v) => { const b = new Uint8Array(8); const dv = new DataView(b.buffer); dv.setUint32(0, v >>> 0, true); dv.setUint32(4, Math.floor(v / 4294967296), true); push(b); };
|
| 36 |
+
const str = (s) => { const e = new TextEncoder().encode(s); u64(e.length); push(e); };
|
| 37 |
+
push(new TextEncoder().encode("GGUF")); u32(3); u64(tensors.length); u64(Object.keys(meta).length);
|
| 38 |
+
for (const [k, val] of Object.entries(meta)) { str(k); if (typeof val === "string") { u32(8); str(val); } else if (Number.isInteger(val) && val >= 0 && val < 4294967296) { u32(4); u32(val); } else { u32(6); f32(val); } }
|
| 39 |
+
for (const ti of infos) { str(ti.name); u32(ti.dims.length); for (const d of ti.dims) u64(d); u32(ti.type); u64(ti.offset); }
|
| 40 |
+
if (len % ALIGN) push(new Uint8Array(ALIGN - (len % ALIGN)));
|
| 41 |
+
const dataStart = len;
|
| 42 |
+
for (const ti of infos) { while (len < dataStart + ti.offset) push(new Uint8Array(1)); push(ti.bytes); }
|
| 43 |
+
const out = new Uint8Array(len); let o = 0; for (const p of parts) { out.set(p, o); o += p.length; } return out;
|
| 44 |
+
}
|
| 45 |
+
function forgeMoe() {
|
| 46 |
+
const r = prng(7);
|
| 47 |
+
const w = {
|
| 48 |
+
tok_embd: randF(r, VOCAB * D), output_norm: randF(r, D).map((x) => Math.abs(x) + 0.5), output: randF(r, VOCAB * D),
|
| 49 |
+
attn_norm: randF(r, D).map((x) => Math.abs(x) + 0.5), ffn_norm: randF(r, D).map((x) => Math.abs(x) + 0.5),
|
| 50 |
+
wq: randF(r, QD * D), wk: randF(r, KV * D), wv: randF(r, KV * D), wo: randF(r, D * QD),
|
| 51 |
+
gate_inp: randF(r, E * D), gate_exps: randF(r, E * FF * D), up_exps: randF(r, E * FF * D), down_exps: randF(r, E * D * FF),
|
| 52 |
+
};
|
| 53 |
+
const meta = {
|
| 54 |
+
"general.architecture": "llama", "llama.block_count": 1, "llama.embedding_length": D,
|
| 55 |
+
"llama.attention.head_count": NH, "llama.attention.head_count_kv": NHKV, "llama.attention.key_length": HD,
|
| 56 |
+
"llama.feed_forward_length": FF, "llama.expert_count": E, "llama.expert_used_count": USED,
|
| 57 |
+
"llama.expert_feed_forward_length": FF, "llama.rope.freq_base": FREQ, "llama.attention.layer_norm_rms_epsilon": EPS,
|
| 58 |
+
};
|
| 59 |
+
const T = [
|
| 60 |
+
["token_embd.weight", [D, VOCAB], w.tok_embd], ["output_norm.weight", [D], w.output_norm], ["output.weight", [D, VOCAB], w.output],
|
| 61 |
+
["blk.0.attn_norm.weight", [D], w.attn_norm], ["blk.0.attn_q.weight", [D, QD], w.wq], ["blk.0.attn_k.weight", [D, KV], w.wk],
|
| 62 |
+
["blk.0.attn_v.weight", [D, KV], w.wv], ["blk.0.attn_output.weight", [QD, D], w.wo], ["blk.0.ffn_norm.weight", [D], w.ffn_norm],
|
| 63 |
+
["blk.0.ffn_gate_inp.weight", [D, E], w.gate_inp],
|
| 64 |
+
["blk.0.ffn_gate_exps.weight", [D, FF, E], w.gate_exps], ["blk.0.ffn_up_exps.weight", [D, FF, E], w.up_exps], ["blk.0.ffn_down_exps.weight", [FF, D, E], w.down_exps],
|
| 65 |
+
];
|
| 66 |
+
return forgeGguf(buildGguf(meta, T.map(([name, dims, arr]) => ({ name, type: GGML.F32, dims, bytes: f32bytes(arr) }))));
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
// shared fixture: forge + graph + dir + a "peer" source holding every block.
|
| 70 |
+
function fixture() {
|
| 71 |
+
const forge = forgeMoe();
|
| 72 |
+
const graph = synthesizeGraph(forge.plan);
|
| 73 |
+
const { dir, expertBlocks } = buildExpertDirectory(forge);
|
| 74 |
+
const peer = new Map([...forge.blocks, ...expertBlocks]); // a remote source with all blocks
|
| 75 |
+
const ref = forward(forge.plan, graph, mapStore(peer), [1]); // whole-stack reference logits for [1]
|
| 76 |
+
return { forge, graph, dir, peer, ref };
|
| 77 |
+
}
|
| 78 |
+
const run = (f, store, tokens) => forward(f.forge.plan, f.graph, store, tokens, { expertDir: f.dir });
|
| 79 |
+
const sameLogits = (a, b) => { assert.strictEqual(a.length, b.length); for (let i = 0; i < a.length; i++) assert.strictEqual(a[i], b[i], `logit ${i}`); };
|
| 80 |
+
|
| 81 |
+
t("COLD then WARM: a second forward of the same prompt fetches ZERO blocks (L3)", () => {
|
| 82 |
+
const f = fixture();
|
| 83 |
+
const resident = new Map();
|
| 84 |
+
const cold = makeResidentStore({ sources: [asSource(f.peer)], resident });
|
| 85 |
+
const lc = run(f, cold, [1]);
|
| 86 |
+
assert.ok(cold.stats.fetched > 0 && cold.stats.refused === 0, "cold fetched + verified from peer");
|
| 87 |
+
assert.strictEqual(cold.stats.verified, cold.stats.fetched, "every fetched block re-derived");
|
| 88 |
+
|
| 89 |
+
const warm = makeResidentStore({ sources: [asSource(f.peer)], resident }); // SAME resident Map
|
| 90 |
+
const lw = run(f, warm, [1]);
|
| 91 |
+
assert.strictEqual(warm.stats.fetched, 0, "warm: zero source fetches");
|
| 92 |
+
assert.ok(warm.stats.hits > 0, "served entirely from residency");
|
| 93 |
+
sameLogits(lc, lw); sameLogits(lc, f.ref);
|
| 94 |
+
console.log(` regimes: cold fetched ${cold.stats.fetched} blocks · warm fetched 0`);
|
| 95 |
+
});
|
| 96 |
+
|
| 97 |
+
t("HOT-SET: an overlapping prompt fetches ONLY the newly-routed experts (< cold)", () => {
|
| 98 |
+
const f = fixture();
|
| 99 |
+
// cold load of prompt [2] from scratch — the baseline to beat
|
| 100 |
+
const coldP2 = makeResidentStore({ sources: [asSource(f.peer)], resident: new Map() });
|
| 101 |
+
run(f, coldP2, [2]);
|
| 102 |
+
|
| 103 |
+
// warm on [1], then run overlapping [2] against the warmed residency
|
| 104 |
+
const resident = new Map();
|
| 105 |
+
run(f, makeResidentStore({ sources: [asSource(f.peer)], resident }), [1]);
|
| 106 |
+
const before = resident.size;
|
| 107 |
+
const hot = makeResidentStore({ sources: [asSource(f.peer)], resident });
|
| 108 |
+
run(f, hot, [2]);
|
| 109 |
+
const growth = resident.size - before;
|
| 110 |
+
assert.strictEqual(hot.stats.fetched, growth, "fetched exactly the blocks newly added to residency");
|
| 111 |
+
assert.ok(hot.stats.fetched < coldP2.stats.fetched, `hot ${hot.stats.fetched} < cold ${coldP2.stats.fetched} (shared trunk + experts)`);
|
| 112 |
+
console.log(` regimes: cold[2] ${coldP2.stats.fetched} · hot[2 after 1] ${hot.stats.fetched}`);
|
| 113 |
+
});
|
| 114 |
+
|
| 115 |
+
t("MULTI-SOURCE: a corrupt source is refused by re-derivation; the next source serves it", () => {
|
| 116 |
+
const f = fixture();
|
| 117 |
+
// learn which expert [1] routes, then corrupt that expert's gate slice on source 0
|
| 118 |
+
let sel = null;
|
| 119 |
+
forward(f.forge.plan, f.graph, mapStore(f.peer), [1], { expertDir: f.dir, onExpertSelect: (_k, s) => { sel = s.slice(); } });
|
| 120 |
+
const targetHex = hexOf(expertKappa(f.dir, "blk.0.ffn_gate_exps.weight", sel[0]));
|
| 121 |
+
const corrupt = (src, hex) => { const m = new Map(src); const bad = m.get(hex).slice(); bad[0] ^= 0xff; m.set(hex, bad); return m; };
|
| 122 |
+
|
| 123 |
+
const src0 = corrupt(f.peer, targetHex); // everything right except the target block
|
| 124 |
+
const src1 = f.peer; // correct fallback
|
| 125 |
+
const store = makeResidentStore({ sources: [asSource(src0), asSource(src1)], resident: new Map() });
|
| 126 |
+
const l = run(f, store, [1]);
|
| 127 |
+
sameLogits(l, f.ref); // correct result despite a bad source
|
| 128 |
+
assert.ok(store.stats.refused >= 1, "the corrupt block was refused");
|
| 129 |
+
assert.ok(store.stats.perSource[1] >= 1, "the target was served from the fallback source");
|
| 130 |
+
|
| 131 |
+
// if EVERY source is corrupt for a needed block, the load fails closed
|
| 132 |
+
const allBad0 = corrupt(f.peer, targetHex), allBad1 = corrupt(f.peer, targetHex);
|
| 133 |
+
const store2 = makeResidentStore({ sources: [asSource(allBad0), asSource(allBad1)], resident: new Map() });
|
| 134 |
+
assert.throws(() => run(f, store2, [1]), /not found/, "no good source → fail closed");
|
| 135 |
+
});
|
| 136 |
+
|
| 137 |
+
console.log(`\n${pass} passed, ${fail} failed`);
|
| 138 |
+
process.exit(fail ? 1 : 0);
|
b/7df3f984b8b390d4f7bd37919880eb578b768135c6e28febc7cf0c7e12db34c0
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
import{jsx as a}from"react/jsx-runtime";function l(){return a("small",{className:"text-sm leading-none font-medium",children:"Email address"})}export{l as default};
|
b/7df7b2aed777965801d0c53ccc30aebe168222d4dc7f9655cfab4c0f42304cd7
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import collapse from './object.js';
|
| 2 |
+
import { addPrefix } from '../../functions/addPrefix.js';
|
| 3 |
+
|
| 4 |
+
export default ({ addComponents, prefix = '' }) => {
|
| 5 |
+
const prefixedcollapse = addPrefix(collapse, prefix);
|
| 6 |
+
addComponents({ ...prefixedcollapse });
|
| 7 |
+
};
|
b/7e15964d1bb887e39bb9edebbdcdee192d9b938a8782a8183d07c373034b150b
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.daisyui.radio",
|
| 3 |
+
"name": "daisyui-radio",
|
| 4 |
+
"tier": "component",
|
| 5 |
+
"library": "daisyui",
|
| 6 |
+
"category": "Forms & Inputs",
|
| 7 |
+
"upstream": "https://cdn.jsdelivr.net/npm/daisyui@5.5.23/components/radio.css",
|
| 8 |
+
"docs": "https://daisyui.com/components/radio/",
|
| 9 |
+
"did": "did:holo:sha256:54ef8eb5f6cacfa5c4b0cf7660d9f1f21394dbbbbc6dfe9f4c45721328bbcea4",
|
| 10 |
+
"import": "holo://sha256:54ef8eb5f6cacfa5c4b0cf7660d9f1f21394dbbbbc6dfe9f4c45721328bbcea4",
|
| 11 |
+
"integrity": "sha256-VO+OtfbKz6XEsM92YNnx8hOU27u8bf6fTEVyEyi7zqQ=",
|
| 12 |
+
"kappa": "sha256:54ef8eb5f6cacfa5c4b0cf7660d9f1f21394dbbbbc6dfe9f4c45721328bbcea4",
|
| 13 |
+
"moduleKappa": "sha256:54ef8eb5f6cacfa5c4b0cf7660d9f1f21394dbbbbc6dfe9f4c45721328bbcea4",
|
| 14 |
+
"renderExport": null,
|
| 15 |
+
"format": "css",
|
| 16 |
+
"source": "components/radio.css",
|
| 17 |
+
"module": "vendor/daisyui/components/radio.css",
|
| 18 |
+
"exports": [],
|
| 19 |
+
"bytes": 15238,
|
| 20 |
+
"provenance": {
|
| 21 |
+
"package": "daisyui",
|
| 22 |
+
"version": "5.5.23",
|
| 23 |
+
"integrity": "sha512-xuheNUSL4T6ZVtWXoioqcNkjoyGX85QTDz4HTw2aBPfqk4fuMjax5HDo8qCmpV6M1YN8bGvfx5BpYCoDeRlt+A==",
|
| 24 |
+
"file": "components/radio.css"
|
| 25 |
+
},
|
| 26 |
+
"license": "MIT"
|
| 27 |
+
}
|
b/7e162b2333a13ef1e22b36859b603ed1bea97583111d54f8ec369b06d3ca912c
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Input } from "@/registry/new-york-v4/ui/input"
|
| 2 |
+
|
| 3 |
+
export default function InputDisabled() {
|
| 4 |
+
return <Input disabled type="email" placeholder="Email" />
|
| 5 |
+
}
|
b/7e432d6657c8cfc407353bc200cd6e6f83e64941f4ba7d2a35a6ab5c7399cb2e
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client"
|
| 2 |
+
|
| 3 |
+
import { TrendingUp } from "lucide-react"
|
| 4 |
+
import { RadialBar, RadialBarChart } from "recharts"
|
| 5 |
+
|
| 6 |
+
import {
|
| 7 |
+
Card,
|
| 8 |
+
CardContent,
|
| 9 |
+
CardDescription,
|
| 10 |
+
CardFooter,
|
| 11 |
+
CardHeader,
|
| 12 |
+
CardTitle,
|
| 13 |
+
} from "@/registry/new-york-v4/ui/card"
|
| 14 |
+
import {
|
| 15 |
+
ChartContainer,
|
| 16 |
+
ChartTooltip,
|
| 17 |
+
ChartTooltipContent,
|
| 18 |
+
type ChartConfig,
|
| 19 |
+
} from "@/registry/new-york-v4/ui/chart"
|
| 20 |
+
|
| 21 |
+
export const description = "A radial chart"
|
| 22 |
+
|
| 23 |
+
const chartData = [
|
| 24 |
+
{ browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
|
| 25 |
+
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
|
| 26 |
+
{ browser: "firefox", visitors: 187, fill: "var(--color-firefox)" },
|
| 27 |
+
{ browser: "edge", visitors: 173, fill: "var(--color-edge)" },
|
| 28 |
+
{ browser: "other", visitors: 90, fill: "var(--color-other)" },
|
| 29 |
+
]
|
| 30 |
+
|
| 31 |
+
const chartConfig = {
|
| 32 |
+
visitors: {
|
| 33 |
+
label: "Visitors",
|
| 34 |
+
},
|
| 35 |
+
chrome: {
|
| 36 |
+
label: "Chrome",
|
| 37 |
+
color: "var(--chart-1)",
|
| 38 |
+
},
|
| 39 |
+
safari: {
|
| 40 |
+
label: "Safari",
|
| 41 |
+
color: "var(--chart-2)",
|
| 42 |
+
},
|
| 43 |
+
firefox: {
|
| 44 |
+
label: "Firefox",
|
| 45 |
+
color: "var(--chart-3)",
|
| 46 |
+
},
|
| 47 |
+
edge: {
|
| 48 |
+
label: "Edge",
|
| 49 |
+
color: "var(--chart-4)",
|
| 50 |
+
},
|
| 51 |
+
other: {
|
| 52 |
+
label: "Other",
|
| 53 |
+
color: "var(--chart-5)",
|
| 54 |
+
},
|
| 55 |
+
} satisfies ChartConfig
|
| 56 |
+
|
| 57 |
+
export function ChartRadialSimple() {
|
| 58 |
+
return (
|
| 59 |
+
<Card className="flex flex-col">
|
| 60 |
+
<CardHeader className="items-center pb-0">
|
| 61 |
+
<CardTitle>Radial Chart</CardTitle>
|
| 62 |
+
<CardDescription>January - June 2024</CardDescription>
|
| 63 |
+
</CardHeader>
|
| 64 |
+
<CardContent className="flex-1 pb-0">
|
| 65 |
+
<ChartContainer
|
| 66 |
+
config={chartConfig}
|
| 67 |
+
className="mx-auto aspect-square max-h-[250px]"
|
| 68 |
+
>
|
| 69 |
+
<RadialBarChart data={chartData} innerRadius={30} outerRadius={110}>
|
| 70 |
+
<ChartTooltip
|
| 71 |
+
cursor={false}
|
| 72 |
+
content={<ChartTooltipContent hideLabel nameKey="browser" />}
|
| 73 |
+
/>
|
| 74 |
+
<RadialBar dataKey="visitors" background />
|
| 75 |
+
</RadialBarChart>
|
| 76 |
+
</ChartContainer>
|
| 77 |
+
</CardContent>
|
| 78 |
+
<CardFooter className="flex-col gap-2 text-sm">
|
| 79 |
+
<div className="flex items-center gap-2 leading-none font-medium">
|
| 80 |
+
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
| 81 |
+
</div>
|
| 82 |
+
<div className="leading-none text-muted-foreground">
|
| 83 |
+
Showing total visitors for the last 6 months
|
| 84 |
+
</div>
|
| 85 |
+
</CardFooter>
|
| 86 |
+
</Card>
|
| 87 |
+
)
|
| 88 |
+
}
|
b/7e438a060057b1fe1e317554a97135e7733066c0f3f59ab8dad43a2f8c8437fc
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html><meta charset=utf-8><title>TurboQuant KV-plane GPU decode witness</title>
|
| 2 |
+
<body><pre id=log>loading…</pre><script type=module>
|
| 3 |
+
// WGSL TurboQuant KV-plane DECODE (PQ4_0, d=128): per block, dequant (codebook×norm) →
|
| 4 |
+
// inverse Hadamard rotation (Fast Walsh-Hadamard in workgroup shared mem + ×signs/√d) =
|
| 5 |
+
// tq_inverse_inplace. Witnessed vs the CPU oracle tqDecodeKV. The novel GPU piece is the
|
| 6 |
+
// in-shader FHT (one workgroup per block, log2(d) butterfly passes with barriers).
|
| 7 |
+
const log = (m) => document.getElementById("log").textContent = m;
|
| 8 |
+
(async () => {
|
| 9 |
+
const { d, nb, n, total, bytes, signs, expected } = await (await fetch("./_turbokv_data.json")).json();
|
| 10 |
+
const dev = await (await navigator.gpu.requestAdapter()).requestDevice();
|
| 11 |
+
const pad = new Uint8Array(Math.ceil(bytes.length / 4) * 4); pad.set(bytes);
|
| 12 |
+
const bIn = dev.createBuffer({ size: pad.byteLength, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST }); dev.queue.writeBuffer(bIn, 0, new Uint32Array(pad.buffer));
|
| 13 |
+
const sg = new Float32Array(signs); const bSg = dev.createBuffer({ size: sg.byteLength, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST }); dev.queue.writeBuffer(bSg, 0, sg);
|
| 14 |
+
const bOut = dev.createBuffer({ size: n * 4, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC });
|
| 15 |
+
const rd = dev.createBuffer({ size: n * 4, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST });
|
| 16 |
+
|
| 17 |
+
const WGSL = `
|
| 18 |
+
const CB = array<f32,16>(
|
| 19 |
+
-0.23762692286887249, -0.18079342531272283, -0.14176134070424901, -0.11024676790280842,
|
| 20 |
+
-0.08279230816984559, -0.05774433563409530, -0.03413390187425037, -0.01129645493594766,
|
| 21 |
+
0.01129645493594766, 0.03413390187425037, 0.05774433563409530, 0.08279230816984559,
|
| 22 |
+
0.11024676790280842, 0.14176134070424901, 0.18079342531272283, 0.23762692286887249);
|
| 23 |
+
const D : u32 = ${d}u; const STRIDE : u32 = ${total}u; const INV_SQRT_D : f32 = ${1 / Math.sqrt(d)};
|
| 24 |
+
@group(0) @binding(0) var<storage, read> blk : array<u32>;
|
| 25 |
+
@group(0) @binding(1) var<storage, read> signs : array<f32>;
|
| 26 |
+
@group(0) @binding(2) var<storage, read_write> outp : array<f32>;
|
| 27 |
+
var<workgroup> sh : array<f32, ${d}>;
|
| 28 |
+
fn gb(b : u32) -> u32 { let w = blk[b >> 2u]; return (w >> ((b & 3u) * 8u)) & 0xffu; }
|
| 29 |
+
@compute @workgroup_size(${d})
|
| 30 |
+
fn main(@builtin(workgroup_id) wid : vec3<u32>, @builtin(local_invocation_id) lid : vec3<u32>) {
|
| 31 |
+
let blkIdx = wid.x; let o = lid.x; let base = blkIdx * STRIDE;
|
| 32 |
+
// 1) dequant element o: nibble idx → codebook × norm(f16 @ offset D/2)
|
| 33 |
+
let d16 = gb(base + (D >> 1u)) | (gb(base + (D >> 1u) + 1u) << 8u);
|
| 34 |
+
let nrm = unpack2x16float(d16).x;
|
| 35 |
+
let byte = gb(base + (o >> 1u));
|
| 36 |
+
let idx = select(byte >> 4u, byte & 0xfu, (o & 1u) == 0u);
|
| 37 |
+
sh[o] = CB[idx] * nrm;
|
| 38 |
+
workgroupBarrier();
|
| 39 |
+
// 2) Fast Walsh-Hadamard (tq_fht): log2(D) butterfly passes; left thread writes both
|
| 40 |
+
var len : u32 = 1u;
|
| 41 |
+
loop {
|
| 42 |
+
if (len >= D) { break; }
|
| 43 |
+
if ((o & len) == 0u) { let a = sh[o]; let b = sh[o + len]; sh[o] = a + b; sh[o + len] = a - b; }
|
| 44 |
+
workgroupBarrier();
|
| 45 |
+
len = len << 1u;
|
| 46 |
+
}
|
| 47 |
+
// 3) ×signs/√d (tq_inverse_inplace tail)
|
| 48 |
+
outp[base / STRIDE * D + o] = sh[o] * signs[o] * INV_SQRT_D;
|
| 49 |
+
}`;
|
| 50 |
+
const pipe = dev.createComputePipeline({ layout: "auto", compute: { module: dev.createShaderModule({ code: WGSL }), entryPoint: "main" } });
|
| 51 |
+
const bg = dev.createBindGroup({ layout: pipe.getBindGroupLayout(0), entries: [{ binding: 0, resource: { buffer: bIn } }, { binding: 1, resource: { buffer: bSg } }, { binding: 2, resource: { buffer: bOut } }] });
|
| 52 |
+
const enc = dev.createCommandEncoder(); const p = enc.beginComputePass(); p.setPipeline(pipe); p.setBindGroup(0, bg); p.dispatchWorkgroups(nb); p.end();
|
| 53 |
+
enc.copyBufferToBuffer(bOut, 0, rd, 0, n * 4); dev.queue.submit([enc.finish()]);
|
| 54 |
+
await rd.mapAsync(GPUMapMode.READ); const got = new Float32Array(rd.getMappedRange().slice(0));
|
| 55 |
+
let dot = 0, na = 0, nb2 = 0, maxAbs = 0; for (let i = 0; i < n; i++) { const a = got[i], b = expected[i]; dot += a * b; na += a * a; nb2 += b * b; maxAbs = Math.max(maxAbs, Math.abs(a - b)); }
|
| 56 |
+
const cosine = dot / (Math.sqrt(na) * Math.sqrt(nb2) || 1), ok = cosine > 0.999999 && maxAbs < 1e-4;
|
| 57 |
+
window.__turbokv = { ok, cosine: +cosine.toFixed(9), maxAbs: +maxAbs.toExponential(2), n, nb };
|
| 58 |
+
log(`TurboQuant KV decode (PQ4_0): ${ok ? "PASS" : "FAIL"} cosine=${cosine.toFixed(9)} maxAbs=${maxAbs.toExponential(2)} (${n} vals)`);
|
| 59 |
+
})().catch((e) => { window.__turbokv = { ok: false, err: String(e) }; log("ERR " + e); });
|
| 60 |
+
</script>
|
b/7e502c71cf1bc0c41721f5c03dddc4992da176836b898283c983368a161b7068
ADDED
|
@@ -0,0 +1,864 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect, useRef, useState } from "react"
|
| 2 |
+
import type { CSSProperties, HTMLAttributes } from "react"
|
| 3 |
+
|
| 4 |
+
import { cn } from "@/lib/utils"
|
| 5 |
+
|
| 6 |
+
const ANIMATION_DURATION_SECONDS = 15
|
| 7 |
+
const GRID_HEIGHT_RATIO = 3
|
| 8 |
+
const GRID_LINE_ALIGNMENT_OFFSET_PX = 0.5
|
| 9 |
+
const GRID_LINE_ANTIALIAS_MULTIPLIER = 0.9
|
| 10 |
+
const GRID_LINE_WIDTH_PX = 0.92
|
| 11 |
+
const GRID_START_OFFSET_RATIO = -0.5
|
| 12 |
+
const GRID_WIDTH_RATIO = 6
|
| 13 |
+
const GRID_X_OFFSET_RATIO = -2
|
| 14 |
+
const MAX_ANGLE = 89
|
| 15 |
+
const MAX_DEVICE_PIXEL_RATIO = 2
|
| 16 |
+
const MIN_ANGLE = 1
|
| 17 |
+
const PERSPECTIVE_PX = 200
|
| 18 |
+
const FALLBACK_ANIMATION_NAME = "retro-grid-fallback-scroll"
|
| 19 |
+
const FALLBACK_STYLES = `
|
| 20 |
+
@keyframes ${FALLBACK_ANIMATION_NAME} {
|
| 21 |
+
from {
|
| 22 |
+
transform: translateY(-50%);
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
to {
|
| 26 |
+
transform: translateY(0);
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
@media (prefers-reduced-motion: reduce) {
|
| 31 |
+
[data-retro-grid-scroll="true"] {
|
| 32 |
+
animation: none !important;
|
| 33 |
+
transform: translateY(-50%) !important;
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
`
|
| 37 |
+
|
| 38 |
+
const VERTEX_SHADER_SOURCE = `
|
| 39 |
+
attribute vec2 a_position;
|
| 40 |
+
|
| 41 |
+
void main() {
|
| 42 |
+
gl_Position = vec4(a_position, 0.0, 1.0);
|
| 43 |
+
}
|
| 44 |
+
`
|
| 45 |
+
|
| 46 |
+
const FRAGMENT_SHADER_SOURCE = `
|
| 47 |
+
#extension GL_OES_standard_derivatives : enable
|
| 48 |
+
precision highp float;
|
| 49 |
+
|
| 50 |
+
uniform vec2 u_container_size;
|
| 51 |
+
uniform vec2 u_viewport_size;
|
| 52 |
+
uniform vec4 u_line_color;
|
| 53 |
+
uniform float u_angle;
|
| 54 |
+
uniform float u_cell_size;
|
| 55 |
+
uniform float u_device_pixel_ratio;
|
| 56 |
+
uniform float u_time;
|
| 57 |
+
|
| 58 |
+
const float animationDurationSeconds = ${ANIMATION_DURATION_SECONDS.toFixed(1)};
|
| 59 |
+
const float gridHeightRatio = ${GRID_HEIGHT_RATIO.toFixed(1)};
|
| 60 |
+
const float gridStartOffsetRatio = ${GRID_START_OFFSET_RATIO.toFixed(1)};
|
| 61 |
+
const float gridWidthRatio = ${GRID_WIDTH_RATIO.toFixed(1)};
|
| 62 |
+
const float gridXOffsetRatio = ${GRID_X_OFFSET_RATIO.toFixed(1)};
|
| 63 |
+
const float gridLineAlignmentOffsetPx = ${GRID_LINE_ALIGNMENT_OFFSET_PX.toFixed(1)};
|
| 64 |
+
const float gridLineAntialiasMultiplier = ${GRID_LINE_ANTIALIAS_MULTIPLIER.toFixed(1)};
|
| 65 |
+
const float horizontalLodLevelOneEndPx = 5.6;
|
| 66 |
+
const float horizontalLodLevelOneStartPx = 2.8;
|
| 67 |
+
const float horizontalLodLevelTwoEndPx = 3.0;
|
| 68 |
+
const float horizontalLodLevelTwoStartPx = 1.4;
|
| 69 |
+
const float horizontalCompressionEndPx = 2.8;
|
| 70 |
+
const float horizontalCompressionStartPx = 1.2;
|
| 71 |
+
const float lineWidthPx = ${GRID_LINE_WIDTH_PX.toFixed(2)};
|
| 72 |
+
const float perspectivePx = ${PERSPECTIVE_PX.toFixed(1)};
|
| 73 |
+
const float gridTravelRatio = 0.5;
|
| 74 |
+
const float verticalCompressionEndPx = 2.6;
|
| 75 |
+
const float verticalCompressionStartPx = 1.0;
|
| 76 |
+
const float verticalEdgeCompressionEnd = 0.95;
|
| 77 |
+
const float verticalEdgeCompressionStart = 0.45;
|
| 78 |
+
const float verticalLodLevelEnd = 0.64;
|
| 79 |
+
const float verticalLodLevelStart = 0.22;
|
| 80 |
+
const float verticalTopCompressionEndCells = 6.0;
|
| 81 |
+
const float verticalTopCompressionStartCells = 2.0;
|
| 82 |
+
|
| 83 |
+
float renderGridLine(
|
| 84 |
+
float wrappedCoord,
|
| 85 |
+
float antiAliasWidth,
|
| 86 |
+
float softnessBoost
|
| 87 |
+
) {
|
| 88 |
+
return 1.0 - smoothstep(
|
| 89 |
+
lineWidthPx,
|
| 90 |
+
lineWidthPx + (antiAliasWidth * (1.5 + softnessBoost)),
|
| 91 |
+
wrappedCoord
|
| 92 |
+
);
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
void main() {
|
| 96 |
+
float angle = radians(clamp(u_angle, 1.0, 89.0));
|
| 97 |
+
float sinAngle = sin(angle);
|
| 98 |
+
float cosAngle = cos(angle);
|
| 99 |
+
vec2 screen = vec2(
|
| 100 |
+
(gl_FragCoord.x / u_device_pixel_ratio) - (u_container_size.x * 0.5),
|
| 101 |
+
(u_container_size.y * 0.5) - (gl_FragCoord.y / u_device_pixel_ratio)
|
| 102 |
+
);
|
| 103 |
+
|
| 104 |
+
vec3 rayOrigin = vec3(0.0, 0.0, perspectivePx);
|
| 105 |
+
vec3 rayDirection = normalize(vec3(screen, -perspectivePx));
|
| 106 |
+
vec3 planeXAxis = vec3(1.0, 0.0, 0.0);
|
| 107 |
+
vec3 planeYAxis = vec3(0.0, cosAngle, sinAngle);
|
| 108 |
+
vec3 planeNormal = normalize(cross(planeXAxis, planeYAxis));
|
| 109 |
+
float denominator = dot(rayDirection, planeNormal);
|
| 110 |
+
|
| 111 |
+
if (abs(denominator) < 0.0001) {
|
| 112 |
+
discard;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
float distanceToPlane = dot(-rayOrigin, planeNormal) / denominator;
|
| 116 |
+
|
| 117 |
+
if (distanceToPlane <= 0.0) {
|
| 118 |
+
discard;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
vec3 hitPoint = rayOrigin + (rayDirection * distanceToPlane);
|
| 122 |
+
float localX = hitPoint.x;
|
| 123 |
+
float localY = dot(hitPoint, planeYAxis);
|
| 124 |
+
float gridWidth = u_viewport_size.x * gridWidthRatio;
|
| 125 |
+
float gridHeight = u_viewport_size.y * gridHeightRatio;
|
| 126 |
+
float gridScrollSpeed = (gridHeight * gridTravelRatio) / animationDurationSeconds;
|
| 127 |
+
float patternOffsetY = u_time * gridScrollSpeed;
|
| 128 |
+
float gridLeft = (-0.5 * u_container_size.x) + (gridXOffsetRatio * u_container_size.x);
|
| 129 |
+
float gridTop = (-0.5 * u_container_size.y) + (gridStartOffsetRatio * gridHeight);
|
| 130 |
+
vec2 planePosition = vec2(localX - gridLeft, localY - gridTop);
|
| 131 |
+
|
| 132 |
+
if (
|
| 133 |
+
planePosition.x < 0.0 ||
|
| 134 |
+
planePosition.y < 0.0 ||
|
| 135 |
+
planePosition.x > gridWidth ||
|
| 136 |
+
planePosition.y > gridHeight
|
| 137 |
+
) {
|
| 138 |
+
discard;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
vec2 patternPosition = vec2(planePosition.x, planePosition.y - patternOffsetY);
|
| 142 |
+
vec2 wrapped = mod(
|
| 143 |
+
patternPosition + vec2(gridLineAlignmentOffsetPx),
|
| 144 |
+
u_cell_size
|
| 145 |
+
);
|
| 146 |
+
vec2 patternDerivative = max(fwidth(patternPosition), vec2(0.0001));
|
| 147 |
+
vec2 antiAliasWidth = patternDerivative * gridLineAntialiasMultiplier;
|
| 148 |
+
float horizontalCellSpanPx = u_cell_size / patternDerivative.y;
|
| 149 |
+
float horizontalCompression = 1.0 - smoothstep(
|
| 150 |
+
horizontalCompressionStartPx,
|
| 151 |
+
horizontalCompressionEndPx,
|
| 152 |
+
horizontalCellSpanPx
|
| 153 |
+
);
|
| 154 |
+
float verticalCellSpanPx = u_cell_size / patternDerivative.x;
|
| 155 |
+
float sideDistance = abs((planePosition.x / gridWidth) * 2.0 - 1.0);
|
| 156 |
+
float verticalEdgeCompression = smoothstep(
|
| 157 |
+
verticalEdgeCompressionStart,
|
| 158 |
+
verticalEdgeCompressionEnd,
|
| 159 |
+
sideDistance
|
| 160 |
+
);
|
| 161 |
+
float verticalTopCompression = 1.0 - smoothstep(
|
| 162 |
+
u_cell_size * verticalTopCompressionStartCells,
|
| 163 |
+
u_cell_size * verticalTopCompressionEndCells,
|
| 164 |
+
planePosition.y
|
| 165 |
+
);
|
| 166 |
+
float verticalCompression =
|
| 167 |
+
(1.0 - smoothstep(
|
| 168 |
+
verticalCompressionStartPx,
|
| 169 |
+
verticalCompressionEndPx,
|
| 170 |
+
verticalCellSpanPx
|
| 171 |
+
)) * verticalEdgeCompression * verticalTopCompression;
|
| 172 |
+
float horizontalSoftnessBoost = 1.0 + (horizontalCompression * 3.0);
|
| 173 |
+
float verticalSoftnessBoost = 1.0 + (verticalCompression * 3.5);
|
| 174 |
+
float verticalLod = smoothstep(
|
| 175 |
+
verticalLodLevelStart,
|
| 176 |
+
verticalLodLevelEnd,
|
| 177 |
+
verticalCompression
|
| 178 |
+
);
|
| 179 |
+
float verticalLineFine = renderGridLine(
|
| 180 |
+
wrapped.x,
|
| 181 |
+
antiAliasWidth.x,
|
| 182 |
+
verticalSoftnessBoost
|
| 183 |
+
);
|
| 184 |
+
float verticalWrappedLod = mod(
|
| 185 |
+
patternPosition.x + gridLineAlignmentOffsetPx,
|
| 186 |
+
u_cell_size * 2.0
|
| 187 |
+
);
|
| 188 |
+
float verticalLineCoarse = renderGridLine(
|
| 189 |
+
verticalWrappedLod,
|
| 190 |
+
antiAliasWidth.x,
|
| 191 |
+
verticalSoftnessBoost + verticalLod
|
| 192 |
+
);
|
| 193 |
+
float verticalLine = max(
|
| 194 |
+
verticalLineFine * (1.0 - verticalLod),
|
| 195 |
+
verticalLineCoarse * verticalLod
|
| 196 |
+
);
|
| 197 |
+
float horizontalLodLevelOne = 1.0 - smoothstep(
|
| 198 |
+
horizontalLodLevelOneStartPx,
|
| 199 |
+
horizontalLodLevelOneEndPx,
|
| 200 |
+
horizontalCellSpanPx
|
| 201 |
+
);
|
| 202 |
+
float horizontalLodLevelTwo = 1.0 - smoothstep(
|
| 203 |
+
horizontalLodLevelTwoStartPx,
|
| 204 |
+
horizontalLodLevelTwoEndPx,
|
| 205 |
+
horizontalCellSpanPx
|
| 206 |
+
);
|
| 207 |
+
float horizontalLineFine = renderGridLine(
|
| 208 |
+
wrapped.y,
|
| 209 |
+
antiAliasWidth.y,
|
| 210 |
+
horizontalSoftnessBoost
|
| 211 |
+
);
|
| 212 |
+
float horizontalWrappedLodOne = mod(
|
| 213 |
+
patternPosition.y + gridLineAlignmentOffsetPx,
|
| 214 |
+
u_cell_size * 2.0
|
| 215 |
+
);
|
| 216 |
+
float horizontalWrappedLodTwo = mod(
|
| 217 |
+
patternPosition.y + gridLineAlignmentOffsetPx,
|
| 218 |
+
u_cell_size * 4.0
|
| 219 |
+
);
|
| 220 |
+
float horizontalLineCoarse = renderGridLine(
|
| 221 |
+
horizontalWrappedLodOne,
|
| 222 |
+
antiAliasWidth.y,
|
| 223 |
+
horizontalSoftnessBoost + horizontalLodLevelOne
|
| 224 |
+
);
|
| 225 |
+
float horizontalLineExtraCoarse = renderGridLine(
|
| 226 |
+
horizontalWrappedLodTwo,
|
| 227 |
+
antiAliasWidth.y,
|
| 228 |
+
horizontalSoftnessBoost + horizontalLodLevelOne + horizontalLodLevelTwo
|
| 229 |
+
);
|
| 230 |
+
float horizontalLineReduced = max(
|
| 231 |
+
horizontalLineFine * (1.0 - horizontalLodLevelOne),
|
| 232 |
+
horizontalLineCoarse * horizontalLodLevelOne
|
| 233 |
+
);
|
| 234 |
+
float horizontalLine = max(
|
| 235 |
+
horizontalLineReduced * (1.0 - horizontalLodLevelTwo),
|
| 236 |
+
horizontalLineExtraCoarse * horizontalLodLevelTwo
|
| 237 |
+
);
|
| 238 |
+
float line = max(verticalLine, horizontalLine);
|
| 239 |
+
|
| 240 |
+
if (line <= 0.001) {
|
| 241 |
+
discard;
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
float alpha = u_line_color.a * line;
|
| 245 |
+
gl_FragColor = vec4(u_line_color.rgb * alpha, alpha);
|
| 246 |
+
}
|
| 247 |
+
`
|
| 248 |
+
|
| 249 |
+
interface RetroGridProps extends HTMLAttributes<HTMLDivElement> {
|
| 250 |
+
/**
|
| 251 |
+
* Additional CSS classes to apply to the grid container
|
| 252 |
+
*/
|
| 253 |
+
className?: string
|
| 254 |
+
/**
|
| 255 |
+
* Rotation angle of the grid in degrees
|
| 256 |
+
* @default 65
|
| 257 |
+
*/
|
| 258 |
+
angle?: number
|
| 259 |
+
/**
|
| 260 |
+
* Grid cell size in pixels
|
| 261 |
+
* @default 60
|
| 262 |
+
*/
|
| 263 |
+
cellSize?: number
|
| 264 |
+
/**
|
| 265 |
+
* Grid opacity value between 0 and 1
|
| 266 |
+
* @default 0.5
|
| 267 |
+
*/
|
| 268 |
+
opacity?: number
|
| 269 |
+
/**
|
| 270 |
+
* Grid line color in light mode
|
| 271 |
+
* @default "gray"
|
| 272 |
+
*/
|
| 273 |
+
lightLineColor?: string
|
| 274 |
+
/**
|
| 275 |
+
* Grid line color in dark mode
|
| 276 |
+
* @default "gray"
|
| 277 |
+
*/
|
| 278 |
+
darkLineColor?: string
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
interface ProgramInfo {
|
| 282 |
+
attributeLocation: number
|
| 283 |
+
program: WebGLProgram
|
| 284 |
+
uniforms: {
|
| 285 |
+
angle: WebGLUniformLocation
|
| 286 |
+
cellSize: WebGLUniformLocation
|
| 287 |
+
containerSize: WebGLUniformLocation
|
| 288 |
+
devicePixelRatio: WebGLUniformLocation
|
| 289 |
+
lineColor: WebGLUniformLocation
|
| 290 |
+
time: WebGLUniformLocation
|
| 291 |
+
viewportSize: WebGLUniformLocation
|
| 292 |
+
}
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
let colorResolveContext: CanvasRenderingContext2D | null | undefined
|
| 296 |
+
|
| 297 |
+
function clamp(value: number, min: number, max: number) {
|
| 298 |
+
return Math.min(Math.max(value, min), max)
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
function createShader(gl: WebGLRenderingContext, type: number, source: string) {
|
| 302 |
+
const shader = gl.createShader(type)
|
| 303 |
+
|
| 304 |
+
if (!shader) {
|
| 305 |
+
return null
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
+
gl.shaderSource(shader, source)
|
| 309 |
+
gl.compileShader(shader)
|
| 310 |
+
|
| 311 |
+
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
| 312 |
+
return shader
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
gl.deleteShader(shader)
|
| 316 |
+
return null
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
function createProgram(gl: WebGLRenderingContext) {
|
| 320 |
+
const vertexShader = createShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER_SOURCE)
|
| 321 |
+
const fragmentShader = createShader(
|
| 322 |
+
gl,
|
| 323 |
+
gl.FRAGMENT_SHADER,
|
| 324 |
+
FRAGMENT_SHADER_SOURCE
|
| 325 |
+
)
|
| 326 |
+
|
| 327 |
+
if (!vertexShader || !fragmentShader) {
|
| 328 |
+
return null
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
const program = gl.createProgram()
|
| 332 |
+
|
| 333 |
+
if (!program) {
|
| 334 |
+
gl.deleteShader(vertexShader)
|
| 335 |
+
gl.deleteShader(fragmentShader)
|
| 336 |
+
return null
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
gl.attachShader(program, vertexShader)
|
| 340 |
+
gl.attachShader(program, fragmentShader)
|
| 341 |
+
gl.linkProgram(program)
|
| 342 |
+
gl.deleteShader(vertexShader)
|
| 343 |
+
gl.deleteShader(fragmentShader)
|
| 344 |
+
|
| 345 |
+
if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
| 346 |
+
return program
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
gl.deleteProgram(program)
|
| 350 |
+
return null
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
function getProgramInfo(
|
| 354 |
+
gl: WebGLRenderingContext,
|
| 355 |
+
program: WebGLProgram
|
| 356 |
+
): ProgramInfo | null {
|
| 357 |
+
const attributeLocation = gl.getAttribLocation(program, "a_position")
|
| 358 |
+
const angle = gl.getUniformLocation(program, "u_angle")
|
| 359 |
+
const cellSize = gl.getUniformLocation(program, "u_cell_size")
|
| 360 |
+
const containerSize = gl.getUniformLocation(program, "u_container_size")
|
| 361 |
+
const devicePixelRatio = gl.getUniformLocation(
|
| 362 |
+
program,
|
| 363 |
+
"u_device_pixel_ratio"
|
| 364 |
+
)
|
| 365 |
+
const lineColor = gl.getUniformLocation(program, "u_line_color")
|
| 366 |
+
const time = gl.getUniformLocation(program, "u_time")
|
| 367 |
+
const viewportSize = gl.getUniformLocation(program, "u_viewport_size")
|
| 368 |
+
|
| 369 |
+
if (
|
| 370 |
+
attributeLocation < 0 ||
|
| 371 |
+
!angle ||
|
| 372 |
+
!cellSize ||
|
| 373 |
+
!containerSize ||
|
| 374 |
+
!devicePixelRatio ||
|
| 375 |
+
!lineColor ||
|
| 376 |
+
!time ||
|
| 377 |
+
!viewportSize
|
| 378 |
+
) {
|
| 379 |
+
return null
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
return {
|
| 383 |
+
attributeLocation,
|
| 384 |
+
program,
|
| 385 |
+
uniforms: {
|
| 386 |
+
angle,
|
| 387 |
+
cellSize,
|
| 388 |
+
containerSize,
|
| 389 |
+
devicePixelRatio,
|
| 390 |
+
lineColor,
|
| 391 |
+
time,
|
| 392 |
+
viewportSize,
|
| 393 |
+
},
|
| 394 |
+
}
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
function isDarkMode(colorScheme: MediaQueryList) {
|
| 398 |
+
const root = document.documentElement
|
| 399 |
+
|
| 400 |
+
if (root.classList.contains("dark")) {
|
| 401 |
+
return true
|
| 402 |
+
}
|
| 403 |
+
|
| 404 |
+
if (root.classList.contains("light")) {
|
| 405 |
+
return false
|
| 406 |
+
}
|
| 407 |
+
|
| 408 |
+
return colorScheme.matches
|
| 409 |
+
}
|
| 410 |
+
|
| 411 |
+
function getColorResolveContext() {
|
| 412 |
+
if (colorResolveContext !== undefined) {
|
| 413 |
+
return colorResolveContext
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
const canvas = document.createElement("canvas")
|
| 417 |
+
canvas.width = 1
|
| 418 |
+
canvas.height = 1
|
| 419 |
+
colorResolveContext = canvas.getContext("2d", {
|
| 420 |
+
willReadFrequently: true,
|
| 421 |
+
})
|
| 422 |
+
|
| 423 |
+
return colorResolveContext
|
| 424 |
+
}
|
| 425 |
+
|
| 426 |
+
function resolveLineColor(color: string, element: HTMLElement) {
|
| 427 |
+
const resolver = document.createElement("span")
|
| 428 |
+
resolver.style.color = color
|
| 429 |
+
resolver.style.opacity = "0"
|
| 430 |
+
resolver.style.pointerEvents = "none"
|
| 431 |
+
resolver.style.position = "absolute"
|
| 432 |
+
element.appendChild(resolver)
|
| 433 |
+
|
| 434 |
+
const resolvedColor = getComputedStyle(resolver).color
|
| 435 |
+
resolver.remove()
|
| 436 |
+
const context = getColorResolveContext()
|
| 437 |
+
|
| 438 |
+
if (!context) {
|
| 439 |
+
return new Float32Array([0.5, 0.5, 0.5, 1])
|
| 440 |
+
}
|
| 441 |
+
|
| 442 |
+
context.clearRect(0, 0, 1, 1)
|
| 443 |
+
context.fillStyle = resolvedColor
|
| 444 |
+
context.fillRect(0, 0, 1, 1)
|
| 445 |
+
const pixel = context.getImageData(0, 0, 1, 1).data
|
| 446 |
+
|
| 447 |
+
return new Float32Array([
|
| 448 |
+
pixel[0] / 255,
|
| 449 |
+
pixel[1] / 255,
|
| 450 |
+
pixel[2] / 255,
|
| 451 |
+
pixel[3] / 255,
|
| 452 |
+
])
|
| 453 |
+
}
|
| 454 |
+
|
| 455 |
+
function createFallbackGridStyle(
|
| 456 |
+
cellSize: number,
|
| 457 |
+
lineColor: string
|
| 458 |
+
): CSSProperties {
|
| 459 |
+
return {
|
| 460 |
+
animation: `${FALLBACK_ANIMATION_NAME} ${ANIMATION_DURATION_SECONDS}s linear infinite`,
|
| 461 |
+
backgroundImage: `linear-gradient(to right, ${lineColor} 1px, transparent 0), linear-gradient(to bottom, ${lineColor} 1px, transparent 0)`,
|
| 462 |
+
backgroundRepeat: "repeat",
|
| 463 |
+
backgroundSize: `${cellSize}px ${cellSize}px`,
|
| 464 |
+
transform: "translateY(-50%)",
|
| 465 |
+
}
|
| 466 |
+
}
|
| 467 |
+
|
| 468 |
+
export function RetroGrid({
|
| 469 |
+
className,
|
| 470 |
+
angle = 65,
|
| 471 |
+
cellSize = 60,
|
| 472 |
+
opacity = 0.5,
|
| 473 |
+
lightLineColor = "gray",
|
| 474 |
+
darkLineColor = "gray",
|
| 475 |
+
style,
|
| 476 |
+
...props
|
| 477 |
+
}: RetroGridProps) {
|
| 478 |
+
const canvasRef = useRef<HTMLCanvasElement>(null)
|
| 479 |
+
const containerRef = useRef<HTMLDivElement>(null)
|
| 480 |
+
const [isWebGlReady, setIsWebGlReady] = useState(false)
|
| 481 |
+
const angleRef = useRef(angle)
|
| 482 |
+
const cellSizeRef = useRef(cellSize)
|
| 483 |
+
const darkLineColorRef = useRef(darkLineColor)
|
| 484 |
+
const lightLineColorRef = useRef(lightLineColor)
|
| 485 |
+
const syncSceneRef = useRef<(() => void) | null>(null)
|
| 486 |
+
|
| 487 |
+
useEffect(() => {
|
| 488 |
+
angleRef.current = angle
|
| 489 |
+
cellSizeRef.current = cellSize
|
| 490 |
+
darkLineColorRef.current = darkLineColor
|
| 491 |
+
lightLineColorRef.current = lightLineColor
|
| 492 |
+
syncSceneRef.current?.()
|
| 493 |
+
}, [angle, cellSize, darkLineColor, lightLineColor])
|
| 494 |
+
|
| 495 |
+
useEffect(() => {
|
| 496 |
+
const canvas = canvasRef.current
|
| 497 |
+
const container = containerRef.current
|
| 498 |
+
|
| 499 |
+
if (!canvas || !container) {
|
| 500 |
+
return
|
| 501 |
+
}
|
| 502 |
+
|
| 503 |
+
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)")
|
| 504 |
+
const colorScheme = window.matchMedia("(prefers-color-scheme: dark)")
|
| 505 |
+
|
| 506 |
+
let animationFrameId: number | null = null
|
| 507 |
+
let currentWidth = 0
|
| 508 |
+
let currentHeight = 0
|
| 509 |
+
let currentDevicePixelRatio = 1
|
| 510 |
+
let gl: WebGLRenderingContext | null = null
|
| 511 |
+
let isVisible = true
|
| 512 |
+
let isContextLost = false
|
| 513 |
+
let lineColor = resolveLineColor(lightLineColorRef.current, container)
|
| 514 |
+
let positionBuffer: WebGLBuffer | null = null
|
| 515 |
+
let programInfo: ProgramInfo | null = null
|
| 516 |
+
|
| 517 |
+
const getContext = () => {
|
| 518 |
+
const nextGl = canvas.getContext("webgl", {
|
| 519 |
+
alpha: true,
|
| 520 |
+
antialias: true,
|
| 521 |
+
premultipliedAlpha: true,
|
| 522 |
+
})
|
| 523 |
+
|
| 524 |
+
if (!nextGl || !nextGl.getExtension("OES_standard_derivatives")) {
|
| 525 |
+
return null
|
| 526 |
+
}
|
| 527 |
+
|
| 528 |
+
return nextGl
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
const releasePipeline = (shouldDeleteResources: boolean) => {
|
| 532 |
+
if (shouldDeleteResources && gl) {
|
| 533 |
+
if (positionBuffer) {
|
| 534 |
+
gl.deleteBuffer(positionBuffer)
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
if (programInfo) {
|
| 538 |
+
gl.deleteProgram(programInfo.program)
|
| 539 |
+
}
|
| 540 |
+
}
|
| 541 |
+
|
| 542 |
+
positionBuffer = null
|
| 543 |
+
programInfo = null
|
| 544 |
+
|
| 545 |
+
if (shouldDeleteResources) {
|
| 546 |
+
gl = null
|
| 547 |
+
}
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
const initializePipeline = () => {
|
| 551 |
+
const nextGl = getContext()
|
| 552 |
+
|
| 553 |
+
if (!nextGl) {
|
| 554 |
+
releasePipeline(false)
|
| 555 |
+
return false
|
| 556 |
+
}
|
| 557 |
+
|
| 558 |
+
gl = nextGl
|
| 559 |
+
releasePipeline(true)
|
| 560 |
+
gl = nextGl
|
| 561 |
+
|
| 562 |
+
const program = createProgram(nextGl)
|
| 563 |
+
|
| 564 |
+
if (!program) {
|
| 565 |
+
return false
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
const nextProgramInfo = getProgramInfo(nextGl, program)
|
| 569 |
+
|
| 570 |
+
if (!nextProgramInfo) {
|
| 571 |
+
nextGl.deleteProgram(program)
|
| 572 |
+
return false
|
| 573 |
+
}
|
| 574 |
+
|
| 575 |
+
const nextPositionBuffer = nextGl.createBuffer()
|
| 576 |
+
|
| 577 |
+
if (!nextPositionBuffer) {
|
| 578 |
+
nextGl.deleteProgram(program)
|
| 579 |
+
return false
|
| 580 |
+
}
|
| 581 |
+
|
| 582 |
+
nextGl.bindBuffer(nextGl.ARRAY_BUFFER, nextPositionBuffer)
|
| 583 |
+
nextGl.bufferData(
|
| 584 |
+
nextGl.ARRAY_BUFFER,
|
| 585 |
+
new Float32Array([-1, -1, 3, -1, -1, 3]),
|
| 586 |
+
nextGl.STATIC_DRAW
|
| 587 |
+
)
|
| 588 |
+
|
| 589 |
+
positionBuffer = nextPositionBuffer
|
| 590 |
+
programInfo = nextProgramInfo
|
| 591 |
+
|
| 592 |
+
return true
|
| 593 |
+
}
|
| 594 |
+
|
| 595 |
+
const updateLineColor = () => {
|
| 596 |
+
const activeColor = isDarkMode(colorScheme)
|
| 597 |
+
? darkLineColorRef.current
|
| 598 |
+
: lightLineColorRef.current
|
| 599 |
+
lineColor = resolveLineColor(activeColor, container)
|
| 600 |
+
}
|
| 601 |
+
|
| 602 |
+
const resizeCanvas = () => {
|
| 603 |
+
currentWidth = Math.floor(container.clientWidth)
|
| 604 |
+
currentHeight = Math.floor(container.clientHeight)
|
| 605 |
+
|
| 606 |
+
if (currentWidth === 0 || currentHeight === 0 || !gl) {
|
| 607 |
+
return
|
| 608 |
+
}
|
| 609 |
+
|
| 610 |
+
currentDevicePixelRatio = Math.min(
|
| 611 |
+
window.devicePixelRatio || 1,
|
| 612 |
+
MAX_DEVICE_PIXEL_RATIO
|
| 613 |
+
)
|
| 614 |
+
|
| 615 |
+
canvas.width = Math.floor(currentWidth * currentDevicePixelRatio)
|
| 616 |
+
canvas.height = Math.floor(currentHeight * currentDevicePixelRatio)
|
| 617 |
+
canvas.style.width = `${currentWidth}px`
|
| 618 |
+
canvas.style.height = `${currentHeight}px`
|
| 619 |
+
gl.viewport(0, 0, canvas.width, canvas.height)
|
| 620 |
+
}
|
| 621 |
+
|
| 622 |
+
const draw = (timestamp: number) => {
|
| 623 |
+
if (
|
| 624 |
+
currentWidth === 0 ||
|
| 625 |
+
currentHeight === 0 ||
|
| 626 |
+
!gl ||
|
| 627 |
+
!positionBuffer ||
|
| 628 |
+
!programInfo ||
|
| 629 |
+
isContextLost
|
| 630 |
+
) {
|
| 631 |
+
return
|
| 632 |
+
}
|
| 633 |
+
|
| 634 |
+
gl.useProgram(programInfo.program)
|
| 635 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
|
| 636 |
+
gl.enableVertexAttribArray(programInfo.attributeLocation)
|
| 637 |
+
gl.vertexAttribPointer(
|
| 638 |
+
programInfo.attributeLocation,
|
| 639 |
+
2,
|
| 640 |
+
gl.FLOAT,
|
| 641 |
+
false,
|
| 642 |
+
0,
|
| 643 |
+
0
|
| 644 |
+
)
|
| 645 |
+
gl.clearColor(0, 0, 0, 0)
|
| 646 |
+
gl.clear(gl.COLOR_BUFFER_BIT)
|
| 647 |
+
gl.uniform1f(
|
| 648 |
+
programInfo.uniforms.angle,
|
| 649 |
+
clamp(angleRef.current, MIN_ANGLE, MAX_ANGLE)
|
| 650 |
+
)
|
| 651 |
+
gl.uniform1f(
|
| 652 |
+
programInfo.uniforms.cellSize,
|
| 653 |
+
Math.max(cellSizeRef.current, 1)
|
| 654 |
+
)
|
| 655 |
+
gl.uniform2f(
|
| 656 |
+
programInfo.uniforms.containerSize,
|
| 657 |
+
currentWidth,
|
| 658 |
+
currentHeight
|
| 659 |
+
)
|
| 660 |
+
gl.uniform1f(
|
| 661 |
+
programInfo.uniforms.devicePixelRatio,
|
| 662 |
+
currentDevicePixelRatio
|
| 663 |
+
)
|
| 664 |
+
gl.uniform4fv(programInfo.uniforms.lineColor, lineColor)
|
| 665 |
+
gl.uniform1f(
|
| 666 |
+
programInfo.uniforms.time,
|
| 667 |
+
reducedMotion.matches ? 0 : timestamp / 1000
|
| 668 |
+
)
|
| 669 |
+
gl.uniform2f(
|
| 670 |
+
programInfo.uniforms.viewportSize,
|
| 671 |
+
window.innerWidth,
|
| 672 |
+
window.innerHeight
|
| 673 |
+
)
|
| 674 |
+
gl.drawArrays(gl.TRIANGLES, 0, 3)
|
| 675 |
+
}
|
| 676 |
+
|
| 677 |
+
const stopAnimation = () => {
|
| 678 |
+
if (animationFrameId !== null) {
|
| 679 |
+
cancelAnimationFrame(animationFrameId)
|
| 680 |
+
animationFrameId = null
|
| 681 |
+
}
|
| 682 |
+
}
|
| 683 |
+
|
| 684 |
+
const frame = (timestamp: number) => {
|
| 685 |
+
draw(timestamp)
|
| 686 |
+
|
| 687 |
+
if (!reducedMotion.matches && isVisible) {
|
| 688 |
+
animationFrameId = requestAnimationFrame(frame)
|
| 689 |
+
return
|
| 690 |
+
}
|
| 691 |
+
|
| 692 |
+
animationFrameId = null
|
| 693 |
+
}
|
| 694 |
+
|
| 695 |
+
const syncScene = () => {
|
| 696 |
+
if (isContextLost) {
|
| 697 |
+
stopAnimation()
|
| 698 |
+
setIsWebGlReady(false)
|
| 699 |
+
return
|
| 700 |
+
}
|
| 701 |
+
|
| 702 |
+
if (!gl || !positionBuffer || !programInfo) {
|
| 703 |
+
if (!initializePipeline()) {
|
| 704 |
+
stopAnimation()
|
| 705 |
+
setIsWebGlReady(false)
|
| 706 |
+
return
|
| 707 |
+
}
|
| 708 |
+
}
|
| 709 |
+
|
| 710 |
+
resizeCanvas()
|
| 711 |
+
|
| 712 |
+
if (currentWidth === 0 || currentHeight === 0) {
|
| 713 |
+
stopAnimation()
|
| 714 |
+
return
|
| 715 |
+
}
|
| 716 |
+
|
| 717 |
+
updateLineColor()
|
| 718 |
+
draw(performance.now())
|
| 719 |
+
setIsWebGlReady(true)
|
| 720 |
+
|
| 721 |
+
if (reducedMotion.matches || !isVisible) {
|
| 722 |
+
stopAnimation()
|
| 723 |
+
return
|
| 724 |
+
}
|
| 725 |
+
|
| 726 |
+
if (animationFrameId === null) {
|
| 727 |
+
animationFrameId = requestAnimationFrame(frame)
|
| 728 |
+
}
|
| 729 |
+
}
|
| 730 |
+
|
| 731 |
+
syncSceneRef.current = syncScene
|
| 732 |
+
|
| 733 |
+
const resizeObserver = new ResizeObserver(() => {
|
| 734 |
+
syncScene()
|
| 735 |
+
})
|
| 736 |
+
resizeObserver.observe(container)
|
| 737 |
+
|
| 738 |
+
const handleWindowResize = () => {
|
| 739 |
+
syncScene()
|
| 740 |
+
}
|
| 741 |
+
|
| 742 |
+
const intersectionObserver = new IntersectionObserver(([entry]) => {
|
| 743 |
+
isVisible = entry?.isIntersecting ?? false
|
| 744 |
+
|
| 745 |
+
if (isVisible) {
|
| 746 |
+
syncScene()
|
| 747 |
+
return
|
| 748 |
+
}
|
| 749 |
+
|
| 750 |
+
stopAnimation()
|
| 751 |
+
})
|
| 752 |
+
intersectionObserver.observe(container)
|
| 753 |
+
|
| 754 |
+
const themeObserver = new MutationObserver(() => {
|
| 755 |
+
syncScene()
|
| 756 |
+
})
|
| 757 |
+
themeObserver.observe(document.documentElement, {
|
| 758 |
+
attributeFilter: ["class"],
|
| 759 |
+
attributes: true,
|
| 760 |
+
})
|
| 761 |
+
|
| 762 |
+
const handleMotionChange = () => {
|
| 763 |
+
syncScene()
|
| 764 |
+
}
|
| 765 |
+
|
| 766 |
+
const handleColorSchemeChange = () => {
|
| 767 |
+
syncScene()
|
| 768 |
+
}
|
| 769 |
+
|
| 770 |
+
const handleContextLost = (event: Event) => {
|
| 771 |
+
event.preventDefault()
|
| 772 |
+
isContextLost = true
|
| 773 |
+
stopAnimation()
|
| 774 |
+
releasePipeline(false)
|
| 775 |
+
setIsWebGlReady(false)
|
| 776 |
+
}
|
| 777 |
+
|
| 778 |
+
const handleContextRestored = () => {
|
| 779 |
+
isContextLost = false
|
| 780 |
+
syncScene()
|
| 781 |
+
}
|
| 782 |
+
|
| 783 |
+
reducedMotion.addEventListener("change", handleMotionChange)
|
| 784 |
+
colorScheme.addEventListener("change", handleColorSchemeChange)
|
| 785 |
+
window.addEventListener("resize", handleWindowResize)
|
| 786 |
+
canvas.addEventListener("webglcontextlost", handleContextLost)
|
| 787 |
+
canvas.addEventListener("webglcontextrestored", handleContextRestored)
|
| 788 |
+
|
| 789 |
+
syncScene()
|
| 790 |
+
|
| 791 |
+
return () => {
|
| 792 |
+
stopAnimation()
|
| 793 |
+
resizeObserver.disconnect()
|
| 794 |
+
intersectionObserver.disconnect()
|
| 795 |
+
themeObserver.disconnect()
|
| 796 |
+
reducedMotion.removeEventListener("change", handleMotionChange)
|
| 797 |
+
colorScheme.removeEventListener("change", handleColorSchemeChange)
|
| 798 |
+
window.removeEventListener("resize", handleWindowResize)
|
| 799 |
+
canvas.removeEventListener("webglcontextlost", handleContextLost)
|
| 800 |
+
canvas.removeEventListener("webglcontextrestored", handleContextRestored)
|
| 801 |
+
syncSceneRef.current = null
|
| 802 |
+
releasePipeline(!isContextLost)
|
| 803 |
+
}
|
| 804 |
+
}, [])
|
| 805 |
+
|
| 806 |
+
const gridStyles = {
|
| 807 |
+
...style,
|
| 808 |
+
opacity,
|
| 809 |
+
} as CSSProperties
|
| 810 |
+
const normalizedAngle = clamp(angle, MIN_ANGLE, MAX_ANGLE)
|
| 811 |
+
const normalizedCellSize = Math.max(cellSize, 1)
|
| 812 |
+
const fallbackProjectionStyles = {
|
| 813 |
+
perspective: `${PERSPECTIVE_PX}px`,
|
| 814 |
+
} as CSSProperties
|
| 815 |
+
const fallbackRotationStyles = {
|
| 816 |
+
transform: `rotateX(${normalizedAngle}deg)`,
|
| 817 |
+
} as CSSProperties
|
| 818 |
+
const lightFallbackGridStyles = createFallbackGridStyle(
|
| 819 |
+
normalizedCellSize,
|
| 820 |
+
lightLineColor
|
| 821 |
+
)
|
| 822 |
+
const darkFallbackGridStyles = createFallbackGridStyle(
|
| 823 |
+
normalizedCellSize,
|
| 824 |
+
darkLineColor
|
| 825 |
+
)
|
| 826 |
+
|
| 827 |
+
return (
|
| 828 |
+
<div
|
| 829 |
+
ref={containerRef}
|
| 830 |
+
className={cn(
|
| 831 |
+
"pointer-events-none absolute size-full overflow-hidden",
|
| 832 |
+
className
|
| 833 |
+
)}
|
| 834 |
+
style={gridStyles}
|
| 835 |
+
{...props}
|
| 836 |
+
>
|
| 837 |
+
<style>{FALLBACK_STYLES}</style>
|
| 838 |
+
{!isWebGlReady ? (
|
| 839 |
+
<div className="absolute inset-0" style={fallbackProjectionStyles}>
|
| 840 |
+
<div className="absolute inset-0" style={fallbackRotationStyles}>
|
| 841 |
+
<div
|
| 842 |
+
data-retro-grid-scroll="true"
|
| 843 |
+
className="absolute inset-[0%_0px] ml-[-200%] h-[300vh] w-[600vw] origin-[100%_0_0] dark:hidden"
|
| 844 |
+
style={lightFallbackGridStyles}
|
| 845 |
+
/>
|
| 846 |
+
<div
|
| 847 |
+
data-retro-grid-scroll="true"
|
| 848 |
+
className="absolute inset-[0%_0px] ml-[-200%] hidden h-[300vh] w-[600vw] origin-[100%_0_0] dark:block"
|
| 849 |
+
style={darkFallbackGridStyles}
|
| 850 |
+
/>
|
| 851 |
+
</div>
|
| 852 |
+
</div>
|
| 853 |
+
) : null}
|
| 854 |
+
<canvas
|
| 855 |
+
ref={canvasRef}
|
| 856 |
+
className={cn(
|
| 857 |
+
"absolute inset-0 size-full",
|
| 858 |
+
isWebGlReady ? "opacity-100" : "opacity-0"
|
| 859 |
+
)}
|
| 860 |
+
/>
|
| 861 |
+
<div className="absolute inset-0 bg-linear-to-t from-white to-transparent to-90% dark:from-black" />
|
| 862 |
+
</div>
|
| 863 |
+
)
|
| 864 |
+
}
|
b/7e530ec32c30fd622814756a82a99606dc963865c7bddfe075bfa8adc003d8bb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
var fa=Object.defineProperty;var ia=(e,t)=>{for(var a in t)fa(e,a,{get:t[a],enumerable:!0})};function Ae(e){var t,a,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var l=e.length;for(t=0;t<l;t++)e[t]&&(a=Ae(e[t]))&&(o&&(o+=" "),o+=a)}else for(a in e)e[a]&&(o&&(o+=" "),o+=a);return o}function j(){for(var e,t,a=0,o="",l=arguments.length;a<l;a++)(e=arguments[a])&&(t=Ae(e))&&(o&&(o+=" "),o+=t);return o}var Be=e=>typeof e=="boolean"?`${e}`:e===0?"0":e,ye=j,Me=(e,t)=>a=>{var o;if(t?.variants==null)return ye(e,a?.class,a?.className);let{variants:l,defaultVariants:u}=t,r=Object.keys(l).map(f=>{let L=a?.[f],I=u?.[f];if(L===null)return null;let C=Be(L)||Be(I);return l[f][C]}),c=a&&Object.entries(a).reduce((f,L)=>{let[I,C]=L;return C===void 0||(f[I]=C),f},{}),p=t==null||(o=t.compoundVariants)===null||o===void 0?void 0:o.reduce((f,L)=>{let{class:I,className:C,...h}=L;return Object.entries(h).every(y=>{let[w,k]=y;return Array.isArray(k)?k.includes({...u,...c}[w]):{...u,...c}[w]===k})?[...f,I,C]:f},[]);return ye(e,r,p,a?.class,a?.className)};var Y={};ia(Y,{Root:()=>ca,Slot:()=>ca,Slottable:()=>pa,createSlot:()=>Te,createSlottable:()=>Ue});import*as S from"react";import*as De from"react";function Fe(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function na(...e){return t=>{let a=!1,o=e.map(l=>{let u=Fe(l,t);return!a&&typeof u=="function"&&(a=!0),u});if(a)return()=>{for(let l=0;l<o.length;l++){let u=o[l];typeof u=="function"?u():Fe(e[l],null)}}}}function Re(...e){return De.useCallback(na(...e),e)}function Te(e){let t=S.forwardRef((a,o)=>{let{children:l,...u}=a,r=null,c=!1,p=[];ve(l)&&typeof $=="function"&&(l=$(l._payload)),S.Children.forEach(l,C=>{if(xa(C)){c=!0;let h=C,y="child"in h.props?h.props.child:h.props.children;ve(y)&&typeof $=="function"&&(y=$(y._payload)),r=ma(h,y),p.push(r?.props?.children)}else p.push(C)}),r?r=S.cloneElement(r,void 0,p):!c&&S.Children.count(l)===1&&S.isValidElement(l)&&(r=l);let f=r?Ia(r):void 0,L=Re(o,f);if(!r){if(l||l===0)throw new Error(c?Sa(e):ha(e));return l}let I=La(u,r.props??{});return r.type!==S.Fragment&&(I.ref=o?L:f),S.cloneElement(r,I)});return t.displayName=`${e}.Slot`,t}var ca=Te("Slot"),qe=Symbol.for("radix.slottable");function Ue(e){let t=a=>"child"in a?a.children(a.child):a.children;return t.displayName=`${e}.Slottable`,t.__radixId=qe,t}var pa=Ue("Slottable"),ma=(e,t)=>{if("child"in e.props){let a=e.props.child;return S.isValidElement(a)?S.cloneElement(a,void 0,e.props.children(a.props.children)):null}return S.isValidElement(t)?t:null};function La(e,t){let a={...t};for(let o in t){let l=e[o],u=t[o];/^on[A-Z]/.test(o)?l&&u?a[o]=(...c)=>{let p=u(...c);return l(...c),p}:l&&(a[o]=l):o==="style"?a[o]={...l,...u}:o==="className"&&(a[o]=[l,u].filter(Boolean).join(" "))}return{...e,...a}}function Ia(e){let t=Object.getOwnPropertyDescriptor(e.props,"ref")?.get,a=t&&"isReactWarning"in t&&t.isReactWarning;return a?e.ref:(t=Object.getOwnPropertyDescriptor(e,"ref")?.get,a=t&&"isReactWarning"in t&&t.isReactWarning,a?e.props.ref:e.props.ref||e.ref)}function xa(e){return S.isValidElement(e)&&typeof e.type=="function"&&"__radixId"in e.type&&e.type.__radixId===qe}var Ca=Symbol.for("react.lazy");function ve(e){return e!=null&&typeof e=="object"&&"$$typeof"in e&&e.$$typeof===Ca&&"_payload"in e&&ga(e._payload)}function ga(e){return typeof e=="object"&&e!==null&&"then"in e}var ha=e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,Sa=e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,$=S[" use ".trim().toString()];var wa=(e,t)=>{let a=new Array(e.length+t.length);for(let o=0;o<e.length;o++)a[o]=e[o];for(let o=0;o<t.length;o++)a[e.length+o]=t[o];return a},ka=(e,t)=>({classGroupId:e,validator:t}),We=(e=new Map,t=null,a)=>({nextPart:e,validators:t,classGroupId:a}),te="-",Oe=[],ba="arbitrary..",Pa=e=>{let t=Ba(e),{conflictingClassGroups:a,conflictingClassGroupModifiers:o}=e;return{getClassGroupId:r=>{if(r.startsWith("[")&&r.endsWith("]"))return Aa(r);let c=r.split(te),p=c[0]===""&&c.length>1?1:0;return Ne(c,p,t)},getConflictingClassGroupIds:(r,c)=>{if(c){let p=o[r],f=a[r];return p?f?wa(f,p):p:f||Oe}return a[r]||Oe}}},Ne=(e,t,a)=>{if(e.length-t===0)return a.classGroupId;let l=e[t],u=a.nextPart.get(l);if(u){let f=Ne(e,t+1,u);if(f)return f}let r=a.validators;if(r===null)return;let c=t===0?e.join(te):e.slice(t).join(te),p=r.length;for(let f=0;f<p;f++){let L=r[f];if(L.validator(c))return L.classGroupId}},Aa=e=>e.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let t=e.slice(1,-1),a=t.indexOf(":"),o=t.slice(0,a);return o?ba+o:void 0})(),Ba=e=>{let{theme:t,classGroups:a}=e;return ya(a,t)},ya=(e,t)=>{let a=We();for(let o in e){let l=e[o];Le(l,a,o,t)}return a},Le=(e,t,a,o)=>{let l=e.length;for(let u=0;u<l;u++){let r=e[u];Ma(r,t,a,o)}},Ma=(e,t,a,o)=>{if(typeof e=="string"){Fa(e,t,a);return}if(typeof e=="function"){Da(e,t,a,o);return}Ra(e,t,a,o)},Fa=(e,t,a)=>{let o=e===""?t:Xe(t,e);o.classGroupId=a},Da=(e,t,a,o)=>{if(va(e)){Le(e(o),t,a,o);return}t.validators===null&&(t.validators=[]),t.validators.push(ka(a,e))},Ra=(e,t,a,o)=>{let l=Object.entries(e),u=l.length;for(let r=0;r<u;r++){let[c,p]=l[r];Le(p,Xe(t,c),a,o)}},Xe=(e,t)=>{let a=e,o=t.split(te),l=o.length;for(let u=0;u<l;u++){let r=o[u],c=a.nextPart.get(r);c||(c=We(),a.nextPart.set(r,c)),a=c}return a},va=e=>"isThemeGetter"in e&&e.isThemeGetter===!0,Ta=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,a=Object.create(null),o=Object.create(null),l=(u,r)=>{a[u]=r,t++,t>e&&(t=0,o=a,a=Object.create(null))};return{get(u){let r=a[u];if(r!==void 0)return r;if((r=o[u])!==void 0)return l(u,r),r},set(u,r){u in a?a[u]=r:l(u,r)}}},me="!",He=":",qa=[],Ge=(e,t,a,o,l)=>({modifiers:e,hasImportantModifier:t,baseClassName:a,maybePostfixModifierPosition:o,isExternal:l}),Ua=e=>{let{prefix:t,experimentalParseClassName:a}=e,o=l=>{let u=[],r=0,c=0,p=0,f,L=l.length;for(let w=0;w<L;w++){let k=l[w];if(r===0&&c===0){if(k===He){u.push(l.slice(p,w)),p=w+1;continue}if(k==="/"){f=w;continue}}k==="["?r++:k==="]"?r--:k==="("?c++:k===")"&&c--}let I=u.length===0?l:l.slice(p),C=I,h=!1;I.endsWith(me)?(C=I.slice(0,-1),h=!0):I.startsWith(me)&&(C=I.slice(1),h=!0);let y=f&&f>p?f-p:void 0;return Ge(u,h,C,y)};if(t){let l=t+He,u=o;o=r=>r.startsWith(l)?u(r.slice(l.length)):Ge(qa,!1,r,void 0,!0)}if(a){let l=o;o=u=>a({className:u,parseClassName:l})}return o},Oa=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((a,o)=>{t.set(a,1e6+o)}),a=>{let o=[],l=[];for(let u=0;u<a.length;u++){let r=a[u],c=r[0]==="[",p=t.has(r);c||p?(l.length>0&&(l.sort(),o.push(...l),l=[]),o.push(r)):l.push(r)}return l.length>0&&(l.sort(),o.push(...l)),o}},Ha=e=>({cache:Ta(e.cacheSize),parseClassName:Ua(e),sortModifiers:Oa(e),postfixLookupClassGroupIds:Ga(e),...Pa(e)}),Ga=e=>{let t=Object.create(null),a=e.postfixLookupClassGroups;if(a)for(let o=0;o<a.length;o++)t[a[o]]=!0;return t},za=/\s+/,Va=(e,t)=>{let{parseClassName:a,getClassGroupId:o,getConflictingClassGroupIds:l,sortModifiers:u,postfixLookupClassGroupIds:r}=t,c=[],p=e.trim().split(za),f="";for(let L=p.length-1;L>=0;L-=1){let I=p[L],{isExternal:C,modifiers:h,hasImportantModifier:y,baseClassName:w,maybePostfixModifierPosition:k}=a(I);if(C){f=I+(f.length>0?" "+f:f);continue}let U=!!k,A;if(U){let D=w.substring(0,k);A=o(D);let i=A&&r[A]?o(w):void 0;i&&i!==A&&(A=i,U=!1)}else A=o(w);if(!A){if(!U){f=I+(f.length>0?" "+f:f);continue}if(A=o(w),!A){f=I+(f.length>0?" "+f:f);continue}U=!1}let N=h.length===0?"":h.length===1?h[0]:u(h).join(":"),z=y?N+me:N,V=z+A;if(c.indexOf(V)>-1)continue;c.push(V);let E=l(A,U);for(let D=0;D<E.length;++D){let i=E[D];c.push(z+i)}f=I+(f.length>0?" "+f:f)}return f},Ea=(...e)=>{let t=0,a,o,l="";for(;t<e.length;)(a=e[t++])&&(o=Ke(a))&&(l&&(l+=" "),l+=o);return l},Ke=e=>{if(typeof e=="string")return e;let t,a="";for(let o=0;o<e.length;o++)e[o]&&(t=Ke(e[o]))&&(a&&(a+=" "),a+=t);return a},Wa=(e,...t)=>{let a,o,l,u,r=p=>{let f=t.reduce((L,I)=>I(L),e());return a=Ha(f),o=a.cache.get,l=a.cache.set,u=c,c(p)},c=p=>{let f=o(p);if(f)return f;let L=Va(p,a);return l(p,L),L};return u=r,(...p)=>u(Ea(...p))},Na=[],x=e=>{let t=a=>a[e]||Na;return t.isThemeGetter=!0,t},Ze=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Je=/^\((?:(\w[\w-]*):)?(.+)\)$/i,Xa=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,Ka=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,Za=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,Ja=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,_a=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,Qa=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,v=e=>Xa.test(e),m=e=>!!e&&!Number.isNaN(Number(e)),F=e=>!!e&&Number.isInteger(Number(e)),pe=e=>e.endsWith("%")&&m(e.slice(0,-1)),R=e=>Ka.test(e),_e=()=>!0,ja=e=>Za.test(e)&&!Ja.test(e),Ie=()=>!1,$a=e=>_a.test(e),Ya=e=>Qa.test(e),et=e=>!d(e)&&!s(e),at=e=>e.startsWith("@container")&&(e[10]==="/"&&e[11]!==void 0||e[11]==="s"&&e[16]!==void 0&&e.startsWith("-size/",10)||e[11]==="n"&&e[18]!==void 0&&e.startsWith("-normal/",10)),tt=e=>T(e,$e,Ie),d=e=>Ze.test(e),H=e=>T(e,Ye,ja),ze=e=>T(e,it,m),ot=e=>T(e,aa,_e),lt=e=>T(e,ea,Ie),Ve=e=>T(e,Qe,Ie),rt=e=>T(e,je,Ya),ee=e=>T(e,ta,$a),s=e=>Je.test(e),X=e=>G(e,Ye),ut=e=>G(e,ea),Ee=e=>G(e,Qe),dt=e=>G(e,$e),st=e=>G(e,je),ae=e=>G(e,ta,!0),ft=e=>G(e,aa,!0),T=(e,t,a)=>{let o=Ze.exec(e);return o?o[1]?t(o[1]):a(o[2]):!1},G=(e,t,a=!1)=>{let o=Je.exec(e);return o?o[1]?t(o[1]):a:!1},Qe=e=>e==="position"||e==="percentage",je=e=>e==="image"||e==="url",$e=e=>e==="length"||e==="size"||e==="bg-size",Ye=e=>e==="length",it=e=>e==="number",ea=e=>e==="family-name",aa=e=>e==="number"||e==="weight",ta=e=>e==="shadow";var nt=()=>{let e=x("color"),t=x("font"),a=x("text"),o=x("font-weight"),l=x("tracking"),u=x("leading"),r=x("breakpoint"),c=x("container"),p=x("spacing"),f=x("radius"),L=x("shadow"),I=x("inset-shadow"),C=x("text-shadow"),h=x("drop-shadow"),y=x("blur"),w=x("perspective"),k=x("aspect"),U=x("ease"),A=x("animate"),N=()=>["auto","avoid","all","avoid-page","page","left","right","column"],z=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],V=()=>[...z(),s,d],E=()=>["auto","hidden","clip","visible","scroll"],D=()=>["auto","contain","none"],i=()=>[s,d,p],B=()=>[v,"full","auto",...i()],Ce=()=>[F,"none","subgrid",s,d],ge=()=>["auto",{span:["full",F,s,d]},F,s,d],K=()=>[F,"auto",s,d],he=()=>["auto","min","max","fr",s,d],se=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],W=()=>["start","end","center","stretch","center-safe","end-safe"],M=()=>["auto",...i()],O=()=>[v,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...i()],fe=()=>[v,"screen","full","dvw","lvw","svw","min","max","fit",...i()],ie=()=>[v,"screen","full","lh","dvh","lvh","svh","min","max","fit",...i()],n=()=>[e,s,d],Se=()=>[...z(),Ee,Ve,{position:[s,d]}],we=()=>["no-repeat",{repeat:["","x","y","space","round"]}],ke=()=>["auto","cover","contain",dt,tt,{size:[s,d]}],ne=()=>[pe,X,H],b=()=>["","none","full",f,s,d],P=()=>["",m,X,H],Z=()=>["solid","dashed","dotted","double"],be=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],g=()=>[m,pe,Ee,Ve],Pe=()=>["","none",y,s,d],J=()=>["none",m,s,d],_=()=>["none",m,s,d],ce=()=>[m,s,d],Q=()=>[v,"full",...i()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[R],breakpoint:[R],color:[_e],container:[R],"drop-shadow":[R],ease:["in","out","in-out"],font:[et],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[R],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[R],shadow:[R],spacing:["px",m],text:[R],"text-shadow":[R],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",v,d,s,k]}],container:["container"],"container-type":[{"@container":["","normal","size",s,d]}],"container-named":[at],columns:[{columns:[m,d,s,c]}],"break-after":[{"break-after":N()}],"break-before":[{"break-before":N()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:V()}],overflow:[{overflow:E()}],"overflow-x":[{"overflow-x":E()}],"overflow-y":[{"overflow-y":E()}],overscroll:[{overscroll:D()}],"overscroll-x":[{"overscroll-x":D()}],"overscroll-y":[{"overscroll-y":D()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:B()}],"inset-x":[{"inset-x":B()}],"inset-y":[{"inset-y":B()}],start:[{"inset-s":B(),start:B()}],end:[{"inset-e":B(),end:B()}],"inset-bs":[{"inset-bs":B()}],"inset-be":[{"inset-be":B()}],top:[{top:B()}],right:[{right:B()}],bottom:[{bottom:B()}],left:[{left:B()}],visibility:["visible","invisible","collapse"],z:[{z:[F,"auto",s,d]}],basis:[{basis:[v,"full","auto",c,...i()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[m,v,"auto","initial","none",d]}],grow:[{grow:["",m,s,d]}],shrink:[{shrink:["",m,s,d]}],order:[{order:[F,"first","last","none",s,d]}],"grid-cols":[{"grid-cols":Ce()}],"col-start-end":[{col:ge()}],"col-start":[{"col-start":K()}],"col-end":[{"col-end":K()}],"grid-rows":[{"grid-rows":Ce()}],"row-start-end":[{row:ge()}],"row-start":[{"row-start":K()}],"row-end":[{"row-end":K()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":he()}],"auto-rows":[{"auto-rows":he()}],gap:[{gap:i()}],"gap-x":[{"gap-x":i()}],"gap-y":[{"gap-y":i()}],"justify-content":[{justify:[...se(),"normal"]}],"justify-items":[{"justify-items":[...W(),"normal"]}],"justify-self":[{"justify-self":["auto",...W()]}],"align-content":[{content:["normal",...se()]}],"align-items":[{items:[...W(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...W(),{baseline:["","last"]}]}],"place-content":[{"place-content":se()}],"place-items":[{"place-items":[...W(),"baseline"]}],"place-self":[{"place-self":["auto",...W()]}],p:[{p:i()}],px:[{px:i()}],py:[{py:i()}],ps:[{ps:i()}],pe:[{pe:i()}],pbs:[{pbs:i()}],pbe:[{pbe:i()}],pt:[{pt:i()}],pr:[{pr:i()}],pb:[{pb:i()}],pl:[{pl:i()}],m:[{m:M()}],mx:[{mx:M()}],my:[{my:M()}],ms:[{ms:M()}],me:[{me:M()}],mbs:[{mbs:M()}],mbe:[{mbe:M()}],mt:[{mt:M()}],mr:[{mr:M()}],mb:[{mb:M()}],ml:[{ml:M()}],"space-x":[{"space-x":i()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":i()}],"space-y-reverse":["space-y-reverse"],size:[{size:O()}],"inline-size":[{inline:["auto",...fe()]}],"min-inline-size":[{"min-inline":["auto",...fe()]}],"max-inline-size":[{"max-inline":["none",...fe()]}],"block-size":[{block:["auto",...ie()]}],"min-block-size":[{"min-block":["auto",...ie()]}],"max-block-size":[{"max-block":["none",...ie()]}],w:[{w:[c,"screen",...O()]}],"min-w":[{"min-w":[c,"screen","none",...O()]}],"max-w":[{"max-w":[c,"screen","none","prose",{screen:[r]},...O()]}],h:[{h:["screen","lh",...O()]}],"min-h":[{"min-h":["screen","lh","none",...O()]}],"max-h":[{"max-h":["screen","lh",...O()]}],"font-size":[{text:["base",a,X,H]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[o,ft,ot]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",pe,d]}],"font-family":[{font:[ut,lt,t]}],"font-features":[{"font-features":[d]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[l,s,d]}],"line-clamp":[{"line-clamp":[m,"none",s,ze]}],leading:[{leading:[u,...i()]}],"list-image":[{"list-image":["none",s,d]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",s,d]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:n()}],"text-color":[{text:n()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...Z(),"wavy"]}],"text-decoration-thickness":[{decoration:[m,"from-font","auto",s,H]}],"text-decoration-color":[{decoration:n()}],"underline-offset":[{"underline-offset":[m,"auto",s,d]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:i()}],"tab-size":[{tab:[F,s,d]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",s,d]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",s,d]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:Se()}],"bg-repeat":[{bg:we()}],"bg-size":[{bg:ke()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},F,s,d],radial:["",s,d],conic:[F,s,d]},st,rt]}],"bg-color":[{bg:n()}],"gradient-from-pos":[{from:ne()}],"gradient-via-pos":[{via:ne()}],"gradient-to-pos":[{to:ne()}],"gradient-from":[{from:n()}],"gradient-via":[{via:n()}],"gradient-to":[{to:n()}],rounded:[{rounded:b()}],"rounded-s":[{"rounded-s":b()}],"rounded-e":[{"rounded-e":b()}],"rounded-t":[{"rounded-t":b()}],"rounded-r":[{"rounded-r":b()}],"rounded-b":[{"rounded-b":b()}],"rounded-l":[{"rounded-l":b()}],"rounded-ss":[{"rounded-ss":b()}],"rounded-se":[{"rounded-se":b()}],"rounded-ee":[{"rounded-ee":b()}],"rounded-es":[{"rounded-es":b()}],"rounded-tl":[{"rounded-tl":b()}],"rounded-tr":[{"rounded-tr":b()}],"rounded-br":[{"rounded-br":b()}],"rounded-bl":[{"rounded-bl":b()}],"border-w":[{border:P()}],"border-w-x":[{"border-x":P()}],"border-w-y":[{"border-y":P()}],"border-w-s":[{"border-s":P()}],"border-w-e":[{"border-e":P()}],"border-w-bs":[{"border-bs":P()}],"border-w-be":[{"border-be":P()}],"border-w-t":[{"border-t":P()}],"border-w-r":[{"border-r":P()}],"border-w-b":[{"border-b":P()}],"border-w-l":[{"border-l":P()}],"divide-x":[{"divide-x":P()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":P()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...Z(),"hidden","none"]}],"divide-style":[{divide:[...Z(),"hidden","none"]}],"border-color":[{border:n()}],"border-color-x":[{"border-x":n()}],"border-color-y":[{"border-y":n()}],"border-color-s":[{"border-s":n()}],"border-color-e":[{"border-e":n()}],"border-color-bs":[{"border-bs":n()}],"border-color-be":[{"border-be":n()}],"border-color-t":[{"border-t":n()}],"border-color-r":[{"border-r":n()}],"border-color-b":[{"border-b":n()}],"border-color-l":[{"border-l":n()}],"divide-color":[{divide:n()}],"outline-style":[{outline:[...Z(),"none","hidden"]}],"outline-offset":[{"outline-offset":[m,s,d]}],"outline-w":[{outline:["",m,X,H]}],"outline-color":[{outline:n()}],shadow:[{shadow:["","none",L,ae,ee]}],"shadow-color":[{shadow:n()}],"inset-shadow":[{"inset-shadow":["none",I,ae,ee]}],"inset-shadow-color":[{"inset-shadow":n()}],"ring-w":[{ring:P()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:n()}],"ring-offset-w":[{"ring-offset":[m,H]}],"ring-offset-color":[{"ring-offset":n()}],"inset-ring-w":[{"inset-ring":P()}],"inset-ring-color":[{"inset-ring":n()}],"text-shadow":[{"text-shadow":["none",C,ae,ee]}],"text-shadow-color":[{"text-shadow":n()}],opacity:[{opacity:[m,s,d]}],"mix-blend":[{"mix-blend":[...be(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":be()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[m]}],"mask-image-linear-from-pos":[{"mask-linear-from":g()}],"mask-image-linear-to-pos":[{"mask-linear-to":g()}],"mask-image-linear-from-color":[{"mask-linear-from":n()}],"mask-image-linear-to-color":[{"mask-linear-to":n()}],"mask-image-t-from-pos":[{"mask-t-from":g()}],"mask-image-t-to-pos":[{"mask-t-to":g()}],"mask-image-t-from-color":[{"mask-t-from":n()}],"mask-image-t-to-color":[{"mask-t-to":n()}],"mask-image-r-from-pos":[{"mask-r-from":g()}],"mask-image-r-to-pos":[{"mask-r-to":g()}],"mask-image-r-from-color":[{"mask-r-from":n()}],"mask-image-r-to-color":[{"mask-r-to":n()}],"mask-image-b-from-pos":[{"mask-b-from":g()}],"mask-image-b-to-pos":[{"mask-b-to":g()}],"mask-image-b-from-color":[{"mask-b-from":n()}],"mask-image-b-to-color":[{"mask-b-to":n()}],"mask-image-l-from-pos":[{"mask-l-from":g()}],"mask-image-l-to-pos":[{"mask-l-to":g()}],"mask-image-l-from-color":[{"mask-l-from":n()}],"mask-image-l-to-color":[{"mask-l-to":n()}],"mask-image-x-from-pos":[{"mask-x-from":g()}],"mask-image-x-to-pos":[{"mask-x-to":g()}],"mask-image-x-from-color":[{"mask-x-from":n()}],"mask-image-x-to-color":[{"mask-x-to":n()}],"mask-image-y-from-pos":[{"mask-y-from":g()}],"mask-image-y-to-pos":[{"mask-y-to":g()}],"mask-image-y-from-color":[{"mask-y-from":n()}],"mask-image-y-to-color":[{"mask-y-to":n()}],"mask-image-radial":[{"mask-radial":[s,d]}],"mask-image-radial-from-pos":[{"mask-radial-from":g()}],"mask-image-radial-to-pos":[{"mask-radial-to":g()}],"mask-image-radial-from-color":[{"mask-radial-from":n()}],"mask-image-radial-to-color":[{"mask-radial-to":n()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":z()}],"mask-image-conic-pos":[{"mask-conic":[m]}],"mask-image-conic-from-pos":[{"mask-conic-from":g()}],"mask-image-conic-to-pos":[{"mask-conic-to":g()}],"mask-image-conic-from-color":[{"mask-conic-from":n()}],"mask-image-conic-to-color":[{"mask-conic-to":n()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:Se()}],"mask-repeat":[{mask:we()}],"mask-size":[{mask:ke()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",s,d]}],filter:[{filter:["","none",s,d]}],blur:[{blur:Pe()}],brightness:[{brightness:[m,s,d]}],contrast:[{contrast:[m,s,d]}],"drop-shadow":[{"drop-shadow":["","none",h,ae,ee]}],"drop-shadow-color":[{"drop-shadow":n()}],grayscale:[{grayscale:["",m,s,d]}],"hue-rotate":[{"hue-rotate":[m,s,d]}],invert:[{invert:["",m,s,d]}],saturate:[{saturate:[m,s,d]}],sepia:[{sepia:["",m,s,d]}],"backdrop-filter":[{"backdrop-filter":["","none",s,d]}],"backdrop-blur":[{"backdrop-blur":Pe()}],"backdrop-brightness":[{"backdrop-brightness":[m,s,d]}],"backdrop-contrast":[{"backdrop-contrast":[m,s,d]}],"backdrop-grayscale":[{"backdrop-grayscale":["",m,s,d]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[m,s,d]}],"backdrop-invert":[{"backdrop-invert":["",m,s,d]}],"backdrop-opacity":[{"backdrop-opacity":[m,s,d]}],"backdrop-saturate":[{"backdrop-saturate":[m,s,d]}],"backdrop-sepia":[{"backdrop-sepia":["",m,s,d]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":i()}],"border-spacing-x":[{"border-spacing-x":i()}],"border-spacing-y":[{"border-spacing-y":i()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",s,d]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[m,"initial",s,d]}],ease:[{ease:["linear","initial",U,s,d]}],delay:[{delay:[m,s,d]}],animate:[{animate:["none",A,s,d]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[w,s,d]}],"perspective-origin":[{"perspective-origin":V()}],rotate:[{rotate:J()}],"rotate-x":[{"rotate-x":J()}],"rotate-y":[{"rotate-y":J()}],"rotate-z":[{"rotate-z":J()}],scale:[{scale:_()}],"scale-x":[{"scale-x":_()}],"scale-y":[{"scale-y":_()}],"scale-z":[{"scale-z":_()}],"scale-3d":["scale-3d"],skew:[{skew:ce()}],"skew-x":[{"skew-x":ce()}],"skew-y":[{"skew-y":ce()}],transform:[{transform:[s,d,"","none","gpu","cpu"]}],"transform-origin":[{origin:V()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:Q()}],"translate-x":[{"translate-x":Q()}],"translate-y":[{"translate-y":Q()}],"translate-z":[{"translate-z":Q()}],"translate-none":["translate-none"],zoom:[{zoom:[F,s,d]}],accent:[{accent:n()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:n()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",s,d]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scrollbar-thumb-color":[{"scrollbar-thumb":n()}],"scrollbar-track-color":[{"scrollbar-track":n()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":i()}],"scroll-mx":[{"scroll-mx":i()}],"scroll-my":[{"scroll-my":i()}],"scroll-ms":[{"scroll-ms":i()}],"scroll-me":[{"scroll-me":i()}],"scroll-mbs":[{"scroll-mbs":i()}],"scroll-mbe":[{"scroll-mbe":i()}],"scroll-mt":[{"scroll-mt":i()}],"scroll-mr":[{"scroll-mr":i()}],"scroll-mb":[{"scroll-mb":i()}],"scroll-ml":[{"scroll-ml":i()}],"scroll-p":[{"scroll-p":i()}],"scroll-px":[{"scroll-px":i()}],"scroll-py":[{"scroll-py":i()}],"scroll-ps":[{"scroll-ps":i()}],"scroll-pe":[{"scroll-pe":i()}],"scroll-pbs":[{"scroll-pbs":i()}],"scroll-pbe":[{"scroll-pbe":i()}],"scroll-pt":[{"scroll-pt":i()}],"scroll-pr":[{"scroll-pr":i()}],"scroll-pb":[{"scroll-pb":i()}],"scroll-pl":[{"scroll-pl":i()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",s,d]}],fill:[{fill:["none",...n()]}],"stroke-w":[{stroke:[m,X,H,ze]}],stroke:[{stroke:["none",...n()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{"container-named":["container-type"],overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","inset-bs","inset-be","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pbs","pbe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mbs","mbe","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-bs","border-w-be","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-bs","border-color-be","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mbs","scroll-mbe","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pbs","scroll-pbe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},postfixLookupClassGroups:["container-type"],orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}};var oa=Wa(nt);function oe(...e){return oa(j(e))}import{jsx as pt}from"react/jsx-runtime";var ct=Me("inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3",{variants:{variant:{default:"bg-primary text-primary-foreground [a&]:hover:bg-primary/90",secondary:"bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",destructive:"bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90",outline:"border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",ghost:"[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",link:"text-primary underline-offset-4 [a&]:hover:underline"}},defaultVariants:{variant:"default"}});function le({className:e,variant:t="default",asChild:a=!1,...o}){let l=a?Y.Root:"span";return pt(l,{"data-slot":"badge","data-variant":t,className:oe(ct({variant:t}),e),...o})}import{forwardRef as Lt,createElement as It}from"react";var la=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),re=(...e)=>e.filter((t,a,o)=>!!t&&t.trim()!==""&&o.indexOf(t)===a).join(" ").trim();import{forwardRef as mt,createElement as ua}from"react";var ra={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var da=mt(({color:e="currentColor",size:t=24,strokeWidth:a=2,absoluteStrokeWidth:o,className:l="",children:u,iconNode:r,...c},p)=>ua("svg",{ref:p,...ra,width:t,height:t,stroke:e,strokeWidth:o?Number(a)*24/Number(t):a,className:re("lucide",l),...c},[...r.map(([f,L])=>ua(f,L)),...Array.isArray(u)?u:[u]]));var sa=(e,t)=>{let a=Lt(({className:o,...l},u)=>It(da,{ref:u,iconNode:t,className:re(`lucide-${la(e)}`,o),...l}));return a.displayName=`${e}`,a};var q=sa("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);import{jsx as xt}from"react/jsx-runtime";function ue({className:e,...t}){return xt(q,{role:"status","aria-label":"Loading",className:oe("size-4 animate-spin",e),...t})}import{jsx as xe,jsxs as de}from"react/jsx-runtime";function Ct(){return de("div",{className:"flex items-center gap-4 [--radius:1.2rem]",children:[de(le,{children:[xe(ue,{}),"Syncing"]}),de(le,{variant:"secondary",children:[xe(ue,{}),"Updating"]}),de(le,{variant:"outline",children:[xe(ue,{}),"Processing"]})]})}export{Ct as default};
|
| 2 |
+
/*! Bundled license information:
|
| 3 |
+
|
| 4 |
+
lucide-react/dist/esm/shared/src/utils.js:
|
| 5 |
+
(**
|
| 6 |
+
* @license lucide-react v0.456.0 - ISC
|
| 7 |
+
*
|
| 8 |
+
* This source code is licensed under the ISC license.
|
| 9 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 10 |
+
*)
|
| 11 |
+
|
| 12 |
+
lucide-react/dist/esm/defaultAttributes.js:
|
| 13 |
+
(**
|
| 14 |
+
* @license lucide-react v0.456.0 - ISC
|
| 15 |
+
*
|
| 16 |
+
* This source code is licensed under the ISC license.
|
| 17 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 18 |
+
*)
|
| 19 |
+
|
| 20 |
+
lucide-react/dist/esm/Icon.js:
|
| 21 |
+
(**
|
| 22 |
+
* @license lucide-react v0.456.0 - ISC
|
| 23 |
+
*
|
| 24 |
+
* This source code is licensed under the ISC license.
|
| 25 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 26 |
+
*)
|
| 27 |
+
|
| 28 |
+
lucide-react/dist/esm/createLucideIcon.js:
|
| 29 |
+
(**
|
| 30 |
+
* @license lucide-react v0.456.0 - ISC
|
| 31 |
+
*
|
| 32 |
+
* This source code is licensed under the ISC license.
|
| 33 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 34 |
+
*)
|
| 35 |
+
|
| 36 |
+
lucide-react/dist/esm/icons/loader-circle.js:
|
| 37 |
+
(**
|
| 38 |
+
* @license lucide-react v0.456.0 - ISC
|
| 39 |
+
*
|
| 40 |
+
* This source code is licensed under the ISC license.
|
| 41 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 42 |
+
*)
|
| 43 |
+
|
| 44 |
+
lucide-react/dist/esm/lucide-react.js:
|
| 45 |
+
(**
|
| 46 |
+
* @license lucide-react v0.456.0 - ISC
|
| 47 |
+
*
|
| 48 |
+
* This source code is licensed under the ISC license.
|
| 49 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 50 |
+
*)
|
| 51 |
+
*/
|
b/7e64e42a03aae2b794cc12945866d47f2832b7d36aa68f5b824feb07b99f7c9d
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.example.toggle-group-outline",
|
| 3 |
+
"name": "toggle-group-outline",
|
| 4 |
+
"tier": "example",
|
| 5 |
+
"library": "shadcn",
|
| 6 |
+
"category": "Examples",
|
| 7 |
+
"upstream": "https://ui.shadcn.com/r/styles/new-york-v4/toggle-group-outline.json",
|
| 8 |
+
"did": "did:holo:sha256:ce375cf41a1125f1b6f29eb36eb1a8da6fbfe418e6fd1530dc79e6f22fe4f39d",
|
| 9 |
+
"import": "holo://sha256:f9c0e8226aecbd320fd791f12c298f7ca8d25f908dd81d9913e283d7eadd48bd",
|
| 10 |
+
"integrity": "sha256-+cDoImrsvTIP15HxLCmPfKjSX5CN2B2ZE+KD1+rdSL0=",
|
| 11 |
+
"kappa": "sha256:ce375cf41a1125f1b6f29eb36eb1a8da6fbfe418e6fd1530dc79e6f22fe4f39d",
|
| 12 |
+
"moduleKappa": "sha256:f9c0e8226aecbd320fd791f12c298f7ca8d25f908dd81d9913e283d7eadd48bd",
|
| 13 |
+
"renderExport": "default",
|
| 14 |
+
"source": "registry/new-york-v4/examples/toggle-group-outline.tsx",
|
| 15 |
+
"module": "vendor/components/toggle-group-outline.js",
|
| 16 |
+
"exports": [
|
| 17 |
+
"default"
|
| 18 |
+
],
|
| 19 |
+
"license": "MIT"
|
| 20 |
+
}
|
b/7e8619577045f8535dcbcf93bd8be3c72a4e657de3605709f364a17ccd9d22d9
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Mamba-1 end-to-end test. Build a tiny mamba with random F32 weights, forge ->
|
| 2 |
+
// synthesize -> run forward, and compare logits to an INDEPENDENT float64 reference
|
| 3 |
+
// that reproduces mamba.cpp / mamba-base.cpp build_mamba_layer: RMSNorm -> in_proj
|
| 4 |
+
// split [x|z] -> causal conv1d(+bias,silu) with recurrent conv state -> x_proj
|
| 5 |
+
// (Δt,B,C) -> dt_proj+bias -> selective scan with recurrent ssm state -> D skip ->
|
| 6 |
+
// z-gate(silu) -> out_proj -> residual; no attention, no FFN. A 4-token prompt
|
| 7 |
+
// exercises the recurrent state across positions (conv window fill + scan carry).
|
| 8 |
+
// Plus a structural check against a real mamba header when present.
|
| 9 |
+
|
| 10 |
+
import assert from "node:assert";
|
| 11 |
+
import { existsSync, openSync, readSync, closeSync } from "node:fs";
|
| 12 |
+
import { forgeGguf } from "./gguf-forge.mjs";
|
| 13 |
+
import { synthesizeGraph } from "./gguf-forge-graph.mjs";
|
| 14 |
+
import { forward } from "./gguf-forge-exec.mjs";
|
| 15 |
+
import { GGML } from "./gguf-forge-dequant.mjs";
|
| 16 |
+
import { parseGgufHeader } from "../qvac-ingest.mjs";
|
| 17 |
+
|
| 18 |
+
let pass = 0, fail = 0;
|
| 19 |
+
const t = (name, fn) => { try { fn(); pass++; console.log(" ok " + name); } catch (e) { fail++; console.log("FAIL " + name + "\n " + e.message); } };
|
| 20 |
+
|
| 21 |
+
// ── tiny dims ──
|
| 22 |
+
const D = 8, DI = 16, DS = 4, DC = 4, DT = 3, VOCAB = 5, NL = 2, EPS = 1e-6;
|
| 23 |
+
|
| 24 |
+
function prng(seed) { let s = seed >>> 0; return () => { s = (s * 1664525 + 1013904223) >>> 0; return (s / 4294967296) * 2 - 1; }; }
|
| 25 |
+
const r = prng(99);
|
| 26 |
+
const randF = (n, scale = 0.3) => { const a = new Float32Array(n); for (let i = 0; i < n; i++) a[i] = r() * scale; return a; };
|
| 27 |
+
const normW = (n) => randF(n, 1).map((x) => Math.abs(x) + 0.5);
|
| 28 |
+
|
| 29 |
+
const L = [];
|
| 30 |
+
for (let il = 0; il < NL; il++) L.push({
|
| 31 |
+
attn_norm: normW(D), ssm_in: randF(2 * DI * D), conv1d: randF(DI * DC), conv1d_b: randF(DI),
|
| 32 |
+
ssm_x: randF((DT + 2 * DS) * DI), ssm_dt: randF(DI * DT), ssm_dt_b: randF(DI),
|
| 33 |
+
ssm_a: randF(DS * DI, 1).map((x) => -(Math.abs(x) + 0.1)), ssm_d: randF(DI), ssm_out: randF(D * DI),
|
| 34 |
+
});
|
| 35 |
+
const w = { tok_embd: randF(VOCAB * D), output_norm: normW(D) };
|
| 36 |
+
|
| 37 |
+
function buildGguf(meta, tensors) {
|
| 38 |
+
const ALIGN = 32; let off = 0;
|
| 39 |
+
const infos = tensors.map((t) => { const o = off; off = Math.ceil((o + t.bytes.length) / ALIGN) * ALIGN; return { ...t, offset: o }; });
|
| 40 |
+
let parts = [], len = 0; const push = (b) => { parts.push(b); len += b.length; };
|
| 41 |
+
const u32 = (v) => { const b = new Uint8Array(4); new DataView(b.buffer).setUint32(0, v >>> 0, true); push(b); };
|
| 42 |
+
const f32 = (v) => { const b = new Uint8Array(4); new DataView(b.buffer).setFloat32(0, v, true); push(b); };
|
| 43 |
+
const u64 = (v) => { const b = new Uint8Array(8); const dv = new DataView(b.buffer); dv.setUint32(0, v >>> 0, true); dv.setUint32(4, Math.floor(v / 4294967296), true); push(b); };
|
| 44 |
+
const str = (s) => { const e = new TextEncoder().encode(s); u64(e.length); push(e); };
|
| 45 |
+
push(new TextEncoder().encode("GGUF")); u32(3); u64(tensors.length); u64(Object.keys(meta).length);
|
| 46 |
+
for (const [k, val] of Object.entries(meta)) { str(k); if (typeof val === "string") { u32(8); str(val); } else if (Number.isInteger(val) && val >= 0 && val < 4294967296) { u32(4); u32(val); } else { u32(6); f32(val); } }
|
| 47 |
+
for (const ti of infos) { str(ti.name); u32(ti.dims.length); for (const d of ti.dims) u64(d); u32(ti.type); u64(ti.offset); }
|
| 48 |
+
if (len % ALIGN) push(new Uint8Array(ALIGN - (len % ALIGN)));
|
| 49 |
+
const dataStart = len;
|
| 50 |
+
for (const ti of infos) { while (len < dataStart + ti.offset) push(new Uint8Array(1)); push(ti.bytes); }
|
| 51 |
+
const out = new Uint8Array(len); let o = 0; for (const p of parts) { out.set(p, o); o += p.length; } return out;
|
| 52 |
+
}
|
| 53 |
+
const f32bytes = (arr) => new Uint8Array(arr.buffer.slice(arr.byteOffset, arr.byteOffset + arr.byteLength));
|
| 54 |
+
|
| 55 |
+
const meta = {
|
| 56 |
+
"general.architecture": "mamba", "mamba.block_count": NL, "mamba.embedding_length": D,
|
| 57 |
+
"mamba.ssm.conv_kernel": DC, "mamba.ssm.inner_size": DI, "mamba.ssm.state_size": DS, "mamba.ssm.time_step_rank": DT,
|
| 58 |
+
"mamba.attention.layer_norm_rms_epsilon": EPS,
|
| 59 |
+
};
|
| 60 |
+
const tensors = [["token_embd.weight", [D, VOCAB], w.tok_embd], ["output_norm.weight", [D], w.output_norm]];
|
| 61 |
+
for (let il = 0; il < NL; il++) { const p = `blk.${il}.`, x = L[il]; tensors.push(
|
| 62 |
+
[p + "attn_norm.weight", [D], x.attn_norm], [p + "ssm_in.weight", [D, 2 * DI], x.ssm_in],
|
| 63 |
+
[p + "ssm_conv1d.weight", [DC, DI], x.conv1d], [p + "ssm_conv1d.bias", [DI], x.conv1d_b],
|
| 64 |
+
[p + "ssm_x.weight", [DI, DT + 2 * DS], x.ssm_x], [p + "ssm_dt.weight", [DT, DI], x.ssm_dt], [p + "ssm_dt.bias", [DI], x.ssm_dt_b],
|
| 65 |
+
[p + "ssm_a", [DS, DI], x.ssm_a], [p + "ssm_d", [DI], x.ssm_d], [p + "ssm_out.weight", [DI, D], x.ssm_out]);
|
| 66 |
+
}
|
| 67 |
+
const ggufTensors = tensors.map(([name, dims, arr]) => ({ name, type: GGML.F32, dims, bytes: f32bytes(arr) }));
|
| 68 |
+
|
| 69 |
+
// ── independent float64 reference forward (reproduces build_mamba_layer) ──
|
| 70 |
+
function matvecRef(W, x, K, N) { const y = new Float64Array(N); for (let n = 0; n < N; n++) { let s = 0; for (let k = 0; k < K; k++) s += W[n * K + k] * x[k]; y[n] = s; } return y; }
|
| 71 |
+
function rmsRef(x, wt) { let s = 0; for (const v of x) s += v * v; const sc = 1 / Math.sqrt(s / x.length + EPS); return Array.from(x, (v, i) => v * sc * wt[i]); }
|
| 72 |
+
const siluRef = (v) => v / (1 + Math.exp(-v));
|
| 73 |
+
const softplusRef = (v) => (v > 20 ? v : Math.log1p(Math.exp(v)));
|
| 74 |
+
const addV = (a, b) => a.map((x, i) => x + b[i]);
|
| 75 |
+
|
| 76 |
+
function referenceForward(tokens) {
|
| 77 |
+
const H = tokens.map((tk) => Array.from(w.tok_embd.slice(tk * D, tk * D + D)));
|
| 78 |
+
const convSt = Array.from({ length: NL }, () => new Float64Array(DI * (DC - 1)));
|
| 79 |
+
const ssmSt = Array.from({ length: NL }, () => new Float64Array(DI * DS));
|
| 80 |
+
for (let pos = 0; pos < tokens.length; pos++) {
|
| 81 |
+
let h = H[pos];
|
| 82 |
+
for (let il = 0; il < NL; il++) {
|
| 83 |
+
const x = L[il], cs = convSt[il], ss = ssmSt[il];
|
| 84 |
+
const xn = rmsRef(h, x.attn_norm);
|
| 85 |
+
const xz = matvecRef(x.ssm_in, xn, D, 2 * DI);
|
| 86 |
+
const xin = xz.slice(0, DI), z = xz.slice(DI, 2 * DI);
|
| 87 |
+
// causal conv1d (+bias, silu), slide conv state
|
| 88 |
+
const xc = new Array(DI);
|
| 89 |
+
for (let ch = 0; ch < DI; ch++) {
|
| 90 |
+
const base = ch * (DC - 1), wb = ch * DC; let s = 0;
|
| 91 |
+
for (let k = 0; k < DC - 1; k++) s += cs[base + k] * x.conv1d[wb + k];
|
| 92 |
+
s += xin[ch] * x.conv1d[wb + DC - 1];
|
| 93 |
+
xc[ch] = siluRef(s + x.conv1d_b[ch]);
|
| 94 |
+
for (let k = 0; k < DC - 2; k++) cs[base + k] = cs[base + k + 1];
|
| 95 |
+
cs[base + DC - 2] = xin[ch];
|
| 96 |
+
}
|
| 97 |
+
const xdb = matvecRef(x.ssm_x, xc, DI, DT + 2 * DS);
|
| 98 |
+
const B = xdb.slice(DT, DT + DS), C = xdb.slice(DT + DS, DT + 2 * DS);
|
| 99 |
+
const dt = addV(Array.from(matvecRef(x.ssm_dt, xdb.slice(0, DT), DT, DI)), Array.from(x.ssm_dt_b));
|
| 100 |
+
const y = new Array(DI);
|
| 101 |
+
for (let ch = 0; ch < DI; ch++) {
|
| 102 |
+
const dtsp = softplusRef(dt[ch]), xdt = xc[ch] * dtsp, sb = ch * DS; let acc = 0;
|
| 103 |
+
for (let i0 = 0; i0 < DS; i0++) { const st = ss[sb + i0] * Math.exp(dtsp * x.ssm_a[sb + i0]) + B[i0] * xdt; acc += st * C[i0]; ss[sb + i0] = st; }
|
| 104 |
+
y[ch] = siluRef(z[ch]) * (acc + xc[ch] * x.ssm_d[ch]);
|
| 105 |
+
}
|
| 106 |
+
h = addV(Array.from(matvecRef(x.ssm_out, y, DI, D)), h); // out_proj + residual
|
| 107 |
+
H[pos] = h;
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
const fn = rmsRef(H[tokens.length - 1], w.output_norm);
|
| 111 |
+
return Array.from(matvecRef(w.tok_embd, fn, D, VOCAB)); // tied lm_head
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
const f = forgeGguf(buildGguf(meta, ggufTensors));
|
| 115 |
+
const graph = synthesizeGraph(f.plan);
|
| 116 |
+
const store = { get: (hex) => f.blocks.get(hex) };
|
| 117 |
+
const tokens = [3, 1, 4, 2];
|
| 118 |
+
|
| 119 |
+
t("graph is family=ssm, correct op count + all weights resolve", () => {
|
| 120 |
+
assert.strictEqual(graph.family, "ssm", graph.reason);
|
| 121 |
+
assert.strictEqual(graph.stats.n_layer, NL);
|
| 122 |
+
assert.deepStrictEqual([graph.stats.d_conv, graph.stats.d_inner, graph.stats.d_state, graph.stats.dt_rank], [DC, DI, DS, DT]);
|
| 123 |
+
assert.strictEqual(graph.stats.ops, 3 + 3 * NL); // embd + (norm+mamba+add)*L + result_norm + lm_head
|
| 124 |
+
assert.strictEqual(graph.stats.weightsUsed, tensors.length);
|
| 125 |
+
const hist = {}; for (const o of graph.ops) hist[o.op] = (hist[o.op] || 0) + 1;
|
| 126 |
+
assert.strictEqual(hist.mamba, NL);
|
| 127 |
+
});
|
| 128 |
+
|
| 129 |
+
t("executor logits match independent f64 reference (mamba forward, recurrent state)", () => {
|
| 130 |
+
const got = forward(f.plan, graph, store, tokens), ref = referenceForward(tokens);
|
| 131 |
+
assert.strictEqual(got.length, VOCAB);
|
| 132 |
+
for (let i = 0; i < VOCAB; i++) {
|
| 133 |
+
const rel = Math.abs(got[i] - ref[i]) / (Math.abs(ref[i]) + 1e-4);
|
| 134 |
+
assert.ok(rel < 5e-3, `logit ${i}: got ${got[i]} ref ${ref[i]} rel ${rel}`);
|
| 135 |
+
}
|
| 136 |
+
console.log(` logits: [${Array.from(got).map((x) => x.toFixed(4)).join(", ")}]`);
|
| 137 |
+
});
|
| 138 |
+
|
| 139 |
+
t("argmax (greedy token) matches reference", () => {
|
| 140 |
+
const am = (a) => a.indexOf(Math.max(...a));
|
| 141 |
+
assert.strictEqual(am(Array.from(forward(f.plan, graph, store, tokens))), am(referenceForward(tokens)));
|
| 142 |
+
});
|
| 143 |
+
|
| 144 |
+
t("executor is deterministic", () => {
|
| 145 |
+
const a = forward(f.plan, graph, store, tokens), b = forward(f.plan, graph, store, tokens);
|
| 146 |
+
for (let i = 0; i < VOCAB; i++) assert.strictEqual(a[i], b[i]);
|
| 147 |
+
});
|
| 148 |
+
|
| 149 |
+
// ── structural check against a real mamba header (skipped if absent) ──
|
| 150 |
+
const REALS = [
|
| 151 |
+
"C:/Users/pavel/.lmstudio/models/lmstudio-community/mamba-2.8b-GGUF/mamba-2.8b-Q4_K_M.gguf",
|
| 152 |
+
`${process.env.HOME || ""}/.cache/lm-studio/models/mamba.gguf`,
|
| 153 |
+
];
|
| 154 |
+
t("real mamba header: family=ssm, every tensor resolves, ssm hparams correct", () => {
|
| 155 |
+
const path = REALS.find((p) => existsSync(p));
|
| 156 |
+
if (!path) { console.log(" (skipped — no mamba model present)"); return; }
|
| 157 |
+
const fd = openSync(path, "r"); const buf = Buffer.alloc(64 * 1024 * 1024); readSync(fd, buf, 0, buf.length, 0); closeSync(fd);
|
| 158 |
+
const h = parseGgufHeader(new Uint8Array(buf));
|
| 159 |
+
const plan = { arch: h.meta["general.architecture"], meta: h.meta,
|
| 160 |
+
tensors: h.tensors.map((x) => ({ name: x.name, dims: x.dims, type: x.ggmlType, typeName: String(x.ggmlType), kappa: "sha256:" + "0".repeat(64) })) };
|
| 161 |
+
const g = synthesizeGraph(plan);
|
| 162 |
+
assert.strictEqual(g.family, "ssm", g.reason);
|
| 163 |
+
assert.strictEqual(g.stats.weightsUsed, h.tensors.length, "every tensor referenced");
|
| 164 |
+
console.log(` ${plan.arch}: ${g.stats.n_layer}L d_inner=${g.stats.d_inner} d_state=${g.stats.d_state} d_conv=${g.stats.d_conv}, ${g.stats.weightsUsed}/${h.tensors.length} tensors`);
|
| 165 |
+
});
|
| 166 |
+
|
| 167 |
+
console.log(`\n${pass} passed, ${fail} failed`);
|
| 168 |
+
process.exit(fail ? 1 : 0);
|
b/7eb1c553d98e3051cc249c3cca0f88e6f569becfdf9674316f138f3d10a1dbda
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.example.typography-lead",
|
| 3 |
+
"name": "typography-lead",
|
| 4 |
+
"tier": "example",
|
| 5 |
+
"library": "shadcn",
|
| 6 |
+
"category": "Examples",
|
| 7 |
+
"upstream": "https://ui.shadcn.com/r/styles/new-york-v4/typography-lead.json",
|
| 8 |
+
"did": "did:holo:sha256:1f26283c4d3995918549f577daa45e2ef645f4ebd1a771c2eab6e1dbc18c1c03",
|
| 9 |
+
"import": "holo://sha256:44793260d35c516f523e9628f7271d66788dc56e69a0cd20d0e9aebfa8d7d240",
|
| 10 |
+
"integrity": "sha256-RHkyYNNcUW9SPpYo9ycdZniNxW5poM0g0Omuv6jX0kA=",
|
| 11 |
+
"kappa": "sha256:1f26283c4d3995918549f577daa45e2ef645f4ebd1a771c2eab6e1dbc18c1c03",
|
| 12 |
+
"moduleKappa": "sha256:44793260d35c516f523e9628f7271d66788dc56e69a0cd20d0e9aebfa8d7d240",
|
| 13 |
+
"renderExport": "default",
|
| 14 |
+
"source": "registry/new-york-v4/examples/typography-lead.tsx",
|
| 15 |
+
"module": "vendor/components/typography-lead.js",
|
| 16 |
+
"exports": [
|
| 17 |
+
"default"
|
| 18 |
+
],
|
| 19 |
+
"license": "MIT"
|
| 20 |
+
}
|
b/7ebcefa0db306029a6037f2cf631157bc1d6fc18dc9f7275800b8485aaf87af5
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// holo-voice-wake.mjs — W0: "Hey Q" wake word, built on the STREAMING EAR's partials (no separate KWS model, no
|
| 2 |
+
// download — the wake faculty IS the ear, so it's on-device + private by construction). Watches each rolling
|
| 3 |
+
// partial for the wake phrase, matched PHONETICALLY (the ASR renders "hey q" as "hey cue"/"hey queue"/"hey kew"),
|
| 4 |
+
// fires ONCE per utterance, strips the phrase, and hands the TRAILING command straight to the conversation — so
|
| 5 |
+
// "Hey Q, what's the weather?" is one breath, never "say it twice".
|
| 6 |
+
//
|
| 7 |
+
// Pure + DOM-free; onWake injected. The phrase is just text, so ANY wake word works with no model swap.
|
| 8 |
+
|
| 9 |
+
// tokenize keeping ORIGINAL tokens (casing/apostrophes for the downstream command) aligned 1:1 with a normalized
|
| 10 |
+
// form used only for matching — so the trailing command is returned verbatim ("what's the weather?", not "what s …").
|
| 11 |
+
function tokenize(text) {
|
| 12 |
+
const orig = String(text || "").trim().split(/\s+/).filter(Boolean);
|
| 13 |
+
const n = orig.map((w) => w.toLowerCase().replace(/[^a-z0-9']/g, ""));
|
| 14 |
+
return { orig, n };
|
| 15 |
+
}
|
| 16 |
+
const editDist = (a, b) => { const m = a.length, n = b.length, d = Array.from({ length: m + 1 }, (_, i) => [i, ...Array(n).fill(0)]); for (let j = 0; j <= n; j++) d[0][j] = j; for (let i = 1; i <= m; i++) for (let j = 1; j <= n; j++) d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)); return d[m][n]; };
|
| 17 |
+
|
| 18 |
+
// homophone variants for the short keywords the ASR most often mangles (single letters / names). The default
|
| 19 |
+
// covers "hey q"; a custom phrase can pass its own `variants` (per-word arrays) or just rely on edit distance.
|
| 20 |
+
const DEFAULT_VARIANTS = {
|
| 21 |
+
q: ["q", "cue", "queue", "kew", "kyu", "cu", "kue", "qu"],
|
| 22 |
+
hey: ["hey", "hay", "hi", "ay"],
|
| 23 |
+
ok: ["ok", "okay"],
|
| 24 |
+
computer: ["computer"],
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
function wordMatches(phraseWord, heard, variants) {
|
| 28 |
+
if (heard === phraseWord) return true;
|
| 29 |
+
const v = (variants && variants[phraseWord]) || DEFAULT_VARIANTS[phraseWord];
|
| 30 |
+
if (v && v.includes(heard)) return true;
|
| 31 |
+
return editDist(heard, phraseWord) <= Math.floor(phraseWord.length * 0.34); // tolerant for longer words only
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// makeWakeWord({ phrase, variants, onWake, cooldownMs, scanLead }) → { observe(partialText, atMs), reset(), armed() }
|
| 35 |
+
// phrase : the wake phrase, e.g. "hey q" (text — any phrase, no model).
|
| 36 |
+
// variants : optional { word: [forms] } overrides/extends the homophone map.
|
| 37 |
+
// onWake : ({ at, tail }) — fired ONCE when the phrase is heard; `tail` = the command after the phrase.
|
| 38 |
+
// cooldownMs : ignore a re-fire within this window after a turn (debounce the growing-partial repeats / turn tail).
|
| 39 |
+
// scanLead : allow the phrase to start within the first N words (leading "um"/"ok" filler). Default 2.
|
| 40 |
+
export function makeWakeWord({ phrase = "hey q", variants = null, onWake = () => {}, cooldownMs = 1500, scanLead = 2 } = {}) {
|
| 41 |
+
const pw = tokenize(phrase).n; const P = pw.length;
|
| 42 |
+
let fired = false, lastWakeAt = -1e9;
|
| 43 |
+
|
| 44 |
+
// match the phrase starting at index `i` (over normalized tokens `n`); return the ORIGINAL tail after it, or null.
|
| 45 |
+
function matchAt(orig, n, i) {
|
| 46 |
+
if (i + P > n.length) return null;
|
| 47 |
+
for (let k = 0; k < P; k++) if (!wordMatches(pw[k], n[i + k], variants)) return null;
|
| 48 |
+
return orig.slice(i + P).join(" ");
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
function observe(text, atMs = 0) {
|
| 52 |
+
const { orig, n } = tokenize(text);
|
| 53 |
+
if (fired) { // already armed: keep returning the growing command tail
|
| 54 |
+
for (let i = 0; i <= Math.min(scanLead, n.length - P); i++) { const tail = matchAt(orig, n, i); if (tail != null) return { woke: false, armed: true, tail }; }
|
| 55 |
+
return { woke: false, armed: true, tail: orig.join(" ") };
|
| 56 |
+
}
|
| 57 |
+
if (atMs - lastWakeAt < cooldownMs) return { woke: false, armed: false }; // debounce
|
| 58 |
+
for (let i = 0; i <= Math.min(scanLead, Math.max(0, n.length - P)); i++) {
|
| 59 |
+
const tail = matchAt(orig, n, i);
|
| 60 |
+
if (tail != null) { fired = true; lastWakeAt = atMs; onWake({ at: atMs, tail }); return { woke: true, armed: true, tail }; }
|
| 61 |
+
}
|
| 62 |
+
return { woke: false, armed: false };
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
return { observe, reset() { fired = false; }, armed: () => fired };
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// makeEchoSafeWake — W2: wrap a wake detector so Q can NEVER wake itself. While Q is speaking, its own TTS leaks
|
| 69 |
+
// into the mic and the ear transcribes it — if Q's response happens to contain the wake phrase, that must NOT
|
| 70 |
+
// self-wake. Gate: while speaking, only forward a partial to the wake detector when the mic energy passes the
|
| 71 |
+
// echo threshold (a genuine user talking OVER Q — the same gate barge-in uses). Q's own echo is below it → no
|
| 72 |
+
// self-wake. A real user over the top wakes (and the barge path stops Q). Off-speech, the wake detector is normal.
|
| 73 |
+
// observe(partialText, { micLevel, qSpeaking, qOutputLevel, atMs }) → { woke, armed?, tail?, suppressed? }
|
| 74 |
+
export function makeEchoSafeWake({ wake, bargeFloor = 0.05, bargeEcho = 0.4, echoGuard = null } = {}) {
|
| 75 |
+
if (!wake) throw new Error("makeEchoSafeWake needs a wake (makeWakeWord)");
|
| 76 |
+
const isEcho = echoGuard || ((micLevel, qOutputLevel) => micLevel < Math.max(bargeFloor, (qOutputLevel || 0) * bargeEcho));
|
| 77 |
+
function observe(text, ctx = {}) {
|
| 78 |
+
if (ctx.qSpeaking && isEcho(ctx.micLevel == null ? 1 : ctx.micLevel, ctx.qOutputLevel)) return { woke: false, suppressed: true };
|
| 79 |
+
return wake.observe(text, ctx.atMs || 0);
|
| 80 |
+
}
|
| 81 |
+
return { observe, reset: () => wake.reset(), armed: () => wake.armed() };
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
export default { makeWakeWord, makeEchoSafeWake };
|
b/7ee16de3c3d73e5301f3c8f8f4eff9e5a934a95962ac68cb6a46bd10d38e7102
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
function xe(e){var t,o,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var i=e.length;for(t=0;t<i;t++)e[t]&&(o=xe(e[t]))&&(r&&(r+=" "),r+=o)}else for(o in e)e[o]&&(r&&(r+=" "),r+=o);return r}function K(){for(var e,t,o=0,r="",i=arguments.length;o<i;o++)(e=arguments[o])&&(t=xe(e))&&(r&&(r+=" "),r+=t);return r}var ye=e=>typeof e=="boolean"?`${e}`:e===0?"0":e,ke=K,we=(e,t)=>o=>{var r;if(t?.variants==null)return ke(e,o?.class,o?.className);let{variants:i,defaultVariants:m}=t,l=Object.keys(i).map(c=>{let b=o?.[c],g=m?.[c];if(b===null)return null;let z=ye(b)||ye(g);return i[c][z]}),u=o&&Object.entries(o).reduce((c,b)=>{let[g,z]=b;return z===void 0||(c[g]=z),c},{}),f=t==null||(r=t.compoundVariants)===null||r===void 0?void 0:r.reduce((c,b)=>{let{class:g,className:z,...S}=b;return Object.entries(S).every(T=>{let[y,k]=T;return Array.isArray(k)?k.includes({...m,...u}[y]):{...m,...u}[y]===k})?[...c,g,z]:c},[]);return ke(e,l,f,o?.class,o?.className)};var $e=(e,t)=>{let o=new Array(e.length+t.length);for(let r=0;r<e.length;r++)o[r]=e[r];for(let r=0;r<t.length;r++)o[e.length+r]=t[r];return o},Ue=(e,t)=>({classGroupId:e,validator:t}),Pe=(e=new Map,t=null,o)=>({nextPart:e,validators:t,classGroupId:o}),ee="-",ve=[],De="arbitrary..",Ye=e=>{let t=Xe(e),{conflictingClassGroups:o,conflictingClassGroupModifiers:r}=e;return{getClassGroupId:l=>{if(l.startsWith("[")&&l.endsWith("]"))return qe(l);let u=l.split(ee),f=u[0]===""&&u.length>1?1:0;return Me(u,f,t)},getConflictingClassGroupIds:(l,u)=>{if(u){let f=r[l],c=o[l];return f?c?$e(c,f):f:c||ve}return o[l]||ve}}},Me=(e,t,o)=>{if(e.length-t===0)return o.classGroupId;let i=e[t],m=o.nextPart.get(i);if(m){let c=Me(e,t+1,m);if(c)return c}let l=o.validators;if(l===null)return;let u=t===0?e.join(ee):e.slice(t).join(ee),f=l.length;for(let c=0;c<f;c++){let b=l[c];if(b.validator(u))return b.classGroupId}},qe=e=>e.slice(1,-1).indexOf(":")===-1?void 0:(()=>{let t=e.slice(1,-1),o=t.indexOf(":"),r=t.slice(0,o);return r?De+r:void 0})(),Xe=e=>{let{theme:t,classGroups:o}=e;return He(o,t)},He=(e,t)=>{let o=Pe();for(let r in e){let i=e[r];le(i,o,r,t)}return o},le=(e,t,o,r)=>{let i=e.length;for(let m=0;m<i;m++){let l=e[m];Je(l,t,o,r)}},Je=(e,t,o,r)=>{if(typeof e=="string"){Ke(e,t,o);return}if(typeof e=="function"){Qe(e,t,o,r);return}Ze(e,t,o,r)},Ke=(e,t,o)=>{let r=e===""?t:Re(t,e);r.classGroupId=o},Qe=(e,t,o,r)=>{if(eo(e)){le(e(r),t,o,r);return}t.validators===null&&(t.validators=[]),t.validators.push(Ue(o,e))},Ze=(e,t,o,r)=>{let i=Object.entries(e),m=i.length;for(let l=0;l<m;l++){let[u,f]=i[l];le(f,Re(t,u),o,r)}},Re=(e,t)=>{let o=e,r=t.split(ee),i=r.length;for(let m=0;m<i;m++){let l=r[m],u=o.nextPart.get(l);u||(u=Pe(),o.nextPart.set(l,u)),o=u}return o},eo=e=>"isThemeGetter"in e&&e.isThemeGetter===!0,oo=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,o=Object.create(null),r=Object.create(null),i=(m,l)=>{o[m]=l,t++,t>e&&(t=0,r=o,o=Object.create(null))};return{get(m){let l=o[m];if(l!==void 0)return l;if((l=r[m])!==void 0)return i(m,l),l},set(m,l){m in o?o[m]=l:i(m,l)}}},ie="!",ze=":",to=[],Ce=(e,t,o,r,i)=>({modifiers:e,hasImportantModifier:t,baseClassName:o,maybePostfixModifierPosition:r,isExternal:i}),ro=e=>{let{prefix:t,experimentalParseClassName:o}=e,r=i=>{let m=[],l=0,u=0,f=0,c,b=i.length;for(let y=0;y<b;y++){let k=i[y];if(l===0&&u===0){if(k===ze){m.push(i.slice(f,y)),f=y+1;continue}if(k==="/"){c=y;continue}}k==="["?l++:k==="]"?l--:k==="("?u++:k===")"&&u--}let g=m.length===0?i:i.slice(f),z=g,S=!1;g.endsWith(ie)?(z=g.slice(0,-1),S=!0):g.startsWith(ie)&&(z=g.slice(1),S=!0);let T=c&&c>f?c-f:void 0;return Ce(m,S,z,T)};if(t){let i=t+ze,m=r;r=l=>l.startsWith(i)?m(l.slice(i.length)):Ce(to,!1,l,void 0,!0)}if(o){let i=r;r=m=>o({className:m,parseClassName:i})}return r},so=e=>{let t=new Map;return e.orderSensitiveModifiers.forEach((o,r)=>{t.set(o,1e6+r)}),o=>{let r=[],i=[];for(let m=0;m<o.length;m++){let l=o[m],u=l[0]==="[",f=t.has(l);u||f?(i.length>0&&(i.sort(),r.push(...i),i=[]),r.push(l)):i.push(l)}return i.length>0&&(i.sort(),r.push(...i)),r}},no=e=>({cache:oo(e.cacheSize),parseClassName:ro(e),sortModifiers:so(e),postfixLookupClassGroupIds:ao(e),...Ye(e)}),ao=e=>{let t=Object.create(null),o=e.postfixLookupClassGroups;if(o)for(let r=0;r<o.length;r++)t[o[r]]=!0;return t},io=/\s+/,lo=(e,t)=>{let{parseClassName:o,getClassGroupId:r,getConflictingClassGroupIds:i,sortModifiers:m,postfixLookupClassGroupIds:l}=t,u=[],f=e.trim().split(io),c="";for(let b=f.length-1;b>=0;b-=1){let g=f[b],{isExternal:z,modifiers:S,hasImportantModifier:T,baseClassName:y,maybePostfixModifierPosition:k}=o(g);if(z){c=g+(c.length>0?" "+c:c);continue}let V=!!k,C;if(V){let M=y.substring(0,k);C=r(M);let a=C&&l[C]?r(y):void 0;a&&a!==C&&(C=a,V=!1)}else C=r(y);if(!C){if(!V){c=g+(c.length>0?" "+c:c);continue}if(C=r(y),!C){c=g+(c.length>0?" "+c:c);continue}V=!1}let U=S.length===0?"":S.length===1?S[0]:m(S).join(":"),_=T?U+ie:U,W=_+C;if(u.indexOf(W)>-1)continue;u.push(W);let F=i(C,V);for(let M=0;M<F.length;++M){let a=F[M];u.push(_+a)}c=g+(c.length>0?" "+c:c)}return c},co=(...e)=>{let t=0,o,r,i="";for(;t<e.length;)(o=e[t++])&&(r=Ie(o))&&(i&&(i+=" "),i+=r);return i},Ie=e=>{if(typeof e=="string")return e;let t,o="";for(let r=0;r<e.length;r++)e[r]&&(t=Ie(e[r]))&&(o&&(o+=" "),o+=t);return o},mo=(e,...t)=>{let o,r,i,m,l=f=>{let c=t.reduce((b,g)=>g(b),e());return o=no(c),r=o.cache.get,i=o.cache.set,m=u,u(f)},u=f=>{let c=r(f);if(c)return c;let b=lo(f,o);return i(f,b),b};return m=l,(...f)=>m(co(...f))},po=[],h=e=>{let t=o=>o[e]||po;return t.isThemeGetter=!0,t},Ne=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Te=/^\((?:(\w[\w-]*):)?(.+)\)$/i,uo=/^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/,fo=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,bo=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,go=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,ho=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,xo=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,I=e=>uo.test(e),p=e=>!!e&&!Number.isNaN(Number(e)),P=e=>!!e&&Number.isInteger(Number(e)),ae=e=>e.endsWith("%")&&p(e.slice(0,-1)),R=e=>fo.test(e),Ve=()=>!0,yo=e=>bo.test(e)&&!go.test(e),ce=()=>!1,ko=e=>ho.test(e),wo=e=>xo.test(e),vo=e=>!s(e)&&!n(e),zo=e=>e.startsWith("@container")&&(e[10]==="/"&&e[11]!==void 0||e[11]==="s"&&e[16]!==void 0&&e.startsWith("-size/",10)||e[11]==="n"&&e[18]!==void 0&&e.startsWith("-normal/",10)),Co=e=>N(e,je,ce),s=e=>Ne.test(e),E=e=>N(e,Oe,yo),Ae=e=>N(e,No,p),Ao=e=>N(e,We,Ve),So=e=>N(e,_e,ce),Se=e=>N(e,Le,ce),Go=e=>N(e,Ee,wo),Q=e=>N(e,Fe,ko),n=e=>Te.test(e),D=e=>j(e,Oe),Po=e=>j(e,_e),Ge=e=>j(e,Le),Mo=e=>j(e,je),Ro=e=>j(e,Ee),Z=e=>j(e,Fe,!0),Io=e=>j(e,We,!0),N=(e,t,o)=>{let r=Ne.exec(e);return r?r[1]?t(r[1]):o(r[2]):!1},j=(e,t,o=!1)=>{let r=Te.exec(e);return r?r[1]?t(r[1]):o:!1},Le=e=>e==="position"||e==="percentage",Ee=e=>e==="image"||e==="url",je=e=>e==="length"||e==="size"||e==="bg-size",Oe=e=>e==="length",No=e=>e==="number",_e=e=>e==="family-name",We=e=>e==="number"||e==="weight",Fe=e=>e==="shadow";var To=()=>{let e=h("color"),t=h("font"),o=h("text"),r=h("font-weight"),i=h("tracking"),m=h("leading"),l=h("breakpoint"),u=h("container"),f=h("spacing"),c=h("radius"),b=h("shadow"),g=h("inset-shadow"),z=h("text-shadow"),S=h("drop-shadow"),T=h("blur"),y=h("perspective"),k=h("aspect"),V=h("ease"),C=h("animate"),U=()=>["auto","avoid","all","avoid-page","page","left","right","column"],_=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],W=()=>[..._(),n,s],F=()=>["auto","hidden","clip","visible","scroll"],M=()=>["auto","contain","none"],a=()=>[n,s,f],A=()=>[I,"full","auto",...a()],de=()=>[P,"none","subgrid",n,s],me=()=>["auto",{span:["full",P,n,s]},P,n,s],Y=()=>[P,"auto",n,s],pe=()=>["auto","min","max","fr",n,s],oe=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],B=()=>["start","end","center","stretch","center-safe","end-safe"],G=()=>["auto",...a()],L=()=>[I,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...a()],te=()=>[I,"screen","full","dvw","lvw","svw","min","max","fit",...a()],re=()=>[I,"screen","full","lh","dvh","lvh","svh","min","max","fit",...a()],d=()=>[e,n,s],ue=()=>[..._(),Ge,Se,{position:[n,s]}],fe=()=>["no-repeat",{repeat:["","x","y","space","round"]}],be=()=>["auto","cover","contain",Mo,Co,{size:[n,s]}],se=()=>[ae,D,E],w=()=>["","none","full",c,n,s],v=()=>["",p,D,E],q=()=>["solid","dashed","dotted","double"],ge=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],x=()=>[p,ae,Ge,Se],he=()=>["","none",T,n,s],X=()=>["none",p,n,s],H=()=>["none",p,n,s],ne=()=>[p,n,s],J=()=>[I,"full",...a()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[R],breakpoint:[R],color:[Ve],container:[R],"drop-shadow":[R],ease:["in","out","in-out"],font:[vo],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[R],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[R],shadow:[R],spacing:["px",p],text:[R],"text-shadow":[R],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",I,s,n,k]}],container:["container"],"container-type":[{"@container":["","normal","size",n,s]}],"container-named":[zo],columns:[{columns:[p,s,n,u]}],"break-after":[{"break-after":U()}],"break-before":[{"break-before":U()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:W()}],overflow:[{overflow:F()}],"overflow-x":[{"overflow-x":F()}],"overflow-y":[{"overflow-y":F()}],overscroll:[{overscroll:M()}],"overscroll-x":[{"overscroll-x":M()}],"overscroll-y":[{"overscroll-y":M()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:A()}],"inset-x":[{"inset-x":A()}],"inset-y":[{"inset-y":A()}],start:[{"inset-s":A(),start:A()}],end:[{"inset-e":A(),end:A()}],"inset-bs":[{"inset-bs":A()}],"inset-be":[{"inset-be":A()}],top:[{top:A()}],right:[{right:A()}],bottom:[{bottom:A()}],left:[{left:A()}],visibility:["visible","invisible","collapse"],z:[{z:[P,"auto",n,s]}],basis:[{basis:[I,"full","auto",u,...a()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[p,I,"auto","initial","none",s]}],grow:[{grow:["",p,n,s]}],shrink:[{shrink:["",p,n,s]}],order:[{order:[P,"first","last","none",n,s]}],"grid-cols":[{"grid-cols":de()}],"col-start-end":[{col:me()}],"col-start":[{"col-start":Y()}],"col-end":[{"col-end":Y()}],"grid-rows":[{"grid-rows":de()}],"row-start-end":[{row:me()}],"row-start":[{"row-start":Y()}],"row-end":[{"row-end":Y()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":pe()}],"auto-rows":[{"auto-rows":pe()}],gap:[{gap:a()}],"gap-x":[{"gap-x":a()}],"gap-y":[{"gap-y":a()}],"justify-content":[{justify:[...oe(),"normal"]}],"justify-items":[{"justify-items":[...B(),"normal"]}],"justify-self":[{"justify-self":["auto",...B()]}],"align-content":[{content:["normal",...oe()]}],"align-items":[{items:[...B(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...B(),{baseline:["","last"]}]}],"place-content":[{"place-content":oe()}],"place-items":[{"place-items":[...B(),"baseline"]}],"place-self":[{"place-self":["auto",...B()]}],p:[{p:a()}],px:[{px:a()}],py:[{py:a()}],ps:[{ps:a()}],pe:[{pe:a()}],pbs:[{pbs:a()}],pbe:[{pbe:a()}],pt:[{pt:a()}],pr:[{pr:a()}],pb:[{pb:a()}],pl:[{pl:a()}],m:[{m:G()}],mx:[{mx:G()}],my:[{my:G()}],ms:[{ms:G()}],me:[{me:G()}],mbs:[{mbs:G()}],mbe:[{mbe:G()}],mt:[{mt:G()}],mr:[{mr:G()}],mb:[{mb:G()}],ml:[{ml:G()}],"space-x":[{"space-x":a()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":a()}],"space-y-reverse":["space-y-reverse"],size:[{size:L()}],"inline-size":[{inline:["auto",...te()]}],"min-inline-size":[{"min-inline":["auto",...te()]}],"max-inline-size":[{"max-inline":["none",...te()]}],"block-size":[{block:["auto",...re()]}],"min-block-size":[{"min-block":["auto",...re()]}],"max-block-size":[{"max-block":["none",...re()]}],w:[{w:[u,"screen",...L()]}],"min-w":[{"min-w":[u,"screen","none",...L()]}],"max-w":[{"max-w":[u,"screen","none","prose",{screen:[l]},...L()]}],h:[{h:["screen","lh",...L()]}],"min-h":[{"min-h":["screen","lh","none",...L()]}],"max-h":[{"max-h":["screen","lh",...L()]}],"font-size":[{text:["base",o,D,E]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[r,Io,Ao]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",ae,s]}],"font-family":[{font:[Po,So,t]}],"font-features":[{"font-features":[s]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[i,n,s]}],"line-clamp":[{"line-clamp":[p,"none",n,Ae]}],leading:[{leading:[m,...a()]}],"list-image":[{"list-image":["none",n,s]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",n,s]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:d()}],"text-color":[{text:d()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...q(),"wavy"]}],"text-decoration-thickness":[{decoration:[p,"from-font","auto",n,E]}],"text-decoration-color":[{decoration:d()}],"underline-offset":[{"underline-offset":[p,"auto",n,s]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:a()}],"tab-size":[{tab:[P,n,s]}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",n,s]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",n,s]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:ue()}],"bg-repeat":[{bg:fe()}],"bg-size":[{bg:be()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},P,n,s],radial:["",n,s],conic:[P,n,s]},Ro,Go]}],"bg-color":[{bg:d()}],"gradient-from-pos":[{from:se()}],"gradient-via-pos":[{via:se()}],"gradient-to-pos":[{to:se()}],"gradient-from":[{from:d()}],"gradient-via":[{via:d()}],"gradient-to":[{to:d()}],rounded:[{rounded:w()}],"rounded-s":[{"rounded-s":w()}],"rounded-e":[{"rounded-e":w()}],"rounded-t":[{"rounded-t":w()}],"rounded-r":[{"rounded-r":w()}],"rounded-b":[{"rounded-b":w()}],"rounded-l":[{"rounded-l":w()}],"rounded-ss":[{"rounded-ss":w()}],"rounded-se":[{"rounded-se":w()}],"rounded-ee":[{"rounded-ee":w()}],"rounded-es":[{"rounded-es":w()}],"rounded-tl":[{"rounded-tl":w()}],"rounded-tr":[{"rounded-tr":w()}],"rounded-br":[{"rounded-br":w()}],"rounded-bl":[{"rounded-bl":w()}],"border-w":[{border:v()}],"border-w-x":[{"border-x":v()}],"border-w-y":[{"border-y":v()}],"border-w-s":[{"border-s":v()}],"border-w-e":[{"border-e":v()}],"border-w-bs":[{"border-bs":v()}],"border-w-be":[{"border-be":v()}],"border-w-t":[{"border-t":v()}],"border-w-r":[{"border-r":v()}],"border-w-b":[{"border-b":v()}],"border-w-l":[{"border-l":v()}],"divide-x":[{"divide-x":v()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":v()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...q(),"hidden","none"]}],"divide-style":[{divide:[...q(),"hidden","none"]}],"border-color":[{border:d()}],"border-color-x":[{"border-x":d()}],"border-color-y":[{"border-y":d()}],"border-color-s":[{"border-s":d()}],"border-color-e":[{"border-e":d()}],"border-color-bs":[{"border-bs":d()}],"border-color-be":[{"border-be":d()}],"border-color-t":[{"border-t":d()}],"border-color-r":[{"border-r":d()}],"border-color-b":[{"border-b":d()}],"border-color-l":[{"border-l":d()}],"divide-color":[{divide:d()}],"outline-style":[{outline:[...q(),"none","hidden"]}],"outline-offset":[{"outline-offset":[p,n,s]}],"outline-w":[{outline:["",p,D,E]}],"outline-color":[{outline:d()}],shadow:[{shadow:["","none",b,Z,Q]}],"shadow-color":[{shadow:d()}],"inset-shadow":[{"inset-shadow":["none",g,Z,Q]}],"inset-shadow-color":[{"inset-shadow":d()}],"ring-w":[{ring:v()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:d()}],"ring-offset-w":[{"ring-offset":[p,E]}],"ring-offset-color":[{"ring-offset":d()}],"inset-ring-w":[{"inset-ring":v()}],"inset-ring-color":[{"inset-ring":d()}],"text-shadow":[{"text-shadow":["none",z,Z,Q]}],"text-shadow-color":[{"text-shadow":d()}],opacity:[{opacity:[p,n,s]}],"mix-blend":[{"mix-blend":[...ge(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":ge()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[p]}],"mask-image-linear-from-pos":[{"mask-linear-from":x()}],"mask-image-linear-to-pos":[{"mask-linear-to":x()}],"mask-image-linear-from-color":[{"mask-linear-from":d()}],"mask-image-linear-to-color":[{"mask-linear-to":d()}],"mask-image-t-from-pos":[{"mask-t-from":x()}],"mask-image-t-to-pos":[{"mask-t-to":x()}],"mask-image-t-from-color":[{"mask-t-from":d()}],"mask-image-t-to-color":[{"mask-t-to":d()}],"mask-image-r-from-pos":[{"mask-r-from":x()}],"mask-image-r-to-pos":[{"mask-r-to":x()}],"mask-image-r-from-color":[{"mask-r-from":d()}],"mask-image-r-to-color":[{"mask-r-to":d()}],"mask-image-b-from-pos":[{"mask-b-from":x()}],"mask-image-b-to-pos":[{"mask-b-to":x()}],"mask-image-b-from-color":[{"mask-b-from":d()}],"mask-image-b-to-color":[{"mask-b-to":d()}],"mask-image-l-from-pos":[{"mask-l-from":x()}],"mask-image-l-to-pos":[{"mask-l-to":x()}],"mask-image-l-from-color":[{"mask-l-from":d()}],"mask-image-l-to-color":[{"mask-l-to":d()}],"mask-image-x-from-pos":[{"mask-x-from":x()}],"mask-image-x-to-pos":[{"mask-x-to":x()}],"mask-image-x-from-color":[{"mask-x-from":d()}],"mask-image-x-to-color":[{"mask-x-to":d()}],"mask-image-y-from-pos":[{"mask-y-from":x()}],"mask-image-y-to-pos":[{"mask-y-to":x()}],"mask-image-y-from-color":[{"mask-y-from":d()}],"mask-image-y-to-color":[{"mask-y-to":d()}],"mask-image-radial":[{"mask-radial":[n,s]}],"mask-image-radial-from-pos":[{"mask-radial-from":x()}],"mask-image-radial-to-pos":[{"mask-radial-to":x()}],"mask-image-radial-from-color":[{"mask-radial-from":d()}],"mask-image-radial-to-color":[{"mask-radial-to":d()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":_()}],"mask-image-conic-pos":[{"mask-conic":[p]}],"mask-image-conic-from-pos":[{"mask-conic-from":x()}],"mask-image-conic-to-pos":[{"mask-conic-to":x()}],"mask-image-conic-from-color":[{"mask-conic-from":d()}],"mask-image-conic-to-color":[{"mask-conic-to":d()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:ue()}],"mask-repeat":[{mask:fe()}],"mask-size":[{mask:be()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",n,s]}],filter:[{filter:["","none",n,s]}],blur:[{blur:he()}],brightness:[{brightness:[p,n,s]}],contrast:[{contrast:[p,n,s]}],"drop-shadow":[{"drop-shadow":["","none",S,Z,Q]}],"drop-shadow-color":[{"drop-shadow":d()}],grayscale:[{grayscale:["",p,n,s]}],"hue-rotate":[{"hue-rotate":[p,n,s]}],invert:[{invert:["",p,n,s]}],saturate:[{saturate:[p,n,s]}],sepia:[{sepia:["",p,n,s]}],"backdrop-filter":[{"backdrop-filter":["","none",n,s]}],"backdrop-blur":[{"backdrop-blur":he()}],"backdrop-brightness":[{"backdrop-brightness":[p,n,s]}],"backdrop-contrast":[{"backdrop-contrast":[p,n,s]}],"backdrop-grayscale":[{"backdrop-grayscale":["",p,n,s]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[p,n,s]}],"backdrop-invert":[{"backdrop-invert":["",p,n,s]}],"backdrop-opacity":[{"backdrop-opacity":[p,n,s]}],"backdrop-saturate":[{"backdrop-saturate":[p,n,s]}],"backdrop-sepia":[{"backdrop-sepia":["",p,n,s]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":a()}],"border-spacing-x":[{"border-spacing-x":a()}],"border-spacing-y":[{"border-spacing-y":a()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",n,s]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[p,"initial",n,s]}],ease:[{ease:["linear","initial",V,n,s]}],delay:[{delay:[p,n,s]}],animate:[{animate:["none",C,n,s]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[y,n,s]}],"perspective-origin":[{"perspective-origin":W()}],rotate:[{rotate:X()}],"rotate-x":[{"rotate-x":X()}],"rotate-y":[{"rotate-y":X()}],"rotate-z":[{"rotate-z":X()}],scale:[{scale:H()}],"scale-x":[{"scale-x":H()}],"scale-y":[{"scale-y":H()}],"scale-z":[{"scale-z":H()}],"scale-3d":["scale-3d"],skew:[{skew:ne()}],"skew-x":[{"skew-x":ne()}],"skew-y":[{"skew-y":ne()}],transform:[{transform:[n,s,"","none","gpu","cpu"]}],"transform-origin":[{origin:W()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:J()}],"translate-x":[{"translate-x":J()}],"translate-y":[{"translate-y":J()}],"translate-z":[{"translate-z":J()}],"translate-none":["translate-none"],zoom:[{zoom:[P,n,s]}],accent:[{accent:d()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:d()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",n,s]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scrollbar-thumb-color":[{"scrollbar-thumb":d()}],"scrollbar-track-color":[{"scrollbar-track":d()}],"scrollbar-gutter":[{"scrollbar-gutter":["auto","stable","both"]}],"scrollbar-w":[{scrollbar:["auto","thin","none"]}],"scroll-m":[{"scroll-m":a()}],"scroll-mx":[{"scroll-mx":a()}],"scroll-my":[{"scroll-my":a()}],"scroll-ms":[{"scroll-ms":a()}],"scroll-me":[{"scroll-me":a()}],"scroll-mbs":[{"scroll-mbs":a()}],"scroll-mbe":[{"scroll-mbe":a()}],"scroll-mt":[{"scroll-mt":a()}],"scroll-mr":[{"scroll-mr":a()}],"scroll-mb":[{"scroll-mb":a()}],"scroll-ml":[{"scroll-ml":a()}],"scroll-p":[{"scroll-p":a()}],"scroll-px":[{"scroll-px":a()}],"scroll-py":[{"scroll-py":a()}],"scroll-ps":[{"scroll-ps":a()}],"scroll-pe":[{"scroll-pe":a()}],"scroll-pbs":[{"scroll-pbs":a()}],"scroll-pbe":[{"scroll-pbe":a()}],"scroll-pt":[{"scroll-pt":a()}],"scroll-pr":[{"scroll-pr":a()}],"scroll-pb":[{"scroll-pb":a()}],"scroll-pl":[{"scroll-pl":a()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",n,s]}],fill:[{fill:["none",...d()]}],"stroke-w":[{stroke:[p,D,E,Ae]}],stroke:[{stroke:["none",...d()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{"container-named":["container-type"],overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","inset-bs","inset-be","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pbs","pbe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mbs","mbe","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-bs","border-w-be","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-bs","border-color-be","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mbs","scroll-mbe","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pbs","scroll-pbe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},postfixLookupClassGroups:["container-type"],orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}};var Be=mo(To);function O(...e){return Be(K(e))}import{jsx as $}from"react/jsx-runtime";function Uo({className:e,...t}){return $("div",{"data-slot":"empty",className:O("flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12",e),...t})}function Do({className:e,...t}){return $("div",{"data-slot":"empty-header",className:O("flex max-w-sm flex-col items-center gap-2 text-center",e),...t})}var Vo=we("mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",{variants:{variant:{default:"bg-transparent",icon:"flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-6"}},defaultVariants:{variant:"default"}});function Yo({className:e,variant:t="default",...o}){return $("div",{"data-slot":"empty-icon","data-variant":t,className:O(Vo({variant:t,className:e})),...o})}function qo({className:e,...t}){return $("div",{"data-slot":"empty-title",className:O("text-lg font-medium tracking-tight",e),...t})}function Xo({className:e,...t}){return $("div",{"data-slot":"empty-description",className:O("text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",e),...t})}function Ho({className:e,...t}){return $("div",{"data-slot":"empty-content",className:O("flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance",e),...t})}export{Uo as Empty,Ho as EmptyContent,Xo as EmptyDescription,Do as EmptyHeader,Yo as EmptyMedia,qo as EmptyTitle};
|
b/7ef7c27c5e1302f62fb0d4dca0988546bc6600abb18d7313c2076fb9b1bdcb5e
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// holo-parakeet-ear.mjs — production adapter exposing the κ-native Parakeet-TDT-0.6B streaming ASR to Q's voice
|
| 2 |
+
// stack, conforming EXACTLY to the holo-voice-asr.mjs knativeEar seam (so holo-voice-asr drives it unchanged):
|
| 3 |
+
// createWhisperEar({ holoUrl, upgradeUrl, kappa, release, upgradeKappa, upgradeRelease, language, … })
|
| 4 |
+
// → { load(progressCb), transcribe(pcm16k, opts) -> { text, … }, info() }
|
| 5 |
+
// Mirrors holo-moonshine-ear.mjs. The encoder weights stream from the encoder .holo BY κ (streamHolo: Range →
|
| 6 |
+
// release → κ-route → OPFS), the decoder (joint) streams from the joint .holo BY κ, decode is κ-native pure-JS.
|
| 7 |
+
// The mel front-end (nemo128) is the one external piece (onnxruntime-web) and is injected as `toFeatures`.
|
| 8 |
+
//
|
| 9 |
+
// EXTRA knativeEar fields this ear understands (passed through cfg.knativeEar in holo-voice.js):
|
| 10 |
+
// jointUrl/jointKappa/jointRelease — the joint .holo (defaults beside holoUrl)
|
| 11 |
+
// rescaleUrl/rescaleBinUrl/vocabUrl — the small encoder rescale + SentencePiece vocab (default beside holoUrl)
|
| 12 |
+
// toFeatures(pcm) -> { features, T } — mel+stem front-end; until wired, transcribe(audio) throws and
|
| 13 |
+
// holo-voice-asr's own fallback path (Moonshine/Whisper) handles audio.
|
| 14 |
+
//
|
| 15 |
+
// `deps` (last arg) is injectable for headless witnessing: { openStream, fetchBytes, hasWebGPU }. Production
|
| 16 |
+
// defaults: openStream=streamHolo, fetchBytes=fetch→bytes, hasWebGPU=navigator.gpu probe.
|
| 17 |
+
import { streamHolo } from "./holo-whisper-stream.mjs";
|
| 18 |
+
import { createParakeetASR } from "./holo-parakeet-asr.mjs";
|
| 19 |
+
import { makeMelStemFrontend } from "./holo-parakeet-frontend.mjs";
|
| 20 |
+
import { createParakeetStream } from "./holo-parakeet-stream.mjs";
|
| 21 |
+
import { makeEndpoint } from "./holo-voice-endpoint.mjs";
|
| 22 |
+
|
| 23 |
+
// a trivial content-addressed memo for the default endpoint (identical partial text ⇒ no re-predict). Production
|
| 24 |
+
// can inject the real O(1) holo-compute-memo + turn-detector via cfg.endpoint instead.
|
| 25 |
+
const trivialMemo = () => ({ _c: new Map(), async compute(tag, key, fn) { const k = tag + "|" + key; if (this._c.has(k)) return { bytes: this._c.get(k), hit: true }; const b = await fn(); this._c.set(k, b); return { bytes: b, hit: false }; } });
|
| 26 |
+
|
| 27 |
+
const dirOf = (u) => { const i = String(u).lastIndexOf("/"); return i >= 0 ? String(u).slice(0, i + 1) : ""; };
|
| 28 |
+
|
| 29 |
+
async function defaultFetchBytes(url) { const r = await fetch(url); if (!r.ok) throw new Error("fetch " + url + " " + r.status); return new Uint8Array(await r.arrayBuffer()); }
|
| 30 |
+
async function defaultHasWebGPU() { try { return !!(globalThis.navigator?.gpu && (await navigator.gpu.requestAdapter())); } catch (e) { return false; } }
|
| 31 |
+
|
| 32 |
+
export function createWhisperEar(cfg = {}, deps = {}) {
|
| 33 |
+
const openStream = deps.openStream || ((url, o) => streamHolo(url, o));
|
| 34 |
+
const fetchBytes = deps.fetchBytes || defaultFetchBytes;
|
| 35 |
+
const hasWebGPU = deps.hasWebGPU || defaultHasWebGPU;
|
| 36 |
+
const base = dirOf(cfg.holoUrl || "");
|
| 37 |
+
const jointUrl = cfg.jointUrl || (base + "parakeet-tdt-0.6b-v2-joint.holo");
|
| 38 |
+
const rescaleUrl = cfg.rescaleUrl || (base + "parakeet-encoder-rescale.json");
|
| 39 |
+
const rescaleBinUrl = cfg.rescaleBinUrl || (base + "parakeet-encoder-rescale.bin");
|
| 40 |
+
const vocabUrl = cfg.vocabUrl || (base + "parakeet-vocab.txt");
|
| 41 |
+
const nemoUrl = ("nemoUrl" in cfg) ? cfg.nemoUrl : (base + "parakeet-nemo128.onnx"); // null disables the mel+stem front-end
|
| 42 |
+
let asr = null, tier = "0.6b", backend = "cpu", ready = false;
|
| 43 |
+
|
| 44 |
+
return {
|
| 45 |
+
async load(progress) {
|
| 46 |
+
const webgpu = await hasWebGPU();
|
| 47 |
+
backend = webgpu ? "gpu" : "cpu"; // GPU path = the proven WGSL encoder; CPU = headless/fallback
|
| 48 |
+
const encoderStream = await openStream(cfg.holoUrl, { kappa: cfg.kappa, release: cfg.release || "" });
|
| 49 |
+
const jointStream = await openStream(jointUrl, { kappa: cfg.jointKappa, release: cfg.jointRelease || "" });
|
| 50 |
+
const rescale = JSON.parse(new TextDecoder().decode(await fetchBytes(rescaleUrl)));
|
| 51 |
+
const rescaleBin = await fetchBytes(rescaleBinUrl);
|
| 52 |
+
const vocab = new TextDecoder().decode(await fetchBytes(vocabUrl)).split("\n").map((l) => l.replace(/\s+\d+$/, ""));
|
| 53 |
+
// audio front-end (mel+stem). Injected toFeatures wins; else build mel(nemo128, ort-web) → κ-native stem
|
| 54 |
+
// (the stem κs live in the encoder .holo, so reuse encoderStream.getBody). The stem is validated to the
|
| 55 |
+
// real pre_encode output (cosine 0.9987). ort-web is the one external runtime; mel is the labeled piece.
|
| 56 |
+
let toFeatures = cfg.toFeatures || deps.toFeatures || null;
|
| 57 |
+
if (!toFeatures && nemoUrl) {
|
| 58 |
+
try { toFeatures = makeMelStemFrontend({ getWeight: (k) => encoderStream.getBody(k), rescale, rescaleBin, nemoUrl, ort: deps.ort || null, backend }); }
|
| 59 |
+
catch (e) { try { console.warn("[parakeet ear] mel+stem front-end unavailable:", e && e.message || e); } catch (_) {} }
|
| 60 |
+
}
|
| 61 |
+
asr = await createParakeetASR({ encoderStream, jointStream, rescale, rescaleBin, vocab, toFeatures, backend });
|
| 62 |
+
ready = true;
|
| 63 |
+
try { progress && progress({ phase: "ready", engine: "parakeet-κ", backend, tier }); } catch (e) {}
|
| 64 |
+
return true;
|
| 65 |
+
},
|
| 66 |
+
// knativeEar contract: transcribe(pcm) → { text, … }. Full audio path needs the mel+stem front-end.
|
| 67 |
+
async transcribe(audio, opts = {}) {
|
| 68 |
+
if (!asr) await this.load();
|
| 69 |
+
const r = await asr.transcribeAudio(audio, opts); // throws if toFeatures (mel+stem) not wired
|
| 70 |
+
return { text: r.text, ids: r.ids, ms: r.ms, tier, backend };
|
| 71 |
+
},
|
| 72 |
+
// direct features path (the κ-native core, no mel front-end) — used by witnesses + callers that already have
|
| 73 |
+
// acoustic features. transcribe(features[T*1024], T) → { text, … }.
|
| 74 |
+
async transcribeFeatures(features, T) { if (!asr) await this.load(); const r = await asr.transcribe(features, T); return { text: r.text, ids: r.ids, ms: r.ms, tier, backend }; },
|
| 75 |
+
|
| 76 |
+
// STREAMING surface (Arc B): live mic → growing EXACT partials → instant final on MEANING. feed(pcm,atMs) as
|
| 77 |
+
// audio arrives, poll(atMs) on a timer, end() at the VAD/turn boundary. The semantic endpoint (injected
|
| 78 |
+
// cfg.endpoint, or a default heuristic one) fires ~120ms after the utterance reads done and vetoes mid-thought.
|
| 79 |
+
// The heavy work happens DURING speech; the final reuses the last partial ⇒ ~0ms perceived after you stop.
|
| 80 |
+
stream({ onPartial = () => {}, onFinal = () => {}, endpoint = null, cadenceMs = 500 } = {}) {
|
| 81 |
+
const ep = endpoint || cfg.endpoint || makeEndpoint({ predict: async () => null, memo: trivialMemo(), earlyMs: 120, floorMs: 550 });
|
| 82 |
+
return createParakeetStream({ transcribe: async (pcm) => { if (!asr) await this.load(); return asr.transcribeAudio(pcm); }, endpoint: ep, onPartial, onFinal, cadenceMs });
|
| 83 |
+
},
|
| 84 |
+
info: () => ({ engine: "parakeet-κ", ready, backend, tier, holoUrl: cfg.holoUrl, jointUrl, kappa: cfg.kappa }),
|
| 85 |
+
};
|
| 86 |
+
}
|
| 87 |
+
export default createWhisperEar;
|
b/7f0e7ae2d260d288634152afa17778c566dd011c50242aca93db24da4990e45a
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default {".dock":{"@layer daisyui.l1.l2.l3":{"position":"fixed","right":"calc(0.25rem * 0)","bottom":"calc(0.25rem * 0)","left":"calc(0.25rem * 0)","z-index":1,"display":"flex","width":"100%","flex-direction":"row","align-items":"center","justify-content":"space-around","background-color":"var(--color-base-100)","padding":"calc(0.25rem * 2)","color":"currentcolor","border-top":"0.5px solid color-mix(in oklab, var(--color-base-content) 5%, #0000)","height":["4rem","calc(4rem + env(safe-area-inset-bottom))"],"padding-bottom":"env(safe-area-inset-bottom)","> *":{"position":"relative","margin-bottom":"calc(0.25rem * 2)","display":"flex","height":"100%","max-width":"calc(0.25rem * 32)","flex-shrink":1,"flex-basis":"100%","cursor":"pointer","flex-direction":"column","align-items":"center","justify-content":"center","gap":"1px","border-radius":"var(--radius-box)","background-color":"transparent","transition":"opacity 0.2s ease-out","@media (hover: hover)":{"&:hover":{"opacity":"80%"}},"&[aria-disabled=\"true\"], &[disabled]":{"&, &:hover":{"pointer-events":"none","color":"color-mix(in oklab, var(--color-base-content) 10%, transparent)","opacity":"100%"}},".dock-label":{"font-size":"0.6875rem"},"&:after":{"content":"\"\"","position":"absolute","height":"calc(0.25rem * 1)","width":"calc(0.25rem * 6)","border-radius":"calc(infinity * 1px)","background-color":"transparent","bottom":"0.2rem","border-top":"3px solid transparent","transition":"background-color 0.1s ease-out, text-color 0.1s ease-out, width 0.1s ease-out"}}}},".dock-active":{"@layer daisyui.l1.l2":{"&:after":{"width":"calc(0.25rem * 10)","background-color":"currentcolor","color":"currentcolor"}}},".dock-xs":{"@layer daisyui.l1.l2":{"height":["3rem","calc(3rem + env(safe-area-inset-bottom))"],".dock-active":{"&:after":{"bottom":"-0.1rem"}},".dock-label":{"font-size":"0.625rem"}}},".dock-sm":{"@layer daisyui.l1.l2":{"height":["calc(0.25rem * 14)","3.5rem","calc(3.5rem + env(safe-area-inset-bottom))"],".dock-active":{"&:after":{"bottom":"-0.1rem"}},".dock-label":{"font-size":"0.625rem"}}},".dock-md":{"@layer daisyui.l1.l2":{"height":["4rem","calc(4rem + env(safe-area-inset-bottom))"],".dock-label":{"font-size":"0.6875rem"}}},".dock-lg":{"@layer daisyui.l1.l2":{"height":["4.5rem","calc(4.5rem + env(safe-area-inset-bottom))"],".dock-active":{"&:after":{"bottom":"0.4rem"}},".dock-label":{"font-size":"0.6875rem"}}},".dock-xl":{"@layer daisyui.l1.l2":{"height":["5rem","calc(5rem + env(safe-area-inset-bottom))"],".dock-active":{"&:after":{"bottom":"0.4rem"}},".dock-label":{"font-size":"0.75rem"}}}};
|
b/7f156a842f39b67c777393add8fcb4e4d6f4a48f60dad200886f201f51abe68c
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client"
|
| 2 |
+
|
| 3 |
+
import { useState } from "react"
|
| 4 |
+
|
| 5 |
+
import {
|
| 6 |
+
Field,
|
| 7 |
+
FieldDescription,
|
| 8 |
+
FieldTitle,
|
| 9 |
+
} from "@/registry/new-york-v4/ui/field"
|
| 10 |
+
import { Slider } from "@/registry/new-york-v4/ui/slider"
|
| 11 |
+
|
| 12 |
+
export default function FieldSlider() {
|
| 13 |
+
const [value, setValue] = useState([200, 800])
|
| 14 |
+
return (
|
| 15 |
+
<div className="w-full max-w-md">
|
| 16 |
+
<Field>
|
| 17 |
+
<FieldTitle>Price Range</FieldTitle>
|
| 18 |
+
<FieldDescription>
|
| 19 |
+
Set your budget range ($
|
| 20 |
+
<span className="font-medium tabular-nums">{value[0]}</span> -{" "}
|
| 21 |
+
<span className="font-medium tabular-nums">{value[1]}</span>).
|
| 22 |
+
</FieldDescription>
|
| 23 |
+
<Slider
|
| 24 |
+
value={value}
|
| 25 |
+
onValueChange={setValue}
|
| 26 |
+
max={1000}
|
| 27 |
+
min={0}
|
| 28 |
+
step={10}
|
| 29 |
+
className="mt-2 w-full"
|
| 30 |
+
aria-label="Price Range"
|
| 31 |
+
/>
|
| 32 |
+
</Field>
|
| 33 |
+
</div>
|
| 34 |
+
)
|
| 35 |
+
}
|
b/7f3399686bd8522e467759a93261b3c3b19332caf6a242eedc333ce9a5ce1889
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from "react"
|
| 2 |
+
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui"
|
| 3 |
+
|
| 4 |
+
import { cn } from "@/lib/utils"
|
| 5 |
+
|
| 6 |
+
function ScrollArea({
|
| 7 |
+
className,
|
| 8 |
+
children,
|
| 9 |
+
...props
|
| 10 |
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
| 11 |
+
return (
|
| 12 |
+
<ScrollAreaPrimitive.Root
|
| 13 |
+
data-slot="scroll-area"
|
| 14 |
+
className={cn("relative", className)}
|
| 15 |
+
{...props}
|
| 16 |
+
>
|
| 17 |
+
<ScrollAreaPrimitive.Viewport
|
| 18 |
+
data-slot="scroll-area-viewport"
|
| 19 |
+
className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
|
| 20 |
+
>
|
| 21 |
+
{children}
|
| 22 |
+
</ScrollAreaPrimitive.Viewport>
|
| 23 |
+
<ScrollBar />
|
| 24 |
+
<ScrollAreaPrimitive.Corner />
|
| 25 |
+
</ScrollAreaPrimitive.Root>
|
| 26 |
+
)
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
function ScrollBar({
|
| 30 |
+
className,
|
| 31 |
+
orientation = "vertical",
|
| 32 |
+
...props
|
| 33 |
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
| 34 |
+
return (
|
| 35 |
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
| 36 |
+
data-slot="scroll-area-scrollbar"
|
| 37 |
+
orientation={orientation}
|
| 38 |
+
className={cn(
|
| 39 |
+
"flex touch-none p-px transition-colors select-none",
|
| 40 |
+
orientation === "vertical" &&
|
| 41 |
+
"h-full w-2.5 border-l border-l-transparent",
|
| 42 |
+
orientation === "horizontal" &&
|
| 43 |
+
"h-2.5 flex-col border-t border-t-transparent",
|
| 44 |
+
className
|
| 45 |
+
)}
|
| 46 |
+
{...props}
|
| 47 |
+
>
|
| 48 |
+
<ScrollAreaPrimitive.ScrollAreaThumb
|
| 49 |
+
data-slot="scroll-area-thumb"
|
| 50 |
+
className="relative flex-1 rounded-full bg-border"
|
| 51 |
+
/>
|
| 52 |
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
| 53 |
+
)
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
export { ScrollArea, ScrollBar }
|
b/7f5f9102ebee5f45184b8d79389490682cdf2a1c38b33a771c924f9444f28ae3
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client"
|
| 2 |
+
|
| 3 |
+
import * as React from "react"
|
| 4 |
+
import { CartesianGrid, Line, LineChart, XAxis } from "recharts"
|
| 5 |
+
|
| 6 |
+
import {
|
| 7 |
+
Card,
|
| 8 |
+
CardContent,
|
| 9 |
+
CardDescription,
|
| 10 |
+
CardHeader,
|
| 11 |
+
CardTitle,
|
| 12 |
+
} from "@/registry/new-york-v4/ui/card"
|
| 13 |
+
import {
|
| 14 |
+
ChartContainer,
|
| 15 |
+
ChartTooltip,
|
| 16 |
+
ChartTooltipContent,
|
| 17 |
+
type ChartConfig,
|
| 18 |
+
} from "@/registry/new-york-v4/ui/chart"
|
| 19 |
+
|
| 20 |
+
export const description = "An interactive line chart"
|
| 21 |
+
|
| 22 |
+
const chartData = [
|
| 23 |
+
{ date: "2024-04-01", desktop: 222, mobile: 150 },
|
| 24 |
+
{ date: "2024-04-02", desktop: 97, mobile: 180 },
|
| 25 |
+
{ date: "2024-04-03", desktop: 167, mobile: 120 },
|
| 26 |
+
{ date: "2024-04-04", desktop: 242, mobile: 260 },
|
| 27 |
+
{ date: "2024-04-05", desktop: 373, mobile: 290 },
|
| 28 |
+
{ date: "2024-04-06", desktop: 301, mobile: 340 },
|
| 29 |
+
{ date: "2024-04-07", desktop: 245, mobile: 180 },
|
| 30 |
+
{ date: "2024-04-08", desktop: 409, mobile: 320 },
|
| 31 |
+
{ date: "2024-04-09", desktop: 59, mobile: 110 },
|
| 32 |
+
{ date: "2024-04-10", desktop: 261, mobile: 190 },
|
| 33 |
+
{ date: "2024-04-11", desktop: 327, mobile: 350 },
|
| 34 |
+
{ date: "2024-04-12", desktop: 292, mobile: 210 },
|
| 35 |
+
{ date: "2024-04-13", desktop: 342, mobile: 380 },
|
| 36 |
+
{ date: "2024-04-14", desktop: 137, mobile: 220 },
|
| 37 |
+
{ date: "2024-04-15", desktop: 120, mobile: 170 },
|
| 38 |
+
{ date: "2024-04-16", desktop: 138, mobile: 190 },
|
| 39 |
+
{ date: "2024-04-17", desktop: 446, mobile: 360 },
|
| 40 |
+
{ date: "2024-04-18", desktop: 364, mobile: 410 },
|
| 41 |
+
{ date: "2024-04-19", desktop: 243, mobile: 180 },
|
| 42 |
+
{ date: "2024-04-20", desktop: 89, mobile: 150 },
|
| 43 |
+
{ date: "2024-04-21", desktop: 137, mobile: 200 },
|
| 44 |
+
{ date: "2024-04-22", desktop: 224, mobile: 170 },
|
| 45 |
+
{ date: "2024-04-23", desktop: 138, mobile: 230 },
|
| 46 |
+
{ date: "2024-04-24", desktop: 387, mobile: 290 },
|
| 47 |
+
{ date: "2024-04-25", desktop: 215, mobile: 250 },
|
| 48 |
+
{ date: "2024-04-26", desktop: 75, mobile: 130 },
|
| 49 |
+
{ date: "2024-04-27", desktop: 383, mobile: 420 },
|
| 50 |
+
{ date: "2024-04-28", desktop: 122, mobile: 180 },
|
| 51 |
+
{ date: "2024-04-29", desktop: 315, mobile: 240 },
|
| 52 |
+
{ date: "2024-04-30", desktop: 454, mobile: 380 },
|
| 53 |
+
{ date: "2024-05-01", desktop: 165, mobile: 220 },
|
| 54 |
+
{ date: "2024-05-02", desktop: 293, mobile: 310 },
|
| 55 |
+
{ date: "2024-05-03", desktop: 247, mobile: 190 },
|
| 56 |
+
{ date: "2024-05-04", desktop: 385, mobile: 420 },
|
| 57 |
+
{ date: "2024-05-05", desktop: 481, mobile: 390 },
|
| 58 |
+
{ date: "2024-05-06", desktop: 498, mobile: 520 },
|
| 59 |
+
{ date: "2024-05-07", desktop: 388, mobile: 300 },
|
| 60 |
+
{ date: "2024-05-08", desktop: 149, mobile: 210 },
|
| 61 |
+
{ date: "2024-05-09", desktop: 227, mobile: 180 },
|
| 62 |
+
{ date: "2024-05-10", desktop: 293, mobile: 330 },
|
| 63 |
+
{ date: "2024-05-11", desktop: 335, mobile: 270 },
|
| 64 |
+
{ date: "2024-05-12", desktop: 197, mobile: 240 },
|
| 65 |
+
{ date: "2024-05-13", desktop: 197, mobile: 160 },
|
| 66 |
+
{ date: "2024-05-14", desktop: 448, mobile: 490 },
|
| 67 |
+
{ date: "2024-05-15", desktop: 473, mobile: 380 },
|
| 68 |
+
{ date: "2024-05-16", desktop: 338, mobile: 400 },
|
| 69 |
+
{ date: "2024-05-17", desktop: 499, mobile: 420 },
|
| 70 |
+
{ date: "2024-05-18", desktop: 315, mobile: 350 },
|
| 71 |
+
{ date: "2024-05-19", desktop: 235, mobile: 180 },
|
| 72 |
+
{ date: "2024-05-20", desktop: 177, mobile: 230 },
|
| 73 |
+
{ date: "2024-05-21", desktop: 82, mobile: 140 },
|
| 74 |
+
{ date: "2024-05-22", desktop: 81, mobile: 120 },
|
| 75 |
+
{ date: "2024-05-23", desktop: 252, mobile: 290 },
|
| 76 |
+
{ date: "2024-05-24", desktop: 294, mobile: 220 },
|
| 77 |
+
{ date: "2024-05-25", desktop: 201, mobile: 250 },
|
| 78 |
+
{ date: "2024-05-26", desktop: 213, mobile: 170 },
|
| 79 |
+
{ date: "2024-05-27", desktop: 420, mobile: 460 },
|
| 80 |
+
{ date: "2024-05-28", desktop: 233, mobile: 190 },
|
| 81 |
+
{ date: "2024-05-29", desktop: 78, mobile: 130 },
|
| 82 |
+
{ date: "2024-05-30", desktop: 340, mobile: 280 },
|
| 83 |
+
{ date: "2024-05-31", desktop: 178, mobile: 230 },
|
| 84 |
+
{ date: "2024-06-01", desktop: 178, mobile: 200 },
|
| 85 |
+
{ date: "2024-06-02", desktop: 470, mobile: 410 },
|
| 86 |
+
{ date: "2024-06-03", desktop: 103, mobile: 160 },
|
| 87 |
+
{ date: "2024-06-04", desktop: 439, mobile: 380 },
|
| 88 |
+
{ date: "2024-06-05", desktop: 88, mobile: 140 },
|
| 89 |
+
{ date: "2024-06-06", desktop: 294, mobile: 250 },
|
| 90 |
+
{ date: "2024-06-07", desktop: 323, mobile: 370 },
|
| 91 |
+
{ date: "2024-06-08", desktop: 385, mobile: 320 },
|
| 92 |
+
{ date: "2024-06-09", desktop: 438, mobile: 480 },
|
| 93 |
+
{ date: "2024-06-10", desktop: 155, mobile: 200 },
|
| 94 |
+
{ date: "2024-06-11", desktop: 92, mobile: 150 },
|
| 95 |
+
{ date: "2024-06-12", desktop: 492, mobile: 420 },
|
| 96 |
+
{ date: "2024-06-13", desktop: 81, mobile: 130 },
|
| 97 |
+
{ date: "2024-06-14", desktop: 426, mobile: 380 },
|
| 98 |
+
{ date: "2024-06-15", desktop: 307, mobile: 350 },
|
| 99 |
+
{ date: "2024-06-16", desktop: 371, mobile: 310 },
|
| 100 |
+
{ date: "2024-06-17", desktop: 475, mobile: 520 },
|
| 101 |
+
{ date: "2024-06-18", desktop: 107, mobile: 170 },
|
| 102 |
+
{ date: "2024-06-19", desktop: 341, mobile: 290 },
|
| 103 |
+
{ date: "2024-06-20", desktop: 408, mobile: 450 },
|
| 104 |
+
{ date: "2024-06-21", desktop: 169, mobile: 210 },
|
| 105 |
+
{ date: "2024-06-22", desktop: 317, mobile: 270 },
|
| 106 |
+
{ date: "2024-06-23", desktop: 480, mobile: 530 },
|
| 107 |
+
{ date: "2024-06-24", desktop: 132, mobile: 180 },
|
| 108 |
+
{ date: "2024-06-25", desktop: 141, mobile: 190 },
|
| 109 |
+
{ date: "2024-06-26", desktop: 434, mobile: 380 },
|
| 110 |
+
{ date: "2024-06-27", desktop: 448, mobile: 490 },
|
| 111 |
+
{ date: "2024-06-28", desktop: 149, mobile: 200 },
|
| 112 |
+
{ date: "2024-06-29", desktop: 103, mobile: 160 },
|
| 113 |
+
{ date: "2024-06-30", desktop: 446, mobile: 400 },
|
| 114 |
+
]
|
| 115 |
+
|
| 116 |
+
const chartConfig = {
|
| 117 |
+
views: {
|
| 118 |
+
label: "Page Views",
|
| 119 |
+
},
|
| 120 |
+
desktop: {
|
| 121 |
+
label: "Desktop",
|
| 122 |
+
color: "var(--chart-1)",
|
| 123 |
+
},
|
| 124 |
+
mobile: {
|
| 125 |
+
label: "Mobile",
|
| 126 |
+
color: "var(--chart-2)",
|
| 127 |
+
},
|
| 128 |
+
} satisfies ChartConfig
|
| 129 |
+
|
| 130 |
+
export function ChartLineInteractive() {
|
| 131 |
+
const [activeChart, setActiveChart] =
|
| 132 |
+
React.useState<keyof typeof chartConfig>("desktop")
|
| 133 |
+
|
| 134 |
+
const total = React.useMemo(
|
| 135 |
+
() => ({
|
| 136 |
+
desktop: chartData.reduce((acc, curr) => acc + curr.desktop, 0),
|
| 137 |
+
mobile: chartData.reduce((acc, curr) => acc + curr.mobile, 0),
|
| 138 |
+
}),
|
| 139 |
+
[]
|
| 140 |
+
)
|
| 141 |
+
|
| 142 |
+
return (
|
| 143 |
+
<Card className="py-4 sm:py-0">
|
| 144 |
+
<CardHeader className="flex flex-col items-stretch border-b p-0! sm:flex-row">
|
| 145 |
+
<div className="flex flex-1 flex-col justify-center gap-1 px-6 pb-3 sm:pb-0">
|
| 146 |
+
<CardTitle>Line Chart - Interactive</CardTitle>
|
| 147 |
+
<CardDescription>
|
| 148 |
+
Showing total visitors for the last 3 months
|
| 149 |
+
</CardDescription>
|
| 150 |
+
</div>
|
| 151 |
+
<div className="flex">
|
| 152 |
+
{["desktop", "mobile"].map((key) => {
|
| 153 |
+
const chart = key as keyof typeof chartConfig
|
| 154 |
+
return (
|
| 155 |
+
<button
|
| 156 |
+
key={chart}
|
| 157 |
+
data-active={activeChart === chart}
|
| 158 |
+
className="flex flex-1 flex-col justify-center gap-1 border-t px-6 py-4 text-left even:border-l data-[active=true]:bg-muted/50 sm:border-t-0 sm:border-l sm:px-8 sm:py-6"
|
| 159 |
+
onClick={() => setActiveChart(chart)}
|
| 160 |
+
>
|
| 161 |
+
<span className="text-xs text-muted-foreground">
|
| 162 |
+
{chartConfig[chart].label}
|
| 163 |
+
</span>
|
| 164 |
+
<span className="text-lg leading-none font-bold sm:text-3xl">
|
| 165 |
+
{total[key as keyof typeof total].toLocaleString()}
|
| 166 |
+
</span>
|
| 167 |
+
</button>
|
| 168 |
+
)
|
| 169 |
+
})}
|
| 170 |
+
</div>
|
| 171 |
+
</CardHeader>
|
| 172 |
+
<CardContent className="px-2 sm:p-6">
|
| 173 |
+
<ChartContainer
|
| 174 |
+
config={chartConfig}
|
| 175 |
+
className="aspect-auto h-[250px] w-full"
|
| 176 |
+
>
|
| 177 |
+
<LineChart
|
| 178 |
+
accessibilityLayer
|
| 179 |
+
data={chartData}
|
| 180 |
+
margin={{
|
| 181 |
+
left: 12,
|
| 182 |
+
right: 12,
|
| 183 |
+
}}
|
| 184 |
+
>
|
| 185 |
+
<CartesianGrid vertical={false} />
|
| 186 |
+
<XAxis
|
| 187 |
+
dataKey="date"
|
| 188 |
+
tickLine={false}
|
| 189 |
+
axisLine={false}
|
| 190 |
+
tickMargin={8}
|
| 191 |
+
minTickGap={32}
|
| 192 |
+
tickFormatter={(value) => {
|
| 193 |
+
const date = new Date(value)
|
| 194 |
+
return date.toLocaleDateString("en-US", {
|
| 195 |
+
month: "short",
|
| 196 |
+
day: "numeric",
|
| 197 |
+
})
|
| 198 |
+
}}
|
| 199 |
+
/>
|
| 200 |
+
<ChartTooltip
|
| 201 |
+
content={
|
| 202 |
+
<ChartTooltipContent
|
| 203 |
+
className="w-[150px]"
|
| 204 |
+
nameKey="views"
|
| 205 |
+
labelFormatter={(value) => {
|
| 206 |
+
return new Date(value).toLocaleDateString("en-US", {
|
| 207 |
+
month: "short",
|
| 208 |
+
day: "numeric",
|
| 209 |
+
year: "numeric",
|
| 210 |
+
})
|
| 211 |
+
}}
|
| 212 |
+
/>
|
| 213 |
+
}
|
| 214 |
+
/>
|
| 215 |
+
<Line
|
| 216 |
+
dataKey={activeChart}
|
| 217 |
+
type="monotone"
|
| 218 |
+
stroke={`var(--color-${activeChart})`}
|
| 219 |
+
strokeWidth={2}
|
| 220 |
+
dot={false}
|
| 221 |
+
/>
|
| 222 |
+
</LineChart>
|
| 223 |
+
</ChartContainer>
|
| 224 |
+
</CardContent>
|
| 225 |
+
</Card>
|
| 226 |
+
)
|
| 227 |
+
}
|
b/7f942a10f50e561c4bba8d3c124cb9f5c79bf7cfeca73df5c5034c86f1f5bf66
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
export default {".cally":{"@layer daisyui.l1.l2.l3":{"font-size":"0.7rem","&::part(container)":{"padding":"0.5rem 1rem","user-select":"none"},"::part(th)":{"font-weight":"normal","block-size":"auto"},"&::part(header)":{"direction":"ltr"},"::part(head)":{"opacity":0.5,"font-size":"0.7rem"},"&::part(button)":{"border-radius":"var(--radius-field)","border":"none","padding":"0.5rem","background":"#0000"},"&::part(button):hover":{"background":"var(--color-base-200)"},"::part(day)":{"border-radius":"var(--radius-field)","font-size":"0.7rem"},"::part(day):hover":{"&:not(selected, today)":{"background":"var(--color-base-200)"}},"::part(button day today)":{"background":"var(--color-primary)","color":"var(--color-primary-content)"},"::part(selected)":{"color":"var(--color-base-100)","background":"var(--color-base-content)","border-radius":"var(--radius-field)"},"::part(range-inner)":{"border-radius":"0"},"::part(range-start)":{"border-start-end-radius":"0","border-end-end-radius":"0"},"::part(range-end)":{"border-start-start-radius":"0","border-end-start-radius":"0"},"::part(range-start range-end)":{"border-radius":"var(--radius-field)"},"calendar-month":{"width":"100%"}}},".react-day-picker":{"@layer daisyui.l1.l2.l3":{"user-select":"none","background-color":"var(--color-base-100)","border-radius":"var(--radius-box)","border":"var(--border) solid var(--color-base-200)","font-size":"0.75rem","display":"inline-block","position":"relative","overflow":"clip","&[dir=\"rtl\"]":{".rdp-nav":{".rdp-chevron":{"transform-origin":"50%","transform":"rotate(180deg)"}}},"*":{"box-sizing":"border-box"},".rdp-day":{"width":"2.25rem","height":"2.25rem","text-align":"center"},".rdp-day_button":{"cursor":"pointer","font":"inherit","color":"inherit","width":"2.25rem","height":"2.25rem","border":"2px solid #0000","border-radius":"var(--radius-field)","background":"0 0","justify-content":"center","align-items":"center","margin":"0","padding":"0","display":"flex","&:disabled":{"cursor":"revert"},"&:hover":{"background-color":"var(--color-base-200)"},"&:disabled:hover, &[aria-disabled=\"true\"]:hover":{"background-color":"transparent","cursor":"not-allowed"}},".rdp-caption_label":{"z-index":1,"white-space":"nowrap","border":"0","align-items":"center","display":"inline-flex","position":"relative"},".rdp-button_next":{"border-radius":"var(--radius-field)","&:hover":{"background-color":"var(--color-base-200)"}},".rdp-button_previous":{"border-radius":"var(--radius-field)","&:hover":{"background-color":"var(--color-base-200)"}},".rdp-button_next, .rdp-button_previous":{"cursor":"pointer","font":"inherit","color":"inherit","appearance":"none","width":"2.25rem","height":"2.25rem","background":"0 0","border":"none","justify-content":"center","align-items":"center","margin":"0","padding":"0","display":"inline-flex","position":"relative","&:disabled, &[aria-disabled=\"true\"]":{"cursor":"revert","opacity":0.5},"&:disabled:hover, &[aria-disabled=\"true\"]:hover":{"background-color":"transparent"}},".rdp-chevron":{"fill":"var(--color-base-content)","width":"1rem","height":"1rem","display":"inline-block"},".rdp-dropdowns":{"align-items":"center","gap":"0.5rem","display":"inline-flex","position":"relative"},".rdp-dropdown":{"z-index":2,"opacity":0,"appearance":"none","cursor":"inherit","line-height":"inherit","border":"none","width":"100%","margin":"0","padding":"0","position":"absolute","inset-block":"0","inset-inline-start":"0","&:focus-visible":{"~ .rdp-caption_label":{"outline":["5px auto highlight","5px auto -webkit-focus-ring-color"]}}},".rdp-dropdown_root":{"align-items":"center","display":"inline-flex","position":"relative","&[data-disabled=\"true\"]":{".rdp-chevron":{"opacity":0.5}}},".rdp-month_caption":{"height":"2.75rem","font-size":"0.75rem","font-weight":"inherit","place-content":"center","display":"flex"},".rdp-months":{"gap":"2rem","flex-wrap":"wrap","max-width":"fit-content","padding":"0.5rem","display":"flex","position":"relative"},".rdp-month_grid":{"border-collapse":"collapse"},".rdp-nav":{"height":"2.75rem","inset-block-start":"0","inset-inline-end":"0","justify-content":"space-between","align-items":"center","width":"100%","padding-inline":"0.5rem","display":"flex","position":"absolute","top":"0.25rem"},".rdp-weekday":{"opacity":0.6,"padding":"0.5rem 0rem","text-align":"center","font-size":"smaller","font-weight":500},".rdp-week_number":{"opacity":0.6,"height":"2.25rem","width":"2.25rem","border":"none","border-radius":"100%","text-align":"center","font-size":"small","font-weight":400},".rdp-today:not(.rdp-outside)":{".rdp-day_button":{"background":"var(--color-primary)","color":"var(--color-primary-content)"}},".rdp-selected":{"font-weight":"inherit","font-size":"0.75rem",".rdp-day_button":{"color":"var(--color-base-100)","background-color":"var(--color-base-content)","border-radius":"var(--radius-field)","border":"none","&:hover":{"background-color":"var(--color-base-content)"}}},".rdp-outside":{"opacity":0.75},".rdp-disabled":{"opacity":0.5},".rdp-hidden":{"visibility":"hidden","color":"var(--color-base-content)"},".rdp-range_start":{".rdp-day_button":{"border-radius":"var(--radius-field) 0 0 var(--radius-field)"}},".rdp-range_start .rdp-day_button":{"background-color":"var(--color-base-content)","color":"var(--color-base-100)"},".rdp-range_middle":{"background-color":"var(--color-base-200)"},".rdp-range_middle .rdp-day_button":{"border":"unset","border-radius":"unset","color":"inherit"},".rdp-range_end":{"color":"var(--color-base-content)",".rdp-day_button":{"border-radius":"0 var(--radius-field) var(--radius-field) 0"}},".rdp-range_end .rdp-day_button":{"background-color":"var(--color-base-content)","color":"var(--color-base-100)"},".rdp-range_start.rdp-range_end":{"background":"revert"},".rdp-focusable":{"cursor":"pointer"},".rdp-footer":{"border-top":"var(--border) solid var(--color-base-200)","padding":"0.5rem"}}},".pika-single":{"@layer daisyui.l1.l2.l3":{"&:is(div)":{"user-select":"none","font-size":"0.75rem","z-index":999,"display":"inline-block","position":"relative","color":"var(--color-base-content)","background-color":"var(--color-base-100)","border-radius":"var(--radius-box)","border":"var(--border) solid var(--color-base-200)","padding":"0.5rem","&:before, &:after":{"content":"\"\"","display":"table"},"&:after":{"clear":"both"},"&.is-hidden":{"display":"none"},"&.is-bound":{"position":"absolute"},".pika-lendar":{"css-float":"left"},".pika-title":{"position":"relative","text-align":"center","select":{"cursor":"pointer","position":"absolute","z-index":999,"margin":"0","left":"0","top":"5px","opacity":0}},".pika-label":{"display":"inline-block","position":"relative","z-index":999,"overflow":"hidden","margin":"0","padding":"5px 3px","background-color":"var(--color-base-100)"},".pika-prev, .pika-next":{"display":"block","cursor":"pointer","position":"absolute","top":"0","outline":"none","border":"0","width":"2.25rem","height":"2.25rem","color":"#0000","font-size":"1.2em","border-radius":"var(--radius-field)","&:hover":{"background-color":"var(--color-base-200)"},"&.is-disabled":{"cursor":"default","opacity":0.2},"&:before":{"display":"inline-block","width":"2.25rem","height":"2.25rem","line-height":2.25,"color":"var(--color-base-content)"}},".pika-prev":{"left":"0","&:before":{"--tw-content":"\"‹\"","content":"var(--tw-content)"}},".pika-next":{"right":"0","&:before":{"--tw-content":"\"›\"","content":"var(--tw-content)"}},".pika-select":{"display":"inline-block"},".pika-table":{"width":"100%","border-collapse":"collapse","border-spacing":"0","border":"0","th, td":{"padding":"0"},"th":{"opacity":0.6,"text-align":"center","width":"2.25rem","height":"2.25rem"}},".pika-button":{"cursor":"pointer","display":"block","outline":"none","border":"0","margin":"0","width":"2.25rem","height":"2.25rem","padding":"5px","text-align":["right","center"]},".pika-week":{"color":"var(--color-base-content)"},".is-today":{".pika-button":{"background":"var(--color-primary)","color":"var(--color-primary-content)"}},".is-selected, .has-event":{".pika-button":{"&, &:hover":{"color":"var(--color-base-100)","background-color":"var(--color-base-content)","border-radius":"var(--radius-field)"}}},".has-event":{".pika-button":{"background":"var(--color-base-primary)"}},".is-disabled, .is-inrange":{".pika-button":{"background":"var(--color-base-primary)"}},".is-startrange":{".pika-button":{"color":"var(--color-base-100)","background":"var(--color-base-content)","border-radius":"var(--radius-field)"}},".is-endrange":{".pika-button":{"color":"var(--color-base-100)","background":"var(--color-base-content)","border-radius":"var(--radius-field)"}},".is-disabled":{".pika-button":{"pointer-events":"none","cursor":"default","color":"var(--color-base-content)","opacity":0.3}},".is-outside-current-month":{".pika-button":{"color":"var(--color-base-content)","opacity":0.3}},".is-selection-disabled":{"pointer-events":"none","cursor":"default"},".pika-button:hover, .pika-row.pick-whole-week:hover .pika-button":{"color":"var(--color-base-content)","background-color":"var(--color-base-200)","border-radius":"var(--radius-field)"},".pika-table abbr":{"text-decoration":"none","font-weight":"normal"}}}}};
|
b/7fd646dca67a8e4acba92ac322d190ea76a34c9b194e32f228154171fc60d20e
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.daisyui.label",
|
| 3 |
+
"name": "daisyui-label",
|
| 4 |
+
"tier": "component",
|
| 5 |
+
"library": "daisyui",
|
| 6 |
+
"category": "Forms & Inputs",
|
| 7 |
+
"upstream": "https://cdn.jsdelivr.net/npm/daisyui@5.5.23/components/label.css",
|
| 8 |
+
"docs": "https://daisyui.com/components/label/",
|
| 9 |
+
"did": "did:holo:sha256:6c5ad2fcc538df2de66c94f0ba813a413470575626263e1d91d0fed24c455d53",
|
| 10 |
+
"import": "holo://sha256:6c5ad2fcc538df2de66c94f0ba813a413470575626263e1d91d0fed24c455d53",
|
| 11 |
+
"integrity": "sha256-bFrS/MU43y3mbJTwuoE6QTRwV1YmJj4dkdD+0kxFXVM=",
|
| 12 |
+
"kappa": "sha256:6c5ad2fcc538df2de66c94f0ba813a413470575626263e1d91d0fed24c455d53",
|
| 13 |
+
"moduleKappa": "sha256:6c5ad2fcc538df2de66c94f0ba813a413470575626263e1d91d0fed24c455d53",
|
| 14 |
+
"renderExport": null,
|
| 15 |
+
"format": "css",
|
| 16 |
+
"source": "components/label.css",
|
| 17 |
+
"module": "vendor/daisyui/components/label.css",
|
| 18 |
+
"exports": [],
|
| 19 |
+
"bytes": 12801,
|
| 20 |
+
"provenance": {
|
| 21 |
+
"package": "daisyui",
|
| 22 |
+
"version": "5.5.23",
|
| 23 |
+
"integrity": "sha512-xuheNUSL4T6ZVtWXoioqcNkjoyGX85QTDz4HTw2aBPfqk4fuMjax5HDo8qCmpV6M1YN8bGvfx5BpYCoDeRlt+A==",
|
| 24 |
+
"file": "components/label.css"
|
| 25 |
+
},
|
| 26 |
+
"license": "MIT"
|
| 27 |
+
}
|
b/7fe9c4fd23bd6f219d5f21107168cd3ac4f6d9e88b40ebe3525c104780bc89db
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { BookmarkIcon } from "lucide-react"
|
| 2 |
+
|
| 3 |
+
import { Toggle } from "@/registry/new-york-v4/ui/toggle"
|
| 4 |
+
|
| 5 |
+
export default function ToggleDemo() {
|
| 6 |
+
return (
|
| 7 |
+
<Toggle
|
| 8 |
+
aria-label="Toggle bookmark"
|
| 9 |
+
size="sm"
|
| 10 |
+
variant="outline"
|
| 11 |
+
className="data-[state=on]:bg-transparent data-[state=on]:*:[svg]:fill-blue-500 data-[state=on]:*:[svg]:stroke-blue-500"
|
| 12 |
+
>
|
| 13 |
+
<BookmarkIcon />
|
| 14 |
+
Bookmark
|
| 15 |
+
</Toggle>
|
| 16 |
+
)
|
| 17 |
+
}
|
b/7ff6489df10ee40d906b0322fbb2e6030e96a60f24399b11ea520f09702bbbfb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// q-live-sw.js — BOOT-ONCE. The brain's weights are immutable content-addressed κ-blocks (HF …/resolve/main/
|
| 2 |
+
// b/<sha256>): fetch them from HuggingFace ONCE, cache-first forever, so every visit after the first is
|
| 3 |
+
// ~0-network and instant — and a flaky cold-stream can't wedge a returning user. Only immutable, content-
|
| 4 |
+
// addressed URLs are cached (the sha256 IS the version), so cache-first is always correct — never stale.
|
| 5 |
+
//
|
| 6 |
+
// Scope /apps/q/ controls q-live.html; the fetch handler still sees its cross-origin HF requests. claim() on
|
| 7 |
+
// activate takes control of the already-open page so the FIRST brain load is intercepted + cached as it streams.
|
| 8 |
+
const CACHE = "q-live-kappa-v1";
|
| 9 |
+
|
| 10 |
+
// immutable content-addressed weight blocks + the tokenizer header (both keyed by content). Anything else
|
| 11 |
+
// (manifests, app code, the localhost .holo Range reads) passes straight through to the network untouched.
|
| 12 |
+
const CACHEABLE = /\/resolve\/main\/b\/|\/b\/sha256_|\/resolve\/main\/tokenizer\.gguf/;
|
| 13 |
+
|
| 14 |
+
self.addEventListener("install", () => self.skipWaiting());
|
| 15 |
+
self.addEventListener("activate", (e) => e.waitUntil(self.clients.claim()));
|
| 16 |
+
|
| 17 |
+
self.addEventListener("fetch", (e) => {
|
| 18 |
+
const url = e.request.url;
|
| 19 |
+
if (e.request.method !== "GET" || !CACHEABLE.test(url)) return; // network as normal
|
| 20 |
+
e.respondWith((async () => {
|
| 21 |
+
const cache = await caches.open(CACHE);
|
| 22 |
+
const hit = await cache.match(e.request);
|
| 23 |
+
if (hit) return hit; // served from cache — 0 network
|
| 24 |
+
let res;
|
| 25 |
+
try { res = await fetch(e.request); } catch (err) { // offline + not cached → let it surface
|
| 26 |
+
const stale = await cache.match(e.request); if (stale) return stale; throw err;
|
| 27 |
+
}
|
| 28 |
+
// cache opaque (cross-origin no-cors) and 200 bodies; a κ-block is immutable so this is safe forever.
|
| 29 |
+
try { if (res && (res.status === 200 || res.type === "opaque")) await cache.put(e.request, res.clone()); } catch (_) {}
|
| 30 |
+
return res;
|
| 31 |
+
})());
|
| 32 |
+
});
|
b/80165c49198f10b2f3aad4c627e2cf3dc707ab863d779a6131d6645f8a861cd1
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import textarea from './object.js';
|
| 2 |
+
import { addPrefix } from '../../functions/addPrefix.js';
|
| 3 |
+
|
| 4 |
+
export default ({ addComponents, prefix = '' }) => {
|
| 5 |
+
const prefixedtextarea = addPrefix(textarea, prefix);
|
| 6 |
+
addComponents({ ...prefixedtextarea });
|
| 7 |
+
};
|
b/80235b3abcba833ae912ef0c682f2ffa3162aac12dc2e61691495bdb852e3ff5
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { IconPlus } from "@tabler/icons-react"
|
| 2 |
+
|
| 3 |
+
import { Button } from "@/registry/new-york-v4/ui/button"
|
| 4 |
+
import {
|
| 5 |
+
ButtonGroup,
|
| 6 |
+
ButtonGroupSeparator,
|
| 7 |
+
} from "@/registry/new-york-v4/ui/button-group"
|
| 8 |
+
|
| 9 |
+
export default function ButtonGroupSplit() {
|
| 10 |
+
return (
|
| 11 |
+
<ButtonGroup>
|
| 12 |
+
<Button variant="secondary">Button</Button>
|
| 13 |
+
<ButtonGroupSeparator />
|
| 14 |
+
<Button size="icon" variant="secondary">
|
| 15 |
+
<IconPlus />
|
| 16 |
+
</Button>
|
| 17 |
+
</ButtonGroup>
|
| 18 |
+
)
|
| 19 |
+
}
|
b/807d9cb5d6bc7dcfc02da6704130597c68309e997dd7d5d1ff1ffff5960d5e85
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.example.input-group-icon",
|
| 3 |
+
"name": "input-group-icon",
|
| 4 |
+
"tier": "example",
|
| 5 |
+
"library": "shadcn",
|
| 6 |
+
"category": "Examples",
|
| 7 |
+
"upstream": "https://ui.shadcn.com/r/styles/new-york-v4/input-group-icon.json",
|
| 8 |
+
"did": "did:holo:sha256:80e8f6a2298e726ad36975aa7c1720ce5c245a7247499155571b6c6f055bebd0",
|
| 9 |
+
"import": "holo://sha256:64c5a31ce66c83eae45385f0fc1ba777b3b761e96b50ba4d626995a8ed8eb041",
|
| 10 |
+
"integrity": "sha256-ZMWjHOZsg+rkU4Xw/Bund7O3YelrULpNYmmVqO2OsEE=",
|
| 11 |
+
"kappa": "sha256:80e8f6a2298e726ad36975aa7c1720ce5c245a7247499155571b6c6f055bebd0",
|
| 12 |
+
"moduleKappa": "sha256:64c5a31ce66c83eae45385f0fc1ba777b3b761e96b50ba4d626995a8ed8eb041",
|
| 13 |
+
"renderExport": "default",
|
| 14 |
+
"source": "registry/new-york-v4/examples/input-group-icon.tsx",
|
| 15 |
+
"module": "vendor/components/input-group-icon.js",
|
| 16 |
+
"exports": [
|
| 17 |
+
"default"
|
| 18 |
+
],
|
| 19 |
+
"license": "MIT"
|
| 20 |
+
}
|
b/807fd730926d5b732ad87b35cb4eb6c725151ebf8f6a18a75cefcc2f1cb8f7c9
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "org.hologram.ui.daisyui.chat",
|
| 3 |
+
"name": "daisyui-chat",
|
| 4 |
+
"tier": "component",
|
| 5 |
+
"library": "daisyui",
|
| 6 |
+
"category": "Data Display",
|
| 7 |
+
"upstream": "https://cdn.jsdelivr.net/npm/daisyui@5.5.23/components/chat.css",
|
| 8 |
+
"docs": "https://daisyui.com/components/chat/",
|
| 9 |
+
"did": "did:holo:sha256:e51ccc2543414d8b27941e37d31aeedbd90010e99c5067703e07a70a3c8a4ca0",
|
| 10 |
+
"import": "holo://sha256:e51ccc2543414d8b27941e37d31aeedbd90010e99c5067703e07a70a3c8a4ca0",
|
| 11 |
+
"integrity": "sha256-5RzMJUNBTYsnlB430xru29kAEOmcUGdwPgenCjyKTKA=",
|
| 12 |
+
"kappa": "sha256:e51ccc2543414d8b27941e37d31aeedbd90010e99c5067703e07a70a3c8a4ca0",
|
| 13 |
+
"moduleKappa": "sha256:e51ccc2543414d8b27941e37d31aeedbd90010e99c5067703e07a70a3c8a4ca0",
|
| 14 |
+
"renderExport": null,
|
| 15 |
+
"format": "css",
|
| 16 |
+
"source": "components/chat.css",
|
| 17 |
+
"module": "vendor/daisyui/components/chat.css",
|
| 18 |
+
"exports": [],
|
| 19 |
+
"bytes": 17361,
|
| 20 |
+
"provenance": {
|
| 21 |
+
"package": "daisyui",
|
| 22 |
+
"version": "5.5.23",
|
| 23 |
+
"integrity": "sha512-xuheNUSL4T6ZVtWXoioqcNkjoyGX85QTDz4HTw2aBPfqk4fuMjax5HDo8qCmpV6M1YN8bGvfx5BpYCoDeRlt+A==",
|
| 24 |
+
"file": "components/chat.css"
|
| 25 |
+
},
|
| 26 |
+
"license": "MIT"
|
| 27 |
+
}
|
b/80ecd8805b348cda9c3140fa857c11a9279643e4d418d7aae84fa4985891a269
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// e8-quant.mjs — quantize an LLM's weights onto the E₈ lattice (the structure the atlas generates).
|
| 2 |
+
// E₈ is the densest lattice in 8 dimensions (Viazovska 2016) and, being UNIMODULAR (det = 1), E₈ at
|
| 3 |
+
// step δ and the integer lattice Z⁸ at step δ have the SAME point density — so comparing E₈-at-δ to
|
| 4 |
+
// scalar-round-at-δ is a fair EQUAL-RATE comparison, where E₈'s quantizing gain should give ≈0.86×
|
| 5 |
+
// the distortion (its normalized 2nd moment G(E₈)≈0.0717 vs 1/12≈0.0833 for scalar). Pure JS, zero deps.
|
| 6 |
+
//
|
| 7 |
+
// This is the literal "fit a model to the atlas at compile time, in the substrate": a content-addressed
|
| 8 |
+
// transform κ(weights) ⊕ κ(E₈-codebook) ⊕ κ(δ) → κ(quantized) realized as a weight requantizer the
|
| 9 |
+
// QVAC engine then runs. Honest scope: a principled, optimal vector quantizer — a compression/fidelity
|
| 10 |
+
// tool, not a semantic "truth" fix.
|
| 11 |
+
|
| 12 |
+
// ── nearest lattice point ──
|
| 13 |
+
// D_n = integer vectors with even coordinate sum. Decode: round all; if the sum is odd, flip the one
|
| 14 |
+
// coordinate with the largest rounding error to the other side (parity flips, distance cost minimal).
|
| 15 |
+
function nearestDn(x, y) {
|
| 16 |
+
let sum = 0, worst = -1, wi = 0;
|
| 17 |
+
for (let i = 0; i < 8; i++) { const r = Math.round(x[i]); y[i] = r; sum += r; const e = Math.abs(x[i] - r); if (e > worst) { worst = e; wi = i; } }
|
| 18 |
+
if ((sum & 1) !== 0) { const r = Math.round(x[wi]); y[wi] = x[wi] >= r ? r + 1 : r - 1; }
|
| 19 |
+
return y;
|
| 20 |
+
}
|
| 21 |
+
// E₈ = D₈ ∪ (D₈ + (½)⁸). Decode: closer of nearestD8(x) and nearestD8(x−½)+½.
|
| 22 |
+
const _a = new Float64Array(8), _b = new Float64Array(8), _xs = new Float64Array(8);
|
| 23 |
+
export function nearestE8(x, out) {
|
| 24 |
+
nearestDn(x, _a);
|
| 25 |
+
for (let i = 0; i < 8; i++) _xs[i] = x[i] - 0.5;
|
| 26 |
+
nearestDn(_xs, _b);
|
| 27 |
+
let e0 = 0, e1 = 0;
|
| 28 |
+
for (let i = 0; i < 8; i++) { const d0 = x[i] - _a[i], h = _b[i] + 0.5, d1 = x[i] - h; e0 += d0 * d0; e1 += d1 * d1; _b[i] = h; }
|
| 29 |
+
const src = e0 <= e1 ? _a : _b;
|
| 30 |
+
for (let i = 0; i < 8; i++) out[i] = src[i];
|
| 31 |
+
return out;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// quantize a flat Float32Array IN PLACE onto E₈ at step δ (groups of 8 consecutive values = one vector).
|
| 35 |
+
// Returns the summed squared error (for MSE). Leftover (len % 8) values are scalar-rounded at δ.
|
| 36 |
+
export function e8QuantizeInPlace(w, delta) {
|
| 37 |
+
const v = new Float64Array(8), q = new Float64Array(8); let sse = 0, n = w.length, m = n - (n % 8);
|
| 38 |
+
for (let o = 0; o < m; o += 8) {
|
| 39 |
+
for (let i = 0; i < 8; i++) v[i] = w[o + i] / delta;
|
| 40 |
+
nearestE8(v, q);
|
| 41 |
+
for (let i = 0; i < 8; i++) { const r = q[i] * delta; const e = w[o + i] - r; sse += e * e; w[o + i] = r; }
|
| 42 |
+
}
|
| 43 |
+
for (let o = m; o < n; o++) { const r = Math.round(w[o] / delta) * delta; const e = w[o] - r; sse += e * e; w[o] = r; }
|
| 44 |
+
return sse;
|
| 45 |
+
}
|
| 46 |
+
// scalar (Z⁸) baseline at the same δ — the equal-rate comparison.
|
| 47 |
+
export function scalarQuantizeInPlace(w, delta) {
|
| 48 |
+
let sse = 0; for (let o = 0; o < w.length; o++) { const r = Math.round(w[o] / delta) * delta; const e = w[o] - r; sse += e * e; w[o] = r; }
|
| 49 |
+
return sse;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
// ── incoherence processing (QuIP#): a randomized Hadamard rotation spreads weight outliers so a
|
| 53 |
+
// single lattice step quantizes them well, then is undone — making 2-bit E₈ viable. The sign pattern
|
| 54 |
+
// is deterministic (declared once, part of the atlas E₈ standard), so the transform re-derives. ──
|
| 55 |
+
const _pow2 = (n) => { let p = 1; while (p < n) p <<= 1; return p; };
|
| 56 |
+
function fwht(a) { const n = a.length; for (let len = 1; len < n; len <<= 1) for (let i = 0; i < n; i += len << 1) for (let j = i; j < i + len; j++) { const x = a[j], y = a[j + len]; a[j] = x + y; a[j + len] = x - y; } const s = 1 / Math.sqrt(n); for (let i = 0; i < n; i++) a[i] *= s; } // self-inverse: applied twice = identity
|
| 57 |
+
function signsFor(d) { const s = new Int8Array(d); let x = (0x9e3779b9 ^ d) >>> 0; for (let i = 0; i < d; i++) { x ^= x << 13; x ^= x >>> 17; x ^= x << 5; x >>>= 0; s[i] = (x & 1) ? 1 : -1; } return s; }
|
| 58 |
+
// quantize one row of length K onto E₈ in the incoherence-rotated basis at step δ, IN PLACE (back in
|
| 59 |
+
// the original basis). Returns the row's summed squared error.
|
| 60 |
+
function quantizeRowIncoherent(w, base, K, sign, Kp, delta, buf) {
|
| 61 |
+
for (let k = 0; k < Kp; k++) buf[k] = k < K ? w[base + k] * sign[k] : 0;
|
| 62 |
+
fwht(buf); // rotate to the incoherent basis
|
| 63 |
+
const v = new Float64Array(8), q = new Float64Array(8);
|
| 64 |
+
for (let o = 0; o < Kp; o += 8) { for (let i = 0; i < 8; i++) v[i] = buf[o + i] / delta; nearestE8(v, q); for (let i = 0; i < 8; i++) buf[o + i] = q[i] * delta; }
|
| 65 |
+
fwht(buf); // rotate back (self-inverse)
|
| 66 |
+
let sse = 0; for (let k = 0; k < K; k++) { const r = buf[k] * sign[k]; const e = w[base + k] - r; sse += e * e; w[base + k] = r; }
|
| 67 |
+
return sse;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// ── LDLQ adaptive rounding (QuIP, Chee et al. 2023) ──────────────────────────────────────────────
|
| 71 |
+
// Minimises the OUTPUT error ‖(W−Ŵ)·H^½‖ (not the weight error) by rounding input columns high→low and
|
| 72 |
+
// feeding each future column's quantization error back through the LDL factor of the input Hessian
|
| 73 |
+
// H = Eᵀ·E. VALIDATED: ~5× lower output-weighted error vs independent rounding on a real layer with a
|
| 74 |
+
// real Hessian. To apply across a whole model it needs H per layer — i.e. a calibration forward-pass
|
| 75 |
+
// collecting each layer's input activations (the remaining wiring). These are the validated primitives.
|
| 76 |
+
export function ldlDecompose(H, n) { // H symmetric row-major → {L unit-lower, d diag}, H = L·diag(d)·Lᵀ
|
| 77 |
+
const L = new Float64Array(n * n), d = new Float64Array(n);
|
| 78 |
+
for (let j = 0; j < n; j++) {
|
| 79 |
+
let dj = H[j * n + j]; for (let k = 0; k < j; k++) dj -= L[j * n + k] * L[j * n + k] * d[k]; d[j] = dj; L[j * n + j] = 1;
|
| 80 |
+
for (let i = j + 1; i < n; i++) { let s = H[i * n + j]; for (let k = 0; k < j; k++) s -= L[i * n + k] * L[j * n + k] * d[k]; L[i * n + j] = dj !== 0 ? s / dj : 0; }
|
| 81 |
+
}
|
| 82 |
+
return { L, d };
|
| 83 |
+
}
|
| 84 |
+
export function ldlqRound(W, N, K, L, delta) { // W [N,K] row-major (K = input dim); scalar Q at step δ
|
| 85 |
+
const What = new Float32Array(N * K), E = new Float32Array(N * K);
|
| 86 |
+
for (let k = K - 1; k >= 0; k--) for (let i = 0; i < N; i++) {
|
| 87 |
+
let corr = W[i * K + k]; for (let j = k + 1; j < K; j++) corr += E[i * K + j] * L[j * K + k];
|
| 88 |
+
const r = Math.round(corr / delta) * delta; What[i * K + k] = r; E[i * K + k] = W[i * K + k] - r;
|
| 89 |
+
}
|
| 90 |
+
return What;
|
| 91 |
+
}
|
| 92 |
+
// CODEBOOK-AWARE LDLQ (QuIP# composition done right): quantize each input column DIRECTLY to the E₈
|
| 93 |
+
// lattice — group the N output rows into blocks of 8 and snap each to its nearest E₈ point — INSIDE the
|
| 94 |
+
// recursion, so the feedback error E reflects the lattice-rounded value. This is the correct fusion of
|
| 95 |
+
// the adaptive-rounding lever with the lattice codebook: no scalar-round-then-re-snap (which double-
|
| 96 |
+
// quantizes and undoes the tuning). Output value lands exactly on the δ·E₈ grid (coords ∈ ½ℤ).
|
| 97 |
+
export function ldlqRoundE8(W, N, K, L, delta) {
|
| 98 |
+
const What = new Float32Array(N * K), E = new Float32Array(N * K);
|
| 99 |
+
const corr = new Float64Array(N), v = new Float64Array(8), q = new Float64Array(8);
|
| 100 |
+
const Nb = N - (N % 8);
|
| 101 |
+
for (let k = K - 1; k >= 0; k--) {
|
| 102 |
+
for (let i = 0; i < N; i++) { let c = W[i * K + k]; for (let j = k + 1; j < K; j++) c += E[i * K + j] * L[j * K + k]; corr[i] = c; }
|
| 103 |
+
for (let o = 0; o < Nb; o += 8) { // 8 output rows → one E₈ vector
|
| 104 |
+
for (let i = 0; i < 8; i++) v[i] = corr[o + i] / delta; nearestE8(v, q);
|
| 105 |
+
for (let i = 0; i < 8; i++) { const r = q[i] * delta, p = (o + i) * K + k; What[p] = r; E[p] = W[p] - r; }
|
| 106 |
+
}
|
| 107 |
+
for (let i = Nb; i < N; i++) { const r = Math.round(corr[i] / delta) * delta, p = i * K + k; What[p] = r; E[p] = W[p] - r; } // leftover rows: scalar
|
| 108 |
+
}
|
| 109 |
+
return What;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
// ── engine integration: requantize a QVAC Q8 tensor [int8 N*K][f32 scales N*(K/32)] ──
|
| 113 |
+
// Dequantize → quantize (mode 'e8'|'scalar') at δ = rel × tensorRMS → re-encode Q8 (recompute per-32
|
| 114 |
+
// block scales). Same byte layout in/out, so the GPU kernels run it unchanged. Returns {bytes, mse, rms}.
|
| 115 |
+
export function requantTensorQ8(raw, N, K, { mode = "e8", rel = 1.0 } = {}) {
|
| 116 |
+
const qn = N * K, nsc = N * (K / 32);
|
| 117 |
+
const q = new Int8Array(raw.buffer.slice(raw.byteOffset, raw.byteOffset + qn)); // signed int8 quants (copy → aligned)
|
| 118 |
+
const sc = new Float32Array(raw.buffer.slice(raw.byteOffset + qn, raw.byteOffset + qn + nsc * 4));
|
| 119 |
+
const w = new Float32Array(qn);
|
| 120 |
+
let ss = 0;
|
| 121 |
+
for (let n = 0; n < N; n++) for (let k = 0; k < K; k++) { const val = q[n * K + k] * sc[n * (K / 32) + (k >> 5)]; w[n * K + k] = val; ss += val * val; }
|
| 122 |
+
const rms = Math.sqrt(ss / qn) || 1e-8;
|
| 123 |
+
let mse = 0, delta;
|
| 124 |
+
if (mode === "e8i") { // E₈ with incoherence (QuIP#) — viable at 2-bit
|
| 125 |
+
const Kp = _pow2(K), sign = signsFor(Kp), buf = new Float64Array(Kp);
|
| 126 |
+
delta = rel * rms * Math.sqrt(K / Kp);
|
| 127 |
+
for (let n = 0; n < N; n++) mse += quantizeRowIncoherent(w, n * K, K, sign, Kp, delta, buf);
|
| 128 |
+
} else { // quantize each row in 8-blocks (no rotation)
|
| 129 |
+
delta = rel * rms;
|
| 130 |
+
for (let n = 0; n < N; n++) { const row = w.subarray(n * K, n * K + K); mse += (mode === "e8" ? e8QuantizeInPlace(row, delta) : scalarQuantizeInPlace(row, delta)); }
|
| 131 |
+
}
|
| 132 |
+
mse /= qn;
|
| 133 |
+
// re-encode to Q8: per-32-block symmetric int8 + f32 scale (recomputed from the reconstructed weights)
|
| 134 |
+
const outQ = new Int8Array(qn), outS = new Float32Array(nsc);
|
| 135 |
+
for (let n = 0; n < N; n++) for (let b = 0; b < K / 32; b++) {
|
| 136 |
+
let mx = 0; const base = n * K + b * 32; for (let i = 0; i < 32; i++) { const a = Math.abs(w[base + i]); if (a > mx) mx = a; }
|
| 137 |
+
const s = mx / 127 || 1e-12; outS[n * (K / 32) + b] = s;
|
| 138 |
+
for (let i = 0; i < 32; i++) { let qi = Math.round(w[base + i] / s); if (qi > 127) qi = 127; else if (qi < -127) qi = -127; outQ[base + i] = qi; }
|
| 139 |
+
}
|
| 140 |
+
const out = new Uint8Array(qn + nsc * 4);
|
| 141 |
+
out.set(new Uint8Array(outQ.buffer), 0); out.set(new Uint8Array(outS.buffer), qn);
|
| 142 |
+
return { bytes: out, mse, rms, delta };
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
// ── node self-test: validate the quantizer + the lattice gain ──
|
| 146 |
+
if (typeof process !== "undefined" && process.argv[1] && process.argv[1].endsWith("e8-quant.mjs")) {
|
| 147 |
+
let s = 99; const nx = () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296;
|
| 148 |
+
const gauss = () => { const u = Math.max(1e-12, nx()), v = nx(); return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v); };
|
| 149 |
+
const N = 80000;
|
| 150 |
+
for (const delta of [0.5, 1.0, 2.0]) {
|
| 151 |
+
const a = new Float32Array(N), b = new Float32Array(N); for (let i = 0; i < N; i++) { const g = gauss(); a[i] = g; b[i] = g; }
|
| 152 |
+
const e8 = e8QuantizeInPlace(a, delta) / N, sc = scalarQuantizeInPlace(b, delta) / N;
|
| 153 |
+
console.log(`δ=${delta} E8 MSE=${e8.toFixed(5)} scalar MSE=${sc.toFixed(5)} ratio E8/scalar=${(e8 / sc).toFixed(3)} (theory ≈0.860 = the E₈ quantizing gain)`);
|
| 154 |
+
}
|
| 155 |
+
// sanity: a known E₈ point quantizes to itself
|
| 156 |
+
const p = new Float64Array([1, 1, 0, 0, 0, 0, 0, 0]), o = new Float64Array(8); nearestE8(p, o);
|
| 157 |
+
console.log("nearestE8([1,1,0,...]) =", Array.from(o).join(","), "(should be the same root; sum even ✓)");
|
| 158 |
+
}
|
b/80fad96c6271e3e14f74a4ca503bef27df355f99b5a920bd7753fc98066e140f
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import * as React from "react"
|
| 2 |
+
import { CircleIcon } from "lucide-react"
|
| 3 |
+
import { RadioGroup as RadioGroupPrimitive } from "radix-ui"
|
| 4 |
+
|
| 5 |
+
import { cn } from "@/lib/utils"
|
| 6 |
+
|
| 7 |
+
function RadioGroup({
|
| 8 |
+
className,
|
| 9 |
+
...props
|
| 10 |
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
|
| 11 |
+
return (
|
| 12 |
+
<RadioGroupPrimitive.Root
|
| 13 |
+
data-slot="radio-group"
|
| 14 |
+
className={cn("grid gap-3", className)}
|
| 15 |
+
{...props}
|
| 16 |
+
/>
|
| 17 |
+
)
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
function RadioGroupItem({
|
| 21 |
+
className,
|
| 22 |
+
...props
|
| 23 |
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
|
| 24 |
+
return (
|
| 25 |
+
<RadioGroupPrimitive.Item
|
| 26 |
+
data-slot="radio-group-item"
|
| 27 |
+
className={cn(
|
| 28 |
+
"aspect-square size-4 shrink-0 rounded-full border border-input text-primary shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:ring-destructive/40",
|
| 29 |
+
className
|
| 30 |
+
)}
|
| 31 |
+
{...props}
|
| 32 |
+
>
|
| 33 |
+
<RadioGroupPrimitive.Indicator
|
| 34 |
+
data-slot="radio-group-indicator"
|
| 35 |
+
className="relative flex items-center justify-center"
|
| 36 |
+
>
|
| 37 |
+
<CircleIcon className="absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 fill-primary" />
|
| 38 |
+
</RadioGroupPrimitive.Indicator>
|
| 39 |
+
</RadioGroupPrimitive.Item>
|
| 40 |
+
)
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
export { RadioGroup, RadioGroupItem }
|
b/80fdc692e539bffcc25e337d147a9eb104da31201c311b6a5625f086a3d39eca
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// m9b-prefill.mjs — KV-cache PREFILL memoization on the REAL Q model. A long shared prefix (system
|
| 2 |
+
// prompt + RAG) is prefilled ONCE and cached by classκ = H(prefixTokens ⊕ modelκ ⊕ deviceClass); a
|
| 3 |
+
// repeat RESTORES the KV (forward opts.inKV) and decodes only the suffix — skipping the expensive prefill.
|
| 4 |
+
// 9a proved the KV κ reproduces (same/fresh-process, CPU), so WARM output is byte-identical to COLD.
|
| 5 |
+
import { readFileSync } from "node:fs";
|
| 6 |
+
import crypto from "node:crypto";
|
| 7 |
+
import { performance } from "node:perf_hooks";
|
| 8 |
+
import { forgeGguf } from "./gguf-forge.mjs";
|
| 9 |
+
import { synthesizeGraph } from "./gguf-forge-graph.mjs";
|
| 10 |
+
import { forward } from "./gguf-forge-exec.mjs";
|
| 11 |
+
import { sha256hex } from "../../../../holo-os/system/os/usr/lib/holo/holo-uor.mjs";
|
| 12 |
+
|
| 13 |
+
const sha = (u8) => crypto.createHash("sha256").update(u8).digest("hex");
|
| 14 |
+
const bytesOf = (f) => new Uint8Array(f.buffer, f.byteOffset, f.byteLength);
|
| 15 |
+
const buf = new Uint8Array(readFileSync(".models/qwen2.5-0.5b-instruct-q4_k_m.gguf"));
|
| 16 |
+
const f = forgeGguf(buf); const graph = synthesizeGraph(f.plan); const store = { get: (h) => f.blocks.get(h) };
|
| 17 |
+
const verified = new Set();
|
| 18 |
+
const load = (st, k) => { const hex = String(k).split(":").pop(); const b = st.get(hex); if (!b) throw new Error("κ?"); if (!verified.has(hex)) { if (sha256hex(b) !== hex) throw new Error("L5"); verified.add(hex); } return b; };
|
| 19 |
+
const modelK = f.rootKappa; const deviceClass = "cpu-tierA-f32"; // 9c: KV-κ valid at OWN + same-device-class scope
|
| 20 |
+
const tok = (i, salt = 0) => ((i * 2654435761 + salt * 40503) % 150000) >>> 0; // deterministic valid token ids
|
| 21 |
+
const classKappa = (prefix) => sha256hex(new TextEncoder().encode("kv:" + modelK + "|" + deviceClass + "|" + prefix.join(",")));
|
| 22 |
+
|
| 23 |
+
// the memo: classκ(prefix) -> cached prefill KV (own/device-class scope)
|
| 24 |
+
const kvStore = new Map();
|
| 25 |
+
function prefillCached(prefix) {
|
| 26 |
+
const ck = classKappa(prefix);
|
| 27 |
+
if (kvStore.has(ck)) return { kv: kvStore.get(ck), hit: true, ck };
|
| 28 |
+
const kv = {}; forward(f.plan, graph, store, prefix, { load, outKV: kv }); kvStore.set(ck, kv);
|
| 29 |
+
return { kv, hit: false, ck };
|
| 30 |
+
}
|
| 31 |
+
const decodeLogits = (seq, inKV) => forward(f.plan, graph, store, seq, inKV ? { load, inKV } : { load });
|
| 32 |
+
|
| 33 |
+
console.log(`MODEL Qwen2.5-0.5B · device-class "${deviceClass}" · modelκ ${modelK.slice(0, 12)}…`);
|
| 34 |
+
console.log(`prefixLen COLD(full prefill+decode) WARM(restore KV, decode suffix) speedup output byte-identical`);
|
| 35 |
+
for (const PLEN of [16, 48, 96]) {
|
| 36 |
+
const prefix = Array.from({ length: PLEN }, (_, i) => tok(i));
|
| 37 |
+
const query = Array.from({ length: 8 }, (_, i) => tok(i, 1));
|
| 38 |
+
const seq = prefix.concat(query);
|
| 39 |
+
const { kv } = prefillCached(prefix); // turn 1 already cached this prefix's KV
|
| 40 |
+
|
| 41 |
+
const c0 = performance.now(); const cold = decodeLogits(seq, null); const coldMs = performance.now() - c0; // recompute everything
|
| 42 |
+
const w0 = performance.now(); const warm = decodeLogits(seq, kv); const warmMs = performance.now() - w0; // restore KV, decode only the 8-tok suffix
|
| 43 |
+
const identical = sha(bytesOf(cold)) === sha(bytesOf(warm));
|
| 44 |
+
console.log(` ${String(PLEN).padStart(4)} ${coldMs.toFixed(0).padStart(8)} ms ${warmMs.toFixed(0).padStart(8)} ms ${(coldMs / warmMs).toFixed(1).padStart(5)}x ${identical ? "YES ✓" : "NO ✗"}`);
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
// null control: a UNIQUE prefix never seen → no cache → pays full prefill + the hash (memo loses)
|
| 48 |
+
{
|
| 49 |
+
const uniq = Array.from({ length: 64 }, (_, i) => tok(i, 999));
|
| 50 |
+
const t0 = performance.now(); const r = prefillCached(uniq); const ms = performance.now() - t0;
|
| 51 |
+
console.log(`\n[null control] unique 128-tok prefix: cache hit=${r.hit} → paid full prefill ${ms.toFixed(0)}ms + classκ hash. Memo wins ONLY when the prefix recurs.`);
|
| 52 |
+
}
|
| 53 |
+
console.log(`SCOPE (9c): this KV reuse is sound at OWN + same-device-class ("${deviceClass}") — 9a proved κ reproduces there. Cross-backend/cross-device κ DIVERGES (WITNESS GEMV 4.8e-7) → recompute or 7e-quorum the OUTPUT, never share raw KV across heterogeneous devices.`);
|
b/8106443153817133945aa49cdf1377054560d97974e6ca62fd142e324dff39a2
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!doctype html><html><head><meta charset=utf8><title>spec-tape-capture (init)</title>
|
| 2 |
+
<style>body{font:14px/1.5 monospace;background:#0b0e14;color:#e6e9ef;padding:18px}pre{white-space:pre-wrap}#out{color:#7cffa0}</style>
|
| 3 |
+
</head><body>
|
| 4 |
+
<h3>Q spec-tape-capture — greedy tapes from the real 9B (WebGPU)</h3>
|
| 5 |
+
<div id=log>booting…</div>
|
| 6 |
+
<pre id=out></pre>
|
| 7 |
+
<script type=module>
|
| 8 |
+
// Captures real greedy token tapes from Qwen3.5-9B for spec-p0-eval.mjs. Uses the readback ORACLE
|
| 9 |
+
// brain (step/argmax/newState/tok) exposed by loadQwen35Brain — correct greedy, a few sec/token.
|
| 10 |
+
// Result is stashed on window.__tapes (JSON) and rendered; window.__progress tracks live state so a
|
| 11 |
+
// driver can poll without blocking. document.title flips to DONE / ERROR at the end.
|
| 12 |
+
import { loadQwen35Brain } from "./holo-qwen35-gpu-real.mjs";
|
| 13 |
+
const $ = (s) => document.querySelector(s);
|
| 14 |
+
const log = (m) => { $("#log").textContent = m; window.__progress = m; };
|
| 15 |
+
const HOLO = new URL("../.models/qwen3.5-9b-thinking.holo", location.href).href;
|
| 16 |
+
const EOS = new Set([248046, 248044]);
|
| 17 |
+
const SYS = "You are Q, a concise, helpful thinking assistant.";
|
| 18 |
+
const Q = new URLSearchParams(location.search);
|
| 19 |
+
const MAXNEW = +(Q.get("new") || 48);
|
| 20 |
+
const NCAP = +(Q.get("n") || 0); // 0 = all served intents
|
| 21 |
+
const SKIP = +(Q.get("skip") || 0); // resume: skip the first N intents
|
| 22 |
+
let PROMPTS = [
|
| 23 |
+
"The capital of France is",
|
| 24 |
+
"Write a Python function that returns the nth Fibonacci number.",
|
| 25 |
+
"Explain why the sky is blue in two sentences.",
|
| 26 |
+
"List the first five prime numbers and their sum.",
|
| 27 |
+
];
|
| 28 |
+
const frame = (msgs) => { let s = ""; for (const m of msgs) s += `<|im_start|>${m.role}\n${m.content}<|im_end|>\n`; return s + "<|im_start|>assistant\n"; };
|
| 29 |
+
|
| 30 |
+
window.__tapes = null; window.__progress = "boot";
|
| 31 |
+
try {
|
| 32 |
+
if (!navigator.gpu) throw new Error("no WebGPU (need Chrome/Edge/CEF with WebGPU)");
|
| 33 |
+
const t0 = performance.now();
|
| 34 |
+
const loaded = await loadQwen35Brain({ holoUrl: HOLO, onProgress: (m, p) => log(`load: ${m} ${p ? Math.round(p * 100) + "%" : ""}`) });
|
| 35 |
+
window.__brain = loaded;
|
| 36 |
+
const R = loaded.resident || loaded; // resident engine: step() returns the argmax token id directly, ~1 readback/token
|
| 37 |
+
const { tok, step, newState, D } = R;
|
| 38 |
+
try { const r = await fetch(new URL("../spec-intents.json", location.href)); if (r.ok) { const arr = await r.json(); if (Array.isArray(arr) && arr.length) { const s = arr.slice(SKIP); PROMPTS = NCAP ? s.slice(0, NCAP) : s; } } } catch (e) {}
|
| 39 |
+
log(`brain ready (${D.n_layer} layers, vocab ${D.vocab}, resident) in ${((performance.now() - t0) / 1000).toFixed(0)}s — capturing ${PROMPTS.length} intents × ${MAXNEW}…`);
|
| 40 |
+
let tapes = [];
|
| 41 |
+
try { const r0 = await fetch(new URL("../spec-tapes-live.json?t=" + Date.now(), location.href)); if (r0.ok) { const d0 = await r0.json(); if (d0 && Array.isArray(d0.tapes)) tapes = d0.tapes; } } catch (e) {}
|
| 42 |
+
const startIdx = tapes.length; // RESUME: continue from what's already on disk (stable PROMPTS order)
|
| 43 |
+
log(`resuming from ${startIdx} existing tapes → capturing to ${PROMPTS.length}`);
|
| 44 |
+
for (let pi = startIdx; pi < PROMPTS.length; pi++) {
|
| 45 |
+
const text = PROMPTS[pi];
|
| 46 |
+
const prompt = tok.encode(frame([{ role: "system", content: SYS }, { role: "user", content: text }]), { addSpecial: false, parseSpecial: true });
|
| 47 |
+
const state = newState(); let next, pos = 0;
|
| 48 |
+
for (; pos < prompt.length; pos++) { next = await step(prompt[pos], pos, state); if (pos % 8 === 0) log(`tape ${pi + 1}/${PROMPTS.length}: prefill ${pos + 1}/${prompt.length}`); }
|
| 49 |
+
const greedy = [];
|
| 50 |
+
for (let n = 0; n < MAXNEW; n++) { if (EOS.has(next)) break; greedy.push(next); log(`tape ${pi + 1}/${PROMPTS.length}: gen ${n + 1}/${MAXNEW} (${greedy.length} tok)`); next = await step(next, pos++, state); }
|
| 51 |
+
tapes.push({ prompt, greedy, text });
|
| 52 |
+
window.__tapes = { model: "qwen3.5-9b-thinking", new: MAXNEW, tapes }; // publish incrementally
|
| 53 |
+
$("#out").textContent = tapes.length + " tapes captured";
|
| 54 |
+
try { await fetch(new URL("../spec-tapes-live.json", location.href), { method: "POST", body: JSON.stringify(window.__tapes) }); } catch (e) {} // persist to disk (survives tab death)
|
| 55 |
+
}
|
| 56 |
+
log(`DONE — ${tapes.length} tapes, ${tapes.reduce((a, t) => a + t.greedy.length, 0)} greedy tokens`);
|
| 57 |
+
document.title = "DONE";
|
| 58 |
+
} catch (e) {
|
| 59 |
+
log("ERROR: " + e.message); window.__error = e.message; document.title = "ERROR"; throw e;
|
| 60 |
+
}
|
| 61 |
+
</script></body></html>
|
b/81397eb59910f084716618642f5f50bd9c5790dd44ddaf735a341cb5f2165419
ADDED
|
Binary file (17 kB). View file
|
|
|
b/81663f74ed767954e39c49f77b49a2a1989544a53fb5d9a45a7d58b00054feaf
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react"
|
| 2 |
+
|
| 3 |
+
import { cn } from "@/lib/utils"
|
| 4 |
+
|
| 5 |
+
export interface OrbitingCirclesProps extends React.HTMLAttributes<HTMLDivElement> {
|
| 6 |
+
className?: string
|
| 7 |
+
children?: React.ReactNode
|
| 8 |
+
reverse?: boolean
|
| 9 |
+
duration?: number
|
| 10 |
+
delay?: number
|
| 11 |
+
radius?: number
|
| 12 |
+
path?: boolean
|
| 13 |
+
iconSize?: number
|
| 14 |
+
speed?: number
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
export function OrbitingCircles({
|
| 18 |
+
className,
|
| 19 |
+
children,
|
| 20 |
+
reverse,
|
| 21 |
+
duration = 20,
|
| 22 |
+
radius = 160,
|
| 23 |
+
path = true,
|
| 24 |
+
iconSize = 30,
|
| 25 |
+
speed = 1,
|
| 26 |
+
...props
|
| 27 |
+
}: OrbitingCirclesProps) {
|
| 28 |
+
const calculatedDuration = duration / speed
|
| 29 |
+
return (
|
| 30 |
+
<>
|
| 31 |
+
{path && (
|
| 32 |
+
<svg
|
| 33 |
+
xmlns="http://www.w3.org/2000/svg"
|
| 34 |
+
version="1.1"
|
| 35 |
+
className="pointer-events-none absolute inset-0 size-full"
|
| 36 |
+
>
|
| 37 |
+
<circle
|
| 38 |
+
className="stroke-black/10 stroke-1 dark:stroke-white/10"
|
| 39 |
+
cx="50%"
|
| 40 |
+
cy="50%"
|
| 41 |
+
r={radius}
|
| 42 |
+
fill="none"
|
| 43 |
+
/>
|
| 44 |
+
</svg>
|
| 45 |
+
)}
|
| 46 |
+
{React.Children.map(children, (child, index) => {
|
| 47 |
+
const angle = (360 / React.Children.count(children)) * index
|
| 48 |
+
return (
|
| 49 |
+
<div
|
| 50 |
+
style={
|
| 51 |
+
{
|
| 52 |
+
"--duration": calculatedDuration,
|
| 53 |
+
"--radius": radius,
|
| 54 |
+
"--angle": angle,
|
| 55 |
+
"--icon-size": `${iconSize}px`,
|
| 56 |
+
} as React.CSSProperties
|
| 57 |
+
}
|
| 58 |
+
className={cn(
|
| 59 |
+
`animate-orbit absolute flex size-(--icon-size) transform-gpu items-center justify-center rounded-full`,
|
| 60 |
+
{ "[animation-direction:reverse]": reverse },
|
| 61 |
+
className
|
| 62 |
+
)}
|
| 63 |
+
{...props}
|
| 64 |
+
>
|
| 65 |
+
{child}
|
| 66 |
+
</div>
|
| 67 |
+
)
|
| 68 |
+
})}
|
| 69 |
+
</>
|
| 70 |
+
)
|
| 71 |
+
}
|
b/816d69918ec74ddbfee25527da0b25148f41abac0fe0c4183811a8c3d4659b3a
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// TurboQuant / PolarQuant fidelity witness — both directions, BIT-FOR-BIT vs ggml's
|
| 2 |
+
// real to_float / quantize_chunk (types 42-49) in the llama.cpp fork.
|
| 3 |
+
// • dequant: tqDequant vs iq-ref.exe to_float (all 8 types)
|
| 4 |
+
// • quant: tqQuant vs quant-ref.exe quantize (all 8: PQ Stage-1 + TBQ Stage-1+QJL)
|
| 5 |
+
// PQ = PolarQuant (Stage 1: rotation-graph-level + Lloyd-Max codebook + bit-pack).
|
| 6 |
+
// TBQ = TurboQuant (+ QJL 1-bit residual sketch). Per-block kernels exclude the
|
| 7 |
+
// Hadamard rotation (graph-level), exactly like ggml's type_traits to_float.
|
| 8 |
+
import { execFileSync } from "node:child_process";
|
| 9 |
+
import { existsSync } from "node:fs";
|
| 10 |
+
import assert from "node:assert";
|
| 11 |
+
import { tqDequant, tqQuant, TQ_TYPES } from "./gguf-forge-turboquant.mjs";
|
| 12 |
+
|
| 13 |
+
const QV = "C:/Users/pavel/Desktop/qvac-fabric-llm.cpp-master/qvac-fabric-llm.cpp-master";
|
| 14 |
+
const IQREF = `${QV}/iq-ref.exe`, QREF = `${QV}/quant-ref.exe`;
|
| 15 |
+
const MINGW = "C:/Users/pavel/AppData/Local/Microsoft/WinGet/Packages/BrechtSanders.WinLibs.POSIX.UCRT_Microsoft.Winget.Source_8wekyb3d8bbwe/mingw64/bin";
|
| 16 |
+
const ENV = { env: { ...process.env, PATH: `${MINGW};${process.env.PATH}` }, maxBuffer: 1 << 26 };
|
| 17 |
+
|
| 18 |
+
function mulberry32(a) { return () => { a |= 0; a = (a + 0x6d2b79f5) | 0; let t = Math.imul(a ^ (a >>> 15), 1 | a); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; }
|
| 19 |
+
const f32bits = (f) => { const b = new ArrayBuffer(4); new Float32Array(b)[0] = f; return new Uint32Array(b)[0]; };
|
| 20 |
+
const hexf = (arr) => Array.from(arr, (v) => f32bits(v).toString(16).padStart(8, "0")).join(" ");
|
| 21 |
+
|
| 22 |
+
function refDequant(typeId, n, raw) {
|
| 23 |
+
const out = execFileSync(IQREF, [String(typeId), String(n), Buffer.from(raw).toString("hex")], ENV).toString().trim();
|
| 24 |
+
return out.split(/\s+/).map((h) => parseInt(h, 16) >>> 0);
|
| 25 |
+
}
|
| 26 |
+
function refQuant(typeId, n, x) {
|
| 27 |
+
const out = execFileSync(QREF, [String(typeId), String(n)], { ...ENV, input: hexf(x) + "\n" }).toString().trim();
|
| 28 |
+
return out.split(/\s+/).map((h) => parseInt(h, 16));
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
let pass = 0, fail = 0;
|
| 32 |
+
const ok = (c, m) => { if (c) { console.log(` ok ${m}`); pass++; } else { console.log(` XX ${m}`); fail++; } };
|
| 33 |
+
assert(existsSync(IQREF), "iq-ref.exe missing"); assert(existsSync(QREF), "quant-ref.exe missing");
|
| 34 |
+
|
| 35 |
+
// Per type: forge a block from random data with OUR quantizer, dequant both via ggml
|
| 36 |
+
// and ours from the SAME bytes, and separately compare OUR quant bytes to ggml's.
|
| 37 |
+
for (const [id, t] of Object.entries(TQ_TYPES)) {
|
| 38 |
+
const typeId = Number(id), nb = 3, n = t.d * nb;
|
| 39 |
+
// varied-magnitude random KV-like vector
|
| 40 |
+
const rnd = mulberry32(0x5151 + typeId), x = new Float32Array(n);
|
| 41 |
+
for (let i = 0; i < n; i++) x[i] = (rnd() * 2 - 1) * (0.5 + (i % 5) * 0.4);
|
| 42 |
+
|
| 43 |
+
// QUANT: our bytes vs ggml bytes (Stage-1 for PQ; Stage-1 + QJL for TBQ)
|
| 44 |
+
const jsq = tqQuant(typeId, x, n), refq = refQuant(typeId, n, x);
|
| 45 |
+
assert.equal(jsq.length, t.total * nb, `${t.name} quant length`);
|
| 46 |
+
let qbad = -1; for (let i = 0; i < jsq.length; i++) if (jsq[i] !== refq[i]) { qbad = i; break; }
|
| 47 |
+
ok(qbad < 0, `${t.name.padEnd(9)} quant BIT-EXACT vs ggml (${jsq.length} B)${qbad < 0 ? "" : ` first@${qbad} js=${jsq[qbad]} ref=${refq[qbad]}`}`);
|
| 48 |
+
|
| 49 |
+
// DEQUANT: feed ggml's own block bytes to our dequant → must equal ggml to_float
|
| 50 |
+
const ref = refDequant(typeId, n, Uint8Array.from(refq)), js = tqDequant(typeId, Uint8Array.from(refq), n);
|
| 51 |
+
let dbad = -1, fin = 0; for (let i = 0; i < n; i++) { const rf = new Float32Array(new Uint32Array([ref[i]]).buffer)[0]; if (!Number.isFinite(rf)) continue; fin++; if (f32bits(js[i]) !== ref[i]) { dbad = i; break; } }
|
| 52 |
+
ok(dbad < 0, `${t.name.padEnd(9)} dequant BIT-EXACT vs ggml to_float (${fin}/${n})${dbad < 0 ? "" : ` first@${dbad}`}`);
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
console.log(`\n${pass} passed, ${fail} failed`);
|
| 56 |
+
process.exit(fail ? 1 : 0);
|
b/817514b0589eb6db36a802fe5cfeb2bc3786035885ffd023fb504d00c6a292eb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// holo-whisper-frontend.mjs — browser-local Whisper front-end (mel + specials + detok).
|
| 2 |
+
// Verbatim copies of the pure functions from ../gguf-forge-whisper.mjs (the CPU oracle that is
|
| 3 |
+
// byte-exact to whisper-cli). Duplicated ONLY because the oracle module transitively imports
|
| 4 |
+
// holo-uor.mjs, which lives outside the forge static-server root. These three functions use NO
|
| 5 |
+
// external deps, so the copies are exact — keep them in lockstep with the oracle if it changes.
|
| 6 |
+
|
| 7 |
+
// log-mel spectrogram: n_fft=400, hop=160; |DFT|² over 201 bins; mel filterbank; log10 + the
|
| 8 |
+
// whisper normalize (max−8 floor, +4 /4). Returns { mel:[nMel*nFrames], nFrames, nMel }.
|
| 9 |
+
export function logMelSpectrogram(samples, filters, { nMel = 80, nFft = 400, hop = 160, nBins = 201, nSamples = 480000 } = {}) {
|
| 10 |
+
const x = new Float32Array(nSamples + nFft); x.set(samples.subarray(0, Math.min(samples.length, nSamples)));
|
| 11 |
+
const nFrames = (nSamples / hop) | 0;
|
| 12 |
+
const hann = new Float32Array(nFft); for (let i = 0; i < nFft; i++) hann[i] = 0.5 - 0.5 * Math.cos((2 * Math.PI * i) / nFft);
|
| 13 |
+
const cosT = new Float32Array(nBins * nFft), sinT = new Float32Array(nBins * nFft);
|
| 14 |
+
for (let b = 0; b < nBins; b++) for (let n = 0; n < nFft; n++) { const a = (-2 * Math.PI * b * n) / nFft; cosT[b * nFft + n] = Math.cos(a); sinT[b * nFft + n] = Math.sin(a); }
|
| 15 |
+
const mel = new Float32Array(nMel * nFrames), win = new Float32Array(nFft), pw = new Float64Array(nBins);
|
| 16 |
+
let mmax = -Infinity;
|
| 17 |
+
for (let f = 0; f < nFrames; f++) {
|
| 18 |
+
const off = f * hop;
|
| 19 |
+
for (let n = 0; n < nFft; n++) win[n] = hann[n] * x[off + n];
|
| 20 |
+
// power spectrum |DFT|² computed ONCE per frame (was recomputed inside the per-mel loop —
|
| 21 |
+
// an 80× redundancy). Same arithmetic + accumulation order ⇒ bit-identical mel, ~80× faster.
|
| 22 |
+
for (let b = 0; b < nBins; b++) { let re = 0.0, im = 0.0; const tb = b * nFft; for (let n = 0; n < nFft; n++) { re += win[n] * cosT[tb + n]; im += win[n] * sinT[tb + n]; } pw[b] = re * re + im * im; }
|
| 23 |
+
for (let k = 0; k < nMel; k++) {
|
| 24 |
+
let s = 0.0; const fb = k * nBins;
|
| 25 |
+
for (let b = 0; b < nBins; b++) s += filters[fb + b] * pw[b];
|
| 26 |
+
let lv = Math.log10(Math.max(s, 1e-10));
|
| 27 |
+
mel[k * nFrames + f] = lv; if (lv > mmax) mmax = lv;
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
const floor = mmax - 8.0;
|
| 31 |
+
for (let i = 0; i < mel.length; i++) mel[i] = (Math.max(mel[i], floor) + 4.0) / 4.0;
|
| 32 |
+
return { mel, nFrames, nMel };
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// Whisper special tokens — derived from n_vocab so the same code serves tiny…large-v3.
|
| 36 |
+
export function whisperSpecials(nVocab) {
|
| 37 |
+
const TS_BEGIN = nVocab - 1501;
|
| 38 |
+
return { EOT: 50257, SOT: 50258, LANG_EN: 50259, TRANSLATE: TS_BEGIN - 6, TRANSCRIBE: TS_BEGIN - 5, NO_TIMESTAMPS: TS_BEGIN - 1, TS_BEGIN };
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
const WHISPER_MAGIC = 0x67676d6c, N_HPARAM = 11;
|
| 42 |
+
// parse just the vocab from the legacy-ggml header (magic + 11 hparams + mel filterbank + vocab).
|
| 43 |
+
function parseVocab(bytes) {
|
| 44 |
+
const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength); let o = 0;
|
| 45 |
+
const i32 = () => { const v = dv.getInt32(o, true); o += 4; return v; };
|
| 46 |
+
if (dv.getUint32(o, true) !== WHISPER_MAGIC) throw new Error("whisper: bad magic"); o += 4;
|
| 47 |
+
for (let i = 0; i < N_HPARAM; i++) i32();
|
| 48 |
+
const n_mel = i32(), n_fft = i32(); o += n_mel * n_fft * 4; // skip mel filterbank
|
| 49 |
+
const nVocab = i32(), tokens = [];
|
| 50 |
+
for (let i = 0; i < nVocab; i++) { const len = i32(); tokens.push(bytes.subarray(o, o + len)); o += len; }
|
| 51 |
+
return tokens;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// whisper.cpp stores tokens as RAW UTF-8 text (literal spaces) — no GPT-2 byte decoder.
|
| 55 |
+
export function whisperDetok(headerBytes, ids) {
|
| 56 |
+
const tokens = parseVocab(headerBytes);
|
| 57 |
+
let total = 0; for (const id of ids) if (id < tokens.length) total += tokens[id].length;
|
| 58 |
+
const out = new Uint8Array(total); let p = 0;
|
| 59 |
+
for (const id of ids) if (id < tokens.length) { out.set(tokens[id], p); p += tokens[id].length; }
|
| 60 |
+
return new TextDecoder().decode(out);
|
| 61 |
+
}
|
b/818d57be07161f271298770ffe37855d76d52efc0525fe1f56371cc35cc4474d
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// quant-floor-eval.mjs — C: make "4-bit is the floor for POST-HOC quant" reproducible instead of asserted.
|
| 2 |
+
// It measures the per-bit-width reconstruction error of naive symmetric per-block quantization (GGUF-style
|
| 3 |
+
// 32-wide blocks, absmax scale) on a realistic weight distribution, and shows the error CLIFF below 4 bits.
|
| 4 |
+
// This is a labeled RECONSTRUCTION PROXY, not an end-task eval — it isolates the quantizer's own damage. The
|
| 5 |
+
// real production path (compile2bit.mjs) confirms the mechanism: sub-4-bit needs full QuIP#-grade incoherence +
|
| 6 |
+
// a per-layer Hessian, and only a PROXY embedding Hessian exists here (no GPU calibration box). The two regimes:
|
| 7 |
+
// • post-hoc quant of a normal fp model below 4-bit → collapses (this script) → floor = 4-bit.
|
| 8 |
+
// • NATIVELY-TERNARY BitNet → 2-bit runs with bit-exact parity (committed: gguf-forge-tq2 / -bitnet tests).
|
| 9 |
+
// Pure Node, deterministic (seeded), no model download. Every number is computed in this run.
|
| 10 |
+
|
| 11 |
+
let pass = 0, fail = 0;
|
| 12 |
+
const ok = (c, m) => { console.log((c ? " ok " : " XX ") + m); c ? pass++ : fail++; };
|
| 13 |
+
|
| 14 |
+
// deterministic Gaussian weights (Box–Muller over a seeded LCG) — the standard proxy for transformer weights.
|
| 15 |
+
const lcg = (seed) => { let s = (seed >>> 0) || 1; return () => { s = (Math.imul(s, 1103515245) + 12345) >>> 0; return s / 4294967296; }; };
|
| 16 |
+
const rnd = lcg(12345);
|
| 17 |
+
const gauss = () => { let u = 0, v = 0; while (u === 0) u = rnd(); while (v === 0) v = rnd(); return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v); };
|
| 18 |
+
const N = 1 << 20, BLK = 32; // 1M weights, 32-wide quant blocks
|
| 19 |
+
const W = new Float64Array(N); for (let i = 0; i < N; i++) W[i] = gauss() * 0.02; // ~N(0, 0.02) like real weights
|
| 20 |
+
|
| 21 |
+
// symmetric per-block round-trip at `bits`; returns reconstruction RMSE / signal-RMS = relative error.
|
| 22 |
+
function roundTripRelErr(bits) {
|
| 23 |
+
const qmax = (1 << (bits - 1)) - 1; // signed: ±qmax (e.g. 4-bit → ±7, 2-bit → ±1)
|
| 24 |
+
let se = 0, sig = 0;
|
| 25 |
+
for (let b = 0; b < N; b += BLK) {
|
| 26 |
+
let amax = 0; for (let i = 0; i < BLK; i++) { const a = Math.abs(W[b + i]); if (a > amax) amax = a; }
|
| 27 |
+
const scale = amax > 0 ? amax / qmax : 1;
|
| 28 |
+
for (let i = 0; i < BLK; i++) {
|
| 29 |
+
const w = W[b + i];
|
| 30 |
+
const q = Math.max(-qmax, Math.min(qmax, Math.round(w / scale)));
|
| 31 |
+
const r = q * scale, e = w - r;
|
| 32 |
+
se += e * e; sig += w * w;
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
return Math.sqrt(se / N) / Math.sqrt(sig / N);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
console.log("post-hoc symmetric per-block quant — reconstruction error vs fp (lower = better):\n");
|
| 39 |
+
console.log(" bits levels relative-error SNR(dB)");
|
| 40 |
+
const rel = {};
|
| 41 |
+
for (const bits of [8, 6, 5, 4, 3, 2]) {
|
| 42 |
+
const e = roundTripRelErr(bits); rel[bits] = e;
|
| 43 |
+
const snr = -20 * Math.log10(e);
|
| 44 |
+
console.log(` ${bits} ±${String((1 << (bits - 1)) - 1).padStart(3)} ${(e * 100).toFixed(2).padStart(7)} % ${snr.toFixed(1).padStart(6)}`);
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
console.log("");
|
| 48 |
+
// monotonic degradation + a sharp drop below 4-bit is the whole point.
|
| 49 |
+
ok(rel[8] < rel[6] && rel[6] < rel[5] && rel[5] < rel[4] && rel[4] < rel[3] && rel[3] < rel[2], "error increases monotonically as bits fall");
|
| 50 |
+
ok(rel[4] < 0.12, `naive 4-bit error is moderate (${(rel[4] * 100).toFixed(2)} %) — the lowest usable tier; real GGUF k-quant (Q4_K superblocks) does better still`);
|
| 51 |
+
ok(rel[3] > rel[4] * 1.7, `3-bit error jumps vs 4-bit (${(rel[3] * 100).toFixed(2)} % vs ${(rel[4] * 100).toFixed(2)} %)`);
|
| 52 |
+
ok(rel[2] > 0.25, `2-bit error is severe (${(rel[2] * 100).toFixed(2)} %) — naive post-hoc 2-bit collapses`);
|
| 53 |
+
ok(rel[2] / rel[4] > 5, `2-bit is >5× worse than 4-bit (${(rel[2] / rel[4]).toFixed(1)}×) — the floor is 4-bit for post-hoc quant`);
|
| 54 |
+
|
| 55 |
+
console.log(`\nREGIME LABELS (honest):`);
|
| 56 |
+
console.log(` • This proxy isolates the quantizer's own error. Real GGUF k-quants (Q4_K…) add codebooks/superblocks,`);
|
| 57 |
+
console.log(` so 4-bit stays usable — but sub-4-bit still needs QuIP#-grade incoherence + a per-layer Hessian to`);
|
| 58 |
+
console.log(` survive; compile2bit.mjs ships only a PROXY embedding Hessian (no GPU calibration box) → research-grade.`);
|
| 59 |
+
console.log(` • EXCEPTION — natively-ternary BitNet: its 2-bit is bit-exact (committed: gguf-forge-tq2 / -bitnet tests).`);
|
| 60 |
+
console.log(` "sub-4-bit fails" is therefore POST-HOC-quant-specific, not a blanket claim.`);
|
| 61 |
+
|
| 62 |
+
console.log(`\n${pass}/${pass + fail}${fail ? " FAIL" : " — WITNESSED: post-hoc quant below 4 bits collapses (measured), so 4-bit is the realistic floor for a normal fp model; natively-ternary BitNet 2-bit is the labeled exception, proven elsewhere by parity tests."}`);
|
| 63 |
+
process.exit(fail ? 1 : 0);
|