From da7fc72e3022c55c521b3b15addefaf39d076ea3 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/bubble-feedback.iife.js | 8 + dist/bubble-feedback.iife.js.map | 1 + glitch.manifest.json | 15 + index.html | 12 + package-lock.json | 2919 ++++++++++++++++++++++++++++++ package.json | 50 + src/Component.tsx | 432 +++++ src/dev-theme.css | 49 + src/dev.tsx | 56 + src/index.tsx | 65 + src/styles.module.css | 451 +++++ src/types.ts | 59 + src/vite-env.d.ts | 1 + tsconfig.json | 30 + vite.config.ts | 32 + 17 files changed, 4193 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 dist/bubble-feedback.iife.js create mode 100644 dist/bubble-feedback.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..26980be --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Bubble Feedback + +Standalone Glitch University component that shows bubbles as self-amplifying feedback loops: output becomes input, and each completed loop pushes the chart higher. + +## Development + +- `npm install` +- `npm run dev` +- `npm run build` + +The component follows the Glitch Component contract and registers itself as `window.GlitchComponents["bubble-feedback"]` when loaded from the built IIFE bundle. diff --git a/dist/bubble-feedback.iife.js b/dist/bubble-feedback.iife.js new file mode 100644 index 0000000..9a09fc5 --- /dev/null +++ b/dist/bubble-feedback.iife.js @@ -0,0 +1,8 @@ +(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode('._wrapper_cbum2_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_cbum2_1 *,._wrapper_cbum2_1 *:before,._wrapper_cbum2_1 *:after{box-sizing:inherit}._frame_cbum2_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;gap:.65em;overflow:hidden;padding:1em;color:var(--gc-text);font-family:var(--gc-font-main);font-size:clamp(10px,1.08cqw,18px);line-height:1.2;background:radial-gradient(circle at 16% 12%,color-mix(in srgb,var(--bubble-color) 22%,transparent),transparent 28%),radial-gradient(circle at 82% 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_cbum2_52,._controls_cbum2_53,._loopHeader_cbum2_54,._footer_cbum2_55,._cycleReadout_cbum2_56{display:flex;align-items:center}._header_cbum2_52,._loopHeader_cbum2_54,._footer_cbum2_55{justify-content:space-between;gap:1em}._header_cbum2_52 h2{margin:.1em 0 0;font-family:var(--gc-font-display);font-size:1.42em;line-height:1;letter-spacing:0}._kicker_cbum2_76{display:block;color:color-mix(in srgb,var(--gc-accent) 78%,white);font-family:var(--gc-font-mono);font-size:.62em;font-weight:700;letter-spacing:.12em;text-transform:uppercase}._controls_cbum2_53{gap:.45em}._iconButton_cbum2_90,._modeButton_cbum2_91,._completeButton_cbum2_92{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:.66em;font-weight:700;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;transition:transform .12s ease,border-color .12s ease,background-color .12s ease}._iconButton_cbum2_90:hover,._modeButton_cbum2_91:hover,._completeButton_cbum2_92:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--gc-accent) 62%,var(--gc-border))}._iconButton_cbum2_90{min-width:3.5em;min-height:2.6em;background:#0a0e18b8}._modeButton_cbum2_91{min-height:2.6em;padding:0 .8em;background:#0a0e1894}._modeActive_cbum2_124{color:#090b10;background:linear-gradient(90deg,var(--bubble-color),color-mix(in srgb,var(--gc-accent) 42%,var(--bubble-color)));border-color:#ffffff8f}._stageGrid_cbum2_130{min-height:0;display:grid;grid-template-columns:minmax(0,1.32fr) minmax(12em,.68fr);gap:.65em}._loopPanel_cbum2_137,._eventPanel_cbum2_138{min-width:0;min-height:0;border:1px solid color-mix(in srgb,var(--gc-border) 76%,transparent);background:#0509128f}._loopPanel_cbum2_137{display:grid;grid-template-rows:auto minmax(0,1fr);gap:.3em;padding:.75em}._loopHeader_cbum2_54 strong{display:block;margin-top:.2em;font-size:.86em;font-weight:650}._cycleReadout_cbum2_56{align-items:flex-end;flex-direction:column;gap:.16em;color:var(--gc-text-muted);font-family:var(--gc-font-mono);font-size:.66em;letter-spacing:.08em;text-transform:uppercase}._cycleReadout_cbum2_56 strong{color:var(--bubble-color);font-family:var(--gc-font-display);font-size:2.1em;line-height:.9;letter-spacing:0}._loop_cbum2_54{position:relative;width:min(100%,34em);aspect-ratio:1;align-self:center;justify-self:center}._ring_cbum2_186{position:absolute;inset:18%;border:.28em solid color-mix(in srgb,var(--bubble-color) 44%,transparent);border-radius:50%;box-shadow:inset 0 0 1.7em #ffffff0d,0 0 1.6em color-mix(in srgb,var(--bubble-color) 28%,transparent)}._ring_cbum2_186:after{content:"";position:absolute;inset:-.55em;border-radius:50%;border:1px dashed color-mix(in srgb,var(--gc-text) 24%,transparent)}._pulse_cbum2_204{position:absolute;inset:50%;width:1.05em;height:1.05em;border-radius:50%;background:var(--gc-accent);box-shadow:0 0 0 .4em color-mix(in srgb,var(--gc-accent) 14%,transparent),0 0 1.4em color-mix(in srgb,var(--gc-accent) 80%,transparent);transform:rotate(var(--rotation)) translateY(-10.7em) translate(-50%,-50%);transform-origin:0 0}._core_cbum2_218{position:absolute;inset:34%;overflow:hidden;border:1px solid color-mix(in srgb,var(--gc-border) 78%,transparent);border-radius:50%;background:#070b11e0;text-align:center}._coreOverlay_cbum2_228{position:absolute;inset:auto 12% 13%;display:flex;align-items:flex-end;justify-content:space-between;gap:.5em;pointer-events:none}._coreOverlay_cbum2_228 span{max-width:9em;color:color-mix(in srgb,var(--gc-text-muted) 88%,white);font-family:var(--gc-font-mono);font-size:.58em;font-weight:700;letter-spacing:.1em;line-height:1.1;text-align:left;text-transform:uppercase}._coreOverlay_cbum2_228 strong{color:var(--bubble-color);font-family:var(--gc-font-display);font-size:1.28em;line-height:.9}._canvas_cbum2_257{display:block;width:100%;height:100%;border:0;background:linear-gradient(90deg,color-mix(in srgb,var(--bubble-color) 8%,transparent),transparent 40%),#070b11c7}._loopStation_cbum2_267{position:absolute;z-index:2;width:0;height:0;transform:translate(-50%,-50%)}._loopNode_cbum2_275{position:absolute;left:0;top:0;width:2.4em;height:2.4em;display:grid;place-items:center;border:1px solid color-mix(in srgb,var(--gc-border) 80%,transparent);border-radius:50%;background:#090d16f0;color:var(--gc-text-muted);font-family:var(--gc-font-mono);font-size:.78em;font-weight:800;transform:translate(-50%,-50%);transition:color .16s ease,border-color .16s ease,background-color .16s ease,box-shadow .16s ease}._nodeActive_cbum2_294{color:#071018;background:var(--bubble-color);border-color:#ffffffb8;box-shadow:0 0 1.2em color-mix(in srgb,var(--bubble-color) 54%,transparent)}._stationLabel_cbum2_301{position:absolute;left:0;top:0;width:12.4em;max-height:4.6em;overflow:hidden;margin:0;padding:.48em .58em;border:1px solid color-mix(in srgb,var(--gc-border) 72%,transparent);background:#050912d1;color:color-mix(in srgb,var(--gc-text-muted) 86%,white);font-size:.62em;line-height:1.14;transform:translate(calc(-50% + var(--label-x)),calc(-50% + var(--label-y)));transition:color .16s ease,border-color .16s ease,background-color .16s ease,box-shadow .16s ease}._labelActive_cbum2_319{border-color:color-mix(in srgb,var(--bubble-color) 70%,var(--gc-border));background:color-mix(in srgb,var(--bubble-color) 18%,rgb(5 9 18));color:var(--gc-text);box-shadow:0 0 1.1em color-mix(in srgb,var(--bubble-color) 26%,transparent)}._eventPanel_cbum2_138{display:flex;flex-direction:column;justify-content:space-between;gap:1em;padding:.9em}._eventPanel_cbum2_138 h3{margin:0;color:var(--gc-text);font-family:var(--gc-font-display);font-size:1.18em;line-height:1.04;letter-spacing:0}._nextEvent_cbum2_343{padding-top:.75em;border-top:1px solid color-mix(in srgb,var(--gc-border) 72%,transparent)}._nextEvent_cbum2_343 span,._definition_cbum2_349 span{color:var(--bubble-color);font-family:var(--gc-font-mono);font-size:.62em;font-weight:800;letter-spacing:.1em;text-transform:uppercase}._nextEvent_cbum2_343 p,._definition_cbum2_349 p{margin:.35em 0 0;color:color-mix(in srgb,var(--gc-text-muted) 86%,white);font-size:.8em;line-height:1.22}._definition_cbum2_349{padding-top:.75em;border-top:1px solid color-mix(in srgb,var(--gc-border) 72%,transparent)}._footer_cbum2_55{display:grid;grid-template-columns:minmax(0,1fr) auto;padding:.62em .8em;border:1px solid color-mix(in srgb,var(--gc-border) 76%,transparent);background:#0509128a}._footer_cbum2_55 input{width:100%;accent-color:var(--bubble-color)}._completeButton_cbum2_92{min-width:3em;min-height:2.35em;padding:0 .8em;background:color-mix(in srgb,var(--gc-primary) 28%,rgb(5 9 18))}._completeButton_cbum2_92:disabled{cursor:default;opacity:.68;transform:none}@media(orientation:portrait){._frame_cbum2_27{width:min(100%,calc((100dvh - (var(--gc-shell-padding) * 2)) / 2));aspect-ratio:1 / 2;grid-template-rows:auto minmax(0,1fr) auto;font-size:clamp(10px,3.15cqw,16px)}._header_cbum2_52{align-items:flex-start;flex-direction:column;gap:.55em}._header_cbum2_52 h2{font-size:1.2em}._controls_cbum2_53{width:100%;display:grid;grid-template-columns:3.4em repeat(2,minmax(0,1fr))}._stageGrid_cbum2_130{grid-template-columns:1fr;grid-template-rows:minmax(0,1fr) auto}._loop_cbum2_54{width:min(100%,29em)}._pulse_cbum2_204{transform:rotate(var(--rotation)) translateY(-9.2em) translate(-50%,-50%)}._eventPanel_cbum2_138{padding:.75em}._eventPanel_cbum2_138 h3{font-size:.96em}._nextEvent_cbum2_343 p{display:none}._stationLabel_cbum2_301{width:10.8em;max-height:3.9em;font-size:.54em}}')),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})(); +var GlitchComponent=(function(z,b){"use strict";var H={exports:{}},F={};var ne;function ce(){if(ne)return F;ne=1;var r=Symbol.for("react.transitional.element"),u=Symbol.for("react.fragment");function g(i,d,v){var p=null;if(v!==void 0&&(p=""+v),d.key!==void 0&&(p=""+d.key),"key"in d){v={};for(var m in d)m!=="key"&&(v[m]=d[m])}else v=d;return d=v.ref,{$$typeof:r,type:i,key:p,ref:d!==void 0?d:null,props:v}}return F.Fragment=u,F.jsx=g,F.jsxs=g,F}var Y={};var re;function le(){return re||(re=1,process.env.NODE_ENV!=="production"&&(function(){function r(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===J?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case A:return"Fragment";case _:return"Profiler";case O:return"StrictMode";case G:return"Suspense";case N:return"SuspenseList";case U: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 P:return"Portal";case C:return e.displayName||"Context";case y:return(e._context.displayName||"Context")+".Consumer";case l:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case D:return n=e.displayName||null,n!==null?n:r(e.type)||"Memo";case W:n=e._payload,e=e._init;try{return r(e(n))}catch{}}return null}function u(e){return""+e}function g(e){try{u(e);var n=!1}catch{n=!0}if(n){n=console;var c=n.error,f=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return c.call(n,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",f),u(e)}}function i(e){if(e===A)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===W)return"<...>";try{var n=r(e);return n?"<"+n+">":"<...>"}catch{return"<...>"}}function d(){var e=L.A;return e===null?null:e.getOwner()}function v(){return Error("react-stack-top-frame")}function p(e){if(X.call(e,"key")){var n=Object.getOwnPropertyDescriptor(e,"key").get;if(n&&n.isReactWarning)return!1}return e.key!==void 0}function m(e,n){function c(){K||(K=!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)",n))}c.isReactWarning=!0,Object.defineProperty(e,"key",{get:c,configurable:!0})}function R(){var e=r(this.type);return Z[e]||(Z[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 o(e,n,c,f,I,ee){var h=c.ref;return e={$$typeof:T,type:e,key:n,props:c,_owner:f},(h!==void 0?h:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:R}):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:I}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:ee}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function E(e,n,c,f,I,ee){var h=n.children;if(h!==void 0)if(f)if(V(h)){for(f=0;f +React keys must be passed directly to JSX without using spread: + let props = %s; + <%s key={someKey} {...props} />`,f,h,B,h),S[h+f]=!0)}if(h=null,c!==void 0&&(g(c),h=""+c),p(n)&&(g(n.key),h=""+n.key),"key"in n){c={};for(var te in n)te!=="key"&&(c[te]=n[te])}else c=n;return h&&m(c,typeof e=="function"?e.displayName||e.name||"Unknown":e),o(e,h,c,d(),I,ee)}function x(e){k(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===W&&(e._payload.status==="fulfilled"?k(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function k(e){return typeof e=="object"&&e!==null&&e.$$typeof===T}var j=b,T=Symbol.for("react.transitional.element"),P=Symbol.for("react.portal"),A=Symbol.for("react.fragment"),O=Symbol.for("react.strict_mode"),_=Symbol.for("react.profiler"),y=Symbol.for("react.consumer"),C=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),G=Symbol.for("react.suspense"),N=Symbol.for("react.suspense_list"),D=Symbol.for("react.memo"),W=Symbol.for("react.lazy"),U=Symbol.for("react.activity"),J=Symbol.for("react.client.reference"),L=j.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,X=Object.prototype.hasOwnProperty,V=Array.isArray,w=console.createTask?console.createTask:function(){return null};j={react_stack_bottom_frame:function(e){return e()}};var K,Z={},Q=j.react_stack_bottom_frame.bind(j,v)(),s=w(i(v)),S={};Y.Fragment=A,Y.jsx=function(e,n,c){var f=1e4>L.recentlyCreatedOwnerStacks++;return E(e,n,c,!1,f?Error("react-stack-top-frame"):Q,f?w(i(e)):s)},Y.jsxs=function(e,n,c){var f=1e4>L.recentlyCreatedOwnerStacks++;return E(e,n,c,!0,f?Error("react-stack-top-frame"):Q,f?w(i(e)):s)}})()),Y}var oe;function ie(){return oe||(oe=1,process.env.NODE_ENV==="production"?H.exports=ce():H.exports=le()),H.exports}var t=ie();const a={wrapper:"_wrapper_cbum2_1",frame:"_frame_cbum2_27",header:"_header_cbum2_52",controls:"_controls_cbum2_53",loopHeader:"_loopHeader_cbum2_54",footer:"_footer_cbum2_55",cycleReadout:"_cycleReadout_cbum2_56",kicker:"_kicker_cbum2_76",iconButton:"_iconButton_cbum2_90",modeButton:"_modeButton_cbum2_91",completeButton:"_completeButton_cbum2_92",modeActive:"_modeActive_cbum2_124",stageGrid:"_stageGrid_cbum2_130",loopPanel:"_loopPanel_cbum2_137",eventPanel:"_eventPanel_cbum2_138",loop:"_loop_cbum2_54",ring:"_ring_cbum2_186",pulse:"_pulse_cbum2_204",core:"_core_cbum2_218",coreOverlay:"_coreOverlay_cbum2_228",canvas:"_canvas_cbum2_257",loopStation:"_loopStation_cbum2_267",loopNode:"_loopNode_cbum2_275",nodeActive:"_nodeActive_cbum2_294",stationLabel:"_stationLabel_cbum2_301",labelActive:"_labelActive_cbum2_319",nextEvent:"_nextEvent_cbum2_343",definition:"_definition_cbum2_349"},ue=[{key:"ai-stock",title:"AI Stock Bubble",shortLabel:"AI STOCK",subject:"Market price becomes evidence",outputLabel:"price",chartLabel:"price expectation",color:"#f0c45c",events:["Stock price rises because people buy","Stronger financial position lets the company borrow more","Borrowing more results in larger AI investment","Larger AI investment increases AI race winning probability","AI race winning increases future earnings expectation"]},{key:"string-theory",title:"String Theory Field Bubble",shortLabel:"STRING",subject:"Activity becomes evidence",outputLabel:"field activity",chartLabel:"field promise",color:"#74d6ff",events:["People choose String Theory for doctoral theses because of job opportunities","String Theory gets lots of new researchers","Researchers publish research and cite other string theorists","Activity and citations become proxy for how promising a research field is","Promising translates to successful grants","Grants become open positions"]}],M=(r,u,g)=>Math.min(g,Math.max(u,r)),$=(r,u)=>typeof r=="number"?r:u,de=(r,u)=>!Array.isArray(r.events)||r.events.length<2?null:{key:r.key??`custom-${u}`,title:r.title??`Custom Loop ${u+1}`,shortLabel:r.shortLabel??`LOOP ${u+1}`,subject:r.subject??"Output becomes input",outputLabel:r.outputLabel??"output",chartLabel:r.chartLabel??"amplification",color:r.color??"#8ee6a8",events:r.events},me=r=>{const u=Array.isArray(r.scenarios)?r.scenarios.map(de).filter(g=>!!g):[];return u.length>0?u:ue},ae=(r,u,g)=>{const i=r*Math.max(.02,u-.52)*.22,d=Math.exp(r*Math.max(0,u-.86)*.11),v=Math.sin(r*1.38)*g*.42;return M(.1+i+d*.18-v,.08,2.7)};function fe(r,u,g,i,d){const v=r.getBoundingClientRect(),p=window.devicePixelRatio||1,m=v.width,R=v.height;r.width=Math.floor(m*p),r.height=Math.floor(R*p);const o=r.getContext("2d");if(!o)return;o.setTransform(p,0,0,p,0,0),o.clearRect(0,0,m,R);const E=m*.08,x=R*.14,k=m-E*2,j=R-x*2;o.lineWidth=1,o.strokeStyle=d.grid;for(let _=0;_<=4;_+=1){const y=x+_/4*j;o.beginPath(),o.moveTo(E,y),o.lineTo(m-E,y),o.stroke()}const T=80,P=Array.from({length:T},(_,y)=>{const C=Math.max(0,u-7+y/(T-1)*7),l=ae(C,g,i);return{x:E+y/(T-1)*k,y:x+j-l/2.7*j}}),A=o.createLinearGradient(0,x,0,R-x);A.addColorStop(0,d.scenario),A.addColorStop(1,"rgba(255, 255, 255, 0)"),o.beginPath(),P.forEach((_,y)=>{y===0?o.moveTo(_.x,_.y):o.lineTo(_.x,_.y)}),o.lineTo(m-E,R-x),o.lineTo(E,R-x),o.closePath(),o.fillStyle=A,o.globalAlpha=.22,o.fill(),o.globalAlpha=1,o.beginPath(),P.forEach((_,y)=>{y===0?o.moveTo(_.x,_.y):o.lineTo(_.x,_.y)}),o.strokeStyle=d.scenario,o.lineWidth=Math.max(2,m*.006),o.stroke();const O=P[P.length-1];o.beginPath(),o.arc(O.x,O.y,Math.max(5,m*.014),0,Math.PI*2),o.fillStyle=d.accent,o.fill()}function se({config:r,onComplete:u,onProgress:g,theme:i,className:d,host:v}){const p=r.params,m=b.useMemo(()=>me(p),[p]),[R,o]=b.useState(()=>String(p.scenario??m[0].key)),[E,x]=b.useState(!0),[k,j]=b.useState(0),[T,P]=b.useState(!1),A=b.useRef(null),O=b.useRef(0),_=M($(p.animationSpeed,1),.25,3),y=M($(p.feedbackStrength,1.18),.55,1.8),C=M($(p.correctionPressure,.18),0,.65),l=m.find(s=>s.key===R)??m[0],G=k%1,N=Math.floor(G*l.events.length)%l.events.length,D=(N+1)%l.events.length,W=ae(k,y,C),U=Math.round(M(W/2.7*100,0,100)),J=Math.round(M(k/12*100,0,100)),L=b.useMemo(()=>({accent:i?.accent??"#22d3ee",text:i?.text??"#e8e8ec",muted:i?.textMuted??"#9999a8",grid:"rgba(232, 232, 236, 0.13)",scenario:l.color}),[l.color,i?.accent,i?.text,i?.textMuted]),X=b.useMemo(()=>({"--gc-primary":i?.primary,"--gc-accent":i?.accent,"--gc-bg":i?.bg,"--gc-bg-secondary":i?.bgSecondary,"--gc-text":i?.text,"--gc-text-muted":i?.textMuted,"--gc-border":i?.border,"--bubble-color":l.color,"--rotation":`${G*360}deg`}),[G,l.color,i]),V=b.useCallback(()=>{A.current&&fe(A.current,k,y,C,L)},[C,k,y,L]);b.useEffect(()=>{o(String(p.scenario??m[0].key))},[p.scenario,m]),b.useEffect(()=>{j(0)},[R]),b.useEffect(()=>{g?.(J)},[g,J]),b.useEffect(()=>{V();const s=A.current;if(!s)return;const S=new ResizeObserver(V);return S.observe(s),()=>S.disconnect()},[V]),b.useEffect(()=>{let s=0;const S=e=>{const n=34/_;E&&e-O.current>n&&(j(c=>c>=12?0:c+.0125),O.current=e),s=window.requestAnimationFrame(S)};return s=window.requestAnimationFrame(S),()=>window.cancelAnimationFrame(s)},[_,E]);const w=b.useCallback(s=>{v?.playSound?.("ui.button_click",{target:s,component:r.name})},[r.name,v]),K=b.useCallback(s=>{w(s),x(!0),o(s)},[w]),Z=b.useCallback(()=>{T||(P(!0),w("complete"),u({success:!0,score:100,data:{scenario:l.key,cycle:k,pressure:U,activeEvent:l.events[N],nextEvent:l.events[D],definition:"A bubble is a self-amplifying feedback loop: output becomes input.",configId:r.id,completedAt:new Date().toISOString()}}))},[T,r.id,k,N,D,u,w,U,l]),Q=d?`${a.wrapper} ${d}`:a.wrapper;return t.jsx("section",{className:Q,style:X,"aria-label":"Bubble feedback simulator",children:t.jsxs("div",{className:a.frame,children:[t.jsxs("header",{className:a.header,children:[t.jsxs("div",{children:[t.jsx("span",{className:a.kicker,children:"Feedback loop"}),t.jsx("h2",{children:"A bubble is output used as input"})]}),t.jsxs("div",{className:a.controls,"aria-label":"Simulation controls",children:[t.jsx("button",{className:a.iconButton,type:"button",onClick:()=>x(s=>!s),children:E?"II":">"}),m.map(s=>t.jsx("button",{className:`${a.modeButton} ${s.key===l.key?a.modeActive:""}`,type:"button",onClick:()=>K(s.key),children:s.shortLabel},s.key))]})]}),t.jsxs("main",{className:a.stageGrid,children:[t.jsxs("section",{className:a.loopPanel,"aria-label":`${l.title} loop`,children:[t.jsxs("div",{className:a.loopHeader,children:[t.jsxs("div",{children:[t.jsx("span",{className:a.kicker,children:l.title}),t.jsx("strong",{children:l.subject})]}),t.jsxs("div",{className:a.cycleReadout,children:[t.jsx("span",{children:"cycle"}),t.jsx("strong",{children:k.toFixed(1)})]})]}),t.jsxs("div",{className:a.loop,children:[t.jsx("div",{className:a.ring,"aria-hidden":"true"}),t.jsx("div",{className:a.pulse,"aria-hidden":"true"}),t.jsxs("div",{className:a.core,children:[t.jsx("canvas",{ref:A,className:a.canvas,"aria-label":`${l.chartLabel} chart`}),t.jsxs("div",{className:a.coreOverlay,children:[t.jsx("span",{children:l.chartLabel}),t.jsxs("strong",{children:[U,"%"]})]})]}),l.events.map((s,S)=>{const e=S/l.events.length*Math.PI*2-Math.PI/2,n=50+Math.cos(e)*32,c=50+Math.sin(e)*32,f=Math.cos(e)*5.4,I=Math.sin(e)*4.5;return t.jsxs("div",{className:a.loopStation,style:{left:`${n}%`,top:`${c}%`,"--label-x":`${f}em`,"--label-y":`${I}em`},children:[t.jsx("div",{className:`${a.loopNode} ${S===N?a.nodeActive:""}`,children:t.jsx("span",{children:S+1})}),t.jsx("p",{className:`${a.stationLabel} ${S===N?a.labelActive:""}`,children:s})]},s)})]})]}),t.jsxs("aside",{className:a.eventPanel,children:[t.jsx("span",{className:a.kicker,children:"Now feeding back"}),t.jsx("h3",{children:l.events[N]}),t.jsxs("div",{className:a.nextEvent,children:[t.jsx("span",{children:"next"}),t.jsx("p",{children:l.events[D]})]}),t.jsxs("div",{className:a.definition,children:[t.jsx("span",{children:"definition"}),t.jsx("p",{children:"A bubble is a self-amplifying feedback loop: output becomes input."})]})]})]}),t.jsxs("footer",{className:a.footer,children:[t.jsx("input",{"aria-label":"Loop cycle",type:"range",min:0,max:12,step:.05,value:k,onChange:s=>{w("cycle"),x(!1),j(Number(s.currentTarget.value))}}),t.jsx("button",{className:a.completeButton,type:"button",onClick:Z,disabled:T,children:T?"OK":"✓"})]})]})})}const q={name:"bubble-feedback",displayName:"Bubble Feedback",version:"1.0.0",paramSchema:{scenario:{type:"select",label:"Scenario",default:"ai-stock",options:[{value:"ai-stock",label:"AI Stock Bubble"},{value:"string-theory",label:"String Theory Field Bubble"}]},animationSpeed:{type:"range",label:"Animation Speed",default:1,min:.25,max:3,step:.25},feedbackStrength:{type:"range",label:"Feedback Strength",default:1.18,min:.55,max:1.8,step:.05},correctionPressure:{type:"range",label:"Correction Pressure",default:.18,min:0,max:.65,step:.05}},defaultParams:{scenario:"ai-stock",animationSpeed:1,feedbackStrength:1.18,correctionPressure:.18}};return typeof window<"u"&&(window.GlitchComponents??={},window.GlitchComponents[q.name]={default:se,metadata:q}),z.default=se,z.metadata=q,Object.defineProperties(z,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),z})({},React); +//# sourceMappingURL=bubble-feedback.iife.js.map diff --git a/dist/bubble-feedback.iife.js.map b/dist/bubble-feedback.iife.js.map new file mode 100644 index 0000000..f5ea055 --- /dev/null +++ b/dist/bubble-feedback.iife.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bubble-feedback.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 ScenarioKey = 'ai-stock' | 'string-theory'\n\ninterface LoopScenario {\n key: ScenarioKey\n title: string\n shortLabel: string\n subject: string\n outputLabel: string\n chartLabel: string\n color: string\n events: string[]\n}\n\ninterface CustomScenario {\n key?: string\n title?: string\n shortLabel?: string\n subject?: string\n outputLabel?: string\n chartLabel?: string\n color?: string\n events?: string[]\n}\n\ninterface ComponentParams {\n scenario?: string\n scenarios?: CustomScenario[]\n animationSpeed?: number\n feedbackStrength?: number\n correctionPressure?: number\n}\n\ninterface Palette {\n accent: string\n text: string\n muted: string\n grid: string\n scenario: string\n}\n\nconst DEFAULT_SCENARIOS: LoopScenario[] = [\n {\n key: 'ai-stock',\n title: 'AI Stock Bubble',\n shortLabel: 'AI STOCK',\n subject: 'Market price becomes evidence',\n outputLabel: 'price',\n chartLabel: 'price expectation',\n color: '#f0c45c',\n events: [\n 'Stock price rises because people buy',\n 'Stronger financial position lets the company borrow more',\n 'Borrowing more results in larger AI investment',\n 'Larger AI investment increases AI race winning probability',\n 'AI race winning increases future earnings expectation'\n ]\n },\n {\n key: 'string-theory',\n title: 'String Theory Field Bubble',\n shortLabel: 'STRING',\n subject: 'Activity becomes evidence',\n outputLabel: 'field activity',\n chartLabel: 'field promise',\n color: '#74d6ff',\n events: [\n 'People choose String Theory for doctoral theses because of job opportunities',\n 'String Theory gets lots of new researchers',\n 'Researchers publish research and cite other string theorists',\n 'Activity and citations become proxy for how promising a research field is',\n 'Promising translates to successful grants',\n 'Grants become open positions'\n ]\n }\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 createScenario = (scenario: CustomScenario, index: number): LoopScenario | null => {\n if (!Array.isArray(scenario.events) || scenario.events.length < 2) return null\n\n return {\n key: (scenario.key ?? `custom-${index}`) as ScenarioKey,\n title: scenario.title ?? `Custom Loop ${index + 1}`,\n shortLabel: scenario.shortLabel ?? `LOOP ${index + 1}`,\n subject: scenario.subject ?? 'Output becomes input',\n outputLabel: scenario.outputLabel ?? 'output',\n chartLabel: scenario.chartLabel ?? 'amplification',\n color: scenario.color ?? '#8ee6a8',\n events: scenario.events\n }\n}\n\nconst getScenarios = (params: ComponentParams) => {\n const customScenarios = Array.isArray(params.scenarios)\n ? params.scenarios.map(createScenario).filter((scenario): scenario is LoopScenario => Boolean(scenario))\n : []\n\n return customScenarios.length > 0 ? customScenarios : DEFAULT_SCENARIOS\n}\n\nconst getBubbleValue = (cycle: number, feedbackStrength: number, correctionPressure: number) => {\n const drift = cycle * Math.max(0.02, feedbackStrength - 0.52) * 0.22\n const compounding = Math.exp(cycle * Math.max(0, feedbackStrength - 0.86) * 0.11)\n const correction = Math.sin(cycle * 1.38) * correctionPressure * 0.42\n return clamp(0.1 + drift + compounding * 0.18 - correction, 0.08, 2.7)\n}\n\nfunction drawChart(\n canvas: HTMLCanvasElement,\n cycle: number,\n feedbackStrength: number,\n correctionPressure: 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.08\n const padY = height * 0.14\n const chartW = width - padX * 2\n const chartH = height - padY * 2\n\n ctx.lineWidth = 1\n ctx.strokeStyle = palette.grid\n for (let index = 0; index <= 4; index += 1) {\n const y = padY + (index / 4) * chartH\n ctx.beginPath()\n ctx.moveTo(padX, y)\n ctx.lineTo(width - padX, y)\n ctx.stroke()\n }\n\n const samples = 80\n const points = Array.from({ length: samples }, (_, index) => {\n const sampleCycle = Math.max(0, cycle - 7 + (index / (samples - 1)) * 7)\n const value = getBubbleValue(sampleCycle, feedbackStrength, correctionPressure)\n return {\n x: padX + (index / (samples - 1)) * chartW,\n y: padY + chartH - (value / 2.7) * chartH\n }\n })\n\n const gradient = ctx.createLinearGradient(0, padY, 0, height - padY)\n gradient.addColorStop(0, palette.scenario)\n gradient.addColorStop(1, 'rgba(255, 255, 255, 0)')\n\n ctx.beginPath()\n points.forEach((point, index) => {\n if (index === 0) ctx.moveTo(point.x, point.y)\n else ctx.lineTo(point.x, point.y)\n })\n ctx.lineTo(width - padX, height - padY)\n ctx.lineTo(padX, height - padY)\n ctx.closePath()\n ctx.fillStyle = gradient\n ctx.globalAlpha = 0.22\n ctx.fill()\n ctx.globalAlpha = 1\n\n ctx.beginPath()\n points.forEach((point, index) => {\n if (index === 0) ctx.moveTo(point.x, point.y)\n else ctx.lineTo(point.x, point.y)\n })\n ctx.strokeStyle = palette.scenario\n ctx.lineWidth = Math.max(2, width * 0.006)\n ctx.stroke()\n\n const latest = points[points.length - 1]\n ctx.beginPath()\n ctx.arc(latest.x, latest.y, Math.max(5, width * 0.014), 0, Math.PI * 2)\n ctx.fillStyle = palette.accent\n ctx.fill()\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 scenarios = useMemo(() => getScenarios(params), [params])\n const [scenarioKey, setScenarioKey] = useState(() => String(params.scenario ?? scenarios[0].key))\n const [running, setRunning] = useState(true)\n const [cycle, setCycle] = useState(0)\n const [completed, setCompleted] = useState(false)\n const canvasRef = useRef(null)\n const lastTickRef = useRef(0)\n\n const animationSpeed = clamp(numberParam(params.animationSpeed, 1), 0.25, 3)\n const feedbackStrength = clamp(numberParam(params.feedbackStrength, 1.18), 0.55, 1.8)\n const correctionPressure = clamp(numberParam(params.correctionPressure, 0.18), 0, 0.65)\n const scenario = scenarios.find((item) => item.key === scenarioKey) ?? scenarios[0]\n const phase = cycle % 1\n const eventIndex = Math.floor(phase * scenario.events.length) % scenario.events.length\n const nextEventIndex = (eventIndex + 1) % scenario.events.length\n const bubbleValue = getBubbleValue(cycle, feedbackStrength, correctionPressure)\n const pressure = Math.round(clamp((bubbleValue / 2.7) * 100, 0, 100))\n const progress = Math.round(clamp((cycle / 12) * 100, 0, 100))\n\n const palette = useMemo(() => ({\n accent: theme?.accent ?? '#22d3ee',\n text: theme?.text ?? '#e8e8ec',\n muted: theme?.textMuted ?? '#9999a8',\n grid: 'rgba(232, 232, 236, 0.13)',\n scenario: scenario.color\n }), [scenario.color, theme?.accent, theme?.text, theme?.textMuted])\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 '--bubble-color': scenario.color,\n '--rotation': `${phase * 360}deg`\n }) as CSSProperties, [phase, scenario.color, theme])\n\n const redraw = useCallback(() => {\n if (!canvasRef.current) return\n drawChart(canvasRef.current, cycle, feedbackStrength, correctionPressure, palette)\n }, [correctionPressure, cycle, feedbackStrength, palette])\n\n useEffect(() => {\n setScenarioKey(String(params.scenario ?? scenarios[0].key))\n }, [params.scenario, scenarios])\n\n useEffect(() => {\n setCycle(0)\n }, [scenarioKey])\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 = 34 / animationSpeed\n if (running && timestamp - lastTickRef.current > interval) {\n setCycle((current) => (current >= 12 ? 0 : current + 0.0125))\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, running])\n\n const playClick = useCallback((target: string) => {\n host?.playSound?.('ui.button_click', { target, component: config.name })\n }, [config.name, host])\n\n const chooseScenario = useCallback((key: ScenarioKey) => {\n playClick(key)\n setRunning(true)\n setScenarioKey(key)\n }, [playClick])\n\n const finish = useCallback(() => {\n if (completed) return\n\n setCompleted(true)\n playClick('complete')\n onComplete({\n success: true,\n score: 100,\n data: {\n scenario: scenario.key,\n cycle,\n pressure,\n activeEvent: scenario.events[eventIndex],\n nextEvent: scenario.events[nextEventIndex],\n definition: 'A bubble is a self-amplifying feedback loop: output becomes input.',\n configId: config.id,\n completedAt: new Date().toISOString()\n }\n })\n }, [completed, config.id, cycle, eventIndex, nextEventIndex, onComplete, playClick, pressure, scenario])\n\n const rootClassName = className ? `${styles.wrapper} ${className}` : styles.wrapper\n\n return (\n
\n
\n
\n
\n Feedback loop\n

