From 40d67c1d6b40ce758d22c5abeb33d3e1c1c655f6 Mon Sep 17 00:00:00 2001 From: jenstandstad Date: Wed, 10 Jun 2026 11:48:40 +0200 Subject: [PATCH] Initial commit --- .gitignore | 2 + README.md | 11 + dist/demographic-wave.iife.js | 8 + dist/demographic-wave.iife.js.map | 1 + glitch.manifest.json | 15 + index.html | 12 + package-lock.json | 2919 +++++++++++++++++++++++++++++ package.json | 49 + src/Component.tsx | 460 +++++ src/dev-theme.css | 49 + src/dev.tsx | 51 + src/index.tsx | 70 + src/styles.module.css | 494 +++++ src/types.ts | 59 + src/vite-env.d.ts | 1 + tsconfig.json | 30 + vite.config.ts | 32 + 17 files changed, 4263 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 dist/demographic-wave.iife.js create mode 100644 dist/demographic-wave.iife.js.map create mode 100644 glitch.manifest.json create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/Component.tsx create mode 100644 src/dev-theme.css create mode 100644 src/dev.tsx create mode 100644 src/index.tsx create mode 100644 src/styles.module.css create mode 100644 src/types.ts create mode 100644 src/vite-env.d.ts create mode 100644 tsconfig.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2752eb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..baad6bf --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Demographic Wave + +Standalone Glitch University component that simulates how a large generation moves through age bands and changes which cohort's policy preferences dominate. + +## Development + +- `npm install` +- `npm run dev` +- `npm run build` + +The component follows the Glitch Component contract and registers itself as `window.GlitchComponents["demographic-wave"]` when loaded from the built IIFE bundle. diff --git a/dist/demographic-wave.iife.js b/dist/demographic-wave.iife.js new file mode 100644 index 0000000..4071353 --- /dev/null +++ b/dist/demographic-wave.iife.js @@ -0,0 +1,8 @@ +(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode("._wrapper_8in6g_1{--gc-bg: var(--color-bg, #0a0a0f);--gc-bg-secondary: var(--color-bg-secondary, #12121a);--gc-text: var(--color-text, #e8e8ec);--gc-text-muted: var(--color-text-muted, #9999a8);--gc-primary: var(--color-primary, #6366f1);--gc-accent: var(--color-accent, #22d3ee);--gc-border: var(--color-border, #2a2a3a);--gc-font-main: var(--font-main, system-ui, sans-serif);--gc-font-display: var(--font-display, var(--gc-font-main));--gc-font-mono: var(--font-mono, monospace);--gc-shell-padding: clamp(8px, 2vw, 18px);width:100%;min-height:100dvh;display:grid;place-items:center;padding:var(--gc-shell-padding);box-sizing:border-box}._wrapper_8in6g_1 *,._wrapper_8in6g_1 *:before,._wrapper_8in6g_1 *:after{box-sizing:inherit}._frame_8in6g_27{position:relative;width:min(100%,calc((100dvh - (var(--gc-shell-padding) * 2)) * 16 / 9));max-height:calc(100dvh - (var(--gc-shell-padding) * 2));aspect-ratio:16 / 9;display:grid;grid-template-rows:auto minmax(0,1fr) auto auto;gap:.5em;overflow:hidden;padding:1em;color:var(--gc-text);font-family:var(--gc-font-main);font-size:clamp(10px,1.12cqw,18px);line-height:1.25;background:radial-gradient(circle at 12% 10%,color-mix(in srgb,var(--gc-primary) 26%,transparent),transparent 34%),radial-gradient(circle at 86% 16%,color-mix(in srgb,var(--gc-accent) 18%,transparent),transparent 30%),linear-gradient(145deg,var(--gc-bg),var(--gc-bg-secondary));border:1px solid color-mix(in srgb,var(--gc-border) 74%,transparent);box-shadow:inset 0 0 0 1px #ffffff0a,0 18px 48px #00000057;container-type:inline-size}._header_8in6g_52,._stageGrid_8in6g_53,._readoutRow_8in6g_54,._proofHeader_8in6g_55,._timeline_8in6g_56,._controls_8in6g_57,._legend_8in6g_58,._meter_8in6g_59{display:flex;align-items:center}._header_8in6g_52,._readoutRow_8in6g_54,._proofHeader_8in6g_55,._meter_8in6g_59{justify-content:space-between;gap:1em}._label_8in6g_72{display:block;margin:0 0 .25em;color:color-mix(in srgb,var(--gc-accent) 80%,white);font-family:var(--gc-font-mono);font-size:.62em;font-weight:600;letter-spacing:.14em;text-transform:uppercase}._controls_8in6g_57{gap:.45em;justify-content:stretch;width:100%}._iconButton_8in6g_89,._modeButton_8in6g_90,._completeButton_8in6g_91{border:1px solid color-mix(in srgb,var(--gc-border) 78%,transparent);color:var(--gc-text);font:inherit;font-family:var(--gc-font-mono);font-size:.68em;font-weight:600;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;transition:transform .12s ease,border-color .12s ease,background-color .12s ease}._iconButton_8in6g_89:hover,._modeButton_8in6g_90:hover,._completeButton_8in6g_91:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--gc-accent) 62%,var(--gc-border))}._iconButton_8in6g_89{min-width:3.7em;min-height:2.75em;background:#0a0e18b8}._modeButton_8in6g_90{min-height:2.75em;padding:0 .85em;background:#0a0e1894}._modeActive_8in6g_123{color:#090b10;background:linear-gradient(90deg,#e7b84f,color-mix(in srgb,var(--gc-accent) 58%,#e7b84f));border-color:#ffffff8f}._stageGrid_8in6g_53{min-height:0;display:grid;grid-template-columns:minmax(0,1.36fr) minmax(12em,.64fr);align-items:stretch;gap:.65em}._wavePanel_8in6g_137,._eventPanel_8in6g_138,._proofPanel_8in6g_139,._timeline_8in6g_56{min-width:0;border:1px solid color-mix(in srgb,var(--gc-border) 76%,transparent);background:#0509128a}._wavePanel_8in6g_137{min-height:0;display:grid;grid-template-rows:auto minmax(0,1fr);gap:.45em;padding:.7em}._year_8in6g_154{display:block;font-family:var(--gc-font-display);font-size:1.85em;line-height:.9}._legend_8in6g_58{gap:.4em;justify-content:end;color:var(--gc-text-muted);font-family:var(--gc-font-mono);font-size:.62em;letter-spacing:.05em;text-transform:uppercase}._legend_8in6g_58 i{display:inline-block;width:.8em;height:.8em;margin-right:0;border-radius:999px}._track_8in6g_179{position:relative;min-height:0;overflow:hidden;border:1px solid color-mix(in srgb,var(--gc-border) 70%,transparent);background:linear-gradient(90deg,rgb(113 166 210 / 6%),transparent 32%,rgb(231 184 79 / 8%) 62%,rgb(126 224 160 / 7%)),#070b11c7}._canvas_8in6g_189{display:block;width:100%;height:100%}._ageMarks_8in6g_195,._stageMarks_8in6g_196{position:absolute;left:7%;right:7%;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));color:#e8e8ec99;font-family:var(--gc-font-mono);font-size:.58em;font-weight:600;letter-spacing:.08em;pointer-events:none;text-transform:uppercase}._ageMarks_8in6g_195{top:.8em}._stageMarks_8in6g_196{bottom:.75em;text-align:center}._eventPanel_8in6g_138{display:flex;align-items:center;justify-content:space-between;flex-direction:row;gap:1em;padding:.9em}._eventPanel_8in6g_138 h3,._proofHeader_8in6g_55 h3{margin:0;color:var(--gc-text);font-family:var(--gc-font-display);letter-spacing:.04em;text-transform:uppercase}._eventPanel_8in6g_138 h3{font-size:1.1em}._eventPanel_8in6g_138 p{display:none;margin:.65em 0 0;color:color-mix(in srgb,var(--gc-text-muted) 86%,white);font-size:.88em}._meter_8in6g_59{margin-top:0;padding-top:0;border-top:0;color:var(--gc-text-muted);font-family:var(--gc-font-mono);font-size:.7em;letter-spacing:.08em;text-transform:uppercase}._meter_8in6g_59 strong{color:#e7b84f;font-family:var(--gc-font-display);font-size:2.2em;letter-spacing:.02em}._timeline_8in6g_56{display:grid;grid-template-columns:minmax(0,1fr) 3.5em;gap:.8em;padding:.62em .8em}._timeline_8in6g_56 ._label_8in6g_72{margin:0}._timeline_8in6g_56 input{width:100%;accent-color:#e7b84f}._timeline_8in6g_56 strong{text-align:right;font-family:var(--gc-font-mono);font-size:.72em}._proofPanel_8in6g_139{display:grid;grid-template-columns:minmax(0,1fr);gap:.8em;padding:.8em}._proofHeader_8in6g_55{grid-column:1 / -1}._proofHeader_8in6g_55 h3{display:none}._modePill_8in6g_304{white-space:nowrap;border:1px solid color-mix(in srgb,var(--gc-border) 72%,transparent);min-width:3em;padding:.45em .7em;color:var(--gc-text-muted);font-family:var(--gc-font-mono);font-size:.62em;letter-spacing:.08em;text-transform:uppercase}._proofActions_8in6g_316{display:flex;align-items:center;gap:.45em}._bars_8in6g_322{display:grid;gap:.45em}._barRow_8in6g_327{display:grid;grid-template-columns:1.3em minmax(0,1fr) 2.2em;align-items:center;gap:.65em;color:var(--gc-text-muted);font-family:var(--gc-font-mono);font-size:.68em;letter-spacing:.05em;text-transform:uppercase}._barTrack_8in6g_339{height:1.35em;overflow:hidden;border:1px solid color-mix(in srgb,var(--gc-border) 76%,transparent);background:#03060cb8}._barFill_8in6g_346{height:100%;transition:width .18s ease}._barRow_8in6g_327 strong{color:var(--gc-text);text-align:right}._silent_8in6g_356{background:#71a6d2}._boomer_8in6g_360{background:#e7b84f}._post_8in6g_364{background:#7ee0a0}._completeButton_8in6g_91{min-height:2.35em;padding:0 .8em;background:color-mix(in srgb,var(--gc-primary) 28%,rgb(5 9 18))}._completeButton_8in6g_91:disabled{cursor:default;opacity:.68;transform:none}@media(orientation:portrait){._frame_8in6g_27{width:min(100%,calc((100dvh - (var(--gc-shell-padding) * 2)) / 2));aspect-ratio:1 / 2;grid-template-rows:auto minmax(0,1.24fr) auto minmax(0,.56fr);font-size:clamp(10px,3.2cqw,16px)}._title_8in6g_388{font-size:1.2em}._header_8in6g_52{align-items:flex-start;flex-direction:column;gap:.55em}._controls_8in6g_57{width:100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}._iconButton_8in6g_89,._modeButton_8in6g_90{min-height:2.35em}._stageGrid_8in6g_53{grid-template-columns:1fr;grid-template-rows:minmax(0,1.25fr) auto}._wavePanel_8in6g_137{padding:.75em}._readoutRow_8in6g_54{align-items:flex-start;flex-direction:column;gap:.45em}._legend_8in6g_58{justify-content:start}._eventPanel_8in6g_138{min-height:0;padding:.72em}._eventPanel_8in6g_138 h3{font-size:1em}._eventPanel_8in6g_138 p{margin-top:.42em;font-size:.78em;line-height:1.22}._meter_8in6g_59{padding-top:.48em}._meter_8in6g_59 strong{font-size:1.7em}._stageMarks_8in6g_196{display:none}._proofPanel_8in6g_139{grid-template-columns:1fr;gap:.5em;padding:.65em}._proofHeader_8in6g_55{align-items:flex-start;flex-direction:column;gap:.45em}._proofActions_8in6g_316{width:100%;display:grid;grid-template-columns:minmax(0,1fr) auto}._proofHeader_8in6g_55 h3{font-size:.82em}._barRow_8in6g_327{grid-template-columns:1fr 2.2em;gap:.32em;font-size:.6em}._barRow_8in6g_327 span{grid-column:1 / -1}._barTrack_8in6g_339{height:.85em}._completeButton_8in6g_91{min-height:2.35em}}")),document.head.appendChild(e)}}catch(n){console.error("vite-plugin-css-injected-by-js",n)}})(); +var GlitchComponent=(function(J,d){"use strict";var X={exports:{}},z={};var ce;function he(){if(ce)return z;ce=1;var r=Symbol.for("react.transitional.element"),u=Symbol.for("react.fragment");function p(m,f,b){var h=null;if(b!==void 0&&(h=""+b),f.key!==void 0&&(h=""+f.key),"key"in f){b={};for(var i in f)i!=="key"&&(b[i]=f[i])}else b=f;return f=b.ref,{$$typeof:r,type:m,key:h,ref:f!==void 0?f:null,props:b}}return z.Fragment=u,z.jsx=p,z.jsxs=p,z}var D={};var le;function ge(){return le||(le=1,process.env.NODE_ENV!=="production"&&(function(){function r(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===I?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case N:return"Fragment";case R:return"Profiler";case x:return"StrictMode";case G:return"Suspense";case P:return"SuspenseList";case L:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case y:return"Portal";case Y:return e.displayName||"Context";case A:return(e._context.displayName||"Context")+".Consumer";case F:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case ae:return t=e.displayName||null,t!==null?t:r(e.type)||"Memo";case M:t=e._payload,e=e._init;try{return r(e(t))}catch{}}return null}function u(e){return""+e}function p(e){try{u(e);var t=!1}catch{t=!0}if(t){t=console;var o=t.error,l=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return o.call(t,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",l),u(e)}}function m(e){if(e===N)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===M)return"<...>";try{var t=r(e);return t?"<"+t+">":"<...>"}catch{return"<...>"}}function f(){var e=H.A;return e===null?null:e.getOwner()}function b(){return Error("react-stack-top-frame")}function h(e){if(B.call(e,"key")){var t=Object.getOwnPropertyDescriptor(e,"key").get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function i(e,t){function o(){V||(V=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}o.isReactWarning=!0,Object.defineProperty(e,"key",{get:o,configurable:!0})}function g(){var e=r(this.type);return K[e]||(K[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function c(e,t,o,l,w,oe){var _=o.ref;return e={$$typeof:S,type:e,key:t,props:o,_owner:l},(_!==void 0?_:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:g}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:w}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:oe}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function E(e,t,o,l,w,oe){var _=t.children;if(_!==void 0)if(l)if(U(_)){for(l=0;l<_.length;l++)v(_[l]);Object.freeze&&Object.freeze(_)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else v(_);if(B.call(t,"key")){_=r(e);var W=Object.keys(t).filter(function(xe){return xe!=="key"});l=0 +React keys must be passed directly to JSX without using spread: + let props = %s; + <%s key={someKey} {...props} />`,l,_,W,_),a[_+l]=!0)}if(_=null,o!==void 0&&(p(o),_=""+o),h(t)&&(p(t.key),_=""+t.key),"key"in t){o={};for(var se in t)se!=="key"&&(o[se]=t[se])}else o=t;return _&&i(o,typeof e=="function"?e.displayName||e.name||"Unknown":e),c(e,_,o,f(),w,oe)}function v(e){T(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===M&&(e._payload.status==="fulfilled"?T(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function T(e){return typeof e=="object"&&e!==null&&e.$$typeof===S}var k=d,S=Symbol.for("react.transitional.element"),y=Symbol.for("react.portal"),N=Symbol.for("react.fragment"),x=Symbol.for("react.strict_mode"),R=Symbol.for("react.profiler"),A=Symbol.for("react.consumer"),Y=Symbol.for("react.context"),F=Symbol.for("react.forward_ref"),G=Symbol.for("react.suspense"),P=Symbol.for("react.suspense_list"),ae=Symbol.for("react.memo"),M=Symbol.for("react.lazy"),L=Symbol.for("react.activity"),I=Symbol.for("react.client.reference"),H=k.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,B=Object.prototype.hasOwnProperty,U=Array.isArray,j=console.createTask?console.createTask:function(){return null};k={react_stack_bottom_frame:function(e){return e()}};var V,K={},q=k.react_stack_bottom_frame.bind(k,b)(),$=j(m(b)),a={};D.Fragment=N,D.jsx=function(e,t,o){var l=1e4>H.recentlyCreatedOwnerStacks++;return E(e,t,o,!1,l?Error("react-stack-top-frame"):q,l?j(m(e)):$)},D.jsxs=function(e,t,o){var l=1e4>H.recentlyCreatedOwnerStacks++;return E(e,t,o,!0,l?Error("react-stack-top-frame"):q,l?j(m(e)):$)}})()),D}var ie;function ve(){return ie||(ie=1,process.env.NODE_ENV==="production"?X.exports=he():X.exports=ge()),X.exports}var n=ve();const s={wrapper:"_wrapper_8in6g_1",frame:"_frame_8in6g_27",header:"_header_8in6g_52",stageGrid:"_stageGrid_8in6g_53",readoutRow:"_readoutRow_8in6g_54",proofHeader:"_proofHeader_8in6g_55",timeline:"_timeline_8in6g_56",controls:"_controls_8in6g_57",legend:"_legend_8in6g_58",meter:"_meter_8in6g_59",label:"_label_8in6g_72",iconButton:"_iconButton_8in6g_89",modeButton:"_modeButton_8in6g_90",completeButton:"_completeButton_8in6g_91",modeActive:"_modeActive_8in6g_123",wavePanel:"_wavePanel_8in6g_137",eventPanel:"_eventPanel_8in6g_138",proofPanel:"_proofPanel_8in6g_139",year:"_year_8in6g_154",track:"_track_8in6g_179",canvas:"_canvas_8in6g_189",ageMarks:"_ageMarks_8in6g_195",stageMarks:"_stageMarks_8in6g_196",modePill:"_modePill_8in6g_304",proofActions:"_proofActions_8in6g_316",bars:"_bars_8in6g_322",barRow:"_barRow_8in6g_327",barTrack:"_barTrack_8in6g_339",barFill:"_barFill_8in6g_346",silent:"_silent_8in6g_356",boomer:"_boomer_8in6g_360",post:"_post_8in6g_364",title:"_title_8in6g_388"},ee=Array.from({length:82},(r,u)=>1928+u),Z=1957,ue=1946,te=2038,ne=[{min:0,title:"SCHOOLS",copy:"A large child cohort pulls classrooms, teachers, and local budgets toward youth infrastructure.",policy:"Education and schools"},{min:18,title:"CAMPUS",copy:"The wave enters college and first jobs. Credentials, housing, and entry labor markets start to flex.",policy:"Universities and entry jobs"},{min:30,title:"FAMILY",copy:"The cohort becomes parents and buyers. Homes, childcare, transport, and suburbs absorb the demand.",policy:"Housing and family subsidies"},{min:50,title:"VOTES",copy:"High turnout meets cohort size. Tax, asset, and stability preferences become easier to pass.",policy:"Tax and asset rules"},{min:65,title:"RETIREMENT",copy:"The wave reaches old age. Health care, pensions, and age-linked spending gain political gravity.",policy:"Pensions and health care"}],O=[{key:"silent",label:"Silent generation"},{key:"boomer",label:"Boomers"},{key:"post",label:"Later cohorts"}],C=(r,u,p)=>Math.min(p,Math.max(u,r)),Q=(r,u)=>typeof r=="number"?r:u,de=(r,u)=>typeof r=="boolean"?r:u,me=r=>r>=1946&&r<=1964?"boomer":r<1946?"silent":"post",fe=r=>r<18||r>88?0:r<30?.42:r<45?.62:r<65?.82:.9-Math.max(0,r-72)*.018,pe=r=>ne.reduce((u,p)=>r>=p.min?p:u,ne[0]),_e=(r,u)=>p=>{if(r)return 1;const m=Math.exp(-Math.pow((p-Z)/7.5,2))*u,f=Math.exp(-Math.pow((p-1974)/8,2))*-.22,b=Math.exp(-Math.pow((p-1991)/9,2))*.18;return Math.max(.5,.78+m+f+b)};function ye(r,u,p,m,f){const b=r.getBoundingClientRect(),h=window.devicePixelRatio||1,i=b.width,g=b.height;r.width=Math.floor(i*h),r.height=Math.floor(g*h);const c=r.getContext("2d");if(!c)return;c.setTransform(h,0,0,h,0,0),c.clearRect(0,0,i,g);const E=i*.07,v=g*.72,T=g*.68,k=_e(p,m);c.lineWidth=1,c.strokeStyle=f.grid;for(let x=0;x<=4;x+=1){const R=E+x/4*(i-E*2);c.beginPath(),c.moveTo(R,g*.14),c.lineTo(R,g*.88),c.stroke()}for(const x of ee){const R=u-x;if(R<0||R>88)continue;const A=k(x),Y=E+R/88*(i-E*2),F=Math.max(4,i*.006+A*i*.009),G=v-A*T*.52-Math.sin((x+u)*.18)*g*.025,P=me(x);c.beginPath(),c.arc(Y,G,F,0,Math.PI*2),c.fillStyle=f[P],c.globalAlpha=P==="boomer"?.94:.68,c.fill(),c.globalAlpha=1}const S=u-Z;if(S<0||S>88)return;const y=E+S/88*(i-E*2),N=v-k(Z)*T*.52;c.beginPath(),c.moveTo(y,g*.16),c.lineTo(y,g*.9),c.strokeStyle=f.boomer,c.globalAlpha=.42,c.lineWidth=2,c.stroke(),c.globalAlpha=1,c.beginPath(),c.arc(y,N,Math.max(16,i*.035),0,Math.PI*2),c.strokeStyle=f.accent,c.lineWidth=3,c.stroke()}function be({config:r,onComplete:u,onProgress:p,theme:m,className:f,host:b}){const h=r.params,i=C(Math.round(Q(h.startYear,ue)),ue,te),g=C(Math.round(Q(h.endYear,te)),i+1,te),c=C(Q(h.animationSpeed,1),.25,3),E=C(Q(h.waveScale,1.15),.2,1.8),[v,T]=d.useState(i),[k,S]=d.useState(!0),[y,N]=d.useState(()=>de(h.startEqualized,!1)),[x,R]=d.useState(!1),A=d.useRef(null),Y=d.useRef(0),F=d.useMemo(()=>({silent:"#71a6d2",boomer:"#e7b84f",post:"#7ee0a0",accent:m?.accent??"#22d3ee",grid:"rgba(232, 232, 236, 0.13)",text:m?.text??"#e8e8ec"}),[m?.accent,m?.text]),G=d.useMemo(()=>({"--gc-primary":m?.primary,"--gc-accent":m?.accent,"--gc-bg":m?.bg,"--gc-bg-secondary":m?.bgSecondary,"--gc-text":m?.text,"--gc-text-muted":m?.textMuted,"--gc-border":m?.border}),[m]),P=d.useMemo(()=>_e(y,E),[y,E]),ae=v-Z,M=pe(C(ae,0,88)),L=d.useMemo(()=>{const a=Object.fromEntries(ne.map(t=>[t.policy,0]));for(const t of ee){const o=v-t;if(o<0||o>88)continue;const l=P(t)*fe(o);a[pe(o).policy]+=l}const e=Object.values(a).reduce((t,o)=>t+o,0);return e>0?Math.round(a[M.policy]/e*100):0},[M.policy,P,v]),I=d.useMemo(()=>{const a=Object.fromEntries(O.map(e=>[e.key,0]));for(let e=i;e<=v;e+=1){const t=Object.fromEntries(O.map(l=>[l.key,0]));for(const l of ee){const w=e-l;w<18||w>88||(t[me(l)]+=P(l)*fe(w))}const o=O.reduce((l,w)=>t[w.key]>t[l.key]?w:l,O[0]);t[o.key]>0&&(a[o.key]+=1)}return a},[P,i,v]),H=Math.max(...Object.values(I),1),B=Math.round((v-i)/Math.max(1,g-i)*100),U=d.useCallback(()=>{A.current&&ye(A.current,v,y,E,F)},[y,F,E,v]);d.useEffect(()=>{T(a=>C(a,i,g))},[g,i]),d.useEffect(()=>{N(de(h.startEqualized,!1))},[h.startEqualized]),d.useEffect(()=>{p?.(B)},[p,B]),d.useEffect(()=>{U();const a=A.current;if(!a)return;const e=new ResizeObserver(U);return e.observe(a),()=>e.disconnect()},[U]),d.useEffect(()=>{let a=0;const e=t=>{const o=260/c;k&&t-Y.current>o&&(T(l=>l>=g?i:l+1),Y.current=t),a=window.requestAnimationFrame(e)};return a=window.requestAnimationFrame(e),()=>window.cancelAnimationFrame(a)},[c,g,k,i]);const j=d.useCallback(a=>{b?.playSound?.("ui.button_click",{target:a,component:r.name})},[r.name,b]),V=d.useCallback(a=>{j(a?"equal-generations":"boomer-wave"),N(a)},[j]),K=d.useCallback(a=>{j("timeline"),S(!1),T(Number(a.currentTarget.value))},[j]),q=d.useCallback(()=>{x||(R(!0),j("complete"),u({success:!0,score:100,data:{year:v,mode:y?"equal-generations":"boomer-wave",generationWins:I,currentPressure:L,configId:r.id,completedAt:new Date().toISOString()}}))},[x,r.id,L,y,I,u,j,v]),$=f?`${s.wrapper} ${f}`:s.wrapper;return n.jsx("section",{className:$,style:G,"aria-label":"Demographic wave simulator",children:n.jsxs("div",{className:s.frame,children:[n.jsx("header",{className:s.header,children:n.jsxs("div",{className:s.controls,"aria-label":"Simulation controls",children:[n.jsx("button",{className:s.iconButton,type:"button",onClick:()=>S(a=>!a),children:k?"II":">"}),n.jsx("button",{className:`${s.modeButton} ${y?"":s.modeActive}`,type:"button",onClick:()=>V(!1),children:"W"}),n.jsx("button",{className:`${s.modeButton} ${y?s.modeActive:""}`,type:"button",onClick:()=>V(!0),children:"="})]})}),n.jsxs("div",{className:s.stageGrid,children:[n.jsxs("div",{className:s.wavePanel,children:[n.jsxs("div",{className:s.readoutRow,children:[n.jsx("div",{children:n.jsx("strong",{className:s.year,children:v})}),n.jsx("div",{className:s.legend,children:O.map(a=>n.jsx("span",{children:n.jsx("i",{className:s[a.key]})},a.key))})]}),n.jsxs("div",{className:s.track,children:[n.jsxs("div",{className:s.ageMarks,"aria-hidden":"true",children:[n.jsx("span",{children:"0"}),n.jsx("span",{children:"20"}),n.jsx("span",{children:"40"}),n.jsx("span",{children:"60"}),n.jsx("span",{children:"80"})]}),n.jsx("canvas",{ref:A,className:s.canvas}),n.jsxs("div",{className:s.stageMarks,"aria-hidden":"true",children:[n.jsx("span",{children:"Kids"}),n.jsx("span",{children:"Campus"}),n.jsx("span",{children:"Work"}),n.jsx("span",{children:"Assets"}),n.jsx("span",{children:"Care"})]})]})]}),n.jsxs("aside",{className:s.eventPanel,children:[n.jsx("h3",{children:M.title}),n.jsx("div",{className:s.meter,children:n.jsxs("strong",{children:[L,"%"]})})]})]}),n.jsxs("div",{className:s.timeline,children:[n.jsx("input",{"aria-label":"Simulation year",type:"range",min:i,max:g,value:v,onChange:K}),n.jsxs("strong",{children:[B,"%"]})]}),n.jsxs("section",{className:s.proofPanel,"aria-label":"Accepted policy preference winners",children:[n.jsxs("div",{className:s.proofHeader,children:[n.jsx("div",{children:n.jsx("h3",{children:"Policy wins"})}),n.jsxs("div",{className:s.proofActions,children:[n.jsx("span",{className:s.modePill,children:y?"=":"W"}),n.jsx("button",{className:s.completeButton,type:"button",onClick:q,disabled:x,children:x?"OK":"✓"})]})]}),n.jsx("div",{className:s.bars,children:O.map(a=>{const e=Math.round(I[a.key]/H*100);return n.jsxs("div",{className:s.barRow,children:[n.jsx("span",{children:a.key==="silent"?"S":a.key==="boomer"?"B":"L"}),n.jsx("div",{className:s.barTrack,children:n.jsx("div",{className:`${s.barFill} ${s[a.key]}`,style:{width:`${e}%`}})}),n.jsx("strong",{children:e})]},a.key)})})]})]})})}const re={name:"demographic-wave",displayName:"Demographic Wave",version:"1.0.0",paramSchema:{startYear:{type:"range",label:"Start Year",default:1946,min:1946,max:2028,step:1},endYear:{type:"range",label:"End Year",default:2038,min:1964,max:2038,step:1},animationSpeed:{type:"range",label:"Animation Speed",default:1,min:.25,max:3,step:.25},waveScale:{type:"range",label:"Boomer Wave Scale",default:1.15,min:.2,max:1.8,step:.05},startEqualized:{type:"boolean",label:"Start Equalized",default:!1}},defaultParams:{startYear:1946,endYear:2038,animationSpeed:1,waveScale:1.15,startEqualized:!1}};return typeof window<"u"&&(window.GlitchComponents??={},window.GlitchComponents[re.name]={default:be,metadata:re}),J.default=be,J.metadata=re,Object.defineProperties(J,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),J})({},React); +//# sourceMappingURL=demographic-wave.iife.js.map diff --git a/dist/demographic-wave.iife.js.map b/dist/demographic-wave.iife.js.map new file mode 100644 index 0000000..8bc0136 --- /dev/null +++ b/dist/demographic-wave.iife.js.map @@ -0,0 +1 @@ +{"version":3,"file":"demographic-wave.iife.js","sources":["../node_modules/react/cjs/react-jsx-runtime.production.js","../node_modules/react/cjs/react-jsx-runtime.development.js","../node_modules/react/jsx-runtime.js","../src/Component.tsx","../src/index.tsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport styles from './styles.module.css'\nimport type { GlitchComponentProps } from './types'\n\ntype GenerationKey = 'silent' | 'boomer' | 'post'\n\ninterface Stage {\n min: number\n title: string\n copy: string\n policy: string\n}\n\ninterface ComponentParams {\n startYear?: number\n endYear?: number\n animationSpeed?: number\n waveScale?: number\n startEqualized?: boolean\n}\n\ninterface Palette {\n silent: string\n boomer: string\n post: string\n accent: string\n grid: string\n text: string\n}\n\nconst COHORT_YEARS = Array.from({ length: 82 }, (_, index) => 1928 + index)\nconst BOOMER_CENTER_YEAR = 1957\nconst MIN_YEAR = 1946\nconst MAX_YEAR = 2038\n\nconst STAGES: Stage[] = [\n {\n min: 0,\n title: 'SCHOOLS',\n copy: 'A large child cohort pulls classrooms, teachers, and local budgets toward youth infrastructure.',\n policy: 'Education and schools'\n },\n {\n min: 18,\n title: 'CAMPUS',\n copy: 'The wave enters college and first jobs. Credentials, housing, and entry labor markets start to flex.',\n policy: 'Universities and entry jobs'\n },\n {\n min: 30,\n title: 'FAMILY',\n copy: 'The cohort becomes parents and buyers. Homes, childcare, transport, and suburbs absorb the demand.',\n policy: 'Housing and family subsidies'\n },\n {\n min: 50,\n title: 'VOTES',\n copy: 'High turnout meets cohort size. Tax, asset, and stability preferences become easier to pass.',\n policy: 'Tax and asset rules'\n },\n {\n min: 65,\n title: 'RETIREMENT',\n copy: 'The wave reaches old age. Health care, pensions, and age-linked spending gain political gravity.',\n policy: 'Pensions and health care'\n }\n]\n\nconst GENERATIONS: { key: GenerationKey; label: string }[] = [\n { key: 'silent', label: 'Silent generation' },\n { key: 'boomer', label: 'Boomers' },\n { key: 'post', label: 'Later cohorts' }\n]\n\nconst clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value))\n\nconst numberParam = (value: unknown, fallback: number) => (typeof value === 'number' ? value : fallback)\n\nconst booleanParam = (value: unknown, fallback: boolean) => (typeof value === 'boolean' ? value : fallback)\n\nconst cohortFamily = (birthYear: number): GenerationKey => {\n if (birthYear >= 1946 && birthYear <= 1964) return 'boomer'\n if (birthYear < 1946) return 'silent'\n return 'post'\n}\n\nconst turnout = (age: number) => {\n if (age < 18 || age > 88) return 0\n if (age < 30) return 0.42\n if (age < 45) return 0.62\n if (age < 65) return 0.82\n return 0.9 - Math.max(0, age - 72) * 0.018\n}\n\nconst stageForAge = (age: number) =>\n STAGES.reduce((chosen, stage) => (age >= stage.min ? stage : chosen), STAGES[0])\n\nconst createCohortSize = (equalMode: boolean, waveScale: number) => (birthYear: number) => {\n if (equalMode) return 1\n\n const boomerPeak = Math.exp(-Math.pow((birthYear - BOOMER_CENTER_YEAR) / 7.5, 2)) * waveScale\n const postDip = Math.exp(-Math.pow((birthYear - 1974) / 8, 2)) * -0.22\n const echo = Math.exp(-Math.pow((birthYear - 1991) / 9, 2)) * 0.18\n return Math.max(0.5, 0.78 + boomerPeak + postDip + echo)\n}\n\nfunction drawWave(\n canvas: HTMLCanvasElement,\n year: number,\n equalMode: boolean,\n waveScale: number,\n palette: Palette\n) {\n const rect = canvas.getBoundingClientRect()\n const scale = window.devicePixelRatio || 1\n const width = rect.width\n const height = rect.height\n\n canvas.width = Math.floor(width * scale)\n canvas.height = Math.floor(height * scale)\n\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n\n ctx.setTransform(scale, 0, 0, scale, 0, 0)\n ctx.clearRect(0, 0, width, height)\n\n const padX = width * 0.07\n const base = height * 0.72\n const maxH = height * 0.68\n const sizeFor = createCohortSize(equalMode, waveScale)\n\n ctx.lineWidth = 1\n ctx.strokeStyle = palette.grid\n for (let index = 0; index <= 4; index += 1) {\n const x = padX + (index / 4) * (width - padX * 2)\n ctx.beginPath()\n ctx.moveTo(x, height * 0.14)\n ctx.lineTo(x, height * 0.88)\n ctx.stroke()\n }\n\n for (const birthYear of COHORT_YEARS) {\n const age = year - birthYear\n if (age < 0 || age > 88) continue\n\n const size = sizeFor(birthYear)\n const x = padX + (age / 88) * (width - padX * 2)\n const radius = Math.max(4, width * 0.006 + size * width * 0.009)\n const y = base - size * maxH * 0.52 - Math.sin((birthYear + year) * 0.18) * height * 0.025\n const family = cohortFamily(birthYear)\n\n ctx.beginPath()\n ctx.arc(x, y, radius, 0, Math.PI * 2)\n ctx.fillStyle = palette[family]\n ctx.globalAlpha = family === 'boomer' ? 0.94 : 0.68\n ctx.fill()\n ctx.globalAlpha = 1\n }\n\n const boomerAge = year - BOOMER_CENTER_YEAR\n if (boomerAge < 0 || boomerAge > 88) return\n\n const x = padX + (boomerAge / 88) * (width - padX * 2)\n const y = base - sizeFor(BOOMER_CENTER_YEAR) * maxH * 0.52\n\n ctx.beginPath()\n ctx.moveTo(x, height * 0.16)\n ctx.lineTo(x, height * 0.9)\n ctx.strokeStyle = palette.boomer\n ctx.globalAlpha = 0.42\n ctx.lineWidth = 2\n ctx.stroke()\n ctx.globalAlpha = 1\n\n ctx.beginPath()\n ctx.arc(x, y, Math.max(16, width * 0.035), 0, Math.PI * 2)\n ctx.strokeStyle = palette.accent\n ctx.lineWidth = 3\n ctx.stroke()\n}\n\nexport default function Component({\n config,\n onComplete,\n onProgress,\n theme,\n className,\n host\n}: GlitchComponentProps) {\n const params = config.params as ComponentParams\n const startYear = clamp(Math.round(numberParam(params.startYear, MIN_YEAR)), MIN_YEAR, MAX_YEAR)\n const endYear = clamp(Math.round(numberParam(params.endYear, MAX_YEAR)), startYear + 1, MAX_YEAR)\n const animationSpeed = clamp(numberParam(params.animationSpeed, 1), 0.25, 3)\n const waveScale = clamp(numberParam(params.waveScale, 1.15), 0.2, 1.8)\n const [year, setYear] = useState(startYear)\n const [running, setRunning] = useState(true)\n const [equalMode, setEqualMode] = useState(() => booleanParam(params.startEqualized, false))\n const [completed, setCompleted] = useState(false)\n const canvasRef = useRef(null)\n const lastTickRef = useRef(0)\n\n const palette = useMemo(() => ({\n silent: '#71a6d2',\n boomer: '#e7b84f',\n post: '#7ee0a0',\n accent: theme?.accent ?? '#22d3ee',\n grid: 'rgba(232, 232, 236, 0.13)',\n text: theme?.text ?? '#e8e8ec'\n }), [theme?.accent, theme?.text])\n\n const themeStyle = useMemo(() => ({\n '--gc-primary': theme?.primary,\n '--gc-accent': theme?.accent,\n '--gc-bg': theme?.bg,\n '--gc-bg-secondary': theme?.bgSecondary,\n '--gc-text': theme?.text,\n '--gc-text-muted': theme?.textMuted,\n '--gc-border': theme?.border\n }) as CSSProperties, [theme])\n\n const sizeFor = useMemo(() => createCohortSize(equalMode, waveScale), [equalMode, waveScale])\n\n const boomerAge = year - BOOMER_CENTER_YEAR\n const activeStage = stageForAge(clamp(boomerAge, 0, 88))\n\n const currentPressure = useMemo(() => {\n const totals = Object.fromEntries(STAGES.map((stage) => [stage.policy, 0]))\n for (const birthYear of COHORT_YEARS) {\n const age = year - birthYear\n if (age < 0 || age > 88) continue\n\n const voteWeight = sizeFor(birthYear) * turnout(age)\n totals[stageForAge(age).policy] += voteWeight\n }\n\n const total = Object.values(totals).reduce((sum, value) => sum + value, 0)\n return total > 0 ? Math.round((totals[activeStage.policy] / total) * 100) : 0\n }, [activeStage.policy, sizeFor, year])\n\n const generationWins = useMemo(() => {\n const wins = Object.fromEntries(GENERATIONS.map((generation) => [generation.key, 0])) as Record\n\n for (let targetYear = startYear; targetYear <= year; targetYear += 1) {\n const totals = Object.fromEntries(GENERATIONS.map((generation) => [generation.key, 0])) as Record\n\n for (const birthYear of COHORT_YEARS) {\n const age = targetYear - birthYear\n if (age < 18 || age > 88) continue\n totals[cohortFamily(birthYear)] += sizeFor(birthYear) * turnout(age)\n }\n\n const winner = GENERATIONS.reduce((chosen, generation) =>\n totals[generation.key] > totals[chosen.key] ? generation : chosen\n , GENERATIONS[0])\n\n if (totals[winner.key] > 0) wins[winner.key] += 1\n }\n\n return wins\n }, [sizeFor, startYear, year])\n\n const maxWins = Math.max(...Object.values(generationWins), 1)\n const progress = Math.round(((year - startYear) / Math.max(1, endYear - startYear)) * 100)\n\n const redraw = useCallback(() => {\n if (!canvasRef.current) return\n drawWave(canvasRef.current, year, equalMode, waveScale, palette)\n }, [equalMode, palette, waveScale, year])\n\n useEffect(() => {\n setYear((current) => clamp(current, startYear, endYear))\n }, [endYear, startYear])\n\n useEffect(() => {\n setEqualMode(booleanParam(params.startEqualized, false))\n }, [params.startEqualized])\n\n useEffect(() => {\n onProgress?.(progress)\n }, [onProgress, progress])\n\n useEffect(() => {\n redraw()\n const canvas = canvasRef.current\n if (!canvas) return undefined\n\n const resizeObserver = new ResizeObserver(redraw)\n resizeObserver.observe(canvas)\n return () => resizeObserver.disconnect()\n }, [redraw])\n\n useEffect(() => {\n let animationFrame = 0\n\n const step = (timestamp: number) => {\n const interval = 260 / animationSpeed\n if (running && timestamp - lastTickRef.current > interval) {\n setYear((current) => (current >= endYear ? startYear : current + 1))\n lastTickRef.current = timestamp\n }\n\n animationFrame = window.requestAnimationFrame(step)\n }\n\n animationFrame = window.requestAnimationFrame(step)\n return () => window.cancelAnimationFrame(animationFrame)\n }, [animationSpeed, endYear, running, startYear])\n\n const playClick = useCallback((target: string) => {\n host?.playSound?.('ui.button_click', { target, component: config.name })\n }, [config.name, host])\n\n const setMode = useCallback((nextEqualMode: boolean) => {\n playClick(nextEqualMode ? 'equal-generations' : 'boomer-wave')\n setEqualMode(nextEqualMode)\n }, [playClick])\n\n const handleSlider = useCallback((event: React.ChangeEvent) => {\n playClick('timeline')\n setRunning(false)\n setYear(Number(event.currentTarget.value))\n }, [playClick])\n\n const finishProof = useCallback(() => {\n if (completed) return\n\n setCompleted(true)\n playClick('complete')\n onComplete({\n success: true,\n score: 100,\n data: {\n year,\n mode: equalMode ? 'equal-generations' : 'boomer-wave',\n generationWins,\n currentPressure,\n configId: config.id,\n completedAt: new Date().toISOString()\n }\n })\n }, [completed, config.id, currentPressure, equalMode, generationWins, onComplete, playClick, year])\n\n const rootClassName = className ? `${styles.wrapper} ${className}` : styles.wrapper\n\n return (\n
\n
\n
\n
\n \n setMode(false)}\n >\n W\n \n setMode(true)}\n >\n =\n \n
\n
\n\n
\n
\n
\n
\n {year}\n
\n
\n {GENERATIONS.map((generation) => (\n \n \n \n ))}\n
\n
\n\n
\n
\n 0\n 20\n 40\n 60\n 80\n
\n \n
\n Kids\n Campus\n Work\n Assets\n Care\n
\n
\n
\n\n \n
\n\n
\n \n {progress}%\n
\n\n
\n
\n
\n