A bubble is output used as input

\n
\n
\n \n {scenarios.map((item) => (\n chooseScenario(item.key)}\n >\n {item.shortLabel}\n \n ))}\n
\n
\n\n
\n
\n
\n
\n {scenario.title}\n {scenario.subject}\n
\n
\n cycle\n {cycle.toFixed(1)}\n
\n
\n\n
\n
\n
\n
\n \n
\n {scenario.chartLabel}\n {pressure}%\n
\n
\n {scenario.events.map((event, index) => {\n const angle = (index / scenario.events.length) * Math.PI * 2 - Math.PI / 2\n const x = 50 + Math.cos(angle) * 32\n const y = 50 + Math.sin(angle) * 32\n const labelX = Math.cos(angle) * 5.4\n const labelY = Math.sin(angle) * 4.5\n return (\n \n
\n {index + 1}\n
\n

\n {event}\n

\n
\n )\n })}\n
\n
\n\n \n
\n\n
\n {\n playClick('cycle')\n setRunning(false)\n setCycle(Number(event.currentTarget.value))\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: 'bubble-feedback',\n displayName: 'Bubble Feedback',\n version: '1.0.0',\n paramSchema: {\n scenario: {\n type: 'select',\n label: 'Scenario',\n default: 'ai-stock',\n options: [\n { value: 'ai-stock', label: 'AI Stock Bubble' },\n { value: 'string-theory', label: 'String Theory Field Bubble' }\n ]\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 feedbackStrength: {\n type: 'range',\n label: 'Feedback Strength',\n default: 1.18,\n min: 0.55,\n max: 1.8,\n step: 0.05\n },\n correctionPressure: {\n type: 'range',\n label: 'Correction Pressure',\n default: 0.18,\n min: 0,\n max: 0.65,\n step: 0.05\n }\n },\n defaultParams: {\n scenario: 'ai-stock',\n animationSpeed: 1,\n feedbackStrength: 1.18,\n correctionPressure: 0.18\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","DEFAULT_SCENARIOS","clamp","min","max","numberParam","fallback","createScenario","scenario","index","getScenarios","params","customScenarios","getBubbleValue","cycle","feedbackStrength","correctionPressure","drift","compounding","correction","drawChart","canvas","palette","rect","scale","width","height","ctx","padX","padY","chartW","chartH","samples","points","sampleCycle","gradient","point","latest","Component","onComplete","onProgress","theme","className","host","scenarios","useMemo","scenarioKey","setScenarioKey","useState","running","setRunning","setCycle","completed","setCompleted","canvasRef","useRef","lastTickRef","animationSpeed","item","phase","eventIndex","nextEventIndex","bubbleValue","pressure","progress","themeStyle","redraw","useCallback","useEffect","resizeObserver","animationFrame","step","timestamp","interval","current","playClick","target","chooseScenario","finish","rootClassName","styles","jsx","jsxs","event","angle","x","y","labelX","labelY","metadata"],"mappings":"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","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..9d8bfb3 --- /dev/null +++ b/glitch.manifest.json @@ -0,0 +1,15 @@ +{ + "componentId": "bubble-feedback", + "displayName": "Bubble Feedback", + "version": "1.0.0", + "folderName": "glitch-bubble-simulator", + "packageName": "@glitch-components/bubble-feedback", + "entry": "dist/bubble-feedback.js", + "source": "src/index.tsx", + "tags": [ + "glitch-component", + "bubble", + "feedback", + "simulation" + ] +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..db28525 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + Bubble Feedback + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ed4a5f6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2919 @@ +{ + "name": "@glitch-components/bubble-feedback", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@glitch-components/bubble-feedback", + "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.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "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-beta.47", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.47.tgz", + "integrity": "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==", + "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.1.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.1.tgz", + "integrity": "sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.5", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.47", + "@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" + } + }, + "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.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "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.2.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz", + "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.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..82b32fd --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "@glitch-components/bubble-feedback", + "version": "1.0.0", + "description": "Bubble Feedback glitch component for Glitch University", + "type": "module", + "main": "./dist/bubble-feedback.js", + "module": "./dist/bubble-feedback.js", + "types": "./src/types.ts", + "exports": { + ".": { + "import": "./dist/bubble-feedback.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", + "bubble", + "feedback", + "simulation", + "component" + ], + "author": "Glitch.university", + "license": "MIT" +} diff --git a/src/Component.tsx b/src/Component.tsx new file mode 100644 index 0000000..2ee001a --- /dev/null +++ b/src/Component.tsx @@ -0,0 +1,432 @@ +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 ScenarioKey = 'ai-stock' | 'string-theory' + +interface LoopScenario { + key: ScenarioKey + title: string + shortLabel: string + subject: string + outputLabel: string + chartLabel: string + color: string + events: string[] +} + +interface CustomScenario { + key?: string + title?: string + shortLabel?: string + subject?: string + outputLabel?: string + chartLabel?: string + color?: string + events?: string[] +} + +interface ComponentParams { + scenario?: string + scenarios?: CustomScenario[] + animationSpeed?: number + feedbackStrength?: number + correctionPressure?: number +} + +interface Palette { + accent: string + text: string + muted: string + grid: string + scenario: string +} + +const DEFAULT_SCENARIOS: LoopScenario[] = [ + { + key: 'ai-stock', + title: 'AI Stock Bubble', + shortLabel: 'AI STOCK', + subject: 'Market price becomes evidence', + outputLabel: 'price', + chartLabel: 'price expectation', + color: '#f0c45c', + events: [ + 'Stock price rises because people buy', + 'Stronger financial position lets the company borrow more', + 'Borrowing more results in larger AI investment', + 'Larger AI investment increases AI race winning probability', + 'AI race winning increases future earnings expectation' + ] + }, + { + key: 'string-theory', + title: 'String Theory Field Bubble', + shortLabel: 'STRING', + subject: 'Activity becomes evidence', + outputLabel: 'field activity', + chartLabel: 'field promise', + color: '#74d6ff', + events: [ + 'People choose String Theory for doctoral theses because of job opportunities', + 'String Theory gets lots of new researchers', + 'Researchers publish research and cite other string theorists', + 'Activity and citations become proxy for how promising a research field is', + 'Promising translates to successful grants', + 'Grants become open positions' + ] + } +] + +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 createScenario = (scenario: CustomScenario, index: number): LoopScenario | null => { + if (!Array.isArray(scenario.events) || scenario.events.length < 2) return null + + return { + key: (scenario.key ?? `custom-${index}`) as ScenarioKey, + title: scenario.title ?? `Custom Loop ${index + 1}`, + shortLabel: scenario.shortLabel ?? `LOOP ${index + 1}`, + subject: scenario.subject ?? 'Output becomes input', + outputLabel: scenario.outputLabel ?? 'output', + chartLabel: scenario.chartLabel ?? 'amplification', + color: scenario.color ?? '#8ee6a8', + events: scenario.events + } +} + +const getScenarios = (params: ComponentParams) => { + const customScenarios = Array.isArray(params.scenarios) + ? params.scenarios.map(createScenario).filter((scenario): scenario is LoopScenario => Boolean(scenario)) + : [] + + return customScenarios.length > 0 ? customScenarios : DEFAULT_SCENARIOS +} + +const getBubbleValue = (cycle: number, feedbackStrength: number, correctionPressure: number) => { + const drift = cycle * Math.max(0.02, feedbackStrength - 0.52) * 0.22 + const compounding = Math.exp(cycle * Math.max(0, feedbackStrength - 0.86) * 0.11) + const correction = Math.sin(cycle * 1.38) * correctionPressure * 0.42 + return clamp(0.1 + drift + compounding * 0.18 - correction, 0.08, 2.7) +} + +function drawChart( + canvas: HTMLCanvasElement, + cycle: number, + feedbackStrength: number, + correctionPressure: 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.08 + const padY = height * 0.14 + const chartW = width - padX * 2 + const chartH = height - padY * 2 + + ctx.lineWidth = 1 + ctx.strokeStyle = palette.grid + for (let index = 0; index <= 4; index += 1) { + const y = padY + (index / 4) * chartH + ctx.beginPath() + ctx.moveTo(padX, y) + ctx.lineTo(width - padX, y) + ctx.stroke() + } + + const samples = 80 + const points = Array.from({ length: samples }, (_, index) => { + const sampleCycle = Math.max(0, cycle - 7 + (index / (samples - 1)) * 7) + const value = getBubbleValue(sampleCycle, feedbackStrength, correctionPressure) + return { + x: padX + (index / (samples - 1)) * chartW, + y: padY + chartH - (value / 2.7) * chartH + } + }) + + const gradient = ctx.createLinearGradient(0, padY, 0, height - padY) + gradient.addColorStop(0, palette.scenario) + gradient.addColorStop(1, 'rgba(255, 255, 255, 0)') + + ctx.beginPath() + points.forEach((point, index) => { + if (index === 0) ctx.moveTo(point.x, point.y) + else ctx.lineTo(point.x, point.y) + }) + ctx.lineTo(width - padX, height - padY) + ctx.lineTo(padX, height - padY) + ctx.closePath() + ctx.fillStyle = gradient + ctx.globalAlpha = 0.22 + ctx.fill() + ctx.globalAlpha = 1 + + ctx.beginPath() + points.forEach((point, index) => { + if (index === 0) ctx.moveTo(point.x, point.y) + else ctx.lineTo(point.x, point.y) + }) + ctx.strokeStyle = palette.scenario + ctx.lineWidth = Math.max(2, width * 0.006) + ctx.stroke() + + const latest = points[points.length - 1] + ctx.beginPath() + ctx.arc(latest.x, latest.y, Math.max(5, width * 0.014), 0, Math.PI * 2) + ctx.fillStyle = palette.accent + ctx.fill() +} + +export default function Component({ + config, + onComplete, + onProgress, + theme, + className, + host +}: GlitchComponentProps) { + const params = config.params as ComponentParams + const scenarios = useMemo(() => getScenarios(params), [params]) + const [scenarioKey, setScenarioKey] = useState(() => String(params.scenario ?? scenarios[0].key)) + const [running, setRunning] = useState(true) + const [cycle, setCycle] = useState(0) + const [completed, setCompleted] = useState(false) + const canvasRef = useRef(null) + const lastTickRef = useRef(0) + + const animationSpeed = clamp(numberParam(params.animationSpeed, 1), 0.25, 3) + const feedbackStrength = clamp(numberParam(params.feedbackStrength, 1.18), 0.55, 1.8) + const correctionPressure = clamp(numberParam(params.correctionPressure, 0.18), 0, 0.65) + const scenario = scenarios.find((item) => item.key === scenarioKey) ?? scenarios[0] + const phase = cycle % 1 + const eventIndex = Math.floor(phase * scenario.events.length) % scenario.events.length + const nextEventIndex = (eventIndex + 1) % scenario.events.length + const bubbleValue = getBubbleValue(cycle, feedbackStrength, correctionPressure) + const pressure = Math.round(clamp((bubbleValue / 2.7) * 100, 0, 100)) + const progress = Math.round(clamp((cycle / 12) * 100, 0, 100)) + + const palette = useMemo(() => ({ + accent: theme?.accent ?? '#22d3ee', + text: theme?.text ?? '#e8e8ec', + muted: theme?.textMuted ?? '#9999a8', + grid: 'rgba(232, 232, 236, 0.13)', + scenario: scenario.color + }), [scenario.color, theme?.accent, theme?.text, theme?.textMuted]) + + 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, + '--bubble-color': scenario.color, + '--rotation': `${phase * 360}deg` + }) as CSSProperties, [phase, scenario.color, theme]) + + const redraw = useCallback(() => { + if (!canvasRef.current) return + drawChart(canvasRef.current, cycle, feedbackStrength, correctionPressure, palette) + }, [correctionPressure, cycle, feedbackStrength, palette]) + + useEffect(() => { + setScenarioKey(String(params.scenario ?? scenarios[0].key)) + }, [params.scenario, scenarios]) + + useEffect(() => { + setCycle(0) + }, [scenarioKey]) + + 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 = 34 / animationSpeed + if (running && timestamp - lastTickRef.current > interval) { + setCycle((current) => (current >= 12 ? 0 : current + 0.0125)) + lastTickRef.current = timestamp + } + + animationFrame = window.requestAnimationFrame(step) + } + + animationFrame = window.requestAnimationFrame(step) + return () => window.cancelAnimationFrame(animationFrame) + }, [animationSpeed, running]) + + const playClick = useCallback((target: string) => { + host?.playSound?.('ui.button_click', { target, component: config.name }) + }, [config.name, host]) + + const chooseScenario = useCallback((key: ScenarioKey) => { + playClick(key) + setRunning(true) + setScenarioKey(key) + }, [playClick]) + + const finish = useCallback(() => { + if (completed) return + + setCompleted(true) + playClick('complete') + onComplete({ + success: true, + score: 100, + data: { + scenario: scenario.key, + cycle, + pressure, + activeEvent: scenario.events[eventIndex], + nextEvent: scenario.events[nextEventIndex], + definition: 'A bubble is a self-amplifying feedback loop: output becomes input.', + configId: config.id, + completedAt: new Date().toISOString() + } + }) + }, [completed, config.id, cycle, eventIndex, nextEventIndex, onComplete, playClick, pressure, scenario]) + + const rootClassName = className ? `${styles.wrapper} ${className}` : styles.wrapper + + return ( +
+
+
+
+ Feedback loop +

A bubble is output used as input

+
+
+ + {scenarios.map((item) => ( + + ))} +
+
+ +
+
+
+
+ {scenario.title} + {scenario.subject} +
+
+ cycle + {cycle.toFixed(1)} +
+
+ +
+
+ + +
+ +
+ { + playClick('cycle') + setRunning(false) + setCycle(Number(event.currentTarget.value)) + }} + /> + +
+
+
+ ) +} 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..90cf132 --- /dev/null +++ b/src/dev.tsx @@ -0,0 +1,56 @@ +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({ + scenario: { + value: 'ai-stock', + options: { + 'AI Stock Bubble': 'ai-stock', + 'String Theory Field Bubble': 'string-theory' + } + }, + animationSpeed: { value: 1, min: 0.25, max: 3, step: 0.25 }, + feedbackStrength: { value: 1.18, min: 0.55, max: 1.8, step: 0.05 }, + correctionPressure: { value: 0.18, min: 0, max: 0.65, step: 0.05 } + }) + + return ( +
+
+ ) +} + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + +) diff --git a/src/index.tsx b/src/index.tsx new file mode 100644 index 0000000..c6226c0 --- /dev/null +++ b/src/index.tsx @@ -0,0 +1,65 @@ +import Component from './Component' +import type { GlitchComponentMetadata } from './types' + +export default Component + +export const metadata: GlitchComponentMetadata = { + name: 'bubble-feedback', + displayName: 'Bubble Feedback', + version: '1.0.0', + paramSchema: { + scenario: { + type: 'select', + label: 'Scenario', + default: 'ai-stock', + options: [ + { value: 'ai-stock', label: 'AI Stock Bubble' }, + { value: 'string-theory', label: 'String Theory Field Bubble' } + ] + }, + animationSpeed: { + type: 'range', + label: 'Animation Speed', + default: 1, + min: 0.25, + max: 3, + step: 0.25 + }, + feedbackStrength: { + type: 'range', + label: 'Feedback Strength', + default: 1.18, + min: 0.55, + max: 1.8, + step: 0.05 + }, + correctionPressure: { + type: 'range', + label: 'Correction Pressure', + default: 0.18, + min: 0, + max: 0.65, + step: 0.05 + } + }, + defaultParams: { + scenario: 'ai-stock', + animationSpeed: 1, + feedbackStrength: 1.18, + correctionPressure: 0.18 + } +} + +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..0d5141e --- /dev/null +++ b/src/styles.module.css @@ -0,0 +1,451 @@ +.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; + gap: 0.65em; + overflow: hidden; + padding: 1em; + color: var(--gc-text); + font-family: var(--gc-font-main); + font-size: clamp(10px, 1.08cqw, 18px); + line-height: 1.2; + background: + radial-gradient(circle at 16% 12%, color-mix(in srgb, var(--bubble-color) 22%, transparent), transparent 28%), + radial-gradient(circle at 82% 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, +.controls, +.loopHeader, +.footer, +.cycleReadout { + display: flex; + align-items: center; +} + +.header, +.loopHeader, +.footer { + justify-content: space-between; + gap: 1em; +} + +.header h2 { + margin: 0.1em 0 0; + font-family: var(--gc-font-display); + font-size: 1.42em; + line-height: 1; + letter-spacing: 0; +} + +.kicker { + display: block; + color: color-mix(in srgb, var(--gc-accent) 78%, white); + font-family: var(--gc-font-mono); + font-size: 0.62em; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.controls { + gap: 0.45em; +} + +.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.66em; + font-weight: 700; + 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.5em; + min-height: 2.6em; + background: rgb(10 14 24 / 72%); +} + +.modeButton { + min-height: 2.6em; + padding: 0 0.8em; + background: rgb(10 14 24 / 58%); +} + +.modeActive { + color: #090b10; + background: linear-gradient(90deg, var(--bubble-color), color-mix(in srgb, var(--gc-accent) 42%, var(--bubble-color))); + border-color: rgb(255 255 255 / 56%); +} + +.stageGrid { + min-height: 0; + display: grid; + grid-template-columns: minmax(0, 1.32fr) minmax(12em, 0.68fr); + gap: 0.65em; +} + +.loopPanel, +.eventPanel { + min-width: 0; + min-height: 0; + border: 1px solid color-mix(in srgb, var(--gc-border) 76%, transparent); + background: rgb(5 9 18 / 56%); +} + +.loopPanel { + display: grid; + grid-template-rows: auto minmax(0, 1fr); + gap: 0.3em; + padding: 0.75em; +} + +.loopHeader strong { + display: block; + margin-top: 0.2em; + font-size: 0.86em; + font-weight: 650; +} + +.cycleReadout { + align-items: flex-end; + flex-direction: column; + gap: 0.16em; + color: var(--gc-text-muted); + font-family: var(--gc-font-mono); + font-size: 0.66em; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.cycleReadout strong { + color: var(--bubble-color); + font-family: var(--gc-font-display); + font-size: 2.1em; + line-height: 0.9; + letter-spacing: 0; +} + +.loop { + position: relative; + width: min(100%, 34em); + aspect-ratio: 1; + align-self: center; + justify-self: center; +} + +.ring { + position: absolute; + inset: 18%; + border: 0.28em solid color-mix(in srgb, var(--bubble-color) 44%, transparent); + border-radius: 50%; + box-shadow: + inset 0 0 1.7em rgb(255 255 255 / 5%), + 0 0 1.6em color-mix(in srgb, var(--bubble-color) 28%, transparent); +} + +.ring::after { + content: ""; + position: absolute; + inset: -0.55em; + border-radius: 50%; + border: 1px dashed color-mix(in srgb, var(--gc-text) 24%, transparent); +} + +.pulse { + position: absolute; + inset: 50%; + width: 1.05em; + height: 1.05em; + border-radius: 50%; + background: var(--gc-accent); + box-shadow: + 0 0 0 0.4em color-mix(in srgb, var(--gc-accent) 14%, transparent), + 0 0 1.4em color-mix(in srgb, var(--gc-accent) 80%, transparent); + transform: rotate(var(--rotation)) translateY(-10.7em) translate(-50%, -50%); + transform-origin: 0 0; +} + +.core { + position: absolute; + inset: 34%; + overflow: hidden; + border: 1px solid color-mix(in srgb, var(--gc-border) 78%, transparent); + border-radius: 50%; + background: rgb(7 11 17 / 88%); + text-align: center; +} + +.coreOverlay { + position: absolute; + inset: auto 12% 13%; + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 0.5em; + pointer-events: none; +} + +.coreOverlay span { + max-width: 9em; + color: color-mix(in srgb, var(--gc-text-muted) 88%, white); + font-family: var(--gc-font-mono); + font-size: 0.58em; + font-weight: 700; + letter-spacing: 0.1em; + line-height: 1.1; + text-align: left; + text-transform: uppercase; +} + +.coreOverlay strong { + color: var(--bubble-color); + font-family: var(--gc-font-display); + font-size: 1.28em; + line-height: 0.9; +} + +.canvas { + display: block; + width: 100%; + height: 100%; + border: 0; + background: + linear-gradient(90deg, color-mix(in srgb, var(--bubble-color) 8%, transparent), transparent 40%), + rgb(7 11 17 / 78%); +} + +.loopStation { + position: absolute; + z-index: 2; + width: 0; + height: 0; + transform: translate(-50%, -50%); +} + +.loopNode { + position: absolute; + left: 0; + top: 0; + width: 2.4em; + height: 2.4em; + display: grid; + place-items: center; + border: 1px solid color-mix(in srgb, var(--gc-border) 80%, transparent); + border-radius: 50%; + background: rgb(9 13 22 / 94%); + color: var(--gc-text-muted); + font-family: var(--gc-font-mono); + font-size: 0.78em; + font-weight: 800; + transform: translate(-50%, -50%); + transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease; +} + +.nodeActive { + color: #071018; + background: var(--bubble-color); + border-color: rgb(255 255 255 / 72%); + box-shadow: 0 0 1.2em color-mix(in srgb, var(--bubble-color) 54%, transparent); +} + +.stationLabel { + position: absolute; + left: 0; + top: 0; + width: 12.4em; + max-height: 4.6em; + overflow: hidden; + margin: 0; + padding: 0.48em 0.58em; + border: 1px solid color-mix(in srgb, var(--gc-border) 72%, transparent); + background: rgb(5 9 18 / 82%); + color: color-mix(in srgb, var(--gc-text-muted) 86%, white); + font-size: 0.62em; + line-height: 1.14; + transform: translate(calc(-50% + var(--label-x)), calc(-50% + var(--label-y))); + transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease; +} + +.labelActive { + border-color: color-mix(in srgb, var(--bubble-color) 70%, var(--gc-border)); + background: color-mix(in srgb, var(--bubble-color) 18%, rgb(5 9 18)); + color: var(--gc-text); + box-shadow: 0 0 1.1em color-mix(in srgb, var(--bubble-color) 26%, transparent); +} + +.eventPanel { + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 1em; + padding: 0.9em; +} + +.eventPanel h3 { + margin: 0; + color: var(--gc-text); + font-family: var(--gc-font-display); + font-size: 1.18em; + line-height: 1.04; + letter-spacing: 0; +} + +.nextEvent { + padding-top: 0.75em; + border-top: 1px solid color-mix(in srgb, var(--gc-border) 72%, transparent); +} + +.nextEvent span, +.definition span { + color: var(--bubble-color); + font-family: var(--gc-font-mono); + font-size: 0.62em; + font-weight: 800; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.nextEvent p, +.definition p { + margin: 0.35em 0 0; + color: color-mix(in srgb, var(--gc-text-muted) 86%, white); + font-size: 0.8em; + line-height: 1.22; +} + +.definition { + padding-top: 0.75em; + border-top: 1px solid color-mix(in srgb, var(--gc-border) 72%, transparent); +} + +.footer { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + padding: 0.62em 0.8em; + border: 1px solid color-mix(in srgb, var(--gc-border) 76%, transparent); + background: rgb(5 9 18 / 54%); +} + +.footer input { + width: 100%; + accent-color: var(--bubble-color); +} + +.completeButton { + min-width: 3em; + 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, 1fr) auto; + font-size: clamp(10px, 3.15cqw, 16px); + } + + .header { + align-items: flex-start; + flex-direction: column; + gap: 0.55em; + } + + .header h2 { + font-size: 1.2em; + } + + .controls { + width: 100%; + display: grid; + grid-template-columns: 3.4em repeat(2, minmax(0, 1fr)); + } + + .stageGrid { + grid-template-columns: 1fr; + grid-template-rows: minmax(0, 1fr) auto; + } + + .loop { + width: min(100%, 29em); + } + + .pulse { + transform: rotate(var(--rotation)) translateY(-9.2em) translate(-50%, -50%); + } + + .eventPanel { + padding: 0.75em; + } + + .eventPanel h3 { + font-size: 0.96em; + } + + .nextEvent p { + display: none; + } + + .stationLabel { + width: 10.8em; + max-height: 3.9em; + font-size: 0.54em; + } +} 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..60fad8b --- /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: 'bubble-feedback', + 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: 3002, + open: true + } +}))