Policy wins

\n
\n
\n {equalMode ? '=' : 'W'}\n \n
\n
\n\n
\n {GENERATIONS.map((generation) => {\n const percent = Math.round((generationWins[generation.key] / maxWins) * 100)\n return (\n
\n {generation.key === 'silent' ? 'S' : generation.key === 'boomer' ? 'B' : 'L'}\n
\n \n
\n {percent}\n
\n )\n })}\n
\n
\n
\n
\n )\n}\n","import Component from './Component'\nimport type { GlitchComponentMetadata } from './types'\n\nexport default Component\n\nexport const metadata: GlitchComponentMetadata = {\n name: 'demographic-wave',\n displayName: 'Demographic Wave',\n version: '1.0.0',\n paramSchema: {\n startYear: {\n type: 'range',\n label: 'Start Year',\n default: 1946,\n min: 1946,\n max: 2028,\n step: 1\n },\n endYear: {\n type: 'range',\n label: 'End Year',\n default: 2038,\n min: 1964,\n max: 2038,\n step: 1\n },\n animationSpeed: {\n type: 'range',\n label: 'Animation Speed',\n default: 1,\n min: 0.25,\n max: 3,\n step: 0.25\n },\n waveScale: {\n type: 'range',\n label: 'Boomer Wave Scale',\n default: 1.15,\n min: 0.2,\n max: 1.8,\n step: 0.05\n },\n startEqualized: {\n type: 'boolean',\n label: 'Start Equalized',\n default: false\n }\n },\n defaultParams: {\n startYear: 1946,\n endYear: 2038,\n animationSpeed: 1,\n waveScale: 1.15,\n startEqualized: false\n }\n}\n\nexport type {\n GlitchComponentProps,\n GlitchComponentConfig,\n GlitchComponentResult,\n GlitchTheme,\n GlitchHostBridge\n} from './types'\n\nif (typeof window !== 'undefined') {\n type GCRegistry = Record\n ;(window as unknown as { GlitchComponents: GCRegistry }).GlitchComponents ??= {}\n ;(window as unknown as { GlitchComponents: GCRegistry }).GlitchComponents[metadata.name] = { default: Component, metadata }\n}\n"],"names":["REACT_ELEMENT_TYPE","REACT_FRAGMENT_TYPE","jsxProd","type","config","maybeKey","key","propName","reactJsxRuntime_production","getComponentNameFromType","REACT_CLIENT_REFERENCE","REACT_PROFILER_TYPE","REACT_STRICT_MODE_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_ACTIVITY_TYPE","REACT_PORTAL_TYPE","REACT_CONTEXT_TYPE","REACT_CONSUMER_TYPE","REACT_FORWARD_REF_TYPE","innerType","REACT_MEMO_TYPE","REACT_LAZY_TYPE","testStringCoercion","value","checkKeyStringCoercion","JSCompiler_inline_result","JSCompiler_temp_const","JSCompiler_inline_result$jscomp$0","getTaskName","name","getOwner","dispatcher","ReactSharedInternals","UnknownOwner","hasValidKey","hasOwnProperty","getter","defineKeyPropWarningGetter","props","displayName","warnAboutAccessingKey","specialPropKeyWarningShown","elementRefGetterWithDeprecationWarning","componentName","didWarnAboutElementRef","ReactElement","owner","debugStack","debugTask","refProp","jsxDEVImpl","isStaticChildren","children","isArrayImpl","validateChildKeys","keys","k","didWarnAboutKeySpread","node","isValidElement","object","React","require$$0","createTask","callStackForError","unknownOwnerDebugStack","unknownOwnerDebugTask","reactJsxRuntime_development","trackActualOwner","jsxRuntimeModule","require$$1","COHORT_YEARS","_","index","BOOMER_CENTER_YEAR","MIN_YEAR","MAX_YEAR","STAGES","GENERATIONS","clamp","min","max","numberParam","fallback","booleanParam","cohortFamily","birthYear","turnout","age","stageForAge","chosen","stage","createCohortSize","equalMode","waveScale","boomerPeak","postDip","echo","drawWave","canvas","year","palette","rect","scale","width","height","ctx","padX","base","maxH","sizeFor","x","size","radius","y","family","boomerAge","Component","onComplete","onProgress","theme","className","host","params","startYear","endYear","animationSpeed","setYear","useState","running","setRunning","setEqualMode","completed","setCompleted","canvasRef","useRef","lastTickRef","useMemo","themeStyle","activeStage","currentPressure","totals","voteWeight","total","sum","generationWins","wins","generation","targetYear","winner","maxWins","progress","redraw","useCallback","useEffect","current","resizeObserver","animationFrame","step","timestamp","interval","playClick","target","setMode","nextEqualMode","handleSlider","event","finishProof","rootClassName","styles","jsx","jsxs","percent","metadata"],"mappings":"iHAWA,IAAIA,EAAqB,OAAO,IAAI,4BAA4B,EAC9DC,EAAsB,OAAO,IAAI,gBAAgB,EACnD,SAASC,EAAQC,EAAMC,EAAQC,EAAU,CACvC,IAAIC,EAAM,KAGV,GAFWD,IAAX,SAAwBC,EAAM,GAAKD,GACxBD,EAAO,MAAlB,SAA0BE,EAAM,GAAKF,EAAO,KACxC,QAASA,EAAQ,CACnBC,EAAW,CAAA,EACX,QAASE,KAAYH,EACTG,IAAV,QAAuBF,EAASE,CAAQ,EAAIH,EAAOG,CAAQ,EACjE,MAASF,EAAWD,EAClB,OAAAA,EAASC,EAAS,IACX,CACL,SAAUL,EACV,KAAMG,EACN,IAAKG,EACL,IAAgBF,IAAX,OAAoBA,EAAS,KAClC,MAAOC,EAEX,CACA,OAAAG,EAAA,SAAmBP,EACnBO,EAAA,IAAcN,EACdM,EAAA,KAAeN,mDCtBE,QAAQ,IAAI,WAA7B,eACG,UAAY,CACX,SAASO,EAAyBN,EAAM,CACtC,GAAYA,GAAR,KAAc,OAAO,KACzB,GAAmB,OAAOA,GAAtB,WACF,OAAOA,EAAK,WAAaO,EACrB,KACAP,EAAK,aAAeA,EAAK,MAAQ,KACvC,GAAiB,OAAOA,GAApB,SAA0B,OAAOA,EACrC,OAAQA,EAAI,CACV,KAAKF,EACH,MAAO,WACT,KAAKU,EACH,MAAO,WACT,KAAKC,EACH,MAAO,aACT,KAAKC,EACH,MAAO,WACT,KAAKC,EACH,MAAO,eACT,KAAKC,EACH,MAAO,UACjB,CACM,GAAiB,OAAOZ,GAApB,SACF,OACgB,OAAOA,EAAK,KAAzB,UACC,QAAQ,MACN,qHAEJA,EAAK,SACf,CACU,KAAKa,EACH,MAAO,SACT,KAAKC,EACH,OAAOd,EAAK,aAAe,UAC7B,KAAKe,EACH,OAAQf,EAAK,SAAS,aAAe,WAAa,YACpD,KAAKgB,EACH,IAAIC,EAAYjB,EAAK,OACrB,OAAAA,EAAOA,EAAK,YACZA,IACIA,EAAOiB,EAAU,aAAeA,EAAU,MAAQ,GACnDjB,EAAcA,IAAP,GAAc,cAAgBA,EAAO,IAAM,cAC9CA,EACT,KAAKkB,GACH,OACGD,EAAYjB,EAAK,aAAe,KACxBiB,IAAT,KACIA,EACAX,EAAyBN,EAAK,IAAI,GAAK,OAE/C,KAAKmB,EACHF,EAAYjB,EAAK,SACjBA,EAAOA,EAAK,MACZ,GAAI,CACF,OAAOM,EAAyBN,EAAKiB,CAAS,CAAC,CAC7D,MAAwB,CAAA,CACxB,CACM,OAAO,IACb,CACI,SAASG,EAAmBC,EAAO,CACjC,MAAO,GAAKA,CAClB,CACI,SAASC,EAAuBD,EAAO,CACrC,GAAI,CACFD,EAAmBC,CAAK,EACxB,IAAIE,EAA2B,EACvC,MAAkB,CACVA,EAA2B,EACnC,CACM,GAAIA,EAA0B,CAC5BA,EAA2B,QAC3B,IAAIC,EAAwBD,EAAyB,MACjDE,EACc,OAAO,QAAtB,YACC,OAAO,aACPJ,EAAM,OAAO,WAAW,GAC1BA,EAAM,YAAY,MAClB,SACF,OAAAG,EAAsB,KACpBD,EACA,2GACAE,GAEKL,EAAmBC,CAAK,CACvC,CACA,CACI,SAASK,EAAY1B,EAAM,CACzB,GAAIA,IAASF,EAAqB,MAAO,KACzC,GACe,OAAOE,GAApB,UACSA,IAAT,MACAA,EAAK,WAAamB,EAElB,MAAO,QACT,GAAI,CACF,IAAIQ,EAAOrB,EAAyBN,CAAI,EACxC,OAAO2B,EAAO,IAAMA,EAAO,IAAM,OACzC,MAAkB,CACV,MAAO,OACf,CACA,CACI,SAASC,GAAW,CAClB,IAAIC,EAAaC,EAAqB,EACtC,OAAgBD,IAAT,KAAsB,KAAOA,EAAW,SAAQ,CAC7D,CACI,SAASE,GAAe,CACtB,OAAO,MAAM,uBAAuB,CAC1C,CACI,SAASC,EAAY/B,EAAQ,CAC3B,GAAIgC,EAAe,KAAKhC,EAAQ,KAAK,EAAG,CACtC,IAAIiC,EAAS,OAAO,yBAAyBjC,EAAQ,KAAK,EAAE,IAC5D,GAAIiC,GAAUA,EAAO,eAAgB,MAAO,EACpD,CACM,OAAkBjC,EAAO,MAAlB,MACb,CACI,SAASkC,EAA2BC,EAAOC,EAAa,CACtD,SAASC,GAAwB,CAC/BC,IACIA,EAA6B,GAC/B,QAAQ,MACN,0OACAF,CACZ,EACA,CACMC,EAAsB,eAAiB,GACvC,OAAO,eAAeF,EAAO,MAAO,CAClC,IAAKE,EACL,aAAc,EACtB,CAAO,CACP,CACI,SAASE,GAAyC,CAChD,IAAIC,EAAgBnC,EAAyB,KAAK,IAAI,EACtD,OAAAoC,EAAuBD,CAAa,IAChCC,EAAuBD,CAAa,EAAI,GAC1C,QAAQ,MACN,6IACV,GACMA,EAAgB,KAAK,MAAM,IACTA,IAAX,OAA2BA,EAAgB,IACxD,CACI,SAASE,EAAa3C,EAAMG,EAAKiC,EAAOQ,EAAOC,EAAYC,GAAW,CACpE,IAAIC,EAAUX,EAAM,IACpB,OAAApC,EAAO,CACL,SAAUH,EACV,KAAMG,EACN,IAAKG,EACL,MAAOiC,EACP,OAAQQ,IAEWG,IAAX,OAAqBA,EAAU,QAAzC,KACI,OAAO,eAAe/C,EAAM,MAAO,CACjC,WAAY,GACZ,IAAKwC,EACN,EACD,OAAO,eAAexC,EAAM,MAAO,CAAE,WAAY,GAAI,MAAO,KAAM,EACtEA,EAAK,OAAS,CAAA,EACd,OAAO,eAAeA,EAAK,OAAQ,YAAa,CAC9C,aAAc,GACd,WAAY,GACZ,SAAU,GACV,MAAO,CACf,CAAO,EACD,OAAO,eAAeA,EAAM,aAAc,CACxC,aAAc,GACd,WAAY,GACZ,SAAU,GACV,MAAO,IACf,CAAO,EACD,OAAO,eAAeA,EAAM,cAAe,CACzC,aAAc,GACd,WAAY,GACZ,SAAU,GACV,MAAO6C,CACf,CAAO,EACD,OAAO,eAAe7C,EAAM,aAAc,CACxC,aAAc,GACd,WAAY,GACZ,SAAU,GACV,MAAO8C,EACf,CAAO,EACD,OAAO,SAAW,OAAO,OAAO9C,EAAK,KAAK,EAAG,OAAO,OAAOA,CAAI,GACxDA,CACb,CACI,SAASgD,EACPhD,EACAC,EACAC,EACA+C,EACAJ,EACAC,GACA,CACA,IAAII,EAAWjD,EAAO,SACtB,GAAeiD,IAAX,OACF,GAAID,EACF,GAAIE,EAAYD,CAAQ,EAAG,CACzB,IACED,EAAmB,EACnBA,EAAmBC,EAAS,OAC5BD,IAEAG,EAAkBF,EAASD,CAAgB,CAAC,EAC9C,OAAO,QAAU,OAAO,OAAOC,CAAQ,CACnD,MACY,QAAQ,MACN,6JAEDE,EAAkBF,CAAQ,EACjC,GAAIjB,EAAe,KAAKhC,EAAQ,KAAK,EAAG,CACtCiD,EAAW5C,EAAyBN,CAAI,EACxC,IAAIqD,EAAO,OAAO,KAAKpD,CAAM,EAAE,OAAO,SAAUqD,GAAG,CACjD,OAAiBA,KAAV,KACjB,CAAS,EACDL,EACE,EAAII,EAAK,OACL,kBAAoBA,EAAK,KAAK,SAAS,EAAI,SAC3C,iBACNE,EAAsBL,EAAWD,CAAgB,IAC7CI,EACA,EAAIA,EAAK,OAAS,IAAMA,EAAK,KAAK,SAAS,EAAI,SAAW,KAC5D,QAAQ,MACN;AAAA;AAAA;AAAA;AAAA;AAAA,mCACAJ,EACAC,EACAG,EACAH,GAEDK,EAAsBL,EAAWD,CAAgB,EAAI,GAChE,CAMM,GALAC,EAAW,KACAhD,IAAX,SACGoB,EAAuBpB,CAAQ,EAAIgD,EAAW,GAAKhD,GACtD8B,EAAY/B,CAAM,IACfqB,EAAuBrB,EAAO,GAAG,EAAIiD,EAAW,GAAKjD,EAAO,KAC3D,QAASA,EAAQ,CACnBC,EAAW,CAAA,EACX,QAASE,MAAYH,EACTG,KAAV,QAAuBF,EAASE,EAAQ,EAAIH,EAAOG,EAAQ,EACrE,MAAaF,EAAWD,EAClB,OAAAiD,GACEf,EACEjC,EACe,OAAOF,GAAtB,WACIA,EAAK,aAAeA,EAAK,MAAQ,UACjCA,GAED2C,EACL3C,EACAkD,EACAhD,EACA0B,EAAQ,EACRiB,EACAC,GAER,CACI,SAASM,EAAkBI,EAAM,CAC/BC,EAAeD,CAAI,EACfA,EAAK,SAAWA,EAAK,OAAO,UAAY,GAC3B,OAAOA,GAApB,UACSA,IAAT,MACAA,EAAK,WAAarC,IACDqC,EAAK,SAAS,SAA9B,YACGC,EAAeD,EAAK,SAAS,KAAK,GAClCA,EAAK,SAAS,MAAM,SACnBA,EAAK,SAAS,MAAM,OAAO,UAAY,GACxCA,EAAK,SAAWA,EAAK,OAAO,UAAY,GACtD,CACI,SAASC,EAAeC,EAAQ,CAC9B,OACe,OAAOA,GAApB,UACSA,IAAT,MACAA,EAAO,WAAa7D,CAE5B,CACI,IAAI8D,EAAQC,EACV/D,EAAqB,OAAO,IAAI,4BAA4B,EAC5DgB,EAAoB,OAAO,IAAI,cAAc,EAC7Cf,EAAsB,OAAO,IAAI,gBAAgB,EACjDW,EAAyB,OAAO,IAAI,mBAAmB,EACvDD,EAAsB,OAAO,IAAI,gBAAgB,EACjDO,EAAsB,OAAO,IAAI,gBAAgB,EACjDD,EAAqB,OAAO,IAAI,eAAe,EAC/CE,EAAyB,OAAO,IAAI,mBAAmB,EACvDN,EAAsB,OAAO,IAAI,gBAAgB,EACjDC,EAA2B,OAAO,IAAI,qBAAqB,EAC3DO,GAAkB,OAAO,IAAI,YAAY,EACzCC,EAAkB,OAAO,IAAI,YAAY,EACzCP,EAAsB,OAAO,IAAI,gBAAgB,EACjDL,EAAyB,OAAO,IAAI,wBAAwB,EAC5DuB,EACE6B,EAAM,gEACR1B,EAAiB,OAAO,UAAU,eAClCkB,EAAc,MAAM,QACpBU,EAAa,QAAQ,WACjB,QAAQ,WACR,UAAY,CACV,OAAO,IACnB,EACIF,EAAQ,CACN,yBAA0B,SAAUG,EAAmB,CACrD,OAAOA,EAAiB,CAChC,GAEI,IAAIvB,EACAG,EAAyB,CAAA,EACzBqB,EAAyBJ,EAAM,yBAAyB,KAC1DA,EACA5B,CACN,EAAK,EACGiC,EAAwBH,EAAWnC,EAAYK,CAAY,CAAC,EAC5DwB,EAAwB,CAAA,EAC5BU,EAAA,SAAmBnE,EACnBmE,EAAA,IAAc,SAAUjE,EAAMC,EAAQC,EAAU,CAC9C,IAAIgE,EACF,IAAMpC,EAAqB,6BAC7B,OAAOkB,EACLhD,EACAC,EACAC,EACA,GACAgE,EACI,MAAM,uBAAuB,EAC7BH,EACJG,EAAmBL,EAAWnC,EAAY1B,CAAI,CAAC,EAAIgE,EAE3D,EACIC,EAAA,KAAe,SAAUjE,EAAMC,EAAQC,EAAU,CAC/C,IAAIgE,EACF,IAAMpC,EAAqB,6BAC7B,OAAOkB,EACLhD,EACAC,EACAC,EACA,GACAgE,EACI,MAAM,uBAAuB,EAC7BH,EACJG,EAAmBL,EAAWnC,EAAY1B,CAAI,CAAC,EAAIgE,EAE3D,CACA,GAAG,2CC7VC,QAAQ,IAAI,WAAa,aAC3BG,EAAA,QAAiBP,GAAA,EAEjBO,EAAA,QAAiBC,GAAA,0/BC0BbC,GAAe,MAAM,KAAK,CAAE,OAAQ,IAAM,CAACC,EAAGC,IAAU,KAAOA,CAAK,EACpEC,EAAqB,KACrBC,GAAW,KACXC,GAAW,KAEXC,GAAkB,CACtB,CACE,IAAK,EACL,MAAO,UACP,KAAM,kGACN,OAAQ,uBAAA,EAEV,CACE,IAAK,GACL,MAAO,SACP,KAAM,uGACN,OAAQ,6BAAA,EAEV,CACE,IAAK,GACL,MAAO,SACP,KAAM,qGACN,OAAQ,8BAAA,EAEV,CACE,IAAK,GACL,MAAO,QACP,KAAM,+FACN,OAAQ,qBAAA,EAEV,CACE,IAAK,GACL,MAAO,aACP,KAAM,mGACN,OAAQ,0BAAA,CAEZ,EAEMC,EAAuD,CAC3D,CAAE,IAAK,SAAU,MAAO,mBAAA,EACxB,CAAE,IAAK,SAAU,MAAO,SAAA,EACxB,CAAE,IAAK,OAAQ,MAAO,eAAA,CACxB,EAEMC,EAAQ,CAACxD,EAAeyD,EAAaC,IAAgB,KAAK,IAAIA,EAAK,KAAK,IAAID,EAAKzD,CAAK,CAAC,EAEvF2D,EAAc,CAAC3D,EAAgB4D,IAAsB,OAAO5D,GAAU,SAAWA,EAAQ4D,EAEzFC,GAAe,CAAC7D,EAAgB4D,IAAuB,OAAO5D,GAAU,UAAYA,EAAQ4D,EAE5FE,GAAgBC,GAChBA,GAAa,MAAQA,GAAa,KAAa,SAC/CA,EAAY,KAAa,SACtB,OAGHC,GAAWC,GACXA,EAAM,IAAMA,EAAM,GAAW,EAC7BA,EAAM,GAAW,IACjBA,EAAM,GAAW,IACjBA,EAAM,GAAW,IACd,GAAM,KAAK,IAAI,EAAGA,EAAM,EAAE,EAAI,KAGjCC,GAAeD,GACnBX,GAAO,OAAO,CAACa,EAAQC,IAAWH,GAAOG,EAAM,IAAMA,EAAQD,EAASb,GAAO,CAAC,CAAC,EAE3Ee,GAAmB,CAACC,EAAoBC,IAAuBR,GAAsB,CACzF,GAAIO,EAAW,MAAO,GAEtB,MAAME,EAAa,KAAK,IAAI,CAAC,KAAK,KAAKT,EAAYZ,GAAsB,IAAK,CAAC,CAAC,EAAIoB,EAC9EE,EAAU,KAAK,IAAI,CAAC,KAAK,KAAKV,EAAY,MAAQ,EAAG,CAAC,CAAC,EAAI,KAC3DW,EAAO,KAAK,IAAI,CAAC,KAAK,KAAKX,EAAY,MAAQ,EAAG,CAAC,CAAC,EAAI,IAC9D,OAAO,KAAK,IAAI,GAAK,IAAOS,EAAaC,EAAUC,CAAI,CACzD,EAEA,SAASC,GACPC,EACAC,EACAP,EACAC,EACAO,EACA,CACA,MAAMC,EAAOH,EAAO,sBAAA,EACdI,EAAQ,OAAO,kBAAoB,EACnCC,EAAQF,EAAK,MACbG,EAASH,EAAK,OAEpBH,EAAO,MAAQ,KAAK,MAAMK,EAAQD,CAAK,EACvCJ,EAAO,OAAS,KAAK,MAAMM,EAASF,CAAK,EAEzC,MAAMG,EAAMP,EAAO,WAAW,IAAI,EAClC,GAAI,CAACO,EAAK,OAEVA,EAAI,aAAaH,EAAO,EAAG,EAAGA,EAAO,EAAG,CAAC,EACzCG,EAAI,UAAU,EAAG,EAAGF,EAAOC,CAAM,EAEjC,MAAME,EAAOH,EAAQ,IACfI,EAAOH,EAAS,IAChBI,EAAOJ,EAAS,IAChBK,EAAUlB,GAAiBC,EAAWC,CAAS,EAErDY,EAAI,UAAY,EAChBA,EAAI,YAAcL,EAAQ,KAC1B,QAAS5B,EAAQ,EAAGA,GAAS,EAAGA,GAAS,EAAG,CAC1C,MAAMsC,EAAIJ,EAAQlC,EAAQ,GAAM+B,EAAQG,EAAO,GAC/CD,EAAI,UAAA,EACJA,EAAI,OAAOK,EAAGN,EAAS,GAAI,EAC3BC,EAAI,OAAOK,EAAGN,EAAS,GAAI,EAC3BC,EAAI,OAAA,CACN,CAEA,UAAWpB,KAAaf,GAAc,CACpC,MAAMiB,EAAMY,EAAOd,EACnB,GAAIE,EAAM,GAAKA,EAAM,GAAI,SAEzB,MAAMwB,EAAOF,EAAQxB,CAAS,EACxByB,EAAIJ,EAAQnB,EAAM,IAAOgB,EAAQG,EAAO,GACxCM,EAAS,KAAK,IAAI,EAAGT,EAAQ,KAAQQ,EAAOR,EAAQ,IAAK,EACzDU,EAAIN,EAAOI,EAAOH,EAAO,IAAO,KAAK,KAAKvB,EAAYc,GAAQ,GAAI,EAAIK,EAAS,KAC/EU,EAAS9B,GAAaC,CAAS,EAErCoB,EAAI,UAAA,EACJA,EAAI,IAAIK,EAAGG,EAAGD,EAAQ,EAAG,KAAK,GAAK,CAAC,EACpCP,EAAI,UAAYL,EAAQc,CAAM,EAC9BT,EAAI,YAAcS,IAAW,SAAW,IAAO,IAC/CT,EAAI,KAAA,EACJA,EAAI,YAAc,CACpB,CAEA,MAAMU,EAAYhB,EAAO1B,EACzB,GAAI0C,EAAY,GAAKA,EAAY,GAAI,OAErC,MAAML,EAAIJ,EAAQS,EAAY,IAAOZ,EAAQG,EAAO,GAC9CO,EAAIN,EAAOE,EAAQpC,CAAkB,EAAImC,EAAO,IAEtDH,EAAI,UAAA,EACJA,EAAI,OAAOK,EAAGN,EAAS,GAAI,EAC3BC,EAAI,OAAOK,EAAGN,EAAS,EAAG,EAC1BC,EAAI,YAAcL,EAAQ,OAC1BK,EAAI,YAAc,IAClBA,EAAI,UAAY,EAChBA,EAAI,OAAA,EACJA,EAAI,YAAc,EAElBA,EAAI,UAAA,EACJA,EAAI,IAAIK,EAAGG,EAAG,KAAK,IAAI,GAAIV,EAAQ,IAAK,EAAG,EAAG,KAAK,GAAK,CAAC,EACzDE,EAAI,YAAcL,EAAQ,OAC1BK,EAAI,UAAY,EAChBA,EAAI,OAAA,CACN,CAEA,SAAwBW,GAAU,CAChC,OAAAlH,EACA,WAAAmH,EACA,WAAAC,EACA,MAAAC,EACA,UAAAC,EACA,KAAAC,CACF,EAAyB,CACvB,MAAMC,EAASxH,EAAO,OAChByH,EAAY7C,EAAM,KAAK,MAAMG,EAAYyC,EAAO,UAAWhD,EAAQ,CAAC,EAAGA,GAAUC,EAAQ,EACzFiD,EAAU9C,EAAM,KAAK,MAAMG,EAAYyC,EAAO,QAAS/C,EAAQ,CAAC,EAAGgD,EAAY,EAAGhD,EAAQ,EAC1FkD,EAAiB/C,EAAMG,EAAYyC,EAAO,eAAgB,CAAC,EAAG,IAAM,CAAC,EACrE7B,EAAYf,EAAMG,EAAYyC,EAAO,UAAW,IAAI,EAAG,GAAK,GAAG,EAC/D,CAACvB,EAAM2B,CAAO,EAAIC,EAAAA,SAASJ,CAAS,EACpC,CAACK,EAASC,CAAU,EAAIF,EAAAA,SAAS,EAAI,EACrC,CAACnC,EAAWsC,CAAY,EAAIH,EAAAA,SAAS,IAAM5C,GAAauC,EAAO,eAAgB,EAAK,CAAC,EACrF,CAACS,EAAWC,CAAY,EAAIL,EAAAA,SAAS,EAAK,EAC1CM,EAAYC,EAAAA,OAAiC,IAAI,EACjDC,EAAcD,EAAAA,OAAO,CAAC,EAEtBlC,EAAUoC,EAAAA,QAAiB,KAAO,CACtC,OAAQ,UACR,OAAQ,UACR,KAAM,UACN,OAAQjB,GAAO,QAAU,UACzB,KAAM,4BACN,KAAMA,GAAO,MAAQ,SAAA,GACnB,CAACA,GAAO,OAAQA,GAAO,IAAI,CAAC,EAE1BkB,EAAaD,EAAAA,QAAQ,KAAO,CAChC,eAAgBjB,GAAO,QACvB,cAAeA,GAAO,OACtB,UAAWA,GAAO,GAClB,oBAAqBA,GAAO,YAC5B,YAAaA,GAAO,KACpB,kBAAmBA,GAAO,UAC1B,cAAeA,GAAO,MAAA,GACH,CAACA,CAAK,CAAC,EAEtBV,EAAU2B,UAAQ,IAAM7C,GAAiBC,EAAWC,CAAS,EAAG,CAACD,EAAWC,CAAS,CAAC,EAEtFsB,GAAYhB,EAAO1B,EACnBiE,EAAclD,GAAYV,EAAMqC,GAAW,EAAG,EAAE,CAAC,EAEjDwB,EAAkBH,EAAAA,QAAQ,IAAM,CACpC,MAAMI,EAAS,OAAO,YAAYhE,GAAO,IAAKc,GAAU,CAACA,EAAM,OAAQ,CAAC,CAAC,CAAC,EAC1E,UAAWL,KAAaf,GAAc,CACpC,MAAMiB,EAAMY,EAAOd,EACnB,GAAIE,EAAM,GAAKA,EAAM,GAAI,SAEzB,MAAMsD,EAAahC,EAAQxB,CAAS,EAAIC,GAAQC,CAAG,EACnDqD,EAAOpD,GAAYD,CAAG,EAAE,MAAM,GAAKsD,CACrC,CAEA,MAAMC,EAAQ,OAAO,OAAOF,CAAM,EAAE,OAAO,CAACG,EAAKzH,IAAUyH,EAAMzH,EAAO,CAAC,EACzE,OAAOwH,EAAQ,EAAI,KAAK,MAAOF,EAAOF,EAAY,MAAM,EAAII,EAAS,GAAG,EAAI,CAC9E,EAAG,CAACJ,EAAY,OAAQ7B,EAASV,CAAI,CAAC,EAEhC6C,EAAiBR,EAAAA,QAAQ,IAAM,CACnC,MAAMS,EAAO,OAAO,YAAYpE,EAAY,IAAKqE,GAAe,CAACA,EAAW,IAAK,CAAC,CAAC,CAAC,EAEpF,QAASC,EAAaxB,EAAWwB,GAAchD,EAAMgD,GAAc,EAAG,CACpE,MAAMP,EAAS,OAAO,YAAY/D,EAAY,IAAKqE,GAAe,CAACA,EAAW,IAAK,CAAC,CAAC,CAAC,EAEtF,UAAW7D,KAAaf,GAAc,CACpC,MAAMiB,EAAM4D,EAAa9D,EACrBE,EAAM,IAAMA,EAAM,KACtBqD,EAAOxD,GAAaC,CAAS,CAAC,GAAKwB,EAAQxB,CAAS,EAAIC,GAAQC,CAAG,EACrE,CAEA,MAAM6D,EAASvE,EAAY,OAAO,CAACY,EAAQyD,IACzCN,EAAOM,EAAW,GAAG,EAAIN,EAAOnD,EAAO,GAAG,EAAIyD,EAAazD,EAC3DZ,EAAY,CAAC,CAAA,EAEX+D,EAAOQ,EAAO,GAAG,EAAI,IAAGH,EAAKG,EAAO,GAAG,GAAK,EAClD,CAEA,OAAOH,CACT,EAAG,CAACpC,EAASc,EAAWxB,CAAI,CAAC,EAEvBkD,EAAU,KAAK,IAAI,GAAG,OAAO,OAAOL,CAAc,EAAG,CAAC,EACtDM,EAAW,KAAK,OAAQnD,EAAOwB,GAAa,KAAK,IAAI,EAAGC,EAAUD,CAAS,EAAK,GAAG,EAEnF4B,EAASC,EAAAA,YAAY,IAAM,CAC1BnB,EAAU,SACfpC,GAASoC,EAAU,QAASlC,EAAMP,EAAWC,EAAWO,CAAO,CACjE,EAAG,CAACR,EAAWQ,EAASP,EAAWM,CAAI,CAAC,EAExCsD,EAAAA,UAAU,IAAM,CACd3B,EAAS4B,GAAY5E,EAAM4E,EAAS/B,EAAWC,CAAO,CAAC,CACzD,EAAG,CAACA,EAASD,CAAS,CAAC,EAEvB8B,EAAAA,UAAU,IAAM,CACdvB,EAAa/C,GAAauC,EAAO,eAAgB,EAAK,CAAC,CACzD,EAAG,CAACA,EAAO,cAAc,CAAC,EAE1B+B,EAAAA,UAAU,IAAM,CACdnC,IAAagC,CAAQ,CACvB,EAAG,CAAChC,EAAYgC,CAAQ,CAAC,EAEzBG,EAAAA,UAAU,IAAM,CACdF,EAAA,EACA,MAAMrD,EAASmC,EAAU,QACzB,GAAI,CAACnC,EAAQ,OAEb,MAAMyD,EAAiB,IAAI,eAAeJ,CAAM,EAChD,OAAAI,EAAe,QAAQzD,CAAM,EACtB,IAAMyD,EAAe,WAAA,CAC9B,EAAG,CAACJ,CAAM,CAAC,EAEXE,EAAAA,UAAU,IAAM,CACd,IAAIG,EAAiB,EAErB,MAAMC,EAAQC,GAAsB,CAClC,MAAMC,EAAW,IAAMlC,EACnBG,GAAW8B,EAAYvB,EAAY,QAAUwB,IAC/CjC,EAAS4B,GAAaA,GAAW9B,EAAUD,EAAY+B,EAAU,CAAE,EACnEnB,EAAY,QAAUuB,GAGxBF,EAAiB,OAAO,sBAAsBC,CAAI,CACpD,EAEA,OAAAD,EAAiB,OAAO,sBAAsBC,CAAI,EAC3C,IAAM,OAAO,qBAAqBD,CAAc,CACzD,EAAG,CAAC/B,EAAgBD,EAASI,EAASL,CAAS,CAAC,EAEhD,MAAMqC,EAAYR,cAAaS,GAAmB,CAChDxC,GAAM,YAAY,kBAAmB,CAAE,OAAAwC,EAAQ,UAAW/J,EAAO,KAAM,CACzE,EAAG,CAACA,EAAO,KAAMuH,CAAI,CAAC,EAEhByC,EAAUV,cAAaW,GAA2B,CACtDH,EAAUG,EAAgB,oBAAsB,aAAa,EAC7DjC,EAAaiC,CAAa,CAC5B,EAAG,CAACH,CAAS,CAAC,EAERI,EAAeZ,cAAaa,GAA+C,CAC/EL,EAAU,UAAU,EACpB/B,EAAW,EAAK,EAChBH,EAAQ,OAAOuC,EAAM,cAAc,KAAK,CAAC,CAC3C,EAAG,CAACL,CAAS,CAAC,EAERM,EAAcd,EAAAA,YAAY,IAAM,CAChCrB,IAEJC,EAAa,EAAI,EACjB4B,EAAU,UAAU,EACpB3C,EAAW,CACT,QAAS,GACT,MAAO,IACP,KAAM,CACJ,KAAAlB,EACA,KAAMP,EAAY,oBAAsB,cACxC,eAAAoD,EACA,gBAAAL,EACA,SAAUzI,EAAO,GACjB,YAAa,IAAI,KAAA,EAAO,YAAA,CAAY,CACtC,CACD,EACH,EAAG,CAACiI,EAAWjI,EAAO,GAAIyI,EAAiB/C,EAAWoD,EAAgB3B,EAAY2C,EAAW7D,CAAI,CAAC,EAE5FoE,EAAgB/C,EAAY,GAAGgD,EAAO,OAAO,IAAIhD,CAAS,GAAKgD,EAAO,QAE5E,OACEC,EAAAA,IAAC,UAAA,CAAQ,UAAWF,EAAe,MAAO9B,EAAY,aAAW,6BAC/D,SAAAiC,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,MACrB,SAAA,CAAAC,EAAAA,IAAC,SAAA,CAAO,UAAWD,EAAO,OACxB,SAAAE,EAAAA,KAAC,OAAI,UAAWF,EAAO,SAAU,aAAW,sBAC1C,SAAA,CAAAC,EAAAA,IAAC,UAAO,UAAWD,EAAO,WAAY,KAAK,SAAS,QAAS,IAAMvC,EAAY3G,GAAU,CAACA,CAAK,EAC5F,SAAA0G,EAAU,KAAO,IACpB,EACAyC,EAAAA,IAAC,SAAA,CACC,UAAW,GAAGD,EAAO,UAAU,IAAK5E,EAAgC,GAApB4E,EAAO,UAAe,GACtE,KAAK,SACL,QAAS,IAAMN,EAAQ,EAAK,EAC7B,SAAA,GAAA,CAAA,EAGDO,EAAAA,IAAC,SAAA,CACC,UAAW,GAAGD,EAAO,UAAU,IAAI5E,EAAY4E,EAAO,WAAa,EAAE,GACrE,KAAK,SACL,QAAS,IAAMN,EAAQ,EAAI,EAC5B,SAAA,GAAA,CAAA,CAED,CAAA,CACF,CAAA,CACF,EAEAQ,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,UACrB,SAAA,CAAAE,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,UACrB,SAAA,CAAAE,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,WACrB,SAAA,CAAAC,EAAAA,IAAC,OACC,SAAAA,EAAAA,IAAC,SAAA,CAAO,UAAWD,EAAO,KAAO,WAAK,CAAA,CACxC,EACAC,EAAAA,IAAC,OAAI,UAAWD,EAAO,OACpB,SAAA3F,EAAY,IAAKqE,GAChBuB,EAAAA,IAAC,OAAA,CACC,eAAC,IAAA,CAAE,UAAWD,EAAOtB,EAAW,GAAG,EAAG,CAAA,EAD7BA,EAAW,GAEtB,CACD,CAAA,CACH,CAAA,EACF,EAEAwB,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,MACrB,SAAA,CAAAE,OAAC,MAAA,CAAI,UAAWF,EAAO,SAAU,cAAY,OAC3C,SAAA,CAAAC,EAAAA,IAAC,QAAK,SAAA,GAAA,CAAC,EACPA,EAAAA,IAAC,QAAK,SAAA,IAAA,CAAE,EACRA,EAAAA,IAAC,QAAK,SAAA,IAAA,CAAE,EACRA,EAAAA,IAAC,QAAK,SAAA,IAAA,CAAE,EACRA,EAAAA,IAAC,QAAK,SAAA,IAAA,CAAE,CAAA,EACV,QACC,SAAA,CAAO,IAAKpC,EAAW,UAAWmC,EAAO,OAAQ,SACjD,MAAA,CAAI,UAAWA,EAAO,WAAY,cAAY,OAC7C,SAAA,CAAAC,EAAAA,IAAC,QAAK,SAAA,MAAA,CAAI,EACVA,EAAAA,IAAC,QAAK,SAAA,QAAA,CAAM,EACZA,EAAAA,IAAC,QAAK,SAAA,MAAA,CAAI,EACVA,EAAAA,IAAC,QAAK,SAAA,QAAA,CAAM,EACZA,EAAAA,IAAC,QAAK,SAAA,MAAA,CAAI,CAAA,CAAA,CACZ,CAAA,CAAA,CACF,CAAA,EACF,EAEAC,EAAAA,KAAC,QAAA,CAAM,UAAWF,EAAO,WACvB,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAI,WAAY,KAAA,CAAM,QACtB,MAAA,CAAI,UAAWD,EAAO,MACrB,gBAAC,SAAA,CAAQ,SAAA,CAAA7B,EAAgB,GAAA,CAAA,CAAC,CAAA,CAC5B,CAAA,CAAA,CACF,CAAA,EACF,EAEA+B,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,SACrB,SAAA,CAAAC,EAAAA,IAAC,QAAA,CACC,aAAW,kBACX,KAAK,QACL,IAAK9C,EACL,IAAKC,EACL,MAAOzB,EACP,SAAUiE,CAAA,CAAA,SAEX,SAAA,CAAQ,SAAA,CAAAd,EAAS,GAAA,CAAA,CAAC,CAAA,EACrB,SAEC,UAAA,CAAQ,UAAWkB,EAAO,WAAY,aAAW,qCAChD,SAAA,CAAAE,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,YACrB,SAAA,CAAAC,MAAC,MAAA,CACC,SAAAA,EAAAA,IAAC,KAAA,CAAG,SAAA,aAAA,CAAW,EACjB,EACAC,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,aACrB,SAAA,CAAAC,MAAC,QAAK,UAAWD,EAAO,SAAW,SAAA5E,EAAY,IAAM,IAAI,EACzD6E,EAAAA,IAAC,SAAA,CAAO,UAAWD,EAAO,eAAgB,KAAK,SAAS,QAASF,EAAa,SAAUnC,EACrF,SAAAA,EAAY,KAAO,GAAA,CACtB,CAAA,CAAA,CACF,CAAA,EACF,EAEAsC,MAAC,OAAI,UAAWD,EAAO,KACpB,SAAA3F,EAAY,IAAKqE,GAAe,CAC/B,MAAMyB,EAAU,KAAK,MAAO3B,EAAeE,EAAW,GAAG,EAAIG,EAAW,GAAG,EAC3E,OACEqB,EAAAA,KAAC,MAAA,CAAI,UAAWF,EAAO,OACrB,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAM,WAAW,MAAQ,SAAW,IAAMvB,EAAW,MAAQ,SAAW,IAAM,GAAA,CAAI,EACnFuB,EAAAA,IAAC,MAAA,CAAI,UAAWD,EAAO,SACrB,SAAAC,EAAAA,IAAC,MAAA,CACC,UAAW,GAAGD,EAAO,OAAO,IAAIA,EAAOtB,EAAW,GAAG,CAAC,GACtD,MAAO,CAAE,MAAO,GAAGyB,CAAO,GAAA,CAAI,CAAA,EAElC,EACAF,EAAAA,IAAC,UAAQ,SAAAE,CAAA,CAAQ,CAAA,CAAA,EARiBzB,EAAW,GAS/C,CAEJ,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CCtcO,MAAM0B,GAAoC,CAC/C,KAAM,mBACN,YAAa,mBACb,QAAS,QACT,YAAa,CACX,UAAW,CACT,KAAM,QACN,MAAO,aACP,QAAS,KACT,IAAK,KACL,IAAK,KACL,KAAM,CAAA,EAER,QAAS,CACP,KAAM,QACN,MAAO,WACP,QAAS,KACT,IAAK,KACL,IAAK,KACL,KAAM,CAAA,EAER,eAAgB,CACd,KAAM,QACN,MAAO,kBACP,QAAS,EACT,IAAK,IACL,IAAK,EACL,KAAM,GAAA,EAER,UAAW,CACT,KAAM,QACN,MAAO,oBACP,QAAS,KACT,IAAK,GACL,IAAK,IACL,KAAM,GAAA,EAER,eAAgB,CACd,KAAM,UACN,MAAO,kBACP,QAAS,EAAA,CACX,EAEF,cAAe,CACb,UAAW,KACX,QAAS,KACT,eAAgB,EAChB,UAAW,KACX,eAAgB,EAAA,CAEpB,EAUA,OAAI,OAAO,OAAW,MAElB,OAAuD,mBAAqB,CAAA,EAC5E,OAAuD,iBAAiBA,GAAS,IAAI,EAAI,CAAE,QAASxD,GAAW,SAAAwD,EAAA","x_google_ignoreList":[0,1,2]} \ No newline at end of file diff --git a/glitch.manifest.json b/glitch.manifest.json new file mode 100644 index 0000000..6123929 --- /dev/null +++ b/glitch.manifest.json @@ -0,0 +1,15 @@ +{ + "componentId": "demographic-wave", + "displayName": "Demographic Wave", + "version": "1.0.0", + "folderName": "glitch_demographic_wave", + "packageName": "@glitch-components/demographic-wave", + "entry": "dist/demographic-wave.js", + "source": "src/index.tsx", + "tags": [ + "glitch-component", + "demography", + "policy", + "simulation" + ] +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..5f17803 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + Demographic Wave + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d2fd097 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2919 @@ +{ + "name": "@glitch-components/demographic-wave", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@glitch-components/demographic-wave", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@types/react": "^19.2.0", + "@types/react-dom": "^19.2.0", + "@vitejs/plugin-react": "^5.1.1", + "leva": "^0.10.1", + "react": "^19.2.0", + "react-dom": "^19.2.0", + "typescript": "^5.9.3", + "vite": "^7.2.4", + "vite-plugin-css-injected-by-js": "^3.5.2" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.10.tgz", + "integrity": "sha512-4kY9IVa6+9nJPsYmngK5Uk2kUmZnv7ChhHAFeQ5oaj8jrR1bIi3xww8nH71pz1/Ve4d/cXO3YxT8eikt1B0a8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.4", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz", + "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz", + "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz", + "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz", + "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz", + "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz", + "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz", + "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz", + "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz", + "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz", + "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz", + "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz", + "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz", + "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz", + "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz", + "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz", + "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz", + "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", + "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz", + "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz", + "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz", + "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz", + "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz", + "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz", + "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz", + "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@stitches/react": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@stitches/react/-/react-1.2.8.tgz", + "integrity": "sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": ">= 16.3.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.15.tgz", + "integrity": "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@use-gesture/core": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", + "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@use-gesture/react": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz", + "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@use-gesture/core": "10.3.1" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/attr-accept": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", + "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.31", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.31.tgz", + "integrity": "sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001793", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", + "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.360", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.360.tgz", + "integrity": "sha512-GkcBt6YYAw9SxFWn+xVar4cLVGlXVuswwtRLBozi2zp0GjXs4ZnOrqV4zbXzg35n7w81hCkyJNYicgXlVHAmBA==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-selector": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.5.0.tgz", + "integrity": "sha512-s8KNnmIDTBoD0p9uJ9uD0XY38SCeBOtj0UMXyQSLg1Ypfrfj8+dAvwsLjYQkQ2GjhVtp2HrnF5cJzMhBjfD8HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/leva": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/leva/-/leva-0.10.1.tgz", + "integrity": "sha512-BcjnfUX8jpmwZUz2L7AfBtF9vn4ggTH33hmeufDULbP3YgNZ/C+ss/oO3stbrqRQyaOmRwy70y7BGTGO81S3rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-portal": "^1.1.4", + "@radix-ui/react-tooltip": "^1.1.8", + "@stitches/react": "^1.2.8", + "@use-gesture/react": "^10.2.5", + "colord": "^2.9.2", + "dequal": "^2.0.2", + "merge-value": "^1.0.0", + "react-colorful": "^5.5.1", + "react-dropzone": "^12.0.0", + "v8n": "^1.3.3", + "zustand": "^3.6.9" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/merge-value/-/merge-value-1.0.0.tgz", + "integrity": "sha512-fJMmvat4NeKz63Uv9iHWcPDjCWcCkoiRoajRTEO8hlhUC6rwaHg0QCF9hBOTjZmm4JuglPckPSTtcuJL5kp0TQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "is-extendable": "^1.0.0", + "mixin-deep": "^1.2.0", + "set-value": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.44", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", + "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/react": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-colorful": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.7.0.tgz", + "integrity": "sha512-fuesYIemttah97XmsIHmz4OORDHiSFzyc9HMAIrCHJou2jaRQmL8cFJ76K4zQhhj8jzwOBlOi4BaGTjjOZCfTg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.6" + } + }, + "node_modules/react-dropzone": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-12.1.0.tgz", + "integrity": "sha512-iBYHA1rbopIvtzokEX4QubO6qk5IF/x3BtKGu74rF2JkQDXnwC4uO/lHKpaw4PJIV6iIAYOlwLv2FpiGyqHNog==", + "dev": true, + "license": "MIT", + "dependencies": { + "attr-accept": "^2.2.2", + "file-selector": "^0.5.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz", + "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.4", + "@rollup/rollup-android-arm64": "4.60.4", + "@rollup/rollup-darwin-arm64": "4.60.4", + "@rollup/rollup-darwin-x64": "4.60.4", + "@rollup/rollup-freebsd-arm64": "4.60.4", + "@rollup/rollup-freebsd-x64": "4.60.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", + "@rollup/rollup-linux-arm-musleabihf": "4.60.4", + "@rollup/rollup-linux-arm64-gnu": "4.60.4", + "@rollup/rollup-linux-arm64-musl": "4.60.4", + "@rollup/rollup-linux-loong64-gnu": "4.60.4", + "@rollup/rollup-linux-loong64-musl": "4.60.4", + "@rollup/rollup-linux-ppc64-gnu": "4.60.4", + "@rollup/rollup-linux-ppc64-musl": "4.60.4", + "@rollup/rollup-linux-riscv64-gnu": "4.60.4", + "@rollup/rollup-linux-riscv64-musl": "4.60.4", + "@rollup/rollup-linux-s390x-gnu": "4.60.4", + "@rollup/rollup-linux-x64-gnu": "4.60.4", + "@rollup/rollup-linux-x64-musl": "4.60.4", + "@rollup/rollup-openbsd-x64": "4.60.4", + "@rollup/rollup-openharmony-arm64": "4.60.4", + "@rollup/rollup-win32-arm64-msvc": "4.60.4", + "@rollup/rollup-win32-ia32-msvc": "4.60.4", + "@rollup/rollup-win32-x64-gnu": "4.60.4", + "@rollup/rollup-win32-x64-msvc": "4.60.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8n": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/v8n/-/v8n-1.5.1.tgz", + "integrity": "sha512-LdabyT4OffkyXFCe9UT+uMkxNBs5rcTVuZClvxQr08D5TUgo1OFKkoT65qYRCsiKBl/usHjpXvP4hHMzzDRj3A==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz", + "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-css-injected-by-js": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/vite-plugin-css-injected-by-js/-/vite-plugin-css-injected-by-js-3.5.2.tgz", + "integrity": "sha512-2MpU/Y+SCZyWUB6ua3HbJCrgnF0KACAsmzOQt1UvRVJCGF6S8xdA3ZUhWcWdM9ivG4I5az8PnQmwwrkC2CAQrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "vite": ">2.0.0-0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..54e773d --- /dev/null +++ b/package.json @@ -0,0 +1,49 @@ +{ + "name": "@glitch-components/demographic-wave", + "version": "1.0.0", + "description": "Demographic Wave glitch component for Glitch University", + "type": "module", + "main": "./dist/demographic-wave.js", + "module": "./dist/demographic-wave.js", + "types": "./src/types.ts", + "exports": { + ".": { + "import": "./dist/demographic-wave.js", + "types": "./src/types.ts" + } + }, + "files": [ + "dist", + "src/types.ts", + "glitch.manifest.json" + ], + "scripts": { + "dev": "vite", + "build": "tsc --noEmit && vite build", + "preview": "vite preview", + "typecheck": "tsc --noEmit" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "devDependencies": { + "@types/react": "^19.2.0", + "@types/react-dom": "^19.2.0", + "@vitejs/plugin-react": "^5.1.1", + "leva": "^0.10.1", + "react": "^19.2.0", + "react-dom": "^19.2.0", + "typescript": "^5.9.3", + "vite": "^7.2.4", + "vite-plugin-css-injected-by-js": "^3.5.2" + }, + "keywords": [ + "glitch", + "demography", + "simulation", + "component" + ], + "author": "Glitch.university", + "license": "MIT" +} diff --git a/src/Component.tsx b/src/Component.tsx new file mode 100644 index 0000000..4946216 --- /dev/null +++ b/src/Component.tsx @@ -0,0 +1,460 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import type { CSSProperties } from 'react' +import styles from './styles.module.css' +import type { GlitchComponentProps } from './types' + +type GenerationKey = 'silent' | 'boomer' | 'post' + +interface Stage { + min: number + title: string + copy: string + policy: string +} + +interface ComponentParams { + startYear?: number + endYear?: number + animationSpeed?: number + waveScale?: number + startEqualized?: boolean +} + +interface Palette { + silent: string + boomer: string + post: string + accent: string + grid: string + text: string +} + +const COHORT_YEARS = Array.from({ length: 82 }, (_, index) => 1928 + index) +const BOOMER_CENTER_YEAR = 1957 +const MIN_YEAR = 1946 +const MAX_YEAR = 2038 + +const STAGES: Stage[] = [ + { + min: 0, + title: 'SCHOOLS', + copy: 'A large child cohort pulls classrooms, teachers, and local budgets toward youth infrastructure.', + policy: 'Education and schools' + }, + { + min: 18, + title: 'CAMPUS', + copy: 'The wave enters college and first jobs. Credentials, housing, and entry labor markets start to flex.', + policy: 'Universities and entry jobs' + }, + { + min: 30, + title: 'FAMILY', + copy: 'The cohort becomes parents and buyers. Homes, childcare, transport, and suburbs absorb the demand.', + policy: 'Housing and family subsidies' + }, + { + min: 50, + title: 'VOTES', + copy: 'High turnout meets cohort size. Tax, asset, and stability preferences become easier to pass.', + policy: 'Tax and asset rules' + }, + { + min: 65, + title: 'RETIREMENT', + copy: 'The wave reaches old age. Health care, pensions, and age-linked spending gain political gravity.', + policy: 'Pensions and health care' + } +] + +const GENERATIONS: { key: GenerationKey; label: string }[] = [ + { key: 'silent', label: 'Silent generation' }, + { key: 'boomer', label: 'Boomers' }, + { key: 'post', label: 'Later cohorts' } +] + +const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value)) + +const numberParam = (value: unknown, fallback: number) => (typeof value === 'number' ? value : fallback) + +const booleanParam = (value: unknown, fallback: boolean) => (typeof value === 'boolean' ? value : fallback) + +const cohortFamily = (birthYear: number): GenerationKey => { + if (birthYear >= 1946 && birthYear <= 1964) return 'boomer' + if (birthYear < 1946) return 'silent' + return 'post' +} + +const turnout = (age: number) => { + if (age < 18 || age > 88) return 0 + if (age < 30) return 0.42 + if (age < 45) return 0.62 + if (age < 65) return 0.82 + return 0.9 - Math.max(0, age - 72) * 0.018 +} + +const stageForAge = (age: number) => + STAGES.reduce((chosen, stage) => (age >= stage.min ? stage : chosen), STAGES[0]) + +const createCohortSize = (equalMode: boolean, waveScale: number) => (birthYear: number) => { + if (equalMode) return 1 + + const boomerPeak = Math.exp(-Math.pow((birthYear - BOOMER_CENTER_YEAR) / 7.5, 2)) * waveScale + const postDip = Math.exp(-Math.pow((birthYear - 1974) / 8, 2)) * -0.22 + const echo = Math.exp(-Math.pow((birthYear - 1991) / 9, 2)) * 0.18 + return Math.max(0.5, 0.78 + boomerPeak + postDip + echo) +} + +function drawWave( + canvas: HTMLCanvasElement, + year: number, + equalMode: boolean, + waveScale: number, + palette: Palette +) { + const rect = canvas.getBoundingClientRect() + const scale = window.devicePixelRatio || 1 + const width = rect.width + const height = rect.height + + canvas.width = Math.floor(width * scale) + canvas.height = Math.floor(height * scale) + + const ctx = canvas.getContext('2d') + if (!ctx) return + + ctx.setTransform(scale, 0, 0, scale, 0, 0) + ctx.clearRect(0, 0, width, height) + + const padX = width * 0.07 + const base = height * 0.72 + const maxH = height * 0.68 + const sizeFor = createCohortSize(equalMode, waveScale) + + ctx.lineWidth = 1 + ctx.strokeStyle = palette.grid + for (let index = 0; index <= 4; index += 1) { + const x = padX + (index / 4) * (width - padX * 2) + ctx.beginPath() + ctx.moveTo(x, height * 0.14) + ctx.lineTo(x, height * 0.88) + ctx.stroke() + } + + for (const birthYear of COHORT_YEARS) { + const age = year - birthYear + if (age < 0 || age > 88) continue + + const size = sizeFor(birthYear) + const x = padX + (age / 88) * (width - padX * 2) + const radius = Math.max(4, width * 0.006 + size * width * 0.009) + const y = base - size * maxH * 0.52 - Math.sin((birthYear + year) * 0.18) * height * 0.025 + const family = cohortFamily(birthYear) + + ctx.beginPath() + ctx.arc(x, y, radius, 0, Math.PI * 2) + ctx.fillStyle = palette[family] + ctx.globalAlpha = family === 'boomer' ? 0.94 : 0.68 + ctx.fill() + ctx.globalAlpha = 1 + } + + const boomerAge = year - BOOMER_CENTER_YEAR + if (boomerAge < 0 || boomerAge > 88) return + + const x = padX + (boomerAge / 88) * (width - padX * 2) + const y = base - sizeFor(BOOMER_CENTER_YEAR) * maxH * 0.52 + + ctx.beginPath() + ctx.moveTo(x, height * 0.16) + ctx.lineTo(x, height * 0.9) + ctx.strokeStyle = palette.boomer + ctx.globalAlpha = 0.42 + ctx.lineWidth = 2 + ctx.stroke() + ctx.globalAlpha = 1 + + ctx.beginPath() + ctx.arc(x, y, Math.max(16, width * 0.035), 0, Math.PI * 2) + ctx.strokeStyle = palette.accent + ctx.lineWidth = 3 + ctx.stroke() +} + +export default function Component({ + config, + onComplete, + onProgress, + theme, + className, + host +}: GlitchComponentProps) { + const params = config.params as ComponentParams + const startYear = clamp(Math.round(numberParam(params.startYear, MIN_YEAR)), MIN_YEAR, MAX_YEAR) + const endYear = clamp(Math.round(numberParam(params.endYear, MAX_YEAR)), startYear + 1, MAX_YEAR) + const animationSpeed = clamp(numberParam(params.animationSpeed, 1), 0.25, 3) + const waveScale = clamp(numberParam(params.waveScale, 1.15), 0.2, 1.8) + const [year, setYear] = useState(startYear) + const [running, setRunning] = useState(true) + const [equalMode, setEqualMode] = useState(() => booleanParam(params.startEqualized, false)) + const [completed, setCompleted] = useState(false) + const canvasRef = useRef(null) + const lastTickRef = useRef(0) + + const palette = useMemo(() => ({ + silent: '#71a6d2', + boomer: '#e7b84f', + post: '#7ee0a0', + accent: theme?.accent ?? '#22d3ee', + grid: 'rgba(232, 232, 236, 0.13)', + text: theme?.text ?? '#e8e8ec' + }), [theme?.accent, theme?.text]) + + const themeStyle = useMemo(() => ({ + '--gc-primary': theme?.primary, + '--gc-accent': theme?.accent, + '--gc-bg': theme?.bg, + '--gc-bg-secondary': theme?.bgSecondary, + '--gc-text': theme?.text, + '--gc-text-muted': theme?.textMuted, + '--gc-border': theme?.border + }) as CSSProperties, [theme]) + + const sizeFor = useMemo(() => createCohortSize(equalMode, waveScale), [equalMode, waveScale]) + + const boomerAge = year - BOOMER_CENTER_YEAR + const activeStage = stageForAge(clamp(boomerAge, 0, 88)) + + const currentPressure = useMemo(() => { + const totals = Object.fromEntries(STAGES.map((stage) => [stage.policy, 0])) + for (const birthYear of COHORT_YEARS) { + const age = year - birthYear + if (age < 0 || age > 88) continue + + const voteWeight = sizeFor(birthYear) * turnout(age) + totals[stageForAge(age).policy] += voteWeight + } + + const total = Object.values(totals).reduce((sum, value) => sum + value, 0) + return total > 0 ? Math.round((totals[activeStage.policy] / total) * 100) : 0 + }, [activeStage.policy, sizeFor, year]) + + const generationWins = useMemo(() => { + const wins = Object.fromEntries(GENERATIONS.map((generation) => [generation.key, 0])) as Record + + for (let targetYear = startYear; targetYear <= year; targetYear += 1) { + const totals = Object.fromEntries(GENERATIONS.map((generation) => [generation.key, 0])) as Record + + for (const birthYear of COHORT_YEARS) { + const age = targetYear - birthYear + if (age < 18 || age > 88) continue + totals[cohortFamily(birthYear)] += sizeFor(birthYear) * turnout(age) + } + + const winner = GENERATIONS.reduce((chosen, generation) => + totals[generation.key] > totals[chosen.key] ? generation : chosen + , GENERATIONS[0]) + + if (totals[winner.key] > 0) wins[winner.key] += 1 + } + + return wins + }, [sizeFor, startYear, year]) + + const maxWins = Math.max(...Object.values(generationWins), 1) + const progress = Math.round(((year - startYear) / Math.max(1, endYear - startYear)) * 100) + + const redraw = useCallback(() => { + if (!canvasRef.current) return + drawWave(canvasRef.current, year, equalMode, waveScale, palette) + }, [equalMode, palette, waveScale, year]) + + useEffect(() => { + setYear((current) => clamp(current, startYear, endYear)) + }, [endYear, startYear]) + + useEffect(() => { + setEqualMode(booleanParam(params.startEqualized, false)) + }, [params.startEqualized]) + + useEffect(() => { + onProgress?.(progress) + }, [onProgress, progress]) + + useEffect(() => { + redraw() + const canvas = canvasRef.current + if (!canvas) return undefined + + const resizeObserver = new ResizeObserver(redraw) + resizeObserver.observe(canvas) + return () => resizeObserver.disconnect() + }, [redraw]) + + useEffect(() => { + let animationFrame = 0 + + const step = (timestamp: number) => { + const interval = 260 / animationSpeed + if (running && timestamp - lastTickRef.current > interval) { + setYear((current) => (current >= endYear ? startYear : current + 1)) + lastTickRef.current = timestamp + } + + animationFrame = window.requestAnimationFrame(step) + } + + animationFrame = window.requestAnimationFrame(step) + return () => window.cancelAnimationFrame(animationFrame) + }, [animationSpeed, endYear, running, startYear]) + + const playClick = useCallback((target: string) => { + host?.playSound?.('ui.button_click', { target, component: config.name }) + }, [config.name, host]) + + const setMode = useCallback((nextEqualMode: boolean) => { + playClick(nextEqualMode ? 'equal-generations' : 'boomer-wave') + setEqualMode(nextEqualMode) + }, [playClick]) + + const handleSlider = useCallback((event: React.ChangeEvent) => { + playClick('timeline') + setRunning(false) + setYear(Number(event.currentTarget.value)) + }, [playClick]) + + const finishProof = useCallback(() => { + if (completed) return + + setCompleted(true) + playClick('complete') + onComplete({ + success: true, + score: 100, + data: { + year, + mode: equalMode ? 'equal-generations' : 'boomer-wave', + generationWins, + currentPressure, + configId: config.id, + completedAt: new Date().toISOString() + } + }) + }, [completed, config.id, currentPressure, equalMode, generationWins, onComplete, playClick, year]) + + const rootClassName = className ? `${styles.wrapper} ${className}` : styles.wrapper + + return ( +
+
+
+
+ + + +
+
+ +
+
+
+
+ {year} +
+
+ {GENERATIONS.map((generation) => ( + + + + ))} +
+
+ +
+ + + +
+
+ + +
+ +
+ + {progress}% +
+ +
+
+
+

Policy wins

+
+
+ {equalMode ? '=' : 'W'} + +
+
+ +
+ {GENERATIONS.map((generation) => { + const percent = Math.round((generationWins[generation.key] / maxWins) * 100) + return ( +
+ {generation.key === 'silent' ? 'S' : generation.key === 'boomer' ? 'B' : 'L'} +
+
+
+ {percent} +
+ ) + })} +
+
+
+
+ ) +} diff --git a/src/dev-theme.css b/src/dev-theme.css new file mode 100644 index 0000000..04dbfea --- /dev/null +++ b/src/dev-theme.css @@ -0,0 +1,49 @@ +@import url("https://fonts.googleapis.com/css2?family=Iceland&family=JetBrains+Mono:wght@400;600&family=Russo+One&display=swap"); + +:root { + --color-bg: #0a0a0f; + --color-bg-secondary: #12121a; + --color-text: #e8e8ec; + --color-text-muted: #9999a8; + --color-primary: #6366f1; + --color-primary-hover: #818cf8; + --color-accent: #22d3ee; + --color-accent-secondary: #a855f7; + --color-border: #2a2a3a; + --font-main: "Iceland", -apple-system, BlinkMacSystemFont, sans-serif; + --font-display: "Russo One", -apple-system, BlinkMacSystemFont, sans-serif; + --font-mono: "JetBrains Mono", "Iceland", monospace; + --small-font: 1.875rem; + --spacing-xs: 0.5rem; + --spacing-sm: 1rem; + --spacing-md: 2rem; + --spacing-lg: 4rem; + --spacing-xl: 6rem; + --max-width: 1200px; + --border-radius: 12px; + --border-radius-sm: 8px; + --transition: 0.2s ease; +} + +html, +body, +#root { + width: 100%; + min-height: 100%; +} + +body { + margin: 0; + background: + radial-gradient(circle at top, rgb(99 102 241 / 18%), transparent 36%), + linear-gradient(180deg, #080810, #0d1018); + color: var(--color-text); + font-family: var(--font-main); +} + +button, +input, +select, +textarea { + font: inherit; +} diff --git a/src/dev.tsx b/src/dev.tsx new file mode 100644 index 0000000..8f1ea1d --- /dev/null +++ b/src/dev.tsx @@ -0,0 +1,51 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import { Leva, useControls } from 'leva' +import Component from './Component' +import { metadata } from './index' +import './dev-theme.css' + +function DevHarness() { + const params = useControls({ + startYear: { value: 1946, min: 1946, max: 2028, step: 1 }, + endYear: { value: 2038, min: 1964, max: 2038, step: 1 }, + animationSpeed: { value: 1, min: 0.25, max: 3, step: 0.25 }, + waveScale: { value: 1.15, min: 0.2, max: 1.8, step: 0.05 }, + startEqualized: false + }) + + return ( +
+
+ ) +} + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + +) diff --git a/src/index.tsx b/src/index.tsx new file mode 100644 index 0000000..1ba445f --- /dev/null +++ b/src/index.tsx @@ -0,0 +1,70 @@ +import Component from './Component' +import type { GlitchComponentMetadata } from './types' + +export default Component + +export const metadata: GlitchComponentMetadata = { + name: 'demographic-wave', + displayName: 'Demographic Wave', + version: '1.0.0', + paramSchema: { + startYear: { + type: 'range', + label: 'Start Year', + default: 1946, + min: 1946, + max: 2028, + step: 1 + }, + endYear: { + type: 'range', + label: 'End Year', + default: 2038, + min: 1964, + max: 2038, + step: 1 + }, + animationSpeed: { + type: 'range', + label: 'Animation Speed', + default: 1, + min: 0.25, + max: 3, + step: 0.25 + }, + waveScale: { + type: 'range', + label: 'Boomer Wave Scale', + default: 1.15, + min: 0.2, + max: 1.8, + step: 0.05 + }, + startEqualized: { + type: 'boolean', + label: 'Start Equalized', + default: false + } + }, + defaultParams: { + startYear: 1946, + endYear: 2038, + animationSpeed: 1, + waveScale: 1.15, + startEqualized: false + } +} + +export type { + GlitchComponentProps, + GlitchComponentConfig, + GlitchComponentResult, + GlitchTheme, + GlitchHostBridge +} from './types' + +if (typeof window !== 'undefined') { + type GCRegistry = Record + ;(window as unknown as { GlitchComponents: GCRegistry }).GlitchComponents ??= {} + ;(window as unknown as { GlitchComponents: GCRegistry }).GlitchComponents[metadata.name] = { default: Component, metadata } +} diff --git a/src/styles.module.css b/src/styles.module.css new file mode 100644 index 0000000..b490dc7 --- /dev/null +++ b/src/styles.module.css @@ -0,0 +1,494 @@ +.wrapper { + --gc-bg: var(--color-bg, #0a0a0f); + --gc-bg-secondary: var(--color-bg-secondary, #12121a); + --gc-text: var(--color-text, #e8e8ec); + --gc-text-muted: var(--color-text-muted, #9999a8); + --gc-primary: var(--color-primary, #6366f1); + --gc-accent: var(--color-accent, #22d3ee); + --gc-border: var(--color-border, #2a2a3a); + --gc-font-main: var(--font-main, system-ui, sans-serif); + --gc-font-display: var(--font-display, var(--gc-font-main)); + --gc-font-mono: var(--font-mono, monospace); + --gc-shell-padding: clamp(8px, 2vw, 18px); + width: 100%; + min-height: 100dvh; + display: grid; + place-items: center; + padding: var(--gc-shell-padding); + box-sizing: border-box; +} + +.wrapper *, +.wrapper *::before, +.wrapper *::after { + box-sizing: inherit; +} + +.frame { + position: relative; + width: min(100%, calc((100dvh - (var(--gc-shell-padding) * 2)) * 16 / 9)); + max-height: calc(100dvh - (var(--gc-shell-padding) * 2)); + aspect-ratio: 16 / 9; + display: grid; + grid-template-rows: auto minmax(0, 1fr) auto auto; + gap: 0.5em; + overflow: hidden; + padding: 1em; + color: var(--gc-text); + font-family: var(--gc-font-main); + font-size: clamp(10px, 1.12cqw, 18px); + line-height: 1.25; + background: + radial-gradient(circle at 12% 10%, color-mix(in srgb, var(--gc-primary) 26%, transparent), transparent 34%), + radial-gradient(circle at 86% 16%, color-mix(in srgb, var(--gc-accent) 18%, transparent), transparent 30%), + linear-gradient(145deg, var(--gc-bg), var(--gc-bg-secondary)); + border: 1px solid color-mix(in srgb, var(--gc-border) 74%, transparent); + box-shadow: + inset 0 0 0 1px rgb(255 255 255 / 4%), + 0 18px 48px rgb(0 0 0 / 34%); + container-type: inline-size; +} + +.header, +.stageGrid, +.readoutRow, +.proofHeader, +.timeline, +.controls, +.legend, +.meter { + display: flex; + align-items: center; +} + +.header, +.readoutRow, +.proofHeader, +.meter { + justify-content: space-between; + gap: 1em; +} + +.label { + display: block; + margin: 0 0 0.25em; + color: color-mix(in srgb, var(--gc-accent) 80%, white); + font-family: var(--gc-font-mono); + font-size: 0.62em; + font-weight: 600; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +.controls { + gap: 0.45em; + justify-content: stretch; + width: 100%; +} + +.iconButton, +.modeButton, +.completeButton { + border: 1px solid color-mix(in srgb, var(--gc-border) 78%, transparent); + color: var(--gc-text); + font: inherit; + font-family: var(--gc-font-mono); + font-size: 0.68em; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; + cursor: pointer; + transition: transform 120ms ease, border-color 120ms ease, background-color 120ms ease; +} + +.iconButton:hover, +.modeButton:hover, +.completeButton:hover { + transform: translateY(-1px); + border-color: color-mix(in srgb, var(--gc-accent) 62%, var(--gc-border)); +} + +.iconButton { + min-width: 3.7em; + min-height: 2.75em; + background: rgb(10 14 24 / 72%); +} + +.modeButton { + min-height: 2.75em; + padding: 0 0.85em; + background: rgb(10 14 24 / 58%); +} + +.modeActive { + color: #090b10; + background: linear-gradient(90deg, #e7b84f, color-mix(in srgb, var(--gc-accent) 58%, #e7b84f)); + border-color: rgb(255 255 255 / 56%); +} + +.stageGrid { + min-height: 0; + display: grid; + grid-template-columns: minmax(0, 1.36fr) minmax(12em, 0.64fr); + align-items: stretch; + gap: 0.65em; +} + +.wavePanel, +.eventPanel, +.proofPanel, +.timeline { + min-width: 0; + border: 1px solid color-mix(in srgb, var(--gc-border) 76%, transparent); + background: rgb(5 9 18 / 54%); +} + +.wavePanel { + min-height: 0; + display: grid; + grid-template-rows: auto minmax(0, 1fr); + gap: 0.45em; + padding: 0.7em; +} + +.year { + display: block; + font-family: var(--gc-font-display); + font-size: 1.85em; + line-height: 0.9; +} + +.legend { + gap: 0.4em; + justify-content: end; + color: var(--gc-text-muted); + font-family: var(--gc-font-mono); + font-size: 0.62em; + letter-spacing: 0.05em; + text-transform: uppercase; +} + +.legend i { + display: inline-block; + width: 0.8em; + height: 0.8em; + margin-right: 0; + border-radius: 999px; +} + +.track { + position: relative; + min-height: 0; + overflow: hidden; + border: 1px solid color-mix(in srgb, var(--gc-border) 70%, transparent); + background: + linear-gradient(90deg, rgb(113 166 210 / 6%), transparent 32%, rgb(231 184 79 / 8%) 62%, rgb(126 224 160 / 7%)), + rgb(7 11 17 / 78%); +} + +.canvas { + display: block; + width: 100%; + height: 100%; +} + +.ageMarks, +.stageMarks { + position: absolute; + left: 7%; + right: 7%; + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + color: rgb(232 232 236 / 60%); + font-family: var(--gc-font-mono); + font-size: 0.58em; + font-weight: 600; + letter-spacing: 0.08em; + pointer-events: none; + text-transform: uppercase; +} + +.ageMarks { + top: 0.8em; +} + +.stageMarks { + bottom: 0.75em; + text-align: center; +} + +.eventPanel { + display: flex; + align-items: center; + justify-content: space-between; + flex-direction: row; + gap: 1em; + padding: 0.9em; +} + +.eventPanel h3, +.proofHeader h3 { + margin: 0; + color: var(--gc-text); + font-family: var(--gc-font-display); + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.eventPanel h3 { + font-size: 1.1em; +} + +.eventPanel p { + display: none; + margin: 0.65em 0 0; + color: color-mix(in srgb, var(--gc-text-muted) 86%, white); + font-size: 0.88em; +} + +.meter { + margin-top: 0; + padding-top: 0; + border-top: 0; + color: var(--gc-text-muted); + font-family: var(--gc-font-mono); + font-size: 0.7em; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.meter strong { + color: #e7b84f; + font-family: var(--gc-font-display); + font-size: 2.2em; + letter-spacing: 0.02em; +} + +.timeline { + display: grid; + grid-template-columns: minmax(0, 1fr) 3.5em; + gap: 0.8em; + padding: 0.62em 0.8em; +} + +.timeline .label { + margin: 0; +} + +.timeline input { + width: 100%; + accent-color: #e7b84f; +} + +.timeline strong { + text-align: right; + font-family: var(--gc-font-mono); + font-size: 0.72em; +} + +.proofPanel { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: 0.8em; + padding: 0.8em; +} + +.proofHeader { + grid-column: 1 / -1; +} + +.proofHeader h3 { + display: none; +} + +.modePill { + white-space: nowrap; + border: 1px solid color-mix(in srgb, var(--gc-border) 72%, transparent); + min-width: 3em; + padding: 0.45em 0.7em; + color: var(--gc-text-muted); + font-family: var(--gc-font-mono); + font-size: 0.62em; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.proofActions { + display: flex; + align-items: center; + gap: 0.45em; +} + +.bars { + display: grid; + gap: 0.45em; +} + +.barRow { + display: grid; + grid-template-columns: 1.3em minmax(0, 1fr) 2.2em; + align-items: center; + gap: 0.65em; + color: var(--gc-text-muted); + font-family: var(--gc-font-mono); + font-size: 0.68em; + letter-spacing: 0.05em; + text-transform: uppercase; +} + +.barTrack { + height: 1.35em; + overflow: hidden; + border: 1px solid color-mix(in srgb, var(--gc-border) 76%, transparent); + background: rgb(3 6 12 / 72%); +} + +.barFill { + height: 100%; + transition: width 180ms ease; +} + +.barRow strong { + color: var(--gc-text); + text-align: right; +} + +.silent { + background: #71a6d2; +} + +.boomer { + background: #e7b84f; +} + +.post { + background: #7ee0a0; +} + +.completeButton { + min-height: 2.35em; + padding: 0 0.8em; + background: color-mix(in srgb, var(--gc-primary) 28%, rgb(5 9 18)); +} + +.completeButton:disabled { + cursor: default; + opacity: 0.68; + transform: none; +} + +@media (orientation: portrait) { + .frame { + width: min(100%, calc((100dvh - (var(--gc-shell-padding) * 2)) / 2)); + aspect-ratio: 1 / 2; + grid-template-rows: auto minmax(0, 1.24fr) auto minmax(0, 0.56fr); + font-size: clamp(10px, 3.2cqw, 16px); + } + + .title { + font-size: 1.2em; + } + + .header { + align-items: flex-start; + flex-direction: column; + gap: 0.55em; + } + + .controls { + width: 100%; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .iconButton, + .modeButton { + min-height: 2.35em; + } + + .stageGrid { + grid-template-columns: 1fr; + grid-template-rows: minmax(0, 1.25fr) auto; + } + + .wavePanel { + padding: 0.75em; + } + + .readoutRow { + align-items: flex-start; + flex-direction: column; + gap: 0.45em; + } + + .legend { + justify-content: start; + } + + .eventPanel { + min-height: 0; + padding: 0.72em; + } + + .eventPanel h3 { + font-size: 1em; + } + + .eventPanel p { + margin-top: 0.42em; + font-size: 0.78em; + line-height: 1.22; + } + + .meter { + padding-top: 0.48em; + } + + .meter strong { + font-size: 1.7em; + } + + .stageMarks { + display: none; + } + + .proofPanel { + grid-template-columns: 1fr; + gap: 0.5em; + padding: 0.65em; + } + + .proofHeader { + align-items: flex-start; + flex-direction: column; + gap: 0.45em; + } + + .proofActions { + width: 100%; + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + } + + .proofHeader h3 { + font-size: 0.82em; + } + + .barRow { + grid-template-columns: 1fr 2.2em; + gap: 0.32em; + font-size: 0.6em; + } + + .barRow span { + grid-column: 1 / -1; + } + + .barTrack { + height: 0.85em; + } + + .completeButton { + min-height: 2.35em; + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..f8f83b8 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,59 @@ +export interface GlitchComponentConfig { + id: string + name: string + version: string + params: Record +} + +export interface GlitchHostBridge { + playSound?: (id: string, payload?: Record) => void + stopSound?: (id: string, payload?: Record) => void + emit?: (type: string, payload?: unknown) => void +} + +export interface GlitchTheme { + primary: string + accent: string + bg: string + bgSecondary: string + text: string + textMuted: string + border: string +} + +export interface GlitchComponentResult { + success: boolean + score?: number + data?: unknown + error?: string +} + +export interface GlitchComponentProps { + config: GlitchComponentConfig + onComplete: (result: GlitchComponentResult) => void + onProgress?: (percent: number) => void + theme?: GlitchTheme + className?: string + host?: GlitchHostBridge +} + +export interface ParamSchema { + [key: string]: { + type: 'number' | 'string' | 'boolean' | 'color' | 'select' | 'range' + label?: string + description?: string + default: unknown + options?: { value: string | number; label: string }[] + min?: number + max?: number + step?: number + } +} + +export interface GlitchComponentMetadata { + name: string + displayName: string + version: string + paramSchema: ParamSchema + defaultParams: Record +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e65dca4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "lib": [ + "ES2022", + "DOM", + "DOM.Iterable" + ], + "module": "ESNext", + "types": [ + "vite/client" + ], + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": [ + "src" + ] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..d4eedee --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,32 @@ +import { resolve } from 'path' +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' +import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' + +export default defineConfig(({ mode }) => ({ + plugins: [react(), cssInjectedByJsPlugin()], + build: { + lib: { + entry: resolve(__dirname, 'src/index.tsx'), + name: 'GlitchComponent', + fileName: 'demographic-wave', + formats: ['iife'] + }, + rollupOptions: { + external: ['react', 'react-dom'], + output: { + globals: { + react: 'React', + 'react-dom': 'ReactDOM' + }, + assetFileNames: 'assets/[name][extname]' + } + }, + sourcemap: true, + minify: mode === 'production' + }, + server: { + port: 3001, + open: true + } +}))